Xyst test code coverage report
Current view: top level - Control - InciterConfig.cpp (source / functions) Hit Total Coverage
Commit: 7512f2d92be539d3e2bf801c81cb357720d8ffd7 Lines: 592 945 62.6 %
Date: 2025-04-27 10:04:21 Functions: 49 52 94.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 476 1802 26.4 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/Control/InciterConfig.cpp
       4                 :            :   \copyright 2012-2015 J. Bakosi,
       5                 :            :              2016-2018 Los Alamos National Security, LLC.,
       6                 :            :              2019-2021 Triad National Security, LLC.,
       7                 :            :              2022-2025 J. Bakosi
       8                 :            :              All rights reserved. See the LICENSE file for details.
       9                 :            :   \brief     Lua parser for Inciter's control file
      10                 :            :   \see       https://github.com/edubart/minilua
      11                 :            :   \see       https://www.codingwiththomas.com/blog/a-lua-c-api-cheat-sheet
      12                 :            : */
      13                 :            : // *****************************************************************************
      14                 :            : 
      15                 :            : #include "Compiler.hpp"
      16                 :            : 
      17                 :            : #if defined(__clang__)
      18                 :            :   #pragma clang diagnostic push
      19                 :            :   #pragma clang diagnostic ignored "-Wold-style-cast"
      20                 :            : #endif
      21                 :            : 
      22                 :            : #include "minilua.h"
      23                 :            : 
      24                 :            : #if defined(__clang__)
      25                 :            :   #pragma clang diagnostic pop
      26                 :            : #endif
      27                 :            : 
      28                 :            : #include "InciterConfig.hpp"
      29                 :            : 
      30                 :            : #include "NoWarning/charm++.hpp"
      31                 :            : 
      32                 :            : #include "XystConfig.hpp"
      33                 :            : #include "Exception.hpp"
      34                 :            : #include "Print.hpp"
      35                 :            : #include "TaggedTuple.hpp"
      36                 :            : #include "PrintTaggedTupleDeep.hpp"
      37                 :            : #include "Writer.hpp"
      38                 :            : 
      39                 :            : namespace inciter {
      40                 :            : 
      41                 :            : extern int g_nrestart;
      42                 :            : 
      43                 :            : namespace ctr {
      44                 :            : 
      45                 :            : static constexpr auto largeint = std::numeric_limits< int64_t >::max();
      46                 :            : static constexpr auto largeuint = std::numeric_limits< uint64_t >::max();
      47                 :            : static constexpr auto largereal = std::numeric_limits< double >::max();
      48                 :            : 
      49                 :            : void
      50                 :        271 : Config::cmdline( int argc, char** argv )
      51                 :            : // *****************************************************************************
      52                 :            : //! Contructor: parse inciter command line
      53                 :            : //! \param[in] argc Number of arguments to executable
      54                 :            : //! \param[in] argv Arguments to executable
      55                 :            : // *****************************************************************************
      56                 :            : {
      57         [ -  + ]:        271 :   if (!argc) return;
      58                 :            : 
      59                 :            :   // Defaults
      60 [ +  - ][ +  - ]:        271 :   if (!tk::git_commit().empty()) get< tag::commit >() = tk::git_commit();
                 [ +  - ]
      61         [ +  - ]:        271 :   get< tag::output >() = "out";
      62         [ +  - ]:        271 :   get< tag::diag >() = "diag";
      63         [ +  - ]:        271 :   get< tag::checkpoint >() = "restart";
      64                 :        271 :   get< tag::lbfreq >() = 1;
      65                 :        271 :   get< tag::rsfreq >() = 1000;
      66                 :            : 
      67         [ -  + ]:        271 :   if (argc == 1) {
      68         [ -  - ]:          0 :     help( argv );
      69         [ -  - ]:          0 :     CkExit( EXIT_FAILURE );
      70                 :            :   }
      71                 :        271 :   tk::Print print;
      72                 :            : 
      73                 :            :   // Process command line arguments
      74                 :            :   int c;
      75         [ +  + ]:       1285 :   while ((c = getopt( argc, argv, "bc:d:fh?i:l:no:qr:s:u:v" )) != -1) {
      76 [ +  + ][ +  - ]:       1017 :     switch (c) {
         [ +  + ][ +  - ]
         [ -  - ][ +  + ]
                    [ + ]
      77                 :          2 :       case '?':
      78                 :            :       case 'h':
      79                 :            :       default:
      80         [ +  - ]:          2 :         help( argv );
      81         [ -  - ]:          2 :         CkExit();
      82                 :          0 :         break;
      83                 :        108 :       case 'b':
      84                 :        108 :         get< tag::benchmark >() = true;
      85                 :        108 :         break;
      86                 :        268 :       case 'c':
      87         [ +  - ]:        268 :         get< tag::control >() = optarg;
      88                 :        268 :         break;
      89                 :          0 :       case 'd':
      90         [ -  - ]:          0 :         get< tag::diag >() = optarg;
      91                 :          0 :         break;
      92                 :         13 :       case 'f':
      93                 :         13 :         get< tag::feedback >() = true;
      94                 :         13 :         break;
      95                 :        268 :       case 'i':
      96 [ +  + ][ +  - ]:        268 :         if (!g_nrestart) get< tag::input >().push_back( optarg );
                 [ +  - ]
      97                 :        268 :         break;
      98                 :         14 :       case 'l':
      99 [ +  - ][ +  - ]:         14 :         get< tag::lbfreq >() = std::stoul( optarg );
     100                 :         14 :         break;
     101                 :          0 :       case 'n':
     102                 :          0 :         get< tag::nonblocking >() = true;
     103                 :          0 :         break;
     104                 :          0 :       case 'o':
     105         [ -  - ]:          0 :         get< tag::output >() = optarg;
     106                 :          0 :         break;
     107                 :          0 :       case 'r':
     108 [ -  - ][ -  - ]:          0 :         get< tag::rsfreq >() = std::stoul( optarg );
     109                 :          0 :         break;
     110                 :        197 :       case 'q':
     111                 :        197 :         get< tag::quiescence >() = true;
     112                 :        197 :         break;
     113                 :        146 :       case 'u':
     114 [ +  - ][ +  - ]:        146 :         if (!g_nrestart) get< tag::virt >().push_back( std::stod( optarg ) );
         [ +  - ][ +  - ]
     115                 :        146 :         break;
     116                 :          1 :       case 'v':
     117         [ +  - ]:          1 :         print << '\n';
     118 [ +  - ][ +  - ]:          1 :         print.version( tk::inciter_executable(), tk::git_commit() );
                 [ +  - ]
     119         [ -  - ]:          1 :         CkExit();
     120                 :          0 :         break;
     121                 :            :     }
     122                 :            :   }
     123                 :            : 
     124         [ -  + ]:        268 :   if (optind != argc) {
     125         [ -  - ]:          0 :     print << "\nA non-option was supplied";
     126         [ -  - ]:          0 :     help( argv );
     127         [ -  - ]:          0 :     CkExit( EXIT_FAILURE );
     128                 :            :   }
     129                 :            : 
     130                 :            :   // Augment virtualization parameters if necessary
     131                 :        268 :   auto& vir = get< tag::virt>();
     132                 :        268 :   auto inps = get< tag::input >().size();
     133 [ +  + ][ +  - ]:        268 :   if (inps > vir.size()) vir.resize( inps, 0.0 );
     134                 :            : 
     135                 :            :   // Basic error handling
     136 [ -  + ][ -  - ]:        268 :   ErrChk( not get< tag::input >().empty(),
         [ -  - ][ -  - ]
     137                 :            :           "Mandatory input mesh file not specified. Use -i <filename>." );
     138 [ -  + ][ -  - ]:        268 :   ErrChk( get< tag::input >().size() <= 2,
         [ -  - ][ -  - ]
     139                 :            :           "The maximum number of meshes for coupled problems is 2. If you "
     140                 :            :           "need more, put them into the same mesh file." );
     141 [ -  + ][ -  - ]:        268 :   ErrChk( not get< tag::control >().empty(),
         [ -  - ][ -  - ]
     142                 :            :           "Mandatory control file not specified. Use -c <filename>." );
     143                 :            : }
     144                 :            : 
     145                 :            : void
     146                 :          2 : Config::help( char** argv )
     147                 :            : // *****************************************************************************
     148                 :            : // Echo help on command line arguments
     149                 :            : //! \param[in] argv Arguments to executable
     150                 :            : // *****************************************************************************
     151                 :            : {
     152                 :          2 :   tk::Print() <<
     153                 :            :     "\nUsage: " << argv[0] << " -i <in.exo> -c <config.q> [OPTION]...\n"
     154                 :            :     "\n"
     155                 :            :     "  -h, -?        Print out this help\n"
     156                 :            :     "  -b            Benchmark mode, "
     157                 :          2 :                      "default: " << get< tag::benchmark >() << "\n" <<
     158                 :            :     "  -c <config.q> Specify control file\n"
     159                 :            :     "  -d <diag>     Specify diagnostics file, "
     160                 :          2 :                      "default: " << get< tag::diag >() << "\n" <<
     161                 :            :     "  -f            Extra feedback, "
     162                 :          2 :                      "default: " << get< tag::feedback >() << "\n" <<
     163                 :            :     "  -i <in.exo>   Specify an input mesh file. Use it another time to "
     164                 :            :                      "specify a second mesh file for coupled problems.\n"
     165                 :            :     "  -l <int>      Load balancing frequency, "
     166                 :          2 :                      "default: " << get< tag::lbfreq >() << "\n" <<
     167                 :            :     "  -n            Non-blocking migration, "
     168                 :          2 :                      "default: " << get< tag::nonblocking >() << "\n" <<
     169                 :            :     "  -o <outfile>  Base-filename for field output, "
     170                 :          2 :                      "default: " << get< tag::output >() << "\n" <<
     171                 :            :     "  -r <int>      Checkpoint frequency, "
     172                 :          2 :                      "default: " << get< tag::rsfreq >() << "\n" <<
     173                 :            :     "  -q            Enable quiescence detection, "
     174                 :          2 :                      "default: " << get< tag::quiescence >() << "\n" <<
     175                 :            :     "  -u <real>     Virtualization, default: 0.0\n" <<
     176                 :            :     "  -v            Print revision information\n"
     177 [ +  - ][ +  - ]:          2 :     "\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     178                 :          2 : }
     179                 :            : 
     180                 :            : [[maybe_unused]] static void
     181                 :          0 : dumpstack( lua_State *L )
     182                 :            : // *****************************************************************************
     183                 :            : // Dump lua stack for debugging
     184                 :            : //! \param[in] L Lua state
     185                 :            : // *****************************************************************************
     186                 :            : {
     187                 :          0 :   int top=lua_gettop(L);
     188         [ -  - ]:          0 :   for (int i=1; i <= top; i++) {
     189                 :          0 :     printf("%d\t%s\t", i, luaL_typename(L,i));
     190 [ -  - ][ -  - ]:          0 :     switch (lua_type(L, i)) {
                    [ - ]
     191                 :          0 :       case LUA_TNUMBER:
     192                 :          0 :         printf("%g\n",lua_tonumber(L,i));
     193                 :          0 :         break;
     194                 :          0 :       case LUA_TSTRING:
     195                 :          0 :         printf("%s\n",lua_tostring(L,i));
     196                 :          0 :         break;
     197                 :          0 :       case LUA_TBOOLEAN:
     198         [ -  - ]:          0 :         printf("%s\n", (lua_toboolean(L, i) ? "true" : "false"));
     199                 :          0 :         break;
     200                 :          0 :       case LUA_TNIL:
     201                 :          0 :         printf("%s\n", "nil");
     202                 :          0 :         break;
     203                 :          0 :       default:
     204                 :          0 :         printf("%p\n",lua_topointer(L,i));
     205                 :          0 :         break;
     206                 :            :     }
     207                 :            :   }
     208                 :          0 : }
     209                 :            : 
     210                 :            : static int64_t
     211                 :        804 : sigint( lua_State* L,
     212                 :            :         const char* name,
     213                 :            :         int64_t def = largeint,
     214                 :            :         bool global = false )
     215                 :            : // *****************************************************************************
     216                 :            : // Parse integer from global scope
     217                 :            : //! \param[in] L Lua state
     218                 :            : //! \param[in] name Label to parse
     219                 :            : //! \param[in] def Default if does not exist
     220                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     221                 :            : // *****************************************************************************
     222                 :            : {
     223                 :        804 :   int64_t a = def;
     224                 :            : 
     225         [ -  + ]:        804 :   if (global) {
     226                 :          0 :     lua_getglobal( L, name );
     227                 :            :   } else {
     228         [ +  + ]:        804 :     if (lua_istable( L, -1 )) {
     229                 :        175 :       lua_getfield( L, -1, name );
     230                 :            :     } else {
     231                 :        629 :       return a;
     232                 :            :     }
     233                 :            :   }
     234                 :            : 
     235         [ +  + ]:        175 :   if (!lua_isnil( L, -1 )) {
     236 [ -  + ][ -  - ]:         88 :     ErrChk( lua_isinteger( L, -1 ), std::string(name) + " must be an integer" );
         [ -  - ][ -  - ]
                 [ -  - ]
     237                 :         88 :     a = lua_tointeger( L, -1 );
     238                 :            :   }
     239                 :            : 
     240                 :        175 :   lua_pop( L, 1 );
     241                 :            : 
     242                 :        175 :   return a;
     243                 :            : }
     244                 :            : 
     245                 :            : static uint64_t
     246                 :       4288 : unsigint( lua_State* L,
     247                 :            :           const char* name,
     248                 :            :           uint64_t def = largeuint,
     249                 :            :           bool global = false )
     250                 :            : // *****************************************************************************
     251                 :            : // Parse unsigned integer from global scope
     252                 :            : //! \param[in] L Lua state
     253                 :            : //! \param[in] name Label to parse
     254                 :            : //! \param[in] def Default if does not exist
     255                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     256                 :            : // *****************************************************************************
     257                 :            : {
     258                 :       4288 :   uint64_t a = def;
     259                 :            : 
     260         [ +  + ]:       4288 :   if (global) {
     261                 :       1072 :     lua_getglobal( L, name );
     262                 :            :   } else {
     263         [ +  + ]:       3216 :     if (lua_istable( L, -1 )) {
     264                 :        516 :       lua_getfield( L, -1, name );
     265                 :            :     } else {
     266                 :       2700 :       return a;
     267                 :            :     }
     268                 :            :   }
     269                 :            : 
     270         [ +  + ]:       1588 :   if (!lua_isnil( L, -1 )) {
     271 [ -  + ][ -  - ]:        973 :     ErrChk( lua_isinteger( L, -1 ), std::string(name) + " must be an integer" );
         [ -  - ][ -  - ]
                 [ -  - ]
     272                 :        973 :     a = static_cast< uint64_t >( lua_tointeger( L, -1 ) );
     273                 :            :   }
     274                 :            : 
     275                 :       1588 :   lua_pop( L, 1 );
     276                 :            : 
     277                 :       1588 :   return a;
     278                 :            : }
     279                 :            : 
     280                 :            : static bool
     281                 :       2144 : boolean( lua_State* L, const char* name, bool def = false, bool global = false )
     282                 :            : // *****************************************************************************
     283                 :            : // Parse boolean from global scope or table
     284                 :            : //! \param[in] L Lua state
     285                 :            : //! \param[in] name Label to parse
     286                 :            : //! \param[in] def Default if does not exist
     287                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     288                 :            : // *****************************************************************************
     289                 :            : {
     290                 :       2144 :   bool a = def;
     291                 :            : 
     292         [ +  + ]:       2144 :   if (global) {
     293                 :       1608 :     lua_getglobal( L, name );
     294                 :            :   } else {
     295         [ +  + ]:        536 :     if (lua_istable( L, -1 )) {
     296                 :         24 :       lua_getfield( L, -1, name );
     297                 :            :     } else {
     298                 :        512 :       return a;
     299                 :            :     }
     300                 :            :   }
     301                 :            : 
     302         [ +  + ]:       1632 :   if (!lua_isnil( L, -1 )) {
     303 [ -  + ][ -  - ]:         66 :     ErrChk( lua_isboolean( L, -1 ), std::string(name) + " must be a boolean" );
         [ -  - ][ -  - ]
                 [ -  - ]
     304                 :         66 :     a = lua_toboolean( L, -1 );
     305                 :            :   }
     306                 :            : 
     307                 :       1632 :   lua_pop( L, 1 );
     308                 :            : 
     309                 :       1632 :   return a;
     310                 :            : }
     311                 :            : 
     312                 :            : static double
     313                 :      10506 : real( lua_State* L,
     314                 :            :       const char* name,
     315                 :            :       double def = largereal,
     316                 :            :       bool global = false )
     317                 :            : // *****************************************************************************
     318                 :            : // Parse real from global scope or table
     319                 :            : //! \param[in] L Lua state
     320                 :            : //! \param[in] name Label to parse
     321                 :            : //! \param[in] def Default if does not exist
     322                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     323                 :            : // *****************************************************************************
     324                 :            : {
     325                 :      10506 :   double a = def;
     326                 :            : 
     327         [ +  + ]:      10506 :   if (global) {
     328                 :       3484 :     lua_getglobal( L, name );
     329                 :            :   } else {
     330         [ +  + ]:       7022 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, name ); else return a;
     331                 :            :   }
     332                 :            : 
     333         [ +  + ]:       6537 :   if (!lua_isnil( L, -1 )) {
     334 [ -  + ][ -  - ]:       1078 :     ErrChk( lua_isnumber( L, -1 ), std::string(name) + " must be a number" );
         [ -  - ][ -  - ]
                 [ -  - ]
     335                 :       1078 :     a = lua_tonumber( L, -1 );
     336                 :            :   }
     337                 :            : 
     338                 :       6537 :   lua_pop( L, 1 );
     339                 :            : 
     340                 :       6537 :   return a;
     341                 :            : }
     342                 :            : 
     343                 :            : static std::string
     344                 :       2680 : string( lua_State* L,
     345                 :            :         const char* name,
     346                 :            :         const char* def = "default",
     347                 :            :         bool global = false )
     348                 :            : // *****************************************************************************
     349                 :            : // Parse string from global scope or table
     350                 :            : //! \param[in] L Lua state
     351                 :            : //! \param[in] name Label to parse
     352                 :            : //! \param[in] def Default if does not exist
     353                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     354                 :            : // *****************************************************************************
     355                 :            : {
     356         [ +  - ]:       2680 :   std::string a = def;
     357                 :            : 
     358         [ +  + ]:       2680 :   if (global) {
     359         [ +  - ]:        804 :     lua_getglobal( L, name );
     360                 :            :   } else {
     361 [ +  - ][ +  + ]:       1876 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, name ); else return a;
                 [ +  - ]
     362                 :            :   }
     363                 :            : 
     364 [ +  - ][ +  + ]:       1156 :   if (!lua_isnil( L, -1 )) {
     365 [ +  - ][ -  + ]:        746 :     ErrChk( lua_isstring( L, -1 ), std::string(name) + " must be a string" );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     366 [ +  - ][ +  - ]:        746 :     a = lua_tostring( L, -1 );
     367                 :            :   }
     368                 :            : 
     369         [ +  - ]:       1156 :   lua_pop( L, 1 );
     370                 :            : 
     371                 :       1156 :   return a;
     372                 :          0 : }
     373                 :            : 
     374                 :            : static std::vector< double >
     375                 :       1081 : vector( lua_State* L,
     376                 :            :         const char* name,
     377                 :            :         double def = largereal,
     378                 :            :         bool global = false )
     379                 :            : // *****************************************************************************
     380                 :            : // Parse vector table from global scope or table
     381                 :            : //! \param[in] L Lua state
     382                 :            : //! \param[in] name Label to parse
     383                 :            : //! \param[in] def Default if does not exist
     384                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     385                 :            : //! \return Vector components parsed
     386                 :            : // *****************************************************************************
     387                 :            : {
     388         [ +  - ]:       1081 :   std::vector< double > v( 3, def );
     389                 :            : 
     390         [ +  + ]:       1081 :   if (global) {
     391         [ +  - ]:        268 :     lua_getglobal( L, name );
     392                 :            :   } else {
     393 [ +  - ][ +  + ]:        813 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, name ); else return v;
                 [ +  - ]
     394                 :            :   }
     395                 :            : 
     396 [ +  - ][ +  + ]:        559 :   if (!lua_isnil( L, -1 )) {
     397 [ +  - ][ -  + ]:        203 :     ErrChk( lua_istable( L, -1 ), "vector must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     398         [ +  - ]:        203 :     int64_t n = luaL_len( L, -1 );
     399         [ +  + ]:        812 :     for (int64_t i=1; i<=n; ++i) {
     400         [ +  - ]:        609 :       lua_geti( L, -1, i );
     401 [ +  - ][ -  + ]:        609 :       ErrChk( lua_isnumber( L, -1 ), "vector components must be numbers" );
         [ -  - ][ -  - ]
                 [ -  - ]
     402         [ +  - ]:        609 :       v[ static_cast<std::size_t>(i-1) ] = lua_tonumber( L, -1 );
     403         [ +  - ]:        609 :       lua_pop( L, 1 );
     404                 :            :     }
     405                 :            :   }
     406                 :            : 
     407         [ +  - ]:        559 :   lua_pop( L, 1 );
     408                 :            : 
     409                 :        559 :   return v;
     410                 :          0 : }
     411                 :            : 
     412                 :            : static std::vector< std::string >
     413                 :        804 : stringlist( lua_State* L, const char* name, bool global = false )
     414                 :            : // *****************************************************************************
     415                 :            : // Parse string list table from global scope or table
     416                 :            : //! \param[in] L Lua state
     417                 :            : //! \param[in] name Label to parse
     418                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     419                 :            : //! \return List of strings parsed
     420                 :            : // *****************************************************************************
     421                 :            : {
     422                 :        804 :   std::vector< std::string > v;
     423                 :            : 
     424         [ +  + ]:        804 :   if (global) {
     425         [ +  - ]:        268 :     lua_getglobal( L, name );
     426                 :            :   } else {
     427 [ +  - ][ +  + ]:        536 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, name ); else return v;
                 [ +  - ]
     428                 :            :   }
     429                 :            : 
     430 [ +  - ][ +  + ]:        288 :   if (!lua_isnil( L, -1 )) {
     431 [ +  - ][ -  + ]:         22 :     ErrChk( lua_istable( L, -1 ), "stringlist must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     432         [ +  - ]:         22 :     int64_t n = luaL_len( L, -1 );
     433         [ +  + ]:         76 :     for (int64_t i=1; i<=n; ++i) {
     434         [ +  - ]:         54 :       lua_geti( L, -1, i );
     435 [ +  - ][ -  + ]:         54 :       ErrChk( lua_isstring( L, -1 ), "stringlist components must be strings" );
         [ -  - ][ -  - ]
                 [ -  - ]
     436 [ +  - ][ +  - ]:         54 :       v.push_back( lua_tostring( L, -1 ) );
                 [ +  - ]
     437         [ +  - ]:         54 :       lua_pop( L, 1 );
     438                 :            :     }
     439                 :            :   }
     440                 :            : 
     441         [ +  - ]:        288 :   lua_pop( L, 1 );
     442                 :            : 
     443                 :        288 :   return v;
     444                 :          0 : }
     445                 :            : 
     446                 :            : static std::vector< uint64_t >
     447                 :        804 : unsigints( lua_State* L, const char* name, bool global = false )
     448                 :            : // *****************************************************************************
     449                 :            : // Parse table of unsigned integers from global scope or table
     450                 :            : //! \param[in] L Lua state
     451                 :            : //! \param[in] name Label to parse
     452                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     453                 :            : //! \return List of unsigned integers parsed
     454                 :            : // *****************************************************************************
     455                 :            : {
     456                 :        804 :   std::vector< uint64_t > v;
     457                 :            : 
     458         [ +  + ]:        804 :   if (global) {
     459         [ +  - ]:        268 :     lua_getglobal( L, name );
     460                 :            :   } else {
     461 [ +  - ][ +  + ]:        536 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, name ); else return v;
                 [ +  - ]
     462                 :            :   }
     463                 :            : 
     464 [ +  - ][ +  + ]:        281 :   if (!lua_isnil( L, -1 )) {
     465 [ +  - ][ -  + ]:         23 :     ErrChk( lua_istable( L, -1 ), "unsigints must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     466         [ +  - ]:         23 :     int64_t n = luaL_len( L, -1 );
     467         [ +  + ]:         86 :     for (int64_t i=1; i<=n; ++i) {
     468         [ +  - ]:         63 :       lua_geti( L, -1, i );
     469 [ +  - ][ -  + ]:         63 :       ErrChk( lua_isinteger( L, -1 ), "unsigints components must be numbers" );
         [ -  - ][ -  - ]
                 [ -  - ]
     470 [ +  - ][ +  - ]:         63 :       v.push_back( static_cast< uint64_t >( lua_tointeger( L, -1 ) ) );
     471         [ +  - ]:         63 :       lua_pop( L, 1 );
     472                 :            :     }
     473                 :            :   }
     474                 :            : 
     475         [ +  - ]:        281 :   lua_pop( L, 1 );
     476                 :            : 
     477                 :        281 :   return v;
     478                 :          0 : }
     479                 :            : 
     480                 :            : static std::vector< int >
     481                 :       1001 : sideset( lua_State* L, bool global = false )
     482                 :            : // *****************************************************************************
     483                 :            : // Parse sideset table from global scope or table
     484                 :            : //! \param[in] L Lua state
     485                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     486                 :            : //! \return Vector of side set ids parsed
     487                 :            : // *****************************************************************************
     488                 :            : {
     489                 :       1001 :   std::vector< int > v;
     490                 :            : 
     491         [ -  + ]:       1001 :   if (global) {
     492         [ -  - ]:          0 :     lua_getglobal( L, "sideset" );
     493                 :            :   } else {
     494 [ +  - ][ +  + ]:       1001 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, "sideset" ); else return v;
                 [ +  - ]
     495                 :            :   }
     496                 :            : 
     497 [ +  - ][ +  + ]:        376 :   if (!lua_isnil( L, -1 )) {
     498 [ +  - ][ -  + ]:        230 :     ErrChk( lua_istable( L, -1 ), "sideset must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     499         [ +  - ]:        230 :     int64_t n = luaL_len( L, -1 );
     500         [ +  + ]:        651 :     for (int64_t i=1; i<=n; ++i) {
     501         [ +  - ]:        421 :       lua_geti( L, -1, i );
     502 [ +  - ][ -  + ]:        421 :       ErrChk( lua_isinteger( L, -1 ), "sideset id must be a number" );
         [ -  - ][ -  - ]
                 [ -  - ]
     503         [ +  - ]:        421 :       int a = static_cast< int >( lua_tointeger( L, -1 ) );
     504 [ -  + ][ -  - ]:        421 :       ErrChk( a >= 0, "sideset id must be non-negative" );
         [ -  - ][ -  - ]
     505         [ +  - ]:        421 :       v.push_back( a );
     506         [ +  - ]:        421 :       lua_pop( L, 1 );
     507                 :            :     }
     508                 :            :   }
     509                 :            : 
     510         [ +  - ]:        376 :   lua_pop( L, 1 );
     511                 :            : 
     512                 :        376 :   return v;
     513                 :          0 : }
     514                 :            : 
     515                 :            : static std::vector< std::vector< double > >
     516                 :        804 : range( lua_State* L, bool global = false )
     517                 :            : // *****************************************************************************
     518                 :            : // Parse range(s) table from global scope or table
     519                 :            : //! \param[in] L Lua state
     520                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     521                 :            : //! \return Vector of vectors of range(s)
     522                 :            : // *****************************************************************************
     523                 :            : {
     524                 :        804 :   std::vector< std::vector< double > > v;
     525                 :            : 
     526         [ -  + ]:        804 :   if (global) {
     527         [ -  - ]:          0 :     lua_getglobal( L, "range" );
     528                 :            :   } else {
     529 [ +  - ][ +  + ]:        804 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, "range" ); else return v;
                 [ +  - ]
     530                 :            :   }
     531                 :            : 
     532 [ +  - ][ +  + ]:        183 :   if (!lua_isnil( L, -1 )) {
     533 [ +  - ][ -  + ]:          6 :     ErrChk( lua_istable( L, -1 ), "range must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     534         [ +  - ]:          6 :     int64_t n = luaL_len( L, -1 );
     535         [ +  - ]:          6 :     v.emplace_back();
     536         [ +  + ]:         23 :     for (int64_t i=1; i<=n; ++i) {
     537         [ +  - ]:         17 :       lua_geti( L, -1, i );
     538 [ +  - ][ +  + ]:         17 :       if (lua_isnumber( L, -1 )) {
     539 [ +  - ][ +  - ]:         15 :         v.back().push_back( lua_tonumber( L, -1 ) );
     540                 :            :       } else {
     541 [ +  - ][ -  + ]:          2 :         ErrChk( lua_istable( L, -1 ), "non-number range must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     542 [ +  + ][ +  - ]:          2 :         if (i>1) v.emplace_back();
     543         [ +  - ]:          2 :         int64_t m = luaL_len( L, -1 );
     544         [ +  + ]:          8 :         for (int64_t j=1; j<=m; ++j) {
     545         [ +  - ]:          6 :           lua_geti( L, -1, j );
     546 [ +  - ][ -  + ]:          6 :           ErrChk( lua_isnumber( L, -1 ), "vector components must be numbers" );
         [ -  - ][ -  - ]
                 [ -  - ]
     547 [ +  - ][ +  - ]:          6 :           v.back().push_back( lua_tonumber( L, -1 ) );
     548         [ +  - ]:          6 :           lua_pop( L, 1 );
     549                 :            :         }
     550                 :            :       }
     551         [ +  - ]:         17 :       lua_pop( L, 1 );
     552                 :            :     }
     553                 :            :   }
     554                 :            : 
     555         [ +  - ]:        183 :   lua_pop( L, 1 );
     556                 :            : 
     557                 :        183 :   return v;
     558                 :          0 : }
     559                 :            : 
     560                 :            : static void
     561                 :        268 : intergrid_( lua_State* L, Config& cfg,
     562                 :            :             std::vector< std::vector< int > >& sets,
     563                 :            :             std::vector< std::vector< uint64_t > >& lays,
     564                 :            :             std::vector< std::string >& syms )
     565                 :            : // *****************************************************************************
     566                 :            : // Parse integrid_* table from table for multple meshes
     567                 :            : //! \param[in,out] L Lua state
     568                 :            : //! \param[in,out] cfg Config state
     569                 :            : //! \param[in,out] sets State to push back intergrid setids to (outer vec: mesh)
     570                 :            : //! \param[in,out] lays State to push back intergrid layers to (outer vec: mesh)
     571                 :            : //! \param[in,out] syms State to push back holes-ymmetries to (vec: mesh)
     572                 :            : // *****************************************************************************
     573                 :            : {
     574                 :        268 :   auto nf = cfg.get< tag::input >().size();
     575         [ +  - ]:        268 :   if (nf == 1) return;
     576                 :            : 
     577         [ -  - ]:          0 :   sets.resize( nf );
     578         [ -  - ]:          0 :   lays.resize( nf );
     579         [ -  - ]:          0 :   syms.resize( nf );
     580         [ -  - ]:          0 :   std::string basename = "intergrid_";
     581                 :            : 
     582         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
     583                 :            : 
     584 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
     585 [ -  - ][ -  - ]:          0 :     if (lua_istable(L, -1)) lua_getfield( L, -1, name.c_str() ); else return;
                 [ -  - ]
     586                 :            : 
     587 [ -  - ][ -  - ]:          0 :     if (!lua_isnil( L, -1 )) {
     588         [ -  - ]:          0 :       sets[k] = sideset( L );
     589         [ -  - ]:          0 :       lays[k] = unsigints( L, "layers" );
     590         [ -  - ]:          0 :       syms[k] = string( L, "sym", "" );
     591                 :            :     }
     592                 :            : 
     593         [ -  - ]:          0 :     lua_pop( L, 1 );
     594                 :            : 
     595         [ -  - ]:          0 :   }
     596         [ -  - ]:          0 : }
     597                 :            : 
     598                 :            : static void
     599                 :        268 : overset( lua_State* L, Config& cfg )
     600                 :            : // *****************************************************************************
     601                 :            : // Parse overset table from global scope
     602                 :            : //! \param[in,out] L Lua state
     603                 :            : //! \param[in,out] cfg Config state
     604                 :            : // *****************************************************************************
     605                 :            : {
     606                 :        268 :   lua_getglobal( L, "overset" );
     607                 :            : 
     608                 :        268 :   auto& tf = cfg.get< tag::overset>();
     609                 :        268 :   intergrid_( L, cfg,
     610                 :            :               tf.get< tag::intergrid_ >(),
     611                 :            :               tf.get< tag::layers_ >(),
     612                 :            :               tf.get< tag::sym_ >() );
     613                 :            : 
     614                 :        268 :   lua_pop( L, 1 );
     615                 :        268 : }
     616                 :            : 
     617                 :            : static void
     618                 :        268 : fieldout( lua_State* L, Config& cfg )
     619                 :            : // *****************************************************************************
     620                 :            : // Parse fieldout table from global scope
     621                 :            : //! \param[in,out] L Lua state
     622                 :            : //! \param[in,out] cfg Config state
     623                 :            : // *****************************************************************************
     624                 :            : {
     625                 :        268 :   lua_getglobal( L, "fieldout" );
     626                 :            : 
     627                 :        268 :   auto& tf = cfg.get< tag::fieldout >();
     628         [ +  - ]:        268 :   tf.get< tag::sidesets >() = sideset( L );
     629                 :        268 :   tf.get< tag::iter >() = unsigint( L, "iter" );
     630                 :        268 :   tf.get< tag::time >() = real( L, "time" );
     631         [ +  - ]:        268 :   tf.get< tag::range >() = range( L );
     632                 :            : 
     633                 :        268 :   lua_pop( L, 1 );
     634                 :        268 : }
     635                 :            : 
     636                 :            : static void
     637                 :        268 : fieldout_( lua_State* L, Config& cfg )
     638                 :            : // *****************************************************************************
     639                 :            : // Parse fieldout_* table from global scope for multiple meshes
     640                 :            : //! \param[in,out] L Lua state
     641                 :            : //! \param[in,out] cfg Config state
     642                 :            : // *****************************************************************************
     643                 :            : {
     644                 :        268 :   auto nf = cfg.get< tag::input >().size();
     645         [ +  - ]:        268 :   if (nf == 1) return;
     646                 :            : 
     647         [ -  - ]:          0 :   std::string basename = "fieldout_";
     648                 :          0 :   auto& tf = cfg.get< tag::fieldout_ >();
     649         [ -  - ]:          0 :   tf.resize( nf );
     650                 :            : 
     651         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
     652                 :            : 
     653 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
     654         [ -  - ]:          0 :     lua_getglobal( L, name.c_str() );
     655                 :            : 
     656                 :          0 :     auto& tfk = tf[k];
     657         [ -  - ]:          0 :     tfk.get< tag::sidesets >() = sideset( L );
     658         [ -  - ]:          0 :     tfk.get< tag::iter >() = unsigint( L, "iter" );
     659         [ -  - ]:          0 :     tfk.get< tag::time >() = real( L, "time" );
     660         [ -  - ]:          0 :     tfk.get< tag::range >() = range( L );
     661                 :            : 
     662         [ -  - ]:          0 :     lua_pop( L, 1 );
     663                 :            : 
     664                 :          0 :   }
     665                 :          0 : }
     666                 :            : 
     667                 :            : static void
     668                 :        268 : histout( lua_State* L, Config& cfg )
     669                 :            : // *****************************************************************************
     670                 :            : // Parse histout table from global scope
     671                 :            : //! \param[in,out] L Lua state
     672                 :            : //! \param[in,out] cfg Config state
     673                 :            : // *****************************************************************************
     674                 :            : {
     675                 :        268 :   lua_getglobal( L, "histout" );
     676                 :            : 
     677                 :        268 :   auto& th = cfg.get< tag::histout >();
     678                 :        268 :   th.get< tag::iter >() = unsigint( L, "iter" );
     679                 :        268 :   th.get< tag::time >() = real( L, "time" );
     680         [ +  - ]:        268 :   th.get< tag::range >() = range( L );
     681                 :        268 :   th.get< tag::precision >() = sigint( L, "precision", 8 );
     682         [ +  - ]:        268 :   th.get< tag::format >() = string( L, "format" );
     683                 :            : 
     684         [ +  + ]:        268 :   if (lua_istable( L, -1 )) {
     685                 :         15 :     lua_getfield( L, -1, "points" );
     686         [ +  - ]:         15 :     if (!lua_isnil( L, -1 )) {
     687 [ -  + ][ -  - ]:         15 :       ErrChk( lua_istable( L, -1 ), "histout points must be a table" );
         [ -  - ][ -  - ]
     688                 :         15 :       auto& r = th.get< tag::points >();
     689                 :         15 :       int64_t n = luaL_len( L, -1 );
     690         [ +  + ]:         90 :       for (int64_t i=1; i<=n; ++i) {
     691                 :         75 :         lua_geti( L, -1, i );
     692 [ -  + ][ -  - ]:         75 :         ErrChk( lua_istable( L, -1 ), "histout point must be a table" );
         [ -  - ][ -  - ]
     693                 :         75 :         r.emplace_back();
     694                 :         75 :         auto& p = r.back();
     695                 :         75 :         int64_t m = luaL_len( L, -1 );
     696         [ +  + ]:        300 :         for (int64_t j=1; j<=m; ++j) {
     697                 :        225 :           lua_geti( L, -1, j );
     698 [ -  + ][ -  - ]:        225 :           ErrChk( lua_isnumber( L, -1 ), "point coordinate must be a number" );
         [ -  - ][ -  - ]
     699 [ +  - ][ +  - ]:        225 :           p.push_back( lua_tonumber( L, -1 ) );
     700                 :        225 :           lua_pop( L, 1 );
     701                 :            :         }
     702                 :         75 :         lua_pop( L, 1 );
     703                 :            :       }
     704                 :            :     }
     705                 :         15 :     lua_pop( L, 1 );
     706                 :            :   }
     707                 :            : 
     708                 :        268 :   lua_pop( L, 1 );
     709                 :        268 : }
     710                 :            : 
     711                 :            : static void
     712                 :        268 : histout_( lua_State* L, Config& cfg )
     713                 :            : // *****************************************************************************
     714                 :            : // Parse histout_* table from global scope for multiple meshes
     715                 :            : //! \param[in,out] L Lua state
     716                 :            : //! \param[in,out] cfg Config state
     717                 :            : // *****************************************************************************
     718                 :            : {
     719                 :        268 :   auto nf = cfg.get< tag::input >().size();
     720         [ +  - ]:        268 :   if (nf == 1) return;
     721                 :            : 
     722         [ -  - ]:          0 :   std::string basename = "histout_";
     723                 :          0 :   auto& th = cfg.get< tag::histout_ >();
     724         [ -  - ]:          0 :   th.resize( nf );
     725                 :            : 
     726         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
     727                 :            : 
     728 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
     729         [ -  - ]:          0 :     lua_getglobal( L, name.c_str() );
     730                 :            : 
     731                 :          0 :     auto& thk = th[k];
     732                 :            : 
     733         [ -  - ]:          0 :     thk.get< tag::iter >() = unsigint( L, "iter" );
     734         [ -  - ]:          0 :     thk.get< tag::time >() = real( L, "time" );
     735         [ -  - ]:          0 :     thk.get< tag::range >() = range( L );
     736         [ -  - ]:          0 :     thk.get< tag::precision >() = sigint( L, "precision", 8 );
     737         [ -  - ]:          0 :     thk.get< tag::format >() = string( L, "format" );
     738                 :            : 
     739 [ -  - ][ -  - ]:          0 :     if (lua_istable( L, -1 )) {
     740         [ -  - ]:          0 :       lua_getfield( L, -1, "points" );
     741 [ -  - ][ -  - ]:          0 :       if (!lua_isnil( L, -1 )) {
     742 [ -  - ][ -  - ]:          0 :         ErrChk( lua_istable( L, -1 ), "histout points must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     743                 :          0 :         auto& r = thk.get< tag::points >();
     744         [ -  - ]:          0 :         int64_t n = luaL_len( L, -1 );
     745         [ -  - ]:          0 :         for (int64_t i=1; i<=n; ++i) {
     746         [ -  - ]:          0 :           lua_geti( L, -1, i );
     747 [ -  - ][ -  - ]:          0 :           ErrChk( lua_istable( L, -1 ), "histout point must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     748         [ -  - ]:          0 :           r.emplace_back();
     749                 :          0 :           auto& p = r.back();
     750         [ -  - ]:          0 :           int64_t m = luaL_len( L, -1 );
     751         [ -  - ]:          0 :           for (int64_t j=1; j<=m; ++j) {
     752         [ -  - ]:          0 :             lua_geti( L, -1, j );
     753 [ -  - ][ -  - ]:          0 :             ErrChk( lua_isnumber(L,-1), "point coordinate must be a number" );
         [ -  - ][ -  - ]
                 [ -  - ]
     754 [ -  - ][ -  - ]:          0 :             p.push_back( lua_tonumber( L, -1 ) );
     755         [ -  - ]:          0 :             lua_pop( L, 1 );
     756                 :            :           }
     757         [ -  - ]:          0 :           lua_pop( L, 1 );
     758                 :            :         }
     759                 :            :       }
     760         [ -  - ]:          0 :       lua_pop( L, 1 );
     761                 :            :     }
     762                 :            : 
     763         [ -  - ]:          0 :     lua_pop( L, 1 );
     764                 :            : 
     765                 :          0 :   }
     766                 :          0 : }
     767                 :            : 
     768                 :            : static void
     769                 :        268 : integout( lua_State* L, Config& cfg )
     770                 :            : // *****************************************************************************
     771                 :            : // Parse integout table from global scope
     772                 :            : //! \param[in,out] L Lua state
     773                 :            : //! \param[in,out] cfg Config state
     774                 :            : // *****************************************************************************
     775                 :            : {
     776                 :        268 :   lua_getglobal( L, "integout" );
     777                 :            : 
     778                 :        268 :   auto& ti = cfg.get< tag::integout >();
     779         [ +  - ]:        268 :   ti.get< tag::sidesets >() = sideset( L );
     780         [ +  - ]:        268 :   ti.get< tag::integrals >() = stringlist( L, "integrals" );
     781                 :        268 :   ti.get< tag::iter >() = unsigint( L, "iter" );
     782                 :        268 :   ti.get< tag::time >() = real( L, "time" );
     783         [ +  - ]:        268 :   ti.get< tag::range >() = range( L );
     784                 :        268 :   ti.get< tag::precision >() = sigint( L, "precision", 8 );
     785         [ +  - ]:        268 :   ti.get< tag::format >() = string( L, "format" );
     786                 :            : 
     787                 :        268 :   lua_pop( L, 1 );
     788                 :        268 : }
     789                 :            : 
     790                 :            : static void
     791                 :        268 : integout_( lua_State* L, Config& cfg )
     792                 :            : // *****************************************************************************
     793                 :            : // Parse integout_* table from global scope for multiple meshes
     794                 :            : //! \param[in,out] L Lua state
     795                 :            : //! \param[in,out] cfg Config state
     796                 :            : // *****************************************************************************
     797                 :            : {
     798                 :        268 :   auto nf = cfg.get< tag::input >().size();
     799         [ +  - ]:        268 :   if (nf == 1) return;
     800                 :            : 
     801         [ -  - ]:          0 :   std::string basename = "integout_";
     802                 :          0 :   auto& ti = cfg.get< tag::integout_ >();
     803         [ -  - ]:          0 :   ti.resize( nf );
     804                 :            : 
     805         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
     806                 :            : 
     807 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
     808         [ -  - ]:          0 :     lua_getglobal( L, name.c_str() );
     809                 :            : 
     810                 :          0 :     auto& tik = ti[k];
     811                 :            : 
     812         [ -  - ]:          0 :     tik.get< tag::sidesets >() = sideset( L );
     813         [ -  - ]:          0 :     tik.get< tag::integrals >() = stringlist( L, "integrals" );
     814         [ -  - ]:          0 :     tik.get< tag::iter >() = unsigint( L, "iter" );
     815         [ -  - ]:          0 :     tik.get< tag::time >() = real( L, "time" );
     816         [ -  - ]:          0 :     tik.get< tag::range >() = range( L );
     817         [ -  - ]:          0 :     tik.get< tag::precision >() = sigint( L, "precision", 8 );
     818         [ -  - ]:          0 :     tik.get< tag::format >() = string( L, "format" );
     819                 :            : 
     820         [ -  - ]:          0 :     lua_pop( L, 1 );
     821                 :            : 
     822                 :          0 :   }
     823                 :          0 : }
     824                 :            : 
     825                 :            : static void
     826                 :        268 : diag( lua_State* L, Config& cfg )
     827                 :            : // *****************************************************************************
     828                 :            : // Parse diag table
     829                 :            : //! \param[in,out] L Lua state
     830                 :            : //! \param[in,out] cfg Config state
     831                 :            : // *****************************************************************************
     832                 :            : {
     833                 :        268 :   lua_getglobal( L, "diag" );
     834                 :            : 
     835                 :        268 :   cfg.get< tag::diag_iter >() = unsigint( L, "iter", 1 );
     836                 :        268 :   cfg.get< tag::diag_precision >() = sigint( L, "precision", 8 );
     837         [ +  - ]:        268 :   cfg.get< tag::diag_format >() = string( L, "format" );
     838                 :            : 
     839                 :        268 :   lua_pop( L, 1 );
     840                 :        268 : }
     841                 :            : 
     842                 :            : static void
     843                 :        536 : bc_dir( lua_State* L,
     844                 :            :         std::vector< std::vector< int > >& mask,
     845                 :            :         bool global = false )
     846                 :            : // *****************************************************************************
     847                 :            : // Parse bc_dir table
     848                 :            : //! \param[in,out] L Lua state
     849                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     850                 :            : //! \param[in,out] mask Config state to store Dirichlet BC setids and mask
     851                 :            : // *****************************************************************************
     852                 :            : {
     853         [ +  + ]:        536 :   if (global) {
     854                 :        268 :     lua_getglobal( L, "bc_dir" );
     855                 :            :   } else {
     856         [ +  + ]:        268 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, "bc_dir" ); else return;
     857                 :            :   }
     858                 :            : 
     859         [ +  + ]:        316 :   if (!lua_isnil( L, -1 )) {
     860 [ -  + ][ -  - ]:        151 :     ErrChk( lua_istable( L, -1 ), "bc_dir must be a table" );
         [ -  - ][ -  - ]
     861                 :        151 :     int64_t n = luaL_len( L, -1 );
     862         [ +  + ]:        685 :     for (int64_t i=1; i<=n; ++i) {
     863                 :        534 :       lua_geti( L, -1, i );
     864 [ -  + ][ -  - ]:        534 :       ErrChk( lua_istable( L, -1 ), "bc_dir table entry must be a table" );
         [ -  - ][ -  - ]
     865                 :        534 :       mask.emplace_back();
     866                 :        534 :       auto& b = mask.back();
     867                 :        534 :       int64_t m = luaL_len( L, -1 );
     868         [ +  + ]:       3450 :       for (int64_t j=1; j<=m; ++j) {
     869                 :       2916 :         lua_geti( L, -1, j );
     870 [ -  + ][ -  - ]:       2916 :         ErrChk( lua_isinteger( L, -1 ), "bc_dir entry must be an integer" );
         [ -  - ][ -  - ]
     871 [ +  - ][ +  - ]:       2916 :         b.push_back( static_cast< int >( lua_tointeger( L, -1 ) ) );
     872                 :       2916 :         lua_pop( L, 1 );
     873                 :            :       }
     874                 :        534 :       lua_pop( L, 1 );
     875                 :            :     }
     876                 :            :   }
     877                 :            : 
     878                 :        316 :   lua_pop( L, 1 );
     879                 :            : }
     880                 :            : 
     881                 :            : static void
     882                 :        536 : bc_dirval( lua_State* L,
     883                 :            :            std::vector< std::vector< double > >& val,
     884                 :            :            bool global = false )
     885                 :            : // *****************************************************************************
     886                 :            : // Parse bc_dirval table
     887                 :            : //! \param[in,out] L Lua state
     888                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     889                 :            : //! \param[in,out] val Config state to store Dirichlet BC setids and values
     890                 :            : // *****************************************************************************
     891                 :            : {
     892         [ +  + ]:        536 :   if (global) {
     893                 :        268 :     lua_getglobal( L, "bc_dirval" );
     894                 :            :   } else {
     895         [ +  + ]:        268 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, "bc_dirval" ); else return;
     896                 :            :   }
     897                 :            : 
     898         [ +  + ]:        316 :   if (!lua_isnil( L, -1 )) {
     899 [ -  + ][ -  - ]:         25 :     ErrChk( lua_istable( L, -1 ), "bc_dirval must be a table" );
         [ -  - ][ -  - ]
     900                 :         25 :     int64_t n = luaL_len( L, -1 );
     901         [ +  + ]:         64 :     for (int64_t i=1; i<=n; ++i) {
     902                 :         39 :       lua_geti( L, -1, i );
     903 [ -  + ][ -  - ]:         39 :       ErrChk( lua_istable( L, -1 ), "bc_dirval table entry must be a table" );
         [ -  - ][ -  - ]
     904                 :         39 :       val.emplace_back();
     905                 :         39 :       auto& b = val.back();
     906                 :         39 :       int64_t m = luaL_len( L, -1 );
     907         [ +  + ]:        145 :       for (int64_t j=1; j<=m; ++j) {
     908                 :        106 :         lua_geti( L, -1, j );
     909 [ -  + ][ -  - ]:        106 :         ErrChk( lua_isnumber( L, -1 ), "bc_dirval entry must be an real" );
         [ -  - ][ -  - ]
     910 [ +  - ][ +  - ]:        106 :         b.push_back( static_cast< double >( lua_tonumber( L, -1 ) ) );
     911                 :        106 :         lua_pop( L, 1 );
     912                 :            :       }
     913                 :         39 :       lua_pop( L, 1 );
     914                 :            :     }
     915                 :            :   }
     916                 :            : 
     917                 :        316 :   lua_pop( L, 1 );
     918                 :            : }
     919                 :            : 
     920                 :            : static void
     921                 :        268 : bc_dir_( lua_State* L,
     922                 :            :          std::vector< std::vector< std::vector< int > > >& mask,
     923                 :            :          std::size_t nf,
     924                 :            :          bool global = false )
     925                 :            : // *****************************************************************************
     926                 :            : // Parse bc_dir_* table from global scope or table for multiple meshes
     927                 :            : //! \param[in,out] L Lua state
     928                 :            : //! \param[in,out] mask State to push back Dirichlet BC setids and mask to
     929                 :            : //!                (outer vec: mesh)
     930                 :            : //! \param[in] nf Number of mesh files specified on command line
     931                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     932                 :            : // *****************************************************************************
     933                 :            : {
     934         [ +  - ]:        268 :   if (nf == 1) return;
     935                 :            : 
     936         [ -  - ]:          0 :   mask.resize( nf );
     937         [ -  - ]:          0 :   std::string basename = "bc_dir_";
     938                 :            : 
     939         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
     940                 :            : 
     941 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
     942                 :            : 
     943         [ -  - ]:          0 :     if (global) {
     944         [ -  - ]:          0 :       lua_getglobal( L, name.c_str() );
     945                 :            :     } else {
     946 [ -  - ][ -  - ]:          0 :       if (lua_istable(L, -1)) lua_getfield( L, -1, name.c_str() ); else return;
                 [ -  - ]
     947                 :            :     }
     948                 :            : 
     949 [ -  - ][ -  - ]:          0 :     if (!lua_isnil( L, -1 )) {
     950 [ -  - ][ -  - ]:          0 :       ErrChk( lua_istable( L, -1 ), name + " must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     951         [ -  - ]:          0 :       int64_t n = luaL_len( L, -1 );
     952         [ -  - ]:          0 :       for (int64_t i=1; i<=n; ++i) {
     953         [ -  - ]:          0 :         lua_geti( L, -1, i );
     954 [ -  - ][ -  - ]:          0 :         ErrChk( lua_istable( L, -1 ), name + " table entry must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     955         [ -  - ]:          0 :         mask[k].emplace_back();
     956                 :          0 :         auto& b = mask[k].back();
     957         [ -  - ]:          0 :         int64_t m = luaL_len( L, -1 );
     958         [ -  - ]:          0 :         for (int64_t j=1; j<=m; ++j) {
     959         [ -  - ]:          0 :           lua_geti( L, -1, j );
     960 [ -  - ][ -  - ]:          0 :           ErrChk( lua_isinteger( L, -1 ), name + " entry must be an integer" );
         [ -  - ][ -  - ]
                 [ -  - ]
     961 [ -  - ][ -  - ]:          0 :           b.push_back( static_cast< int >( lua_tointeger( L, -1 ) ) );
     962         [ -  - ]:          0 :           lua_pop( L, 1 );
     963                 :            :         }
     964         [ -  - ]:          0 :         lua_pop( L, 1 );
     965                 :            :       }
     966                 :            :     }
     967                 :            : 
     968         [ -  - ]:          0 :     lua_pop( L, 1 );
     969                 :            : 
     970         [ -  - ]:          0 :   }
     971         [ -  - ]:          0 : }
     972                 :            : 
     973                 :            : static void
     974                 :        268 : bc_dirval_( lua_State* L,
     975                 :            :             std::vector< std::vector< std::vector< double > > >& val,
     976                 :            :             std::size_t nf,
     977                 :            :             bool global = false )
     978                 :            : // *****************************************************************************
     979                 :            : // Parse bc_dirval table
     980                 :            : //! \param[in,out] L Lua state
     981                 :            : //! \param[in,out] val Config state to store Dirichlet BC setids and values
     982                 :            : //! \param[in] nf Number of mesh files specified on command line
     983                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     984                 :            : // *****************************************************************************
     985                 :            : {
     986         [ +  - ]:        268 :   if (nf == 1) return;
     987                 :            : 
     988         [ -  - ]:          0 :   val.resize( nf );
     989         [ -  - ]:          0 :   std::string basename = "bc_dirval_";
     990                 :            : 
     991         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
     992                 :            : 
     993 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
     994                 :            : 
     995         [ -  - ]:          0 :     if (global) {
     996         [ -  - ]:          0 :       lua_getglobal( L, name.c_str() );
     997                 :            :     } else {
     998 [ -  - ][ -  - ]:          0 :       if (lua_istable(L, -1)) lua_getfield( L, -1, name.c_str() ); else return;
                 [ -  - ]
     999                 :            :     }
    1000                 :            : 
    1001 [ -  - ][ -  - ]:          0 :     if (!lua_isnil( L, -1 )) {
    1002 [ -  - ][ -  - ]:          0 :       ErrChk( lua_istable( L, -1 ), "bc_dirval must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
    1003         [ -  - ]:          0 :       int64_t n = luaL_len( L, -1 );
    1004         [ -  - ]:          0 :       for (int64_t i=1; i<=n; ++i) {
    1005         [ -  - ]:          0 :         lua_geti( L, -1, i );
    1006 [ -  - ][ -  - ]:          0 :         ErrChk( lua_istable( L, -1 ), "bc_dirval table entry must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
    1007         [ -  - ]:          0 :         val[k].emplace_back();
    1008                 :          0 :         auto& b = val[k].back();
    1009         [ -  - ]:          0 :         int64_t m = luaL_len( L, -1 );
    1010         [ -  - ]:          0 :         for (int64_t j=1; j<=m; ++j) {
    1011         [ -  - ]:          0 :           lua_geti( L, -1, j );
    1012 [ -  - ][ -  - ]:          0 :           ErrChk( lua_isnumber( L, -1 ), "bc_dirval entry must be an real" );
         [ -  - ][ -  - ]
                 [ -  - ]
    1013 [ -  - ][ -  - ]:          0 :           b.push_back( static_cast< double >( lua_tonumber( L, -1 ) ) );
    1014         [ -  - ]:          0 :           lua_pop( L, 1 );
    1015                 :            :         }
    1016         [ -  - ]:          0 :         lua_pop( L, 1 );
    1017                 :            :       }
    1018                 :            :     }
    1019                 :            : 
    1020         [ -  - ]:          0 :     lua_pop( L, 1 );
    1021                 :            : 
    1022         [ -  - ]:          0 :   }
    1023         [ -  - ]:          0 : }
    1024                 :            : 
    1025                 :            : static void
    1026                 :        536 : bc_sym( lua_State* L, std::vector< int >& s, bool global = false )
    1027                 :            : // *****************************************************************************
    1028                 :            : // Parse bc_sym table from global scope or table
    1029                 :            : //! \param[in,out] L Lua state
    1030                 :            : //! \param[in] global True to parse from global scope, false from table on stack
    1031                 :            : //! \param[in,out] s Config state
    1032                 :            : // *****************************************************************************
    1033                 :            : {
    1034         [ +  + ]:        536 :   if (global) {
    1035                 :        268 :     lua_getglobal( L, "bc_sym" );
    1036                 :            :   } else {
    1037         [ +  + ]:        268 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, "bc_sym" ); else return;
    1038                 :            :   }
    1039                 :            : 
    1040         [ +  + ]:        316 :   if (!lua_isnil( L, -1 )) {
    1041         [ +  - ]:        157 :     s = sideset( L );
    1042                 :            :   }
    1043                 :            : 
    1044                 :        316 :   lua_pop( L, 1 );
    1045                 :            : }
    1046                 :            : 
    1047                 :            : static void
    1048                 :        268 : bc_sym_( lua_State* L,
    1049                 :            :          std::vector< std::vector< int > >& s,
    1050                 :            :          std::size_t nf,
    1051                 :            :          bool global = false )
    1052                 :            : // *****************************************************************************
    1053                 :            : // Parse bc_sym table from global scope or table for multiple meshes
    1054                 :            : //! \param[in,out] L Lua state
    1055                 :            : //! \param[in,out] s State to push back symmetry BC to (outer vec: mesh)
    1056                 :            : //! \param[in] nf Number of mesh files specified on command line
    1057                 :            : //! \param[in] global True to parse from global scope, false from table on stack
    1058                 :            : // *****************************************************************************
    1059                 :            : {
    1060         [ +  - ]:        268 :   if (nf == 1) return;
    1061                 :            : 
    1062         [ -  - ]:          0 :   s.resize( nf );
    1063         [ -  - ]:          0 :   std::string basename = "bc_sym_";
    1064                 :            : 
    1065         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
    1066                 :            : 
    1067 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
    1068                 :            : 
    1069         [ -  - ]:          0 :     if (global) {
    1070         [ -  - ]:          0 :       lua_getglobal( L, name.c_str() );
    1071                 :            :     } else {
    1072 [ -  - ][ -  - ]:          0 :       if (lua_istable(L, -1)) lua_getfield( L, -1, name.c_str() ); else return;
                 [ -  - ]
    1073                 :            :     }
    1074                 :            : 
    1075 [ -  - ][ -  - ]:          0 :     if (!lua_isnil( L, -1 )) {
    1076         [ -  - ]:          0 :       s[k] = sideset( L );
    1077                 :            :     }
    1078                 :            : 
    1079         [ -  - ]:          0 :     lua_pop( L, 1 );
    1080                 :            : 
    1081         [ -  - ]:          0 :   }
    1082         [ -  - ]:          0 : }
    1083                 :            : 
    1084                 :            : static void
    1085                 :        268 : bc_noslip( lua_State* L, std::vector< int >& s, bool global = false )
    1086                 :            : // *****************************************************************************
    1087                 :            : // Parse bc_noslip table from global scope or table
    1088                 :            : //! \param[in,out] L Lua state
    1089                 :            : //! \param[in,out] s State to push back no-slip BC setids to
    1090                 :            : //! \param[in] global True to parse from global scope, false from table on stack
    1091                 :            : // *****************************************************************************
    1092                 :            : {
    1093         [ +  - ]:        268 :   if (global) {
    1094                 :        268 :     lua_getglobal( L, "bc_noslip" );
    1095                 :            :   } else {
    1096         [ -  - ]:          0 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, "bc_noslip" ); else return;
    1097                 :            :   }
    1098                 :            : 
    1099         [ +  + ]:        268 :   if (!lua_isnil( L, -1 )) {
    1100         [ +  - ]:         28 :     s = sideset( L );
    1101                 :            :   }
    1102                 :            : 
    1103                 :        268 :   lua_pop( L, 1 );
    1104                 :            : }
    1105                 :            : 
    1106                 :            : static void
    1107                 :        268 : bc_noslip_( lua_State* L,
    1108                 :            :             std::vector< std::vector< int > >& s,
    1109                 :            :             std::size_t nf,
    1110                 :            :             bool global = false )
    1111                 :            : // *****************************************************************************
    1112                 :            : // Parse bc_noslip_* table from global scope or table for multple meshes
    1113                 :            : //! \param[in,out] L Lua state
    1114                 :            : //! \param[in,out] s State to push back no-slip BC setids to (outer vec: mesh)
    1115                 :            : //! \param[in] nf Number of mesh files specified on command line
    1116                 :            : //! \param[in] global True to parse from global scope, false from table on stack
    1117                 :            : // *****************************************************************************
    1118                 :            : {
    1119         [ +  - ]:        268 :   if (nf == 1) return;
    1120                 :            : 
    1121         [ -  - ]:          0 :   s.resize( nf );
    1122         [ -  - ]:          0 :   std::string basename = "bc_noslip_";
    1123                 :            : 
    1124         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
    1125                 :            : 
    1126 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
    1127                 :            : 
    1128         [ -  - ]:          0 :     if (global) {
    1129         [ -  - ]:          0 :       lua_getglobal( L, name.c_str() );
    1130                 :            :     } else {
    1131 [ -  - ][ -  - ]:          0 :       if (lua_istable(L, -1)) lua_getfield( L, -1, name.c_str() ); else return;
                 [ -  - ]
    1132                 :            :     }
    1133                 :            : 
    1134 [ -  - ][ -  - ]:          0 :     if (!lua_isnil( L, -1 )) {
    1135         [ -  - ]:          0 :       s[k] = sideset( L );
    1136                 :            :     }
    1137                 :            : 
    1138         [ -  - ]:          0 :     lua_pop( L, 1 );
    1139                 :            : 
    1140         [ -  - ]:          0 :   }
    1141         [ -  - ]:          0 : }
    1142                 :            : 
    1143                 :            : static void
    1144                 :        268 : bc_far( lua_State* L, Config& cfg )
    1145                 :            : // *****************************************************************************
    1146                 :            : // Parse bc_far table from global scope
    1147                 :            : //! \param[in,out] L Lua state
    1148                 :            : //! \param[in,out] cfg Config state
    1149                 :            : // *****************************************************************************
    1150                 :            : {
    1151                 :        268 :   lua_getglobal( L, "bc_far" );
    1152                 :            : 
    1153                 :        268 :   auto& tf = cfg.get< tag::bc_far >();
    1154         [ +  - ]:        268 :   tf.get< tag::sidesets >() = sideset( L );
    1155         [ +  - ]:        268 :   tf.get< tag::velocity >() = vector( L, "velocity" );
    1156                 :        268 :   tf.get< tag::density >() = real( L, "density" );
    1157                 :        268 :   tf.get< tag::pressure >() = real( L, "pressure" );
    1158                 :            : 
    1159                 :        268 :   lua_pop( L, 1 );
    1160                 :        268 : }
    1161                 :            : 
    1162                 :            : static void
    1163                 :        268 : bc_far_( lua_State* L, Config& cfg )
    1164                 :            : // *****************************************************************************
    1165                 :            : // Parse bc_far_* table from global scope for multiple meshes
    1166                 :            : //! \param[in,out] L Lua state
    1167                 :            : //! \param[in,out] cfg Config state
    1168                 :            : // *****************************************************************************
    1169                 :            : {
    1170                 :        268 :   auto nf = cfg.get< tag::input >().size();
    1171         [ +  - ]:        268 :   if (nf == 1) return;
    1172                 :            : 
    1173         [ -  - ]:          0 :   std::string basename = "bc_far_";
    1174                 :          0 :   auto& tf = cfg.get< tag::bc_far_ >();
    1175         [ -  - ]:          0 :   tf.resize( nf );
    1176                 :            : 
    1177         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
    1178                 :            : 
    1179 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
    1180         [ -  - ]:          0 :     lua_getglobal( L, name.c_str() );
    1181                 :            : 
    1182                 :          0 :     auto& tfk = tf[k];
    1183         [ -  - ]:          0 :     tfk.get< tag::sidesets >() = sideset( L );
    1184         [ -  - ]:          0 :     tfk.get< tag::velocity >() = vector( L, "velocity" );
    1185         [ -  - ]:          0 :     tfk.get< tag::density >() = real( L, "density" );
    1186         [ -  - ]:          0 :     tfk.get< tag::pressure >() = real( L, "pressure" );
    1187                 :            : 
    1188         [ -  - ]:          0 :     lua_pop( L, 1 );
    1189                 :            : 
    1190                 :          0 :   }
    1191                 :          0 : }
    1192                 :            : 
    1193                 :            : static void
    1194                 :        268 : bc_pre( lua_State* L, Config& cfg )
    1195                 :            : // *****************************************************************************
    1196                 :            : // Parse bc_pre table from global scope
    1197                 :            : //! \param[in,out] L Lua state
    1198                 :            : //! \param[in,out] cfg Config state
    1199                 :            : // *****************************************************************************
    1200                 :            : {
    1201                 :        268 :   lua_getglobal( L, "bc_pre" );
    1202                 :            : 
    1203         [ +  + ]:        268 :   if (lua_istable( L, -1 )) {
    1204                 :         12 :     auto bc_pre_set = [&]( const char* name ) {
    1205                 :         12 :       lua_getfield( L, -1, name );
    1206         [ +  - ]:         12 :       if (!lua_isnil( L, -1 )) {
    1207 [ -  + ][ -  - ]:         12 :         ErrChk( lua_istable( L, -1 ), "bc_pre must be a table" );
         [ -  - ][ -  - ]
    1208                 :         12 :         auto& tb = cfg.get< tag::bc_pre >();
    1209 [ +  - ][ +  - ]:         12 :         tb.get< tag::sidesets >().push_back( sideset( L ) );
    1210 [ +  - ][ +  - ]:         12 :         tb.get< tag::density >().push_back( real(L,"density") );
    1211 [ +  - ][ +  - ]:         12 :         tb.get< tag::pressure >().push_back( real(L,"pressure") );
    1212                 :            :       }
    1213                 :         12 :       lua_pop( L, 1 );
    1214                 :         12 :     };
    1215                 :            : 
    1216         [ +  - ]:          6 :     bc_pre_set( "inlet" );
    1217         [ +  - ]:          6 :     bc_pre_set( "outlet" );
    1218                 :            :   }
    1219                 :            : 
    1220                 :        268 :   lua_pop( L, 1 );
    1221                 :        268 : }
    1222                 :            : 
    1223                 :            : static void
    1224                 :        268 : bc_pre_( lua_State* L, Config& cfg )
    1225                 :            : // *****************************************************************************
    1226                 :            : // Parse bc_pre_* table from global scope for multiple meshes
    1227                 :            : //! \param[in,out] L Lua state
    1228                 :            : //! \param[in,out] cfg Config state
    1229                 :            : // *****************************************************************************
    1230                 :            : {
    1231                 :        268 :   auto nf = cfg.get< tag::input >().size();
    1232         [ +  - ]:        268 :   if (nf == 1) return;
    1233                 :            : 
    1234         [ -  - ]:          0 :   std::string basename = "bc_pre_";
    1235                 :          0 :   auto& tb = cfg.get< tag::bc_pre_ >();
    1236         [ -  - ]:          0 :   tb.resize( nf );
    1237                 :            : 
    1238         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
    1239                 :            : 
    1240 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
    1241         [ -  - ]:          0 :     lua_getglobal( L, name.c_str() );
    1242                 :          0 :     auto& tbk = tb[k];
    1243                 :            : 
    1244 [ -  - ][ -  - ]:          0 :     if (lua_istable( L, -1 )) {
    1245                 :          0 :       auto bc_pre_set = [&]( const char* n ) {
    1246                 :          0 :         lua_getfield( L, -1, n );
    1247         [ -  - ]:          0 :         if (!lua_isnil( L, -1 )) {
    1248 [ -  - ][ -  - ]:          0 :           ErrChk( lua_istable( L, -1 ), "bc_pre must be a table" );
         [ -  - ][ -  - ]
    1249 [ -  - ][ -  - ]:          0 :           tbk.get< tag::sidesets >().push_back( sideset( L ) );
    1250 [ -  - ][ -  - ]:          0 :           tbk.get< tag::density >().push_back( real(L,"density") );
    1251 [ -  - ][ -  - ]:          0 :           tbk.get< tag::pressure >().push_back( real(L,"pressure") );
    1252                 :            :         }
    1253                 :          0 :         lua_pop( L, 1 );
    1254                 :          0 :       };
    1255                 :            : 
    1256         [ -  - ]:          0 :       bc_pre_set( "inlet" );
    1257         [ -  - ]:          0 :       bc_pre_set( "outlet" );
    1258                 :            :     }
    1259                 :            : 
    1260         [ -  - ]:          0 :     lua_pop( L, 1 );
    1261                 :            : 
    1262                 :          0 :   }
    1263                 :          0 : }
    1264                 :            : 
    1265                 :            : static void
    1266                 :        268 : ic( lua_State* L, Config& cfg )
    1267                 :            : // *****************************************************************************
    1268                 :            : // Parse ic table from global scope
    1269                 :            : //! \param[in,out] L Lua state
    1270                 :            : //! \param[in,out] cfg Config state
    1271                 :            : // *****************************************************************************
    1272                 :            : {
    1273         [ +  - ]:        268 :   lua_getglobal( L, "ic" );
    1274                 :            : 
    1275                 :        268 :   auto& tic = cfg.get< tag::ic >();
    1276         [ +  - ]:        268 :   tic.get< tag::velocity >() = vector( L, "velocity" );
    1277         [ +  - ]:        268 :   tic.get< tag::density >() = real( L, "density" );
    1278         [ +  - ]:        268 :   tic.get< tag::pressure >() = real( L, "pressure" );
    1279         [ +  - ]:        268 :   tic.get< tag::energy >() = real( L, "energy" );
    1280         [ +  - ]:        268 :   tic.get< tag::temperature >() = real( L, "temperature" );
    1281                 :            : 
    1282                 :         18 :   auto box_extent = [&]( const char* axis, auto& v ) {
    1283                 :         18 :     lua_getfield( L, -1, axis );
    1284         [ +  - ]:         18 :     if (!lua_isnil( L, -1 )) {
    1285 [ -  + ][ -  - ]:         18 :       ErrChk( lua_istable( L, -1 ), "ic box extents must be a table" );
         [ -  - ][ -  - ]
    1286                 :         18 :       int64_t n = luaL_len( L, -1 );
    1287         [ +  + ]:         54 :       for (int64_t i=1; i<=n; ++i) {
    1288                 :         36 :         lua_geti( L, -1, i );
    1289 [ -  + ][ -  - ]:         36 :         ErrChk( lua_isnumber( L, -1 ), "ic extent must be a number" );
         [ -  - ][ -  - ]
    1290 [ +  - ][ +  - ]:         36 :         v.push_back( lua_tonumber( L, -1 ) );
    1291                 :         36 :         lua_pop( L, 1 );
    1292                 :            :       }
    1293                 :            :     }
    1294                 :         18 :     lua_pop( L, 1 );
    1295                 :         18 :   };
    1296                 :            : 
    1297 [ +  - ][ +  + ]:        268 :   if (lua_istable( L, -1 )) {
    1298         [ +  - ]:        160 :     lua_getfield( L, -1, "boxes" );
    1299 [ +  - ][ +  + ]:        160 :     if (!lua_isnil( L, -1 )) {
    1300 [ +  - ][ -  + ]:          3 :       ErrChk( lua_istable( L, -1 ), "ic boxes must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
    1301                 :          3 :       auto& boxes = tic.get< tag::boxes >();
    1302         [ +  - ]:          3 :       int64_t n = luaL_len( L, -1 );
    1303         [ +  + ]:          9 :       for (int64_t i=1; i<=n; ++i) {
    1304         [ +  - ]:          6 :         lua_geti( L, -1, i );
    1305 [ +  - ][ -  + ]:          6 :         ErrChk( lua_istable( L, -1 ), "ic box must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
    1306         [ +  - ]:          6 :         boxes.emplace_back();
    1307                 :          6 :         auto& box = boxes.back();
    1308         [ +  - ]:          6 :         box_extent( "x", box.get< tag::box_x >() );
    1309         [ +  - ]:          6 :         box_extent( "y", box.get< tag::box_y >() );
    1310         [ +  - ]:          6 :         box_extent( "z", box.get< tag::box_z >() );
    1311         [ +  - ]:          6 :         box.get< tag::box_velocity >() = vector( L, "velocity" );
    1312         [ +  - ]:          6 :         box.get< tag::box_density >() = real( L, "density" );
    1313         [ +  - ]:          6 :         box.get< tag::box_pressure >() = real( L, "pressure" );
    1314         [ +  - ]:          6 :         box.get< tag::box_energy >() = real( L, "energy" );
    1315         [ +  - ]:          6 :         box.get< tag::box_temperature >() = real( L, "temperature" );
    1316         [ +  - ]:          6 :         lua_pop( L, 1 );
    1317                 :            :       }
    1318                 :            :     }
    1319         [ +  - ]:        160 :     lua_pop( L, 1 );
    1320                 :            :   }
    1321                 :            : 
    1322         [ +  - ]:        268 :   lua_pop( L, 1 );
    1323                 :        268 : }
    1324                 :            : 
    1325                 :            : static void
    1326                 :        268 : ic_( lua_State* L, Config& cfg )
    1327                 :            : // *****************************************************************************
    1328                 :            : // Parse ic table from global scope for multiple meshes
    1329                 :            : //! \param[in,out] L Lua state
    1330                 :            : //! \param[in,out] cfg Config state
    1331                 :            : // *****************************************************************************
    1332                 :            : {
    1333                 :        268 :   auto nf = cfg.get< tag::input >().size();
    1334         [ +  - ]:        268 :   if (nf == 1) return;
    1335                 :            : 
    1336         [ -  - ]:          0 :   std::string basename = "ic_";
    1337                 :          0 :   auto& tic = cfg.get< tag::ic_ >();
    1338         [ -  - ]:          0 :   tic.resize( nf );
    1339                 :            : 
    1340         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
    1341                 :            : 
    1342 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
    1343         [ -  - ]:          0 :     lua_getglobal( L, name.c_str() );
    1344                 :            : 
    1345                 :          0 :     auto& tick = tic[k];
    1346         [ -  - ]:          0 :     tick.get< tag::velocity >() = vector( L, "velocity" );
    1347         [ -  - ]:          0 :     tick.get< tag::density >() = real( L, "density" );
    1348         [ -  - ]:          0 :     tick.get< tag::pressure >() = real( L, "pressure" );
    1349         [ -  - ]:          0 :     tick.get< tag::energy >() = real( L, "energy" );
    1350         [ -  - ]:          0 :     tick.get< tag::temperature >() = real( L, "temperature" );
    1351                 :            : 
    1352                 :          0 :     auto box_extent = [&]( const char* axis, auto& v ) {
    1353                 :          0 :       lua_getfield( L, -1, axis );
    1354         [ -  - ]:          0 :       if (!lua_isnil( L, -1 )) {
    1355 [ -  - ][ -  - ]:          0 :         ErrChk( lua_istable( L, -1 ), name + " box extents must be a table" );
         [ -  - ][ -  - ]
    1356                 :          0 :         int64_t n = luaL_len( L, -1 );
    1357         [ -  - ]:          0 :         for (int64_t i=1; i<=n; ++i) {
    1358                 :          0 :           lua_geti( L, -1, i );
    1359 [ -  - ][ -  - ]:          0 :           ErrChk( lua_isnumber( L, -1 ), name + " extent must be a number" );
         [ -  - ][ -  - ]
    1360 [ -  - ][ -  - ]:          0 :           v.push_back( lua_tonumber( L, -1 ) );
    1361                 :          0 :           lua_pop( L, 1 );
    1362                 :            :         }
    1363                 :            :       }
    1364                 :          0 :       lua_pop( L, 1 );
    1365                 :          0 :     };
    1366                 :            : 
    1367 [ -  - ][ -  - ]:          0 :     if (lua_istable( L, -1 )) {
    1368         [ -  - ]:          0 :       lua_getfield( L, -1, "boxes" );
    1369 [ -  - ][ -  - ]:          0 :       if (!lua_isnil( L, -1 )) {
    1370 [ -  - ][ -  - ]:          0 :         ErrChk( lua_istable( L, -1 ), name + " boxes must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
    1371                 :          0 :         auto& boxes = tick.get< tag::boxes >();
    1372         [ -  - ]:          0 :         int64_t n = luaL_len( L, -1 );
    1373         [ -  - ]:          0 :         for (int64_t i=1; i<=n; ++i) {
    1374         [ -  - ]:          0 :           lua_geti( L, -1, i );
    1375 [ -  - ][ -  - ]:          0 :           ErrChk( lua_istable( L, -1 ), name + " box must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
    1376         [ -  - ]:          0 :           boxes.emplace_back();
    1377                 :          0 :           auto& box = boxes.back();
    1378         [ -  - ]:          0 :           box_extent( "x", box.get< tag::box_x >() );
    1379         [ -  - ]:          0 :           box_extent( "y", box.get< tag::box_y >() );
    1380         [ -  - ]:          0 :           box_extent( "z", box.get< tag::box_z >() );
    1381         [ -  - ]:          0 :           box.get< tag::box_velocity >() = vector( L, "velocity" );
    1382         [ -  - ]:          0 :           box.get< tag::box_density >() = real( L, "density" );
    1383         [ -  - ]:          0 :           box.get< tag::box_pressure >() = real( L, "pressure" );
    1384         [ -  - ]:          0 :           box.get< tag::box_energy >() = real( L, "energy" );
    1385         [ -  - ]:          0 :           box.get< tag::box_temperature >() = real( L, "temperature" );
    1386         [ -  - ]:          0 :           lua_pop( L, 1 );
    1387                 :            :         }
    1388                 :            :       }
    1389         [ -  - ]:          0 :       lua_pop( L, 1 );
    1390                 :            :     }
    1391                 :            : 
    1392         [ -  - ]:          0 :     lua_pop( L, 1 );
    1393                 :            : 
    1394                 :          0 :   }
    1395                 :          0 : }
    1396                 :            : 
    1397                 :            : static void
    1398                 :        268 : mat( lua_State* L, Config& cfg )
    1399                 :            : // *****************************************************************************
    1400                 :            : // Parse mat table
    1401                 :            : //! \param[in,out] L Lua state
    1402                 :            : //! \param[in,out] cfg Config state
    1403                 :            : // *****************************************************************************
    1404                 :            : {
    1405                 :        268 :   lua_getglobal( L, "mat" );
    1406                 :            : 
    1407                 :        268 :   cfg.get< tag::mat_spec_heat_ratio >() = real( L, "spec_heat_ratio", 1.4 );
    1408                 :        268 :   cfg.get< tag::mat_spec_heat_const_vol >() = real( L, "spec_heat_const_vol" );
    1409                 :        268 :   cfg.get< tag::mat_spec_gas_const >() = real(L, "spec_gas_const", 287.052874);
    1410                 :        268 :   cfg.get< tag::mat_heat_conductivity >() = real( L, "heat_conductivity" );
    1411                 :        268 :   cfg.get< tag::mat_dyn_viscosity >() = real( L, "dyn_viscosity", 0.0 );
    1412                 :        268 :   cfg.get< tag::mat_dyn_diffusivity >() = real( L, "dyn_diffusivity", 0.0 );
    1413                 :            : 
    1414                 :        268 :   lua_pop( L, 1 );
    1415                 :        268 : }
    1416                 :            : 
    1417                 :            : static void
    1418                 :        268 : problem( lua_State* L, Config& cfg )
    1419                 :            : // *****************************************************************************
    1420                 :            : // Parse problem table
    1421                 :            : //! \param[in,out] L Lua state
    1422                 :            : //! \param[in,out] cfg Config state
    1423                 :            : // *****************************************************************************
    1424                 :            : {
    1425                 :        268 :   lua_getglobal( L, "problem" );
    1426                 :            : 
    1427         [ +  - ]:        268 :   cfg.get< tag::problem >() = string( L, "name", "userdef" );
    1428                 :        268 :   cfg.get< tag::problem_alpha >() = real( L, "alpha" );
    1429                 :        268 :   cfg.get< tag::problem_kappa >() = real( L, "kappa" );
    1430                 :        268 :   cfg.get< tag::problem_r0 >() = real( L, "r0" );
    1431                 :        268 :   cfg.get< tag::problem_p0 >() = real( L, "p0" );
    1432                 :        268 :   cfg.get< tag::problem_ce >() = real( L, "ce" );
    1433         [ +  - ]:        268 :   cfg.get< tag::problem_beta >() = vector( L, "beta" );
    1434                 :            : 
    1435         [ +  + ]:        268 :   if (lua_istable( L, -1 )) {
    1436                 :        111 :     lua_getfield( L, -1, "src" );
    1437         [ +  + ]:        111 :     if (!lua_isnil( L, -1 )) {
    1438 [ -  + ][ -  - ]:          3 :       ErrChk( lua_istable( L, -1 ), "problem source must be a table" );
         [ -  - ][ -  - ]
    1439                 :          3 :       auto& s = cfg.get< tag::problem_src >();
    1440         [ +  - ]:          3 :       s.get< tag::location >() = vector( L, "location" );
    1441                 :          3 :       s.get< tag::radius >() = real( L, "radius" );
    1442                 :          3 :       s.get< tag::release_time >() = real( L, "release_time" );
    1443                 :            :     }
    1444                 :        111 :     lua_pop( L, 1 );
    1445                 :            :   }
    1446                 :            : 
    1447                 :        268 :   const auto& solver = cfg.get< tag::solver >();
    1448                 :        268 :   const auto& problem = cfg.get< tag::problem >();
    1449                 :            : 
    1450                 :        268 :   auto& n = cfg.get< tag::problem_ncomp >();
    1451                 :        268 :   n = 5;
    1452         [ +  + ]:        505 :   if ( problem == "slot_cyl" or
    1453 [ +  + ][ -  + ]:        505 :        problem == "point_src" or
                 [ +  + ]
    1454                 :        234 :        problem == "sheardiff" )
    1455                 :            :   {
    1456                 :         34 :      ++n;
    1457                 :            :   }
    1458                 :            : 
    1459         [ +  + ]:        268 :   if (solver == "chocg") {
    1460                 :         49 :     n -= 2;
    1461                 :            :   }
    1462         [ +  + ]:        219 :   else if (solver == "lohcg") {
    1463                 :         35 :     n -= 1;
    1464                 :            :   }
    1465                 :            : 
    1466                 :        268 :   lua_pop( L, 1 );
    1467                 :        268 : }
    1468                 :            : 
    1469                 :            : static void
    1470                 :        268 : href( lua_State* L, Config& cfg )
    1471                 :            : // *****************************************************************************
    1472                 :            : // Parse href table from global scope
    1473                 :            : //! \param[in,out] L Lua state
    1474                 :            : //! \param[in,out] cfg Config state
    1475                 :            : // *****************************************************************************
    1476                 :            : {
    1477                 :        268 :   lua_getglobal( L, "href" );
    1478                 :            : 
    1479                 :        268 :   auto& ht = cfg.get< tag::href >();
    1480                 :        268 :   ht.get< tag::t0 >() = boolean( L, "t0" );
    1481                 :        268 :   ht.get< tag::dt >() = boolean( L, "dt" );
    1482                 :        268 :   ht.get< tag::dtfreq >() = unsigint( L, "dtfreq", 5 );
    1483         [ +  - ]:        268 :   ht.get< tag::init >() = stringlist( L, "init" );
    1484         [ +  - ]:        268 :   ht.get< tag::refvar >() = unsigints( L, "refvar" );
    1485         [ +  - ]:        268 :   ht.get< tag::error >() = string( L, "error", "jump" );
    1486                 :        268 :   ht.get< tag::maxlevels >() = unsigint( L, "maxlevels", 2 );
    1487                 :            : 
    1488                 :        268 :   lua_pop( L, 1 );
    1489                 :        268 : }
    1490                 :            : 
    1491                 :            : 
    1492                 :            : static void
    1493                 :        268 : href_( lua_State* L, Config& cfg )
    1494                 :            : // *****************************************************************************
    1495                 :            : // Parse href table from global scope for multiple meshes
    1496                 :            : //! \param[in,out] L Lua state
    1497                 :            : //! \param[in,out] cfg Config state
    1498                 :            : // *****************************************************************************
    1499                 :            : {
    1500                 :        268 :   auto nf = cfg.get< tag::input >().size();
    1501         [ +  - ]:        268 :   if (nf == 1) return;
    1502                 :            : 
    1503         [ -  - ]:          0 :   std::string basename = "href_";
    1504                 :          0 :   auto& ht = cfg.get< tag::href_ >();
    1505         [ -  - ]:          0 :   ht.resize( nf );
    1506                 :            : 
    1507         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
    1508                 :            : 
    1509 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
    1510         [ -  - ]:          0 :     lua_getglobal( L, name.c_str() );
    1511                 :            : 
    1512                 :          0 :     auto& htk = ht[k];
    1513         [ -  - ]:          0 :     htk.get< tag::t0 >() = boolean( L, "t0" );
    1514         [ -  - ]:          0 :     htk.get< tag::dt >() = boolean( L, "dt" );
    1515         [ -  - ]:          0 :     htk.get< tag::dtfreq >() = unsigint( L, "dtfreq", 5 );
    1516         [ -  - ]:          0 :     htk.get< tag::init >() = stringlist( L, "init" );
    1517         [ -  - ]:          0 :     htk.get< tag::refvar >() = unsigints( L, "refvar" );
    1518         [ -  - ]:          0 :     htk.get< tag::error >() = string( L, "error", "jump" );
    1519         [ -  - ]:          0 :     htk.get< tag::maxlevels >() = unsigint( L, "maxlevels", 6 );
    1520                 :            : 
    1521         [ -  - ]:          0 :     lua_pop( L, 1 );
    1522                 :            : 
    1523                 :          0 :   }
    1524                 :          0 : }
    1525                 :            : 
    1526                 :            : static void
    1527                 :        268 : deactivate( lua_State* L, Config& cfg )
    1528                 :            : // *****************************************************************************
    1529                 :            : // Parse deactivate table
    1530                 :            : //! \param[in,out] L Lua state
    1531                 :            : //! \param[in,out] cfg Config state
    1532                 :            : // *****************************************************************************
    1533                 :            : {
    1534                 :        268 :   lua_getglobal( L, "deactivate" );
    1535                 :            : 
    1536                 :        268 :   cfg.get< tag::deafreq >() = unsigint( L, "freq", 0 );
    1537                 :        268 :   cfg.get< tag::deatol >() = real( L, "tol", 1.0e-3 );
    1538                 :        268 :   cfg.get< tag::deadif >() = real( L, "dif", 0.0 );
    1539         [ +  - ]:        268 :   cfg.get< tag::deasys >() = unsigints( L, "sys" );
    1540                 :        268 :   cfg.get< tag::deatime >() = real( L, "time", 0.0 );
    1541                 :            : 
    1542                 :        268 :   cfg.get< tag::deactivate >() = cfg.get< tag::deafreq >();  // on if freq > 0
    1543                 :            : 
    1544                 :        268 :   lua_pop( L, 1 );
    1545                 :        268 : }
    1546                 :            : 
    1547                 :            : static void
    1548                 :        268 : pressure( lua_State* L, Config& cfg )
    1549                 :            : // *****************************************************************************
    1550                 :            : // Parse pressure table from global scope
    1551                 :            : //! \param[in,out] L Lua state
    1552                 :            : //! \param[in,out] cfg Config state
    1553                 :            : // *****************************************************************************
    1554                 :            : {
    1555                 :        268 :   lua_getglobal( L, "pressure" );
    1556                 :            : 
    1557                 :        268 :   auto& tp = cfg.get< tag::pressure >();
    1558                 :        268 :   tp.get< tag::iter >() = unsigint( L, "iter", 10 );
    1559                 :        268 :   tp.get< tag::tol >() = real( L, "tol", 1.0e-3 );
    1560                 :        268 :   tp.get< tag::verbose >() = unsigint( L, "verbose", 0 );
    1561                 :        268 :   tp.get< tag::hydrostat >() = unsigint( L, "hydrostat" );
    1562         [ +  - ]:        268 :   tp.get< tag::pc >() = string( L, "pc", "none" );
    1563                 :        268 :   bc_dir( L, tp.get< tag::bc_dir >() );
    1564                 :        268 :   bc_dirval( L, tp.get< tag::bc_dirval >() );
    1565                 :        268 :   bc_sym( L, tp.get< tag::bc_sym >() );
    1566                 :            : 
    1567                 :        268 :   lua_pop( L, 1 );
    1568                 :        268 : }
    1569                 :            : 
    1570                 :            : static void
    1571                 :        268 : pressure_( lua_State* L, Config& cfg )
    1572                 :            : // *****************************************************************************
    1573                 :            : // Parse pressure_* table from global scope for multiple meshes
    1574                 :            : //! \param[in,out] L Lua state
    1575                 :            : //! \param[in,out] cfg Config state
    1576                 :            : // *****************************************************************************
    1577                 :            : {
    1578                 :        268 :   auto nf = cfg.get< tag::input >().size();
    1579         [ +  - ]:        268 :   if (nf == 1) return;
    1580                 :            : 
    1581         [ -  - ]:          0 :   std::string basename = "pressure_";
    1582                 :          0 :   auto& tp = cfg.get< tag::pressure_ >();
    1583         [ -  - ]:          0 :   tp.resize( nf );
    1584                 :            : 
    1585         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
    1586                 :            : 
    1587 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
    1588         [ -  - ]:          0 :     lua_getglobal( L, name.c_str() );
    1589                 :            : 
    1590                 :          0 :     auto& tpk = tp[k];
    1591         [ -  - ]:          0 :     tpk.get< tag::iter >() = unsigint( L, "iter", 10 );
    1592         [ -  - ]:          0 :     tpk.get< tag::tol >() = real( L, "tol", 1.0e-3 );
    1593         [ -  - ]:          0 :     tpk.get< tag::verbose >() = unsigint( L, "verbose", 0 );
    1594         [ -  - ]:          0 :     tpk.get< tag::hydrostat >() = unsigint( L, "hydrostat" );
    1595         [ -  - ]:          0 :     tpk.get< tag::pc >() = string( L, "pc", "none" );
    1596         [ -  - ]:          0 :     bc_dir( L, tpk.get< tag::bc_dir >() );
    1597         [ -  - ]:          0 :     bc_dirval( L, tpk.get< tag::bc_dirval >() );
    1598         [ -  - ]:          0 :     bc_sym( L, tpk.get< tag::bc_sym >() );
    1599                 :            : 
    1600         [ -  - ]:          0 :     lua_pop( L, 1 );
    1601                 :            : 
    1602                 :          0 :   }
    1603                 :          0 : }
    1604                 :            : 
    1605                 :            : static void
    1606                 :        268 : part_( lua_State* L, Config& cfg, const char* def = "default" )
    1607                 :            : // *****************************************************************************
    1608                 :            : // Parse part_* field from global scope for multiple meshes
    1609                 :            : //! \param[in,out] L Lua state
    1610                 :            : //! \param[in,out] cfg Config state
    1611                 :            : //! \param[in] def Default if does not exist
    1612                 :            : // *****************************************************************************
    1613                 :            : {
    1614                 :        268 :   auto nf = cfg.get< tag::input >().size();
    1615         [ +  - ]:        268 :   if (nf == 1) return;
    1616                 :            : 
    1617         [ -  - ]:          0 :   std::string basename = "part_";
    1618                 :          0 :   auto& vp = cfg.get< tag::part_ >();
    1619 [ -  - ][ -  - ]:          0 :   if (vp.size() != nf ) vp.resize( nf, def );
                 [ -  - ]
    1620                 :            : 
    1621         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
    1622                 :            : 
    1623 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
    1624         [ -  - ]:          0 :     lua_getglobal( L, name.c_str() );
    1625                 :            : 
    1626 [ -  - ][ -  - ]:          0 :     if (!lua_isnil( L, -1 )) {
    1627 [ -  - ][ -  - ]:          0 :       ErrChk( lua_isstring( L, -1 ), std::string(name) + " must be a string" );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
    1628 [ -  - ][ -  - ]:          0 :       vp[k] = lua_tostring( L, -1 );
    1629                 :            :     }
    1630                 :            : 
    1631         [ -  - ]:          0 :     lua_pop( L, 1 );
    1632                 :            : 
    1633                 :          0 :   }
    1634                 :          0 : }
    1635                 :            : 
    1636                 :            : static void
    1637                 :        268 : zoltan_params_( lua_State* L, Config& cfg )
    1638                 :            : // *****************************************************************************
    1639                 :            : // Parse zoltan_params_* field from global scope for multiple meshes
    1640                 :            : //! \param[in,out] L Lua state
    1641                 :            : //! \param[in,out] cfg Config state
    1642                 :            : // *****************************************************************************
    1643                 :            : {
    1644                 :        268 :   auto nf = cfg.get< tag::input >().size();
    1645         [ +  - ]:        268 :   if (nf == 1) return;
    1646                 :            : 
    1647         [ -  - ]:          0 :   std::string basename = "zoltan_params_";
    1648                 :          0 :   auto& vl = cfg.get< tag::zoltan_params_ >();
    1649         [ -  - ]:          0 :   vl.resize( nf );
    1650                 :            : 
    1651         [ -  - ]:          0 :   for (std::size_t k=0; k<nf; ++k) {
    1652                 :            : 
    1653 [ -  - ][ -  - ]:          0 :     std::string name = basename + std::to_string(k+1);
    1654         [ -  - ]:          0 :     lua_getglobal( L, name.c_str() );
    1655                 :          0 :     auto& v = vl[k];
    1656                 :            : 
    1657 [ -  - ][ -  - ]:          0 :     if (!lua_isnil( L, -1 )) {
    1658 [ -  - ][ -  - ]:          0 :       ErrChk( lua_istable( L, -1 ), "stringlist must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
    1659         [ -  - ]:          0 :       int64_t n = luaL_len( L, -1 );
    1660         [ -  - ]:          0 :       for (int64_t i=1; i<=n; ++i) {
    1661         [ -  - ]:          0 :         lua_geti( L, -1, i );
    1662 [ -  - ][ -  - ]:          0 :         ErrChk( lua_isstring( L, -1 ), "stringlist components must be strings" );
         [ -  - ][ -  - ]
                 [ -  - ]
    1663 [ -  - ][ -  - ]:          0 :         v.push_back( lua_tostring( L, -1 ) );
                 [ -  - ]
    1664         [ -  - ]:          0 :         lua_pop( L, 1 );
    1665                 :            :       }
    1666                 :            :     }
    1667                 :            : 
    1668         [ -  - ]:          0 :     lua_pop( L, 1 );
    1669                 :            : 
    1670                 :          0 :   }
    1671                 :          0 : }
    1672                 :            : 
    1673                 :            : static void
    1674                 :        268 : momentum( lua_State* L, Config& cfg )
    1675                 :            : // *****************************************************************************
    1676                 :            : // Parse momentum table
    1677                 :            : //! \param[in,out] L Lua state
    1678                 :            : //! \param[in,out] cfg Config state
    1679                 :            : // *****************************************************************************
    1680                 :            : {
    1681                 :        268 :   lua_getglobal( L, "momentum" );
    1682                 :            : 
    1683                 :        268 :   cfg.get< tag::mom_iter >() = unsigint( L, "iter", 10 );
    1684                 :        268 :   cfg.get< tag::mom_tol >() = real( L, "tol", 1.0e-3 );
    1685                 :        268 :   cfg.get< tag::mom_verbose >() = unsigint( L, "verbose", 0 );
    1686         [ +  - ]:        268 :   cfg.get< tag::mom_pc >() = string( L, "pc", "none" );
    1687                 :            : 
    1688                 :        268 :   lua_pop( L, 1 );
    1689                 :        268 : }
    1690                 :            : 
    1691                 :            : static void
    1692                 :        268 : lb( lua_State* L, Config& cfg )
    1693                 :            : // *****************************************************************************
    1694                 :            : // Parse lb (load balancing configuration) table
    1695                 :            : //! \param[in,out] L Lua state
    1696                 :            : //! \param[in,out] cfg Config state
    1697                 :            : // *****************************************************************************
    1698                 :            : {
    1699                 :        268 :   lua_getglobal( L, "lb" );
    1700                 :            : 
    1701                 :        268 :   cfg.get< tag::lbtime >() = real( L, "time", 0.0 );
    1702                 :            : 
    1703                 :        268 :   lua_pop( L, 1 );
    1704                 :        268 : }
    1705                 :            : 
    1706                 :            : void
    1707                 :        268 : Config::control()
    1708                 :            : // *****************************************************************************
    1709                 :            : // Parse control file
    1710                 :            : // *****************************************************************************
    1711                 :            : {
    1712                 :        268 :   const auto& controlfile = get< tag::control >();
    1713                 :            : 
    1714                 :        268 :   tk::Print print;
    1715 [ +  - ][ +  - ]:        268 :   print.section( "Control file: " + controlfile );
    1716                 :            : 
    1717         [ +  - ]:        268 :   lua_State* L = luaL_newstate();
    1718         [ +  - ]:        268 :   luaL_openlibs( L );
    1719                 :            : 
    1720                 :        268 :   std::string err;
    1721                 :            : 
    1722 [ +  - ][ +  - ]:        268 :   if (luaL_dofile( L, controlfile.c_str() ) == LUA_OK) {
         [ +  - ][ -  + ]
                 [ +  - ]
    1723                 :            : 
    1724         [ +  - ]:        268 :     get< tag::nstep >() = unsigint( L, "nstep", largeuint, true );
    1725         [ +  - ]:        268 :     get< tag::term >() = real( L, "term", largereal, true );
    1726         [ +  - ]:        268 :     get< tag::ttyi >() = unsigint( L, "ttyi", 1, true );
    1727         [ +  - ]:        268 :     get< tag::cfl >() = real( L, "cfl", 0.0, true );
    1728         [ +  - ]:        268 :     get< tag::rk >() = unsigint( L, "rk", 1, true );
    1729         [ +  - ]:        268 :     get< tag::theta >() = real( L, "theta", 0.0, true );
    1730         [ +  - ]:        268 :     get< tag::dt >() = real( L, "dt", 0.0, true );
    1731         [ +  - ]:        268 :     get< tag::turkel >() = real( L, "turkel", 0.5, true );
    1732         [ +  - ]:        268 :     get< tag::soundspeed >() = real( L, "soundspeed", 1.0, true );
    1733         [ +  - ]:        268 :     get< tag::velinf >() = vector( L, "velinf", 1.0, true );
    1734         [ +  - ]:        268 :     get< tag::t0 >() = real( L, "t0", 0.0, true );
    1735         [ +  - ]:        268 :     get< tag::reorder >() = boolean( L, "reorder", false, true );
    1736         [ +  - ]:        268 :     get< tag::flux >() = string( L, "flux", "rusanov", true );
    1737         [ +  - ]:        268 :     get< tag::steady >() = boolean( L, "steady", false, true );
    1738         [ +  - ]:        268 :     get< tag::residual >() = real( L, "residual", 0.0, true );
    1739         [ +  - ]:        268 :     get< tag::rescomp >() = unsigint( L, "rescomp", 1, true );
    1740                 :            : 
    1741         [ +  - ]:        268 :     get< tag::part >() = string( L, "part", "rcb", true );
    1742         [ +  - ]:        268 :     part_( L, *this, "rcb" );
    1743                 :            : 
    1744         [ +  - ]:        268 :     get< tag::zoltan_params >() = stringlist( L, "zoltan_params", true );
    1745         [ +  - ]:        268 :     zoltan_params_( L, *this );
    1746                 :            : 
    1747         [ +  - ]:        268 :     get< tag::solver >() = string( L, "solver", "riecg", true );
    1748         [ +  - ]:        268 :     get< tag::stab >() = boolean( L, "stab", true, true );
    1749         [ +  - ]:        268 :     get< tag::stab2 >() = boolean( L, "stab2", false, true );
    1750         [ +  - ]:        268 :     get< tag::stab2coef >() = real( L, "stab2coef", 0.2, true );
    1751         [ +  - ]:        268 :     get< tag::fct >() = boolean( L, "fct", true, true );
    1752         [ +  - ]:        268 :     get< tag::fctdif >() = real( L, "fctdif", 1.0, true );
    1753         [ +  - ]:        268 :     get< tag::fctclip >() = boolean( L, "fctclip", false, true );
    1754         [ +  - ]:        268 :     get< tag::fctsys >() = unsigints( L, "fctsys", true );
    1755         [ +  - ]:        268 :     get< tag::fctfreeze >() = real( L, "fctfreeze", -largereal, true );
    1756         [ +  - ]:        268 :     get< tag::freezeflow >() = real( L, "freezeflow", 1.0, true );
    1757         [ +  - ]:        268 :     get< tag::freezetime >() = real( L, "freezetime", 0.0, true );
    1758                 :            : 
    1759         [ +  - ]:        268 :     ic( L, *this );
    1760         [ +  - ]:        268 :     ic_( L, *this );
    1761                 :            : 
    1762         [ +  - ]:        268 :     bc_dir( L, get< tag::bc_dir >(), true );
    1763         [ +  - ]:        268 :     bc_dir_( L, get< tag::bc_dir_ >(), get< tag::input >().size(), true );
    1764         [ +  - ]:        268 :     bc_dirval( L, get< tag::bc_dirval >(), true );
    1765         [ +  - ]:        268 :     bc_dirval_( L, get< tag::bc_dirval_ >(), get< tag::input >().size(), true );
    1766                 :            : 
    1767         [ +  - ]:        268 :     bc_sym( L, get< tag::bc_sym >(), true );
    1768         [ +  - ]:        268 :     bc_sym_( L, get< tag::bc_sym_ >(), get< tag::input >().size(), true );
    1769                 :            : 
    1770         [ +  - ]:        268 :     bc_noslip( L, get< tag::bc_noslip >(), true );
    1771         [ +  - ]:        268 :     bc_noslip_( L, get< tag::bc_noslip_ >(), get< tag::input >().size(), true );
    1772                 :            : 
    1773         [ +  - ]:        268 :     bc_far( L, *this );
    1774         [ +  - ]:        268 :     bc_far_( L, *this );
    1775                 :            : 
    1776         [ +  - ]:        268 :     bc_pre( L, *this );
    1777         [ +  - ]:        268 :     bc_pre_( L, *this );
    1778                 :            : 
    1779         [ +  - ]:        268 :     problem( L, *this );
    1780         [ +  - ]:        268 :     mat( L, *this );
    1781         [ +  - ]:        268 :     overset( L, *this );
    1782         [ +  - ]:        268 :     fieldout( L, *this );
    1783         [ +  - ]:        268 :     fieldout_( L, *this );
    1784         [ +  - ]:        268 :     histout( L, *this );
    1785         [ +  - ]:        268 :     histout_( L, *this );
    1786         [ +  - ]:        268 :     integout( L, *this );
    1787         [ +  - ]:        268 :     integout_( L, *this );
    1788         [ +  - ]:        268 :     diag( L, *this );
    1789         [ +  - ]:        268 :     href( L, *this );
    1790         [ +  - ]:        268 :     href_( L, *this );
    1791         [ +  - ]:        268 :     deactivate( L, *this );
    1792         [ +  - ]:        268 :     pressure( L, *this );
    1793         [ +  - ]:        268 :     pressure_( L, *this );
    1794         [ +  - ]:        268 :     momentum( L, *this );
    1795         [ +  - ]:        268 :     lb( L, *this );
    1796                 :            : 
    1797 [ +  - ][ +  - ]:        268 :     print << "Solver: " << get< tag::solver >() << '\n';
                 [ +  - ]
    1798                 :            : 
    1799                 :            :   } else {
    1800 [ -  - ][ -  - ]:          0 :     err = lua_tostring( L, -1 );
    1801                 :            :   }
    1802                 :            : 
    1803         [ +  - ]:        268 :   lua_close( L );
    1804                 :            : 
    1805 [ -  + ][ -  - ]:        268 :   ErrChk( err.empty(), "Lua error during control file parsing: " + err );
         [ -  - ][ -  - ]
    1806                 :            : 
    1807                 :            :   // Output command line object to file
    1808 [ +  - ][ +  - ]:        268 :   auto logfilename = tk::inciter_executable() + "_control.log";
    1809         [ +  - ]:        268 :   tk::Writer log( logfilename );
    1810         [ +  - ]:        268 :   tk::print( log.stream(), *this );
    1811 [ +  - ][ +  - ]:        268 :   print << "Control data saved in " << logfilename << '\n';
                 [ +  - ]
    1812                 :        268 : }
    1813                 :            : 
    1814                 :            : } // ctr::
    1815                 :            : } // inciter::

Generated by: LCOV version 1.16