46#include <boost/algorithm/string.hpp>
47#include <boost/iostreams/copy.hpp>
48#include <boost/iostreams/filter/gzip.hpp>
49#include <boost/iostreams/filtering_streambuf.hpp>
61#include <boost/format.hpp>
62#include <boost/program_options.hpp>
65#define NEKTAR_VERSION "Unknown"
70namespace po = boost::program_options;
71namespace io = boost::iostreams;
129 return solverInfoEnums;
143 return solverInfoMap;
158 return gloSysSolnInfoList;
172 return cmdLineArguments;
202 if (
m_comm->GetSpaceComm()->GetSize() > 1)
209 (
unsigned int)time(
nullptr));
216 const std::vector<std::string> &pFilenames,
219 ASSERTL0(pFilenames.size() > 0,
"No filenames specified.");
244 if (
m_comm->GetSpaceComm()->GetSize() > 1)
251 (
unsigned int)time(
nullptr));
277 if (filenames.size() > 0)
290 exists = fs::exists(optfile.c_str());
291 ASSERTL0(exists,
"A valid .opt file was not specified "
292 "with the --use-opt-file command line option");
304 exists = fs::exists(optfile.c_str());
307 if (exists &&
m_comm->IsParallelInTime())
310 doc.LoadFile(optfile);
311 TiXmlElement *xmlTag = doc.FirstChildElement(
"NEKTAR")
312 ->FirstChildElement(
"COLLECTIONS")
313 ->FirstChildElement(
"TIMELEVEL");
322 if (
m_timeLevel == stoi(xmlTag->Attribute(
"VALUE")))
327 xmlTag = xmlTag->NextSiblingElement();
365 if (std::getenv(
"NEKTAR_DISABLE_BACKUPS") !=
nullptr)
375 cout <<
"Parameters:" << endl;
378 cout <<
"\t" << x.first <<
" = " << x.second << endl;
385 cout <<
"Solver Info:" << endl;
388 cout <<
"\t" << x.first <<
" = " << x.second << endl;
402 if (
m_comm->GetSize() > 1)
404 if (
m_comm->GetRank() == 0)
406 std::ofstream testfile(
"shared-fs-testfile");
407 testfile <<
"" << std::endl;
408 ASSERTL1(!testfile.fail(),
"Test file creation failed");
413 int exists = fs::exists(
"shared-fs-testfile");
421 std::remove(
"shared-fs-testfile");
431 cout <<
"Shared filesystem detected" << endl;
443 po::options_description desc(
"Allowed options");
444 po::options_description dep(
"Deprecated options");
448 (
"force-output,f",
"disables backups files and forces output to be "
449 "written without any checks")
450 (
"help,h",
"print this help message")
451 (
"solverinfo,I", po::value<vector<std::string>>(),
452 "override a SOLVERINFO property")
453 (
"parameter,P", po::value<vector<std::string>>(),
454 "override a parameter")
455 (
"verbose,v",
"be verbose")
456 (
"version,V",
"print version information")
457 (
"no-exp-opt",
"Do not use expansion optimisation for collections")
458 (
"npx", po::value<int>(),
459 "number of procs in X-dir")
460 (
"npy", po::value<int>(),
461 "number of procs in Y-dir")
462 (
"npz", po::value<int>(),
463 "number of procs in Z-dir")
464 (
"nsz", po::value<int>(),
465 "number of slices in Z-dir")
466 (
"npt", po::value<int>(),
467 "number of procs in T-dir (parareal)")
468 (
"part-only", po::value<int>(),
469 "only partition mesh into N partitions.")
470 (
"part-only-overlapping", po::value<int>(),
471 "only partition mesh into N overlapping partitions.")
472 (
"part-info",
"output partition information")
473 (
"write-opt-file",
"write an optimisation file")
474 (
"use-opt-file", po::value<std::string>(),
475 "use an optimisation file");
478#ifdef NEKTAR_USE_CWIPI
479 desc.add_options()(
"cwipi", po::value<std::string>(),
"set CWIPI name");
484 std::string names = cmdIt.first;
485 if (cmdIt.second.shortName !=
"")
487 names +=
"," + cmdIt.second.shortName;
489 if (cmdIt.second.isFlag)
491 desc.add_options()(names.c_str(), cmdIt.second.description.c_str());
495 desc.add_options()(names.c_str(), po::value<std::string>(),
496 cmdIt.second.description.c_str());
502 std::map<std::string, std::string> deprecated = {
503 {
"forceoutput",
"force-output"},
504 {
"writeoptfile",
"write-opt-file"},
505 {
"useoptfile",
"use-opt-file"}};
507 for (
auto &
d : deprecated)
509 std::string
description =
"Deprecated: use --" +
d.second;
510 dep.add_options()(
d.first.c_str(),
description.c_str());
515 po::options_description hidden(
"Hidden options");
517 hidden.add_options()(
"input-file", po::value<vector<string>>(),
521 po::options_description all(
"All options");
522 all.add(desc).add(dep).add(hidden);
525 po::positional_options_description
p;
526 p.add(
"input-file", -1);
529 po::parsed_options parsed = po::command_line_parser(argc, argv)
532 .allow_unregistered()
555 boost::replace_all(branch,
"refs/heads/",
"");
557 cout <<
" (git changeset " <<
sha1.substr(0, 8) <<
", ";
561 cout <<
"detached head";
565 cout <<
"head " << branch;
576 for (
auto &
d : deprecated)
580 std::cerr <<
"Warning: --" <<
d.first <<
" deprecated: use --"
581 <<
d.second << std::endl;
618 for (
auto &x : parsed.options)
622 cout <<
"Warning: Unknown option: " << x.string_key << endl;
633 return std::vector<std::string>();
642 ASSERTL0(!filenames.empty(),
"At least one filename expected.");
644 std::string retval =
"";
647 std::string fname = filenames[0];
650 if (fname.size() > 4 && fname.substr(fname.size() - 4, 4) ==
"_xml")
652 retval = fname.substr(0, fname.find_last_of(
"_"));
655 else if (fname.size() > 4 && fname.substr(fname.size() - 4, 4) ==
".xml")
657 retval = fname.substr(0, fname.find_last_of(
"."));
660 else if (fname.size() > 7 && fname.substr(fname.size() - 7, 7) ==
".xml.gz")
662 retval = fname.substr(0, fname.find_last_of(
"."));
663 retval = retval.substr(0, retval.find_last_of(
"."));
702 std::string vPath = boost::to_upper_copy(pPath);
703 std::vector<std::string> st;
704 boost::split(st, vPath, boost::is_any_of(
"\\/ "));
705 ASSERTL0(st.size() > 0,
"No path given in XML element request.");
707 TiXmlElement *vReturn =
m_xmlDoc->FirstChildElement(st[0].c_str());
709 std::string(
"Cannot find element '") + st[0] + std::string(
"'."));
710 for (
int i = 1; i < st.size(); ++i)
712 vReturn = vReturn->FirstChildElement(st[i].c_str());
713 ASSERTL0(vReturn, std::string(
"Cannot find element '") + st[i] +
724 std::string vPath = boost::to_upper_copy(pPath);
725 std::vector<std::string> st;
726 boost::split(st, vPath, boost::is_any_of(
"\\/ "));
727 ASSERTL0(st.size() > 0,
"No path given in XML element request.");
729 TiXmlElement *vReturn =
m_xmlDoc->FirstChildElement(st[0].c_str());
731 std::string(
"Cannot find element '") + st[0] + std::string(
"'."));
732 for (
int i = 1; i < st.size(); ++i)
734 vReturn = vReturn->FirstChildElement(st[i].c_str());
788 std::string vName = boost::to_upper_copy(pName);
802 std::string vName = boost::to_upper_copy(pName);
806 "Unable to find requested parameter: " + pName);
808 return paramIter->second;
825 std::string vName = boost::to_upper_copy(pName);
828 "Required parameter '" + pName +
"' not specified in session.");
829 NekDouble param = round(paramIter->second);
830 pVar = checked_cast<int>(param);
837 const int &pDefault)
const
839 std::string vName = boost::to_upper_copy(pName);
843 NekDouble param = round(paramIter->second);
844 pVar = checked_cast<int>(param);
856 unsigned int &pVar)
const
858 std::string vName = boost::to_upper_copy(pName);
861 "Required parameter '" + pName +
"' not specified in session.");
862 NekDouble param = round(paramIter->second);
863 pVar = checked_cast<unsigned int>(param);
870 const unsigned int &pDefault)
const
872 std::string vName = boost::to_upper_copy(pName);
876 NekDouble param = round(paramIter->second);
877 pVar = checked_cast<unsigned int>(param);
890 std::string vName = boost::to_upper_copy(pName);
893 "Required parameter '" + pName +
"' not specified in session.");
894 NekDouble param = round(paramIter->second);
895 pVar = checked_cast<int>(param);
902 const size_t &pDefault)
const
904 std::string vName = boost::to_upper_copy(pName);
908 NekDouble param = round(paramIter->second);
909 pVar = checked_cast<int>(param);
923 std::string vName = boost::to_upper_copy(pName);
926 "Required parameter '" + pName +
"' not specified in session.");
927 pVar = paramIter->second;
936 std::string vName = boost::to_upper_copy(pName);
940 pVar = paramIter->second;
953 std::string vName = boost::to_upper_copy(pName);
962 std::string vName = boost::to_upper_copy(pName);
971 std::string vName = boost::to_upper_copy(pName);
980 std::string vName = boost::to_upper_copy(pName);
989 std::string vName = boost::to_upper_copy(pName);
998 const std::string &pProperty)
const
1000 std::string vProperty = boost::to_upper_copy(pProperty);
1004 "Unable to find requested property: " + pProperty);
1006 return iter->second;
1013 const std::string &pValue)
1015 std::string vProperty = boost::to_upper_copy(pProperty);
1019 "Unable to find requested property: " + pProperty);
1021 iter->second = pValue;
1028 const std::string &pDefault)
const
1030 std::string vName = boost::to_upper_copy(pName);
1034 pVar = infoIter->second;
1046 const std::string &pTrueVal,
bool &pVar,
1047 const bool &pDefault)
const
1049 std::string vName = boost::to_upper_copy(pName);
1053 pVar = boost::iequals(infoIter->second, pTrueVal);
1065 const std::string &pTrueVal)
const
1069 std::string vName = boost::to_upper_copy(pName);
1073 return boost::iequals(iter->second, pTrueVal);
1083 const std::string &pProperty)
const
1091 std::string vProperty = boost::to_upper_copy(pProperty);
1093 auto iter1 = iter->second.find(vProperty);
1094 if (iter1 == iter->second.end())
1106 const std::string &pVariable,
const std::string &pProperty)
const
1110 "Failed to find variable in GlobalSysSolnInfoList");
1112 std::string vProperty = boost::to_upper_copy(pProperty);
1113 auto iter1 = iter->second.find(vProperty);
1115 ASSERTL0(iter1 != iter->second.end(),
1116 "Failed to find property: " + vProperty +
1117 " in GlobalSysSolnInfoList");
1119 return iter1->second;
1145 TiXmlElement *xmlGeom =
1146 m_xmlDoc->FirstChildElement(
"NEKTAR")->FirstChildElement(
"GEOMETRY");
1147 ASSERTL1(xmlGeom,
"Failed to find a GEOMETRY section in m_xmlDoc");
1149 TiXmlAttribute *attr = xmlGeom->FirstAttribute();
1152 std::string attrName(attr->Name());
1153 if (attrName ==
"HDF5FILE")
1159 attr = attr->Next();
1164 TiXmlElement *element = xmlGeom->FirstChildElement(
"VERTEX");
1165 string IsCompressed;
1166 element->QueryStringAttribute(
"COMPRESSED", &IsCompressed);
1168 if (IsCompressed.size() > 0)
1170 return "XmlCompressed";
1216 std::string vName = boost::to_upper_copy(pName);
1224 const std::string &pVariable,
1225 const int pDomain)
const
1227 std::string vName = boost::to_upper_copy(pName);
1233 pair<std::string, int> key(pVariable, pDomain);
1234 pair<std::string, int> defkey(
"*", pDomain);
1235 bool varExists = it1->second.find(key) != it1->second.end() ||
1236 it1->second.find(defkey) != it1->second.end();
1246 const std::string &pVariable,
1247 const int pDomain)
const
1249 std::string vName = boost::to_upper_copy(pName);
1253 std::string(
"No such function '") + pName +
1254 std::string(
"' has been defined in the session file."));
1257 pair<std::string, int> key(pVariable, pDomain);
1258 pair<std::string, int> defkey(
"*", pDomain);
1260 auto it2 = it1->second.find(key);
1261 auto it3 = it1->second.find(defkey);
1262 bool specific = it2 != it1->second.end();
1263 bool wildcard = it3 != it1->second.end();
1266 ASSERTL0(specific || wildcard,
"No such variable " + pVariable +
1267 " in domain " + std::to_string(pDomain) +
1268 " defined for function " + pName +
1269 " in session file.");
1278 std::string(
"Function is defined by a file."));
1279 return it2->second.m_expression;
1286 const unsigned int &pVar,
1287 const int pDomain)
const
1297 const std::string &pVariable,
1298 const int pDomain)
const
1300 std::string vName = boost::to_upper_copy(pName);
1304 std::string(
"Function '") + pName + std::string(
"' not found."));
1307 pair<std::string, int> key(pVariable, pDomain);
1308 pair<std::string, int> defkey(
"*", pDomain);
1310 auto it2 = it1->second.find(key);
1311 auto it3 = it1->second.find(defkey);
1312 bool specific = it2 != it1->second.end();
1313 bool wildcard = it3 != it1->second.end();
1316 ASSERTL0(specific || wildcard,
"No such variable " + pVariable +
1317 " in domain " + std::to_string(pDomain) +
1318 " defined for function " + pName +
1319 " in session file.");
1327 return it2->second.m_type;
1334 const unsigned int &pVar,
1335 const int pDomain)
const
1345 const std::string &pVariable,
1346 const int pDomain)
const
1348 std::string vName = boost::to_upper_copy(pName);
1352 std::string(
"Function '") + pName + std::string(
"' not found."));
1355 pair<std::string, int> key(pVariable, pDomain);
1356 pair<std::string, int> defkey(
"*", pDomain);
1358 auto it2 = it1->second.find(key);
1359 auto it3 = it1->second.find(defkey);
1360 bool specific = it2 != it1->second.end();
1361 bool wildcard = it3 != it1->second.end();
1364 ASSERTL0(specific || wildcard,
"No such variable " + pVariable +
1365 " in domain " + std::to_string(pDomain) +
1366 " defined for function " + pName +
1367 " in session file.");
1375 return it2->second.m_filename;
1382 const unsigned int &pVar,
1383 const int pDomain)
const
1393 const std::string &pName,
const std::string &pVariable,
1394 const int pDomain)
const
1396 std::string vName = boost::to_upper_copy(pName);
1400 std::string(
"Function '") + pName + std::string(
"' not found."));
1403 pair<std::string, int> key(pVariable, pDomain);
1404 pair<std::string, int> defkey(
"*", pDomain);
1406 auto it2 = it1->second.find(key);
1407 auto it3 = it1->second.find(defkey);
1408 bool specific = it2 != it1->second.end();
1409 bool wildcard = it3 != it1->second.end();
1412 ASSERTL0(specific || wildcard,
"No such variable " + pVariable +
1413 " in domain " + std::to_string(pDomain) +
1414 " defined for function " + pName +
1415 " in session file.");
1423 return it2->second.m_fileVariable;
1431 std::string vName = boost::to_upper_copy(pName);
1440 std::string vName = boost::to_upper_copy(pName);
1449 std::string vName = boost::to_upper_copy(pName);
1450 auto vTagIterator =
m_tags.find(vName);
1451 ASSERTL0(vTagIterator !=
m_tags.end(),
"Requested tag does not exist.");
1452 return vTagIterator->second;
1475 const size_t timeLevel,
1476 const bool enableCheck)
1478 if (Element && Element->FirstChildElement(
"TIMELEVEL"))
1480 Element = Element->FirstChildElement(
"TIMELEVEL");
1481 std::string timeLevelStr;
1484 std::stringstream tagcontent;
1485 tagcontent << *Element;
1486 ASSERTL0(Element->Attribute(
"VALUE"),
1487 "Missing LEVEL attribute in solver info "
1488 "XML element: \n\t'" +
1489 tagcontent.str() +
"'");
1490 timeLevelStr = Element->Attribute(
"VALUE");
1492 "LEVEL attribute must be non-empty in XML "
1494 tagcontent.str() +
"'");
1495 if (stoi(timeLevelStr) == timeLevel)
1499 Element = Element->NextSiblingElement(
"TIMELEVEL");
1503 ASSERTL0(stoi(timeLevelStr) == timeLevel,
1504 "TIMELEVEL value " + std::to_string(timeLevel) +
1505 " not found in solver info "
1506 "XML element: \n\t'");
1515 TiXmlDocument *pDoc)
const
1517 if (pFilename.size() > 3 &&
1518 pFilename.substr(pFilename.size() - 3, 3) ==
".gz")
1520 ifstream file(pFilename.c_str(), ios_base::in | ios_base::binary);
1521 ASSERTL0(file.good(),
"Unable to open file: " + pFilename);
1523 io::filtering_streambuf<io::input> in;
1524 in.push(io::gzip_decompressor());
1531 catch (io::gzip_error &)
1534 "Error: File '" + pFilename +
"' is corrupt.");
1537 else if (pFilename.size() > 4 &&
1538 pFilename.substr(pFilename.size() - 4, 4) ==
"_xml")
1540 fs::path pdirname(pFilename);
1542 pad %
m_comm->GetSpaceComm()->GetRank();
1543 fs::path pRankFilename(pad.str());
1544 fs::path fullpath = pdirname / pRankFilename;
1547 ASSERTL0(file.good(),
"Unable to open file: " + fullpath.string());
1552 ifstream file(pFilename.c_str());
1553 ASSERTL0(file.good(),
"Unable to open file: " + pFilename);
1562 const std::vector<std::string> &pFilenames)
const
1564 ASSERTL0(pFilenames.size() > 0,
"No filenames for merging.");
1567 TiXmlDocument *vMainDoc =
new TiXmlDocument;
1568 LoadDoc(pFilenames[0], vMainDoc);
1570 TiXmlHandle vMainHandle(vMainDoc);
1571 TiXmlElement *vMainNektar =
1577 for (
int i = 1; i < pFilenames.size(); ++i)
1579 if ((pFilenames[i].compare(pFilenames[i].size() - 3, 3,
"xml") == 0) ||
1580 (pFilenames[i].compare(pFilenames[i].size() - 6, 6,
"xml.gz") ==
1582 (pFilenames[i].compare(pFilenames[i].size() - 3, 3,
"opt") == 0))
1584 TiXmlDocument *vTempDoc =
new TiXmlDocument;
1585 LoadDoc(pFilenames[i], vTempDoc);
1587 TiXmlHandle docHandle(vTempDoc);
1588 TiXmlElement *vTempNektar =
1590 TiXmlElement *
p = vTempNektar->FirstChildElement();
1594 TiXmlElement *vMainEntry =
1595 vMainNektar->FirstChildElement(
p->Value());
1599 if (!
p->FirstChild() && vMainEntry &&
1600 !boost::iequals(
p->Value(),
"COLLECTIONS"))
1602 std::string warningmsg =
1603 "File " + pFilenames[i] +
" contains " +
1604 "an empty XML element " + std::string(
p->Value()) +
1605 " which will be ignored.";
1612 vMainNektar->RemoveChild(vMainEntry);
1614 TiXmlElement *
q =
new TiXmlElement(*
p);
1615 vMainNektar->LinkEndChild(
q);
1617 p =
p->NextSiblingElement();
1637 e = docHandle.FirstChildElement(
"NEKTAR")
1638 .FirstChildElement(
"CONDITIONS")
1650 e = docHandle.FirstChildElement(
"NEKTAR")
1651 .FirstChildElement(
"FILTERS")
1669 string vCommModule(
"Serial");
1672 vCommModule =
"ParallelMPI";
1677 vCommModule =
"CWIPI";
1690 if (
m_comm->GetSize() > 1)
1699 nProcX = GetCmdLineArgument<int>(
"npx");
1703 nProcY = GetCmdLineArgument<int>(
"npy");
1707 nProcZ = GetCmdLineArgument<int>(
"npz");
1711 nStripZ = GetCmdLineArgument<int>(
"nsz");
1715 nTime = GetCmdLineArgument<int>(
"npt");
1718 "Cannot exactly partition time using npt value.");
1719 ASSERTL0((
m_comm->GetSize() / nTime) % (nProcZ * nProcY * nProcX) == 0,
1720 "Cannot exactly partition using PROC_Z value.");
1722 "Cannot exactly partition using PROC_Y value.");
1724 "Cannot exactly partition using PROC_X value.");
1727 int nProcSm = nProcZ * nProcY * nProcX;
1731 int nProcSem =
m_comm->GetSize() / nTime / nProcSm;
1733 m_comm->SplitComm(nProcSm, nProcSem, nTime);
1734 m_comm->GetColumnComm()->SplitComm(nProcZ / nStripZ, nStripZ);
1735 m_comm->GetColumnComm()->GetColumnComm()->SplitComm((nProcY * nProcX),
1737 m_comm->GetColumnComm()->GetColumnComm()->GetColumnComm()->SplitComm(
1754 TiXmlElement *parametersElement =
1755 conditions->FirstChildElement(
"PARAMETERS");
1760 if (parametersElement)
1762 TiXmlElement *parameter = parametersElement->FirstChildElement(
"P");
1770 stringstream tagcontent;
1771 tagcontent << *parameter;
1772 TiXmlNode *node = parameter->FirstChild();
1774 while (node && node->Type() != TiXmlNode::TINYXML_TEXT)
1776 node = node->NextSibling();
1782 std::string line = node->ToText()->Value(), lhs, rhs;
1791 "Syntax error in parameter expression '" + line +
1792 "' in XML element: \n\t'" + tagcontent.str() +
1799 if (!lhs.empty() && !rhs.empty())
1807 catch (
const std::runtime_error &)
1810 "Error evaluating parameter expression"
1812 rhs +
"' in XML element: \n\t'" +
1813 tagcontent.str() +
"'");
1816 caseSensitiveParameters[lhs] = value;
1817 boost::to_upper(lhs);
1821 parameter = parameter->NextSiblingElement();
1839 TiXmlElement *solverInfoElement =
1840 conditions->FirstChildElement(
"SOLVERINFO");
1843 if (solverInfoElement)
1845 TiXmlElement *solverInfo = solverInfoElement->FirstChildElement(
"I");
1849 std::stringstream tagcontent;
1850 tagcontent << *solverInfo;
1852 ASSERTL0(solverInfo->Attribute(
"PROPERTY"),
1853 "Missing PROPERTY attribute in solver info "
1854 "XML element: \n\t'" +
1855 tagcontent.str() +
"'");
1856 std::string solverProperty = solverInfo->Attribute(
"PROPERTY");
1858 "PROPERTY attribute must be non-empty in XML "
1860 tagcontent.str() +
"'");
1863 std::string solverPropertyUpper =
1864 boost::to_upper_copy(solverProperty);
1867 ASSERTL0(solverInfo->Attribute(
"VALUE"),
1868 "Missing VALUE attribute in solver info "
1869 "XML element: \n\t'" +
1870 tagcontent.str() +
"'");
1871 std::string solverValue = solverInfo->Attribute(
"VALUE");
1873 "VALUE attribute must be non-empty in XML "
1875 tagcontent.str() +
"'");
1879 solverInfo = solverInfo->NextSiblingElement(
"I");
1887 m_solverInfo[
"GLOBALSYSSOLN"] ==
"IterativeStaticCond" ||
1889 "IterativeMultiLevelStaticCond" ||
1892 m_solverInfo[
"GLOBALSYSSOLN"] ==
"XxtMultiLevelStaticCond" ||
1895 m_solverInfo[
"GLOBALSYSSOLN"] ==
"PETScMultiLevelStaticCond",
1896 "A parallel solver must be used when run in parallel.");
1912 TiXmlElement *GlobalSys =
1913 conditions->FirstChildElement(
"GLOBALSYSSOLNINFO");
1921 TiXmlElement *VarInfo = GlobalSys->FirstChildElement(
"V");
1925 std::stringstream tagcontent;
1926 tagcontent << *VarInfo;
1928 ASSERTL0(VarInfo->Attribute(
"VAR"),
1929 "Missing VAR attribute in GobalSysSolnInfo XML "
1931 tagcontent.str() +
"'");
1932 std::string VarList = VarInfo->Attribute(
"VAR");
1934 "VAR attribute must be non-empty in XML element:\n\t'" +
1935 tagcontent.str() +
"'");
1938 std::vector<std::string> varStrings;
1941 ASSERTL0(valid,
"Unable to process list of variable in XML "
1943 tagcontent.str() +
"'");
1945 if (varStrings.size())
1947 TiXmlElement *SysSolnInfo = VarInfo->FirstChildElement(
"I");
1952 tagcontent << *SysSolnInfo;
1954 ASSERTL0(SysSolnInfo->Attribute(
"PROPERTY"),
1955 "Missing PROPERTY attribute in "
1956 "GlobalSysSolnInfo for variable(s) '" +
1957 VarList +
"' in XML element: \n\t'" +
1958 tagcontent.str() +
"'");
1959 std::string SysSolnProperty =
1960 SysSolnInfo->Attribute(
"PROPERTY");
1962 "GlobalSysSolnIno properties must have a "
1963 "non-empty name for variable(s) : '" +
1964 VarList +
"' in XML element: \n\t'" +
1965 tagcontent.str() +
"'");
1968 std::string SysSolnPropertyUpper =
1969 boost::to_upper_copy(SysSolnProperty);
1972 ASSERTL0(SysSolnInfo->Attribute(
"VALUE"),
1973 "Missing VALUE attribute in GlobalSysSolnInfo "
1974 "for variable(s) '" +
1975 VarList +
"' in XML element: \n\t" +
1976 tagcontent.str() +
"'");
1977 std::string SysSolnValue = SysSolnInfo->Attribute(
"VALUE");
1979 "GlobalSysSolnInfo properties must have a "
1980 "non-empty value for variable(s) '" +
1981 VarList +
"' in XML element: \n\t'" +
1982 tagcontent.str() +
"'");
1985 for (
int i = 0; i < varStrings.size(); ++i)
1991 [SysSolnPropertyUpper] = SysSolnValue;
1995 x->second[SysSolnPropertyUpper] = SysSolnValue;
1998 SysSolnInfo = SysSolnInfo->NextSiblingElement(
"I");
2000 VarInfo = VarInfo->NextSiblingElement(
"V");
2006 if (
m_comm->GetRank() == 0)
2008 cout <<
"GlobalSysSoln Info:" << endl;
2012 cout <<
"\t Variable: " << x.first << endl;
2014 for (
auto &y : x.second)
2016 cout <<
"\t\t " << y.first <<
" = " << y.second << endl;
2034 TiXmlElement *timeInt =
2035 conditions->FirstChildElement(
"TIMEINTEGRATIONSCHEME");
2043 TiXmlElement *method = timeInt->FirstChildElement(
"METHOD");
2044 TiXmlElement *variant = timeInt->FirstChildElement(
"VARIANT");
2045 TiXmlElement *order = timeInt->FirstChildElement(
"ORDER");
2046 TiXmlElement *params = timeInt->FirstChildElement(
"FREEPARAMETERS");
2049 ASSERTL0(method,
"Missing METHOD tag inside "
2050 "TIMEINTEGRATIONSCHEME.");
2051 ASSERTL0(order,
"Missing ORDER tag inside "
2052 "TIMEINTEGRATIONSCHEME.");
2056 std::string orderStr = order->GetText();
2060 "Empty text inside METHOD tag in TIMEINTEGRATIONSCHEME.");
2062 "Empty text inside ORDER tag in TIMEINTEGRATIONSCHEME.");
2071 orderStr +
"' to an unsigned integer.");
2081 std::string paramsStr = params->GetText();
2083 "Empty text inside FREEPARAMETERS tag in "
2084 "TIMEINTEGRATIONSCHEME.");
2086 std::vector<std::string> pSplit;
2087 boost::split(pSplit, paramsStr, boost::is_any_of(
" "));
2090 for (
size_t i = 0; i < pSplit.size(); ++i)
2099 "unable to convert string '" +
2102 "to a floating-point value.");
2109 if (
m_comm->GetRank() == 0)
2111 cout <<
"Trying to use time integration scheme:" << endl;
2118 cout <<
"\t Params :";
2141 TiXmlElement *variablesElement = conditions->FirstChildElement(
"VARIABLES");
2146 if (variablesElement)
2148 TiXmlElement *varElement = variablesElement->FirstChildElement(
"V");
2151 int nextVariableNumber = -1;
2155 stringstream tagcontent;
2156 tagcontent << *varElement;
2160 nextVariableNumber++;
2163 int err = varElement->QueryIntAttribute(
"ID", &i);
2165 "Variables must have a unique ID number attribute "
2166 "in XML element: \n\t'" +
2167 tagcontent.str() +
"'");
2169 "ID numbers for variables must begin with zero and"
2170 " be sequential in XML element: \n\t'" +
2171 tagcontent.str() +
"'");
2173 TiXmlNode *varChild = varElement->FirstChild();
2178 while (varChild && varChild->Type() != TiXmlNode::TINYXML_TEXT)
2180 varChild = varChild->NextSibling();
2183 ASSERTL0(varChild,
"Unable to read variable definition body for "
2184 "variable with ID " +
2186 " in XML element: \n\t'" + tagcontent.str() +
2188 std::string variableName = varChild->ToText()->ValueStr();
2190 std::istringstream variableStrm(variableName);
2191 variableStrm >> variableName;
2195 "Variable with ID " + std::to_string(i) +
2196 " in XML element \n\t'" + tagcontent.str() +
2197 "'\nhas already been defined.");
2201 varElement = varElement->NextSiblingElement(
"V");
2205 "Number of variables must be greater than zero.");
2222 TiXmlElement *function = conditions->FirstChildElement(
"FUNCTION");
2226 stringstream tagcontent;
2227 tagcontent << *function;
2230 ASSERTL0(function->Attribute(
"NAME"),
2231 "Functions must have a NAME attribute defined in XML "
2233 tagcontent.str() +
"'");
2234 std::string functionStr = function->Attribute(
"NAME");
2236 "Functions must have a non-empty name in XML "
2238 tagcontent.str() +
"'");
2241 boost::to_upper(functionStr);
2244 TiXmlElement *element = function;
2246 TiXmlElement *variable = element->FirstChildElement();
2255 std::string conditionType = variable->Value();
2258 std::string variableStr;
2259 if (!variable->Attribute(
"VAR"))
2265 variableStr = variable->Attribute(
"VAR");
2269 std::vector<std::string> variableList;
2273 std::string domainStr;
2274 if (!variable->Attribute(
"DOMAIN"))
2280 domainStr = variable->Attribute(
"DOMAIN");
2284 std::vector<std::string> varSplit;
2285 std::vector<unsigned int> domainList;
2289 std::string evarsStr =
"x y z t";
2290 if (variable->Attribute(
"EVARS"))
2293 evarsStr + std::string(
" ") + variable->Attribute(
"EVARS");
2297 if (conditionType ==
"E")
2302 ASSERTL0(variable->Attribute(
"VALUE"),
2303 "Attribute VALUE expected for function '" +
2304 functionStr +
"'.");
2305 std::string fcnStr = variable->Attribute(
"VALUE");
2307 (std::string(
"Expression for var: ") + variableStr +
2308 std::string(
" must be specified."))
2318 else if (conditionType ==
"F")
2321 if (variable->Attribute(
"TIMEDEPENDENT") &&
2322 boost::lexical_cast<bool>(
2323 variable->Attribute(
"TIMEDEPENDENT")))
2333 ASSERTL0(variable->Attribute(
"FILE"),
2334 "Attribute FILE expected for function '" +
2335 functionStr +
"'.");
2336 std::string filenameStr = variable->Attribute(
"FILE");
2338 "A filename must be specified for the FILE "
2339 "attribute of function '" +
2340 functionStr +
"'.");
2342 std::vector<std::string> fSplit;
2343 boost::split(fSplit, filenameStr, boost::is_any_of(
":"));
2344 ASSERTL0(fSplit.size() == 1 || fSplit.size() == 2,
2345 "Incorrect filename specification in function " +
2348 "Specify variables inside file as: "
2349 "filename:var1,var2");
2352 fs::path fullpath = fSplit[0];
2353 fs::path ftype = fullpath.extension();
2354 if (fullpath.parent_path().extension() ==
".pit")
2356 string filename = fullpath.stem().string();
2357 fullpath = fullpath.parent_path();
2358 size_t start = filename.find_last_of(
"_") + 1;
2360 atoi(filename.substr(start, filename.size()).c_str());
2361 fullpath /= filename.substr(0, start) +
2363 index +
m_comm->GetTimeComm()->GetRank()) +
2368 if (fSplit.size() == 2)
2371 "Filename variable mapping not valid "
2372 "when using * as a variable inside "
2374 functionStr +
"'.");
2376 boost::split(varSplit, fSplit[1], boost::is_any_of(
","));
2377 ASSERTL0(varSplit.size() == variableList.size(),
2378 "Filename variables should contain the "
2379 "same number of variables defined in "
2380 "VAR in function " +
2381 functionStr +
"'.");
2388 stringstream tagcontent;
2389 tagcontent << *variable;
2392 "Identifier " + conditionType +
" in function " +
2393 std::string(function->Attribute(
"NAME")) +
2394 " is not recognised in XML element: \n\t'" +
2395 tagcontent.str() +
"'");
2399 for (
unsigned int i = 0; i < variableList.size(); ++i)
2401 for (
unsigned int j = 0; j < domainList.size(); ++j)
2404 pair<std::string, int> key(variableList[i], domainList[j]);
2405 auto fcnsIter = functionVarMap.find(key);
2406 ASSERTL0(fcnsIter == functionVarMap.end(),
2407 "Error setting expression '" + variableList[i] +
2408 " in domain " + std::to_string(domainList[j]) +
2409 "' in function '" + functionStr +
2411 "Expression has already been defined.");
2413 if (varSplit.size() > 0)
2417 functionVarMap[key] = funcDef2;
2421 functionVarMap[key] = funcDef;
2425 variable = variable->NextSiblingElement();
2430 function = function->NextSiblingElement(
"FUNCTION");
2446 TiXmlElement *filter = filters->FirstChildElement(
"FILTER");
2450 ASSERTL0(filter->Attribute(
"TYPE"),
2451 "Missing attribute 'TYPE' for filter.");
2452 std::string typeStr = filter->Attribute(
"TYPE");
2455 if (filter->Attribute(
"DOMAIN"))
2458 int err = filter->QueryIntAttribute(
"DOMAIN", &domainID);
2460 "Unable to read attribute DOMAIN in filter.");
2463 std::map<std::string, std::string> vParams;
2465 TiXmlElement *element = filter;
2467 TiXmlElement *param = element->FirstChildElement(
"PARAM");
2471 "Missing attribute 'NAME' for parameter in filter " +
2473 std::string nameStr = param->Attribute(
"NAME");
2475 ASSERTL0(param->GetText(),
"Empty value string for param.");
2476 std::string valueStr = param->GetText();
2478 vParams[nameStr] = valueStr;
2480 param = param->NextSiblingElement(
"PARAM");
2484 filterDef.
domain = domainID;
2485 filterDef.
name = typeStr;
2486 filterDef.
params = vParams;
2489 filter = filter->NextSiblingElement(
"FILTER");
2500 size_t beg = line.find_first_not_of(
" ");
2501 size_t end = line.find_first_of(
"=");
2508 if (end != line.find_last_of(
"="))
2513 if (end == std::string::npos)
2518 lhs = line.substr(line.find_first_not_of(
" "), end - beg);
2519 lhs = lhs.substr(0, lhs.find_last_not_of(
" ") + 1);
2520 rhs = line.substr(line.find_last_of(
"=") + 1);
2521 rhs = rhs.substr(rhs.find_first_not_of(
" "));
2522 rhs = rhs.substr(0, rhs.find_last_not_of(
" ") + 1);
2533 std::vector<std::string> solverInfoList =
2536 for (
size_t i = 0; i < solverInfoList.size(); ++i)
2538 std::string lhs, rhs;
2551 std::string lhsUpper = boost::to_upper_copy(lhs);
2558 std::vector<std::string> parametersList =
2561 for (
size_t i = 0; i < parametersList.size(); ++i)
2563 std::string lhs, rhs;
2576 std::string lhsUpper = boost::to_upper_copy(lhs);
2585 "to double value.");
2598 std::string solverProperty = x.first;
2599 std::string solverValue = x.second;
2604 auto valIt = propIt->second.find(solverValue);
2605 ASSERTL0(valIt != propIt->second.end(),
"Value '" + solverValue +
2606 "' is not valid for "
2608 solverProperty +
"'");
2626 std::string elementName,
2627 const TiXmlHandle &docHandle)
2629 TiXmlElement *element = docHandle.FirstChildElement(elementName).Element();
2634 "' XML node in " + filename);
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
NekDouble Evaluate() const
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
const std::string & GetGlobalSysSolnInfo(const std::string &variable, const std::string &property) const
void ReadSolverInfo(TiXmlElement *conditions)
Reads the SOLVERINFO section of the XML document.
bool DefinesFunction(const std::string &name) const
Checks if a specified function is defined in the XML document.
std::string GetFunctionFilenameVariable(const std::string &name, const std::string &variable, const int pDomain=0) const
Returns the filename variable to be loaded for a given variable index.
std::vector< std::string > ParseCommandLineArguments(int argc, char *argv[])
Parse the program arguments and fill m_cmdLineOptions.
bool m_verbose
Be verbose.
static SolverInfoMap & GetSolverInfoDefaults()
Default solver info options.
TimeIntScheme m_timeIntScheme
Time integration scheme information.
InterpreterSharedPtr GetInterpreter()
Returns the instance of the Interpreter specific to this session.
TiXmlElement * GetElement(const std::string &pPath)
Provides direct access to the TiXmlElement specified.
void ReadVariables(TiXmlElement *conditions)
Reads the VARIABLES section of the XML document.
bool DefinesSolverInfo(const std::string &name) const
Checks if a solver info property is specified.
const std::string & GetSessionName() const
Returns the session name of the loaded XML document.
void ReadTimeIntScheme(TiXmlElement *conditions)
Reads the TIMEINTEGRATIONSCHEME section of the XML document.
void ReadFilters(TiXmlElement *filters)
Reads the FILTERS section of the XML document.
void ReadGlobalSysSolnInfo(TiXmlElement *conditions)
Reads the GLOBALSYSSOLNINFO section of the XML document.
bool GetBackups() const
Returns the backups.
void Finalise()
Finalises the session.
void InitSession(const std::vector< std::string > &filenames=std::vector< std::string >())
TagMap m_tags
Custom tags.
VariableList m_variables
Variables.
SolverInfoMap m_solverInfo
Solver information properties.
std::vector< std::string > GetVariables() const
Returns the names of all variables.
static CmdLineArgMap & GetCmdLineArgMap()
CmdLine argument map.
const ParameterMap & GetParameters()
TiXmlDocument * MergeDoc(const std::vector< std::string > &pFilenames) const
Creates an XML document from a list of input files.
void SetVariable(const unsigned int &idx, std::string newname)
~SessionReader()
Destructor.
void CmdLineOverride()
Enforce parameters from command line arguments.
void ParseDocument()
Loads and parses the specified file.
bool m_sharedFilesystem
Running on a shared filesystem.
static void GetXMLElementTimeLevel(TiXmlElement *&element, const size_t timeLevel, const bool enableCheck=true)
Get XML elment time level (Parallel-in-Time)
std::string ParseSessionName(std::vector< std::string > &filenames)
Parse the session name.
std::string GetFunctionFilename(const std::string &name, const std::string &variable, const int pDomain=0) const
Returns the filename to be loaded for a given variable.
enum FunctionType GetFunctionType(const std::string &name, const std::string &variable, const int pDomain=0) const
Returns the type of a given function variable.
bool DefinesTag(const std::string &pName) const
Checks if a specified tag is defined.
bool m_updateOptFile
Update optimisation file.
void LoadParameter(const std::string &name, int &var) const
Load an integer parameter.
CommSharedPtr GetComm()
Returns the communication object.
const FilterMap & GetFilters() const
const NekDouble & GetParameter(const std::string &pName) const
Returns the value of the specified parameter.
ParameterMap m_parameters
Parameters.
void SetParameter(const std::string &name, int &var)
Set an integer parameter.
InterpreterSharedPtr m_interpreter
Interpreter instance.
static EnumMapList & GetSolverInfoEnums()
String to enumeration map for Solver Info parameters.
void VerifySolverInfo()
Check values of solver info options are valid.
SessionReader(int argc, char *argv[], const std::vector< std::string > &pFilenames, const CommSharedPtr &pComm, const int &timelevel)
void SetSolverInfo(const std::string &pProperty, const std::string &pValue)
Sets the value of the specified solver info property.
const std::string & GetVariable(const unsigned int &idx) const
Returns the name of the variable specified by the given index.
EquationSharedPtr GetFunction(const std::string &name, const std::string &variable, const int pDomain=0) const
Returns an EquationSharedPtr to a given function variable.
const std::string & GetTag(const std::string &pName) const
Returns the value of a specified tag.
void TestSharedFilesystem()
FunctionMap m_functions
Functions.
TiXmlDocument & GetDocument()
Provides direct access to the TiXmlDocument object.
bool DefinesElement(const std::string &pPath) const
Tests if a specified element is defined in the XML document.
std::vector< std::string > m_filenames
Filenames.
bool DefinesGlobalSysSolnInfo(const std::string &variable, const std::string &property) const
void ReadFunctions(TiXmlElement *conditions)
Reads the FUNCTIONS section of the XML document.
void LoadDoc(const std::string &pFilename, TiXmlDocument *pDoc) const
Loads an xml file into a tinyxml doc and decompresses if needed.
bool DefinesParameter(const std::string &name) const
Checks if a parameter is specified in the XML document.
size_t m_timeLevel
Time level.
const TimeIntScheme & GetTimeIntScheme() const
Returns the time integration scheme structure m_timeIntScheme from the session file.
FilterMap m_filters
Filters map.
void SetTag(const std::string &pName, const std::string &pValue)
Sets a specified tag.
boost::program_options::variables_map m_cmdLineOptions
std::string m_sessionName
Session name of the loaded XML document (filename minus ext).
CommSharedPtr m_comm
Communication object.
void MatchSolverInfo(const std::string &name, const std::string &trueval, bool &var, const bool &def=false) const
Check if the value of a solver info property matches.
void CreateComm(int &argc, char *argv[])
Loads the given XML document and instantiates an appropriate communication object.
const std::string & GetSolverInfo(const std::string &pProperty) const
Returns the value of the specified solver info property.
void ParseEquals(const std::string &line, std::string &lhs, std::string &rhs)
Parse a string in the form lhs = rhs.
bool DefinesTimeIntScheme() const
Returns true if the TIMEINTEGRATIONSCHEME section is defined in the session file.
const std::vector< std::string > & GetFilenames() const
Returns the filename of the loaded XML document.
bool GetSharedFilesystem()
Returns if file system shared.
static GloSysSolnInfoList & GetGloSysSolnList()
GlobalSysSoln Info map.
void PartitionComm()
Partitions the comm object based on session parameters.
bool DefinesCmdLineArgument(const std::string &pName) const
Checks if a specified cmdline argument has been given.
TiXmlDocument * m_xmlDoc
Pointer to the loaded XML document.
void ReadParameters(TiXmlElement *conditions)
Reads the PARAMETERS section of the XML document.
void LoadSolverInfo(const std::string &name, std::string &var, const std::string &def="") const
Check for and load a solver info property.
std::string GetGeometryType() const
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector.
def description(self, force=False, cellml=False)
std::shared_ptr< Interpreter > InterpreterSharedPtr
std::map< std::string, std::string > SolverInfoMap
std::map< std::string, GloSysInfoMap > GloSysSolnInfoList
std::map< std::pair< std::string, int >, FunctionVariableDefinition > FunctionVariableMap
std::map< std::string, NekDouble > ParameterMap
static std::string PortablePath(const fs::path &path)
create portable path on different platforms for std::filesystem path.
std::shared_ptr< Equation > EquationSharedPtr
TiXmlElement * GetChildElementOrThrow(const std::string &filename, std::string elementName, const TiXmlHandle &docHandle)
std::map< std::string, EnumMap > EnumMapList
std::vector< FilterDefinition > FilterMap
CommFactory & GetCommFactory()
std::map< std::string, CmdLineArg > CmdLineArgMap
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
@ eFunctionTypeExpression
@ eFunctionTypeTransientFile
const std::string kGitBranch
const std::string kGitSha1
InputIterator find(InputIterator first, InputIterator last, InputIterator startingpoint, const EqualityComparable &value)
std::vector< double > d(NPUPPER *NPUPPER)
std::vector< double > q(NPUPPER *NPUPPER)
EquationSharedPtr m_expression
std::string m_fileVariable
std::vector< NekDouble > freeParams