Quinoa all test code coverage report
Current view: top level - Control/Inciter/InputDeck - Grammar.hpp (source / functions) Hit Total Coverage
Commit: Quinoa_v0.3-957-gb4f0efae0 Lines: 437 559 78.2 %
Date: 2021-11-11 18:25:50 Functions: 73 79 92.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 364 912 39.9 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/Control/Inciter/InputDeck/Grammar.hpp
       4                 :            :   \copyright 2012-2015 J. Bakosi,
       5                 :            :              2016-2018 Los Alamos National Security, LLC.,
       6                 :            :              2019-2021 Triad National Security, LLC.
       7                 :            :              All rights reserved. See the LICENSE file for details.
       8                 :            :   \brief     Inciter's input deck grammar definition
       9                 :            :   \details   Inciter's input deck grammar definition. We use the Parsing
      10                 :            :   Expression Grammar Template Library (PEGTL) to create the grammar and the
      11                 :            :   associated parser. Word of advice: read from the bottom up.
      12                 :            : */
      13                 :            : // *****************************************************************************
      14                 :            : #ifndef InciterInputDeckGrammar_h
      15                 :            : #define InciterInputDeckGrammar_h
      16                 :            : 
      17                 :            : #include <limits>
      18                 :            : #include <cmath>
      19                 :            : 
      20                 :            : #include "CommonGrammar.hpp"
      21                 :            : #include "CartesianProduct.hpp"
      22                 :            : #include "Keywords.hpp"
      23                 :            : #include "ContainerUtil.hpp"
      24                 :            : #include "Centering.hpp"
      25                 :            : #include "PDE/MultiMat/MultiMatIndexing.hpp"
      26                 :            : 
      27                 :            : namespace inciter {
      28                 :            : 
      29                 :            : extern ctr::InputDeck g_inputdeck_defaults;
      30                 :            : 
      31                 :            : //! Inciter input deck facilitating user input for computing shock hydrodynamics
      32                 :            : namespace deck {
      33                 :            : 
      34                 :            :   //! \brief Specialization of tk::grm::use for Inciter's input deck parser
      35                 :            :   template< typename keyword >
      36                 :            :   using use = tk::grm::use< keyword, ctr::InputDeck::keywords >;
      37                 :            : 
      38                 :            :   // Inciter's InputDeck state
      39                 :            : 
      40                 :            :   //! \brief Number of registered equations
      41                 :            :   //! \details Counts the number of parsed equation blocks during parsing.
      42                 :            :   static tk::TaggedTuple< brigand::list<
      43                 :            :              tag::transport,   std::size_t
      44                 :            :            , tag::compflow,    std::size_t
      45                 :            :            , tag::multimat,    std::size_t
      46                 :            :          > > neq;
      47                 :            : 
      48                 :            :   //! \brief Parser-lifetime storage for point names
      49                 :            :   //! \details Used to track the point names registered so that parsing new ones
      50                 :            :   //!    can be required to be unique.
      51                 :            :   static std::set< std::string > pointnames;
      52                 :            : 
      53                 :            :   //! Parser-lifetime storage of elem or node centering
      54                 :            :   static tk::Centering centering = tk::Centering::NODE;
      55                 :            : 
      56                 :            :   //! Accepted multimat output variable labels and associated index functions
      57                 :            :   //! \details The keys are a list of characters accepted as labels for
      58                 :            :   //! denoting (matvar-style) output variables used for multi-material variable
      59                 :            :   //! output. We use a case- insesitive comparitor, since when this set is used
      60                 :            :   //! we only care about whether the variable is selected or not and not whether
      61                 :            :   //! it denotes a full variable (upper case) or a fluctuation (lower case).
      62                 :            :   //! This is true when matching these labels for output variables with
      63                 :            :   //! instantaenous variables as well terms of products in parsing requested
      64                 :            :   //! statistics (for turbulence). The values are associated indexing functions
      65                 :            :   //! used to index into the state of the multimaterial system, all must follow
      66                 :            :   //! the same signature.
      67                 :            :   static std::map< char, tk::MultiMatIdxFn,
      68                 :            :                    tk::ctr::CaseInsensitiveCharLess >
      69                 :            :     multimatvars{
      70                 :            :       { 'd', densityIdx }       // density
      71                 :            :     , { 'f', volfracIdx }       // volume fraction
      72                 :            :     , { 'm', momentumIdx }      // momentum
      73                 :            :     , { 'e', energyIdx }        // specific total energy
      74                 :            :     , { 'u', velocityIdx }      // velocity (primitive)
      75                 :            :     , { 'p', pressureIdx }      // material pressure (primitive)
      76                 :            :   };
      77                 :            : 
      78                 :            : } // ::deck
      79                 :            : } // ::inciter
      80                 :            : 
      81                 :            : namespace tk {
      82                 :            : namespace grm {
      83                 :            : 
      84                 :            :   using namespace tao;
      85                 :            : 
      86                 :            :   // Note that PEGTL action specializations must be in the same namespace as the
      87                 :            :   // template being specialized. See http://stackoverflow.com/a/3052604.
      88                 :            : 
      89                 :            :   // Inciter's InputDeck actions
      90                 :            : 
      91                 :            :   //! Rule used to trigger action
      92                 :            :   template< class eq > struct register_inciter_eq : pegtl::success {};
      93                 :            :   //! \brief Register differential equation after parsing its block
      94                 :            :   //! \details This is used by the error checking functors (check_*) during
      95                 :            :   //!    parsing to identify the recently-parsed block.
      96                 :            :   template< class eq >
      97                 :            :   struct action< register_inciter_eq< eq > > {
      98                 :            :     template< typename Input, typename Stack >
      99                 :        233 :     static void apply( const Input&, Stack& ) {
     100                 :            :       using inciter::deck::neq;
     101                 :        233 :       ++neq.get< eq >();
     102                 :        233 :     }
     103                 :            :   };
     104                 :            : 
     105                 :            :   //! Rule used to trigger action
     106                 :            :   template< class eq > struct check_mesh : pegtl::success {};
     107                 :            :   //! \brief Check mesh ... end block for correctness
     108                 :            :   template< class eq >
     109                 :            :   struct action< check_mesh< eq > > {
     110                 :            :     template< typename Input, typename Stack >
     111                 :        233 :     static void apply( const Input& in, Stack& stack ) {
     112                 :            :       using inciter::deck::neq;
     113                 :        233 :       auto& mesh = stack.template get< tag::param, eq, tag::mesh >();
     114                 :        233 :       auto& mesh_ref = mesh.template get< tag::reference >();
     115                 :            :       // if no mesh reference given by user
     116 [ -  + ][ -  - ]:        233 :       if (mesh_ref.empty() || mesh_ref.size() != neq.get< eq >()) {
                 [ +  - ]
     117                 :            :         // put in '-', meaning no reference
     118         [ +  - ]:        233 :         mesh_ref.push_back('-');
     119                 :        233 :         auto& location = mesh.template get< tag::location >();
     120                 :            :         // if no location, put in the origin
     121         [ +  - ]:        233 :         if (location.size() != neq.get< eq >())
     122 [ +  - ][ +  - ]:        233 :           location.push_back( { 0.0, 0.0, 0.0 } );
     123                 :            :         else    // reference was not given, but location was, error out
     124                 :          0 :           Message< Stack, ERROR, MsgKey::LOC_NOMESHREF >( stack, in );
     125                 :        233 :         auto& orientation = mesh.template get< tag::orientation >();
     126         [ +  - ]:        233 :         if (orientation.size() != neq.get< eq >())
     127 [ +  - ][ +  - ]:        233 :           orientation.push_back( { 0.0, 0.0, 0.0 } );
     128                 :            :         else    // reference was not given, but orientation was, error out
     129                 :          0 :           Message< Stack, ERROR, MsgKey::ORI_NOMESHREF >( stack, in );
     130                 :            :       }
     131                 :            : 
     132                 :            :       // Ensure the number of depvars and the number of mesh references equal
     133                 :        233 :       const auto& depvar = stack.template get< tag::param, eq, tag::depvar >();
     134 [ -  + ][ -  - ]:        233 :       Assert( depvar.size() == mesh_ref.size(), "Mesh ref size mismatch" );
         [ -  - ][ -  - ]
     135                 :            : 
     136                 :            :       // Ensure mesh ref var is not the same as the current depvar and is
     137                 :            :       // defined upstream in input file (by another solver)
     138         [ -  + ]:        233 :       if ( mesh_ref.back() != '-' &&
     139 [ -  - ][ -  - ]:          0 :            (mesh_ref.back() == depvar.back() ||
     140 [ -  - ][ -  + ]:        233 :             depvars.find(mesh_ref.back()) == end(depvars)) )
     141                 :            :       {
     142                 :          0 :         Message< Stack, ERROR, MsgKey::DEPVAR_AS_MESHREF >( stack, in );
     143                 :            :       }
     144                 :        233 :     }
     145                 :            :   };
     146                 :            : 
     147                 :            :   //! Rule used to trigger action
     148                 :            :   template< class eq > struct check_transport : pegtl::success {};
     149                 :            :   //! \brief Set defaults and do error checking on the transport equation block
     150                 :            :   //! \details This is error checking that only the transport equation block
     151                 :            :   //!   must satisfy. Besides error checking we also set defaults here as
     152                 :            :   //!   this block is called when parsing of a transport...end block has
     153                 :            :   //!   just finished.
     154                 :            :   template< class eq >
     155                 :            :   struct action< check_transport< eq > > {
     156                 :            :     template< typename Input, typename Stack >
     157                 :        126 :     static void apply( const Input& in, Stack& stack ) {
     158                 :            :       using inciter::deck::neq;
     159                 :            :       using tag::param;
     160                 :            : 
     161                 :            :       // Error out if no dependent variable has been selected
     162                 :        126 :       auto& depvar = stack.template get< param, eq, tag::depvar >();
     163 [ +  - ][ -  + ]:        126 :       if (depvar.empty() || depvar.size() != neq.get< eq >())
                 [ -  + ]
     164                 :          0 :         Message< Stack, ERROR, MsgKey::NODEPVAR >( stack, in );
     165                 :            : 
     166                 :            :       // If no number of components has been selected, default to 1
     167                 :        126 :       auto& ncomp = stack.template get< tag::component, eq >();
     168 [ +  + ][ -  + ]:        126 :       if (ncomp.empty() || ncomp.size() != neq.get< eq >())
                 [ +  + ]
     169         [ +  - ]:         86 :         ncomp.push_back( 1 );
     170                 :            : 
     171                 :            :       // If physics type is not given, default to 'advection'
     172                 :        126 :       auto& physics = stack.template get< param, eq, tag::physics >();
     173 [ +  - ][ -  + ]:        126 :       if (physics.empty() || physics.size() != neq.get< eq >())
                 [ -  + ]
     174         [ -  - ]:          0 :         physics.push_back( inciter::ctr::PhysicsType::ADVECTION );
     175                 :            : 
     176                 :            :       // If physics type is advection-diffusion, check for correct number of
     177                 :            :       // advection velocity, shear, and diffusion coefficients
     178         [ +  + ]:        126 :       if (physics.back() == inciter::ctr::PhysicsType::ADVDIFF) {
     179                 :          7 :         auto& u0 = stack.template get< param, eq, tag::u0 >();
     180         [ -  + ]:          7 :         if (u0.back().size() != ncomp.back())  // must define 1 component
     181                 :          0 :           Message< Stack, ERROR, MsgKey::WRONGSIZE >( stack, in );
     182                 :          7 :         auto& diff = stack.template get< param, eq, tag::diffusivity >();
     183         [ -  + ]:          7 :         if (diff.back().size() != 3*ncomp.back())  // must define 3 components
     184                 :          0 :           Message< Stack, ERROR, MsgKey::WRONGSIZE >( stack, in );
     185                 :          7 :         auto& lambda = stack.template get< param, eq, tag::lambda >();
     186         [ -  + ]:          7 :         if (lambda.back().size() != 2*ncomp.back()) // must define 2 shear comps
     187                 :          0 :           Message< Stack, ERROR, MsgKey::WRONGSIZE >( stack, in );
     188                 :            :       }
     189                 :            :       // If problem type is not given, error out
     190                 :        126 :       auto& problem = stack.template get< param, eq, tag::problem >();
     191 [ +  - ][ -  + ]:        126 :       if (problem.empty() || problem.size() != neq.get< eq >())
                 [ -  + ]
     192                 :          0 :         Message< Stack, ERROR, MsgKey::NOPROBLEM >( stack, in );
     193                 :            :       // Error check Dirichlet boundary condition block for all transport eq
     194                 :            :       // configurations
     195                 :        126 :       const auto& bc = stack.template get< param, eq, tag::bc, tag::bcdir >();
     196         [ +  + ]:        162 :       for (const auto& s : bc)
     197 [ -  + ][ -  - ]:         36 :         if (s.empty()) Message< Stack, ERROR, MsgKey::BC_EMPTY >( stack, in );
     198                 :            : 
     199                 :            :       // If interface compression is not specified, default to 'false'
     200                 :        126 :       auto& intsharp = stack.template get< param, eq, tag::intsharp >();
     201 [ -  + ][ -  - ]:        126 :       if (intsharp.empty() || intsharp.size() != neq.get< eq >())
                 [ +  - ]
     202         [ +  - ]:        126 :         intsharp.push_back( 0 );
     203                 :            : 
     204                 :            :       // If interface compression parameter is not specified, default to 1.0
     205                 :        126 :       auto& intsharp_p = stack.template get< param, eq,
     206                 :            :                                             tag::intsharp_param >();
     207 [ -  + ][ -  - ]:        126 :       if (intsharp_p.empty() || intsharp_p.size() != neq.get< eq >())
                 [ +  - ]
     208         [ +  - ]:        126 :         intsharp_p.push_back( 1.0 );
     209                 :        126 :     }
     210                 :            :   };
     211                 :            : 
     212                 :            :   //! Rule used to trigger action
     213                 :            :   template< class eq > struct check_compflow : pegtl::success {};
     214                 :            :   //! \brief Set defaults and do error checking on the compressible flow
     215                 :            :   //!   equation block
     216                 :            :   //! \details This is error checking that only the compressible flow equation
     217                 :            :   //!   block must satisfy. Besides error checking we also set defaults here as
     218                 :            :   //!   this block is called when parsing of a compflow...end block has
     219                 :            :   //!   just finished.
     220                 :            :   template< class eq >
     221                 :            :   struct action< check_compflow< eq > > {
     222                 :            :     template< typename Input, typename Stack >
     223                 :         95 :     static void apply( const Input& in, Stack& stack ) {
     224                 :            :       using inciter::deck::neq;
     225                 :            :       using tag::param;
     226                 :            : 
     227                 :            :       // Error out if no dependent variable has been selected
     228                 :         95 :       auto& depvar = stack.template get< param, eq, tag::depvar >();
     229 [ +  - ][ -  + ]:         95 :       if (depvar.empty() || depvar.size() != neq.get< eq >())
                 [ -  + ]
     230                 :          0 :         Message< Stack, ERROR, MsgKey::NODEPVAR >( stack, in );
     231                 :            : 
     232                 :            :       // If physics type is not given, default to 'euler'
     233                 :         95 :       auto& physics = stack.template get< param, eq, tag::physics >();
     234 [ +  - ][ -  + ]:         95 :       if (physics.empty() || physics.size() != neq.get< eq >()) {
                 [ -  + ]
     235         [ -  - ]:          0 :         physics.push_back( inciter::ctr::PhysicsType::EULER );
     236                 :            :       }
     237                 :            : 
     238                 :            :       // Set number of components to 5 (mass, 3 x mom, energy)
     239         [ +  - ]:         95 :       stack.template get< tag::component, eq >().push_back( 5 );
     240                 :            : 
     241                 :            :       // Set default to sysfct (on/off) if not specified
     242                 :         95 :       auto& sysfct = stack.template get< param, eq, tag::sysfct >();
     243 [ +  + ][ -  + ]:         95 :       if (sysfct.empty() || sysfct.size() != neq.get< eq >())
                 [ +  + ]
     244         [ +  - ]:         71 :         sysfct.push_back( 1 );
     245                 :            : 
     246                 :            :       // Set default flux to HLLC if not specified
     247                 :         95 :       auto& flux = stack.template get< tag::param, eq, tag::flux >();
     248 [ +  + ][ -  + ]:         95 :       if (flux.empty() || flux.size() != neq.get< eq >())
                 [ +  + ]
     249         [ +  - ]:         93 :         flux.push_back( inciter::ctr::FluxType::HLLC );
     250                 :            : 
     251                 :            :       // Verify that sysfctvar variables are within bounds (if specified) and
     252                 :            :       // defaults if not
     253                 :         95 :       auto& sysfctvar = stack.template get< param, eq, tag::sysfctvar >();
     254                 :            :       // If sysfctvar is not specified, use all variables for system FCT
     255 [ -  + ][ -  - ]:         95 :       if (sysfctvar.empty() || sysfctvar.back().empty()) {
                 [ +  - ]
     256 [ +  - ][ +  - ]:         95 :         sysfctvar.push_back( {0,1,2,3,4} );
     257                 :            :       } else {  // if specified, do error checking on variables
     258                 :          0 :         auto& vars = sysfctvar.back();
     259         [ -  - ]:          0 :         if (vars.size() > 5) {
     260                 :          0 :           Message< Stack, ERROR, MsgKey::SYSFCTVAR >( stack, in );
     261                 :            :         }
     262         [ -  - ]:          0 :         for (const auto& i : vars) {
     263 [ -  - ][ -  - ]:          0 :           if (i > 4) Message< Stack, ERROR, MsgKey::SYSFCTVAR >( stack, in );
     264                 :            :         }
     265                 :            :       }
     266                 :            : 
     267                 :            :       // Verify correct number of material properties configured
     268                 :         95 :       auto& matprop = stack.template get< param, eq, tag::material >().back()[0];
     269                 :         95 :       auto& matidxmap = stack.template get< param, eq, tag::matidxmap >();
     270                 :         95 :       matidxmap.template get< tag::eosidx >().resize(1);
     271                 :         95 :       matidxmap.template get< tag::matidx >().resize(1);
     272                 :         95 :       auto& meos = matprop.template get< tag::eos >();
     273                 :         95 :       auto& mat_id = matprop.template get< tag::id >();
     274                 :            : 
     275         [ +  - ]:         95 :       if (mat_id.empty())
     276         [ +  - ]:         95 :         mat_id.push_back(0);
     277         [ -  - ]:          0 :       else if (mat_id.size() != 1)
     278                 :          0 :         Message< Stack, ERROR, MsgKey::NUMMAT >( stack, in );
     279                 :            :       else
     280                 :          0 :         mat_id[0] = 0;
     281                 :            : 
     282         [ +  - ]:         95 :       if (meos == inciter::ctr::MaterialType::STIFFENEDGAS) {
     283                 :         95 :         const auto& gamma = matprop.template get< tag::gamma >();
     284                 :            :         // If gamma vector is wrong size, error out
     285 [ +  - ][ -  + ]:         95 :         if (gamma.empty() || gamma.size() != 1)
                 [ -  + ]
     286                 :          0 :           Message< Stack, ERROR, MsgKey::EOSGAMMA >( stack, in );
     287                 :            : 
     288                 :         95 :         auto& cv = matprop.template get< tag::cv >();
     289                 :            :         // As a default, the specific heat of air (717.5 J/Kg-K) is used
     290         [ +  + ]:         95 :         if (cv.empty())
     291         [ +  - ]:         93 :           cv.push_back(717.5);
     292                 :            :         // If specific heat vector is wrong size, error out
     293         [ -  + ]:         95 :         if (cv.size() != 1)
     294                 :          0 :           Message< Stack, ERROR, MsgKey::EOSCV >( stack, in );
     295                 :            : 
     296                 :         95 :         auto& pstiff = matprop.template get< tag::pstiff >();
     297                 :            :         // As a default, a stiffness coefficient of 0.0 is used
     298         [ +  - ]:         95 :         if (pstiff.empty())
     299         [ +  - ]:         95 :           pstiff.push_back(0.0);
     300                 :            :         // If stiffness coefficient vector is wrong size, error out
     301         [ -  + ]:         95 :         if (pstiff.size() != 1)
     302                 :          0 :           Message< Stack, ERROR, MsgKey::EOSPSTIFF >( stack, in );
     303                 :            :       }
     304                 :            : 
     305                 :            :       // Generate mapping between material index and eos parameter index
     306                 :         95 :       auto& eosmap = matidxmap.template get< tag::eosidx >();
     307                 :         95 :       auto& idxmap = matidxmap.template get< tag::matidx >();
     308                 :         95 :       eosmap[mat_id[0]] = static_cast< std::size_t >(matprop.template get<
     309                 :            :         tag::eos >());
     310                 :         95 :       idxmap[mat_id[0]] = 0;
     311                 :            : 
     312                 :            :       // If problem type is not given, default to 'user_defined'
     313                 :         95 :       auto& problem = stack.template get< param, eq, tag::problem >();
     314 [ +  + ][ -  + ]:         95 :       if (problem.empty() || problem.size() != neq.get< eq >())
                 [ +  + ]
     315         [ +  - ]:          5 :         problem.push_back( inciter::ctr::ProblemType::USER_DEFINED );
     316         [ +  + ]:         90 :       else if (problem.back() == inciter::ctr::ProblemType::VORTICAL_FLOW) {
     317                 :         27 :         const auto& alpha = stack.template get< param, eq, tag::alpha >();
     318                 :         27 :         const auto& beta = stack.template get< param, eq, tag::beta >();
     319                 :         27 :         const auto& p0 = stack.template get< param, eq, tag::p0 >();
     320         [ +  - ]:         54 :         if ( alpha.size() != problem.size() ||
     321 [ +  - ][ -  + ]:         54 :              beta.size() != problem.size() ||
                 [ -  + ]
     322                 :         27 :              p0.size() != problem.size() )
     323                 :          0 :           Message< Stack, ERROR, MsgKey::VORTICAL_UNFINISHED >( stack, in );
     324                 :            :       }
     325         [ +  + ]:         63 :       else if (problem.back() == inciter::ctr::ProblemType::NL_ENERGY_GROWTH) {
     326                 :         12 :         const auto& alpha = stack.template get< param, eq, tag::alpha >();
     327                 :         12 :         const auto& betax = stack.template get< param, eq, tag::betax >();
     328                 :         12 :         const auto& betay = stack.template get< param, eq, tag::betay >();
     329                 :         12 :         const auto& betaz = stack.template get< param, eq, tag::betaz >();
     330                 :         12 :         const auto& kappa = stack.template get< param, eq, tag::kappa >();
     331                 :         12 :         const auto& r0 = stack.template get< param, eq, tag::r0 >();
     332                 :         12 :         const auto& ce = stack.template get< param, eq, tag::ce >();
     333         [ +  - ]:         24 :         if ( alpha.size() != problem.size() ||
     334         [ +  - ]:         24 :              betax.size() != problem.size() ||
     335         [ +  - ]:         24 :              betay.size() != problem.size() ||
     336         [ +  - ]:         24 :              betaz.size() != problem.size() ||
     337         [ +  - ]:         24 :              kappa.size() != problem.size() ||
     338 [ +  - ][ -  + ]:         36 :              r0.size() != problem.size() ||
                 [ -  + ]
     339                 :         12 :              ce.size() != problem.size() )
     340                 :          0 :           Message< Stack, ERROR, MsgKey::ENERGY_UNFINISHED >( stack, in);
     341                 :            :       }
     342         [ +  + ]:         51 :       else if (problem.back() == inciter::ctr::ProblemType::RAYLEIGH_TAYLOR) {
     343                 :          4 :         const auto& alpha = stack.template get< param, eq, tag::alpha >();
     344                 :          4 :         const auto& betax = stack.template get< param, eq, tag::betax >();
     345                 :          4 :         const auto& betay = stack.template get< param, eq, tag::betay >();
     346                 :          4 :         const auto& betaz = stack.template get< param, eq, tag::betaz >();
     347                 :          4 :         const auto& kappa = stack.template get< param, eq, tag::kappa >();
     348                 :          4 :         const auto& p0 = stack.template get< param, eq, tag::p0 >();
     349                 :          4 :         const auto& r0 = stack.template get< param, eq, tag::r0 >();
     350         [ +  - ]:          8 :         if ( alpha.size() != problem.size() ||
     351         [ +  - ]:          8 :              betax.size() != problem.size() ||
     352         [ +  - ]:          8 :              betay.size() != problem.size() ||
     353         [ +  - ]:          8 :              betaz.size() != problem.size() ||
     354         [ +  - ]:          8 :              kappa.size() != problem.size() ||
     355 [ +  - ][ -  + ]:         12 :              p0.size() != problem.size() ||
                 [ -  + ]
     356                 :          4 :              r0.size() != problem.size() )
     357                 :          0 :           Message< Stack, ERROR, MsgKey::RT_UNFINISHED >( stack, in);
     358                 :            :       }
     359                 :            : 
     360                 :            :       // Error check on user-defined problem type
     361                 :         95 :       auto& ic = stack.template get< param, eq, tag::ic >();
     362                 :         95 :       auto& bgdensityic = ic.template get< tag::density >();
     363                 :         95 :       auto& bgvelocityic = ic.template get< tag::velocity >();
     364                 :         95 :       auto& bgpressureic = ic.template get< tag::pressure >();
     365                 :         95 :       auto& bgenergyic = ic.template get< tag::energy >();
     366                 :         95 :       auto& bgtemperatureic = ic.template get< tag::temperature >();
     367         [ +  + ]:         95 :       if (problem.back() == inciter::ctr::ProblemType::USER_DEFINED) {
     368                 :            :         // must have defined background ICs for user-defined ICs
     369                 :          7 :         auto n = neq.get< eq >();
     370 [ +  - ][ +  - ]:         14 :         if ( bgdensityic.size() != n || bgvelocityic.size() != n ||
         [ -  + ][ -  + ]
     371 [ -  - ][ -  - ]:          7 :              ( bgpressureic.size() != n && bgenergyic.size() != n &&
     372                 :          0 :                bgtemperatureic.size() != n ) )
     373                 :            :         {
     374                 :          0 :           Message< Stack, ERROR, MsgKey::BGICMISSING >( stack, in );
     375                 :            :         }
     376                 :            : 
     377                 :            :         // Error check Dirichlet boundary condition block for all compflow
     378                 :            :         // configurations
     379                 :          7 :         const auto& bc = stack.template get< param, eq, tag::bc, tag::bcdir >();
     380         [ -  + ]:          7 :         for (const auto& s : bc)
     381 [ -  - ][ -  - ]:          0 :           if (s.empty()) Message< Stack, ERROR, MsgKey::BC_EMPTY >( stack, in );
     382                 :            : 
     383                 :            :         // Error check stagnation BC block
     384                 :          7 :         const auto& stag = stack.template get<tag::param, eq, tag::stag>();
     385                 :          7 :         const auto& spoint = stag.template get< tag::point >();
     386                 :          7 :         const auto& sradius = stag.template get< tag::radius >();
     387         [ -  - ]:          7 :         if ( (!spoint.empty() && !spoint.back().empty() &&
     388 [ -  - ][ -  - ]:          0 :               !sradius.empty() && !sradius.back().empty() &&
     389         [ -  - ]:          0 :               spoint.back().size() != 3*sradius.back().size())
     390 [ -  + ][ -  - ]:          7 :          || (!sradius.empty() && !sradius.back().empty() &&
     391 [ -  - ][ -  - ]:          0 :               !spoint.empty() && !spoint.back().empty() &&
     392         [ -  - ]:          0 :               spoint.back().size() != 3*sradius.back().size())
     393 [ -  + ][ -  - ]:          7 :          || (!spoint.empty() && !spoint.back().empty() &&
                 [ -  - ]
     394 [ -  - ][ -  - ]:          0 :               (sradius.empty() || (!sradius.empty() && sradius.back().empty())))
     395 [ -  + ][ -  + ]:         14 :          || (!sradius.empty() && !sradius.back().empty() &&
         [ -  - ][ -  - ]
                 [ -  + ]
     396 [ -  - ][ -  - ]:          0 :               (spoint.empty() || (!spoint.empty() && spoint.back().empty()))) )
     397                 :            :         {
     398                 :          0 :           Message< Stack, ERROR, MsgKey::STAGBCWRONG >( stack, in );
     399                 :            :         }
     400                 :            : 
     401                 :            :         // Error check skip BC block
     402                 :          7 :         const auto& skip = stack.template get<tag::param, eq, tag::skip>();
     403                 :          7 :         const auto& kpoint = skip.template get< tag::point >();
     404                 :          7 :         const auto& kradius = skip.template get< tag::radius >();
     405         [ -  - ]:          7 :         if ( (!kpoint.empty() && !kpoint.back().empty() &&
     406 [ -  - ][ -  - ]:          0 :               !kradius.empty() && !kradius.back().empty() &&
     407         [ -  - ]:          0 :               kpoint.back().size() != 3*kradius.back().size())
     408 [ -  + ][ -  - ]:          7 :           || (!kradius.empty() && !kradius.back().empty() &&
     409 [ -  - ][ -  - ]:          0 :               !kpoint.empty() && !kpoint.back().empty() &&
     410         [ -  - ]:          0 :               kpoint.back().size() != 3*kradius.back().size())
     411 [ -  + ][ -  - ]:          7 :           || (!kpoint.empty() && !kpoint.back().empty() &&
                 [ -  - ]
     412 [ -  - ][ -  - ]:          0 :               (kradius.empty() || (!kradius.empty() && kradius.back().empty())))
     413 [ -  + ][ -  + ]:         14 :           || (!kradius.empty() && !kradius.back().empty() &&
         [ -  - ][ -  - ]
                 [ -  + ]
     414 [ -  - ][ -  - ]:          0 :               (kpoint.empty() || (!kpoint.empty() && kpoint.back().empty()))) )
     415                 :            :         {
     416                 :          0 :           Message< Stack, ERROR, MsgKey::SKIPBCWRONG >( stack, in );
     417                 :            :         }
     418                 :            : 
     419                 :            :         // Error check sponge BC parameter vectors for symmetry BC block
     420                 :          7 :         const auto& sponge =
     421                 :            :           stack.template get< tag::param, eq, tag::sponge >();
     422                 :          7 :         const auto& ss = sponge.template get< tag::sideset >();
     423                 :            : 
     424                 :          7 :         const auto& spvel = sponge.template get< tag::velocity >();
     425 [ -  + ][ -  - ]:          7 :         if ( !spvel.empty() && !spvel.back().empty()) {
                 [ -  + ]
     426         [ -  - ]:          0 :           if (spvel.back().size() != ss.back().size())
     427                 :          0 :             Message< Stack, ERROR, MsgKey::SPONGEBCWRONG >( stack, in );
     428         [ -  - ]:          0 :           for (const auto& s : spvel.back())
     429 [ -  - ][ -  - ]:          0 :             if ( s < 0.0 || s > 1.0 )
     430         [ -  - ]:          0 :               Message< Stack, ERROR, MsgKey::SPONGEBCWRONG >( stack, in );
     431                 :            :         }
     432                 :            : 
     433                 :          7 :         const auto& sppre = sponge.template get< tag::velocity >();
     434 [ -  + ][ -  - ]:          7 :         if ( !sppre.empty() && !sppre.back().empty()) {
                 [ -  + ]
     435         [ -  - ]:          0 :           if (sppre.back().size() != ss.back().size())
     436                 :          0 :             Message< Stack, ERROR, MsgKey::SPONGEBCWRONG >( stack, in );
     437         [ -  - ]:          0 :           for (const auto& s : sppre.back())
     438 [ -  - ][ -  - ]:          0 :             if ( s < 0.0 || s > 1.0 )
     439         [ -  - ]:          0 :               Message< Stack, ERROR, MsgKey::SPONGEBCWRONG >( stack, in );
     440                 :            :         }
     441                 :            : 
     442                 :            :         // Error check user defined time dependent BC for this system
     443                 :          7 :         const auto& tdepbc =
     444                 :          7 :           stack.template get< tag::param, eq, tag::bctimedep >().back();
     445                 :            :         // multiple time dependent BCs can be specified on different side sets
     446         [ +  + ]:          8 :         for (const auto& bndry : tdepbc) {
     447                 :          1 :           const auto& s = bndry.template get< tag::sideset >();
     448 [ -  + ][ -  - ]:          1 :           if (s.empty()) Message< Stack, ERROR, MsgKey::BC_EMPTY >( stack, in );
     449                 :          1 :           const auto& f = bndry.template get< tag::fn >();
     450 [ +  - ][ -  + ]:          1 :           if (f.empty() or f.size() % 6 != 0)
                 [ -  + ]
     451         [ -  - ]:          0 :             Message< Stack, ERROR, MsgKey::INCOMPLETEUSERFN>( stack, in );
     452                 :            :         }
     453                 :            :       }
     454                 :         95 :     }
     455                 :            :   };
     456                 :            : 
     457                 :            :   //! Rule used to trigger action
     458                 :            :   template< class eq > struct check_multimat : pegtl::success {};
     459                 :            :   //! \brief Set defaults and do error checking on the multimaterial
     460                 :            :   //!    compressible flow equation block
     461                 :            :   //! \details This is error checking that only the multimaterial compressible
     462                 :            :   //!   flow equation block must satisfy. Besides error checking we also set
     463                 :            :   //!   defaults here as this block is called when parsing of a
     464                 :            :   //!   multimat...end block has just finished.
     465                 :            :   template< class eq >
     466                 :            :   struct action< check_multimat< eq > > {
     467                 :            :     template< typename Input, typename Stack >
     468                 :         12 :     static void apply( const Input& in, Stack& stack ) {
     469                 :            :       using inciter::deck::neq;
     470                 :            :       using tag::param;
     471                 :            : 
     472                 :            :       // Error out if no dependent variable has been selected
     473                 :         12 :       auto& depvar = stack.template get< param, eq, tag::depvar >();
     474 [ +  - ][ -  + ]:         12 :       if (depvar.empty() || depvar.size() != neq.get< eq >())
                 [ -  + ]
     475         [ -  - ]:          0 :         Message< Stack, ERROR, MsgKey::NODEPVAR >( stack, in );
     476                 :            : 
     477                 :            :       // If physics type is not given, default to 'veleq'
     478                 :         12 :       auto& physics = stack.template get< param, eq, tag::physics >();
     479 [ +  - ][ -  + ]:         12 :       if (physics.empty() || physics.size() != neq.get< eq >())
                 [ -  + ]
     480         [ -  - ]:          0 :         physics.push_back( inciter::ctr::PhysicsType::VELEQ );
     481                 :            : 
     482                 :            :       // Set default flux to AUSM if not specified
     483                 :         12 :       auto& flux = stack.template get< tag::param, eq, tag::flux >();
     484 [ -  + ][ -  - ]:         12 :       if (flux.empty() || flux.size() != neq.get< eq >())
                 [ +  - ]
     485         [ +  - ]:         12 :         flux.push_back( inciter::ctr::FluxType::AUSM );
     486                 :            : 
     487                 :            :       // Set number of scalar components based on number of materials
     488                 :         12 :       auto& nmat = stack.template get< param, eq, tag::nmat >();
     489                 :         12 :       auto& ncomp = stack.template get< tag::component, eq >();
     490         [ +  - ]:         12 :       if (physics.back() == inciter::ctr::PhysicsType::VELEQ) {
     491                 :            :         // physics = veleq: m-material compressible flow
     492                 :            :         // scalar components: volfrac:m + mass:m + momentum:3 + energy:m
     493                 :            :         // if nmat is unspecified, configure it be 2
     494 [ +  - ][ -  + ]:         12 :         if (nmat.empty() || nmat.size() != neq.get< eq >()) {
                 [ -  + ]
     495         [ -  - ]:          0 :           Message< Stack, WARNING, MsgKey::NONMAT >( stack, in );
     496         [ -  - ]:          0 :           nmat.push_back( 2 );
     497                 :            :         }
     498                 :            :         // set ncomp based on nmat
     499                 :         12 :         auto m = nmat.back();
     500         [ +  - ]:         12 :         ncomp.push_back( m + m + 3 + m );
     501                 :            :       }
     502                 :            : 
     503                 :            :       // Verify correct number of multi-material properties (gamma, cv, pstiff)
     504                 :            :       // have been configured
     505                 :         12 :       auto& matprop = stack.template get< param, eq, tag::material >();
     506                 :         12 :       auto& matidxmap = stack.template get< param, eq, tag::matidxmap >();
     507         [ +  - ]:         12 :       matidxmap.template get< tag::eosidx >().resize(nmat.back());
     508         [ +  - ]:         12 :       matidxmap.template get< tag::matidx >().resize(nmat.back());
     509                 :         12 :       std::size_t tmat(0), i(0);
     510                 :         24 :       std::set< std::size_t > matidset;
     511                 :            : 
     512         [ +  + ]:         24 :       for (auto& mtype : matprop.back()) {
     513                 :         12 :         const auto& meos = mtype.template get< tag::eos >();
     514                 :         12 :         const auto& mat_id = mtype.template get< tag::id >();
     515                 :            : 
     516         [ +  - ]:         12 :         if (meos == inciter::ctr::MaterialType::STIFFENEDGAS) {
     517                 :         12 :           const auto& gamma = mtype.template get< tag::gamma >();
     518                 :            :           // If gamma vector is wrong size, error out
     519 [ +  - ][ -  + ]:         12 :           if (gamma.empty() || gamma.size() != mat_id.size())
                 [ -  + ]
     520         [ -  - ]:          0 :             Message< Stack, ERROR, MsgKey::EOSGAMMA >( stack, in );
     521                 :            : 
     522                 :         12 :           auto& cv = mtype.template get< tag::cv >();
     523                 :            :           // As a default, the specific heat of air (717.5 J/Kg-K) is used
     524         [ +  + ]:         12 :           if (cv.empty()) {
     525         [ +  + ]:         21 :             for (std::size_t k=0; k<mat_id.size(); ++k) {
     526         [ +  - ]:         14 :               cv.push_back(717.5);
     527                 :            :             }
     528                 :            :           }
     529                 :            :           // If specific heat vector is wrong size, error out
     530         [ -  + ]:         12 :           if (cv.size() != mat_id.size())
     531         [ -  - ]:          0 :             Message< Stack, ERROR, MsgKey::EOSCV >( stack, in );
     532                 :            : 
     533                 :         12 :           auto& pstiff = mtype.template get< tag::pstiff >();
     534                 :            :           // As a default, a stiffness coefficient of 0.0 is used
     535         [ +  + ]:         12 :           if (pstiff.empty()) {
     536         [ +  + ]:         29 :             for (std::size_t k=0; k<mat_id.size(); ++k) {
     537         [ +  - ]:         20 :               pstiff.push_back(0.0);
     538                 :            :             }
     539                 :            :           }
     540                 :            :           // If stiffness coefficient vector is wrong size, error out
     541         [ -  + ]:         12 :           if (pstiff.size() != mat_id.size())
     542         [ -  - ]:          0 :             Message< Stack, ERROR, MsgKey::EOSPSTIFF >( stack, in );
     543                 :            :         }
     544                 :            : 
     545                 :            :         // Track total number of materials in multiple material blocks
     546                 :         12 :         tmat += mat_id.size();
     547                 :            : 
     548                 :            :         // Check for repeating user specified material ids
     549         [ +  + ]:         38 :         for (auto midx : mat_id) {
     550 [ +  - ][ +  - ]:         26 :           if (!matidset.count(midx))
     551         [ +  - ]:         26 :             matidset.insert(midx);
     552                 :            :           else
     553         [ -  - ]:          0 :             Message< Stack, ERROR, MsgKey::REPMATID >( stack, in );
     554                 :            :         }
     555                 :            : 
     556                 :            :         // Generate mapping between material index and eos parameter index
     557                 :         12 :         auto& eosmap = matidxmap.template get< tag::eosidx >();
     558                 :         12 :         auto& idxmap = matidxmap.template get< tag::matidx >();
     559         [ +  + ]:         38 :         for (auto midx : mat_id) {
     560                 :         26 :           midx -= 1;
     561                 :         26 :           eosmap[midx] = static_cast< std::size_t >(mtype.template get<
     562                 :            :             tag::eos >());
     563                 :         26 :           idxmap[midx] = i;
     564                 :         26 :           ++i;
     565                 :            :         }
     566                 :            :         // end of materials for this eos, thus reset index counter
     567                 :         12 :         i = 0;
     568                 :            :       }
     569                 :            : 
     570                 :            :       // If total number of materials is incorrect, error out
     571         [ -  + ]:         12 :       if (tmat != nmat.back())
     572         [ -  - ]:          0 :         Message< Stack, ERROR, MsgKey::NUMMAT >( stack, in );
     573                 :            : 
     574                 :            :       // Check if material ids are contiguous and 1-based
     575 [ +  - ][ -  + ]:         12 :       if (!matidset.count(1))
     576         [ -  - ]:          0 :         Message< Stack, ERROR, MsgKey::ONEMATID >( stack, in );
     577                 :         12 :       std::size_t icount(1);
     578         [ +  + ]:         38 :       for (auto midx : matidset) {
     579         [ -  + ]:         26 :         if (midx != icount)
     580         [ -  - ]:          0 :           Message< Stack, ERROR, MsgKey::GAPMATID >( stack, in );
     581                 :         26 :         ++icount;
     582                 :            :       }
     583                 :            : 
     584                 :            :       // If pressure relaxation is not specified, default to 'false'
     585                 :         12 :       auto& prelax = stack.template get< param, eq, tag::prelax >();
     586 [ +  + ][ -  + ]:         12 :       if (prelax.empty() || prelax.size() != neq.get< eq >())
                 [ +  + ]
     587         [ +  - ]:          9 :         prelax.push_back( 0 );
     588                 :            : 
     589                 :            :       // If pressure relaxation time-scale is not specified, default to 1.0
     590                 :         12 :       auto& prelax_ts = stack.template get< param, eq,
     591                 :            :                                             tag::prelax_timescale >();
     592 [ +  + ][ -  + ]:         12 :       if (prelax_ts.empty() || prelax_ts.size() != neq.get< eq >())
                 [ +  + ]
     593         [ +  - ]:          9 :         prelax_ts.push_back( 1.0 );
     594                 :            : 
     595                 :            :       // If interface compression is not specified, default to 'false'
     596                 :         12 :       auto& intsharp = stack.template get< param, eq, tag::intsharp >();
     597 [ +  + ][ -  + ]:         12 :       if (intsharp.empty() || intsharp.size() != neq.get< eq >())
                 [ +  + ]
     598         [ +  - ]:         10 :         intsharp.push_back( 0 );
     599                 :            : 
     600                 :            :       // If interface compression parameter is not specified, default to 1.0
     601                 :         12 :       auto& intsharp_p = stack.template get< param, eq,
     602                 :            :                                             tag::intsharp_param >();
     603 [ +  + ][ -  + ]:         12 :       if (intsharp_p.empty() || intsharp_p.size() != neq.get< eq >())
                 [ +  + ]
     604         [ +  - ]:         10 :         intsharp_p.push_back( 1.0 );
     605                 :            : 
     606                 :            :       // If problem type is not given, default to 'user_defined'
     607                 :         12 :       auto& problem = stack.template get< param, eq, tag::problem >();
     608 [ +  - ][ -  + ]:         12 :       if (problem.empty() || problem.size() != neq.get< eq >())
                 [ -  + ]
     609         [ -  - ]:          0 :         problem.push_back( inciter::ctr::ProblemType::USER_DEFINED );
     610         [ -  + ]:         12 :       else if (problem.back() == inciter::ctr::ProblemType::VORTICAL_FLOW) {
     611                 :          0 :         const auto& alpha = stack.template get< param, eq, tag::alpha >();
     612                 :          0 :         const auto& beta = stack.template get< param, eq, tag::beta >();
     613                 :          0 :         const auto& p0 = stack.template get< param, eq, tag::p0 >();
     614         [ -  - ]:          0 :         if ( alpha.size() != problem.size() ||
     615 [ -  - ][ -  - ]:          0 :              beta.size() != problem.size() ||
                 [ -  - ]
     616                 :          0 :              p0.size() != problem.size() )
     617         [ -  - ]:          0 :           Message< Stack, ERROR, MsgKey::VORTICAL_UNFINISHED >( stack, in );
     618                 :            :       }
     619                 :            : 
     620                 :            :       // Error check on user-defined problem type
     621                 :         12 :       auto& ic = stack.template get< param, eq, tag::ic >();
     622                 :         12 :       auto& bgmatid = ic.template get< tag::materialid >();
     623                 :         12 :       auto& bgdensityic = ic.template get< tag::density >();
     624                 :         12 :       auto& bgvelocityic = ic.template get< tag::velocity >();
     625                 :         12 :       auto& bgpressureic = ic.template get< tag::pressure >();
     626                 :         12 :       auto& bgenergyic = ic.template get< tag::energy >();
     627                 :         12 :       auto& bgtemperatureic = ic.template get< tag::temperature >();
     628         [ -  + ]:         12 :       if (problem.back() == inciter::ctr::ProblemType::USER_DEFINED) {
     629                 :            :         // must have defined background ICs for user-defined ICs
     630                 :          0 :         auto n = neq.get< eq >();
     631         [ -  - ]:          0 :         if (bgmatid.size() != n) {
     632         [ -  - ]:          0 :           Message< Stack, ERROR, MsgKey::BGMATIDMISSING >( stack, in );
     633                 :            :         }
     634                 :            : 
     635 [ -  - ][ -  - ]:          0 :         if ( bgdensityic.size() != n || bgvelocityic.size() != n ||
         [ -  - ][ -  - ]
     636 [ -  - ][ -  - ]:          0 :              ( bgpressureic.size() != n && bgenergyic.size() != n &&
     637                 :          0 :                bgtemperatureic.size() != n ) )
     638                 :            :         {
     639         [ -  - ]:          0 :           Message< Stack, ERROR, MsgKey::BGICMISSING >( stack, in );
     640                 :            :         }
     641                 :            : 
     642                 :            :         // each IC box should have material id specified, and it should be
     643                 :            :         // within nmat
     644                 :          0 :         auto& icbox = ic.template get< tag::box >();
     645                 :            : 
     646         [ -  - ]:          0 :         if (!icbox.empty()) {
     647         [ -  - ]:          0 :           for (const auto& b : icbox.back()) {   // for all boxes
     648                 :          0 :             auto boxmatid = b.template get< tag::materialid >();
     649         [ -  - ]:          0 :             if (boxmatid == 0) {
     650         [ -  - ]:          0 :               Message< Stack, ERROR, MsgKey::BOXMATIDMISSING >( stack, in );
     651                 :            :             }
     652         [ -  - ]:          0 :             else if (boxmatid > nmat.back()) {
     653         [ -  - ]:          0 :               Message< Stack, ERROR, MsgKey::BOXMATIDWRONG >( stack, in );
     654                 :            :             }
     655                 :            :           }
     656                 :            :         }
     657                 :            :       }
     658                 :            : 
     659                 :            :       // Error check Dirichlet boundary condition block for all multimat
     660                 :            :       // configurations
     661                 :         12 :       const auto& bc = stack.template get< param, eq, tag::bc, tag::bcdir >();
     662         [ +  + ]:         14 :       for (const auto& s : bc)
     663 [ -  + ][ -  - ]:          2 :         if (s.empty()) Message< Stack, ERROR, MsgKey::BC_EMPTY >( stack, in );
     664                 :         12 :     }
     665                 :            :   };
     666                 :            : 
     667                 :            :   //! Rule used to trigger action
     668                 :            :   template< class Option, typename...tags >
     669                 :            :   struct store_inciter_option : pegtl::success {};
     670                 :            :   //! \brief Put option in state at position given by tags
     671                 :            :   //! \details This is simply a wrapper around tk::grm::store_option passing the
     672                 :            :   //!    stack defaults for inciter.
     673                 :            :   template< class Option, typename... tags >
     674                 :            :   struct action< store_inciter_option< Option, tags... > > {
     675                 :            :     template< typename Input, typename Stack >
     676                 :        539 :     static void apply( const Input& in, Stack& stack ) {
     677                 :            :       store_option< Stack, inciter::deck::use, Option, inciter::ctr::InputDeck,
     678                 :            :                     Input, tags... >
     679                 :        539 :                   ( stack, in, inciter::g_inputdeck_defaults );
     680                 :        539 :     }
     681                 :            :   };
     682                 :            : 
     683                 :            :   //! Function object to ensure disjoint side sets for all boundary conditions
     684                 :            :   //! \details This is instantiated using a Cartesian product of all PDE types
     685                 :            :   //!    and all BC types at compile time. It goes through all side sets
     686                 :            :   //!    configured by the user and triggers an error if a side set is assigned
     687                 :            :   //!    a BC more than once (within a solver).
     688                 :            :   template< typename Input, typename Stack >
     689                 :            :   struct ensure_disjoint {
     690                 :            :     const Input& m_input;
     691                 :            :     Stack& m_stack;
     692                 :        233 :     explicit ensure_disjoint( const Input& in, Stack& stack ) :
     693                 :        233 :       m_input( in ), m_stack( stack ) {}
     694                 :       4194 :     template< typename U > void operator()( brigand::type_<U> ) {
     695                 :            :       using Eq = typename brigand::front< U >;
     696                 :            :       using BC = typename brigand::back< U >;
     697                 :       4194 :       const auto& bc = m_stack.template get< tag::param, Eq, tag::bc, BC >();
     698         [ +  + ]:       4459 :       for (const auto& eq : bc) {
     699                 :        530 :         std::unordered_set< int > bcset;
     700         [ +  + ]:        982 :         for (const auto& s : eq) {
     701         [ +  - ]:        717 :           auto id = std::stoi(s);
     702 [ +  - ][ -  + ]:        717 :           if (bcset.find(id) != end(bcset))
     703         [ -  - ]:          0 :             Message< Stack, ERROR, MsgKey::NONDISJOINTBC >( m_stack, m_input );
     704                 :            :           else
     705         [ +  - ]:        717 :             bcset.insert( id );
     706                 :            :         }
     707                 :            :       }
     708                 :       4194 :     }
     709                 :            :   };
     710                 :            : 
     711                 :            :   //! Function object to count the number of meshes assigned to solvers
     712                 :            :   //! \details This is instantiated for all PDE types at compile time. It goes
     713                 :            :   //!   through all configured solvers (equation system configuration blocks)
     714                 :            :   //!   and counts the number of mesh filenames configured.
     715                 :            :   template< typename Stack >
     716                 :            :   struct count_meshes {
     717                 :            :     const Stack& stack;
     718                 :            :     std::size_t& count;
     719                 :            :     explicit
     720                 :        233 :     count_meshes( const Stack& s, std::size_t& c ) : stack(s), count(c) {}
     721                 :        699 :     template< typename eq > void operator()( brigand::type_<eq> ) {
     722                 :        699 :       count +=
     723                 :        699 :         stack.template get< tag::param, eq, tag::mesh, tag::filename >().size();
     724                 :        699 :     }
     725                 :            :   };
     726                 :            : 
     727                 :            :   //! Function object to assign mesh ids to solvers
     728                 :            :   //! \details This is instantiated for all PDE types at compile time. It goes
     729                 :            :   //!   through all configured solvers (equation system configuration blocks)
     730                 :            :   //!   and assigns a new mesh id to all solvers configured in the input file.
     731                 :            :   template< typename Stack >
     732                 :            :   struct assign_meshid {
     733                 :            :     Stack& stack;
     734                 :            :     std::size_t& meshid;
     735                 :        233 :     explicit assign_meshid( Stack& s, std::size_t& m ) : stack(s), meshid(m) {}
     736                 :        699 :     template< typename eq > void operator()( brigand::type_<eq> ) {
     737                 :        699 :       const auto& eq_mesh_filename =
     738                 :        699 :         stack.template get< tag::param, eq, tag::mesh, tag::filename >();
     739                 :        699 :       auto& id = stack.template get< tag::param, eq, tag::mesh, tag::id >();
     740         [ +  + ]:        709 :       for (std::size_t i=0; i<eq_mesh_filename.size(); ++i)
     741         [ +  - ]:         10 :         id.push_back( meshid++ );
     742                 :        699 :     }
     743                 :            :   };
     744                 :            : 
     745                 :            :   //! Rule used to trigger action
     746                 :            :   struct configure_scheme : pegtl::success {};
     747                 :            :   //! Configure scheme selected by user
     748                 :            :   //! \details This grammar action configures the number of degrees of freedom
     749                 :            :   //! (NDOF) used for DG methods. For finite volume (or DGP0), the DOF are the
     750                 :            :   //! cell-averages. This implies ndof=1 for DGP0. Similarly, ndof=4 and 10 for
     751                 :            :   //! DGP1 and DGP2 respectively, since they evolve higher (>1) order solution
     752                 :            :   //! information (e.g. gradients) as well. "rdof" includes degrees of freedom
     753                 :            :   //! that are both, evolved and reconstructed. For rDGPnPm methods (e.g. P0P1
     754                 :            :   //! and P1P2), "n" denotes the evolved solution-order and "m" denotes the
     755                 :            :   //! reconstructed solution-order; i.e. P0P1 has ndof=1 and rdof=4, whereas
     756                 :            :   //! P1P2 has ndof=4 and rdof=10. For a pure DG method without reconstruction
     757                 :            :   //! (DGP0, DGP1, DGP2), rdof=ndof. For more information about rDGPnPm methods,
     758                 :            :   //! ref. Luo, H. et al. (2013).  A reconstructed discontinuous Galerkin method
     759                 :            :   //! based on a hierarchical WENO reconstruction for compressible flows on
     760                 :            :   //! tetrahedral grids. Journal of Computational Physics, 236, 477-492.
     761                 :            :   template<> struct action< configure_scheme > {
     762                 :            :     template< typename Input, typename Stack >
     763                 :        204 :     static void apply( const Input&, Stack& stack ) {
     764                 :            :       using inciter::ctr::SchemeType;
     765                 :        204 :       auto& discr = stack.template get< tag::discr >();
     766                 :        204 :       auto& ndof = discr.template get< tag::ndof >();
     767                 :        204 :       auto& rdof = discr.template get< tag::rdof >();
     768                 :        204 :       auto scheme = discr.template get< tag::scheme >();
     769         [ +  + ]:        204 :       if (scheme == SchemeType::P0P1) {
     770                 :          8 :         ndof = 1; rdof = 4;
     771         [ +  + ]:        196 :       } else if (scheme == SchemeType::DGP1) {
     772                 :         16 :         ndof = rdof = 4;
     773         [ +  + ]:        180 :       } else if (scheme == SchemeType::DGP2) {
     774                 :         10 :         ndof = rdof = 10;
     775         [ +  + ]:        170 :       } else if (scheme == SchemeType::PDG) {
     776                 :         12 :         ndof = rdof = 10;
     777                 :         12 :         stack.template get< tag::pref, tag::pref >() = true;
     778                 :            :       }
     779                 :        204 :     }
     780                 :            :   };
     781                 :            : 
     782                 :            :   //! Function object to do error checking on output time ranges
     783                 :            :   template< typename Stack, typename Input >
     784                 :            :   struct range_errchk {
     785                 :            :     Stack& stack;
     786                 :            :     const Input& input;
     787                 :        233 :     explicit range_errchk( Stack& s, const Input& in ) : stack(s), input(in) {}
     788                 :        466 :     template< typename U > void operator()( brigand::type_<U> ) {
     789         [ +  + ]:        468 :       for (const auto& r : stack.template get< tag::output, tag::range, U >())
     790 [ +  - ][ +  - ]:          2 :         if ( r.size() != 3 or r[0] > r[1] or r[2] < 0.0 or r[2] > r[1]-r[0] )
         [ +  - ][ -  + ]
                 [ -  + ]
     791         [ -  - ]:          0 :           Message< Stack, ERROR, MsgKey::BADRANGE >( stack, input );
     792                 :        466 :     }
     793                 :            :   };
     794                 :            : 
     795                 :            :   //! Rule used to trigger action
     796                 :            :   struct check_inciter : pegtl::success {};
     797                 :            :   //! \brief Do error checking on the inciter block
     798                 :            :   template<> struct action< check_inciter > {
     799                 :            :     template< typename Input, typename Stack >
     800                 :        233 :     static void apply( const Input& in, Stack& stack ) {
     801                 :            :       using inciter::deck::neq;
     802                 :            :       using inciter::g_inputdeck_defaults;
     803                 :            : 
     804                 :            :       // Error out if no dt policy has been selected
     805                 :        233 :       const auto& dt = stack.template get< tag::discr, tag::dt >();
     806                 :        233 :       const auto& cfl = stack.template get< tag::discr, tag::cfl >();
     807                 :        233 :       if ( std::abs(dt - g_inputdeck_defaults.get< tag::discr, tag::dt >()) <
     808 [ +  + ][ -  + ]:        349 :             std::numeric_limits< tk::real >::epsilon() &&
                 [ -  + ]
     809                 :        116 :           std::abs(cfl - g_inputdeck_defaults.get< tag::discr, tag::cfl >()) <
     810                 :        116 :             std::numeric_limits< tk::real >::epsilon() )
     811         [ -  - ]:          0 :         Message< Stack, ERROR, MsgKey::NODT >( stack, in );
     812                 :            : 
     813                 :            :       // If both dt and cfl are given, warn that dt wins over cfl
     814                 :        233 :       if ( std::abs(dt - g_inputdeck_defaults.get< tag::discr, tag::dt >()) >
     815 [ +  + ][ -  + ]:        350 :             std::numeric_limits< tk::real >::epsilon() &&
                 [ -  + ]
     816                 :        117 :           std::abs(cfl - g_inputdeck_defaults.get< tag::discr, tag::cfl >()) >
     817                 :        117 :             std::numeric_limits< tk::real >::epsilon() )
     818         [ -  - ]:          0 :         Message< Stack, WARNING, MsgKey::MULDT >( stack, in );
     819                 :            : 
     820                 :            :       // Do error checking on time history points
     821                 :        233 :       const auto& hist = stack.template get< tag::history, tag::point >();
     822 [ +  - ][ -  + ]:        233 :       if (std::any_of( begin(hist), end(hist),
     823                 :         14 :            [](const auto& p){ return p.size() != 3; } ) )
     824                 :            :       {
     825         [ -  - ]:          0 :         Message< Stack, ERROR, MsgKey::WRONGSIZE >( stack, in );
     826                 :            :       }
     827                 :            : 
     828                 :            :       // Do error checking on residual eq system component index
     829                 :        233 :       const auto rc = stack.template get< tag::discr, tag::rescomp >();
     830                 :        233 :       const auto& ncomps = stack.template get< tag::component >();
     831 [ +  - ][ -  + ]:        233 :       if (rc < 1 || rc > ncomps.nprop())
                 [ -  + ]
     832         [ -  - ]:          0 :         Message< Stack, ERROR, MsgKey::LARGECOMP >( stack, in );
     833                 :            : 
     834                 :            :       // Ensure no different BC types are assigned to the same side set
     835                 :            :       using PDETypes = inciter::ctr::parameters::Keys;
     836                 :            :       using BCTypes = inciter::ctr::bc::Keys;
     837         [ +  - ]:        233 :       brigand::for_each< tk::cartesian_product< PDETypes, BCTypes > >(
     838                 :            :         ensure_disjoint< Input, Stack >( in, stack ) );
     839                 :            : 
     840                 :            :       // Do error checking on output time range configuration parameters: they
     841                 :            :       // all must be a 3 reals: mintime, maxtime, and dt with maxtime >
     842                 :            :       // mintime, and dt<maxtime-mintime.
     843                 :            :       brigand::for_each< inciter::ctr::time_range::Keys >
     844         [ +  - ]:        233 :                        ( range_errchk< Stack, Input >( stack, in ) );
     845                 :            : 
     846                 :            :       // Do error checking on time history point names (this is a programmer
     847                 :            :       // error if triggers, hence assert)
     848 [ -  + ][ -  - ]:        233 :       Assert(
         [ -  - ][ -  - ]
     849                 :            :         (stack.template get< tag::history, tag::id >().size() == hist.size()),
     850                 :            :         "Number of history points and ids must equal" );
     851                 :            : 
     852                 :            :       // If at least a mesh filename is assigned to a solver, all solvers must
     853                 :            :       // have a mesh filename assigned
     854                 :        233 :       std::size_t nmesh = 0;
     855         [ +  - ]:        233 :       brigand::for_each< PDETypes >( count_meshes< Stack >( stack, nmesh ) );
     856 [ +  + ][ -  + ]:        233 :       if (nmesh > 0 && nmesh != depvars.size())
                 [ -  + ]
     857         [ -  - ]:          0 :         Message< Stack, ERROR, MsgKey::MULTIMESH >( stack, in );
     858                 :            : 
     859                 :            :       // Remove duplicate transfer steps
     860         [ +  - ]:        233 :       tk::unique( stack.template get< tag::couple, tag::transfer >() );
     861                 :            : 
     862                 :            :       // Now that the inciter ... end block is finished, assign mesh ids to
     863                 :            :       // solvers configured
     864                 :        233 :       std::size_t meshid = 0;
     865         [ +  - ]:        233 :       brigand::for_each< PDETypes >( assign_meshid< Stack >( stack, meshid ) );
     866 [ -  + ][ -  - ]:        233 :       Assert( meshid == nmesh, "Not all meshes configured have mesh ids" );
         [ -  - ][ -  - ]
     867                 :        233 :     }
     868                 :            :   };
     869                 :            : 
     870                 :            :   //! Rule used to trigger action
     871                 :            :   struct check_ale : pegtl::success {};
     872                 :            :   //! \brief Do error checking on the inciter block
     873                 :            :   template<> struct action< check_ale > {
     874                 :            :     template< typename Input, typename Stack >
     875                 :         10 :     static void apply( const Input& in, Stack& stack ) {
     876                 :            :       using inciter::g_inputdeck_defaults;
     877                 :            : 
     878                 :            :      // Trigger error if steady state + ALE are both enabled
     879                 :         10 :       auto steady = stack.template get< tag::discr, tag::steady_state >();
     880                 :         10 :       auto ale = stack.template get< tag::ale, tag::ale >();
     881 [ -  + ][ -  - ]:         10 :       if (steady && ale) {
     882                 :          0 :         Message< Stack, ERROR, MsgKey::STEADYALE >( stack, in );
     883                 :            :       }
     884                 :            : 
     885                 :            :       // Set a sensible default for dvCFL if ALE is enabled and if dvcfl not set
     886                 :         10 :       auto& dvcfl = stack.template get< tag::ale, tag::dvcfl >();
     887                 :         10 :       auto dvcfl_default = g_inputdeck_defaults.get< tag::ale, tag::dvcfl >();
     888                 :         10 :       auto eps = std::numeric_limits< tk::real >::epsilon();
     889 [ +  - ][ -  + ]:         10 :       if (ale && std::abs(dvcfl - dvcfl_default) < eps) dvcfl = 0.01;
                 [ -  + ]
     890                 :            : 
     891                 :            :       // Set a default of zeros for the mesh force ALE parameters
     892                 :         10 :       auto& meshforce = stack.template get< tag::ale, tag::meshforce >();
     893 [ +  - ][ +  - ]:         10 :       if (ale && meshforce.size() != 4) meshforce = { 0, 0, 0, 0 };
         [ +  - ][ +  - ]
     894                 :            : 
     895                 :            :       // Set a default for the ALE mesh motion dimensions
     896                 :         10 :       auto& mesh_motion = stack.template get< tag::ale, tag::mesh_motion >();
     897 [ +  - ][ +  + ]:         10 :       if (ale && mesh_motion.empty()) mesh_motion = { 0, 1, 2 };
         [ +  + ][ +  - ]
     898                 :            : 
     899                 :            :       // Error out if mesh motion dimensions are wrong
     900 [ +  - ][ +  - ]:         20 :       if (ale && (mesh_motion.size() > 3 ||
                 [ -  + ]
     901         [ -  + ]:         10 :                   std::any_of( begin(mesh_motion), end(mesh_motion),
     902                 :         24 :                      [](auto d){return d > 2;} )) )
     903                 :            :       {
     904                 :          0 :         Message< Stack, ERROR, MsgKey::WRONGMESHMOTION >( stack, in );
     905                 :            :       }
     906                 :            : 
     907                 :            :       // Error checking on user-defined function for ALE's moving sides
     908                 :         10 :       const auto& move = stack.template get< tag::ale, tag::move >();
     909         [ +  + ]:         12 :       for (const auto& s : move) {
     910                 :          2 :         const auto& f = s.template get< tag::fn >();
     911 [ +  - ][ -  + ]:          2 :         if (f.empty() or f.size() % 4 != 0)
                 [ -  + ]
     912         [ -  - ]:          0 :           Message< Stack, ERROR, MsgKey::INCOMPLETEUSERFN>( stack, in );
     913                 :            :       }
     914                 :         10 :     }
     915                 :            :   };
     916                 :            : 
     917                 :            :   //! Rule used to trigger action
     918                 :            :   template< typename Feature >
     919                 :            :   struct enable : pegtl::success {};
     920                 :            :   //! Enable adaptive mesh refinement (AMR)
     921                 :            :   template< typename Feature >
     922                 :            :   struct action< enable< Feature > > {
     923                 :            :     template< typename Input, typename Stack >
     924                 :         52 :     static void apply( const Input&, Stack& stack ) {
     925                 :         52 :       stack.template get< Feature, Feature >() = true;
     926                 :         52 :     }
     927                 :            :   };
     928                 :            : 
     929                 :            :   //! Rule used to trigger action
     930                 :            :   struct compute_refvar_idx : pegtl::success {};
     931                 :            :   //! Compute indices of refinement variables
     932                 :            :   //! \details This functor computes the indices in the unknown vector for all
     933                 :            :   //!   refinement variables in the system of systems of dependent variables
     934                 :            :   //!   after the refvar...end block has been parsed in the amr...end block.
     935                 :            :   //!   After basic error checking, the vector at stack.get<tag::amr,tag::id>()
     936                 :            :   //!   is filled.
     937                 :            :   template<>
     938                 :            :   struct action< compute_refvar_idx > {
     939                 :            :     template< typename Input, typename Stack >
     940                 :         33 :     static void apply( const Input& in, Stack& stack ) {
     941                 :            :       // reference variables just parsed by refvar...end block
     942                 :         33 :       const auto& refvar = stack.template get< tag::amr, tag::refvar >();
     943                 :            :       // get ncomponents object from this input deck
     944                 :         33 :       const auto& ncomps = stack.template get< tag::component >();
     945                 :            :       // compute offset map associating offsets to dependent variables
     946         [ +  - ]:         66 :       auto offsetmap = ncomps.offsetmap( stack );
     947                 :            :       // compute number of components associated to dependent variabels
     948         [ +  - ]:         66 :       auto ncompmap = ncomps.ncompmap( stack );
     949                 :            :       // reference variable index vector to fill
     950                 :         33 :       auto& refidx = stack.template get< tag::amr, tag::id >();
     951                 :            :       // Compute indices for all refvars
     952         [ +  + ]:         66 :       for (const auto& v : refvar) {    // for all reference variables parsed
     953                 :            :         // depvar is the first char of a refvar
     954                 :         33 :         auto depvar = v[0];
     955                 :            :         // the field ID is optional and is the rest of the depvar string
     956 [ -  + ][ -  - ]:         33 :         std::size_t f = (v.size()>1 ? std::stoul(v.substr(1)) : 1) - 1;
         [ -  - ][ -  + ]
                 [ -  - ]
     957                 :            :         // field ID must be less than or equal to the number of scalar
     958                 :            :         // components configured for the eq system for this dependent variable
     959 [ +  - ][ -  + ]:         33 :         if (f >= tk::cref_find( ncompmap, depvar ))
     960         [ -  - ]:          0 :           Message< Stack, ERROR, MsgKey::NOSUCHCOMPONENT >( stack, in );
     961                 :            :         // get offset for depvar
     962         [ +  - ]:         33 :         auto eqsys_offset = tk::cref_find( offsetmap, depvar );
     963                 :            :         // the index is the eq offset + field ID
     964                 :         33 :         auto idx = eqsys_offset + f;
     965                 :            :         // save refvar index in system of all systems
     966         [ +  - ]:         33 :         refidx.push_back( idx );
     967                 :            :       }
     968                 :         33 :     }
     969                 :            :   };
     970                 :            : 
     971                 :            :   //! Rule used to trigger action
     972                 :            :   struct check_amr_errors : pegtl::success {};
     973                 :            :   //! Do error checking for the amr...end block
     974                 :            :   //! \details This is error checking that only the amr...end block
     975                 :            :   //!   must satisfy. Besides error checking this can also set defaults
     976                 :            :   //!   as this block is called when parsing of a amr...end block has
     977                 :            :   //!   just finished.
     978                 :            :   template<>
     979                 :            :   struct action< check_amr_errors > {
     980                 :            :     template< typename Input, typename Stack >
     981                 :         42 :     static void apply( const Input& in, Stack& stack ) {
     982                 :            :       // Error out if refvar size does not equal refidx size (programmer error)
     983 [ -  + ][ -  - ]:         42 :       Assert( (stack.template get< tag::amr, tag::refvar >().size() ==
         [ -  - ][ -  - ]
     984                 :            :                stack.template get< tag::amr, tag::id >().size()),
     985                 :            :               "The size of refvar and refidx vectors must equal" );
     986                 :         42 :       const auto& initref = stack.template get< tag::amr, tag::init >();
     987                 :         42 :       const auto& refvar = stack.template get< tag::amr, tag::refvar >();
     988                 :         42 :       const auto& edgelist = stack.template get< tag::amr, tag::edge >();
     989                 :            :       // Error out if initref edge list is not divisible by 2 (user error)
     990         [ -  + ]:         42 :       if (edgelist.size() % 2 == 1)
     991                 :          0 :         Message< Stack, ERROR, MsgKey::T0REFODD >( stack, in );
     992                 :            :       // Warn if initial AMR will be a no-op
     993 [ +  + ][ -  + ]:         42 :       if ( stack.template get< tag::amr, tag::t0ref >() && initref.empty() )
                 [ -  + ]
     994                 :          0 :         Message< Stack, WARNING, MsgKey::T0REFNOOP >( stack, in );
     995                 :            :       // Error out if timestepping AMR will be a no-op (user error)
     996 [ +  + ][ -  + ]:         42 :       if ( stack.template get< tag::amr, tag::dtref >() && refvar.empty() )
                 [ -  + ]
     997                 :          0 :         Message< Stack, ERROR, MsgKey::DTREFNOOP >( stack, in );
     998                 :            :       // Error out if mesh refinement frequency is zero (programmer error)
     999 [ -  + ][ -  - ]:         42 :       Assert( (stack.template get< tag::amr, tag::dtfreq >() > 0),
         [ -  - ][ -  - ]
    1000                 :            :               "Mesh refinement frequency must be positive" );
    1001                 :         42 :     }
    1002                 :            :   };
    1003                 :            : 
    1004                 :            :   //! Rule used to trigger action
    1005                 :            :   struct check_pref_errors : pegtl::success {};
    1006                 :            :   //! Do error checking for the pref...end block
    1007                 :            :   template<>
    1008                 :            :   struct action< check_pref_errors > {
    1009                 :            :     template< typename Input, typename Stack >
    1010                 :         12 :     static void apply( const Input& in, Stack& stack ) {
    1011                 :         12 :       auto& tolref = stack.template get< tag::pref, tag::tolref >();
    1012 [ +  - ][ -  + ]:         12 :       if (tolref < 0.0 || tolref > 1.0)
    1013                 :          0 :         Message< Stack, ERROR, MsgKey::PREFTOL >( stack, in );
    1014                 :         12 :     }
    1015                 :            :   };
    1016                 :            : 
    1017                 :            :   //! Rule used to trigger action
    1018                 :            :   struct match_pointname : pegtl::success {};
    1019                 :            :   //! \brief Match PDF name to the registered ones
    1020                 :            :   //! \details This is used to check the set of PDF names dependent previously
    1021                 :            :   //!    registered to make sure all are unique.
    1022                 :            :   template<>
    1023                 :            :   struct action< match_pointname > {
    1024                 :            :     template< typename Input, typename Stack >
    1025                 :         14 :     static void apply( const Input& in, Stack& stack ) {
    1026                 :            :       using inciter::deck::pointnames;
    1027                 :            :       // find matched name in set of registered ones
    1028 [ +  - ][ +  - ]:         14 :       if (pointnames.find( in.string() ) == pointnames.end()) {
                 [ +  - ]
    1029         [ +  - ]:         14 :         pointnames.insert( in.string() );
    1030         [ +  - ]:         14 :         stack.template get< tag::history, tag::id >().push_back( in.string() );
    1031                 :            :       }
    1032                 :            :       else  // error out if name matched var is already registered
    1033                 :          0 :         Message< Stack, ERROR, MsgKey::POINTEXISTS >( stack, in );
    1034                 :         14 :     }
    1035                 :            :   };
    1036                 :            : 
    1037                 :            :   //! Rule used to trigger action
    1038                 :            :   struct push_depvar : pegtl::success {};
    1039                 :            :   //! Add matched outvar based on depvar into vector of outvars
    1040                 :            :   //! \details Push outvar based on depvar: use first char of matched token as
    1041                 :            :   //! OutVar::var, OutVar::name = "" by default. OutVar::name being empty will
    1042                 :            :   //! be used to differentiate a depvar-based outvar from a human-readable
    1043                 :            :   //! outvar. Depvar-based outvars can directly access solution arrays using
    1044                 :            :   //! their field. Human-readable outvars need a mechanism (a function) to read
    1045                 :            :   //! and compute their variables from solution arrays. The 'getvar' function,
    1046                 :            :   //! used to compute a physics variable from the numerical solution is assigned
    1047                 :            :   //! after initial migration and thus not assigned here (during parsing).
    1048                 :            :   template<>
    1049                 :            :   struct action< push_depvar > {
    1050                 :            :     template< typename Input, typename Stack >
    1051                 :         59 :     static void apply( const Input& in, Stack& stack ) {
    1052                 :            :       using inciter::deck::centering;
    1053                 :            :       using inciter::ctr::OutVar;
    1054                 :         59 :       auto& vars = stack.template get< tag::cmd, tag::io, tag::outvar >();
    1055 [ +  - ][ +  - ]:         59 :       vars.emplace_back(OutVar(in.string()[0], field, centering));
         [ +  - ][ +  - ]
    1056                 :         59 :       field = 0;        // reset field
    1057                 :         59 :     }
    1058                 :            :   };
    1059                 :            : 
    1060                 :            :   //! Rule used to trigger action
    1061                 :            :   struct push_matvar : pegtl::success {};
    1062                 :            :   //! Add matched outvar based on matvar into vector of outvars
    1063                 :            :   //! \details Push outvar based on matvar: use depvar char as OutVar::var,
    1064                 :            :   //! OutVar::name = "" by default. Matvar-based outvars are similar to
    1065                 :            :   //! depvar-base outvars, in that the OutVar has empty name and the OutVar::var
    1066                 :            :   //! is a depvar, but instead of having the user try to guess the field id, the
    1067                 :            :   //! grammar accepts a physics label (accepted multimatvars) and a material
    1068                 :            :   //! index, which are then converted to a depvar + field index.
    1069                 :            :   template<>
    1070                 :            :   struct action< push_matvar > {
    1071                 :            :     template< typename Input, typename Stack >
    1072                 :         26 :     static void apply( const Input& in, Stack& stack ) {
    1073                 :            :       using tag::param;
    1074                 :            :       using tag::multimat;
    1075                 :            :       using inciter::deck::centering;
    1076                 :            :       using inciter::deck::multimatvars;
    1077                 :            :       using inciter::ctr::OutVar;
    1078                 :         26 :       auto& vars = stack.template get< tag::cmd, tag::io, tag::outvar >();
    1079                 :         26 :       auto nmat = stack.template get< param, multimat, tag::nmat >().back();
    1080                 :         26 :       auto depvar = stack.template get< param, multimat, tag::depvar >().back();
    1081                 :            :       // first char of matched token: accepted multimatvar label char
    1082 [ +  - ][ +  - ]:         26 :       char v = static_cast<char>( in.string()[0] );
    1083                 :            :       // Since multimat outvars are configured based on an acceptable character
    1084                 :            :       // label (see inciter::deck::multimatvars, denoting a physics variable),
    1085                 :            :       // and a material index (instead of a depvar + a component index),
    1086                 :            :       // multimat material bounds are checked here. Note that for momentum and
    1087                 :            :       // velocity, the field id is the spatial direction not the material id.
    1088                 :            :       // Also note that field (in grammar's state) starts from 0.
    1089 [ +  - ][ +  - ]:         26 :       if ( ((v=='u'||v=='U'||v=='m'||v=='M') && field>2) ||
         [ +  - ][ -  + ]
                 [ -  - ]
    1090 [ +  - ][ +  - ]:         26 :            ((v!='u'&&v!='U'&&v!='m'&&v!='M') && field>=nmat) )
         [ +  - ][ +  - ]
                 [ -  + ]
    1091         [ -  - ]:          0 :         Message< Stack, ERROR, MsgKey::NOSUCHCOMPONENT >( stack, in );
    1092                 :            :       // field contains material id, compute multiat component index
    1093 [ +  - ][ +  - ]:         26 :       auto comp = tk::cref_find( multimatvars, v )( nmat, field );
    1094                 :            :       // save depvar + component index based on physics label + material id,
    1095                 :            :       // also save physics label + material id as matvar
    1096 [ +  - ][ +  - ]:         26 :       vars.emplace_back(
         [ +  - ][ +  - ]
    1097                 :            :         OutVar(depvar, comp, centering, {}, {}, v+std::to_string(field+1)) );
    1098                 :         26 :       field = 0;        // reset field
    1099                 :         26 :     }
    1100                 :            :   };
    1101                 :            : 
    1102                 :            :   //! Function object for adding a human-readable output variable
    1103                 :            :   //! \details Since human-readable outvars do not necessarily have any
    1104                 :            :   //! reference to the depvar of their system they refer to, nor which system
    1105                 :            :   //! they refer to, we configure them for all of the systems they are preceded
    1106                 :            :   //! by. If there is only a single system of the type the outvar is configured,
    1107                 :            :   //! we simply look up the depvar and use that as OutVar::var. If there are
    1108                 :            :   //! multiple systems configured upstream to which the outvar could refer to,
    1109                 :            :   //! we configure an outvar for all systems configured, and postfix the
    1110                 :            :   //! human-readable OutVar::name with '_' + depvar. Hence this function object
    1111                 :            :   //! so the code below can be invoked for all equation types.
    1112                 :            :   template< typename Stack >
    1113                 :            :   struct AddOutVarHuman {
    1114                 :            :     Stack& stack;
    1115                 :            :     const std::string& in_string;
    1116                 :        752 :     explicit AddOutVarHuman( Stack& s, const std::string& ins )
    1117                 :        752 :       : stack(s), in_string(ins) {}
    1118                 :       2256 :     template< typename Eq > void operator()( brigand::type_<Eq> ) {
    1119                 :            :       using inciter::deck::centering;
    1120                 :            :       using inciter::ctr::OutVar;
    1121                 :       2256 :       const auto& depvar = stack.template get< tag::param, Eq, tag::depvar >();
    1122                 :       2256 :       auto& vars = stack.template get< tag::cmd, tag::io, tag::outvar >();
    1123         [ +  + ]:       2256 :       if (depvar.size() == 1)
    1124 [ +  - ][ +  - ]:        752 :         vars.emplace_back( OutVar( depvar[0], 0, centering, in_string ) );
    1125                 :            :       else
    1126         [ -  + ]:       1504 :         for (auto d : depvar)
    1127 [ -  - ][ -  - ]:          0 :           vars.emplace_back( OutVar( d, 0, centering, in_string + '_' + d ) );
         [ -  - ][ -  - ]
    1128                 :       2256 :     }
    1129                 :            :   };
    1130                 :            : 
    1131                 :            :   //! Rule used to trigger action
    1132                 :            :   struct push_humanvar : pegtl::success {};
    1133                 :            :   //! Add matched outvar based on depvar into vector of vector of outvars
    1134                 :            :   //! \details Push outvar based on human readable string for which
    1135                 :            :   //! OutVar::name = matched token. OutVar::name being not empty will be used to
    1136                 :            :   //! differentiate a depvar-based outvar from a human-readable outvar.
    1137                 :            :   //! Depvar-based outvars can directly access solution arrays using their
    1138                 :            :   //! field. Human-readable outvars need a mechanism (a function) to read and
    1139                 :            :   //! compute their variables from solution arrays. The 'getvar' function, used
    1140                 :            :   //! to compute a physics variable from the numerical solution is assigned
    1141                 :            :   //! after initial migration and thus not assigned here (during parsing).
    1142                 :            :   template<>
    1143                 :            :   struct action< push_humanvar > {
    1144                 :            :     template< typename Input, typename Stack >
    1145                 :        752 :     static void apply( const Input& in, Stack& stack ) {
    1146                 :            :       brigand::for_each< inciter::ctr::parameters::Keys >
    1147         [ +  - ]:        752 :                        ( AddOutVarHuman< Stack >( stack, in.string() ) );
    1148                 :        752 :     }
    1149                 :            :   };
    1150                 :            : 
    1151                 :            :   //! Rule used to trigger action
    1152                 :            :   struct set_outvar_alias : pegtl::success {};
    1153                 :            :   //! Set alias of last pushed output variable
    1154                 :            :   template<>
    1155                 :            :   struct action< set_outvar_alias > {
    1156                 :            :     template< typename Input, typename Stack >
    1157                 :        658 :     static void apply( const Input& in, Stack& stack ) {
    1158                 :            :       // Set alias of last pushed outvar:
    1159                 :        658 :       auto& vars = stack.template get< tag::cmd, tag::io, tag::outvar >();
    1160         [ +  - ]:        658 :       if (!vars.empty()) vars.back().alias = in.string();
    1161                 :        658 :     }
    1162                 :            :   };
    1163                 :            : 
    1164                 :            :   //! Function object for error checking outvar bounds for each equation type
    1165                 :            :   template< typename Stack >
    1166                 :            :   struct OutVarBounds {
    1167                 :            :     const Stack& stack;
    1168                 :            :     bool& inbounds;
    1169                 :         85 :     explicit OutVarBounds( const Stack& s, bool& i )
    1170                 :         85 :       : stack(s), inbounds(i) { inbounds = false; }
    1171                 :        255 :     template< typename U > void operator()( brigand::type_<U> ) {
    1172                 :         85 :       if (std::is_same_v< U, tag::multimat >) inbounds = true;  // skip multimat
    1173                 :        255 :       const auto& depvar = stack.template get< tag::param, U, tag::depvar >();
    1174                 :        255 :       const auto& ncomp = stack.template get< tag::component, U >();
    1175 [ -  + ][ -  - ]:        255 :       Assert( depvar.size() == ncomp.size(), "Size mismatch" );
         [ -  - ][ -  - ]
    1176                 :            :       // called after matching each outvar, so only check the last one
    1177                 :        255 :       auto& vars = stack.template get< tag::cmd, tag::io, tag::outvar >();
    1178                 :        255 :       const auto& last_outvar = vars.back();
    1179                 :        255 :       const auto& v = static_cast<char>( std::tolower(last_outvar.var) );
    1180         [ +  + ]:        340 :       for (std::size_t e=0; e<depvar.size(); ++e)
    1181 [ +  - ][ +  - ]:         85 :         if (v == depvar[e] && last_outvar.field < ncomp[e]) inbounds = true;
                 [ +  - ]
    1182                 :        255 :     }
    1183                 :            :   };
    1184                 :            : 
    1185                 :            :   //! Rule used to trigger action
    1186                 :            :   struct check_outvar : pegtl::success {};
    1187                 :            :   //! Bounds checking for output variables at the end of a var ... end block
    1188                 :            :   template<>
    1189                 :            :   struct action< check_outvar > {
    1190                 :            :     template< typename Input, typename Stack >
    1191                 :         85 :     static void apply( const Input& in, Stack& stack ) {
    1192                 :            :       bool inbounds;
    1193                 :            :       brigand::for_each< inciter::ctr::parameters::Keys >
    1194         [ +  - ]:         85 :                        ( OutVarBounds< Stack >( stack, inbounds ) );
    1195         [ -  + ]:         85 :       if (!inbounds)
    1196         [ -  - ]:          0 :         Message< Stack, ERROR, MsgKey::NOSUCHCOMPONENT >( stack, in );
    1197                 :         85 :     }
    1198                 :            :   };
    1199                 :            : 
    1200                 :            :   //! Rule used to trigger action
    1201                 :            :   struct set_centering : pegtl::success {};
    1202                 :            :   //! Set variable centering in parser's state
    1203                 :            :   template<>
    1204                 :            :   struct action< set_centering > {
    1205                 :            :     template< typename Input, typename Stack >
    1206                 :         86 :     static void apply( const Input& in, Stack& ) {
    1207                 :         86 :       inciter::deck::centering =
    1208         [ +  + ]:         86 :         (in.string() == "node") ? tk::Centering::NODE : tk::Centering::ELEM;
    1209                 :         86 :     }
    1210                 :            :   };
    1211                 :            : 
    1212                 :            :   //! Rule used to trigger action
    1213                 :            :   struct match_outvar : pegtl::success {};
    1214                 :            :   //! Match output variable based on depvar
    1215                 :            :   template<>
    1216                 :            :   struct action< match_outvar > {
    1217                 :            :     template< typename Input, typename Stack >
    1218                 :         85 :     static void apply( const Input& in, Stack& stack ) {
    1219                 :            :       using inciter::deck::neq;
    1220                 :            :       using inciter::deck::multimatvars;
    1221                 :            :       // convert matched string to char
    1222 [ +  - ][ +  - ]:         85 :       auto var = stack.template convert< char >( in.string() );
    1223         [ +  + ]:         85 :       if (neq.get< tag::multimat >() == 0) {    // if not multimat
    1224                 :            :         // find matched variable in set of selected ones
    1225 [ +  - ][ +  - ]:         59 :         if (depvars.find(var) != end(depvars))
    1226         [ +  - ]:         59 :           action< push_depvar >::apply( in, stack );
    1227                 :            :         else  // error out if matched var is not selected
    1228         [ -  - ]:          0 :           Message< Stack, ERROR, MsgKey::NOSUCHOUTVAR >( stack, in );
    1229                 :            :       } else {    // if multimat
    1230                 :            :         // find matched variable in set accepted for multimat
    1231 [ +  - ][ +  - ]:         26 :         if (multimatvars.find(var) != end(multimatvars))
    1232         [ +  - ]:         26 :           action< push_matvar >::apply( in, stack );
    1233                 :            :         else
    1234         [ -  - ]:          0 :           Message< Stack, ERROR, MsgKey::NOSUCHMULTIMATVAR >( stack, in );
    1235                 :            :       }
    1236                 :         85 :     }
    1237                 :            :   };
    1238                 :            : 
    1239                 :            :   // Store mesh/solver id as a source of a transfer
    1240                 :            :   template< typename Stack > struct store_transfer_src {
    1241                 :          0 :     store_transfer_src( Stack& stack, std::size_t i ) {
    1242         [ -  - ]:          0 :       stack.template get< tag::couple, tag::transfer >().emplace_back( i, 0 );
    1243                 :          0 :     }
    1244                 :            :   };
    1245                 :            : 
    1246                 :            :   // Store mesh/solver id as a destination of a transfer
    1247                 :            :   template< typename Stack > struct store_transfer_dst {
    1248                 :          0 :     store_transfer_dst( Stack& stack, std::size_t i ) {
    1249                 :          0 :       stack.template get< tag::couple, tag::transfer >().back().dst = i;
    1250                 :          0 :     }
    1251                 :            :   };
    1252                 :            : 
    1253                 :            :   //! Rule used to trigger action
    1254                 :            :   template< template< class > class StoreTransfer >
    1255                 :            :   struct push_transfer : pegtl::success {};
    1256                 :            :   //! Add matched value as a source or destination of solution transfer
    1257                 :            :   //! \tparam StoreTransfer Type of action to invoke: source or destination
    1258                 :            :   template< template< class > class StoreTransfer >
    1259                 :            :   struct action< push_transfer< StoreTransfer > > {
    1260                 :            :     template< typename Input, typename Stack >
    1261                 :          0 :     static void apply( const Input& in, Stack& stack ) {
    1262                 :            :       // Extract dependent variables for solvers configured
    1263         [ -  - ]:          0 :       auto depvar = stack.depvar();
    1264                 :            :       // Store index of parsed depvar of transfer being configured
    1265 [ -  - ][ -  - ]:          0 :       auto c = in.string()[0];
    1266         [ -  - ]:          0 :       for (std::size_t i=0; i<depvar.size(); ++i)
    1267         [ -  - ]:          0 :         if (depvar[i] == c)
    1268         [ -  - ]:          0 :           StoreTransfer< Stack >( stack, i );
    1269                 :          0 :     }
    1270                 :            :   };
    1271                 :            : 
    1272                 :            : } // ::grm
    1273                 :            : } // ::tk
    1274                 :            : 
    1275                 :            : namespace inciter {
    1276                 :            : 
    1277                 :            : //! Inciter input deck facilitating user input for computing shock hydrodynamics
    1278                 :            : namespace deck {
    1279                 :            : 
    1280                 :            :   using namespace tao;
    1281                 :            : 
    1282                 :            :   // Inciter's InputDeck grammar
    1283                 :            : 
    1284                 :            :   //! scan and store_back equation keyword and option
    1285                 :            :   template< typename keyword, class eq >
    1286                 :            :   struct scan_eq :
    1287                 :            :          tk::grm::scan< typename keyword::pegtl_string,
    1288                 :            :                         tk::grm::store_back_option< use,
    1289                 :            :                                                     ctr::PDE,
    1290                 :            :                                                     tag::selected,
    1291                 :            :                                                     tag::pde > > {};
    1292                 :            : 
    1293                 :            :   //! Error checks after an equation...end block has been parsed
    1294                 :            :   template< class eq, template< class > class eqchecker >
    1295                 :            :   struct check_errors :
    1296                 :            :          pegtl::seq<
    1297                 :            :            // register differential equation block
    1298                 :            :            tk::grm::register_inciter_eq< eq >,
    1299                 :            :            // check mesh ... end block
    1300                 :            :            tk::grm::check_mesh< eq >,
    1301                 :            :            // do error checking on this block
    1302                 :            :            eqchecker< eq > > {};
    1303                 :            : 
    1304                 :            :   //! Match discretization option
    1305                 :            :   template< template< class > class use, class keyword, class Option,
    1306                 :            :             class Tag >
    1307                 :            :   struct discroption :
    1308                 :            :          tk::grm::process< use< keyword >,
    1309                 :            :                            tk::grm::store_inciter_option<
    1310                 :            :                              Option, tag::discr, Tag >,
    1311                 :            :                            pegtl::alpha > {};
    1312                 :            : 
    1313                 :            :   //! Discretization parameters
    1314                 :            :   struct discretization :
    1315                 :            :          pegtl::sor<
    1316                 :            :            tk::grm::discrparam< use, kw::nstep, tag::nstep >,
    1317                 :            :            tk::grm::discrparam< use, kw::term, tag::term >,
    1318                 :            :            tk::grm::discrparam< use, kw::t0, tag::t0 >,
    1319                 :            :            tk::grm::discrparam< use, kw::dt, tag::dt >,
    1320                 :            :            tk::grm::discrparam< use, kw::cfl, tag::cfl >,
    1321                 :            :            tk::grm::discrparam< use, kw::residual, tag::residual >,
    1322                 :            :            tk::grm::discrparam< use, kw::rescomp, tag::rescomp >,
    1323                 :            :            tk::grm::process< use< kw::fcteps >,
    1324                 :            :                              tk::grm::Store< tag::discr, tag::fcteps > >,
    1325                 :            :            tk::grm::process< use< kw::fctclip >,
    1326                 :            :                              tk::grm::Store< tag::discr, tag::fctclip >,
    1327                 :            :                              pegtl::alpha >,
    1328                 :            :            tk::grm::process< use< kw::fct >,
    1329                 :            :                              tk::grm::Store< tag::discr, tag::fct >,
    1330                 :            :                              pegtl::alpha >,
    1331                 :            :            tk::grm::process< use< kw::ctau >,
    1332                 :            :                              tk::grm::Store< tag::discr, tag::ctau > >,
    1333                 :            :            tk::grm::process< use< kw::pelocal_reorder >,
    1334                 :            :                              tk::grm::Store< tag::discr, tag::pelocal_reorder >,
    1335                 :            :                              pegtl::alpha >,
    1336                 :            :            tk::grm::process< use< kw::operator_reorder >,
    1337                 :            :                              tk::grm::Store< tag::discr, tag::operator_reorder >,
    1338                 :            :                              pegtl::alpha >,
    1339                 :            :            tk::grm::process< use< kw::steady_state >,
    1340                 :            :                              tk::grm::Store< tag::discr, tag::steady_state >,
    1341                 :            :                              pegtl::alpha >,
    1342                 :            :            tk::grm::interval_iter< use< kw::ttyi >,
    1343                 :            :                                    tag::output, tag::iter, tag::tty >,
    1344                 :            :            tk::grm::process_alpha< use< kw::scheme >,
    1345                 :            :                                    tk::grm::store_inciter_option<
    1346                 :            :                                      inciter::ctr::Scheme,
    1347                 :            :                                      tag::discr,
    1348                 :            :                                      tag::scheme >,
    1349                 :            :                                    tk::grm::configure_scheme >,
    1350                 :            :            discroption< use, kw::limiter, inciter::ctr::Limiter, tag::limiter >,
    1351                 :            :            tk::grm::discrparam< use, kw::cweight, tag::cweight >
    1352                 :            :          > {};
    1353                 :            : 
    1354                 :            :   //! PDE parameter vector
    1355                 :            :   template< class keyword, class eq, class param, class... xparams >
    1356                 :            :   struct pde_parameter_vector :
    1357                 :            :          tk::grm::parameter_vector< use,
    1358                 :            :                                     use< keyword >,
    1359                 :            :                                     tk::grm::Store_back_back,
    1360                 :            :                                     tk::grm::start_vector,
    1361                 :            :                                     tk::grm::check_vector,
    1362                 :            :                                     eq, param, xparams... > {};
    1363                 :            : 
    1364                 :            :    //! Match box parameter
    1365                 :            :   template< class eq, typename keyword, typename target >
    1366                 :            :   struct box_parameter :
    1367                 :            :            pegtl::if_must<
    1368                 :            :              tk::grm::readkw< typename use<keyword>::pegtl_string >,
    1369                 :            :              tk::grm::scan<
    1370                 :            :                pegtl::sor< tk::grm::number,
    1371                 :            :                            tk::grm::msg< tk::grm::ERROR,
    1372                 :            :                                          tk::grm::MsgKey::MISSING > >,
    1373                 :            :                tk::grm::Back_back_store< target,
    1374                 :            :                  tag::param, eq, tag::ic, tag::box > > > {};
    1375                 :            : 
    1376                 :            :    //! Match box parameter and store deep
    1377                 :            :   template< class eq, typename keyword, typename target, typename subtarget >
    1378                 :            :   struct box_deep_parameter :
    1379                 :            :            pegtl::if_must<
    1380                 :            :              tk::grm::readkw< typename use<keyword>::pegtl_string >,
    1381                 :            :              tk::grm::scan<
    1382                 :            :                pegtl::sor< tk::grm::number,
    1383                 :            :                            tk::grm::msg< tk::grm::ERROR,
    1384                 :            :                                          tk::grm::MsgKey::MISSING > >,
    1385                 :            :                tk::grm::Back_back_deep_store< target, subtarget,
    1386                 :            :                  tag::param, eq, tag::ic, tag::box > > > {};
    1387                 :            : 
    1388                 :            :    //! Match box parameter vector
    1389                 :            :   template< class eq, typename keyword, typename target >
    1390                 :            :   struct box_vector :
    1391                 :            :          tk::grm::vector< use< keyword >,
    1392                 :            :                           tk::grm::Back_back_store_back< target,
    1393                 :            :                             tag::param, eq, tag::ic, tag::box >,
    1394                 :            :                           use< kw::end > > {};
    1395                 :            : 
    1396                 :            :    //! Match box parameter vector and store deep
    1397                 :            :   template< class eq, typename keyword, typename target, typename subtarget >
    1398                 :            :   struct box_deep_vector :
    1399                 :            :          tk::grm::vector< use< keyword >,
    1400                 :            :                           tk::grm::Back_back_deep_store_back< target, subtarget,
    1401                 :            :                             tag::param, eq, tag::ic, tag::box >,
    1402                 :            :                           use< kw::end > > {};
    1403                 :            : 
    1404                 :            : 
    1405                 :            :    //! Match box option
    1406                 :            :   template< class eq, typename Option, typename keyword, typename target,
    1407                 :            :             typename subtarget >
    1408                 :            :   struct box_option :
    1409                 :            :          tk::grm::process<
    1410                 :            :            use< keyword >,
    1411                 :            :            tk::grm::back_back_deep_store_option< target, subtarget, use,
    1412                 :            :              Option, tag::param, eq, tag::ic, tag::box >,
    1413                 :            :            pegtl::alpha > {};
    1414                 :            : 
    1415                 :            :    //! Match material option
    1416                 :            :   template< class eq, typename Option, typename keyword, typename target >
    1417                 :            :   struct material_option :
    1418                 :            :          tk::grm::process<
    1419                 :            :            use< keyword >,
    1420                 :            :            tk::grm::back_back_store_option< target, use, Option,
    1421                 :            :              tag::param, eq, tag::material >,
    1422                 :            :            pegtl::alpha > {};
    1423                 :            : 
    1424                 :            :   //! Match material parameter vector
    1425                 :            :   template< class eq, typename keyword, typename target >
    1426                 :            :   struct material_vector :
    1427                 :            :          tk::grm::vector< use< keyword >,
    1428                 :            :                           tk::grm::Back_back_store_back< target,
    1429                 :            :                             tag::param, eq, tag::material >,
    1430                 :            :                           use< kw::end > > {};
    1431                 :            : 
    1432                 :            :   //! put in PDE parameter for equation matching keyword
    1433                 :            :   template< typename eq, typename keyword, typename param,
    1434                 :            :             class kw_type = tk::grm::number >
    1435                 :            :   struct parameter :
    1436                 :            :          tk::grm::process< use< keyword >,
    1437                 :            :                            tk::grm::Store_back< tag::param, eq, param >,
    1438                 :            :                            kw_type > {};
    1439                 :            : 
    1440                 :            :   //! put in PDE bool parameter for equation matching keyword into vector< int >
    1441                 :            :   template< typename eq, typename keyword, typename p >
    1442                 :            :   struct parameter_bool :
    1443                 :            :          tk::grm::process< use< keyword >,
    1444                 :            :                            tk::grm::Store_back_bool< tag::param, eq, p >,
    1445                 :            :                            pegtl::alpha > {};
    1446                 :            : 
    1447                 :            :   //! Boundary conditions block
    1448                 :            :   template< class keyword, class eq, class param >
    1449                 :            :   struct bc :
    1450                 :            :          pegtl::if_must<
    1451                 :            :            tk::grm::readkw< typename use< keyword >::pegtl_string >,
    1452                 :            :            tk::grm::block<
    1453                 :            :              use< kw::end >,
    1454                 :            :              tk::grm::parameter_vector< use,
    1455                 :            :                                         use< kw::sideset >,
    1456                 :            :                                         tk::grm::Store_back_back,
    1457                 :            :                                         tk::grm::start_vector,
    1458                 :            :                                         tk::grm::check_vector,
    1459                 :            :                                         eq, tag::bc, param > > > {};
    1460                 :            : 
    1461                 :            :   //! Match user-defined function as a discrete list of real numbers
    1462                 :            :   template< class target, template< class... > class insert, class tag,
    1463                 :            :     class... tags >
    1464                 :            :   struct user_fn :
    1465                 :            :          pegtl::if_must<
    1466                 :            :            tk::grm::readkw< use< kw::fn >::pegtl_string >,
    1467                 :            :            tk::grm::block< use< kw::end >,
    1468                 :            :              tk::grm::scan< tk::grm::number,
    1469                 :            :                insert< target, tag, tags... > > > > {};
    1470                 :            : 
    1471                 :            :   //! User defined time dependent BC bc_timedep...end block
    1472                 :            :   template< class eq >
    1473                 :            :   struct timedep_bc :
    1474                 :            :          pegtl::if_must<
    1475                 :            :            tk::grm::readkw< use< kw::bc_timedep >::pegtl_string >,
    1476                 :            :            tk::grm::start_vector_back< tag::param, eq, tag::bctimedep >,
    1477                 :            :            tk::grm::block< use< kw::end >,
    1478                 :            :              user_fn< tag::fn, tk::grm::Back_back_store_back, tag::param, eq,
    1479                 :            :                tag::bctimedep >,
    1480                 :            :              pegtl::if_must< tk::grm::vector< use< kw::sideset >,
    1481                 :            :                tk::grm::Back_back_store_back< tag::sideset, tag::param, eq,
    1482                 :            :                  tag::bctimedep >,
    1483                 :            :                use< kw::end > > > > > {};
    1484                 :            : 
    1485                 :            :   //! Stagnation boundary conditions block
    1486                 :            :   template< class eq, class bc, class kwbc >
    1487                 :            :   struct bc_spec :
    1488                 :            :          pegtl::if_must<
    1489                 :            :            tk::grm::readkw< typename kwbc::pegtl_string >,
    1490                 :            :            tk::grm::block<
    1491                 :            :              use< kw::end >,
    1492                 :            :              tk::grm::parameter_vector< use,
    1493                 :            :                                         use< kw::radius >,
    1494                 :            :                                         tk::grm::Store_back_back,
    1495                 :            :                                         tk::grm::start_vector,
    1496                 :            :                                         tk::grm::check_vector,
    1497                 :            :                                         eq, bc, tag::radius >,
    1498                 :            :              tk::grm::parameter_vector< use,
    1499                 :            :                                         use< kw::point >,
    1500                 :            :                                         tk::grm::Store_back_back,
    1501                 :            :                                         tk::grm::start_vector,
    1502                 :            :                                         tk::grm::check_vector,
    1503                 :            :                                         eq, bc, tag::point > > > {};
    1504                 :            : 
    1505                 :            :   //! Boundary conditions block
    1506                 :            :   template< class eq >
    1507                 :            :   struct sponge :
    1508                 :            :          pegtl::if_must<
    1509                 :            :            tk::grm::readkw< typename use< kw::sponge >::pegtl_string >,
    1510                 :            :            tk::grm::block<
    1511                 :            :              use< kw::end >,
    1512                 :            :              tk::grm::parameter_vector< use,
    1513                 :            :                                         use< kw::velocity >,
    1514                 :            :                                         tk::grm::Store_back_back,
    1515                 :            :                                         tk::grm::start_vector,
    1516                 :            :                                         tk::grm::check_vector,
    1517                 :            :                                         eq, tag::sponge, tag::velocity >,
    1518                 :            :              tk::grm::parameter_vector< use,
    1519                 :            :                                         use< kw::pressure >,
    1520                 :            :                                         tk::grm::Store_back_back,
    1521                 :            :                                         tk::grm::start_vector,
    1522                 :            :                                         tk::grm::check_vector,
    1523                 :            :                                         eq, tag::sponge, tag::pressure >,
    1524                 :            :              tk::grm::parameter_vector< use,
    1525                 :            :                                         use< kw::sideset >,
    1526                 :            :                                         tk::grm::Store_back_back,
    1527                 :            :                                         tk::grm::start_vector,
    1528                 :            :                                         tk::grm::check_vector,
    1529                 :            :                                         eq, tag::sponge, tag::sideset > > > {};
    1530                 :            : 
    1531                 :            :   //! Farfield boundary conditions block
    1532                 :            :   template< class keyword, class eq, class param >
    1533                 :            :   struct farfield_bc :
    1534                 :            :          pegtl::if_must<
    1535                 :            :            tk::grm::readkw< typename use< keyword >::pegtl_string >,
    1536                 :            :            tk::grm::block<
    1537                 :            :              use< kw::end >,
    1538                 :            :              parameter< eq, kw::pressure, tag::farfield_pressure >,
    1539                 :            :              parameter< eq, kw::density, tag::farfield_density >,
    1540                 :            :              pde_parameter_vector< kw::velocity, eq,
    1541                 :            :                                    tag::farfield_velocity >,
    1542                 :            :              tk::grm::parameter_vector< use,
    1543                 :            :                                         use< kw::sideset >,
    1544                 :            :                                         tk::grm::Store_back_back,
    1545                 :            :                                         tk::grm::start_vector,
    1546                 :            :                                         tk::grm::check_vector,
    1547                 :            :                                         eq, tag::bc, param > > > {};
    1548                 :            : 
    1549                 :            :   //! edgelist ... end block
    1550                 :            :   struct edgelist :
    1551                 :            :          tk::grm::vector< use< kw::amr_edgelist >,
    1552                 :            :                           tk::grm::Store_back< tag::amr, tag::edge >,
    1553                 :            :                           use< kw::end >,
    1554                 :            :                           tk::grm::check_vector< tag::amr, tag::edge > > {};
    1555                 :            : 
    1556                 :            :   //! xminus configuring coordinate-based edge tagging for mesh refinement
    1557                 :            :   template< typename keyword, typename Tag >
    1558                 :            :   struct half_world :
    1559                 :            :          tk::grm::control< use< keyword >, pegtl::digit, tk::grm::Store,
    1560                 :            :                            tag::amr, Tag > {};
    1561                 :            : 
    1562                 :            :   //! coords ... end block
    1563                 :            :   struct coords :
    1564                 :            :            pegtl::if_must<
    1565                 :            :              tk::grm::readkw< use< kw::amr_coords >::pegtl_string >,
    1566                 :            :              tk::grm::block< use< kw::end >,
    1567                 :            :                              half_world< kw::amr_xminus, tag::xminus >,
    1568                 :            :                              half_world< kw::amr_xplus, tag::xplus >,
    1569                 :            :                              half_world< kw::amr_yminus, tag::yminus >,
    1570                 :            :                              half_world< kw::amr_yplus, tag::yplus >,
    1571                 :            :                              half_world< kw::amr_zminus, tag::zminus >,
    1572                 :            :                              half_world< kw::amr_zplus, tag::zplus > > > {};
    1573                 :            : 
    1574                 :            :   //! initial conditins box block
    1575                 :            :   template< class eq >
    1576                 :            :   struct box :
    1577                 :            :          pegtl::if_must<
    1578                 :            :            tk::grm::readkw< use< kw::box >::pegtl_string >,
    1579                 :            :            tk::grm::start_vector_back< tag::param, eq, tag::ic, tag::box >,
    1580                 :            :            tk::grm::block< use< kw::end >
    1581                 :            :              , box_parameter< eq, kw::xmin, tag::xmin >
    1582                 :            :              , box_parameter< eq, kw::xmax, tag::xmax >
    1583                 :            :              , box_parameter< eq, kw::ymin, tag::ymin >
    1584                 :            :              , box_parameter< eq, kw::ymax, tag::ymax >
    1585                 :            :              , box_parameter< eq, kw::zmin, tag::zmin >
    1586                 :            :              , box_parameter< eq, kw::zmax, tag::zmax >
    1587                 :            :              , box_parameter< eq, kw::materialid, tag::materialid >
    1588                 :            :              , box_parameter< eq, kw::density, tag::density >
    1589                 :            :              , box_parameter< eq, kw::pressure, tag::pressure >
    1590                 :            :              , box_parameter< eq, kw::temperature, tag::temperature >
    1591                 :            :              , box_parameter< eq, kw::energy_content, tag::energy_content >
    1592                 :            :              , box_parameter< eq, kw::energy, tag::energy >
    1593                 :            :              , box_parameter< eq, kw::mass, tag::mass >
    1594                 :            :              , box_vector< eq, kw::velocity, tag::velocity >
    1595                 :            :              , box_option< eq, ctr::Initiate, kw::initiate, tag::initiate,
    1596                 :            :                            tag::init >
    1597                 :            :              , pegtl::if_must<
    1598                 :            :                  tk::grm::readkw< use< kw::linear >::pegtl_string >,
    1599                 :            :                  tk::grm::block< use< kw::end >
    1600                 :            :                    , box_deep_vector< eq, kw::point, tag::initiate, tag::point >
    1601                 :            :                    , box_deep_parameter< eq, kw::radius, tag::initiate,
    1602                 :            :                                          tag::radius >
    1603                 :            :                    , box_deep_parameter< eq, kw::velocity, tag::initiate,
    1604                 :            :                                          tag::velocity > > >
    1605                 :            :              > > {};
    1606                 :            : 
    1607                 :            :   //! initial conditions block for compressible flow
    1608                 :            :   template< class eq >
    1609                 :            :   struct ic :
    1610                 :            :          pegtl::if_must<
    1611                 :            :            tk::grm::readkw< use< kw::ic >::pegtl_string >,
    1612                 :            :            tk::grm::block< use< kw::end >,
    1613                 :            :              pegtl::sor<
    1614                 :            :                pde_parameter_vector< kw::density, eq,
    1615                 :            :                                      tag::ic, tag::density >,
    1616                 :            :                pde_parameter_vector< kw::materialid, eq,
    1617                 :            :                                      tag::ic, tag::materialid >,
    1618                 :            :                pde_parameter_vector< kw::velocity, eq,
    1619                 :            :                                      tag::ic, tag::velocity >,
    1620                 :            :                pde_parameter_vector< kw::pressure, eq,
    1621                 :            :                                      tag::ic, tag::pressure >,
    1622                 :            :                pde_parameter_vector< kw::temperature, eq,
    1623                 :            :                                      tag::ic, tag::temperature >,
    1624                 :            :                pde_parameter_vector< kw::energy, eq,
    1625                 :            :                                      tag::ic, tag::energy > >,
    1626                 :            :                pegtl::seq< box< eq > > > > {};
    1627                 :            : 
    1628                 :            :   //! put in material property for equation matching keyword
    1629                 :            :   template< typename eq, typename keyword, typename property >
    1630                 :            :   struct material_property :
    1631                 :            :          pde_parameter_vector< keyword, eq, property > {};
    1632                 :            : 
    1633                 :            :   //! Material properties block for compressible flow
    1634                 :            :   template< class eq >
    1635                 :            :   struct material_properties :
    1636                 :            :          pegtl::seq<
    1637                 :            :           pegtl::if_must<
    1638                 :            :             tk::grm::readkw< use< kw::material >::pegtl_string >,
    1639                 :            :               tk::grm::start_vector_back< tag::param, eq, tag::material >,
    1640                 :            :             tk::grm::block< use< kw::end >,
    1641                 :            :                 material_vector< eq, kw::id, tag::id >
    1642                 :            :               , material_vector< eq, kw::mat_gamma, tag::gamma >
    1643                 :            :               , material_vector< eq, kw::mat_mu, tag::mu >
    1644                 :            :               , material_vector< eq, kw::mat_pstiff, tag::pstiff >
    1645                 :            :               , material_vector< eq, kw::mat_cv, tag::cv >
    1646                 :            :               , material_vector< eq, kw::mat_k, tag::k >
    1647                 :            :               , material_option< eq, ctr::Material, kw::eos, tag::eos >
    1648                 :            :             > > > {};
    1649                 :            : 
    1650                 :            :   //! Mesh ... end block
    1651                 :            :   template< class eq >
    1652                 :            :   struct mesh :
    1653                 :            :          pegtl::if_must<
    1654                 :            :            tk::grm::readkw< use< kw::mesh >::pegtl_string >,
    1655                 :            :            tk::grm::block< use< kw::end >,
    1656                 :            :              tk::grm::filename< use, tag::param, eq, tag::mesh, tag::filename >
    1657                 :            :            , pde_parameter_vector< kw::location, eq, tag::mesh, tag::location >
    1658                 :            :            , pde_parameter_vector< kw::orientation, eq,
    1659                 :            :                                    tag::mesh, tag::orientation >
    1660                 :            :            , tk::grm::process<
    1661                 :            :                use< kw::reference >,
    1662                 :            :                tk::grm::Store_back< tag::param, eq, tag::mesh, tag::reference >,
    1663                 :            :                pegtl::alpha >
    1664                 :            :            > > {};
    1665                 :            : 
    1666                 :            :   //! transport equation for scalars
    1667                 :            :   struct transport :
    1668                 :            :          pegtl::if_must<
    1669                 :            :            scan_eq< use< kw::transport >, tag::transport >,
    1670                 :            :            tk::grm::block< use< kw::end >,
    1671                 :            :                            tk::grm::policy< use,
    1672                 :            :                                             use< kw::physics >,
    1673                 :            :                                             ctr::Physics,
    1674                 :            :                                             tag::transport,
    1675                 :            :                                             tag::physics >,
    1676                 :            :                            tk::grm::policy< use,
    1677                 :            :                                             use< kw::problem >,
    1678                 :            :                                             ctr::Problem,
    1679                 :            :                                             tag::transport,
    1680                 :            :                                             tag::problem >,
    1681                 :            :                            tk::grm::depvar< use,
    1682                 :            :                                             tag::transport,
    1683                 :            :                                             tag::depvar >,
    1684                 :            :                            mesh< tag::transport >,
    1685                 :            :                            tk::grm::component< use< kw::ncomp >,
    1686                 :            :                                                tag::transport >,
    1687                 :            :                            pde_parameter_vector< kw::pde_diffusivity,
    1688                 :            :                                                  tag::transport,
    1689                 :            :                                                  tag::diffusivity >,
    1690                 :            :                            pde_parameter_vector< kw::pde_lambda,
    1691                 :            :                                                  tag::transport,
    1692                 :            :                                                  tag::lambda >,
    1693                 :            :                            pde_parameter_vector< kw::pde_u0,
    1694                 :            :                                                  tag::transport,
    1695                 :            :                                                  tag::u0 >,
    1696                 :            :                            bc< kw::bc_dirichlet, tag::transport, tag::bcdir >,
    1697                 :            :                            bc< kw::bc_sym, tag::transport, tag::bcsym >,
    1698                 :            :                            bc< kw::bc_inlet, tag::transport, tag::bcinlet >,
    1699                 :            :                            bc< kw::bc_outlet, tag::transport, tag::bcoutlet >,
    1700                 :            :                            bc< kw::bc_extrapolate, tag::transport,
    1701                 :            :                                tag::bcextrapolate >,
    1702                 :            :                            parameter< tag::transport,
    1703                 :            :                                       kw::intsharp_param,
    1704                 :            :                                       tag::intsharp_param >,
    1705                 :            :                            parameter< tag::transport,
    1706                 :            :                                       kw::intsharp,
    1707                 :            :                                       tag::intsharp > >,
    1708                 :            :            check_errors< tag::transport, tk::grm::check_transport > > {};
    1709                 :            : 
    1710                 :            :   //! compressible flow
    1711                 :            :   struct compflow :
    1712                 :            :          pegtl::if_must<
    1713                 :            :            scan_eq< use< kw::compflow >, tag::compflow >,
    1714                 :            :            tk::grm::start_vector< tag::param, tag::compflow, tag::ic, tag::box >,
    1715                 :            :            tk::grm::start_vector< tag::param, tag::compflow, tag::material >,
    1716                 :            :            tk::grm::start_vector< tag::param, tag::compflow, tag::bctimedep >,
    1717                 :            :            tk::grm::block< use< kw::end >,
    1718                 :            :                            tk::grm::policy< use,
    1719                 :            :                                             use< kw::physics >,
    1720                 :            :                                             ctr::Physics,
    1721                 :            :                                             tag::compflow,
    1722                 :            :                                             tag::physics >,
    1723                 :            :                            tk::grm::policy< use,
    1724                 :            :                                             use< kw::problem >,
    1725                 :            :                                             ctr::Problem,
    1726                 :            :                                             tag::compflow,
    1727                 :            :                                             tag::problem >,
    1728                 :            :                            tk::grm::depvar< use,
    1729                 :            :                                             tag::compflow,
    1730                 :            :                                             tag::depvar >,
    1731                 :            :                            mesh< tag::compflow >,
    1732                 :            :                            tk::grm::process<
    1733                 :            :                              use< kw::flux >,
    1734                 :            :                                tk::grm::store_back_option< use,
    1735                 :            :                                                            ctr::Flux,
    1736                 :            :                                                            tag::param,
    1737                 :            :                                                            tag::compflow,
    1738                 :            :                                                            tag::flux >,
    1739                 :            :                              pegtl::alpha >,
    1740                 :            :                            ic< tag::compflow >,
    1741                 :            :                            tk::grm::lua< use, tag::param, tag::compflow >,
    1742                 :            :                            material_properties< tag::compflow >,
    1743                 :            :                            pde_parameter_vector< kw::sysfctvar,
    1744                 :            :                                                  tag::compflow,
    1745                 :            :                                                  tag::sysfctvar >,
    1746                 :            :                            parameter_bool< tag::compflow,
    1747                 :            :                                            kw::sysfct,
    1748                 :            :                                            tag::sysfct >,
    1749                 :            :                            parameter< tag::compflow, kw::npar,
    1750                 :            :                                       tag::npar, pegtl::digit >,
    1751                 :            :                            parameter< tag::compflow, kw::pde_alpha,
    1752                 :            :                                       tag::alpha >,
    1753                 :            :                            parameter< tag::compflow, kw::pde_p0,
    1754                 :            :                                       tag::p0 >,
    1755                 :            :                            parameter< tag::compflow, kw::pde_betax,
    1756                 :            :                                       tag::betax >,
    1757                 :            :                            parameter< tag::compflow, kw::pde_betay,
    1758                 :            :                                       tag::betay >,
    1759                 :            :                            parameter< tag::compflow, kw::pde_betaz,
    1760                 :            :                                       tag::betaz >,
    1761                 :            :                            parameter< tag::compflow, kw::pde_beta,
    1762                 :            :                                       tag::beta >,
    1763                 :            :                            parameter< tag::compflow, kw::pde_r0,
    1764                 :            :                                       tag::r0 >,
    1765                 :            :                            parameter< tag::compflow, kw::pde_ce,
    1766                 :            :                                       tag::ce >,
    1767                 :            :                            parameter< tag::compflow, kw::pde_kappa,
    1768                 :            :                                       tag::kappa >,
    1769                 :            :                            bc< kw::bc_dirichlet, tag::compflow, tag::bcdir >,
    1770                 :            :                            bc< kw::bc_sym, tag::compflow, tag::bcsym >,
    1771                 :            :                            bc_spec< tag::compflow, tag::stag, kw::bc_stag >,
    1772                 :            :                            bc_spec< tag::compflow, tag::skip, kw::bc_skip >,
    1773                 :            :                            bc< kw::bc_inlet, tag::compflow, tag::bcinlet >,
    1774                 :            :                            sponge< tag::compflow >,
    1775                 :            :                            farfield_bc< kw::bc_farfield,
    1776                 :            :                                         tag::compflow,
    1777                 :            :                                         tag::bcfarfield >,
    1778                 :            :                            bc< kw::bc_extrapolate, tag::compflow,
    1779                 :            :                                tag::bcextrapolate >,
    1780                 :            :                            timedep_bc< tag::compflow >
    1781                 :            :                            >,
    1782                 :            :            check_errors< tag::compflow, tk::grm::check_compflow > > {};
    1783                 :            : 
    1784                 :            :   //! compressible multi-material flow
    1785                 :            :   struct multimat :
    1786                 :            :          pegtl::if_must<
    1787                 :            :            scan_eq< use< kw::multimat >, tag::multimat >,
    1788                 :            :            tk::grm::start_vector< tag::param, tag::multimat, tag::ic, tag::box >,
    1789                 :            :            tk::grm::start_vector< tag::param, tag::multimat, tag::material >,
    1790                 :            :            tk::grm::block< use< kw::end >,
    1791                 :            :                            tk::grm::policy< use,
    1792                 :            :                                             use< kw::physics >,
    1793                 :            :                                             ctr::Physics,
    1794                 :            :                                             tag::multimat,
    1795                 :            :                                             tag::physics >,
    1796                 :            :                            tk::grm::policy< use,
    1797                 :            :                                             use< kw::problem >,
    1798                 :            :                                             ctr::Problem,
    1799                 :            :                                             tag::multimat,
    1800                 :            :                                             tag::problem >,
    1801                 :            :                            tk::grm::depvar< use,
    1802                 :            :                                             tag::multimat,
    1803                 :            :                                             tag::depvar >,
    1804                 :            :                            mesh< tag::multimat >,
    1805                 :            :                            parameter< tag::multimat,
    1806                 :            :                                       kw::nmat,
    1807                 :            :                                       tag::nmat >,
    1808                 :            :                            tk::grm::process<
    1809                 :            :                              use< kw::flux >,
    1810                 :            :                                tk::grm::store_back_option< use,
    1811                 :            :                                                            ctr::Flux,
    1812                 :            :                                                            tag::param,
    1813                 :            :                                                            tag::multimat,
    1814                 :            :                                                            tag::flux >,
    1815                 :            :                              pegtl::alpha >,
    1816                 :            :                            ic< tag::multimat >,
    1817                 :            :                            material_properties< tag::multimat >,
    1818                 :            :                            parameter< tag::multimat,
    1819                 :            :                                       kw::pde_alpha,
    1820                 :            :                                       tag::alpha >,
    1821                 :            :                            parameter< tag::multimat,
    1822                 :            :                                       kw::pde_p0,
    1823                 :            :                                       tag::p0 >,
    1824                 :            :                            parameter< tag::multimat,
    1825                 :            :                                       kw::pde_beta,
    1826                 :            :                                       tag::beta >,
    1827                 :            :                            bc< kw::bc_dirichlet,
    1828                 :            :                                tag::multimat,
    1829                 :            :                                tag::bcdir >,
    1830                 :            :                            bc< kw::bc_sym,
    1831                 :            :                                tag::multimat,
    1832                 :            :                                tag::bcsym >,
    1833                 :            :                            bc< kw::bc_inlet,
    1834                 :            :                                tag::multimat,
    1835                 :            :                                tag::bcinlet >,
    1836                 :            :                            bc< kw::bc_outlet,
    1837                 :            :                                tag::multimat,
    1838                 :            :                                tag::bcoutlet >,
    1839                 :            :                            bc< kw::bc_extrapolate,
    1840                 :            :                                tag::multimat,
    1841                 :            :                                tag::bcextrapolate >,
    1842                 :            :                            parameter< tag::multimat,
    1843                 :            :                                       kw::prelax_timescale,
    1844                 :            :                                       tag::prelax_timescale >,
    1845                 :            :                            parameter< tag::multimat,
    1846                 :            :                                       kw::prelax,
    1847                 :            :                                       tag::prelax >,
    1848                 :            :                            parameter< tag::multimat,
    1849                 :            :                                       kw::intsharp_param,
    1850                 :            :                                       tag::intsharp_param >,
    1851                 :            :                            parameter< tag::multimat,
    1852                 :            :                                       kw::intsharp,
    1853                 :            :                                       tag::intsharp > >,
    1854                 :            :            check_errors< tag::multimat, tk::grm::check_multimat > > {};
    1855                 :            : 
    1856                 :            :   //! partitioning ... end block
    1857                 :            :   struct partitioning :
    1858                 :            :          pegtl::if_must<
    1859                 :            :            tk::grm::readkw< use< kw::partitioning >::pegtl_string >,
    1860                 :            :            tk::grm::block< use< kw::end >,
    1861                 :            :                            tk::grm::process<
    1862                 :            :                              use< kw::algorithm >,
    1863                 :            :                              tk::grm::store_inciter_option<
    1864                 :            :                                tk::ctr::PartitioningAlgorithm,
    1865                 :            :                                tag::selected,
    1866                 :            :                                tag::partitioner >,
    1867                 :            :                              pegtl::alpha > > > {};
    1868                 :            : 
    1869                 :            :   //! equation types
    1870                 :            :   struct equations :
    1871                 :            :          pegtl::sor< transport, compflow, multimat > {};
    1872                 :            : 
    1873                 :            :   //! refinement variable(s) (refvar) ... end block
    1874                 :            :   struct refvars :
    1875                 :            :          pegtl::if_must<
    1876                 :            :            tk::grm::vector< use< kw::amr_refvar >,
    1877                 :            :                             tk::grm::match_depvar<
    1878                 :            :                               tk::grm::Store_back< tag::amr, tag::refvar > >,
    1879                 :            :                             use< kw::end >,
    1880                 :            :                             tk::grm::check_vector< tag::amr, tag::refvar >,
    1881                 :            :                             tk::grm::fieldvar< pegtl::alpha > >,
    1882                 :            :            tk::grm::compute_refvar_idx > {};
    1883                 :            : 
    1884                 :            :   //! adaptive mesh refinement (AMR) amr...end block
    1885                 :            :   struct amr :
    1886                 :            :          pegtl::if_must<
    1887                 :            :            tk::grm::readkw< use< kw::amr >::pegtl_string >,
    1888                 :            :            // enable AMR if amr...end block encountered
    1889                 :            :            tk::grm::enable< tag::amr >,
    1890                 :            :            tk::grm::block< use< kw::end >,
    1891                 :            :                            refvars,
    1892                 :            :                            edgelist,
    1893                 :            :                            coords,
    1894                 :            :                            tk::grm::process<
    1895                 :            :                              use< kw::amr_initial >,
    1896                 :            :                              tk::grm::store_back_option< use,
    1897                 :            :                                                          ctr::AMRInitial,
    1898                 :            :                                                          tag::amr,
    1899                 :            :                                                          tag::init >,
    1900                 :            :                              pegtl::alpha >,
    1901                 :            :                            tk::grm::process<
    1902                 :            :                              use< kw::amr_error >,
    1903                 :            :                              tk::grm::store_inciter_option<
    1904                 :            :                                ctr::AMRError,
    1905                 :            :                                tag::amr, tag::error >,
    1906                 :            :                              pegtl::alpha >,
    1907                 :            :                            tk::grm::control< use< kw::amr_tolref >,
    1908                 :            :                                              pegtl::digit,
    1909                 :            :                                              tk::grm::Store,
    1910                 :            :                                              tag::amr,
    1911                 :            :                                              tag::tolref >,
    1912                 :            :                            tk::grm::control< use< kw::amr_tolderef >,
    1913                 :            :                                              pegtl::digit,
    1914                 :            :                                              tk::grm::Store,
    1915                 :            :                                              tag::amr,
    1916                 :            :                                              tag::tolderef >,
    1917                 :            :                            tk::grm::process< use< kw::amr_t0ref >,
    1918                 :            :                              tk::grm::Store< tag::amr, tag::t0ref >,
    1919                 :            :                              pegtl::alpha >,
    1920                 :            :                            tk::grm::process< use< kw::amr_dtref_uniform >,
    1921                 :            :                              tk::grm::Store< tag::amr, tag::dtref_uniform >,
    1922                 :            :                              pegtl::alpha >,
    1923                 :            :                            tk::grm::process< use< kw::amr_dtref >,
    1924                 :            :                              tk::grm::Store< tag::amr, tag::dtref >,
    1925                 :            :                              pegtl::alpha >,
    1926                 :            :                            tk::grm::process< use< kw::amr_dtfreq >,
    1927                 :            :                              tk::grm::Store< tag::amr, tag::dtfreq >,
    1928                 :            :                              pegtl::digit > >,
    1929                 :            :            tk::grm::check_amr_errors > {};
    1930                 :            : 
    1931                 :            : 
    1932                 :            :   //! Arbitrary-Lagrangian-Eulerian (ALE) move...end block
    1933                 :            :   struct moving_sides :
    1934                 :            :          pegtl::if_must<
    1935                 :            :            tk::grm::readkw< use< kw::move >::pegtl_string >,
    1936                 :            :            tk::grm::start_vector< tag::ale, tag::move >,
    1937                 :            :            tk::grm::block< use< kw::end >,
    1938                 :            :              tk::grm::process<
    1939                 :            :                 use< kw::fntype >,
    1940                 :            :                 tk::grm::back_store_option< tag::fntype,
    1941                 :            :                                             use,
    1942                 :            :                                             tk::ctr::UserTable,
    1943                 :            :                                             tag::ale, tag::move >,
    1944                 :            :                 pegtl::alpha >,
    1945                 :            :              user_fn< tag::fn, tk::grm::Back_store_back, tag::ale, tag::move >,
    1946                 :            :              pegtl::if_must< tk::grm::vector< use< kw::sideset >,
    1947                 :            :                tk::grm::Back_store_back< tag::sideset, tag::ale, tag::move >,
    1948                 :            :                use< kw::end > > > > > {};
    1949                 :            : 
    1950                 :            :   //! Arbitrary-Lagrangian-Eulerian (ALE) ale...end block
    1951                 :            :   struct ale :
    1952                 :            :          pegtl::if_must<
    1953                 :            :            tk::grm::readkw< use< kw::ale >::pegtl_string >,
    1954                 :            :            // enable ALE if ale ...end block encountered
    1955                 :            :            tk::grm::enable< tag::ale >,
    1956                 :            :            tk::grm::block< use< kw::end >,
    1957                 :            :               tk::grm::control< use< kw::dvcfl >,
    1958                 :            :                                 pegtl::digit,
    1959                 :            :                                 tk::grm::Store,
    1960                 :            :                                 tag::ale, tag::dvcfl >,
    1961                 :            :               tk::grm::control< use< kw::vortmult >,
    1962                 :            :                                 pegtl::digit,
    1963                 :            :                                 tk::grm::Store,
    1964                 :            :                                 tag::ale, tag::vortmult >,
    1965                 :            :               tk::grm::control< use< kw::meshvel_maxit >,
    1966                 :            :                                 pegtl::digit,
    1967                 :            :                                 tk::grm::Store,
    1968                 :            :                                 tag::ale, tag::maxit >,
    1969                 :            :               tk::grm::control< use< kw::meshvel_tolerance >,
    1970                 :            :                                 pegtl::digit,
    1971                 :            :                                 tk::grm::Store,
    1972                 :            :                                 tag::ale, tag::tolerance >,
    1973                 :            :               moving_sides,
    1974                 :            :               tk::grm::process<
    1975                 :            :                 use< kw::meshvelocity >,
    1976                 :            :                 tk::grm::store_inciter_option< ctr::MeshVelocity,
    1977                 :            :                                                tag::ale, tag::meshvelocity >,
    1978                 :            :                 pegtl::alpha >,
    1979                 :            :               tk::grm::process<
    1980                 :            :                 use< kw::smoother >,
    1981                 :            :                 tk::grm::store_inciter_option< ctr::MeshVelocitySmoother,
    1982                 :            :                                                tag::ale, tag::smoother >,
    1983                 :            :                 pegtl::alpha >,
    1984                 :            :               pegtl::if_must< tk::grm::dimensions< use< kw::mesh_motion >,
    1985                 :            :                               tk::grm::Store_back< tag::ale, tag::mesh_motion >,
    1986                 :            :                               use< kw::end > > >,
    1987                 :            :               pegtl::if_must< tk::grm::vector< use< kw::meshforce >,
    1988                 :            :                               tk::grm::Store_back< tag::ale, tag::meshforce >,
    1989                 :            :                               use< kw::end > > >,
    1990                 :            :               pegtl::if_must<
    1991                 :            :                 tk::grm::readkw< use< kw::bc_dirichlet >::pegtl_string >,
    1992                 :            :                 tk::grm::block< use< kw::end >,
    1993                 :            :                   pegtl::if_must< tk::grm::vector< use< kw::sideset >,
    1994                 :            :                                   tk::grm::Store_back< tag::ale, tag::bcdir >,
    1995                 :            :                                   use< kw::end > > > > >,
    1996                 :            :               pegtl::if_must<
    1997                 :            :                 tk::grm::readkw< use< kw::bc_sym >::pegtl_string >,
    1998                 :            :                 tk::grm::block< use< kw::end >,
    1999                 :            :                   pegtl::if_must< tk::grm::vector< use< kw::sideset >,
    2000                 :            :                                   tk::grm::Store_back< tag::ale, tag::bcsym >,
    2001                 :            :                                   use< kw::end > > > > > >,
    2002                 :            :               tk::grm::check_ale > {};
    2003                 :            : 
    2004                 :            :   //! \brief Match a depvar, defined upstream of control file, coupling a
    2005                 :            :   //!   solver and store
    2006                 :            :   template< template< class > class action >
    2007                 :            :   struct coupled_solver :
    2008                 :            :          tk::grm::scan_until<
    2009                 :            :             pegtl::lower,
    2010                 :            :             tk::grm::match_depvar< tk::grm::push_transfer< action > > > {};
    2011                 :            : 
    2012                 :            :   //! Couple ... end block (used to configure solver coupling)
    2013                 :            :   struct couple :
    2014                 :            :          pegtl::if_must<
    2015                 :            :            tk::grm::readkw< use< kw::couple >::pegtl_string >,
    2016                 :            :            tk::grm::block< use< kw::end >,
    2017                 :            :              pegtl::seq<
    2018                 :            :                coupled_solver< tk::grm::store_transfer_src >,
    2019                 :            :                pegtl::one<'>'>,
    2020                 :            :                coupled_solver< tk::grm::store_transfer_dst > > > > {};
    2021                 :            : 
    2022                 :            :   //! p-adaptive refinement (pref) ...end block
    2023                 :            :   struct pref :
    2024                 :            :          pegtl::if_must<
    2025                 :            :            tk::grm::readkw< use< kw::pref >::pegtl_string >,
    2026                 :            :            tk::grm::block< use< kw::end >,
    2027                 :            :                            tk::grm::control< use< kw::pref_tolref >,
    2028                 :            :                                              pegtl::digit,
    2029                 :            :                                              tk::grm::Store,
    2030                 :            :                                              tag::pref,
    2031                 :            :                                              tag::tolref  >,
    2032                 :            :                            tk::grm::control< use< kw::pref_ndofmax >,
    2033                 :            :                                              pegtl::digit,
    2034                 :            :                                              tk::grm::Store,
    2035                 :            :                                              tag::pref,
    2036                 :            :                                              tag::ndofmax >,
    2037                 :            :                            tk::grm::process<
    2038                 :            :                              use< kw::pref_indicator >,
    2039                 :            :                              tk::grm::store_inciter_option<
    2040                 :            :                                ctr::PrefIndicator,
    2041                 :            :                                tag::pref, tag::indicator >,
    2042                 :            :                              pegtl::alpha >
    2043                 :            :                          >,
    2044                 :            :            tk::grm::check_pref_errors > {};
    2045                 :            : 
    2046                 :            :   //! Match output variable alias
    2047                 :            :   struct outvar_alias :
    2048                 :            :          tk::grm::quoted< tk::grm::set_outvar_alias > {};
    2049                 :            : 
    2050                 :            :   //! Match an output variable in a human readable form: var must be a keyword
    2051                 :            :   template< class var >
    2052                 :            :   struct outvar_human :
    2053                 :            :          tk::grm::exact_scan< use< var >, tk::grm::push_humanvar > {};
    2054                 :            : 
    2055                 :            :   //! Match an output variable based on depvar defined upstream of input file
    2056                 :            :   struct outvar_depvar :
    2057                 :            :            tk::grm::scan< tk::grm::fieldvar< pegtl::upper >,
    2058                 :            :              tk::grm::match_outvar, tk::grm::check_outvar > {};
    2059                 :            : 
    2060                 :            :   //! Parse a centering token and if matches, set centering in parser's state
    2061                 :            :   struct outvar_centering :
    2062                 :            :          pegtl::sor<
    2063                 :            :            tk::grm::exact_scan< use< kw::node >, tk::grm::set_centering >,
    2064                 :            :            tk::grm::exact_scan< use< kw::elem >, tk::grm::set_centering > > {};
    2065                 :            : 
    2066                 :            :   //! outvar ... end block
    2067                 :            :   struct outvar_block :
    2068                 :            :          pegtl::if_must<
    2069                 :            :            tk::grm::readkw< use< kw::outvar >::pegtl_string >,
    2070                 :            :            tk::grm::block<
    2071                 :            :              use< kw::end >
    2072                 :            :            , outvar_centering
    2073                 :            :            , outvar_depvar
    2074                 :            :            , outvar_alias
    2075                 :            :            , outvar_human< kw::outvar_density >
    2076                 :            :            , outvar_human< kw::outvar_xmomentum >
    2077                 :            :            , outvar_human< kw::outvar_ymomentum >
    2078                 :            :            , outvar_human< kw::outvar_zmomentum >
    2079                 :            :            , outvar_human< kw::outvar_specific_total_energy >
    2080                 :            :            , outvar_human< kw::outvar_volumetric_total_energy >
    2081                 :            :            , outvar_human< kw::outvar_xvelocity >
    2082                 :            :            , outvar_human< kw::outvar_yvelocity >
    2083                 :            :            , outvar_human< kw::outvar_zvelocity >
    2084                 :            :            , outvar_human< kw::outvar_pressure >
    2085                 :            :            , outvar_human< kw::outvar_material_indicator >
    2086                 :            :            , outvar_human< kw::outvar_analytic >
    2087                 :            :            > > {};
    2088                 :            : 
    2089                 :            :   //! field_output ... end block
    2090                 :            :   struct field_output :
    2091                 :            :          pegtl::if_must<
    2092                 :            :            tk::grm::readkw< use< kw::field_output >::pegtl_string >,
    2093                 :            :            tk::grm::block<
    2094                 :            :              use< kw::end >,
    2095                 :            :              outvar_block,
    2096                 :            :              tk::grm::process< use< kw::filetype >,
    2097                 :            :                                tk::grm::store_inciter_option<
    2098                 :            :                                  tk::ctr::FieldFile,
    2099                 :            :                                  tag::selected,
    2100                 :            :                                  tag::filetype >,
    2101                 :            :                                pegtl::alpha >,
    2102                 :            :              tk::grm::interval_iter< use< kw::interval_iter >,
    2103                 :            :                                      tag::output, tag::iter, tag::field >,
    2104                 :            :              tk::grm::interval_time< use< kw::interval_time >,
    2105                 :            :                                      tag::output, tag::time, tag::field >,
    2106                 :            :              tk::grm::time_range< use, kw::time_range,
    2107                 :            :                                   tag::output, tag::range, tag::field >,
    2108                 :            :              tk::grm::process<
    2109                 :            :                use< kw::refined >,
    2110                 :            :                tk::grm::Store< tag::cmd, tag::io, tag::refined >,
    2111                 :            :                pegtl::alpha >,
    2112                 :            :              pegtl::if_must<
    2113                 :            :                tk::grm::vector<
    2114                 :            :                  use< kw::sideset >,
    2115                 :            :                  tk::grm::Store_back< tag::cmd, tag::io, tag::surface >,
    2116                 :            :                  use< kw::end > > > > > {};
    2117                 :            : 
    2118                 :            :   //! history_output ... end block
    2119                 :            :   struct history_output :
    2120                 :            :          pegtl::if_must<
    2121                 :            :            tk::grm::readkw< use< kw::history_output >::pegtl_string >,
    2122                 :            :            tk::grm::block<
    2123                 :            :              use< kw::end >,
    2124                 :            :              outvar_block,
    2125                 :            :              tk::grm::interval_iter< use< kw::interval_iter >,
    2126                 :            :                tag::output, tag::iter, tag::history >,
    2127                 :            :              tk::grm::interval_time< use< kw::interval_time >,
    2128                 :            :                tag::output, tag::time, tag::history >,
    2129                 :            :              tk::grm::time_range< use, kw::time_range,
    2130                 :            :                                   tag::output, tag::range, tag::history >,
    2131                 :            :              tk::grm::precision< use, tag::history >,
    2132                 :            :              tk::grm::process<
    2133                 :            :                use< kw::txt_float_format >,
    2134                 :            :                tk::grm::store_inciter_option< tk::ctr::TxtFloatFormat,
    2135                 :            :                                               tag::flformat,
    2136                 :            :                                               tag::history >,
    2137                 :            :                pegtl::alpha >,
    2138                 :            :              pegtl::if_must<
    2139                 :            :                tk::grm::readkw< use< kw::point >::pegtl_string >,
    2140                 :            :                tk::grm::act< pegtl::identifier, tk::grm::match_pointname >,
    2141                 :            :                pegtl::seq<
    2142                 :            :                  tk::grm::start_vector< tag::history, tag::point >,
    2143                 :            :                  tk::grm::block<
    2144                 :            :                    use< kw::end >,
    2145                 :            :                    tk::grm::scan< tk::grm::number,
    2146                 :            :                      tk::grm::Store_back_back< tag::history, tag::point > > >
    2147                 :            :                > > > > {};
    2148                 :            : 
    2149                 :            :   //! 'inciter' block
    2150                 :            :   struct inciter :
    2151                 :            :          pegtl::if_must<
    2152                 :            :            tk::grm::readkw< use< kw::inciter >::pegtl_string >,
    2153                 :            :            pegtl::sor<
    2154                 :            :              pegtl::seq< tk::grm::block<
    2155                 :            :                            use< kw::end >,
    2156                 :            :                            discretization,
    2157                 :            :                            equations,
    2158                 :            :                            amr,
    2159                 :            :                            ale,
    2160                 :            :                            pref,
    2161                 :            :                            partitioning,
    2162                 :            :                            couple,
    2163                 :            :                            field_output,
    2164                 :            :                            history_output,
    2165                 :            :                            tk::grm::diagnostics<
    2166                 :            :                              use,
    2167                 :            :                              tk::grm::store_inciter_option > >,
    2168                 :            :                          tk::grm::check_inciter >,
    2169                 :            :             tk::grm::msg< tk::grm::MsgType::ERROR,
    2170                 :            :                           tk::grm::MsgKey::UNFINISHED > > > {};
    2171                 :            : 
    2172                 :            :   //! \brief All keywords
    2173                 :            :   struct keywords :
    2174                 :            :          pegtl::sor< tk::grm::title< use >, inciter > {};
    2175                 :            : 
    2176                 :            :   //! \brief Grammar entry point: parse keywords and ignores until eof
    2177                 :            :   struct read_file :
    2178                 :            :          tk::grm::read_file< keywords, tk::grm::ignore > {};
    2179                 :            : 
    2180                 :            : } // deck::
    2181                 :            : } // inciter::
    2182                 :            : 
    2183                 :            : #endif // InciterInputDeckGrammar_h

Generated by: LCOV version 1.14