Quinoa all test code coverage report
Current view: top level - Control/Inciter/InputDeck - LuaParser.cpp (source / functions) Hit Total Coverage
Commit: -128-NOTFOUND Lines: 494 663 74.5 %
Date: 2025-11-20 15:05:58 Functions: 6 6 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1138 4102 27.7 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/Control/Inciter/InputDeck/LuaParser.cpp
       4                 :            :   \copyright 2019-2021 Triad National Security, LLC.
       5                 :            :              All rights reserved. See the LICENSE file for details.
       6                 :            :   \brief     Inciter's lua input deck file parser
       7                 :            :   \details   This file defines the input deck, i.e., control file, parser for
       8                 :            :     the computational shock hydrodynamics tool, Inciter.
       9                 :            : */
      10                 :            : // *****************************************************************************
      11                 :            : 
      12                 :            : #include <ostream>
      13                 :            : #include <type_traits>
      14                 :            : 
      15                 :            : #include "QuinoaConfig.hpp"
      16                 :            : 
      17                 :            : #include "NoWarning/pegtl.hpp"
      18                 :            : 
      19                 :            : #include "Print.hpp"
      20                 :            : #include "Exception.hpp"
      21                 :            : #include "Inciter/InputDeck/InputDeck.hpp"
      22                 :            : #include "Inciter/InputDeck/LuaParser.hpp"
      23                 :            : #include "PDE/MultiMat/MultiMatIndexing.hpp"
      24                 :            : #include "PDE/MultiSpecies/MultiSpeciesIndexing.hpp"
      25                 :            : 
      26                 :            : namespace tk {
      27                 :            : namespace grm {
      28                 :            : 
      29                 :            :   //! \brief Case-insensitive character comparison functor
      30                 :            :   struct CaseInsensitiveCharLess {
      31                 :            :     //! Function call operator
      32                 :            :     //! \param[in] lhs Left character of the comparitor operand
      33                 :            :     //! \param[in] rhs Right character of the comparitor operand
      34                 :            :     //! \return Boolean indicating the result of the comparison
      35                 :            :     bool operator() ( char lhs, char rhs ) const {
      36 [ -  + ][ -  + ]:          3 :       return std::tolower( lhs ) < std::tolower( rhs );
                 [ +  - ]
      37                 :            :     }
      38                 :            :   };
      39                 :            : 
      40                 :            :   //! \brief Parser-lifetime storage for dependent variables selected.
      41                 :            :   //! \details Used to track the dependent variable of differential equations
      42                 :            :   //!   (i.e., models) assigned during parsing. It needs to be case insensitive
      43                 :            :   //!   since we only care about whether the variable is selected or not and not
      44                 :            :   //!   whether it denotes a full variable (upper case) or a fluctuation (lower
      45                 :            :   //!   case). This is true for both inserting variables into the set as well as
      46                 :            :   //!   at matching terms of products in parsing requested statistics.
      47                 :            :   static std::set< char, CaseInsensitiveCharLess > depvars;
      48                 :            : 
      49                 :            : } // grm::
      50                 :            : } // tk::
      51                 :            : 
      52                 :            : using inciter::LuaParser;
      53                 :            : 
      54                 :        173 : LuaParser::LuaParser( const tk::Print& /*print*/,
      55                 :            :                       const ctr::CmdLine& cmdline,
      56                 :            :                       ctr::InputDeck& inputdeck ) :
      57                 :        173 :   m_filename( cmdline.get< tag::io, tag::control >() )
      58                 :            : // *****************************************************************************
      59                 :            : //  Constructor
      60                 :            : // //! \param[in] print Pretty printer
      61                 :            : //! \param[in] cmdline Command line stack
      62                 :            : //! \param[in,out] inputdeck Input deck stack where data is stored during
      63                 :            : //!    parsing
      64                 :            : // *****************************************************************************
      65                 :            : {
      66                 :            :   // Make sure there is a filename
      67                 :            :   Assert( !m_filename.empty(), "No filename specified" );
      68                 :            : 
      69                 :            :   // Local file stream handle
      70         [ +  - ]:        346 :   std::ifstream q;
      71                 :            : 
      72                 :            :   // Check if file exists, throw exception if it does not
      73         [ +  - ]:        173 :   q.open( m_filename, std::ifstream::in );
      74 [ -  + ][ -  - ]:        173 :   ErrChk( q.good(), "Failed to open file: " + m_filename );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
      75                 :            : 
      76                 :            :   // Attempt to read a character, throw if it fails
      77                 :            :   // It is curious that on some systems opening a directory instead of a file
      78                 :            :   // with the above ifstream::open() call does not set the failbit. Thus we get
      79                 :            :   // here fine, so we try to read a character from it. If it is a directory or
      80                 :            :   // an empty file the read will fail, so we throw. Read more at: http://
      81                 :            :   // stackoverflow.com/questions/9591036/
      82                 :            :   // ifstream-open-doesnt-set-error-bits-when-argument-is-a-directory.
      83         [ +  - ]:        173 :   q.get();
      84 [ -  + ][ -  - ]:        173 :   ErrChk( q.good(), "Failed to read from file: " + m_filename );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
      85                 :            : 
      86                 :            :   // Close it
      87         [ +  - ]:        173 :   q.close();
      88 [ -  + ][ -  - ]:        173 :   ErrChk( !q.fail(), "Failed to close file: " + m_filename );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
      89                 :            : 
      90                 :            :   // Create InputDeck (a tagged tuple) to store parsed input
      91         [ +  - ]:        173 :   ctr::InputDeck ideck( cmdline );
      92                 :            : 
      93                 :            :   // Read lua file into sol object
      94         [ +  - ]:        346 :   sol::state lua_deck;
      95 [ +  - ][ +  - ]:        173 :   lua_deck.open_libraries(sol::lib::base);
      96         [ +  - ]:        173 :   lua_deck.script_file(m_filename);
      97                 :            : 
      98                 :            :   // Store inputdeck parameters from sol object into tagged tuple
      99         [ +  - ]:        346 :   storeInputDeck(lua_deck["inciter"], ideck);
     100                 :            : 
     101                 :            :   inputdeck = std::move( ideck );
     102                 :        173 : }
     103                 :            : 
     104                 :            : void
     105                 :        173 : LuaParser::storeInputDeck(
     106                 :            :   const sol::table& lua_ideck,
     107                 :            :   ctr::InputDeck& gideck )
     108                 :            : // *****************************************************************************
     109                 :            : //  Store lua inputdeck in custom struct
     110                 :            : //! \param[in] lua_ideck Lua inputdeck parsed by sol2
     111                 :            : //! \param[in,out] gideck Inciter's inputdeck storage
     112                 :            : // *****************************************************************************
     113                 :            : {
     114                 :            :   // TODO: explore replacing storeIfSpecd() and storeOptIfSpecd with sol::get_or()
     115                 :            : 
     116 [ +  - ][ +  - ]:        519 :   storeIfSpecd< std::string >(
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
                 [ -  - ]
     117                 :            :     lua_ideck, "title", gideck.get< tag::title >(), "No title");
     118                 :            : 
     119                 :            :   // time stepping options
     120                 :            :   // ---------------------------------------------------------------------------
     121 [ +  - ][ +  - ]:        519 :   storeIfSpecd< uint64_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     122                 :            :     lua_ideck, "nstep", gideck.get< tag::nstep >(),
     123                 :            :     std::numeric_limits< uint64_t >::max());
     124 [ +  - ][ +  - ]:        519 :   storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     125                 :            :     lua_ideck, "term", gideck.get< tag::term >(),
     126                 :            :     std::numeric_limits< tk::real >::max());
     127 [ +  - ][ +  - ]:        519 :   storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     128                 :            :     lua_ideck, "t0", gideck.get< tag::t0 >(), 0.0);
     129 [ +  - ][ +  - ]:        519 :   storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     130                 :            :     lua_ideck, "dt", gideck.get< tag::dt >(), 0.0);
     131 [ +  - ][ +  - ]:        519 :   storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     132                 :            :     lua_ideck, "cfl", gideck.get< tag::cfl >(), 0.0);
     133 [ +  - ][ +  - ]:        519 :   storeIfSpecd< bool >(
         [ -  + ][ +  - ]
                 [ -  - ]
     134                 :            :     lua_ideck, "cfl_ramping", gideck.get< tag::cfl_ramping >(), false);
     135 [ +  - ][ +  - ]:        692 :   storeIfSpecd< uint32_t >( lua_ideck,
         [ +  - ][ +  - ]
                 [ -  - ]
     136                 :            :     "cfl_ramping_steps", gideck.get< tag::cfl_ramping_steps >(), 100);
     137 [ +  - ][ +  - ]:        519 :   storeIfSpecd< uint32_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     138                 :            :     lua_ideck, "ttyi", gideck.get< tag::ttyi >(), 1);
     139 [ +  - ][ +  - ]:        692 :   storeIfSpecd< bool >(lua_ideck, "implicit_timestepping",
         [ +  - ][ +  - ]
                 [ -  - ]
     140                 :            :     gideck.get< tag::implicit_timestepping >(), false);
     141 [ +  - ][ +  - ]:        519 :   storeIfSpecd< bool >(
         [ -  + ][ +  - ]
                 [ -  - ]
     142                 :            :     lua_ideck, "steady_state", gideck.get< tag::steady_state >(), false);
     143 [ +  - ][ +  - ]:        519 :   storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     144                 :            :     lua_ideck, "residual", gideck.get< tag::residual >(), 1.0e-8);
     145 [ +  - ][ +  - ]:        519 :   storeIfSpecd< uint32_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     146                 :            :     lua_ideck, "rescomp", gideck.get< tag::rescomp >(), 1);
     147 [ +  - ][ +  - ]:        692 :   storeIfSpecd< uint32_t >(
         [ +  - ][ +  - ]
                 [ -  - ]
     148                 :            :     lua_ideck, "imex_runge_kutta", gideck.get< tag::imex_runge_kutta >(), 0);
     149 [ +  - ][ +  - ]:        519 :   storeIfSpecd< uint32_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     150                 :            :     lua_ideck, "imex_maxiter", gideck.get< tag::imex_maxiter >(), 50);
     151 [ +  - ][ +  - ]:        519 :   storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     152                 :            :     lua_ideck, "imex_reltol", gideck.get< tag::imex_reltol >(), 1.0e-02);
     153 [ +  - ][ +  - ]:        519 :   storeIfSpecd< tk::real >(
         [ -  + ][ -  - ]
     154                 :            :     lua_ideck, "imex_abstol", gideck.get< tag::imex_abstol >(), 1.0e-04);
     155                 :            : 
     156 [ +  + ][ -  + ]:        173 :   if (gideck.get< tag::dt >() < 1e-12 && gideck.get< tag::cfl >() < 1e-12)
     157 [ -  - ][ -  - ]:          0 :     Throw("No time step calculation policy has been selected in the "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     158                 :            :       "preceeding block. Use keyword 'dt' to set a constant or 'cfl' to set an "
     159                 :            :       "adaptive time step size calculation policy.");
     160                 :            : 
     161                 :            :   // partitioning/reordering options
     162                 :            :   // ---------------------------------------------------------------------------
     163                 :            :   storeOptIfSpecd< tk::ctr::PartitioningAlgorithmType,
     164 [ +  - ][ +  - ]:        519 :     tk::ctr::PartitioningAlgorithm >(
         [ -  + ][ +  - ]
                 [ -  - ]
     165                 :            :     lua_ideck, "partitioning", gideck.get< tag::partitioning >(),
     166                 :            :     tk::ctr::PartitioningAlgorithmType::RCB);
     167 [ +  - ][ +  - ]:        519 :   storeIfSpecd< bool >(
         [ -  + ][ +  - ]
                 [ -  - ]
     168                 :            :     lua_ideck, "pelocal_reorder", gideck.get< tag::pelocal_reorder >(),
     169                 :            :     false);
     170 [ +  - ][ +  - ]:        692 :   storeIfSpecd< bool >(
         [ +  - ][ +  - ]
                 [ -  - ]
     171                 :            :     lua_ideck, "operator_reorder", gideck.get< tag::operator_reorder >(),
     172                 :            :     false);
     173                 :            : 
     174                 :            :   // discretization scheme options
     175                 :            :   // ---------------------------------------------------------------------------
     176                 :            :   using inciter::ctr::SchemeType;
     177 [ +  - ][ +  - ]:        519 :   storeOptIfSpecd< SchemeType, inciter::ctr::Scheme >(
         [ -  + ][ +  - ]
                 [ -  - ]
     178                 :            :     lua_ideck, "scheme", gideck.get< tag::scheme >(), SchemeType::ALECG);
     179 [ +  - ][ +  - ]:        519 :   storeOptIfSpecd< inciter::ctr::LimiterType, inciter::ctr::Limiter >(
         [ -  + ][ +  - ]
                 [ -  - ]
     180                 :            :     lua_ideck, "limiter", gideck.get< tag::limiter >(),
     181                 :            :     inciter::ctr::LimiterType::NOLIMITER);
     182 [ +  - ][ +  - ]:        519 :   storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     183                 :            :     lua_ideck, "cweight", gideck.get< tag::cweight >(), 1.0);
     184 [ +  - ][ +  - ]:        692 :   storeIfSpecd< tk::real >(
         [ +  - ][ +  - ]
                 [ -  - ]
     185                 :            :     lua_ideck, "shock_detector_coeff",
     186                 :            :     gideck.get< tag::shock_detector_coeff >(), 1.0);
     187 [ +  - ][ +  - ]:        519 :   storeIfSpecd< bool >(
         [ -  + ][ +  - ]
                 [ -  - ]
     188                 :            :     lua_ideck, "accuracy_test", gideck.get< tag::accuracy_test >(), false);
     189 [ +  - ][ +  - ]:        692 :   storeIfSpecd< bool >(
         [ +  - ][ +  - ]
                 [ -  - ]
     190                 :            :     lua_ideck, "limsol_projection", gideck.get< tag::limsol_projection >(),
     191                 :            :     true);
     192 [ +  - ][ +  - ]:        519 :   storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     193                 :            :     lua_ideck, "lowspeed_kp", gideck.get< tag::lowspeed_kp >(), 0.0);
     194 [ +  - ][ +  - ]:        519 :   storeIfSpecd< tk::real >(
         [ -  + ][ -  - ]
     195                 :            :     lua_ideck, "lowspeed_ku", gideck.get< tag::lowspeed_ku >(), 1.0);
     196                 :            : 
     197                 :            :   // configure solutions DOFs
     198                 :        173 :   auto scheme = gideck.get< tag::scheme >();
     199                 :            :   auto& ndof = gideck.get< tag::ndof >();
     200                 :            :   auto& rdof = gideck.get< tag::rdof >();
     201                 :        173 :   ndof = rdof = 1;
     202         [ +  + ]:        173 :   if (scheme == SchemeType::P0P1 || scheme == SchemeType::FV) {
     203                 :         33 :     ndof = 1; rdof = 4;
     204         [ +  + ]:        140 :   } else if (scheme == SchemeType::DGP1) {
     205                 :         11 :     ndof = rdof = 4;
     206         [ +  + ]:        129 :   } else if (scheme == SchemeType::DGP2) {
     207                 :          4 :     ndof = rdof = 10;
     208         [ +  + ]:        125 :   } else if (scheme == SchemeType::PDG) {
     209                 :         12 :     ndof = rdof = 10;
     210                 :         12 :     gideck.get< tag::pref, tag::pref >() = true;
     211                 :        113 :   } else if (scheme != SchemeType::DGP0 &&
     212 [ +  + ][ -  + ]:        113 :       scheme != SchemeType::ALECG &&
     213                 :            :       scheme != SchemeType::OversetFE) {
     214 [ -  - ][ -  - ]:          0 :     Throw("Scheme type not configured in configure_scheme");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     215                 :            :   }
     216                 :            : 
     217                 :            :   // PDE options
     218                 :            :   // ---------------------------------------------------------------------------
     219                 :            : 
     220                 :        173 :   char depvar_cnt = 'a';
     221                 :        173 :   gideck.get< tag::depvar >().resize(1);
     222                 :            : 
     223                 :            :   // check transport
     224         [ +  + ]:        173 :   if (lua_ideck["transport"].valid()) {
     225                 :            : 
     226 [ +  - ][ +  - ]:         51 :     checkBlock< inciter::ctr::transportList::Keys >(lua_ideck["transport"],
         [ -  + ][ -  - ]
     227                 :            :       "transport");
     228                 :            : 
     229         [ +  - ]:         17 :     gideck.get< tag::pde >() = inciter::ctr::PDEType::TRANSPORT;
     230 [ +  - ][ +  - ]:         51 :     storeIfSpecd< std::size_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     231                 :            :       lua_ideck["transport"], "ncomp",
     232                 :            :       gideck.get< tag::transport, tag::ncomp >(), 1);
     233 [ +  - ][ +  - ]:         51 :     storeIfSpecd< int >(
         [ -  + ][ +  - ]
                 [ -  - ]
     234                 :            :       lua_ideck["transport"], "intsharp",
     235                 :            :       gideck.get< tag::transport, tag::intsharp >(), 0);
     236 [ +  - ][ +  - ]:         51 :     storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     237                 :            :       lua_ideck["transport"], "intsharp_param",
     238                 :            :       gideck.get< tag::transport, tag::intsharp_param >(), 1.8);
     239 [ +  - ][ +  - ]:         51 :     storeOptIfSpecd< inciter::ctr::ProblemType, inciter::ctr::Problem >(
         [ -  + ][ -  - ]
     240                 :            :       lua_ideck["transport"], "problem",
     241                 :            :       gideck.get< tag::transport, tag::problem >(),
     242                 :            :       inciter::ctr::ProblemType::USER_DEFINED);
     243 [ +  - ][ +  - ]:         51 :     storeVecIfSpecd< tk::real >(
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
     244                 :            :       lua_ideck["transport"], "diffusivity",
     245                 :            :       gideck.get< tag::transport, tag::diffusivity >(), {0.0, 0.0, 0.0});
     246 [ +  - ][ +  - ]:         51 :     storeVecIfSpecd< tk::real >(
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
     247                 :            :       lua_ideck["transport"], "u0",
     248                 :            :       gideck.get< tag::transport, tag::u0 >(), {0.0, 0.0, 0.0});
     249 [ +  - ][ +  - ]:         51 :     storeVecIfSpecd< tk::real >(
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
     250                 :            :       lua_ideck["transport"], "lambda",
     251                 :            :       gideck.get< tag::transport, tag::lambda >(), {0.0, 0.0, 0.0});
     252         [ +  - ]:         17 :     gideck.get< tag::depvar >()[0] = 'c';
     253 [ +  - ][ +  - ]:         51 :     storeOptIfSpecd< inciter::ctr::FluxType, inciter::ctr::Flux >(
         [ -  + ][ +  - ]
                 [ -  - ]
     254                 :            :       lua_ideck, "flux", gideck.get< tag::flux >(),
     255                 :            :       inciter::ctr::FluxType::UPWIND);
     256 [ +  - ][ +  - ]:         51 :     storeOptIfSpecd< inciter::ctr::PhysicsType, inciter::ctr::Physics >(
         [ -  + ][ -  - ]
     257                 :            :       lua_ideck["transport"], "physics",
     258                 :            :       gideck.get< tag::transport, tag::physics >(),
     259                 :            :       inciter::ctr::PhysicsType::ADVECTION);
     260                 :            : 
     261                 :            :     // store number of equations in PDE system
     262                 :         17 :     gideck.get< tag::ncomp >() =
     263                 :         17 :       gideck.get< tag::transport, tag::ncomp >();
     264                 :            :   }
     265                 :            : 
     266                 :            :   // check compflow
     267         [ +  + ]:        173 :   if (lua_ideck["compflow"].valid()) {
     268                 :            : 
     269 [ +  - ][ +  - ]:        342 :     checkBlock< inciter::ctr::compflowList::Keys >(lua_ideck["compflow"],
         [ -  + ][ -  - ]
     270                 :            :       "compflow");
     271                 :            : 
     272         [ +  - ]:        114 :     gideck.get< tag::pde >() = inciter::ctr::PDEType::COMPFLOW;
     273 [ +  - ][ +  - ]:        342 :     storeOptIfSpecd< inciter::ctr::ProblemType, inciter::ctr::Problem >(
         [ -  + ][ +  - ]
                 [ -  - ]
     274                 :            :       lua_ideck["compflow"], "problem",
     275                 :            :       gideck.get< tag::compflow, tag::problem >(),
     276                 :            :       inciter::ctr::ProblemType::USER_DEFINED);
     277 [ +  - ][ +  - ]:        342 :     storeOptIfSpecd< inciter::ctr::PhysicsType, inciter::ctr::Physics >(
         [ -  + ][ +  - ]
                 [ -  - ]
     278                 :            :       lua_ideck["compflow"], "physics",
     279                 :            :       gideck.get< tag::compflow, tag::physics >(),
     280                 :            :       inciter::ctr::PhysicsType::EULER);
     281                 :            : 
     282                 :            :     // problem parameters for MMS
     283 [ +  - ][ +  - ]:        342 :     storeIfSpecd< tk::real >(lua_ideck["compflow"], "alpha",
         [ -  + ][ +  - ]
                 [ -  - ]
     284                 :            :       gideck.get< tag::compflow, tag::alpha >(), 0.0);
     285 [ +  - ][ +  - ]:        342 :     storeIfSpecd< tk::real >(lua_ideck["compflow"], "beta",
         [ -  + ][ +  - ]
                 [ -  - ]
     286                 :            :       gideck.get< tag::compflow, tag::beta >(), 0.0);
     287 [ +  - ][ +  - ]:        342 :     storeIfSpecd< tk::real >(lua_ideck["compflow"], "betax",
         [ -  + ][ +  - ]
                 [ -  - ]
     288                 :            :       gideck.get< tag::compflow, tag::betax >(), 0.0);
     289 [ +  - ][ +  - ]:        342 :     storeIfSpecd< tk::real >(lua_ideck["compflow"], "betay",
         [ -  + ][ +  - ]
                 [ -  - ]
     290                 :            :       gideck.get< tag::compflow, tag::betay >(), 0.0);
     291 [ +  - ][ +  - ]:        342 :     storeIfSpecd< tk::real >(lua_ideck["compflow"], "betaz",
         [ -  + ][ +  - ]
                 [ -  - ]
     292                 :            :       gideck.get< tag::compflow, tag::betaz >(), 0.0);
     293 [ +  - ][ +  - ]:        342 :     storeIfSpecd< tk::real >(lua_ideck["compflow"], "r0",
         [ -  + ][ +  - ]
                 [ -  - ]
     294                 :            :       gideck.get< tag::compflow, tag::r0 >(), 0.0);
     295 [ +  - ][ +  - ]:        342 :     storeIfSpecd< tk::real >(lua_ideck["compflow"], "p0",
         [ -  + ][ +  - ]
                 [ -  - ]
     296                 :            :       gideck.get< tag::compflow, tag::p0 >(), 0.0);
     297 [ +  - ][ +  - ]:        342 :     storeIfSpecd< tk::real >(lua_ideck["compflow"], "ce",
         [ -  + ][ +  - ]
                 [ -  - ]
     298                 :            :       gideck.get< tag::compflow, tag::ce >(), 0.0);
     299 [ +  - ][ +  - ]:        342 :     storeIfSpecd< tk::real >(lua_ideck["compflow"], "kappa",
         [ -  + ][ -  - ]
     300                 :            :       gideck.get< tag::compflow, tag::kappa >(), 0.0);
     301                 :            : 
     302         [ +  - ]:        114 :     gideck.get< tag::depvar >()[0] = 'a';
     303 [ +  - ][ +  - ]:        342 :     storeOptIfSpecd< inciter::ctr::FluxType, inciter::ctr::Flux >(
         [ -  + ][ -  - ]
     304                 :            :       lua_ideck, "flux", gideck.get< tag::flux >(),
     305                 :            :       inciter::ctr::FluxType::HLLC);
     306                 :            : 
     307                 :            :     // store number of equations in PDE system
     308                 :        114 :     gideck.get< tag::ncomp >() = 5;
     309                 :            :   }
     310                 :            : 
     311                 :            :   // check multimat
     312         [ +  + ]:        173 :   if (lua_ideck["multimat"].valid()) {
     313                 :            : 
     314 [ +  - ][ +  - ]:        108 :     checkBlock< inciter::ctr::multimatList::Keys >(lua_ideck["multimat"],
         [ -  + ][ -  - ]
     315                 :            :       "multimat");
     316                 :            : 
     317         [ +  - ]:         36 :     gideck.get< tag::pde >() = inciter::ctr::PDEType::MULTIMAT;
     318 [ +  - ][ +  - ]:        108 :     storeIfSpecd< std::size_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     319                 :            :       lua_ideck["multimat"], "nmat",
     320                 :            :       gideck.get< tag::multimat, tag::nmat >(), 2);
     321 [ +  - ][ +  - ]:        108 :     storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     322                 :            :       lua_ideck["multimat"], "min_volumefrac",
     323                 :            :       gideck.get< tag::multimat, tag::min_volumefrac >(), 1.0e-12);
     324 [ +  - ][ +  - ]:        108 :     storeIfSpecd< uint64_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     325                 :            :       lua_ideck["multimat"], "prelax",
     326                 :            :       gideck.get< tag::multimat, tag::prelax >(), 1);
     327 [ +  - ][ +  - ]:        144 :     storeIfSpecd< tk::real >(
         [ +  - ][ +  - ]
                 [ -  - ]
     328                 :            :       lua_ideck["multimat"], "prelax_timescale",
     329                 :            :       gideck.get< tag::multimat, tag::prelax_timescale >(), 0.25);
     330 [ +  - ][ +  - ]:        108 :     storeIfSpecd< int >(
         [ -  + ][ +  - ]
                 [ -  - ]
     331                 :            :       lua_ideck["multimat"], "intsharp",
     332                 :            :       gideck.get< tag::multimat, tag::intsharp >(), 0);
     333 [ +  - ][ +  - ]:        108 :     storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     334                 :            :       lua_ideck["multimat"], "intsharp_param",
     335                 :            :       gideck.get< tag::multimat, tag::intsharp_param >(), 1.8);
     336 [ +  - ][ +  - ]:        108 :     storeIfSpecd< uint64_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     337                 :            :       lua_ideck["multimat"], "rho0constraint",
     338                 :            :       gideck.get< tag::multimat, tag::rho0constraint >(), 0);
     339 [ +  - ][ +  - ]:        108 :     storeIfSpecd< int >(
         [ -  + ][ +  - ]
                 [ -  - ]
     340                 :            :       lua_ideck["multimat"], "dt_sos_massavg",
     341                 :            :       gideck.get< tag::multimat, tag::dt_sos_massavg >(), 0);
     342 [ +  - ][ +  - ]:        108 :     storeOptIfSpecd< inciter::ctr::ProblemType, inciter::ctr::Problem >(
         [ -  + ][ +  - ]
                 [ -  - ]
     343                 :            :       lua_ideck["multimat"], "problem",
     344                 :            :       gideck.get< tag::multimat, tag::problem >(),
     345                 :            :       inciter::ctr::ProblemType::USER_DEFINED);
     346 [ +  - ][ +  - ]:        108 :     storeOptIfSpecd< inciter::ctr::PhysicsType, inciter::ctr::Physics >(
         [ -  + ][ -  - ]
     347                 :            :       lua_ideck["multimat"], "physics",
     348                 :            :       gideck.get< tag::multimat, tag::physics >(),
     349                 :            :       inciter::ctr::PhysicsType::EULER);
     350         [ +  - ]:         36 :     gideck.get< tag::depvar >()[0] = 'a';
     351 [ +  - ][ +  - ]:        108 :     storeOptIfSpecd< inciter::ctr::FluxType, inciter::ctr::Flux >(
         [ -  + ][ -  - ]
     352                 :            :       lua_ideck, "flux", gideck.get< tag::flux >(),
     353                 :            :       inciter::ctr::FluxType::AUSM);
     354                 :            : 
     355                 :            :     // number of equations in PDE system are determined based on materials
     356                 :            :   }
     357                 :            : 
     358                 :            :   // check multispecies
     359         [ +  + ]:        173 :   if (lua_ideck["multispecies"].valid()) {
     360                 :            : 
     361 [ +  - ][ +  - ]:         18 :     checkBlock< inciter::ctr::multispeciesList::Keys >(lua_ideck["multispecies"],
         [ -  + ][ -  - ]
     362                 :            :       "multispecies");
     363                 :            : 
     364         [ +  - ]:          6 :     gideck.get< tag::pde >() = inciter::ctr::PDEType::MULTISPECIES;
     365 [ +  - ][ +  - ]:         18 :     storeIfSpecd< std::size_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     366                 :            :       lua_ideck["multispecies"], "nspec",
     367                 :            :       gideck.get< tag::multispecies, tag::nspec >(), 1);
     368 [ +  - ][ +  - ]:         18 :     storeOptIfSpecd< inciter::ctr::ProblemType, inciter::ctr::Problem >(
         [ -  + ][ +  - ]
                 [ -  - ]
     369                 :            :       lua_ideck["multispecies"], "problem",
     370                 :            :       gideck.get< tag::multispecies, tag::problem >(),
     371                 :            :       inciter::ctr::ProblemType::USER_DEFINED);
     372 [ +  - ][ +  - ]:         18 :     storeOptIfSpecd< inciter::ctr::PhysicsType, inciter::ctr::Physics >(
         [ -  + ][ -  - ]
     373                 :            :       lua_ideck["multispecies"], "physics",
     374                 :            :       gideck.get< tag::multispecies, tag::physics >(),
     375                 :            :       inciter::ctr::PhysicsType::EULER);
     376         [ +  - ]:          6 :     gideck.get< tag::depvar >()[0] = 'a';
     377 [ +  - ][ +  - ]:         18 :     storeOptIfSpecd< inciter::ctr::FluxType, inciter::ctr::Flux >(
         [ -  + ][ -  - ]
     378                 :            :       lua_ideck, "flux", gideck.get< tag::flux >(),
     379                 :            :       inciter::ctr::FluxType::AUSM);
     380                 :            : 
     381                 :            :     // store number of equations in PDE system
     382                 :            :     // nspec: species mass conservation equations,
     383                 :            :     // 3: momentum equations,
     384                 :            :     // 1: total energy equation.
     385                 :          6 :     gideck.get< tag::ncomp >() =
     386                 :          6 :       gideck.get< tag::multispecies, tag::nspec >() + 3 + 1;
     387                 :            :   }
     388                 :            : 
     389                 :            :   // number of species, for future use
     390                 :            :   std::size_t nspec(1);
     391         [ +  + ]:        173 :   if (gideck.get< tag::pde >() == inciter::ctr::PDEType::MULTISPECIES)
     392                 :          6 :     nspec = gideck.get< tag::multispecies, tag::nspec >();
     393                 :            : 
     394                 :            :   // add depvar to deck::depvars so it can be selected as outvar later
     395                 :        173 :   tk::grm::depvars.insert( gideck.get< tag::depvar >()[0] );
     396                 :            : 
     397                 :            :   // Assemble material blocks
     398                 :            :   // ---------------------------------------------------------------------------
     399                 :            : 
     400                 :            :   // solid counters
     401                 :            :   std::size_t tmat(0), imatcntr(0), mtypei(0), isolcntr(0);
     402                 :            :   bool is_solid(false);
     403                 :            :   std::set< std::size_t > matidset;
     404                 :            : 
     405                 :            :   // material vector
     406 [ +  - ][ +  + ]:        173 :   if (lua_ideck["material"].valid()) {
     407                 :            : 
     408                 :            :     // size material map vectors
     409                 :            :     std::size_t nmat(1);
     410         [ +  + ]:        156 :     if (gideck.get< tag::pde >() == inciter::ctr::PDEType::MULTIMAT)
     411                 :         36 :       nmat = gideck.get< tag::multimat, tag::nmat >();
     412         [ +  - ]:        156 :     gideck.get< tag::matidxmap, tag::eosidx >().resize(nmat);
     413         [ +  - ]:        156 :     gideck.get< tag::matidxmap, tag::matidx >().resize(nmat);
     414         [ +  - ]:        156 :     gideck.get< tag::matidxmap, tag::solidx >().resize(nmat);
     415                 :            : 
     416                 :            :     // size material vector appropriately
     417                 :            :     // size of the material vector is the number of distinct types of materials
     418                 :            :     sol::table sol_mat = lua_ideck["material"];
     419 [ +  - ][ +  - ]:        156 :     gideck.get< tag::material >().resize(sol_mat.size());
     420                 :            :     // species vector size is one, since all species are only of one type for now
     421         [ +  - ]:        156 :     gideck.get< tag::species >().resize(1);
     422                 :            : 
     423                 :            :     // store material properties
     424         [ +  + ]:        312 :     for (std::size_t i=0; i<gideck.get< tag::material >().size(); ++i) {
     425                 :            : 
     426 [ +  - ][ +  - ]:        468 :       checkBlock< inciter::ctr::materialList::Keys >(sol_mat[i+1], "material");
         [ +  - ][ -  + ]
                 [ -  - ]
     427                 :            : 
     428         [ +  - ]:        156 :       auto& mati_deck = gideck.get< tag::material >()[i];
     429                 :            :       // eos
     430 [ +  - ][ +  - ]:        468 :       storeOptIfSpecd< inciter::ctr::MaterialType, inciter::ctr::Material >(
         [ -  + ][ -  - ]
     431                 :            :         sol_mat[i+1], "eos", mati_deck.get< tag::eos >(),
     432                 :            :         inciter::ctr::MaterialType::STIFFENEDGAS);
     433                 :            : 
     434                 :            :       // material ids in this eos (default is for compflow i.e. single mat)
     435 [ +  - ][ +  - ]:        468 :       storeVecIfSpecd< uint64_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     436                 :            :         sol_mat[i+1], "id", mati_deck.get< tag::id >(),
     437         [ +  - ]:        156 :         std::vector< uint64_t >(1,1));
     438                 :            : 
     439                 :            :       // Track total number of materials in multiple material blocks (eos's)
     440                 :        156 :       tmat += mati_deck.get< tag::id >().size();
     441                 :            : 
     442                 :            :       // Check for repeating user specified material ids
     443         [ +  + ]:        368 :       for (auto midx : mati_deck.get< tag::id >()) {
     444                 :            :         if (!matidset.count(midx))
     445                 :            :           matidset.insert(midx);
     446                 :            :         else
     447 [ -  - ][ -  - ]:          0 :           Throw("Repeating material id specified");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     448                 :            :       }
     449                 :            : 
     450         [ +  - ]:        156 :       std::size_t ntype = mati_deck.get< tag::id >().size();
     451                 :            :       // cv
     452 [ +  - ][ +  + ]:        156 :       if (!sol_mat[i+1]["cv"].valid())
     453 [ +  - ][ -  + ]:        258 :         sol_mat[i+1]["cv"] = std::vector< tk::real >(ntype, 717.5);
                 [ -  - ]
     454 [ +  - ][ +  - ]:        468 :       checkStoreMatProp(sol_mat[i+1], "cv", ntype, mati_deck.get< tag::cv >());
         [ -  + ][ -  - ]
     455                 :            : 
     456                 :            :       // reset solid-marker
     457                 :            :       is_solid = false;
     458                 :            : 
     459                 :            :       // Stiffened-gas materials
     460         [ +  + ]:        156 :       if (mati_deck.get< tag::eos >() ==
     461                 :            :         inciter::ctr::MaterialType::STIFFENEDGAS) {
     462                 :            :         // gamma
     463 [ +  - ][ +  - ]:        450 :         checkStoreMatProp(sol_mat[i+1], "gamma", ntype,
         [ -  + ][ +  - ]
                 [ -  - ]
     464                 :            :           mati_deck.get< tag::gamma >());
     465                 :            : 
     466                 :            :         // pstiff
     467 [ +  - ][ +  + ]:        150 :         if (!sol_mat[i+1]["pstiff"].valid())
     468 [ +  - ][ -  + ]:        292 :           sol_mat[i+1]["pstiff"] = std::vector< tk::real >(ntype, 0.0);
                 [ -  - ]
     469 [ +  - ][ +  - ]:        450 :         checkStoreMatProp(sol_mat[i+1], "pstiff", ntype,
         [ -  + ][ +  - ]
                 [ -  - ]
     470                 :            :           mati_deck.get< tag::pstiff >());
     471                 :            : 
     472                 :            :         // mu (dynamic viscosity) and 'viscous' keyword
     473 [ +  - ][ +  - ]:        150 :         if (!sol_mat[i+1]["mu"].valid())
     474 [ +  - ][ -  + ]:        300 :           sol_mat[i+1]["mu"] = std::vector< tk::real >(ntype, 0.0);
                 [ -  - ]
     475                 :          0 :         else gideck.get< tag::multimat, tag::viscous >() = true;
     476 [ +  - ][ +  - ]:        450 :         checkStoreMatProp(sol_mat[i+1], "mu", ntype, mati_deck.get< tag::mu >());
         [ -  + ][ -  - ]
     477                 :            :       }
     478                 :            :       // Small-shear solid materials
     479         [ -  + ]:          6 :       else if (mati_deck.get< tag::eos >() ==
     480                 :            :         inciter::ctr::MaterialType::SMALLSHEARSOLID) {
     481                 :            :         // gamma
     482 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "gamma", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     483                 :            :           mati_deck.get< tag::gamma >());
     484                 :            : 
     485                 :            :         // pstiff
     486 [ -  - ][ -  - ]:          0 :         if (!sol_mat[i+1]["pstiff"].valid())
     487 [ -  - ][ -  - ]:          0 :           sol_mat[i+1]["pstiff"] = std::vector< tk::real >(ntype, 0.0);
                 [ -  - ]
     488 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "pstiff", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     489                 :            :           mati_deck.get< tag::pstiff >());
     490                 :            : 
     491                 :            :         // mu
     492 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "mu", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     493                 :            :           mati_deck.get< tag::mu >());
     494                 :            : 
     495                 :            :         // plasticity_reltime
     496 [ -  - ][ -  - ]:          0 :         if (!sol_mat[i+1]["plasticity_reltime"].valid())
     497                 :            :           sol_mat[i+1]["plasticity_reltime"] =
     498 [ -  - ][ -  - ]:          0 :             std::vector< tk::real >(ntype, 1.0e-05);
                 [ -  - ]
     499 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "plasticity_reltime", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     500                 :            :           mati_deck.get< tag::plasticity_reltime >());
     501                 :            : 
     502                 :            :         // yield_stress
     503 [ -  - ][ -  - ]:          0 :         if (!sol_mat[i+1]["yield_stress"].valid())
     504                 :            :           sol_mat[i+1]["yield_stress"] =
     505 [ -  - ][ -  - ]:          0 :             std::vector< tk::real >(ntype, 300.0e+06);
                 [ -  - ]
     506 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "yield_stress", ntype,
         [ -  - ][ -  - ]
     507                 :            :           mati_deck.get< tag::yield_stress >());
     508                 :            : 
     509                 :            :         // assign solid
     510                 :            :         is_solid = true;
     511                 :            :       }
     512                 :            :       // Wilkins aluminum materials
     513         [ -  + ]:          6 :       else if (mati_deck.get< tag::eos >() ==
     514                 :            :         inciter::ctr::MaterialType::WILKINSALUMINUM) {
     515                 :            :         // gamma
     516 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "gamma", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     517                 :            :           mati_deck.get< tag::gamma >());
     518                 :            : 
     519                 :            :         // mu
     520 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "mu", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     521                 :            :           mati_deck.get< tag::mu >());
     522                 :            : 
     523                 :            :         // plasticity_reltime
     524 [ -  - ][ -  - ]:          0 :         if (!sol_mat[i+1]["plasticity_reltime"].valid())
     525                 :            :           sol_mat[i+1]["plasticity_reltime"] =
     526 [ -  - ][ -  - ]:          0 :             std::vector< tk::real >(ntype, 1.0e-07);
                 [ -  - ]
     527 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "plasticity_reltime", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     528                 :            :           mati_deck.get< tag::plasticity_reltime >());
     529                 :            : 
     530                 :            :         // yield_stress
     531 [ -  - ][ -  - ]:          0 :         if (!sol_mat[i+1]["yield_stress"].valid())
     532                 :            :           sol_mat[i+1]["yield_stress"] =
     533 [ -  - ][ -  - ]:          0 :             std::vector< tk::real >(ntype, 300.0e+06);
                 [ -  - ]
     534 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "yield_stress", ntype,
         [ -  - ][ -  - ]
     535                 :            :           mati_deck.get< tag::yield_stress >());
     536                 :            : 
     537                 :            :         // assign solid
     538                 :            :         is_solid = true;
     539                 :            :       }
     540                 :            :       // Godunov-Romenski materials
     541         [ -  + ]:          6 :       else if (mati_deck.get< tag::eos >() ==
     542                 :            :         inciter::ctr::MaterialType::GODUNOVROMENSKI) {
     543                 :            :         // gamma
     544 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "gamma", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     545                 :            :           mati_deck.get< tag::gamma >());
     546                 :            : 
     547                 :            :         // mu
     548 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "mu", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     549                 :            :           mati_deck.get< tag::mu >());
     550                 :            : 
     551                 :            :         // rho0_jwl
     552 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "rho0_jwl", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     553                 :            :           mati_deck.get< tag::rho0_jwl >());
     554                 :            : 
     555                 :            :         // alpha
     556 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "alpha", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     557                 :            :           mati_deck.get< tag::alpha >());
     558                 :            : 
     559                 :            :         // K0
     560 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "K0", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     561                 :            :           mati_deck.get< tag::K0 >());
     562                 :            : 
     563                 :            :         // plasticity_reltime
     564 [ -  - ][ -  - ]:          0 :         if (!sol_mat[i+1]["plasticity_reltime"].valid())
     565                 :            :           sol_mat[i+1]["plasticity_reltime"] =
     566 [ -  - ][ -  - ]:          0 :             std::vector< tk::real >(ntype, 1.0e-07);
                 [ -  - ]
     567 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "plasticity_reltime", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     568                 :            :           mati_deck.get< tag::plasticity_reltime >());
     569                 :            : 
     570                 :            :         // yield_stress
     571 [ -  - ][ -  - ]:          0 :         if (!sol_mat[i+1]["yield_stress"].valid())
     572                 :            :           sol_mat[i+1]["yield_stress"] =
     573 [ -  - ][ -  - ]:          0 :             std::vector< tk::real >(ntype, 300.0e+06);
                 [ -  - ]
     574 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "yield_stress", ntype,
         [ -  - ][ -  - ]
     575                 :            :           mati_deck.get< tag::yield_stress >());
     576                 :            : 
     577                 :            :         // assign solid
     578                 :            :         is_solid = true;
     579                 :            :       }
     580                 :            :       // JWL materials
     581         [ -  + ]:          6 :       else if (mati_deck.get< tag::eos >() == inciter::ctr::MaterialType::JWL) {
     582                 :            :         // w_gru
     583 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "w_gru", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     584                 :            :           mati_deck.get< tag::w_gru >());
     585                 :            : 
     586                 :            :         // a_jwl
     587 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "A_jwl", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     588                 :            :           mati_deck.get< tag::A_jwl >());
     589                 :            : 
     590                 :            :         // b_jwl
     591 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "B_jwl", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     592                 :            :           mati_deck.get< tag::B_jwl >());
     593                 :            : 
     594                 :            :         // R1_jwl
     595 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "R1_jwl", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     596                 :            :           mati_deck.get< tag::R1_jwl >());
     597                 :            : 
     598                 :            :         // R2_jwl
     599 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "R2_jwl", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     600                 :            :           mati_deck.get< tag::R2_jwl >());
     601                 :            : 
     602                 :            :         // rho0_jwl
     603 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "rho0_jwl", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     604                 :            :           mati_deck.get< tag::rho0_jwl >());
     605                 :            : 
     606                 :            :         // de_jwl
     607 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "de_jwl", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     608                 :            :           mati_deck.get< tag::de_jwl >());
     609                 :            : 
     610                 :            :         // Pr_jwl
     611 [ -  - ][ -  - ]:          0 :         checkStoreMatProp(sol_mat[i+1], "Pr_jwl", ntype,
         [ -  - ][ -  - ]
                 [ -  - ]
     612                 :            :           mati_deck.get< tag::Pr_jwl >());
     613                 :            : 
     614                 :            :         // rhor_jwl
     615 [ -  - ][ -  - ]:          0 :         if (sol_mat[i+1]["rhor_jwl"].valid()) {
     616 [ -  - ][ -  - ]:          0 :           checkStoreMatProp(sol_mat[i+1], "rhor_jwl", ntype,
         [ -  - ][ -  - ]
     617                 :            :             mati_deck.get< tag::rhor_jwl >());
     618                 :            :         }
     619                 :            :         // Tr_jwl
     620 [ -  - ][ -  - ]:          0 :         else if (sol_mat[i+1]["Tr_jwl"].valid()) {
     621 [ -  - ][ -  - ]:          0 :           checkStoreMatProp(sol_mat[i+1], "Tr_jwl", ntype,
         [ -  - ][ -  - ]
     622                 :            :             mati_deck.get< tag::Tr_jwl >());
     623                 :            :         }
     624                 :            :         else
     625 [ -  - ][ -  - ]:          0 :           Throw("Either reference density or reference temperature must be "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     626                 :            :             "specified for JWL equation of state (EOS).");
     627                 :            :       }
     628                 :            :       // Thermally-perfect gas materials
     629         [ +  - ]:          6 :       else if (mati_deck.get< tag::eos >() ==
     630                 :            :         inciter::ctr::MaterialType::THERMALLYPERFECTGAS) {
     631                 :            : 
     632 [ +  - ][ -  + ]:          6 :         if (!lua_ideck["species"].valid())
                 [ -  - ]
     633 [ -  - ][ -  - ]:          0 :           Throw("Species block must be specified for thermally perfect gas");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     634                 :            :         sol::table sol_spc = lua_ideck["species"];
     635                 :            : 
     636                 :            :         // We have assumed that nmat == 1 always for multi species, and that
     637                 :            :         // all species are of a single type, so that the outer species vector
     638                 :            :         // is of size one
     639                 :          6 :         auto& spci_deck = gideck.get< tag::species >()[0];
     640                 :            : 
     641                 :            :         // species ids (default is for single species)
     642 [ +  - ][ +  - ]:         18 :         storeVecIfSpecd< uint64_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     643                 :            :           sol_spc[i+1], "id", spci_deck.get< tag::id >(),
     644 [ +  - ][ +  - ]:         12 :           std::vector< uint64_t >(1,1));
                 [ -  - ]
     645                 :            : 
     646                 :            :         Assert(nspec == spci_deck.get< tag::id >().size(),
     647                 :            :           "Number of ids in species-block not equal to number of species");
     648                 :            : 
     649                 :            :         // R
     650 [ +  - ][ +  - ]:         18 :         checkStoreMatProp(sol_spc[i+1], "R", nspec,
         [ -  + ][ +  - ]
                 [ -  - ]
     651                 :            :           spci_deck.get< tag::R >());
     652                 :            :         // cp_coeff
     653 [ +  - ][ +  - ]:         18 :         checkStoreMatPropVecVec(sol_spc[i+1], "cp_coeff", nspec, 3, 8,
         [ -  + ][ +  - ]
                 [ -  - ]
     654                 :            :           spci_deck.get< tag::cp_coeff >());
     655                 :            :         // t_range
     656 [ +  - ][ +  - ]:         18 :         checkStoreMatPropVec(sol_spc[i+1], "t_range", nspec, 4,
         [ -  + ][ +  - ]
                 [ -  - ]
     657                 :            :           spci_deck.get< tag::t_range >());
     658                 :            :         // dH_ref
     659 [ +  - ][ +  - ]:         18 :         checkStoreMatProp(sol_spc[i+1], "dH_ref", nspec,
         [ -  + ][ +  - ]
                 [ -  - ]
     660                 :            :           spci_deck.get< tag::dH_ref >());
     661                 :            :       }
     662                 :            : 
     663                 :            :       // Generate mapping between material index and eos parameter index
     664                 :            :       auto& eosmap = gideck.get< tag::matidxmap, tag::eosidx >();
     665                 :            :       auto& idxmap = gideck.get< tag::matidxmap, tag::matidx >();
     666                 :            :       auto& solidxmap = gideck.get< tag::matidxmap, tag::solidx >();
     667         [ +  + ]:        368 :       for (auto midx : mati_deck.get< tag::id >()) {
     668                 :        212 :         midx -= 1;
     669         [ -  + ]:        212 :         eosmap[midx] = mtypei;
     670                 :        212 :         idxmap[midx] = imatcntr;
     671         [ -  + ]:        212 :         if (is_solid) {
     672                 :            :           // add to solid-counter
     673                 :          0 :           ++isolcntr;
     674                 :          0 :           solidxmap[midx] = isolcntr;
     675                 :            :         }
     676                 :        212 :         ++imatcntr;
     677                 :            :       }
     678                 :            :       // end of materials for this eos, thus reset index counter
     679                 :            :       imatcntr = 0;
     680                 :            :       // increment material-type/eos-type index counter
     681                 :            :       ++mtypei;
     682                 :            :     }
     683                 :            : 
     684                 :            :     // Error checking on material ids
     685                 :            :     // -------------------------------------------------------------------------
     686                 :            : 
     687                 :            :     // Total number of materials
     688         [ -  + ]:        156 :     if (tmat != nmat) 
     689 [ -  - ][ -  - ]:          0 :       Throw("The total number of materials in all the material blocks (" +
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     690                 :            :         std::to_string(tmat) +
     691                 :            :         ") is not equal to the number of materials specified 'nmat'.");
     692                 :            : 
     693                 :            :     // Contiguous and 1-based material ids
     694         [ -  + ]:        156 :     if (*matidset.begin() != 1)
     695 [ -  - ][ -  - ]:          0 :       Throw("Material ids specified in material blocks not one-based. "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     696                 :            :         "Material ids must begin with one.");
     697                 :            :     std::size_t icount(1);
     698         [ +  + ]:        368 :     for (auto midx : matidset) {
     699         [ -  + ]:        212 :       if (midx != icount)
     700 [ -  - ][ -  - ]:          0 :         Throw("Material ids specified in material blocks have a gap. "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     701                 :            :           "Material ids must be contiguous.");
     702                 :        212 :       ++icount;
     703                 :            :     }
     704                 :            : 
     705                 :            :     // Set up number of PDEs for multimat
     706         [ +  + ]:        156 :     if (gideck.get< tag::pde >() == inciter::ctr::PDEType::MULTIMAT) {
     707                 :         36 :       auto ntot = nmat + nmat + 3 + nmat;
     708                 :            :       // if solid EOS, add components
     709                 :            :       const auto& solidx = gideck.get< tag::matidxmap, tag::solidx >();
     710         [ +  + ]:        128 :       for (std::size_t i=0; i<solidx.size(); ++i) {
     711         [ -  + ]:         92 :         if (solidx[i] > 0)
     712                 :          0 :           ntot += 9;
     713                 :            :       }
     714                 :         36 :       gideck.get< tag::ncomp >() = ntot;
     715                 :            :     }
     716                 :            :   }
     717                 :            : 
     718                 :            :   // Mesh specification block (for overset)
     719                 :            :   // ---------------------------------------------------------------------------
     720 [ +  - ][ +  + ]:        173 :   if (lua_ideck["mesh"].valid()) {
     721                 :            :     const sol::table& lua_mesh = lua_ideck["mesh"];
     722                 :            :     auto& mesh_deck = gideck.get< tag::mesh >();
     723 [ +  - ][ +  - ]:         11 :     mesh_deck.resize(lua_mesh.size());
     724                 :            : 
     725         [ +  + ]:         23 :     for (std::size_t i=0; i<mesh_deck.size(); ++i) {
     726                 :            : 
     727 [ +  - ][ +  - ]:         36 :       checkBlock< inciter::ctr::meshList::Keys >(lua_mesh[i+1], "mesh");
         [ +  - ][ -  + ]
                 [ -  - ]
     728                 :            : 
     729                 :            :       // filename
     730 [ +  - ][ +  - ]:         48 :       storeIfSpecd< std::string >(lua_mesh[i+1], "filename",
         [ +  - ][ -  + ]
         [ -  + ][ -  - ]
     731         [ +  - ]:         12 :         mesh_deck[i].get< tag::filename >(), "");
     732                 :            : 
     733                 :            :       // location
     734 [ +  - ][ +  - ]:         48 :       storeVecIfSpecd< tk::real >(lua_mesh[i+1], "location",
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
     735         [ +  - ]:         12 :         mesh_deck[i].get< tag::location >(), {0.0, 0.0, 0.0});
     736         [ -  + ]:         12 :       if (mesh_deck[i].get< tag::location >().size() != 3)
     737 [ -  - ][ -  - ]:          0 :         Throw("Mesh location requires 3 coordinates.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     738                 :            : 
     739                 :            :       // orientation
     740 [ +  - ][ +  - ]:         48 :       storeVecIfSpecd< tk::real >(lua_mesh[i+1], "orientation",
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
     741         [ +  - ]:         12 :         mesh_deck[i].get< tag::orientation >(), {0.0, 0.0, 0.0});
     742         [ -  + ]:         12 :       if (mesh_deck[i].get< tag::orientation >().size() != 3)
     743 [ -  - ][ -  - ]:          0 :         Throw("Mesh orientation requires 3 rotation angles.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     744                 :            : 
     745                 :            :       // mass
     746 [ +  - ][ +  - ]:         36 :       storeIfSpecd< tk::real >(lua_mesh[i+1], "mass",
         [ +  - ][ -  + ]
                 [ -  - ]
     747                 :            :         mesh_deck[i].get< tag::mass >(), 0.0);
     748                 :            : 
     749                 :            :       // moment of inertia. this is currently only configured for planar motion
     750 [ +  - ][ +  - ]:         36 :       storeIfSpecd< tk::real >(lua_mesh[i+1], "moment_of_inertia",
         [ +  - ][ -  - ]
     751         [ +  - ]:         12 :         mesh_deck[i].get< tag::moment_of_inertia >(), 0.0);
     752                 :            : 
     753                 :            :       // center of mass
     754 [ +  - ][ +  - ]:         48 :       storeVecIfSpecd< tk::real >(lua_mesh[i+1], "center_of_mass",
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
     755         [ +  - ]:         12 :         mesh_deck[i].get< tag::center_of_mass >(), {0.0, 0.0, 0.0});
     756         [ -  + ]:         12 :       if (mesh_deck[i].get< tag::center_of_mass >().size() != 3)
     757 [ -  - ][ -  - ]:          0 :         Throw("Mesh center of mass requires 3 coordinates.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     758                 :            : 
     759                 :            :       // Transfer object
     760         [ +  + ]:         12 :       if (i > 0) {
     761 [ +  - ][ -  - ]:          1 :         gideck.get< tag::transfer >().emplace_back( 0, i );
     762                 :            : 
     763                 :            :         // assign depvar
     764                 :          1 :         ++depvar_cnt;
     765         [ +  - ]:          1 :         gideck.get< tag::depvar >().push_back(depvar_cnt);
     766                 :            : 
     767                 :            :         // add depvar to deck::depvars so it can be selected as outvar later
     768                 :            :         tk::grm::depvars.insert(depvar_cnt);
     769                 :            :       }
     770                 :            :     }
     771                 :            :   }
     772                 :            :   else {
     773                 :            :     // TODO: remove double-specification of defaults
     774                 :            :     auto& mesh_deck = gideck.get< tag::mesh >();
     775         [ +  - ]:        162 :     mesh_deck.resize(1);
     776         [ +  - ]:        162 :     mesh_deck[0].get< tag::filename >() =
     777                 :            :       gideck.get< tag::cmd, tag::io, tag::input >();
     778         [ +  - ]:        162 :     mesh_deck[0].get< tag::location >() = {0.0, 0.0, 0.0};
     779         [ +  - ]:        162 :     mesh_deck[0].get< tag::orientation >() = {0.0, 0.0, 0.0};
     780                 :        162 :     mesh_deck[0].get< tag::mass >() = 0.0;
     781                 :        162 :     mesh_deck[0].get< tag::moment_of_inertia >() = 0.0;
     782         [ +  - ]:        162 :     mesh_deck[0].get< tag::center_of_mass >() = {0.0, 0.0, 0.0};
     783                 :            :   }
     784                 :            : 
     785                 :            :   Assert(gideck.get< tag::mesh >().size() == gideck.get< tag::depvar >().size(),
     786                 :            :     "Number of depvar not equal to the number of meshes.");
     787                 :            : 
     788                 :            :   // Rigid body motion block for overset meshes
     789                 :            :   // ---------------------------------------------------------------------------
     790 [ +  - ][ -  + ]:        173 :   if (lua_ideck["rigid_body_motion"].valid()) {
     791                 :            : 
     792                 :            :     Assert(gideck.get< tag::mesh >().size() > 1,
     793                 :            :       "Multiple meshes (overset) needed for rigid body motion.");
     794                 :            : 
     795                 :            :     // check that rigid body mass is provided
     796         [ -  - ]:          0 :     const auto mesh_deck = gideck.get< tag::mesh >();
     797         [ -  - ]:          0 :     for (std::size_t i=1; i<mesh_deck.size(); ++i) {
     798                 :            :       Assert(mesh_deck[i].get< tag::mass >() > 1e-10,
     799                 :            :         "Mass of body required for overset meshes with rigid body motion.");
     800                 :            :     }
     801                 :            : 
     802                 :            :     auto& rbm_deck = gideck.get< tag::rigid_body_motion >();
     803                 :            : 
     804         [ -  - ]:          0 :     rbm_deck.get< tag::rigid_body_movt >() = true;
     805                 :            : 
     806                 :            :     // degrees of freedom
     807 [ -  - ][ -  - ]:          0 :     storeIfSpecd< std::size_t >(
         [ -  - ][ -  - ]
     808                 :            :       lua_ideck["rigid_body_motion"], "rigid_body_dof",
     809                 :            :       rbm_deck.get< tag::rigid_body_dof >(), 3);
     810 [ -  - ][ -  - ]:          0 :     if (rbm_deck.get< tag::rigid_body_dof >() != 3 &&
     811                 :            :       rbm_deck.get< tag::rigid_body_dof >() != 6)
     812 [ -  - ][ -  - ]:          0 :       Throw("Only 3 or 6 rigid body DOFs supported.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     813                 :            : 
     814                 :            :     // symmetry plane
     815 [ -  - ][ -  - ]:          0 :     storeIfSpecd< std::size_t >(
         [ -  - ][ -  - ]
     816                 :            :       lua_ideck["rigid_body_motion"], "symmetry_plane",
     817                 :            :       rbm_deck.get< tag::symmetry_plane >(), 0);
     818         [ -  - ]:          0 :     if (rbm_deck.get< tag::symmetry_plane >() > 3)
     819 [ -  - ][ -  - ]:          0 :       Throw("Rigid body motion symmetry plane must be 1(x), 2(y), or 3(z).");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     820         [ -  - ]:          0 :     if (rbm_deck.get< tag::symmetry_plane >() == 0 &&
     821         [ -  - ]:          0 :       rbm_deck.get< tag::rigid_body_dof >() == 3)
     822 [ -  - ][ -  - ]:          0 :       Throw(
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     823                 :            :         "Rigid body motion symmetry plane must be specified for 3 DOF motion.");
     824                 :            :     // reset to 0-based indexing
     825                 :          0 :     rbm_deck.get< tag::symmetry_plane >() -= 1;
     826                 :            :   }
     827                 :            :   else {
     828                 :            :     // TODO: remove double-specification of defaults
     829                 :            :     auto& rbm_deck = gideck.get< tag::rigid_body_motion >();
     830                 :        173 :     rbm_deck.get< tag::rigid_body_movt >() = false;
     831                 :        173 :     rbm_deck.get< tag::rigid_body_dof >() = 0;
     832                 :        173 :     rbm_deck.get< tag::symmetry_plane >() = 0;
     833                 :            :   }
     834                 :            : 
     835                 :            :   // Field output block
     836                 :            :   // ---------------------------------------------------------------------------
     837 [ +  - ][ +  - ]:        173 :   if (lua_ideck["field_output"].valid()) {
     838                 :            : 
     839 [ +  - ][ +  - ]:        519 :     checkBlock< inciter::ctr::fieldOutputList::Keys >(lua_ideck["field_output"],
         [ -  + ][ +  - ]
                 [ -  - ]
     840                 :            :       "field_output");
     841                 :            : 
     842                 :            :     auto& fo_deck = gideck.get< tag::field_output >();
     843                 :            : 
     844                 :            :     // interval iteration
     845 [ +  - ][ +  - ]:        519 :     storeIfSpecd< uint32_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     846                 :            :       lua_ideck["field_output"], "interval",
     847                 :            :       fo_deck.get< tag::interval >(),
     848                 :            :       std::numeric_limits< uint32_t >::max());
     849                 :            : 
     850                 :            :     // interval physical time
     851 [ +  - ][ +  - ]:        519 :     storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     852                 :            :       lua_ideck["field_output"], "time_interval",
     853                 :            :       fo_deck.get< tag::time_interval >(),
     854                 :            :       std::numeric_limits< tk::real >::max());
     855                 :            : 
     856                 :            :     // interval time range
     857 [ +  - ][ +  - ]:        519 :     storeVecIfSpecd< tk::real >(
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
     858                 :            :       lua_ideck["field_output"], "time_range",
     859                 :            :       fo_deck.get< tag::time_range >(), {});
     860                 :            : 
     861                 :            :     // refined mesh field output
     862 [ +  - ][ +  - ]:        519 :     storeIfSpecd< bool >(
         [ -  + ][ -  - ]
     863                 :            :       lua_ideck["field_output"], "refined", fo_deck.get< tag::refined >(),
     864                 :            :       false);
     865         [ +  - ]:        173 :     gideck.get< tag::cmd, tag::io, tag::refined >() = fo_deck.get< tag::refined >();
     866                 :            : 
     867                 :            :     // filetype
     868 [ +  - ][ +  - ]:        519 :     storeOptIfSpecd< tk::ctr::FieldFileType, tk::ctr::FieldFile >(
         [ -  + ][ +  - ]
                 [ -  - ]
     869                 :            :       lua_ideck["field_output"], "filetype", fo_deck.get< tag::filetype >(),
     870                 :            :       tk::ctr::FieldFileType::EXODUSII);
     871                 :            : 
     872                 :            :     // sidesets for field output
     873 [ +  - ][ +  - ]:        519 :     storeVecIfSpecd< uint64_t >(
         [ -  + ][ -  + ]
         [ +  + ][ -  - ]
     874                 :            :       lua_ideck["field_output"], "sideset", fo_deck.get< tag::sideset >(), {});
     875                 :            : 
     876                 :            :     // Assign outvar
     877                 :            :     auto& foutvar = fo_deck.get< tag::outvar >();
     878                 :            :     std::size_t nevar(0), nnvar(0), tensorcompvar(0);
     879                 :            :     std::size_t nmat(1);
     880         [ +  + ]:        173 :     if (gideck.get< tag::pde >() == inciter::ctr::PDEType::MULTIMAT)
     881                 :         36 :       nmat = gideck.get< tag::multimat, tag::nmat >();
     882                 :            : 
     883 [ +  - ][ +  + ]:        173 :     if (lua_ideck["field_output"]["elemvar"].valid())
     884         [ +  - ]:        158 :       nevar = sol::table(lua_ideck["field_output"]["elemvar"]).size();
     885                 :            : 
     886 [ +  - ][ +  + ]:        173 :     if (lua_ideck["field_output"]["nodevar"].valid())
     887         [ +  - ]:         60 :       nnvar = sol::table(lua_ideck["field_output"]["nodevar"]).size();
     888                 :            : 
     889                 :            :     // element variables
     890 [ +  - ][ +  + ]:        173 :     if (lua_ideck["field_output"]["elemvar"].valid()) {
     891         [ +  + ]:        477 :       for (std::size_t i=0; i<nevar; ++i) {
     892         [ +  - ]:        796 :         std::string varname(lua_ideck["field_output"]["elemvar"][i+1]);
     893                 :            :         // add extra outvars for tensor components
     894                 :            :         if (varname.find("_tensor") != std::string::npos) tensorcompvar += 8;
     895         [ +  - ]:        398 :         addOutVar(varname, gideck.get< tag::depvar >(), nmat,
     896                 :            :           nspec, gideck.get< tag::pde >(), tk::Centering::ELEM, foutvar);
     897                 :            :       }
     898                 :            :     }
     899                 :            : 
     900                 :            :     // node variables
     901 [ +  - ][ +  + ]:        173 :     if (lua_ideck["field_output"]["nodevar"].valid()) {
     902         [ +  + ]:        220 :       for (std::size_t i=0; i<nnvar; ++i) {
     903         [ +  - ]:        380 :         std::string varname(lua_ideck["field_output"]["nodevar"][i+1]);
     904                 :            :         // add extra outvars for tensor components
     905                 :            :         if (varname.find("_tensor") != std::string::npos) tensorcompvar += 8;
     906         [ +  - ]:        190 :         addOutVar(varname, gideck.get< tag::depvar >(), nmat,
     907                 :            :           nspec, gideck.get< tag::pde >(), tk::Centering::NODE, foutvar);
     908                 :            :       }
     909                 :            :     }
     910                 :            : 
     911                 :            :     Assert(foutvar.size() == (nevar + nnvar + tensorcompvar),
     912                 :            :       "Incorrectly sized outvar vector.");
     913                 :            :   }
     914                 :            :   else {
     915                 :            :     // TODO: remove double-specification of defaults
     916                 :            :     auto& fo_deck = gideck.get< tag::field_output >();
     917                 :          0 :     fo_deck.get< tag::interval >() =
     918                 :            :       std::numeric_limits< uint32_t >::max();
     919         [ -  - ]:          0 :     fo_deck.get< tag::time_interval >() =
     920                 :            :       std::numeric_limits< tk::real >::max();
     921                 :            :     fo_deck.get< tag::time_range >() = {};
     922                 :          0 :     fo_deck.get< tag::refined >() = false;
     923         [ -  - ]:          0 :     fo_deck.get< tag::filetype >() = tk::ctr::FieldFileType::EXODUSII;
     924                 :            :     fo_deck.get< tag::sideset >() = {};
     925                 :            :   }
     926                 :            : 
     927                 :            :   // Diagnostics output block
     928                 :            :   // ---------------------------------------------------------------------------
     929 [ +  - ][ +  + ]:        173 :   if (lua_ideck["diagnostics"].valid()) {
     930                 :            : 
     931 [ +  - ][ +  - ]:        261 :     checkBlock< inciter::ctr::diagnosticsList::Keys >(lua_ideck["diagnostics"],
         [ -  + ][ +  - ]
                 [ -  - ]
     932                 :            :       "diagnostics");
     933                 :            : 
     934                 :            :     auto& diag_deck = gideck.get< tag::diagnostics >();
     935                 :            : 
     936                 :            :     // interval iteration
     937 [ +  - ][ +  - ]:        261 :     storeIfSpecd< uint32_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     938                 :            :       lua_ideck["diagnostics"], "interval",
     939                 :            :       diag_deck.get< tag::interval >(), 1);
     940                 :            : 
     941                 :            :     // error norm
     942 [ +  - ][ +  - ]:        261 :     storeOptIfSpecd< tk::ctr::ErrorType, tk::ctr::Error >(
         [ -  + ][ +  - ]
                 [ -  - ]
     943                 :            :       lua_ideck["diagnostics"], "error", diag_deck.get< tag::error >(),
     944                 :            :       tk::ctr::ErrorType::L2);
     945                 :            : 
     946                 :            :     // float format
     947 [ +  - ][ +  - ]:        261 :     storeOptIfSpecd< tk::ctr::TxtFloatFormatType, tk::ctr::TxtFloatFormat >(
         [ -  + ][ -  - ]
     948                 :            :       lua_ideck["diagnostics"], "format", diag_deck.get< tag::format >(),
     949                 :            :       tk::ctr::TxtFloatFormatType::DEFAULT);
     950                 :            : 
     951                 :            :     // precision
     952 [ +  - ][ +  - ]:        261 :     storeIfSpecd< std::streamsize >(
         [ -  + ][ -  - ]
     953                 :            :       lua_ideck["diagnostics"], "precision",
     954                 :            :       diag_deck.get< tag::precision >(), std::cout.precision());
     955                 :            :   }
     956                 :            :   else {
     957                 :            :     // TODO: remove double-specification of defaults
     958                 :            :     auto& diag_deck = gideck.get< tag::diagnostics >();
     959                 :         86 :     diag_deck.get< tag::interval >() = 1;
     960                 :         86 :     diag_deck.get< tag::error >() = tk::ctr::ErrorType::L2;
     961                 :         86 :     diag_deck.get< tag::format >() = tk::ctr::TxtFloatFormatType::DEFAULT;
     962                 :         86 :     diag_deck.get< tag::precision >() = std::cout.precision();
     963                 :            :   }
     964                 :            : 
     965                 :            :   // History output block
     966                 :            :   // ---------------------------------------------------------------------------
     967 [ +  - ][ +  + ]:        173 :   if (lua_ideck["history_output"].valid()) {
     968                 :            : 
     969 [ +  - ][ +  - ]:         12 :     checkBlock< inciter::ctr::historyOutputList::Keys >(
         [ -  + ][ +  - ]
                 [ -  - ]
     970                 :            :       lua_ideck["history_output"], "history_output");
     971                 :            : 
     972                 :            :     auto& hist_deck = gideck.get< tag::history_output >();
     973                 :            : 
     974                 :            :     // interval iteration
     975 [ +  - ][ +  - ]:         12 :     storeIfSpecd< uint32_t >(
         [ -  + ][ +  - ]
                 [ -  - ]
     976                 :            :       lua_ideck["history_output"], "interval",
     977                 :            :       hist_deck.get< tag::interval >(),
     978                 :            :       std::numeric_limits< uint32_t >::max());
     979                 :            : 
     980                 :            :     // interval time
     981 [ +  - ][ +  - ]:         12 :     storeIfSpecd< tk::real >(
         [ -  + ][ +  - ]
                 [ -  - ]
     982                 :            :       lua_ideck["history_output"], "time_interval",
     983                 :            :       hist_deck.get< tag::time_interval >(),
     984                 :            :       std::numeric_limits< tk::real >::max());
     985                 :            : 
     986                 :            :     // interval time range
     987 [ +  - ][ +  - ]:         12 :     storeVecIfSpecd< tk::real >(
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
     988                 :            :       lua_ideck["history_output"], "time_range",
     989                 :            :       hist_deck.get< tag::time_range >(), {});
     990                 :            : 
     991                 :            :     // point probes
     992 [ +  - ][ +  - ]:          4 :     if (lua_ideck["history_output"]["point"].valid()) {
     993                 :            :       const sol::table& sol_pt = lua_ideck["history_output"]["point"];
     994 [ +  - ][ +  - ]:          4 :       hist_deck.get< tag::point >().resize(sol_pt.size());
     995                 :            : 
     996         [ +  + ]:         12 :       for (std::size_t i=0; i<hist_deck.get< tag::point >().size(); ++i) {
     997                 :            :         auto& pti = hist_deck.get< tag::point >()[i];
     998 [ +  - ][ +  - ]:         24 :         storeIfSpecd< std::string >(
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
                 [ -  - ]
     999         [ +  - ]:          8 :           sol_pt[i+1], "id", pti.get< tag::id >(), "p");
    1000 [ +  - ][ +  - ]:         24 :         storeVecIfSpecd< tk::real >(
         [ -  + ][ -  + ]
         [ -  - ][ -  - ]
    1001                 :            :           sol_pt[i+1], "coord", pti.get< tag::coord >(), {});
    1002                 :            :       }
    1003                 :            :     }
    1004                 :            : 
    1005                 :            :     // float format
    1006 [ +  - ][ +  - ]:         12 :     storeOptIfSpecd< tk::ctr::TxtFloatFormatType, tk::ctr::TxtFloatFormat >(
         [ -  + ][ -  - ]
    1007                 :            :       lua_ideck["history_output"], "format", hist_deck.get< tag::format >(),
    1008                 :            :       tk::ctr::TxtFloatFormatType::DEFAULT);
    1009                 :            : 
    1010                 :            :     // precision
    1011 [ +  - ][ +  - ]:         12 :     storeIfSpecd< std::streamsize >(
         [ -  + ][ -  - ]
    1012                 :            :       lua_ideck["history_output"], "precision",
    1013                 :            :       hist_deck.get< tag::precision >(), std::cout.precision());
    1014                 :            : 
    1015                 :            :     // error check point
    1016         [ +  + ]:         12 :     for (std::size_t i=0; i<hist_deck.get< tag::point >().size(); ++i) {
    1017         [ -  + ]:          8 :       if (hist_deck.get< tag::point >()[i].get< tag::coord >().size() != 3)
    1018 [ -  - ][ -  - ]:          0 :       Throw("Three reals required for point coordinates in history_output.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1019                 :            :     }
    1020                 :            :   }
    1021                 :            :   else {
    1022                 :            :     // TODO: remove double-specification of defaults
    1023                 :            :     auto& hist_deck = gideck.get< tag::history_output >();
    1024                 :        169 :     hist_deck.get< tag::interval >() =
    1025                 :            :       std::numeric_limits< uint32_t >::max();
    1026         [ +  - ]:        169 :     hist_deck.get< tag::time_interval >() =
    1027                 :            :       std::numeric_limits< tk::real >::max();
    1028                 :            :     hist_deck.get< tag::time_range >() = {};
    1029         [ +  - ]:        169 :     hist_deck.get< tag::precision >() = std::cout.precision();
    1030         [ +  - ]:        169 :     hist_deck.get< tag::point >().resize(0);
    1031                 :            :   }
    1032                 :            : 
    1033                 :            :   // ALE block
    1034                 :            :   // ---------------------------------------------------------------------------
    1035         [ +  - ]:        173 :   gideck.get< tag::ale, tag::ale >() = false;
    1036 [ +  - ][ +  + ]:        173 :   if (lua_ideck["ale"].valid()) {
    1037                 :            :     auto& ale_deck = gideck.get< tag::ale >();
    1038         [ +  - ]:         10 :     ale_deck.get< tag::ale >() = true;
    1039                 :            : 
    1040                 :            :     // Mesh velocity smoother
    1041                 :            :     storeOptIfSpecd< inciter::ctr::MeshVelocitySmootherType,
    1042 [ +  - ][ +  - ]:         30 :       inciter::ctr::MeshVelocitySmoother >(lua_ideck["ale"], "smoother",
         [ -  + ][ +  - ]
                 [ -  - ]
    1043                 :            :       ale_deck.get< tag::smoother >(), inciter::ctr::MeshVelocitySmootherType::NONE);
    1044                 :            : 
    1045                 :            :     // Mesh velocity
    1046                 :            :     storeOptIfSpecd< inciter::ctr::MeshVelocityType,
    1047 [ +  - ][ +  - ]:         30 :       inciter::ctr::MeshVelocity >(lua_ideck["ale"], "mesh_velocity",
         [ -  + ][ -  - ]
    1048                 :            :       ale_deck.get< tag::mesh_velocity >(), inciter::ctr::MeshVelocityType::SINE);
    1049                 :            : 
    1050                 :            :     // Mesh motion direction
    1051 [ +  - ][ +  - ]:         30 :     storeVecIfSpecd< std::size_t >(lua_ideck["ale"], "mesh_motion",
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
    1052                 :            :       ale_deck.get< tag::mesh_motion >(), { 0, 1, 2 });
    1053                 :            : 
    1054                 :            :     // Mesh force
    1055 [ +  - ][ +  - ]:         40 :     storeVecIfSpecd< tk::real >(lua_ideck["ale"], "meshforce",
         [ +  - ][ -  + ]
         [ +  - ][ +  - ]
                 [ -  - ]
    1056                 :            :       ale_deck.get< tag::meshforce >(), { 0, 0, 0, 0 });
    1057                 :            : 
    1058                 :            :     // Dirichlet
    1059 [ +  - ][ +  - ]:         30 :     storeVecIfSpecd< std::size_t >(lua_ideck["ale"], "dirichlet",
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
    1060                 :            :       ale_deck.get< tag::dirichlet >(), {});
    1061                 :            : 
    1062                 :            :     // Symmetry
    1063 [ +  - ][ +  - ]:         30 :     storeVecIfSpecd< std::size_t >(lua_ideck["ale"], "symmetry",
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
    1064                 :            :       ale_deck.get< tag::symmetry >(), {});
    1065                 :            : 
    1066                 :            :     // Move sidesets with user defined function
    1067 [ +  - ][ +  + ]:         10 :     if (lua_ideck["ale"]["move"].valid()) {
    1068                 :            :       const sol::table& sol_mv = lua_ideck["ale"]["move"];
    1069 [ +  - ][ +  - ]:          2 :       ale_deck.get< tag::move >().resize(sol_mv.size());
    1070                 :            : 
    1071         [ +  + ]:          4 :       for (std::size_t i=0; i<ale_deck.get< tag::move >().size(); ++i) {
    1072                 :            :         auto& mvi = ale_deck.get< tag::move >()[i];
    1073 [ +  - ][ +  - ]:          6 :         storeOptIfSpecd< tk::ctr::UserTableType, tk::ctr::UserTable >(
         [ -  + ][ +  - ]
                 [ -  - ]
    1074         [ +  - ]:          2 :           sol_mv[i+1], "fntype", mvi.get< tag::fntype >(),
    1075                 :            :           tk::ctr::UserTableType::POSITION);
    1076 [ +  - ][ +  - ]:          6 :         storeVecIfSpecd< uint64_t >(
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
    1077                 :            :           sol_mv[i+1], "sideset", mvi.get< tag::sideset >(), {});
    1078 [ +  - ][ +  - ]:          6 :         storeVecIfSpecd< tk::real >(
         [ -  + ][ -  + ]
         [ -  - ][ -  - ]
    1079                 :            :           sol_mv[i+1], "fn", mvi.get< tag::fn >(), {});
    1080                 :            : 
    1081                 :            :         // error checking on user-def function
    1082         [ +  - ]:          2 :         if (mvi.get< tag::fn >().size() % 4 != 0)
    1083 [ -  - ][ -  - ]:          0 :           Throw("Incomplete user-defined function for ALE sideset movement. An "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1084                 :            :           "R->R^3 function is expected, the number of descrete entries must be "
    1085                 :            :           "divisible by 4: one 'column' for the abscissa, and 3 for the "
    1086                 :            :           "ordinate.");
    1087                 :            :       }
    1088                 :            :     }
    1089                 :            : 
    1090                 :            :     // dv-CFL
    1091 [ +  - ][ +  - ]:         30 :     storeIfSpecd< tk::real >(lua_ideck["ale"], "dvcfl", ale_deck.get< tag::dvcfl >(),
         [ -  + ][ +  - ]
                 [ -  - ]
    1092                 :            :       0.01);
    1093                 :            : 
    1094                 :            :     // Vorticity multiplier
    1095 [ +  - ][ +  - ]:         30 :     storeIfSpecd< tk::real >(lua_ideck["ale"], "vortmult",
         [ -  + ][ +  - ]
                 [ -  - ]
    1096                 :            :       ale_deck.get< tag::vortmult >(), 0.0);
    1097                 :            : 
    1098                 :            :     // Mesh velocity max iterations
    1099 [ +  - ][ +  - ]:         30 :     storeIfSpecd< std::size_t >(lua_ideck["ale"], "maxit",
         [ -  + ][ +  - ]
                 [ -  - ]
    1100                 :            :       ale_deck.get< tag::maxit >(), 5);
    1101                 :            : 
    1102                 :            :     // Mesh velocity max iterations
    1103 [ +  - ][ +  - ]:         30 :     storeIfSpecd< tk::real >(lua_ideck["ale"], "tolerance",
         [ -  + ][ -  - ]
    1104                 :            :       ale_deck.get< tag::tolerance >(), 1e-2);
    1105                 :            :   }
    1106                 :            : 
    1107                 :            :   // AMR block
    1108                 :            :   // ---------------------------------------------------------------------------
    1109                 :        173 :   gideck.get< tag::amr, tag::amr >() = false;
    1110         [ +  - ]:        173 :   gideck.get< tag::amr, tag::maxlevels >() = 2; // this is needed for outref
    1111 [ +  - ][ +  + ]:        173 :   if (lua_ideck["amr"].valid()) {
    1112                 :            :     auto& amr_deck = gideck.get< tag::amr >();
    1113         [ +  - ]:         20 :     amr_deck.get< tag::amr >() = true;
    1114                 :            : 
    1115                 :            :     // Initial refinement toggle
    1116 [ +  - ][ +  - ]:         60 :     storeIfSpecd< bool >(lua_ideck["amr"], "t0ref", amr_deck.get< tag::t0ref >(),
         [ -  + ][ +  - ]
                 [ -  - ]
    1117                 :            :       false);
    1118                 :            : 
    1119                 :            :     // Mesh refinement during time-stepping toggle
    1120 [ +  - ][ +  - ]:         60 :     storeIfSpecd< bool >(lua_ideck["amr"], "dtref", amr_deck.get< tag::dtref >(),
         [ -  + ][ +  - ]
                 [ -  - ]
    1121                 :            :       false);
    1122                 :            : 
    1123                 :            :     // Uniform mesh refinement during time-stepping toggle
    1124 [ +  - ][ +  - ]:         60 :     storeIfSpecd< bool >(lua_ideck["amr"], "dtref_uniform",
         [ -  + ][ +  - ]
                 [ -  - ]
    1125                 :            :       amr_deck.get< tag::dtref_uniform >(), false);
    1126                 :            : 
    1127                 :            :     // Mesh refinement frequency during time-stepping toggle
    1128 [ +  - ][ +  - ]:         60 :     storeIfSpecd< std::size_t >(lua_ideck["amr"], "dtfreq",
         [ -  + ][ +  - ]
                 [ -  - ]
    1129                 :            :       amr_deck.get< tag::dtfreq >(), 3);
    1130                 :            : 
    1131                 :            :     // Maximum AMR levels
    1132 [ +  - ][ +  - ]:         60 :     storeIfSpecd< std::size_t >(lua_ideck["amr"], "maxlevels",
         [ -  + ][ +  - ]
                 [ -  - ]
    1133                 :            :       amr_deck.get< tag::maxlevels >(), 2);
    1134                 :            : 
    1135                 :            :     // Initial AMR steps
    1136 [ +  - ][ +  - ]:         60 :     storeOptVecIfSpecd< inciter::ctr::AMRInitialType, inciter::ctr::AMRInitial >(
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
    1137                 :            :       lua_ideck["amr"], "initial", amr_deck.get< tag::initial >(), {});
    1138                 :            : 
    1139                 :            :     // Initial AMR coordinate based
    1140 [ +  - ][ +  + ]:         20 :     if (lua_ideck["amr"]["coords"].valid()) {
    1141                 :            :       auto rmax = std::numeric_limits< tk::real >::max() / 100;
    1142                 :            : 
    1143 [ +  - ][ +  - ]:          3 :       storeIfSpecd< tk::real >(lua_ideck["amr"]["coords"], "xminus",
         [ -  + ][ +  - ]
                 [ -  - ]
    1144                 :            :         amr_deck.get< tag::coords, tag::xminus >(), rmax);
    1145 [ +  - ][ +  - ]:          3 :       storeIfSpecd< tk::real >(lua_ideck["amr"]["coords"], "xplus",
         [ -  + ][ +  - ]
                 [ -  - ]
    1146                 :            :         amr_deck.get< tag::coords, tag::xplus >(), -rmax);
    1147                 :            : 
    1148 [ +  - ][ +  - ]:          3 :       storeIfSpecd< tk::real >(lua_ideck["amr"]["coords"], "yminus",
         [ -  + ][ +  - ]
                 [ -  - ]
    1149                 :            :         amr_deck.get< tag::coords, tag::yminus >(), rmax);
    1150 [ +  - ][ +  - ]:          3 :       storeIfSpecd< tk::real >(lua_ideck["amr"]["coords"], "yplus",
         [ -  + ][ +  - ]
                 [ -  - ]
    1151                 :            :         amr_deck.get< tag::coords, tag::yplus >(), -rmax);
    1152                 :            : 
    1153 [ +  - ][ +  - ]:          3 :       storeIfSpecd< tk::real >(lua_ideck["amr"]["coords"], "zminus",
         [ -  + ][ +  - ]
                 [ -  - ]
    1154                 :            :         amr_deck.get< tag::coords, tag::zminus >(), rmax);
    1155 [ +  - ][ +  - ]:          3 :       storeIfSpecd< tk::real >(lua_ideck["amr"]["coords"], "zplus",
         [ -  + ][ -  - ]
    1156                 :            :         amr_deck.get< tag::coords, tag::zplus >(), -rmax);
    1157                 :            :     }
    1158                 :            : 
    1159                 :            :     // Initial AMR edgelist based
    1160 [ +  - ][ +  - ]:         60 :     storeVecIfSpecd< std::size_t >(lua_ideck["amr"], "edgelist",
         [ -  + ][ -  + ]
                 [ -  - ]
    1161                 :            :       amr_deck.get< tag::edgelist >(), {});
    1162         [ -  + ]:         20 :     if (amr_deck.get< tag::edgelist >().size() % 2 != 0)
    1163 [ -  - ][ -  - ]:          0 :       Throw("The number of edge-nodes, marking edges as pairs of nodes, used "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1164                 :            :         "for explicit tagging of edges for initial mesh refineoment, is odd "
    1165                 :            :         "(it must be even).");
    1166                 :            : 
    1167                 :            :     // Error type for AMR
    1168 [ +  - ][ +  - ]:         60 :     storeOptIfSpecd< inciter::ctr::AMRErrorType, inciter::ctr::AMRError >(
         [ -  + ][ +  - ]
                 [ -  - ]
    1169                 :            :       lua_ideck["amr"], "error", amr_deck.get< tag::error >(),
    1170                 :            :       inciter::ctr::AMRErrorType::JUMP);
    1171                 :            : 
    1172                 :            :     // Tolerances for refine/de-refine
    1173 [ +  - ][ +  - ]:         60 :     storeIfSpecd< tk::real >(lua_ideck["amr"], "tol_refine",
         [ -  + ][ +  - ]
                 [ -  - ]
    1174                 :            :       amr_deck.get< tag::tol_refine >(), 0.2);
    1175 [ +  - ][ +  - ]:         60 :     storeIfSpecd< tk::real >(lua_ideck["amr"], "tol_derefine",
         [ -  + ][ -  - ]
    1176                 :            :       amr_deck.get< tag::tol_derefine >(), 0.05);
    1177                 :            :   }
    1178                 :            : 
    1179                 :            :   // p-refinement block
    1180                 :            :   // ---------------------------------------------------------------------------
    1181         [ +  - ]:        173 :   gideck.get< tag::pref, tag::pref >() = false;
    1182 [ +  - ][ +  + ]:        173 :   if (lua_ideck["pref"].valid()) {
    1183                 :            :     auto& pref_deck = gideck.get< tag::pref >();
    1184         [ +  - ]:         12 :     pref_deck.get< tag::pref >() = true;
    1185                 :            : 
    1186                 :            :     // p-ref indicator type
    1187                 :            :     storeOptIfSpecd< inciter::ctr::PrefIndicatorType,
    1188 [ +  - ][ +  - ]:         36 :       inciter::ctr::PrefIndicator >(lua_ideck["pref"], "indicator",
         [ -  + ][ +  - ]
                 [ -  - ]
    1189                 :            :       pref_deck.get< tag::indicator >(),
    1190                 :            :       inciter::ctr::PrefIndicatorType::SPECTRAL_DECAY);
    1191                 :            : 
    1192                 :            :     // p-ref max degrees-of-freedom per cell
    1193 [ +  - ][ +  - ]:         36 :     storeIfSpecd< std::size_t >(lua_ideck["pref"], "ndofmax",
         [ -  + ][ +  - ]
                 [ -  - ]
    1194                 :            :       pref_deck.get< tag::ndofmax >(), 10);
    1195                 :            : 
    1196                 :            :     // p-ref tolerance
    1197 [ +  - ][ +  - ]:         36 :     storeIfSpecd< tk::real >(lua_ideck["pref"], "tolref",
         [ -  + ][ -  - ]
    1198                 :            :       pref_deck.get< tag::tolref >(), 0.5);
    1199                 :            : 
    1200                 :            :     // error checking on the tolerance
    1201 [ +  - ][ -  + ]:         12 :     if (pref_deck.get< tag::tolref >() < 0.0 || pref_deck.get< tag::tolref >() > 1.0)
    1202 [ -  - ][ -  - ]:          0 :       Throw("The p-refinement tolerance must be a real number "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1203                 :            :         "between 0.0 and 1.0, both inclusive.");
    1204                 :            :   }
    1205                 :            : 
    1206                 :            :   // Boundary conditions block
    1207                 :            :   // ---------------------------------------------------------------------------
    1208 [ +  - ][ +  + ]:        173 :   if (lua_ideck["bc"].valid()) {
    1209                 :            :     std::set< std::size_t > totalmesh;
    1210                 :            :     const sol::table& sol_bc = lua_ideck["bc"];
    1211                 :            :     auto& bc_deck = gideck.get< tag::bc >();
    1212 [ +  - ][ +  - ]:        163 :     bc_deck.resize(sol_bc.size());
    1213                 :            : 
    1214         [ +  + ]:        327 :     for (std::size_t i=0; i<bc_deck.size(); ++i) {
    1215                 :            : 
    1216 [ +  - ][ +  - ]:        492 :       checkBlock< inciter::ctr::bcList::Keys >(sol_bc[i+1], "bc");
         [ +  - ][ -  + ]
                 [ -  - ]
    1217                 :            : 
    1218 [ +  - ][ +  - ]:        492 :       storeVecIfSpecd< std::size_t >(sol_bc[i+1], "mesh",
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
    1219         [ +  - ]:        164 :         bc_deck[i].get< tag::mesh >(), {1});
    1220                 :            :       // collect meshes for error checking
    1221                 :            :       totalmesh.insert(bc_deck[i].get< tag::mesh >().begin(),
    1222                 :        164 :         bc_deck[i].get< tag::mesh >().end());
    1223                 :            : 
    1224 [ +  - ][ +  - ]:        492 :       storeVecIfSpecd< uint64_t >(sol_bc[i+1], "dirichlet",
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
    1225         [ +  - ]:        164 :         bc_deck[i].get< tag::dirichlet >(), {});
    1226                 :            : 
    1227 [ +  - ][ +  - ]:        492 :       storeVecIfSpecd< uint64_t >(sol_bc[i+1], "symmetry",
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
    1228         [ +  - ]:        164 :         bc_deck[i].get< tag::symmetry >(), {});
    1229                 :            : 
    1230 [ +  - ][ +  + ]:        164 :       if (sol_bc[i+1]["inlet"].valid()) {
    1231                 :          7 :         const sol::table& sol_inbc = sol_bc[i+1]["inlet"];
    1232         [ +  - ]:          7 :         auto& inbc_deck = bc_deck[i].get< tag::inlet >();
    1233 [ +  - ][ +  - ]:          7 :         inbc_deck.resize(sol_inbc.size());
    1234                 :            : 
    1235         [ +  + ]:         14 :         for (std::size_t j=0; j<inbc_deck.size(); ++j) {
    1236 [ +  - ][ +  - ]:         21 :           storeVecIfSpecd< uint64_t >(sol_inbc[j+1], "sideset",
         [ +  - ][ -  + ]
         [ -  + ][ -  - ]
    1237                 :            :             inbc_deck[j].get< tag::sideset >(), {});
    1238                 :            : 
    1239 [ +  - ][ +  - ]:         21 :           storeVecIfSpecd< tk::real >(sol_inbc[j+1], "velocity",
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
                 [ -  - ]
    1240         [ +  - ]:          7 :             inbc_deck[j].get< tag::velocity >(), {0.0, 0.0, 0.0});
    1241         [ -  + ]:          7 :           if (inbc_deck[j].get< tag::velocity >().size() != 3)
    1242 [ -  - ][ -  - ]:          0 :             Throw("Inlet velocity requires 3 components.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1243                 :            : 
    1244 [ +  - ][ +  - ]:         21 :           storeIfSpecd< tk::real >(sol_inbc[j+1], "pressure",
         [ -  + ][ -  - ]
    1245                 :            :             inbc_deck[j].get< tag::pressure >(), 0.0);
    1246                 :            : 
    1247 [ +  - ][ +  - ]:         21 :           storeIfSpecd< tk::real >(sol_inbc[j+1], "temperature",
         [ -  + ][ -  - ]
    1248         [ +  - ]:          7 :             inbc_deck[j].get< tag::temperature >(), 0.0);
    1249                 :            : 
    1250 [ +  - ][ +  - ]:         21 :           storeIfSpecd< std::size_t >(sol_inbc[j+1], "materialid",
         [ -  + ][ -  - ]
    1251         [ +  - ]:          7 :             inbc_deck[j].get< tag::materialid >(), 1);
    1252                 :            :         }
    1253                 :            :       }
    1254                 :            : 
    1255 [ +  - ][ +  - ]:        492 :       storeVecIfSpecd< uint64_t >(sol_bc[i+1], "outlet",
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
    1256         [ +  - ]:        164 :         bc_deck[i].get< tag::outlet >(), {});
    1257                 :            : 
    1258 [ +  - ][ +  - ]:        492 :       storeVecIfSpecd< uint64_t >(sol_bc[i+1], "farfield",
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
    1259         [ +  - ]:        164 :         bc_deck[i].get< tag::farfield >(), {});
    1260                 :            : 
    1261 [ +  - ][ +  - ]:        492 :       storeVecIfSpecd< uint64_t >(sol_bc[i+1], "extrapolate",
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
    1262         [ +  - ]:        164 :         bc_deck[i].get< tag::extrapolate >(), {});
    1263                 :            : 
    1264 [ +  - ][ +  - ]:        492 :       storeVecIfSpecd< uint64_t >(sol_bc[i+1], "noslipwall",
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
    1265         [ +  - ]:        164 :         bc_deck[i].get< tag::noslipwall >(), {});
    1266                 :            : 
    1267 [ +  - ][ +  - ]:        492 :       storeVecIfSpecd< uint64_t >(sol_bc[i+1], "slipwall",
         [ -  + ][ -  + ]
         [ +  - ][ -  - ]
    1268         [ +  - ]:        164 :         bc_deck[i].get< tag::slipwall >(), {});
    1269                 :            : 
    1270                 :            :       // Time-dependent BC
    1271 [ +  - ][ +  + ]:        164 :       if (sol_bc[i+1]["timedep"].valid()) {
    1272                 :          2 :         const sol::table& sol_tdbc = sol_bc[i+1]["timedep"];
    1273         [ +  - ]:          2 :         auto& tdbc_deck = bc_deck[i].get< tag::timedep >();
    1274 [ +  - ][ +  - ]:          2 :         tdbc_deck.resize(sol_tdbc.size());
    1275                 :            : 
    1276         [ +  + ]:          4 :         for (std::size_t j=0; j<tdbc_deck.size(); ++j) {
    1277 [ +  - ][ +  - ]:          6 :           storeVecIfSpecd< uint64_t >(sol_tdbc[j+1], "sideset",
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
                 [ -  - ]
    1278                 :            :             tdbc_deck[j].get< tag::sideset >(), {});
    1279 [ +  - ][ +  - ]:          6 :           storeVecIfSpecd< tk::real >(sol_tdbc[j+1], "fn",
         [ -  + ][ -  + ]
         [ -  - ][ -  - ]
    1280         [ +  - ]:          2 :             tdbc_deck[j].get< tag::fn >(), {});
    1281                 :            : 
    1282                 :            :           // error checking on user-def function
    1283         [ +  - ]:          2 :           if (tdbc_deck[j].get< tag::fn >().size() % 6 != 0)
    1284 [ -  - ][ -  - ]:          0 :             Throw("Incomplete user-defined function for time-dependent BC. An "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1285                 :            :             "R->R^5 function is expected, the number of descrete entries must "
    1286                 :            :             "be divisible by 6: one 'column' for the abscissa, and 5 for the "
    1287                 :            :             "ordinate.");
    1288                 :            :         }
    1289                 :            :       }
    1290                 :            : 
    1291                 :            :       // Back pressure BC
    1292 [ +  - ][ -  + ]:        164 :       if (sol_bc[i+1]["back_pressure"].valid()) {
    1293                 :          0 :         const sol::table& sol_bpbc = sol_bc[i+1]["back_pressure"];
    1294         [ -  - ]:          0 :         auto& bpbc_deck = bc_deck[i].get< tag::back_pressure >();
    1295                 :            : 
    1296 [ -  - ][ -  - ]:          0 :         storeVecIfSpecd< uint64_t >(sol_bpbc, "sideset",
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1297                 :            :           bpbc_deck.get< tag::sideset >(), {});
    1298                 :            : 
    1299 [ -  - ][ -  - ]:          0 :         if (!sol_bpbc["pressure"].valid())
                 [ -  - ]
    1300 [ -  - ][ -  - ]:          0 :           Throw("Pressure is required for back pressure BC.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1301                 :            : 
    1302 [ -  - ][ -  - ]:          0 :         storeIfSpecd< tk::real >(sol_bpbc, "pressure",
         [ -  - ][ -  - ]
                 [ -  - ]
    1303                 :            :           bpbc_deck.get< tag::pressure >(), 0.0);
    1304                 :            :       }
    1305                 :            : 
    1306                 :            :       // Velocity for inlet/farfield
    1307 [ +  - ][ +  - ]:        492 :       storeVecIfSpecd< tk::real >(sol_bc[i+1], "velocity",
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
    1308         [ +  - ]:        164 :         bc_deck[i].get< tag::velocity >(), {0.0, 0.0, 0.0});
    1309         [ -  + ]:        164 :       if (bc_deck[i].get< tag::velocity >().size() != 3)
    1310 [ -  - ][ -  - ]:          0 :         Throw("BC velocity requires 3 components.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1311                 :            : 
    1312                 :            :       // Pressure for inlet/outlet/farfield
    1313 [ +  - ][ +  - ]:        492 :       storeIfSpecd< tk::real >(sol_bc[i+1], "pressure",
         [ -  + ][ -  - ]
    1314                 :            :         bc_deck[i].get< tag::pressure >(), 0.0);
    1315                 :            : 
    1316                 :            :       // Density for inlet/outlet/farfield
    1317 [ +  - ][ +  - ]:        492 :       storeIfSpecd< tk::real >(sol_bc[i+1], "density",
         [ -  + ][ -  - ]
    1318         [ +  - ]:        164 :         bc_deck[i].get< tag::density >(), 0.0);
    1319                 :            : 
    1320                 :            :       // Temperature for inlet/outlet/farfield
    1321 [ +  - ][ +  - ]:        492 :       storeIfSpecd< tk::real >(sol_bc[i+1], "temperature",
         [ -  + ][ -  - ]
    1322         [ +  - ]:        164 :         bc_deck[i].get< tag::temperature >(), 0.0);
    1323                 :            : 
    1324                 :            :       // Mass fractions for inlet/farfield
    1325 [ +  - ][ +  - ]:        492 :       storeVecIfSpecd< tk::real >(sol_bc[i+1], "mass_fractions",
         [ -  + ][ +  - ]
                 [ -  - ]
    1326         [ +  - ]:        164 :         bc_deck[i].get< tag::mass_fractions >(),
    1327 [ +  - ][ -  - ]:        164 :         std::vector< tk::real >(nspec, 1.0/static_cast<tk::real>(nspec)));
    1328         [ -  + ]:        164 :       if (bc_deck[i].get< tag::mass_fractions >().size() != nspec)
    1329 [ -  - ][ -  - ]:          0 :         Throw("BC mass fraction has incorrect number of species. "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1330                 :            :           "Expected " + std::to_string(nspec));
    1331                 :            : 
    1332                 :            :       // Material-id for inlet/outlet/farfield
    1333 [ +  - ][ +  - ]:        492 :       storeIfSpecd< std::size_t >(sol_bc[i+1], "materialid",
         [ -  + ][ -  - ]
    1334                 :            :         bc_deck[i].get< tag::materialid >(), 1);
    1335                 :            :     }
    1336                 :            : 
    1337                 :            :     // error checking on number of meshes
    1338         [ -  + ]:        163 :     if (totalmesh.size() != gideck.get< tag::mesh >().size())
    1339 [ -  - ][ -  - ]:          0 :       Throw("Total meshes (" + std::to_string(gideck.get< tag::mesh >().size()) +
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1340                 :            :         ") not equal to the meshes on which BC's are specified (" +
    1341                 :            :         std::to_string(totalmesh.size()));
    1342                 :            : 
    1343                 :            :     // error checking on mesh ids
    1344                 :            :     std::size_t ic(1);
    1345         [ +  + ]:        327 :     for (const auto& im : totalmesh) {
    1346 [ -  + ][ -  - ]:        164 :       if (im != ic) Throw("Non-contiguous mesh ids in BC-mesh");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1347                 :        164 :       ++ic;
    1348                 :            :     }
    1349                 :            :   }
    1350 [ -  + ][ -  - ]:         10 :   else if (gideck.get< tag::scheme >() == inciter::ctr::SchemeType::ALECG ||
    1351                 :            :            gideck.get< tag::scheme >() == inciter::ctr::SchemeType::OversetFE)
    1352         [ +  - ]:         10 :     gideck.get< tag::bc >().resize(1);
    1353                 :            :   // error checking for unspecified BC's
    1354                 :            :   else
    1355 [ -  - ][ -  - ]:          0 :     Throw("No boundary conditions specified in input file.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1356                 :            : 
    1357                 :            :   // Initial condition block
    1358                 :            :   // ---------------------------------------------------------------------------
    1359 [ +  - ][ +  + ]:        173 :   if (lua_ideck["ic"].valid()) {
    1360                 :            :     auto& ic_deck = gideck.get< tag::ic >();
    1361                 :            : 
    1362 [ +  - ][ +  - ]:         93 :     checkBlock< inciter::ctr::icList::Keys >(lua_ideck["ic"], "ic");
         [ -  + ][ +  - ]
                 [ -  - ]
    1363                 :            : 
    1364                 :            :     // background IC values
    1365 [ +  - ][ +  - ]:         93 :     storeIfSpecd< std::size_t >(lua_ideck["ic"], "materialid",
         [ -  + ][ +  - ]
                 [ -  - ]
    1366                 :            :       ic_deck.get< tag::materialid >(), 1);
    1367                 :            : 
    1368 [ +  - ][ +  - ]:         93 :     storeIfSpecd< tk::real >(lua_ideck["ic"], "pressure",
         [ -  + ][ +  - ]
                 [ -  - ]
    1369                 :            :       ic_deck.get< tag::pressure >(), 0.0);
    1370                 :            : 
    1371 [ +  - ][ +  - ]:         93 :     storeIfSpecd< tk::real >(lua_ideck["ic"], "temperature",
         [ -  + ][ -  - ]
    1372                 :            :       ic_deck.get< tag::temperature >(), 0.0);
    1373                 :            : 
    1374 [ +  - ][ +  - ]:         93 :     storeVecIfSpecd< tk::real >(lua_ideck["ic"], "mass_fractions",
         [ -  + ][ +  - ]
                 [ -  - ]
    1375                 :            :       ic_deck.get< tag::mass_fractions >(),
    1376         [ +  - ]:         31 :       std::vector< tk::real >(nspec, 1.0/static_cast<tk::real>(nspec)));
    1377         [ -  + ]:         31 :     if (ic_deck.get< tag::mass_fractions >().size() != nspec)
    1378 [ -  - ][ -  - ]:          0 :       Throw("IC mass fraction has incorrect number of species. "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1379                 :            :         "Expected " + std::to_string(nspec));
    1380                 :            : 
    1381 [ +  - ][ +  - ]:         93 :     storeIfSpecd< tk::real >(lua_ideck["ic"], "density",
         [ -  + ][ +  - ]
                 [ -  - ]
    1382                 :            :       ic_deck.get< tag::density >(), 0.0);
    1383                 :            : 
    1384 [ +  - ][ +  - ]:         93 :     storeIfSpecd< tk::real >(lua_ideck["ic"], "energy",
         [ -  + ][ -  - ]
    1385                 :            :       ic_deck.get< tag::energy >(), 0.0);
    1386                 :            : 
    1387 [ +  - ][ +  - ]:         93 :     storeVecIfSpecd< tk::real >(lua_ideck["ic"], "velocity",
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
    1388                 :            :       ic_deck.get< tag::velocity >(), {0.0, 0.0, 0.0});
    1389         [ -  + ]:         31 :     if (ic_deck.get< tag::velocity >().size() != 3)
    1390 [ -  - ][ -  - ]:          0 :       Throw("Velocity in IC requires 3 components.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1391                 :            : 
    1392                 :            :     // IC box
    1393 [ +  - ][ +  + ]:         31 :     if (lua_ideck["ic"]["box"].valid()) {
    1394                 :            :       const sol::table& lua_box = lua_ideck["ic"]["box"];
    1395                 :            :       auto& box_deck = ic_deck.get< tag::box >();
    1396 [ +  - ][ +  - ]:         24 :       box_deck.resize(lua_box.size());
    1397                 :            : 
    1398         [ +  + ]:         49 :       for (std::size_t i=0; i<box_deck.size(); ++i) {
    1399                 :            : 
    1400 [ +  - ][ +  - ]:         75 :         checkBlock< inciter::ctr::boxList::Keys >(lua_box[i+1], "box");
         [ +  - ][ -  + ]
                 [ -  - ]
    1401                 :            : 
    1402 [ +  - ][ +  - ]:         75 :         storeIfSpecd< std::size_t >(lua_box[i+1], "materialid",
         [ -  + ][ -  - ]
    1403         [ +  - ]:         25 :           box_deck[i].get< tag::materialid >(), 1);
    1404                 :            : 
    1405 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "volume",
         [ -  + ][ -  - ]
    1406         [ +  - ]:         25 :           box_deck[i].get< tag::volume >(), 0.0);
    1407                 :            : 
    1408 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "mass",
         [ -  + ][ -  - ]
    1409         [ +  - ]:         25 :           box_deck[i].get< tag::mass >(), 0.0);
    1410                 :            : 
    1411 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "density",
         [ -  + ][ -  - ]
    1412         [ +  - ]:         25 :           box_deck[i].get< tag::density >(), 0.0);
    1413                 :            : 
    1414 [ +  - ][ +  - ]:         75 :         storeVecIfSpecd< tk::real >(lua_box[i+1], "velocity",
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
    1415         [ +  - ]:         25 :           box_deck[i].get< tag::velocity >(), {0.0, 0.0, 0.0});
    1416         [ -  + ]:         25 :         if (box_deck[i].get< tag::velocity >().size() != 3)
    1417 [ -  - ][ -  - ]:          0 :           Throw("Velocity in IC box requires 3 components.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1418                 :            : 
    1419 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "pressure",
         [ -  + ][ -  - ]
    1420                 :            :           box_deck[i].get< tag::pressure >(), 0.0);
    1421                 :            : 
    1422 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "energy",
         [ -  + ][ -  - ]
    1423         [ +  - ]:         25 :           box_deck[i].get< tag::energy >(), 0.0);
    1424                 :            : 
    1425 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "energy_content",
         [ -  + ][ -  - ]
    1426         [ +  - ]:         25 :           box_deck[i].get< tag::energy_content >(), 0.0);
    1427                 :            : 
    1428 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "temperature",
         [ -  + ][ -  - ]
    1429         [ +  - ]:         25 :           box_deck[i].get< tag::temperature >(), 0.0);
    1430                 :            : 
    1431 [ +  - ][ +  - ]:         75 :         storeVecIfSpecd< tk::real >(lua_box[i+1], "mass_fractions",
         [ -  + ][ +  - ]
                 [ -  - ]
    1432         [ +  - ]:         25 :           box_deck[i].get< tag::mass_fractions >(),
    1433         [ +  - ]:         25 :           std::vector< tk::real >(nspec, 1.0/static_cast<tk::real>(nspec)));
    1434         [ -  + ]:         25 :         if (box_deck[i].get< tag::mass_fractions >().size() != nspec)
    1435 [ -  - ][ -  - ]:          0 :           Throw("IC box mass fraction has incorrect number of species. "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1436                 :            :             "Expected " + std::to_string(nspec));
    1437                 :            : 
    1438 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "xmin",
         [ -  + ][ -  - ]
    1439                 :            :           box_deck[i].get< tag::xmin >(), 0.0);
    1440                 :            : 
    1441 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "xmax",
         [ -  + ][ -  - ]
    1442         [ +  - ]:         25 :           box_deck[i].get< tag::xmax >(), 0.0);
    1443                 :            : 
    1444 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "ymin",
         [ -  + ][ -  - ]
    1445         [ +  - ]:         25 :           box_deck[i].get< tag::ymin >(), 0.0);
    1446                 :            : 
    1447 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "ymax",
         [ -  + ][ -  - ]
    1448         [ +  - ]:         25 :           box_deck[i].get< tag::ymax >(), 0.0);
    1449                 :            : 
    1450 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "zmin",
         [ -  + ][ -  - ]
    1451         [ +  - ]:         25 :           box_deck[i].get< tag::zmin >(), 0.0);
    1452                 :            : 
    1453 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "zmax",
         [ -  + ][ -  - ]
    1454         [ +  - ]:         25 :           box_deck[i].get< tag::zmax >(), 0.0);
    1455                 :            : 
    1456 [ +  - ][ +  - ]:         75 :         storeVecIfSpecd< tk::real >(lua_box[i+1], "orientation",
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
    1457         [ +  - ]:         25 :           box_deck[i].get< tag::orientation >(), {0.0, 0.0, 0.0});
    1458         [ -  + ]:         25 :         if (box_deck[i].get< tag::orientation >().size() != 3)
    1459 [ -  - ][ -  - ]:          0 :           Throw("Orientation in IC box requires 3 rotation angles.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1460                 :            : 
    1461 [ +  - ][ +  - ]:         75 :         storeOptIfSpecd< inciter::ctr::InitiateType, inciter::ctr::Initiate >(
         [ -  + ][ -  - ]
    1462                 :            :           lua_box[i+1], "initiate", box_deck[i].get< tag::initiate >(),
    1463                 :            :           inciter::ctr::InitiateType::IMPULSE);
    1464                 :            : 
    1465 [ +  - ][ +  - ]:         75 :         storeVecIfSpecd< tk::real >(lua_box[i+1], "point",
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
                 [ -  - ]
    1466         [ +  - ]:         25 :           box_deck[i].get< tag::point >(), {0.0, 0.0, 0.0});
    1467         [ -  + ]:         25 :         if (box_deck[i].get< tag::point >().size() != 3)
    1468 [ -  - ][ -  - ]:          0 :           Throw("Point in IC box requires 3 coordinates.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1469                 :            : 
    1470 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "init_time",
         [ -  + ][ -  - ]
    1471                 :            :           box_deck[i].get< tag::init_time >(), 0.0);
    1472                 :            : 
    1473 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "front_width",
         [ -  + ][ -  - ]
    1474         [ +  - ]:         25 :           box_deck[i].get< tag::front_width >(), 0.0);
    1475                 :            : 
    1476 [ +  - ][ +  - ]:         75 :         storeIfSpecd< tk::real >(lua_box[i+1], "front_speed",
         [ -  + ][ -  - ]
    1477         [ +  - ]:         25 :           box_deck[i].get< tag::front_speed >(), 0.0);
    1478                 :            :       }
    1479                 :            :     }
    1480                 :            : 
    1481                 :            :     // IC mesh-block
    1482 [ +  - ][ -  + ]:         31 :     if (lua_ideck["ic"]["meshblock"].valid()) {
    1483                 :            :       const sol::table& lua_meshblock = lua_ideck["ic"]["meshblock"];
    1484                 :            :       auto& mblk_deck = ic_deck.get< tag::meshblock >();
    1485 [ -  - ][ -  - ]:          0 :       mblk_deck.resize(lua_meshblock.size());
    1486                 :            : 
    1487         [ -  - ]:          0 :       for (std::size_t i=0; i<mblk_deck.size(); ++i) {
    1488                 :            : 
    1489 [ -  - ][ -  - ]:          0 :         checkBlock< inciter::ctr::meshblockList::Keys >(lua_meshblock[i+1],
         [ -  - ][ -  - ]
                 [ -  - ]
    1490                 :            :           "meshblock");
    1491                 :            : 
    1492 [ -  - ][ -  - ]:          0 :         storeIfSpecd< std::size_t >(lua_meshblock[i+1], "blockid",
         [ -  - ][ -  - ]
    1493         [ -  - ]:          0 :           mblk_deck[i].get< tag::blockid >(), 0);
    1494         [ -  - ]:          0 :         if (mblk_deck[i].get< tag::blockid >() == 0)
    1495 [ -  - ][ -  - ]:          0 :           Throw("Each IC mesh block must specify the mesh block id.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1496                 :            : 
    1497 [ -  - ][ -  - ]:          0 :         storeIfSpecd< std::size_t >(lua_meshblock[i+1], "materialid",
         [ -  - ][ -  - ]
    1498                 :            :           mblk_deck[i].get< tag::materialid >(), 1);
    1499                 :            : 
    1500 [ -  - ][ -  - ]:          0 :         storeIfSpecd< tk::real >(lua_meshblock[i+1], "energy_content",
         [ -  - ][ -  - ]
    1501         [ -  - ]:          0 :           mblk_deck[i].get< tag::energy_content >(), 0.0);
    1502                 :            : 
    1503 [ -  - ][ -  - ]:          0 :         storeIfSpecd< tk::real >(lua_meshblock[i+1], "volume",
         [ -  - ][ -  - ]
    1504         [ -  - ]:          0 :           mblk_deck[i].get< tag::volume >(), 0.0);
    1505         [ -  - ]:          0 :         if (mblk_deck[i].get< tag::energy_content >() > 0.0 &&
    1506         [ -  - ]:          0 :           mblk_deck[i].get< tag::volume >() < 1e-12)
    1507 [ -  - ][ -  - ]:          0 :           Throw("Mesh block volume must be specified, if energy content is "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1508                 :            :             "used to initialize block");
    1509                 :            : 
    1510 [ -  - ][ -  - ]:          0 :         storeIfSpecd< tk::real >(lua_meshblock[i+1], "mass",
         [ -  - ][ -  - ]
    1511                 :            :           mblk_deck[i].get< tag::mass >(), 0.0);
    1512                 :            : 
    1513 [ -  - ][ -  - ]:          0 :         storeIfSpecd< tk::real >(lua_meshblock[i+1], "density",
         [ -  - ][ -  - ]
    1514         [ -  - ]:          0 :           mblk_deck[i].get< tag::density >(), 0.0);
    1515                 :            : 
    1516 [ -  - ][ -  - ]:          0 :         storeVecIfSpecd< tk::real >(lua_meshblock[i+1], "velocity",
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1517         [ -  - ]:          0 :           mblk_deck[i].get< tag::velocity >(), {0.0, 0.0, 0.0});
    1518         [ -  - ]:          0 :         if (mblk_deck[i].get< tag::velocity >().size() != 3)
    1519 [ -  - ][ -  - ]:          0 :           Throw("Velocity in IC meshblock requires 3 components.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1520                 :            : 
    1521 [ -  - ][ -  - ]:          0 :         storeIfSpecd< tk::real >(lua_meshblock[i+1], "pressure",
         [ -  - ][ -  - ]
    1522                 :            :           mblk_deck[i].get< tag::pressure >(), 0.0);
    1523                 :            : 
    1524 [ -  - ][ -  - ]:          0 :         storeIfSpecd< tk::real >(lua_meshblock[i+1], "energy",
         [ -  - ][ -  - ]
    1525         [ -  - ]:          0 :           mblk_deck[i].get< tag::energy >(), 0.0);
    1526                 :            : 
    1527 [ -  - ][ -  - ]:          0 :         storeIfSpecd< tk::real >(lua_meshblock[i+1], "temperature",
         [ -  - ][ -  - ]
    1528         [ -  - ]:          0 :           mblk_deck[i].get< tag::temperature >(), 0.0);
    1529                 :            : 
    1530 [ -  - ][ -  - ]:          0 :         storeVecIfSpecd< tk::real >(lua_meshblock[i+1], "mass_fractions",
         [ -  - ][ -  - ]
                 [ -  - ]
    1531         [ -  - ]:          0 :           mblk_deck[i].get< tag::mass_fractions >(),
    1532         [ -  - ]:          0 :           std::vector< tk::real >(nspec, 1.0/static_cast<tk::real>(nspec)));
    1533         [ -  - ]:          0 :         if (mblk_deck[i].get< tag::mass_fractions >().size() != nspec)
    1534 [ -  - ][ -  - ]:          0 :           Throw("IC meshblock mass fraction has incorrect number of species. "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1535                 :            :             "Expected " + std::to_string(nspec));
    1536                 :            : 
    1537 [ -  - ][ -  - ]:          0 :         storeOptIfSpecd< inciter::ctr::InitiateType, inciter::ctr::Initiate >(
         [ -  - ][ -  - ]
    1538                 :            :           lua_meshblock[i+1], "initiate", mblk_deck[i].get< tag::initiate >(),
    1539                 :            :           inciter::ctr::InitiateType::IMPULSE);
    1540                 :            : 
    1541 [ -  - ][ -  - ]:          0 :         storeVecIfSpecd< tk::real >(lua_meshblock[i+1], "point",
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1542         [ -  - ]:          0 :           mblk_deck[i].get< tag::point >(), {0.0, 0.0, 0.0});
    1543         [ -  - ]:          0 :         if (mblk_deck[i].get< tag::point >().size() != 3)
    1544 [ -  - ][ -  - ]:          0 :           Throw("Point in IC meshblock requires 3 coordinates.");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1545                 :            : 
    1546 [ -  - ][ -  - ]:          0 :         storeIfSpecd< tk::real >(lua_meshblock[i+1], "init_time",
         [ -  - ][ -  - ]
    1547                 :            :           mblk_deck[i].get< tag::init_time >(), 0.0);
    1548                 :            : 
    1549 [ -  - ][ -  - ]:          0 :         storeIfSpecd< tk::real >(lua_meshblock[i+1], "front_width",
         [ -  - ][ -  - ]
    1550         [ -  - ]:          0 :           mblk_deck[i].get< tag::front_width >(), 0.0);
    1551                 :            : 
    1552 [ -  - ][ -  - ]:          0 :         storeIfSpecd< tk::real >(lua_meshblock[i+1], "front_speed",
         [ -  - ][ -  - ]
    1553         [ -  - ]:          0 :           mblk_deck[i].get< tag::front_speed >(), 0.0);
    1554                 :            :       }
    1555                 :            :     }
    1556                 :            :   }
    1557                 :            :   else {
    1558                 :            :     // TODO: remove double-specification of defaults
    1559                 :            :     auto& ic_deck = gideck.get< tag::ic >();
    1560                 :        142 :     ic_deck.get< tag::materialid >() = 1;
    1561                 :        142 :     ic_deck.get< tag::pressure >() = 0.0;
    1562                 :        142 :     ic_deck.get< tag::temperature >() = 1.0;
    1563                 :        142 :     ic_deck.get< tag::density >() = 0.0;
    1564                 :        142 :     ic_deck.get< tag::energy >() = 0.0;
    1565         [ +  - ]:        142 :     ic_deck.get< tag::velocity >() = {0.0, 0.0, 0.0};
    1566                 :            :     ic_deck.get< tag::mass_fractions >() =
    1567         [ +  - ]:        284 :       std::vector< tk::real >(nspec, 1.0/static_cast<tk::real>(nspec));
    1568                 :            :   }
    1569                 :        173 : }
    1570                 :            : 
    1571                 :            : void
    1572                 :        618 : LuaParser::checkStoreMatProp(
    1573                 :            :   const sol::table table,
    1574                 :            :   const std::string key,
    1575                 :            :   std::size_t vecsize,
    1576                 :            :   std::vector< tk::real >& storage )
    1577                 :            : // *****************************************************************************
    1578                 :            : //  Check and store material property into inpudeck storage
    1579                 :            : //! \param[in] table Sol-table which contains said property
    1580                 :            : //! \param[in] key Key for said property in Sol-table
    1581                 :            : //! \param[in] vecsize Number of said property in Sol-table (based on number of
    1582                 :            : //!   materials that are of the same eos type
    1583                 :            : //! \param[in,out] storage Storage space in inputdeck where said property is
    1584                 :            : //!   to be stored
    1585                 :            : // *****************************************************************************
    1586                 :            : {
    1587                 :            :   // check validity of table
    1588 [ +  - ][ -  + ]:       1236 :   if (!table[key].valid())
    1589 [ -  - ][ -  - ]:          0 :     Throw("Material property '" + key + "' not specified");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1590 [ +  - ][ -  + ]:       1236 :   if (sol::table(table[key]).size() != vecsize)
         [ -  + ][ -  - ]
    1591 [ -  - ][ -  - ]:          0 :     Throw("Incorrect number of '" + key + "'s specified. Expected " +
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1592                 :            :       std::to_string(vecsize));
    1593                 :            : 
    1594                 :            :   // store values from table to inputdeck
    1595 [ +  - ][ -  + ]:       1236 :   storeVecIfSpecd< tk::real >(table, key, storage,
         [ +  - ][ -  - ]
                 [ -  - ]
    1596         [ +  - ]:        618 :     std::vector< tk::real >(vecsize, 0.0));
    1597                 :        618 : }
    1598                 :            : 
    1599                 :            : void
    1600                 :          6 : LuaParser::checkStoreMatPropVec(
    1601                 :            :   const sol::table table,
    1602                 :            :   const std::string key,
    1603                 :            :   std::size_t nspec,
    1604                 :            :   std::size_t vecsize,
    1605                 :            :   std::vector<std::vector< tk::real >>& storage )
    1606                 :            : // *****************************************************************************
    1607                 :            : //  Check and store material property vector into inpudeck storage
    1608                 :            : //! \param[in] table Sol-table which contains said property
    1609                 :            : //! \param[in] key Key for said property in Sol-table
    1610                 :            : //! \param[in] nspec Number of species
    1611                 :            : //! \param[in] vecsize Number of said property in Sol-table (based on number of
    1612                 :            : //!   coefficients for the defined species)
    1613                 :            : //! \param[in,out] storage Storage space in inputdeck where said property is
    1614                 :            : //!   to be stored
    1615                 :            : // *****************************************************************************
    1616                 :            : {
    1617                 :            :   // check validity of table
    1618 [ +  - ][ -  + ]:         12 :   if (!table[key].valid())
    1619 [ -  - ][ -  - ]:          0 :     Throw("Material property '" + key + "' not specified");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1620 [ +  - ][ -  + ]:         12 :   if (sol::table(table[key]).size() != nspec)
         [ -  + ][ -  - ]
    1621 [ -  - ][ -  - ]:          0 :     Throw("Incorrect number of '" + key + "' vectors specified. Expected " +
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1622                 :            :       std::to_string(nspec) + " vectors");
    1623                 :            : 
    1624                 :          6 :   storage.resize(nspec);
    1625                 :            : 
    1626                 :            :   const auto& tableentry = table[key];
    1627         [ +  + ]:         15 :   for (std::size_t k=0; k < nspec; k++) {
    1628 [ +  - ][ +  - ]:         27 :     if (sol::table(tableentry[k+1]).size() != vecsize)
         [ -  + ][ +  - ]
                 [ -  - ]
    1629 [ -  - ][ -  - ]:          0 :       Throw("Incorrect number of '" + key + "' entries in vector of species "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1630                 :            :         + std::to_string(k+1) + " specified. Expected " +
    1631                 :            :         std::to_string(vecsize));
    1632                 :            : 
    1633                 :            :     // store values from table to inputdeck
    1634         [ +  + ]:         45 :     for (std::size_t i=0; i<vecsize; ++i)
    1635 [ +  - ][ +  - ]:         72 :       storage[k].push_back(tableentry[k+1][i+1]);
         [ -  + ][ -  + ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1636                 :            :   }
    1637                 :          6 : }
    1638                 :            : 
    1639                 :            : void
    1640                 :          6 : LuaParser::checkStoreMatPropVecVec(
    1641                 :            :   const sol::table table,
    1642                 :            :   const std::string key,
    1643                 :            :   std::size_t nspec,
    1644                 :            :   std::size_t vecsize1,
    1645                 :            :   std::size_t vecsize2,
    1646                 :            :   std::vector<std::vector<std::vector< tk::real >>>& storage )
    1647                 :            : // *****************************************************************************
    1648                 :            : //  Check and store material property vector into inpudeck storage
    1649                 :            : //! \param[in] table Sol-table which contains said property
    1650                 :            : //! \param[in] key Key for said property in Sol-table
    1651                 :            : //! \param[in] nspec Number of species
    1652                 :            : //! \param[in] vecsize1 Outer number of said property in Sol-table (based on
    1653                 :            : //!   number of coefficients for the defined species)
    1654                 :            : //! \param[in] vecsize2 Inner number of said property in Sol-table (based on
    1655                 :            : //!   number of coefficients for the defined species)
    1656                 :            : //! \param[in,out] storage Storage space in inputdeck where said property is
    1657                 :            : //!   to be stored
    1658                 :            : // *****************************************************************************
    1659                 :            : {
    1660                 :            :   // check validity of table
    1661 [ +  - ][ -  + ]:         12 :   if (!table[key].valid())
    1662 [ -  - ][ -  - ]:          0 :     Throw("Material property '" + key + "' not specified");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1663 [ +  - ][ -  + ]:         12 :   if (sol::table(table[key]).size() != nspec)
         [ -  + ][ -  - ]
    1664 [ -  - ][ -  - ]:          0 :     Throw("Incorrect number of '" + key + "' vectors specified. Expected " +
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1665                 :            :       std::to_string(nspec) + " vectors");
    1666                 :            : 
    1667                 :          6 :   storage.resize(nspec);
    1668                 :            : 
    1669                 :            :   const auto& tableentry = table[key];
    1670         [ +  + ]:         15 :   for (std::size_t k=0; k < nspec; k++) {
    1671 [ +  - ][ +  - ]:         27 :     if (sol::table(tableentry[k+1]).size() != vecsize1)
         [ -  + ][ +  - ]
                 [ -  - ]
    1672 [ -  - ][ -  - ]:          0 :       Throw("Incorrect outer number of '" + key + "' entries in vector of species "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1673                 :            :         + std::to_string(k+1) + " specified. Expected " +
    1674                 :            :         std::to_string(vecsize1));
    1675                 :            : 
    1676                 :            :     // store values from table to inputdeck
    1677         [ +  + ]:         36 :     for (std::size_t i=0; i<vecsize1; ++i) {
    1678 [ +  - ][ +  - ]:         81 :       if (sol::table(tableentry[k+1][i+1]).size() != vecsize2)
         [ -  + ][ -  + ]
         [ -  + ][ -  - ]
         [ -  - ][ -  - ]
    1679 [ -  - ][ -  - ]:          0 :         Throw("Incorrect inner number of '" + key + "' entries in vector of species "
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1680                 :            :           + std::to_string(k+1) + " specified. Expected " +
    1681                 :            :           std::to_string(vecsize2));
    1682                 :            :       std::vector< tk::real > temp_storage;
    1683         [ +  + ]:        243 :       for (std::size_t j=0; j<vecsize2; j++)
    1684 [ +  - ][ +  - ]:        432 :         temp_storage.push_back(tableentry[k+1][i+1][j+1]);
         [ -  + ][ -  + ]
         [ -  + ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1685         [ +  - ]:         27 :       storage[k].push_back(temp_storage);
    1686                 :            :     }
    1687                 :            :   }
    1688                 :          6 : }
    1689                 :            : 
    1690                 :            : void
    1691                 :        588 : LuaParser::addOutVar(
    1692                 :            :   const std::string& varname,
    1693                 :            :   std::vector< char >& depv,
    1694                 :            :   std::size_t nmat,
    1695                 :            :   std::size_t nspec,
    1696                 :            :   inciter::ctr::PDEType pde,
    1697                 :            :   tk::Centering c,
    1698                 :            :   std::vector< inciter::ctr::OutVar >& foutvar )
    1699                 :            : // *****************************************************************************
    1700                 :            : //  Check and store field output variables
    1701                 :            : //! \param[in] varname Name of variable requested
    1702                 :            : //! \param[in] depv List of depvars
    1703                 :            : //! \param[in] nmat Number of materials configured
    1704                 :            : //! \param[in] nspec Number of species configured
    1705                 :            : //! \param[in] pde Type of PDE configured
    1706                 :            : //! \param[in] c Variable centering requested
    1707                 :            : //! \param[in,out] foutvar Input deck storage where output vars are stored
    1708                 :            : // *****************************************************************************
    1709                 :            : {
    1710                 :            :   // index-based quantity specification
    1711                 :            :   // ----------------------------------
    1712         [ +  + ]:        588 :   if (varname.length() == 2) {
    1713                 :         60 :     auto qty = varname.at(0);
    1714 [ +  - ][ -  + ]:        120 :     auto j = std::stoul(std::string{varname.at(1)}) - 1;
    1715                 :            : 
    1716         [ +  + ]:         60 :     if (pde == inciter::ctr::PDEType::MULTIMAT) {
    1717                 :            :     // multimat/matvar quantities
    1718         [ -  + ]:         31 :       if (qty == 'D') {  // density
    1719                 :            :         foutvar.emplace_back(
    1720 [ -  - ][ -  - ]:          0 :           inciter::ctr::OutVar(c, varname, inciter::densityIdx(nmat,j)) );
         [ -  - ][ -  - ]
                 [ -  - ]
    1721                 :            :       }
    1722         [ +  - ]:         31 :       else if (qty == 'F') {  // volume fraction
    1723                 :            :         foutvar.emplace_back(
    1724 [ +  - ][ +  - ]:         31 :           inciter::ctr::OutVar(c, varname, inciter::volfracIdx(nmat,j)) );
         [ +  - ][ -  + ]
                 [ -  - ]
    1725                 :            :       }
    1726         [ -  - ]:          0 :       else if (qty == 'M') {  // momentum
    1727                 :            :         foutvar.emplace_back(
    1728 [ -  - ][ -  - ]:          0 :           inciter::ctr::OutVar(c, varname, inciter::momentumIdx(nmat,j)) );
         [ -  - ][ -  - ]
                 [ -  - ]
    1729                 :            :       }
    1730         [ -  - ]:          0 :       else if (qty == 'E') {  // specific total energy
    1731                 :            :         foutvar.emplace_back(
    1732 [ -  - ][ -  - ]:          0 :           inciter::ctr::OutVar(c, varname, inciter::energyIdx(nmat,j)) );
         [ -  - ][ -  - ]
                 [ -  - ]
    1733                 :            :       }
    1734         [ -  - ]:          0 :       else if (qty == 'U') {  // velocity (primitive)
    1735                 :            :         foutvar.emplace_back(
    1736 [ -  - ][ -  - ]:          0 :           inciter::ctr::OutVar(c, varname, inciter::velocityIdx(nmat,j)) );
         [ -  - ][ -  - ]
                 [ -  - ]
    1737                 :            :       }
    1738         [ -  - ]:          0 :       else if (qty == 'P') {  // material pressure (primitive)
    1739                 :            :         foutvar.emplace_back(
    1740 [ -  - ][ -  - ]:          0 :           inciter::ctr::OutVar(c, varname, inciter::pressureIdx(nmat,j)) );
         [ -  - ][ -  - ]
                 [ -  - ]
    1741                 :            :       }
    1742                 :            :       else {
    1743                 :            :         // error out if incorrect matvar used
    1744 [ -  - ][ -  - ]:          0 :         Throw("field_output: matvar " + varname + " not found");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1745                 :            :       }
    1746                 :            :     }
    1747         [ +  + ]:         29 :     else if (pde == inciter::ctr::PDEType::MULTISPECIES) {
    1748                 :            :     // multispecies/matvar quantities
    1749         [ +  - ]:         12 :       if (qty == 'D') {  // density
    1750                 :            :         foutvar.emplace_back(
    1751 [ +  - ][ +  - ]:         24 :           inciter::ctr::OutVar(c, varname,
         [ -  + ][ -  - ]
    1752         [ +  - ]:         12 :             inciter::multispecies::densityIdx(nspec,j)) );
    1753                 :            :       }
    1754         [ -  - ]:          0 :       else if (qty == 'M') {  // momentum
    1755                 :            :         foutvar.emplace_back(
    1756 [ -  - ][ -  - ]:          0 :           inciter::ctr::OutVar(c, varname,
         [ -  - ][ -  - ]
    1757         [ -  - ]:          0 :             inciter::multispecies::momentumIdx(nspec,j)) );
    1758                 :            :       }
    1759         [ -  - ]:          0 :       else if (qty == 'E') {  // specific total energy
    1760                 :            :         foutvar.emplace_back(
    1761 [ -  - ][ -  - ]:          0 :           inciter::ctr::OutVar(c, varname,
         [ -  - ][ -  - ]
    1762         [ -  - ]:          0 :             inciter::multispecies::energyIdx(nspec,j)) );
    1763                 :            :       }
    1764                 :            :       else {
    1765                 :            :         // error out if incorrect matvar used
    1766 [ -  - ][ -  - ]:          0 :         Throw("field_output: matvar " + varname + " not found");
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1767                 :            :       }
    1768                 :            :     }
    1769                 :            :     else {
    1770                 :            :     // quantities specified by depvar
    1771         [ +  + ]:         44 :       for (const auto& id : depv)
    1772         [ +  + ]:         27 :         if (std::tolower(qty) == id) {
    1773 [ +  - ][ +  - ]:         17 :           foutvar.emplace_back( inciter::ctr::OutVar(c, varname, j) );
         [ +  - ][ -  + ]
                 [ -  - ]
    1774                 :            :         }
    1775                 :            :     }
    1776                 :            :   }
    1777                 :            :   // analytic quantity specification
    1778                 :            :   // -------------------------------
    1779         [ +  + ]:        528 :   else if (varname.find("analytic") != std::string::npos) {
    1780 [ +  - ][ +  - ]:         35 :     foutvar.emplace_back( inciter::ctr::OutVar(c, varname, 0) );
         [ +  - ][ -  + ]
                 [ -  - ]
    1781                 :            :   }
    1782                 :            :   // name-based tensor quantity specification
    1783                 :            :   // ----------------------------------------
    1784         [ -  + ]:        493 :   else if (varname.find("_tensor") != std::string::npos) {
    1785                 :            :     std::string namet(varname);
    1786                 :            :     // remove the "_tensor" from the varname
    1787         [ -  - ]:          0 :     for (std::size_t i=0; i<7; ++i) namet.pop_back();
    1788                 :            : 
    1789         [ -  - ]:          0 :     for (std::size_t i=1; i<=3; ++i) {
    1790         [ -  - ]:          0 :       for (std::size_t j=1; j<=3; ++j) {
    1791 [ -  - ][ -  - ]:          0 :         std::string tij(namet + std::to_string(i) + std::to_string(j));
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
    1792 [ -  - ][ -  - ]:          0 :         foutvar.emplace_back( inciter::ctr::OutVar(c, tij, 0, tij) );
         [ -  - ][ -  - ]
    1793                 :            :       }
    1794                 :            :     }
    1795                 :            :   }
    1796                 :            :   // name-based quantity specification
    1797                 :            :   // ---------------------------------
    1798                 :            :   else {
    1799         [ +  - ]:        493 :     foutvar.emplace_back( inciter::ctr::OutVar(c, varname, 0, varname) );
    1800                 :            :   }
    1801                 :        588 : }

Generated by: LCOV version 1.14