Xyst test code coverage report
Current view: top level - Control - InciterConfig.cpp (source / functions) Hit Total Coverage
Commit: b2278901c7a653f0d92b235cc98ed02988a87738 Lines: 512 563 90.9 %
Date: 2024-12-18 15:54:33 Functions: 33 34 97.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 437 1000 43.7 %

           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-2024 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                 :            : namespace ctr {
      41                 :            : 
      42                 :            : static constexpr auto largeint = std::numeric_limits< int64_t >::max();
      43                 :            : static constexpr auto largeuint = std::numeric_limits< uint64_t >::max();
      44                 :            : static constexpr auto largereal = std::numeric_limits< double >::max();
      45                 :            : 
      46                 :            : void
      47                 :        262 : Config::cmdline( int argc, char** argv )
      48                 :            : // *****************************************************************************
      49                 :            : //! Contructor: parse inciter command line
      50                 :            : //! \param[in] argc Number of arguments to executable
      51                 :            : //! \param[in] argv Arguments to executable
      52                 :            : // *****************************************************************************
      53                 :            : {
      54         [ -  + ]:        262 :   if (!argc) return;
      55                 :            : 
      56                 :            :   // Defaults
      57 [ +  - ][ +  - ]:        262 :   if (!tk::git_commit().empty()) get< tag::commit >() = tk::git_commit();
                 [ +  - ]
      58         [ +  - ]:        262 :   get< tag::output >() = "out";
      59         [ +  - ]:        262 :   get< tag::diag >() = "diag";
      60         [ +  - ]:        262 :   get< tag::checkpoint >() = "restart";
      61                 :        262 :   get< tag::lbfreq >() = 1;
      62                 :        262 :   get< tag::rsfreq >() = 1000;
      63                 :            : 
      64         [ -  + ]:        262 :   if (argc == 1) {
      65         [ -  - ]:          0 :     help( argv );
      66         [ -  - ]:          0 :     CkExit( EXIT_FAILURE );
      67                 :            :   }
      68                 :        262 :   tk::Print print;
      69                 :            : 
      70                 :            :   // Process command line arguments
      71                 :            :   int c;
      72         [ +  + ]:       1243 :   while ((c = getopt( argc, argv, "bc:d:fh?i:l:no:qr:s:u:v" )) != -1) {
      73 [ +  + ][ +  - ]:        984 :     switch (c) {
         [ +  + ][ +  - ]
         [ -  - ][ +  + ]
                    [ + ]
      74                 :          2 :       case '?':
      75                 :            :       case 'h':
      76                 :            :       default:
      77         [ +  - ]:          2 :         help( argv );
      78         [ -  - ]:          2 :         CkExit();
      79                 :          0 :         break;
      80                 :        108 :       case 'b':
      81                 :        108 :         get< tag::benchmark >() = true;
      82                 :        108 :         break;
      83                 :        259 :       case 'c':
      84         [ +  - ]:        259 :         get< tag::control >() = optarg;
      85                 :        259 :         break;
      86                 :          0 :       case 'd':
      87         [ -  - ]:          0 :         get< tag::diag >() = optarg;
      88                 :          0 :         break;
      89                 :         11 :       case 'f':
      90                 :         11 :         get< tag::feedback >() = true;
      91                 :         11 :         break;
      92                 :        259 :       case 'i':
      93         [ +  - ]:        259 :         get< tag::input >() = optarg;
      94                 :        259 :         break;
      95                 :         12 :       case 'l':
      96 [ +  - ][ +  - ]:         12 :         get< tag::lbfreq >() = std::stoul( optarg );
      97                 :         12 :         break;
      98                 :          0 :       case 'n':
      99                 :          0 :         get< tag::nonblocking >() = true;
     100                 :          0 :         break;
     101                 :          0 :       case 'o':
     102         [ -  - ]:          0 :         get< tag::output >() = optarg;
     103                 :          0 :         break;
     104                 :          0 :       case 'r':
     105 [ -  - ][ -  - ]:          0 :         get< tag::rsfreq >() = std::stoul( optarg );
     106                 :          0 :         break;
     107                 :        190 :       case 'q':
     108                 :        190 :         get< tag::quiescence >() = true;
     109                 :        190 :         break;
     110                 :        142 :       case 'u':
     111 [ +  - ][ +  - ]:        142 :         get< tag::virt >() = std::stod( optarg );
     112                 :        142 :         break;
     113                 :          1 :       case 'v':
     114         [ +  - ]:          1 :         print << '\n';
     115 [ +  - ][ +  - ]:          1 :         print.version( tk::inciter_executable(), tk::git_commit() );
                 [ +  - ]
     116         [ -  - ]:          1 :         CkExit();
     117                 :          0 :         break;
     118                 :            :     }
     119                 :            :   }
     120                 :            : 
     121         [ -  + ]:        259 :   if (optind != argc) {
     122         [ -  - ]:          0 :     print << "\nA non-option was supplied";
     123         [ -  - ]:          0 :     help( argv );
     124         [ -  - ]:          0 :     CkExit( EXIT_FAILURE );
     125                 :            :   }
     126 [ -  + ][ -  - ]:        259 :   ErrChk( not get< tag::input >().empty(),
         [ -  - ][ -  - ]
     127                 :            :           "Mandatory input mesh file not specified. Use -i <filename>." );
     128 [ -  + ][ -  - ]:        259 :   ErrChk( not get< tag::control >().empty(),
         [ -  - ][ -  - ]
     129                 :            :           "Mandatory control file not specified. Use -c <filename>." );
     130                 :            : }
     131                 :            : 
     132                 :            : void
     133                 :          2 : Config::help( char** argv )
     134                 :            : // *****************************************************************************
     135                 :            : // Echo help on command line arguments
     136                 :            : //! \param[in] argv Arguments to executable
     137                 :            : // *****************************************************************************
     138                 :            : {
     139                 :          2 :   tk::Print() <<
     140                 :            :     "\nUsage: " << argv[0] << " -i <in.exo> -c <config.q> [OPTION]...\n"
     141                 :            :     "\n"
     142                 :            :     "  -h, -?        Print out this help\n"
     143                 :            :     "  -b            Benchmark mode, "
     144                 :          2 :                      "default: " << get< tag::benchmark >() << "\n" <<
     145                 :            :     "  -c <config.q> Specify control file\n"
     146                 :            :     "  -d <diag>     Specify diagnostics file, "
     147                 :          2 :                      "default: " << get< tag::diag >() << "\n" <<
     148                 :            :     "  -f            Extra feedback, "
     149                 :          2 :                      "default: " << get< tag::feedback >() << "\n" <<
     150                 :            :     "  -i <in.exo>   Specify input mesh file\n"
     151                 :            :     "  -l <int>      Load balancing frequency, "
     152                 :          2 :                      "default: " << get< tag::lbfreq >() << "\n" <<
     153                 :            :     "  -n            Non-blocking migration, "
     154                 :          2 :                      "default: " << get< tag::nonblocking >() << "\n" <<
     155                 :            :     "  -o <outfile>  Base-filename for field output, "
     156                 :          2 :                      "default: " << get< tag::output >() << "\n" <<
     157                 :            :     "  -r <int>      Checkpoint frequency, "
     158                 :          2 :                      "default: " << get< tag::rsfreq >() << "\n" <<
     159                 :            :     "  -q            Enable quiescence detection, "
     160                 :          2 :                      "default: " << get< tag::quiescence >() << "\n" <<
     161                 :            :     "  -u <real>     Virtualization, "
     162                 :          2 :                      "default: " << get< tag::virt >() << "\n" <<
     163                 :            :     "  -v            Print revision information\n"
     164 [ +  - ][ +  - ]:          2 :     "\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     165                 :          2 : }
     166                 :            : 
     167                 :            : [[maybe_unused]] static void
     168                 :          0 : dumpstack( lua_State *L )
     169                 :            : // *****************************************************************************
     170                 :            : // Dump lua stack for debugging
     171                 :            : //! \param[in] L Lua state
     172                 :            : // *****************************************************************************
     173                 :            : {
     174                 :          0 :   int top=lua_gettop(L);
     175         [ -  - ]:          0 :   for (int i=1; i <= top; i++) {
     176                 :          0 :     printf("%d\t%s\t", i, luaL_typename(L,i));
     177 [ -  - ][ -  - ]:          0 :     switch (lua_type(L, i)) {
                    [ - ]
     178                 :          0 :       case LUA_TNUMBER:
     179                 :          0 :         printf("%g\n",lua_tonumber(L,i));
     180                 :          0 :         break;
     181                 :          0 :       case LUA_TSTRING:
     182                 :          0 :         printf("%s\n",lua_tostring(L,i));
     183                 :          0 :         break;
     184                 :          0 :       case LUA_TBOOLEAN:
     185         [ -  - ]:          0 :         printf("%s\n", (lua_toboolean(L, i) ? "true" : "false"));
     186                 :          0 :         break;
     187                 :          0 :       case LUA_TNIL:
     188                 :          0 :         printf("%s\n", "nil");
     189                 :          0 :         break;
     190                 :          0 :       default:
     191                 :          0 :         printf("%p\n",lua_topointer(L,i));
     192                 :          0 :         break;
     193                 :            :     }
     194                 :            :   }
     195                 :          0 : }
     196                 :            : 
     197                 :            : static int64_t
     198                 :        777 : sigint( lua_State* L,
     199                 :            :         const char* name,
     200                 :            :         int64_t def = largeint,
     201                 :            :         bool global = false )
     202                 :            : // *****************************************************************************
     203                 :            : // Parse integer from global scope
     204                 :            : //! \param[in] L Lua state
     205                 :            : //! \param[in] name Label to parse
     206                 :            : //! \param[in] def Default if does not exist
     207                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     208                 :            : // *****************************************************************************
     209                 :            : {
     210                 :        777 :   int64_t a = def;
     211                 :            : 
     212         [ -  + ]:        777 :   if (global) {
     213                 :          0 :     lua_getglobal( L, name );
     214                 :            :   } else {
     215         [ +  + ]:        777 :     if (lua_istable( L, -1 )) {
     216                 :        165 :       lua_getfield( L, -1, name );
     217                 :            :     } else {
     218                 :        612 :       return a;
     219                 :            :     }
     220                 :            :   }
     221                 :            : 
     222         [ +  + ]:        165 :   if (!lua_isnil( L, -1 )) {
     223 [ -  + ][ -  - ]:         79 :     ErrChk( lua_isinteger( L, -1 ), std::string(name) + " must be an integer" );
         [ -  - ][ -  - ]
                 [ -  - ]
     224                 :         79 :     a = lua_tointeger( L, -1 );
     225                 :            :   }
     226                 :            : 
     227                 :        165 :   lua_pop( L, 1 );
     228                 :            : 
     229                 :        165 :   return a;
     230                 :            : }
     231                 :            : 
     232                 :            : static uint64_t
     233                 :       4144 : unsigint( lua_State* L,
     234                 :            :           const char* name,
     235                 :            :           uint64_t def = largeuint,
     236                 :            :           bool global = false )
     237                 :            : // *****************************************************************************
     238                 :            : // Parse unsigned integer from global scope
     239                 :            : //! \param[in] L Lua state
     240                 :            : //! \param[in] name Label to parse
     241                 :            : //! \param[in] def Default if does not exist
     242                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     243                 :            : // *****************************************************************************
     244                 :            : {
     245                 :       4144 :   uint64_t a = def;
     246                 :            : 
     247         [ +  + ]:       4144 :   if (global) {
     248                 :       1036 :     lua_getglobal( L, name );
     249                 :            :   } else {
     250         [ +  + ]:       3108 :     if (lua_istable( L, -1 )) {
     251                 :        470 :       lua_getfield( L, -1, name );
     252                 :            :     } else {
     253                 :       2638 :       return a;
     254                 :            :     }
     255                 :            :   }
     256                 :            : 
     257         [ +  + ]:       1506 :   if (!lua_isnil( L, -1 )) {
     258 [ -  + ][ -  - ]:        909 :     ErrChk( lua_isinteger( L, -1 ), std::string(name) + " must be an integer" );
         [ -  - ][ -  - ]
                 [ -  - ]
     259                 :        909 :     a = static_cast< uint64_t >( lua_tointeger( L, -1 ) );
     260                 :            :   }
     261                 :            : 
     262                 :       1506 :   lua_pop( L, 1 );
     263                 :            : 
     264                 :       1506 :   return a;
     265                 :            : }
     266                 :            : 
     267                 :            : static bool
     268                 :       1813 : boolean( lua_State* L, const char* name, bool def = false, bool global = false )
     269                 :            : // *****************************************************************************
     270                 :            : // Parse boolean from global scope or table
     271                 :            : //! \param[in] L Lua state
     272                 :            : //! \param[in] name Label to parse
     273                 :            : //! \param[in] def Default if does not exist
     274                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     275                 :            : // *****************************************************************************
     276                 :            : {
     277                 :       1813 :   bool a = def;
     278                 :            : 
     279         [ +  + ]:       1813 :   if (global) {
     280                 :       1295 :     lua_getglobal( L, name );
     281                 :            :   } else {
     282         [ +  + ]:        518 :     if (lua_istable( L, -1 )) {
     283                 :         24 :       lua_getfield( L, -1, name );
     284                 :            :     } else {
     285                 :        494 :       return a;
     286                 :            :     }
     287                 :            :   }
     288                 :            : 
     289         [ +  + ]:       1319 :   if (!lua_isnil( L, -1 )) {
     290 [ -  + ][ -  - ]:         95 :     ErrChk( lua_isboolean( L, -1 ), std::string(name) + " must be a boolean" );
         [ -  - ][ -  - ]
                 [ -  - ]
     291                 :         95 :     a = lua_toboolean( L, -1 );
     292                 :            :   }
     293                 :            : 
     294                 :       1319 :   lua_pop( L, 1 );
     295                 :            : 
     296                 :       1319 :   return a;
     297                 :            : }
     298                 :            : 
     299                 :            : static double
     300                 :       9894 : real( lua_State* L,
     301                 :            :       const char* name,
     302                 :            :       double def = largereal,
     303                 :            :       bool global = false )
     304                 :            : // *****************************************************************************
     305                 :            : // Parse real from global scope or table
     306                 :            : //! \param[in] L Lua state
     307                 :            : //! \param[in] name Label to parse
     308                 :            : //! \param[in] def Default if does not exist
     309                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     310                 :            : // *****************************************************************************
     311                 :            : {
     312                 :       9894 :   double a = def;
     313                 :            : 
     314         [ +  + ]:       9894 :   if (global) {
     315                 :       3367 :     lua_getglobal( L, name );
     316                 :            :   } else {
     317         [ +  + ]:       6527 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, name ); else return a;
     318                 :            :   }
     319                 :            : 
     320         [ +  + ]:       6052 :   if (!lua_isnil( L, -1 )) {
     321 [ -  + ][ -  - ]:       1056 :     ErrChk( lua_isnumber( L, -1 ), std::string(name) + " must be a number" );
         [ -  - ][ -  - ]
                 [ -  - ]
     322                 :       1056 :     a = lua_tonumber( L, -1 );
     323                 :            :   }
     324                 :            : 
     325                 :       6052 :   lua_pop( L, 1 );
     326                 :            : 
     327                 :       6052 :   return a;
     328                 :            : }
     329                 :            : 
     330                 :            : static std::string
     331                 :       2590 : string( lua_State* L,
     332                 :            :         const char* name,
     333                 :            :         const char* def = "default",
     334                 :            :         bool global = false )
     335                 :            : // *****************************************************************************
     336                 :            : // Parse string from global scope or table
     337                 :            : //! \param[in] L Lua state
     338                 :            : //! \param[in] name Label to parse
     339                 :            : //! \param[in] def Default if does not exist
     340                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     341                 :            : // *****************************************************************************
     342                 :            : {
     343         [ +  - ]:       2590 :   std::string a = def;
     344                 :            : 
     345         [ +  + ]:       2590 :   if (global) {
     346         [ +  - ]:        777 :     lua_getglobal( L, name );
     347                 :            :   } else {
     348 [ +  - ][ +  + ]:       1813 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, name ); else return a;
                 [ +  - ]
     349                 :            :   }
     350                 :            : 
     351 [ +  - ][ +  + ]:       1100 :   if (!lua_isnil( L, -1 )) {
     352 [ +  - ][ -  + ]:        689 :     ErrChk( lua_isstring( L, -1 ), std::string(name) + " must be a string" );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     353 [ +  - ][ +  - ]:        689 :     a = lua_tostring( L, -1 );
     354                 :            :   }
     355                 :            : 
     356         [ +  - ]:       1100 :   lua_pop( L, 1 );
     357                 :            : 
     358                 :       1100 :   return a;
     359                 :          0 : }
     360                 :            : 
     361                 :            : static std::vector< double >
     362                 :       1044 : vector( lua_State* L,
     363                 :            :         const char* name,
     364                 :            :         double def = largereal,
     365                 :            :         bool global = false )
     366                 :            : // *****************************************************************************
     367                 :            : // Parse vector table from global scope or table
     368                 :            : //! \param[in] L Lua state
     369                 :            : //! \param[in] name Label to parse
     370                 :            : //! \param[in] def Default if does not exist
     371                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     372                 :            : //! \return Vector components parsed
     373                 :            : // *****************************************************************************
     374                 :            : {
     375         [ +  - ]:       1044 :   std::vector< double > v( 3, def );
     376                 :            : 
     377         [ +  + ]:       1044 :   if (global) {
     378         [ +  - ]:        259 :     lua_getglobal( L, name );
     379                 :            :   } else {
     380 [ +  - ][ +  + ]:        785 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, name ); else return v;
                 [ +  - ]
     381                 :            :   }
     382                 :            : 
     383 [ +  - ][ +  + ]:        539 :   if (!lua_isnil( L, -1 )) {
     384 [ +  - ][ -  + ]:        202 :     ErrChk( lua_istable( L, -1 ), "vector must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     385         [ +  - ]:        202 :     int64_t n = luaL_len( L, -1 );
     386         [ +  + ]:        808 :     for (int64_t i=1; i<=n; ++i) {
     387         [ +  - ]:        606 :       lua_geti( L, -1, i );
     388 [ +  - ][ -  + ]:        606 :       ErrChk( lua_isnumber( L, -1 ), "vector components must be numbers" );
         [ -  - ][ -  - ]
                 [ -  - ]
     389         [ +  - ]:        606 :       v[ static_cast<std::size_t>(i-1) ] = lua_tonumber( L, -1 );
     390         [ +  - ]:        606 :       lua_pop( L, 1 );
     391                 :            :     }
     392                 :            :   }
     393                 :            : 
     394         [ +  - ]:        539 :   lua_pop( L, 1 );
     395                 :            : 
     396                 :        539 :   return v;
     397                 :          0 : }
     398                 :            : 
     399                 :            : static std::vector< std::string >
     400                 :        777 : stringlist( lua_State* L, const char* name, bool global = false )
     401                 :            : // *****************************************************************************
     402                 :            : // Parse string list table from global scope or table
     403                 :            : //! \param[in] L Lua state
     404                 :            : //! \param[in] name Label to parse
     405                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     406                 :            : //! \return List of strings parsed
     407                 :            : // *****************************************************************************
     408                 :            : {
     409                 :        777 :   std::vector< std::string > v;
     410                 :            : 
     411         [ +  + ]:        777 :   if (global) {
     412         [ +  - ]:        259 :     lua_getglobal( L, name );
     413                 :            :   } else {
     414 [ +  - ][ +  + ]:        518 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, name ); else return v;
                 [ +  - ]
     415                 :            :   }
     416                 :            : 
     417 [ +  - ][ +  + ]:        278 :   if (!lua_isnil( L, -1 )) {
     418 [ +  - ][ -  + ]:         21 :     ErrChk( lua_istable( L, -1 ), "stringlist must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     419         [ +  - ]:         21 :     int64_t n = luaL_len( L, -1 );
     420         [ +  + ]:         74 :     for (int64_t i=1; i<=n; ++i) {
     421         [ +  - ]:         53 :       lua_geti( L, -1, i );
     422 [ +  - ][ -  + ]:         53 :       ErrChk( lua_isstring( L, -1 ), "stringlist components must be strings" );
         [ -  - ][ -  - ]
                 [ -  - ]
     423 [ +  - ][ +  - ]:         53 :       v.push_back( lua_tostring( L, -1 ) );
                 [ +  - ]
     424         [ +  - ]:         53 :       lua_pop( L, 1 );
     425                 :            :     }
     426                 :            :   }
     427                 :            : 
     428         [ +  - ]:        278 :   lua_pop( L, 1 );
     429                 :            : 
     430                 :        278 :   return v;
     431                 :          0 : }
     432                 :            : 
     433                 :            : static std::vector< uint64_t >
     434                 :        777 : unsigints( lua_State* L, const char* name, bool global = false )
     435                 :            : // *****************************************************************************
     436                 :            : // Parse table of unsigned integers from global scope or table
     437                 :            : //! \param[in] L Lua state
     438                 :            : //! \param[in] name Label to parse
     439                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     440                 :            : //! \return List of unsigned integers parsed
     441                 :            : // *****************************************************************************
     442                 :            : {
     443                 :        777 :   std::vector< uint64_t > v;
     444                 :            : 
     445         [ +  + ]:        777 :   if (global) {
     446         [ +  - ]:        259 :     lua_getglobal( L, name );
     447                 :            :   } else {
     448 [ +  - ][ +  + ]:        518 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, name ); else return v;
                 [ +  - ]
     449                 :            :   }
     450                 :            : 
     451 [ +  - ][ +  + ]:        272 :   if (!lua_isnil( L, -1 )) {
     452 [ +  - ][ -  + ]:         23 :     ErrChk( lua_istable( L, -1 ), "unsigints must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     453         [ +  - ]:         23 :     int64_t n = luaL_len( L, -1 );
     454         [ +  + ]:         86 :     for (int64_t i=1; i<=n; ++i) {
     455         [ +  - ]:         63 :       lua_geti( L, -1, i );
     456 [ +  - ][ -  + ]:         63 :       ErrChk( lua_isinteger( L, -1 ), "unsigints components must be numbers" );
         [ -  - ][ -  - ]
                 [ -  - ]
     457 [ +  - ][ +  - ]:         63 :       v.push_back( static_cast< uint64_t >( lua_tointeger( L, -1 ) ) );
     458         [ +  - ]:         63 :       lua_pop( L, 1 );
     459                 :            :     }
     460                 :            :   }
     461                 :            : 
     462         [ +  - ]:        272 :   lua_pop( L, 1 );
     463                 :            : 
     464                 :        272 :   return v;
     465                 :          0 : }
     466                 :            : 
     467                 :            : static std::vector< int >
     468                 :        974 : sideset( lua_State* L, bool global = false )
     469                 :            : // *****************************************************************************
     470                 :            : // Parse sideset table from global scope or table
     471                 :            : //! \param[in] L Lua state
     472                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     473                 :            : //! \return Vector of side set ids parsed
     474                 :            : // *****************************************************************************
     475                 :            : {
     476                 :        974 :   std::vector< int > v;
     477                 :            : 
     478         [ -  + ]:        974 :   if (global) {
     479         [ -  - ]:          0 :     lua_getglobal( L, "sideset" );
     480                 :            :   } else {
     481 [ +  - ][ +  + ]:        974 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, "sideset" ); else return v;
                 [ +  - ]
     482                 :            :   }
     483                 :            : 
     484 [ +  - ][ +  + ]:        366 :   if (!lua_isnil( L, -1 )) {
     485 [ +  - ][ -  + ]:        227 :     ErrChk( lua_istable( L, -1 ), "sideset must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     486         [ +  - ]:        227 :     int64_t n = luaL_len( L, -1 );
     487         [ +  + ]:        646 :     for (int64_t i=1; i<=n; ++i) {
     488         [ +  - ]:        419 :       lua_geti( L, -1, i );
     489 [ +  - ][ -  + ]:        419 :       ErrChk( lua_isinteger( L, -1 ), "sideset id must be a number" );
         [ -  - ][ -  - ]
                 [ -  - ]
     490         [ +  - ]:        419 :       int a = static_cast< int >( lua_tointeger( L, -1 ) );
     491 [ -  + ][ -  - ]:        419 :       ErrChk( a >= 0, "sideset id must be non-negative" );
         [ -  - ][ -  - ]
     492         [ +  - ]:        419 :       v.push_back( a );
     493         [ +  - ]:        419 :       lua_pop( L, 1 );
     494                 :            :     }
     495                 :            :   }
     496                 :            : 
     497         [ +  - ]:        366 :   lua_pop( L, 1 );
     498                 :            : 
     499                 :        366 :   return v;
     500                 :          0 : }
     501                 :            : 
     502                 :            : static std::vector< std::vector< double > >
     503                 :        777 : range( lua_State* L, bool global = false )
     504                 :            : // *****************************************************************************
     505                 :            : // Parse range(s) table from global scope or table
     506                 :            : //! \param[in] L Lua state
     507                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     508                 :            : //! \return Vector of vectors of range(s)
     509                 :            : // *****************************************************************************
     510                 :            : {
     511                 :        777 :   std::vector< std::vector< double > > v;
     512                 :            : 
     513         [ -  + ]:        777 :   if (global) {
     514         [ -  - ]:          0 :     lua_getglobal( L, "range" );
     515                 :            :   } else {
     516 [ +  - ][ +  + ]:        777 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, "range" ); else return v;
                 [ +  - ]
     517                 :            :   }
     518                 :            : 
     519 [ +  - ][ +  + ]:        173 :   if (!lua_isnil( L, -1 )) {
     520 [ +  - ][ -  + ]:          6 :     ErrChk( lua_istable( L, -1 ), "range must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     521         [ +  - ]:          6 :     int64_t n = luaL_len( L, -1 );
     522         [ +  - ]:          6 :     v.emplace_back();
     523         [ +  + ]:         23 :     for (int64_t i=1; i<=n; ++i) {
     524         [ +  - ]:         17 :       lua_geti( L, -1, i );
     525 [ +  - ][ +  + ]:         17 :       if (lua_isnumber( L, -1 )) {
     526 [ +  - ][ +  - ]:         15 :         v.back().push_back( lua_tonumber( L, -1 ) );
     527                 :            :       } else {
     528 [ +  - ][ -  + ]:          2 :         ErrChk( lua_istable( L, -1 ), "non-number range must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     529 [ +  + ][ +  - ]:          2 :         if (i>1) v.emplace_back();
     530         [ +  - ]:          2 :         int64_t m = luaL_len( L, -1 );
     531         [ +  + ]:          8 :         for (int64_t j=1; j<=m; ++j) {
     532         [ +  - ]:          6 :           lua_geti( L, -1, j );
     533 [ +  - ][ -  + ]:          6 :           ErrChk( lua_isnumber( L, -1 ), "vector components must be numbers" );
         [ -  - ][ -  - ]
                 [ -  - ]
     534 [ +  - ][ +  - ]:          6 :           v.back().push_back( lua_tonumber( L, -1 ) );
     535         [ +  - ]:          6 :           lua_pop( L, 1 );
     536                 :            :         }
     537                 :            :       }
     538         [ +  - ]:         17 :       lua_pop( L, 1 );
     539                 :            :     }
     540                 :            :   }
     541                 :            : 
     542         [ +  - ]:        173 :   lua_pop( L, 1 );
     543                 :            : 
     544                 :        173 :   return v;
     545                 :          0 : }
     546                 :            : 
     547                 :            : static void
     548                 :        259 : fieldout( lua_State* L, Config& cfg )
     549                 :            : // *****************************************************************************
     550                 :            : // Parse fieldout table
     551                 :            : //! \param[in,out] L Lua state
     552                 :            : //! \param[in,out] cfg Config state
     553                 :            : // *****************************************************************************
     554                 :            : {
     555                 :        259 :   lua_getglobal( L, "fieldout" );
     556                 :            : 
     557                 :        259 :   cfg.get< tag::fieldout_iter >() = unsigint( L, "iter" );
     558                 :        259 :   cfg.get< tag::fieldout_time >() = real( L, "time" );
     559         [ +  - ]:        259 :   cfg.get< tag::fieldout_range >() = range( L );
     560         [ +  - ]:        259 :   cfg.get< tag::fieldout >() = sideset( L );
     561                 :            : 
     562                 :        259 :   lua_pop( L, 1 );
     563                 :        259 : }
     564                 :            : 
     565                 :            : static void
     566                 :        259 : histout( lua_State* L, Config& cfg )
     567                 :            : // *****************************************************************************
     568                 :            : // Parse histout table
     569                 :            : //! \param[in,out] L Lua state
     570                 :            : //! \param[in,out] cfg Config state
     571                 :            : // *****************************************************************************
     572                 :            : {
     573                 :        259 :   lua_getglobal( L, "histout" );
     574                 :            : 
     575                 :        259 :   cfg.get< tag::histout_iter >() = unsigint( L, "iter" );
     576                 :        259 :   cfg.get< tag::histout_time >() = real( L, "time" );
     577         [ +  - ]:        259 :   cfg.get< tag::histout_range >() = range( L );
     578                 :        259 :   cfg.get< tag::histout_precision >() = sigint( L, "precision", 8 );
     579         [ +  - ]:        259 :   cfg.get< tag::histout_format >() = string( L, "format" );
     580                 :            : 
     581         [ +  + ]:        259 :   if (lua_istable( L, -1 )) {
     582                 :         15 :     lua_getfield( L, -1, "points" );
     583         [ +  - ]:         15 :     if (!lua_isnil( L, -1 )) {
     584 [ -  + ][ -  - ]:         15 :       ErrChk( lua_istable( L, -1 ), "histout points must be a table" );
         [ -  - ][ -  - ]
     585                 :         15 :       auto& r = cfg.get< tag::histout >();
     586                 :         15 :       int64_t n = luaL_len( L, -1 );
     587         [ +  + ]:         90 :       for (int64_t i=1; i<=n; ++i) {
     588                 :         75 :         lua_geti( L, -1, i );
     589 [ -  + ][ -  - ]:         75 :         ErrChk( lua_istable( L, -1 ), "histout point must be a table" );
         [ -  - ][ -  - ]
     590                 :         75 :         r.emplace_back();
     591                 :         75 :         auto& p = r.back();
     592                 :         75 :         int64_t m = luaL_len( L, -1 );
     593         [ +  + ]:        300 :         for (int64_t j=1; j<=m; ++j) {
     594                 :        225 :           lua_geti( L, -1, j );
     595 [ -  + ][ -  - ]:        225 :           ErrChk( lua_isnumber( L, -1 ), "point coordinate must be a number" );
         [ -  - ][ -  - ]
     596 [ +  - ][ +  - ]:        225 :           p.push_back( lua_tonumber( L, -1 ) );
     597                 :        225 :           lua_pop( L, 1 );
     598                 :            :         }
     599                 :         75 :         lua_pop( L, 1 );
     600                 :            :       }
     601                 :            :     }
     602                 :         15 :     lua_pop( L, 1 );
     603                 :            :   }
     604                 :            : 
     605                 :        259 :   lua_pop( L, 1 );
     606                 :        259 : }
     607                 :            : 
     608                 :            : static void
     609                 :        259 : integout( lua_State* L, Config& cfg )
     610                 :            : // *****************************************************************************
     611                 :            : // Parse integout table
     612                 :            : //! \param[in,out] L Lua state
     613                 :            : //! \param[in,out] cfg Config state
     614                 :            : // *****************************************************************************
     615                 :            : {
     616                 :        259 :   lua_getglobal( L, "integout" );
     617                 :            : 
     618                 :        259 :   cfg.get< tag::integout_iter >() = unsigint( L, "iter" );
     619                 :        259 :   cfg.get< tag::integout_time >() = real( L, "time" );
     620         [ +  - ]:        259 :   cfg.get< tag::integout_range >() = range( L );
     621                 :        259 :   cfg.get< tag::integout_precision >() = sigint( L, "precision", 8 );
     622         [ +  - ]:        259 :   cfg.get< tag::integout_format >() = string( L, "format" );
     623         [ +  - ]:        259 :   cfg.get< tag::integout >() = sideset( L );
     624         [ +  - ]:        259 :   cfg.get< tag::integout_integrals >() = stringlist( L, "integrals" );
     625                 :            : 
     626                 :        259 :   lua_pop( L, 1 );
     627                 :        259 : }
     628                 :            : 
     629                 :            : static void
     630                 :        259 : diag( lua_State* L, Config& cfg )
     631                 :            : // *****************************************************************************
     632                 :            : // Parse diag table
     633                 :            : //! \param[in,out] L Lua state
     634                 :            : //! \param[in,out] cfg Config state
     635                 :            : // *****************************************************************************
     636                 :            : {
     637                 :        259 :   lua_getglobal( L, "diag" );
     638                 :            : 
     639                 :        259 :   cfg.get< tag::diag_iter >() = unsigint( L, "iter", 1 );
     640                 :        259 :   cfg.get< tag::diag_precision >() = sigint( L, "precision", 8 );
     641         [ +  - ]:        259 :   cfg.get< tag::diag_format >() = string( L, "format" );
     642                 :            : 
     643                 :        259 :   lua_pop( L, 1 );
     644                 :        259 : }
     645                 :            : 
     646                 :            : static void
     647                 :        518 : bc_dir( lua_State* L,
     648                 :            :         std::vector< std::vector< int > >& mask,
     649                 :            :         bool global = false )
     650                 :            : // *****************************************************************************
     651                 :            : // Parse bc_dir table
     652                 :            : //! \param[in,out] L Lua state
     653                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     654                 :            : //! \param[in,out] mask Config state to store Dirichlet BC setids and mask
     655                 :            : // *****************************************************************************
     656                 :            : {
     657         [ +  + ]:        518 :   if (global) {
     658                 :        259 :     lua_getglobal( L, "bc_dir" );
     659                 :            :   } else {
     660         [ +  + ]:        259 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, "bc_dir" ); else return;
     661                 :            :   }
     662                 :            : 
     663         [ +  + ]:        298 :   if (!lua_isnil( L, -1 )) {
     664 [ -  + ][ -  - ]:        142 :     ErrChk( lua_istable( L, -1 ), "bc_dir must be a table" );
         [ -  - ][ -  - ]
     665                 :        142 :     int64_t n = luaL_len( L, -1 );
     666         [ +  + ]:        660 :     for (int64_t i=1; i<=n; ++i) {
     667                 :        518 :       lua_geti( L, -1, i );
     668 [ -  + ][ -  - ]:        518 :       ErrChk( lua_istable( L, -1 ), "bc_dir table entry must be a table" );
         [ -  - ][ -  - ]
     669                 :        518 :       mask.emplace_back();
     670                 :        518 :       auto& b = mask.back();
     671                 :        518 :       int64_t m = luaL_len( L, -1 );
     672         [ +  + ]:       3340 :       for (int64_t j=1; j<=m; ++j) {
     673                 :       2822 :         lua_geti( L, -1, j );
     674 [ -  + ][ -  - ]:       2822 :         ErrChk( lua_isinteger( L, -1 ), "bc_dir entry must be an integer" );
         [ -  - ][ -  - ]
     675 [ +  - ][ +  - ]:       2822 :         b.push_back( static_cast< int >( lua_tointeger( L, -1 ) ) );
     676                 :       2822 :         lua_pop( L, 1 );
     677                 :            :       }
     678                 :        518 :       lua_pop( L, 1 );
     679                 :            :     }
     680                 :            :   }
     681                 :            : 
     682                 :        298 :   lua_pop( L, 1 );
     683                 :            : }
     684                 :            : 
     685                 :            : static void
     686                 :        518 : bc_dirval( lua_State* L,
     687                 :            :            std::vector< std::vector< double > >& val,
     688                 :            :            bool global = false )
     689                 :            : // *****************************************************************************
     690                 :            : // Parse bc_dirval table
     691                 :            : //! \param[in,out] L Lua state
     692                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     693                 :            : //! \param[in,out] val Config state to store Dirichlet BC setids and values
     694                 :            : // *****************************************************************************
     695                 :            : {
     696         [ +  + ]:        518 :   if (global) {
     697                 :        259 :     lua_getglobal( L, "bc_dirval" );
     698                 :            :   } else {
     699         [ +  + ]:        259 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, "bc_dirval" ); else return;
     700                 :            :   }
     701                 :            : 
     702         [ +  + ]:        298 :   if (!lua_isnil( L, -1 )) {
     703 [ -  + ][ -  - ]:         27 :     ErrChk( lua_istable( L, -1 ), "bc_dirval must be a table" );
         [ -  - ][ -  - ]
     704                 :         27 :     int64_t n = luaL_len( L, -1 );
     705         [ +  + ]:         70 :     for (int64_t i=1; i<=n; ++i) {
     706                 :         43 :       lua_geti( L, -1, i );
     707 [ -  + ][ -  - ]:         43 :       ErrChk( lua_istable( L, -1 ), "bc_dirval table entry must be a table" );
         [ -  - ][ -  - ]
     708                 :         43 :       val.emplace_back();
     709                 :         43 :       auto& b = val.back();
     710                 :         43 :       int64_t m = luaL_len( L, -1 );
     711         [ +  + ]:        157 :       for (int64_t j=1; j<=m; ++j) {
     712                 :        114 :         lua_geti( L, -1, j );
     713 [ -  + ][ -  - ]:        114 :         ErrChk( lua_isnumber( L, -1 ), "bc_dirval entry must be an real" );
         [ -  - ][ -  - ]
     714 [ +  - ][ +  - ]:        114 :         b.push_back( static_cast< double >( lua_tonumber( L, -1 ) ) );
     715                 :        114 :         lua_pop( L, 1 );
     716                 :            :       }
     717                 :         43 :       lua_pop( L, 1 );
     718                 :            :     }
     719                 :            :   }
     720                 :            : 
     721                 :        298 :   lua_pop( L, 1 );
     722                 :            : }
     723                 :            : 
     724                 :            : static void
     725                 :        518 : bc_sym( lua_State* L, std::vector< int >& s, bool global = false )
     726                 :            : // *****************************************************************************
     727                 :            : // Parse bc_sym table
     728                 :            : //! \param[in,out] L Lua state
     729                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     730                 :            : //! \param[in,out] s Config state
     731                 :            : // *****************************************************************************
     732                 :            : {
     733         [ +  + ]:        518 :   if (global) {
     734                 :        259 :     lua_getglobal( L, "bc_sym" );
     735                 :            :   } else {
     736         [ +  + ]:        259 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, "bc_sym" ); else return;
     737                 :            :   }
     738                 :            : 
     739         [ +  + ]:        298 :   if (!lua_isnil( L, -1 )) {
     740         [ +  - ]:        156 :     s = sideset( L );
     741                 :            :   }
     742                 :            : 
     743                 :        298 :   lua_pop( L, 1 );
     744                 :            : }
     745                 :            : 
     746                 :            : static void
     747                 :        259 : bc_noslip( lua_State* L, std::vector< int >& s, bool global = false )
     748                 :            : // *****************************************************************************
     749                 :            : // Parse bc_noslip table
     750                 :            : //! \param[in,out] L Lua state
     751                 :            : //! \param[in] global True to parse from global scope, false from table on stack
     752                 :            : //! \param[in,out] s Config state
     753                 :            : // *****************************************************************************
     754                 :            : {
     755         [ +  - ]:        259 :   if (global) {
     756                 :        259 :     lua_getglobal( L, "bc_noslip" );
     757                 :            :   } else {
     758         [ -  - ]:          0 :     if (lua_istable( L, -1 )) lua_getfield( L, -1, "bc_noslip" ); else return;
     759                 :            :   }
     760                 :            : 
     761         [ +  + ]:        259 :   if (!lua_isnil( L, -1 )) {
     762         [ +  - ]:         29 :     s = sideset( L );
     763                 :            :   }
     764                 :            : 
     765                 :        259 :   lua_pop( L, 1 );
     766                 :            : }
     767                 :            : 
     768                 :            : static void
     769                 :        259 : bc_far( lua_State* L, Config& cfg )
     770                 :            : // *****************************************************************************
     771                 :            : // Parse bc_far table
     772                 :            : //! \param[in,out] L Lua state
     773                 :            : //! \param[in,out] cfg Config state
     774                 :            : // *****************************************************************************
     775                 :            : {
     776                 :        259 :   lua_getglobal( L, "bc_far" );
     777                 :            : 
     778         [ +  - ]:        259 :   cfg.get< tag::bc_far >() = sideset( L );
     779         [ +  - ]:        259 :   cfg.get< tag::bc_far_velocity >() = vector( L, "velocity" );
     780                 :        259 :   cfg.get< tag::bc_far_density >() = real( L, "density" );
     781                 :        259 :   cfg.get< tag::bc_far_pressure >() = real( L, "pressure" );
     782                 :            : 
     783                 :        259 :   lua_pop( L, 1 );
     784                 :        259 : }
     785                 :            : 
     786                 :            : static void
     787                 :        259 : bc_pre( lua_State* L, Config& cfg )
     788                 :            : // *****************************************************************************
     789                 :            : // Parse bc_pre table
     790                 :            : //! \param[in,out] L Lua state
     791                 :            : //! \param[in,out] cfg Config state
     792                 :            : // *****************************************************************************
     793                 :            : {
     794                 :        259 :   lua_getglobal( L, "bc_pre" );
     795                 :            : 
     796         [ +  + ]:        259 :   if (lua_istable( L, -1 )) {
     797                 :         12 :     auto bc_pre_set = [&]( const char* name ) {
     798                 :         12 :       lua_getfield( L, -1, name );
     799         [ +  - ]:         12 :       if (!lua_isnil( L, -1 )) {
     800 [ -  + ][ -  - ]:         12 :         ErrChk( lua_istable( L, -1 ), "bc_pre must be a table" );
         [ -  - ][ -  - ]
     801 [ +  - ][ +  - ]:         12 :         cfg.get< tag::bc_pre >().push_back( sideset( L ) );
     802 [ +  - ][ +  - ]:         12 :         cfg.get< tag::bc_pre_density >().push_back( real(L,"density") );
     803 [ +  - ][ +  - ]:         12 :         cfg.get< tag::bc_pre_pressure >().push_back( real(L,"pressure") );
     804                 :            :       }
     805                 :         12 :       lua_pop( L, 1 );
     806                 :         12 :     };
     807                 :            : 
     808         [ +  - ]:          6 :     bc_pre_set( "inlet" );
     809         [ +  - ]:          6 :     bc_pre_set( "outlet" );
     810                 :            :   }
     811                 :            : 
     812                 :        259 :   lua_pop( L, 1 );
     813                 :        259 : }
     814                 :            : 
     815                 :            : static void
     816                 :        259 : ic( lua_State* L, Config& cfg )
     817                 :            : // *****************************************************************************
     818                 :            : // Parse ic table
     819                 :            : //! \param[in,out] L Lua state
     820                 :            : //! \param[in,out] cfg Config state
     821                 :            : // *****************************************************************************
     822                 :            : {
     823         [ +  - ]:        259 :   lua_getglobal( L, "ic" );
     824                 :            : 
     825         [ +  - ]:        259 :   cfg.get< tag::ic_velocity >() = vector( L, "velocity" );
     826         [ +  - ]:        259 :   cfg.get< tag::ic_density >() = real( L, "density" );
     827         [ +  - ]:        259 :   cfg.get< tag::ic_pressure >() = real( L, "pressure" );
     828         [ +  - ]:        259 :   cfg.get< tag::ic_energy >() = real( L, "energy" );
     829         [ +  - ]:        259 :   cfg.get< tag::ic_temperature >() = real( L, "temperature" );
     830                 :            : 
     831                 :         18 :   auto box_extent = [&]( const char* axis, auto& v ) {
     832                 :         18 :     lua_getfield( L, -1, axis );
     833         [ +  - ]:         18 :     if (!lua_isnil( L, -1 )) {
     834 [ -  + ][ -  - ]:         18 :       ErrChk( lua_istable( L, -1 ), "ic box extents must be a table" );
         [ -  - ][ -  - ]
     835                 :         18 :       int64_t n = luaL_len( L, -1 );
     836         [ +  + ]:         54 :       for (int64_t i=1; i<=n; ++i) {
     837                 :         36 :         lua_geti( L, -1, i );
     838 [ -  + ][ -  - ]:         36 :         ErrChk( lua_isnumber( L, -1 ), "ic extent must be a number" );
         [ -  - ][ -  - ]
     839 [ +  - ][ +  - ]:         36 :         v.push_back( lua_tonumber( L, -1 ) );
     840                 :         36 :         lua_pop( L, 1 );
     841                 :            :       }
     842                 :            :     }
     843                 :         18 :     lua_pop( L, 1 );
     844                 :         18 :   };
     845                 :            : 
     846 [ +  - ][ +  + ]:        259 :   if (lua_istable( L, -1 )) {
     847         [ +  - ]:        160 :     lua_getfield( L, -1, "boxes" );
     848 [ +  - ][ +  + ]:        160 :     if (!lua_isnil( L, -1 )) {
     849 [ +  - ][ -  + ]:          3 :       ErrChk( lua_istable( L, -1 ), "ic boxes must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     850                 :          3 :       auto& boxes = cfg.get< tag::ic >();
     851         [ +  - ]:          3 :       int64_t n = luaL_len( L, -1 );
     852         [ +  + ]:          9 :       for (int64_t i=1; i<=n; ++i) {
     853         [ +  - ]:          6 :         lua_geti( L, -1, i );
     854 [ +  - ][ -  + ]:          6 :         ErrChk( lua_istable( L, -1 ), "ic box must be a table" );
         [ -  - ][ -  - ]
                 [ -  - ]
     855         [ +  - ]:          6 :         boxes.emplace_back();
     856                 :          6 :         auto& box = boxes.back();
     857         [ +  - ]:          6 :         box_extent( "x", box.get< tag::x >() );
     858         [ +  - ]:          6 :         box_extent( "y", box.get< tag::y >() );
     859         [ +  - ]:          6 :         box_extent( "z", box.get< tag::z >() );
     860         [ +  - ]:          6 :         box.get< tag::ic_velocity >() = vector( L, "velocity" );
     861         [ +  - ]:          6 :         box.get< tag::ic_density >() = real( L, "density" );
     862         [ +  - ]:          6 :         box.get< tag::ic_pressure >() = real( L, "pressure" );
     863         [ +  - ]:          6 :         box.get< tag::ic_energy >() = real( L, "energy" );
     864         [ +  - ]:          6 :         box.get< tag::ic_temperature >() = real( L, "temperature" );
     865         [ +  - ]:          6 :         lua_pop( L, 1 );
     866                 :            :       }
     867                 :            :     }
     868         [ +  - ]:        160 :     lua_pop( L, 1 );
     869                 :            :   }
     870                 :            : 
     871         [ +  - ]:        259 :   lua_pop( L, 1 );
     872                 :        259 : }
     873                 :            : 
     874                 :            : static void
     875                 :        259 : mat( lua_State* L, Config& cfg )
     876                 :            : // *****************************************************************************
     877                 :            : // Parse mat table
     878                 :            : //! \param[in,out] L Lua state
     879                 :            : //! \param[in,out] cfg Config state
     880                 :            : // *****************************************************************************
     881                 :            : {
     882                 :        259 :   lua_getglobal( L, "mat" );
     883                 :            : 
     884                 :        259 :   cfg.get< tag::mat_spec_heat_ratio >() = real( L, "spec_heat_ratio", 1.4 );
     885                 :        259 :   cfg.get< tag::mat_spec_heat_const_vol >() = real( L, "spec_heat_const_vol" );
     886                 :        259 :   cfg.get< tag::mat_spec_gas_const >() = real(L, "spec_gas_const", 287.052874);
     887                 :        259 :   cfg.get< tag::mat_heat_conductivity >() = real( L, "heat_conductivity" );
     888                 :        259 :   cfg.get< tag::mat_dyn_viscosity >() = real( L, "dyn_viscosity", 0.0 );
     889                 :            : 
     890                 :        259 :   lua_pop( L, 1 );
     891                 :        259 : }
     892                 :            : 
     893                 :            : static void
     894                 :        259 : problem( lua_State* L, Config& cfg )
     895                 :            : // *****************************************************************************
     896                 :            : // Parse problem table
     897                 :            : //! \param[in,out] L Lua state
     898                 :            : //! \param[in,out] cfg Config state
     899                 :            : // *****************************************************************************
     900                 :            : {
     901                 :        259 :   lua_getglobal( L, "problem" );
     902                 :            : 
     903         [ +  - ]:        259 :   cfg.get< tag::problem >() = string( L, "name", "userdef" );
     904                 :        259 :   cfg.get< tag::problem_alpha >() = real( L, "alpha" );
     905                 :        259 :   cfg.get< tag::problem_kappa >() = real( L, "kappa" );
     906                 :        259 :   cfg.get< tag::problem_r0 >() = real( L, "r0" );
     907                 :        259 :   cfg.get< tag::problem_p0 >() = real( L, "p0" );
     908                 :        259 :   cfg.get< tag::problem_ce >() = real( L, "ce" );
     909         [ +  - ]:        259 :   cfg.get< tag::problem_beta >() = vector( L, "beta" );
     910                 :            : 
     911         [ +  + ]:        259 :   if (lua_istable( L, -1 )) {
     912                 :        101 :     lua_getfield( L, -1, "src" );
     913         [ +  + ]:        101 :     if (!lua_isnil( L, -1 )) {
     914 [ -  + ][ -  - ]:          2 :       ErrChk( lua_istable( L, -1 ), "problem source must be a table" );
         [ -  - ][ -  - ]
     915                 :          2 :       auto& s = cfg.get< tag::problem_src >();
     916         [ +  - ]:          2 :       s.get< tag::location >() = vector( L, "location" );
     917                 :          2 :       s.get< tag::radius >() = real( L, "radius" );
     918                 :          2 :       s.get< tag::release_time >() = real( L, "release_time" );
     919                 :            :     }
     920                 :        101 :     lua_pop( L, 1 );
     921                 :            :   }
     922                 :            : 
     923                 :        259 :   const auto& solver = cfg.get< tag::solver >();
     924                 :        259 :   const auto& problem = cfg.get< tag::problem >();
     925                 :            : 
     926                 :        259 :   auto& n = cfg.get< tag::problem_ncomp >();
     927                 :        259 :   n = 5;
     928 [ +  + ][ +  + ]:        259 :   if (problem == "slot_cyl" || problem == "point_src") ++n;
                 [ +  + ]
     929                 :            : 
     930         [ +  + ]:        259 :        if (solver == "chocg") n -= 2;
     931         [ +  + ]:        216 :   else if (solver == "lohcg") n -= 1;
     932                 :            : 
     933                 :        259 :   lua_pop( L, 1 );
     934                 :        259 : }
     935                 :            : 
     936                 :            : static void
     937                 :        259 : href( lua_State* L, Config& cfg )
     938                 :            : // *****************************************************************************
     939                 :            : // Parse href table
     940                 :            : //! \param[in,out] L Lua state
     941                 :            : //! \param[in,out] cfg Config state
     942                 :            : // *****************************************************************************
     943                 :            : {
     944                 :        259 :   lua_getglobal( L, "href" );
     945                 :            : 
     946                 :        259 :   cfg.get< tag::href_t0 >() = boolean( L, "t0" );
     947                 :        259 :   cfg.get< tag::href_dt >() = boolean( L, "dt" );
     948                 :        259 :   cfg.get< tag::href_dtfreq >() = unsigint( L, "dtfreq", 5 );
     949         [ +  - ]:        259 :   cfg.get< tag::href_init >() = stringlist( L, "init" );
     950         [ +  - ]:        259 :   cfg.get< tag::href_refvar >() = unsigints( L, "refvar" );
     951         [ +  - ]:        259 :   cfg.get< tag::href_error >() = string( L, "error", "jump" );
     952                 :        259 :   cfg.get< tag::href_maxlevels >() = unsigint( L, "maxlevels", 2 );
     953                 :            : 
     954                 :        259 :   lua_pop( L, 1 );
     955                 :        259 : }
     956                 :            : 
     957                 :            : static void
     958                 :        259 : deactivate( lua_State* L, Config& cfg )
     959                 :            : // *****************************************************************************
     960                 :            : // Parse deactivate table
     961                 :            : //! \param[in,out] L Lua state
     962                 :            : //! \param[in,out] cfg Config state
     963                 :            : // *****************************************************************************
     964                 :            : {
     965                 :        259 :   lua_getglobal( L, "deactivate" );
     966                 :            : 
     967                 :        259 :   cfg.get< tag::deafreq >() = unsigint( L, "freq", 0 );
     968                 :        259 :   cfg.get< tag::deatol >() = real( L, "tol", 1.0e-3 );
     969                 :        259 :   cfg.get< tag::deadif >() = real( L, "dif", 0.0 );
     970         [ +  - ]:        259 :   cfg.get< tag::deasys >() = unsigints( L, "sys" );
     971                 :        259 :   cfg.get< tag::deatime >() = real( L, "time", 0.0 );
     972                 :            : 
     973                 :        259 :   cfg.get< tag::deactivate >() = cfg.get< tag::deafreq >();  // on if freq > 0
     974                 :            : 
     975                 :        259 :   lua_pop( L, 1 );
     976                 :        259 : }
     977                 :            : 
     978                 :            : static void
     979                 :        259 : pressure( lua_State* L, Config& cfg )
     980                 :            : // *****************************************************************************
     981                 :            : // Parse pressure table
     982                 :            : //! \param[in,out] L Lua state
     983                 :            : //! \param[in,out] cfg Config state
     984                 :            : // *****************************************************************************
     985                 :            : {
     986                 :        259 :   lua_getglobal( L, "pressure" );
     987                 :            : 
     988                 :        259 :   cfg.get< tag::pre_iter >() = unsigint( L, "iter", 10 );
     989                 :        259 :   cfg.get< tag::pre_tol >() = real( L, "tol", 1.0e-3 );
     990                 :        259 :   cfg.get< tag::pre_verbose >() = unsigint( L, "verbose", 0 );
     991                 :        259 :   cfg.get< tag::pre_hydrostat >() = unsigint( L, "hydrostat" );
     992         [ +  - ]:        259 :   cfg.get< tag::pre_pc >() = string( L, "pc", "none" );
     993                 :        259 :   bc_dir( L, cfg.get< tag::pre_bc_dir >() );
     994                 :        259 :   bc_dirval( L, cfg.get< tag::pre_bc_dirval >() );
     995                 :        259 :   bc_sym( L, cfg.get< tag::pre_bc_sym >() );
     996                 :            : 
     997                 :        259 :   lua_pop( L, 1 );
     998                 :        259 : }
     999                 :            : 
    1000                 :            : static void
    1001                 :        259 : momentum( lua_State* L, Config& cfg )
    1002                 :            : // *****************************************************************************
    1003                 :            : // Parse momentum table
    1004                 :            : //! \param[in,out] L Lua state
    1005                 :            : //! \param[in,out] cfg Config state
    1006                 :            : // *****************************************************************************
    1007                 :            : {
    1008                 :        259 :   lua_getglobal( L, "momentum" );
    1009                 :            : 
    1010                 :        259 :   cfg.get< tag::mom_iter >() = unsigint( L, "iter", 10 );
    1011                 :        259 :   cfg.get< tag::mom_tol >() = real( L, "tol", 1.0e-3 );
    1012                 :        259 :   cfg.get< tag::mom_verbose >() = unsigint( L, "verbose", 0 );
    1013         [ +  - ]:        259 :   cfg.get< tag::mom_pc >() = string( L, "pc", "none" );
    1014                 :            : 
    1015                 :        259 :   lua_pop( L, 1 );
    1016                 :        259 : }
    1017                 :            : 
    1018                 :            : static void
    1019                 :        259 : lb( lua_State* L, Config& cfg )
    1020                 :            : // *****************************************************************************
    1021                 :            : // Parse lb (load balancing configuration) table
    1022                 :            : //! \param[in,out] L Lua state
    1023                 :            : //! \param[in,out] cfg Config state
    1024                 :            : // *****************************************************************************
    1025                 :            : {
    1026                 :        259 :   lua_getglobal( L, "lb" );
    1027                 :            : 
    1028                 :        259 :   cfg.get< tag::lbtime >() = real( L, "time", 0.0 );
    1029                 :            : 
    1030                 :        259 :   lua_pop( L, 1 );
    1031                 :        259 : }
    1032                 :            : 
    1033                 :            : void
    1034                 :        259 : Config::control()
    1035                 :            : // *****************************************************************************
    1036                 :            : // Parse control file
    1037                 :            : // *****************************************************************************
    1038                 :            : {
    1039                 :        259 :   const auto& controlfile = get< tag::control >();
    1040                 :            : 
    1041                 :        259 :   tk::Print print;
    1042 [ +  - ][ +  - ]:        259 :   print.section( "Control file: " + controlfile );
    1043                 :            : 
    1044         [ +  - ]:        259 :   lua_State* L = luaL_newstate();
    1045         [ +  - ]:        259 :   luaL_openlibs( L );
    1046                 :            : 
    1047                 :        259 :   std::string err;
    1048                 :            : 
    1049 [ +  - ][ +  - ]:        259 :   if (luaL_dofile( L, controlfile.c_str() ) == LUA_OK) {
         [ +  - ][ -  + ]
                 [ +  - ]
    1050                 :            : 
    1051         [ +  - ]:        259 :     get< tag::nstep >() = unsigint( L, "nstep", largeuint, true );
    1052         [ +  - ]:        259 :     get< tag::term >() = real( L, "term", largereal, true );
    1053         [ +  - ]:        259 :     get< tag::ttyi >() = unsigint( L, "ttyi", 1, true );
    1054         [ +  - ]:        259 :     get< tag::cfl >() = real( L, "cfl", 0.0, true );
    1055         [ +  - ]:        259 :     get< tag::rk >() = unsigint( L, "rk", 1, true );
    1056         [ +  - ]:        259 :     get< tag::theta >() = real( L, "theta", 0.0, true );
    1057         [ +  - ]:        259 :     get< tag::dt >() = real( L, "dt", 0.0, true );
    1058         [ +  - ]:        259 :     get< tag::turkel >() = real( L, "turkel", 0.5, true );
    1059         [ +  - ]:        259 :     get< tag::soundspeed >() = real( L, "soundspeed", 1.0, true );
    1060         [ +  - ]:        259 :     get< tag::velinf >() = vector( L, "velinf", 1.0, true );
    1061         [ +  - ]:        259 :     get< tag::t0 >() = real( L, "t0", 0.0, true );
    1062         [ +  - ]:        259 :     get< tag::reorder >() = boolean( L, "reorder", false, true );
    1063         [ +  - ]:        259 :     get< tag::flux >() = string( L, "flux", "rusanov", true );
    1064         [ +  - ]:        259 :     get< tag::steady >() = boolean( L, "steady", false, true );
    1065         [ +  - ]:        259 :     get< tag::residual >() = real( L, "residual", 0.0, true );
    1066         [ +  - ]:        259 :     get< tag::rescomp >() = unsigint( L, "rescomp", 1, true );
    1067         [ +  - ]:        259 :     get< tag::part >() = string( L, "part", "rcb", true );
    1068         [ +  - ]:        259 :     get< tag::zoltan_params >() = stringlist( L, "zoltan_params", true );
    1069         [ +  - ]:        259 :     get< tag::solver >() = string( L, "solver", "riecg", true );
    1070         [ +  - ]:        259 :     get< tag::stab2 >() = boolean( L, "stab2", false, true );
    1071         [ +  - ]:        259 :     get< tag::stab2coef >() = real( L, "stab2coef", 0.2, true );
    1072         [ +  - ]:        259 :     get< tag::fct >() = boolean( L, "fct", true, true );
    1073         [ +  - ]:        259 :     get< tag::fctdif >() = real( L, "fctdif", 1.0, true );
    1074         [ +  - ]:        259 :     get< tag::fctclip >() = boolean( L, "fctclip", false, true );
    1075         [ +  - ]:        259 :     get< tag::fctsys >() = unsigints( L, "fctsys", true );
    1076         [ +  - ]:        259 :     get< tag::fctfreeze >() = real( L, "fctfreeze", -largereal, true );
    1077         [ +  - ]:        259 :     get< tag::freezeflow >() = real( L, "freezeflow", 1.0, true );
    1078         [ +  - ]:        259 :     get< tag::freezetime >() = real( L, "freezetime", 0.0, true );
    1079                 :            : 
    1080         [ +  - ]:        259 :     ic( L, *this );
    1081         [ +  - ]:        259 :     bc_dir( L, get< tag::bc_dir >(), true );
    1082         [ +  - ]:        259 :     bc_dirval( L, get< tag::bc_dirval >(), true );
    1083         [ +  - ]:        259 :     bc_sym( L, get< tag::bc_sym >(), true );
    1084         [ +  - ]:        259 :     bc_noslip( L, get< tag::bc_noslip >(), true );
    1085         [ +  - ]:        259 :     bc_far( L, *this );
    1086         [ +  - ]:        259 :     bc_pre( L, *this );
    1087         [ +  - ]:        259 :     problem( L, *this );
    1088         [ +  - ]:        259 :     mat( L, *this );
    1089         [ +  - ]:        259 :     fieldout( L, *this );
    1090         [ +  - ]:        259 :     histout( L, *this );
    1091         [ +  - ]:        259 :     integout( L, *this );
    1092         [ +  - ]:        259 :     diag( L, *this );
    1093         [ +  - ]:        259 :     href( L, *this );
    1094         [ +  - ]:        259 :     deactivate( L, *this );
    1095         [ +  - ]:        259 :     pressure( L, *this );
    1096         [ +  - ]:        259 :     momentum( L, *this );
    1097         [ +  - ]:        259 :     lb( L, *this );
    1098                 :            : 
    1099 [ +  - ][ +  - ]:        259 :     print << "Solver: " << get< tag::solver >() << '\n';
                 [ +  - ]
    1100                 :            : 
    1101                 :            :   } else {
    1102 [ -  - ][ -  - ]:          0 :     err = lua_tostring( L, -1 );
    1103                 :            :   }
    1104                 :            : 
    1105         [ +  - ]:        259 :   lua_close( L );
    1106                 :            : 
    1107 [ -  + ][ -  - ]:        259 :   ErrChk( err.empty(), "Lua error during control file parsing: " + err );
         [ -  - ][ -  - ]
    1108                 :            : 
    1109                 :            :   // Output command line object to file
    1110 [ +  - ][ +  - ]:        259 :   auto logfilename = tk::inciter_executable() + "_control.log";
    1111         [ +  - ]:        259 :   tk::Writer log( logfilename );
    1112         [ +  - ]:        259 :   tk::print( log.stream(), *this );
    1113 [ +  - ][ +  - ]:        259 :   print << "Control data saved in " << logfilename << '\n';
                 [ +  - ]
    1114                 :        259 : }
    1115                 :            : 
    1116                 :            : } // ctr::
    1117                 :            : } // inciter::

Generated by: LCOV version 1.16