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);
963 std::string vName = boost::to_upper_copy(pName);
973 std::string vName = boost::to_upper_copy(pName);
983 std::string vName = boost::to_upper_copy(pName);
993 std::string vName = boost::to_upper_copy(pName);
1002 const std::string &pProperty)
const
1004 std::string vProperty = boost::to_upper_copy(pProperty);
1008 "Unable to find requested property: " + pProperty);
1010 return iter->second;
1017 const std::string &pValue)
1019 std::string vProperty = boost::to_upper_copy(pProperty);
1023 "Unable to find requested property: " + pProperty);
1025 iter->second = pValue;
1032 const std::string &pDefault)
const
1034 std::string vName = boost::to_upper_copy(pName);
1038 pVar = infoIter->second;
1050 const std::string &pTrueVal,
bool &pVar,
1051 const bool &pDefault)
const
1053 std::string vName = boost::to_upper_copy(pName);
1057 pVar = boost::iequals(infoIter->second, pTrueVal);
1069 const std::string &pTrueVal)
const
1073 std::string vName = boost::to_upper_copy(pName);
1077 return boost::iequals(iter->second, pTrueVal);
1087 const std::string &pProperty)
const
1095 std::string vProperty = boost::to_upper_copy(pProperty);
1097 auto iter1 = iter->second.find(vProperty);
1098 if (iter1 == iter->second.end())
1110 const std::string &pVariable,
const std::string &pProperty)
const
1114 "Failed to find variable in GlobalSysSolnInfoList");
1116 std::string vProperty = boost::to_upper_copy(pProperty);
1117 auto iter1 = iter->second.find(vProperty);
1119 ASSERTL0(iter1 != iter->second.end(),
1120 "Failed to find property: " + vProperty +
1121 " in GlobalSysSolnInfoList");
1123 return iter1->second;
1130 const std::string &pProperty,
1131 const std::string &pValue)
1134 std::string vProperty = boost::to_upper_copy(pProperty);
1143 iter->second[vProperty] = pValue;
1170 TiXmlElement *xmlGeom =
1171 m_xmlDoc->FirstChildElement(
"NEKTAR")->FirstChildElement(
"GEOMETRY");
1172 ASSERTL1(xmlGeom,
"Failed to find a GEOMETRY section in m_xmlDoc");
1174 TiXmlAttribute *attr = xmlGeom->FirstAttribute();
1177 std::string attrName(attr->Name());
1178 if (attrName ==
"HDF5FILE")
1184 attr = attr->Next();
1189 TiXmlElement *element = xmlGeom->FirstChildElement(
"VERTEX");
1190 string IsCompressed;
1191 element->QueryStringAttribute(
"COMPRESSED", &IsCompressed);
1193 if (IsCompressed.size() > 0)
1195 return "XmlCompressed";
1241 std::string vName = boost::to_upper_copy(pName);
1249 const std::string &pVariable,
1250 const int pDomain)
const
1252 std::string vName = boost::to_upper_copy(pName);
1258 pair<std::string, int> key(pVariable, pDomain);
1259 pair<std::string, int> defkey(
"*", pDomain);
1260 bool varExists = it1->second.find(key) != it1->second.end() ||
1261 it1->second.find(defkey) != it1->second.end();
1271 const std::string &pVariable,
1272 const int pDomain)
const
1274 std::string vName = boost::to_upper_copy(pName);
1278 std::string(
"No such function '") + pName +
1279 std::string(
"' has been defined in the session file."));
1282 pair<std::string, int> key(pVariable, pDomain);
1283 pair<std::string, int> defkey(
"*", pDomain);
1285 auto it2 = it1->second.find(key);
1286 auto it3 = it1->second.find(defkey);
1287 bool specific = it2 != it1->second.end();
1288 bool wildcard = it3 != it1->second.end();
1291 ASSERTL0(specific || wildcard,
"No such variable " + pVariable +
1292 " in domain " + std::to_string(pDomain) +
1293 " defined for function " + pName +
1294 " in session file.");
1303 std::string(
"Function is defined by a file."));
1304 return it2->second.m_expression;
1311 const unsigned int &pVar,
1312 const int pDomain)
const
1322 const std::string &pVariable,
1323 const int pDomain)
const
1325 std::string vName = boost::to_upper_copy(pName);
1329 std::string(
"Function '") + pName + std::string(
"' not found."));
1332 pair<std::string, int> key(pVariable, pDomain);
1333 pair<std::string, int> defkey(
"*", pDomain);
1335 auto it2 = it1->second.find(key);
1336 auto it3 = it1->second.find(defkey);
1337 bool specific = it2 != it1->second.end();
1338 bool wildcard = it3 != it1->second.end();
1341 ASSERTL0(specific || wildcard,
"No such variable " + pVariable +
1342 " in domain " + std::to_string(pDomain) +
1343 " defined for function " + pName +
1344 " in session file.");
1352 return it2->second.m_type;
1359 const unsigned int &pVar,
1360 const int pDomain)
const
1370 const std::string &pVariable,
1371 const int pDomain)
const
1373 std::string vName = boost::to_upper_copy(pName);
1377 std::string(
"Function '") + pName + std::string(
"' not found."));
1380 pair<std::string, int> key(pVariable, pDomain);
1381 pair<std::string, int> defkey(
"*", pDomain);
1383 auto it2 = it1->second.find(key);
1384 auto it3 = it1->second.find(defkey);
1385 bool specific = it2 != it1->second.end();
1386 bool wildcard = it3 != it1->second.end();
1389 ASSERTL0(specific || wildcard,
"No such variable " + pVariable +
1390 " in domain " + std::to_string(pDomain) +
1391 " defined for function " + pName +
1392 " in session file.");
1400 return it2->second.m_filename;
1407 const unsigned int &pVar,
1408 const int pDomain)
const
1418 const std::string &pName,
const std::string &pVariable,
1419 const int pDomain)
const
1421 std::string vName = boost::to_upper_copy(pName);
1425 std::string(
"Function '") + pName + std::string(
"' not found."));
1428 pair<std::string, int> key(pVariable, pDomain);
1429 pair<std::string, int> defkey(
"*", pDomain);
1431 auto it2 = it1->second.find(key);
1432 auto it3 = it1->second.find(defkey);
1433 bool specific = it2 != it1->second.end();
1434 bool wildcard = it3 != it1->second.end();
1437 ASSERTL0(specific || wildcard,
"No such variable " + pVariable +
1438 " in domain " + std::to_string(pDomain) +
1439 " defined for function " + pName +
1440 " in session file.");
1448 return it2->second.m_fileVariable;
1456 std::string vName = boost::to_upper_copy(pName);
1465 std::string vName = boost::to_upper_copy(pName);
1474 std::string vName = boost::to_upper_copy(pName);
1475 auto vTagIterator =
m_tags.find(vName);
1476 ASSERTL0(vTagIterator !=
m_tags.end(),
"Requested tag does not exist.");
1477 return vTagIterator->second;
1500 const size_t timeLevel,
1501 const bool enableCheck)
1503 if (Element && Element->FirstChildElement(
"TIMELEVEL"))
1505 Element = Element->FirstChildElement(
"TIMELEVEL");
1506 std::string timeLevelStr;
1509 std::stringstream tagcontent;
1510 tagcontent << *Element;
1511 ASSERTL0(Element->Attribute(
"VALUE"),
1512 "Missing LEVEL attribute in solver info "
1513 "XML element: \n\t'" +
1514 tagcontent.str() +
"'");
1515 timeLevelStr = Element->Attribute(
"VALUE");
1517 "LEVEL attribute must be non-empty in XML "
1519 tagcontent.str() +
"'");
1520 if (stoi(timeLevelStr) == timeLevel)
1524 Element = Element->NextSiblingElement(
"TIMELEVEL");
1528 ASSERTL0(stoi(timeLevelStr) == timeLevel,
1529 "TIMELEVEL value " + std::to_string(timeLevel) +
1530 " not found in solver info "
1531 "XML element: \n\t'");
1540 TiXmlDocument *pDoc)
const
1542 if (pFilename.size() > 3 &&
1543 pFilename.substr(pFilename.size() - 3, 3) ==
".gz")
1545 ifstream file(pFilename.c_str(), ios_base::in | ios_base::binary);
1546 ASSERTL0(file.good(),
"Unable to open file: " + pFilename);
1548 io::filtering_streambuf<io::input> in;
1549 in.push(io::gzip_decompressor());
1556 catch (io::gzip_error &)
1559 "Error: File '" + pFilename +
"' is corrupt.");
1562 else if (pFilename.size() > 4 &&
1563 pFilename.substr(pFilename.size() - 4, 4) ==
"_xml")
1565 fs::path pdirname(pFilename);
1566 boost::format pad(
"P%1$07d.xml");
1567 pad %
m_comm->GetSpaceComm()->GetRank();
1568 fs::path pRankFilename(pad.str());
1569 fs::path fullpath = pdirname / pRankFilename;
1572 ASSERTL0(file.good(),
"Unable to open file: " + fullpath.string());
1577 ifstream file(pFilename.c_str());
1578 ASSERTL0(file.good(),
"Unable to open file: " + pFilename);
1587 const std::vector<std::string> &pFilenames)
const
1589 ASSERTL0(pFilenames.size() > 0,
"No filenames for merging.");
1592 TiXmlDocument *vMainDoc =
new TiXmlDocument;
1593 LoadDoc(pFilenames[0], vMainDoc);
1595 TiXmlHandle vMainHandle(vMainDoc);
1596 TiXmlElement *vMainNektar =
1602 for (
int i = 1; i < pFilenames.size(); ++i)
1604 if ((pFilenames[i].compare(pFilenames[i].size() - 3, 3,
"xml") == 0) ||
1605 (pFilenames[i].compare(pFilenames[i].size() - 6, 6,
"xml.gz") ==
1607 (pFilenames[i].compare(pFilenames[i].size() - 3, 3,
"opt") == 0))
1609 TiXmlDocument *vTempDoc =
new TiXmlDocument;
1610 LoadDoc(pFilenames[i], vTempDoc);
1612 TiXmlHandle docHandle(vTempDoc);
1613 TiXmlElement *vTempNektar =
1615 TiXmlElement *p = vTempNektar->FirstChildElement();
1619 TiXmlElement *vMainEntry =
1620 vMainNektar->FirstChildElement(p->Value());
1624 if (!p->FirstChild() && vMainEntry &&
1625 !boost::iequals(p->Value(),
"COLLECTIONS"))
1627 std::string warningmsg =
1628 "File " + pFilenames[i] +
" contains " +
1629 "an empty XML element " + std::string(p->Value()) +
1630 " which will be ignored.";
1637 vMainNektar->RemoveChild(vMainEntry);
1639 TiXmlElement *q =
new TiXmlElement(*p);
1640 vMainNektar->LinkEndChild(q);
1642 p = p->NextSiblingElement();
1662 e = docHandle.FirstChildElement(
"NEKTAR")
1663 .FirstChildElement(
"CONDITIONS")
1675 e = docHandle.FirstChildElement(
"NEKTAR")
1676 .FirstChildElement(
"FILTERS")
1694 string vCommModule(
"Serial");
1697 vCommModule =
"ParallelMPI";
1702 vCommModule =
"CWIPI";
1715 if (
m_comm->GetSize() > 1)
1724 nProcX = GetCmdLineArgument<int>(
"npx");
1728 nProcY = GetCmdLineArgument<int>(
"npy");
1732 nProcZ = GetCmdLineArgument<int>(
"npz");
1736 nStripZ = GetCmdLineArgument<int>(
"nsz");
1740 nTime = GetCmdLineArgument<int>(
"npt");
1746 "Cannot exactly partition time using npt value.");
1747 ASSERTL0((
m_comm->GetSize() / nTime) % (nProcZ * nProcY * nProcX) ==
1749 "Cannot exactly partition using PROC_Z value.");
1751 "Cannot exactly partition using PROC_Y value.");
1753 "Cannot exactly partition using PROC_X value.");
1758 "Cannot exactly partition using PROC_Z value.");
1760 "Cannot exactly partition using PROC_Y value.");
1762 "Cannot exactly partition using PROC_X value.");
1766 int nProcSm = nProcZ * nProcY * nProcX;
1770 int nProcSem = nTime ?
m_comm->GetSize() / nTime / nProcSm
1771 :
m_comm->GetSize() / nProcSm;
1773 m_comm->SplitComm(nProcSm, nProcSem, nTime);
1774 m_comm->GetColumnComm()->SplitComm(nProcZ / nStripZ, nStripZ);
1775 m_comm->GetColumnComm()->GetColumnComm()->SplitComm((nProcY * nProcX),
1777 m_comm->GetColumnComm()->GetColumnComm()->GetColumnComm()->SplitComm(
1794 TiXmlElement *parametersElement =
1795 conditions->FirstChildElement(
"PARAMETERS");
1800 if (parametersElement)
1802 TiXmlElement *parameter = parametersElement->FirstChildElement(
"P");
1810 stringstream tagcontent;
1811 tagcontent << *parameter;
1812 TiXmlNode *node = parameter->FirstChild();
1814 while (node && node->Type() != TiXmlNode::TINYXML_TEXT)
1816 node = node->NextSibling();
1822 std::string line = node->ToText()->Value(), lhs, rhs;
1831 "Syntax error in parameter expression '" + line +
1832 "' in XML element: \n\t'" + tagcontent.str() +
1839 if (!lhs.empty() && !rhs.empty())
1847 catch (
const std::runtime_error &)
1850 "Error evaluating parameter expression"
1852 rhs +
"' in XML element: \n\t'" +
1853 tagcontent.str() +
"'");
1856 caseSensitiveParameters[lhs] = value;
1857 boost::to_upper(lhs);
1861 parameter = parameter->NextSiblingElement();
1879 TiXmlElement *solverInfoElement =
1880 conditions->FirstChildElement(
"SOLVERINFO");
1883 if (solverInfoElement)
1885 TiXmlElement *solverInfo = solverInfoElement->FirstChildElement(
"I");
1889 std::stringstream tagcontent;
1890 tagcontent << *solverInfo;
1892 ASSERTL0(solverInfo->Attribute(
"PROPERTY"),
1893 "Missing PROPERTY attribute in solver info "
1894 "XML element: \n\t'" +
1895 tagcontent.str() +
"'");
1896 std::string solverProperty = solverInfo->Attribute(
"PROPERTY");
1898 "PROPERTY attribute must be non-empty in XML "
1900 tagcontent.str() +
"'");
1903 std::string solverPropertyUpper =
1904 boost::to_upper_copy(solverProperty);
1907 ASSERTL0(solverInfo->Attribute(
"VALUE"),
1908 "Missing VALUE attribute in solver info "
1909 "XML element: \n\t'" +
1910 tagcontent.str() +
"'");
1911 std::string solverValue = solverInfo->Attribute(
"VALUE");
1913 "VALUE attribute must be non-empty in XML "
1915 tagcontent.str() +
"'");
1919 solverInfo = solverInfo->NextSiblingElement(
"I");
1927 m_solverInfo[
"GLOBALSYSSOLN"] ==
"IterativeStaticCond" ||
1929 "IterativeMultiLevelStaticCond" ||
1932 m_solverInfo[
"GLOBALSYSSOLN"] ==
"XxtMultiLevelStaticCond" ||
1935 m_solverInfo[
"GLOBALSYSSOLN"] ==
"PETScMultiLevelStaticCond",
1936 "A parallel solver must be used when run in parallel.");
1952 TiXmlElement *GlobalSys =
1953 conditions->FirstChildElement(
"GLOBALSYSSOLNINFO");
1961 TiXmlElement *VarInfo = GlobalSys->FirstChildElement(
"V");
1965 std::stringstream tagcontent;
1966 tagcontent << *VarInfo;
1968 ASSERTL0(VarInfo->Attribute(
"VAR"),
1969 "Missing VAR attribute in GobalSysSolnInfo XML "
1971 tagcontent.str() +
"'");
1972 std::string VarList = VarInfo->Attribute(
"VAR");
1974 "VAR attribute must be non-empty in XML element:\n\t'" +
1975 tagcontent.str() +
"'");
1978 std::vector<std::string> varStrings;
1981 ASSERTL0(valid,
"Unable to process list of variable in XML "
1983 tagcontent.str() +
"'");
1985 if (varStrings.size())
1987 TiXmlElement *SysSolnInfo = VarInfo->FirstChildElement(
"I");
1992 tagcontent << *SysSolnInfo;
1994 ASSERTL0(SysSolnInfo->Attribute(
"PROPERTY"),
1995 "Missing PROPERTY attribute in "
1996 "GlobalSysSolnInfo for variable(s) '" +
1997 VarList +
"' in XML element: \n\t'" +
1998 tagcontent.str() +
"'");
1999 std::string SysSolnProperty =
2000 SysSolnInfo->Attribute(
"PROPERTY");
2002 "GlobalSysSolnIno properties must have a "
2003 "non-empty name for variable(s) : '" +
2004 VarList +
"' in XML element: \n\t'" +
2005 tagcontent.str() +
"'");
2008 std::string SysSolnPropertyUpper =
2009 boost::to_upper_copy(SysSolnProperty);
2012 ASSERTL0(SysSolnInfo->Attribute(
"VALUE"),
2013 "Missing VALUE attribute in GlobalSysSolnInfo "
2014 "for variable(s) '" +
2015 VarList +
"' in XML element: \n\t" +
2016 tagcontent.str() +
"'");
2017 std::string SysSolnValue = SysSolnInfo->Attribute(
"VALUE");
2019 "GlobalSysSolnInfo properties must have a "
2020 "non-empty value for variable(s) '" +
2021 VarList +
"' in XML element: \n\t'" +
2022 tagcontent.str() +
"'");
2025 for (
int i = 0; i < varStrings.size(); ++i)
2031 [SysSolnPropertyUpper] = SysSolnValue;
2035 x->second[SysSolnPropertyUpper] = SysSolnValue;
2038 SysSolnInfo = SysSolnInfo->NextSiblingElement(
"I");
2040 VarInfo = VarInfo->NextSiblingElement(
"V");
2046 if (
m_comm->GetRank() == 0)
2048 cout <<
"GlobalSysSoln Info:" << endl;
2052 cout <<
"\t Variable: " << x.first << endl;
2054 for (
auto &y : x.second)
2056 cout <<
"\t\t " << y.first <<
" = " << y.second << endl;
2074 TiXmlElement *timeInt =
2075 conditions->FirstChildElement(
"TIMEINTEGRATIONSCHEME");
2083 TiXmlElement *method = timeInt->FirstChildElement(
"METHOD");
2084 TiXmlElement *variant = timeInt->FirstChildElement(
"VARIANT");
2085 TiXmlElement *order = timeInt->FirstChildElement(
"ORDER");
2086 TiXmlElement *params = timeInt->FirstChildElement(
"FREEPARAMETERS");
2089 ASSERTL0(method,
"Missing METHOD tag inside "
2090 "TIMEINTEGRATIONSCHEME.");
2091 ASSERTL0(order,
"Missing ORDER tag inside "
2092 "TIMEINTEGRATIONSCHEME.");
2096 std::string orderStr = order->GetText();
2100 "Empty text inside METHOD tag in TIMEINTEGRATIONSCHEME.");
2102 "Empty text inside ORDER tag in TIMEINTEGRATIONSCHEME.");
2111 orderStr +
"' to an unsigned integer.");
2121 std::string paramsStr = params->GetText();
2123 "Empty text inside FREEPARAMETERS tag in "
2124 "TIMEINTEGRATIONSCHEME.");
2126 std::vector<std::string> pSplit;
2127 boost::split(pSplit, paramsStr, boost::is_any_of(
" "));
2130 for (
size_t i = 0; i < pSplit.size(); ++i)
2139 "unable to convert string '" +
2142 "to a floating-point value.");
2149 if (
m_comm->GetRank() == 0)
2151 cout <<
"Trying to use time integration scheme:" << endl;
2158 cout <<
"\t Params :";
2181 TiXmlElement *variablesElement = conditions->FirstChildElement(
"VARIABLES");
2186 if (variablesElement)
2188 TiXmlElement *varElement = variablesElement->FirstChildElement(
"V");
2191 int nextVariableNumber = -1;
2195 stringstream tagcontent;
2196 tagcontent << *varElement;
2200 nextVariableNumber++;
2203 int err = varElement->QueryIntAttribute(
"ID", &i);
2205 "Variables must have a unique ID number attribute "
2206 "in XML element: \n\t'" +
2207 tagcontent.str() +
"'");
2209 "ID numbers for variables must begin with zero and"
2210 " be sequential in XML element: \n\t'" +
2211 tagcontent.str() +
"'");
2213 TiXmlNode *varChild = varElement->FirstChild();
2218 while (varChild && varChild->Type() != TiXmlNode::TINYXML_TEXT)
2220 varChild = varChild->NextSibling();
2223 ASSERTL0(varChild,
"Unable to read variable definition body for "
2224 "variable with ID " +
2226 " in XML element: \n\t'" + tagcontent.str() +
2228 std::string variableName = varChild->ToText()->ValueStr();
2230 std::istringstream variableStrm(variableName);
2231 variableStrm >> variableName;
2235 "Variable with ID " + std::to_string(i) +
2236 " in XML element \n\t'" + tagcontent.str() +
2237 "'\nhas already been defined.");
2241 varElement = varElement->NextSiblingElement(
"V");
2245 "Number of variables must be greater than zero.");
2262 TiXmlElement *function = conditions->FirstChildElement(
"FUNCTION");
2266 stringstream tagcontent;
2267 tagcontent << *function;
2270 ASSERTL0(function->Attribute(
"NAME"),
2271 "Functions must have a NAME attribute defined in XML "
2273 tagcontent.str() +
"'");
2274 std::string functionStr = function->Attribute(
"NAME");
2276 "Functions must have a non-empty name in XML "
2278 tagcontent.str() +
"'");
2281 boost::to_upper(functionStr);
2284 TiXmlElement *element = function;
2286 TiXmlElement *variable = element->FirstChildElement();
2295 std::string conditionType = variable->Value();
2298 std::string variableStr;
2299 if (!variable->Attribute(
"VAR"))
2305 variableStr = variable->Attribute(
"VAR");
2309 std::vector<std::string> variableList;
2313 std::string domainStr;
2314 if (!variable->Attribute(
"DOMAIN"))
2320 domainStr = variable->Attribute(
"DOMAIN");
2324 std::vector<std::string> varSplit;
2325 std::vector<unsigned int> domainList;
2329 std::string evarsStr =
"x y z t";
2330 if (variable->Attribute(
"EVARS"))
2333 evarsStr + std::string(
" ") + variable->Attribute(
"EVARS");
2337 if (conditionType ==
"E")
2342 ASSERTL0(variable->Attribute(
"VALUE"),
2343 "Attribute VALUE expected for function '" +
2344 functionStr +
"'.");
2345 std::string fcnStr = variable->Attribute(
"VALUE");
2347 (std::string(
"Expression for var: ") + variableStr +
2348 std::string(
" must be specified."))
2358 else if (conditionType ==
"F")
2361 if (variable->Attribute(
"TIMEDEPENDENT") &&
2362 boost::lexical_cast<bool>(
2363 variable->Attribute(
"TIMEDEPENDENT")))
2373 ASSERTL0(variable->Attribute(
"FILE"),
2374 "Attribute FILE expected for function '" +
2375 functionStr +
"'.");
2376 std::string filenameStr = variable->Attribute(
"FILE");
2378 "A filename must be specified for the FILE "
2379 "attribute of function '" +
2380 functionStr +
"'.");
2382 std::vector<std::string> fSplit;
2383 boost::split(fSplit, filenameStr, boost::is_any_of(
":"));
2384 ASSERTL0(fSplit.size() == 1 || fSplit.size() == 2,
2385 "Incorrect filename specification in function " +
2388 "Specify variables inside file as: "
2389 "filename:var1,var2");
2392 fs::path fullpath = fSplit[0];
2393 fs::path ftype = fullpath.extension();
2394 if (fullpath.parent_path().extension() ==
".pit")
2396 string filename = fullpath.stem().string();
2397 fullpath = fullpath.parent_path();
2398 size_t start = filename.find_last_of(
"_") + 1;
2400 atoi(filename.substr(start, filename.size()).c_str());
2401 fullpath /= filename.substr(0, start) +
2403 index +
m_comm->GetTimeComm()->GetRank()) +
2408 if (fSplit.size() == 2)
2411 "Filename variable mapping not valid "
2412 "when using * as a variable inside "
2414 functionStr +
"'.");
2416 boost::split(varSplit, fSplit[1], boost::is_any_of(
","));
2417 ASSERTL0(varSplit.size() == variableList.size(),
2418 "Filename variables should contain the "
2419 "same number of variables defined in "
2420 "VAR in function " +
2421 functionStr +
"'.");
2428 stringstream tagcontent;
2429 tagcontent << *variable;
2432 "Identifier " + conditionType +
" in function " +
2433 std::string(function->Attribute(
"NAME")) +
2434 " is not recognised in XML element: \n\t'" +
2435 tagcontent.str() +
"'");
2439 for (
unsigned int i = 0; i < variableList.size(); ++i)
2441 for (
unsigned int j = 0; j < domainList.size(); ++j)
2444 pair<std::string, int> key(variableList[i], domainList[j]);
2445 auto fcnsIter = functionVarMap.find(key);
2446 ASSERTL0(fcnsIter == functionVarMap.end(),
2447 "Error setting expression '" + variableList[i] +
2448 " in domain " + std::to_string(domainList[j]) +
2449 "' in function '" + functionStr +
2451 "Expression has already been defined.");
2453 if (varSplit.size() > 0)
2457 functionVarMap[key] = funcDef2;
2461 functionVarMap[key] = funcDef;
2465 variable = variable->NextSiblingElement();
2470 function = function->NextSiblingElement(
"FUNCTION");
2486 TiXmlElement *filter = filters->FirstChildElement(
"FILTER");
2490 ASSERTL0(filter->Attribute(
"TYPE"),
2491 "Missing attribute 'TYPE' for filter.");
2492 std::string typeStr = filter->Attribute(
"TYPE");
2495 if (filter->Attribute(
"DOMAIN"))
2498 int err = filter->QueryIntAttribute(
"DOMAIN", &domainID);
2500 "Unable to read attribute DOMAIN in filter.");
2503 std::map<std::string, std::string> vParams;
2505 TiXmlElement *element = filter;
2507 TiXmlElement *param = element->FirstChildElement(
"PARAM");
2511 "Missing attribute 'NAME' for parameter in filter " +
2513 std::string nameStr = param->Attribute(
"NAME");
2515 ASSERTL0(param->GetText(),
"Empty value string for param.");
2516 std::string valueStr = param->GetText();
2518 vParams[nameStr] = valueStr;
2520 param = param->NextSiblingElement(
"PARAM");
2524 filterDef.
domain = domainID;
2525 filterDef.
name = typeStr;
2526 filterDef.
params = vParams;
2529 filter = filter->NextSiblingElement(
"FILTER");
2540 size_t beg = line.find_first_not_of(
" ");
2541 size_t end = line.find_first_of(
"=");
2548 if (end != line.find_last_of(
"="))
2553 if (end == std::string::npos)
2558 lhs = line.substr(line.find_first_not_of(
" "), end - beg);
2559 lhs = lhs.substr(0, lhs.find_last_not_of(
" ") + 1);
2560 rhs = line.substr(line.find_last_of(
"=") + 1);
2561 rhs = rhs.substr(rhs.find_first_not_of(
" "));
2562 rhs = rhs.substr(0, rhs.find_last_not_of(
" ") + 1);
2573 std::vector<std::string> solverInfoList =
2576 for (
size_t i = 0; i < solverInfoList.size(); ++i)
2578 std::string lhs, rhs;
2591 std::string lhsUpper = boost::to_upper_copy(lhs);
2598 std::vector<std::string> parametersList =
2601 for (
size_t i = 0; i < parametersList.size(); ++i)
2603 std::string lhs, rhs;
2616 std::string lhsUpper = boost::to_upper_copy(lhs);
2626 "to double value.");
2639 std::string solverProperty = x.first;
2640 std::string solverValue = x.second;
2645 auto valIt = propIt->second.find(solverValue);
2646 ASSERTL0(valIt != propIt->second.end(),
"Value '" + solverValue +
2647 "' is not valid for "
2649 solverProperty +
"'");
2667 std::string elementName,
2668 const TiXmlHandle &docHandle)
2670 TiXmlElement *element = docHandle.FirstChildElement(elementName).Element();
2675 "' 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.
void SetGlobalSysSolnInfo(const std::string &variable, const std::string &property, const std::string &value)
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.
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
EquationSharedPtr m_expression
std::string m_fileVariable
std::vector< NekDouble > freeParams