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);
857 std::string vName = boost::to_upper_copy(pName);
860 "Required parameter '" + pName +
"' not specified in session.");
861 NekDouble param = round(paramIter->second);
862 pVar = checked_cast<int>(param);
869 const size_t &pDefault)
const
871 std::string vName = boost::to_upper_copy(pName);
875 NekDouble param = round(paramIter->second);
876 pVar = checked_cast<int>(param);
890 std::string vName = boost::to_upper_copy(pName);
893 "Required parameter '" + pName +
"' not specified in session.");
894 pVar = paramIter->second;
903 std::string vName = boost::to_upper_copy(pName);
907 pVar = paramIter->second;
920 std::string vName = boost::to_upper_copy(pName);
929 std::string vName = boost::to_upper_copy(pName);
938 std::string vName = boost::to_upper_copy(pName);
947 std::string vName = boost::to_upper_copy(pName);
956 const std::string &pProperty)
const
958 std::string vProperty = boost::to_upper_copy(pProperty);
962 "Unable to find requested property: " + pProperty);
971 const std::string &pValue)
973 std::string vProperty = boost::to_upper_copy(pProperty);
977 "Unable to find requested property: " + pProperty);
979 iter->second = pValue;
986 const std::string &pDefault)
const
988 std::string vName = boost::to_upper_copy(pName);
992 pVar = infoIter->second;
1004 const std::string &pTrueVal,
bool &pVar,
1005 const bool &pDefault)
const
1007 std::string vName = boost::to_upper_copy(pName);
1011 pVar = boost::iequals(infoIter->second, pTrueVal);
1023 const std::string &pTrueVal)
const
1027 std::string vName = boost::to_upper_copy(pName);
1031 return boost::iequals(iter->second, pTrueVal);
1041 const std::string &pProperty)
const
1049 std::string vProperty = boost::to_upper_copy(pProperty);
1051 auto iter1 = iter->second.find(vProperty);
1052 if (iter1 == iter->second.end())
1064 const std::string &pVariable,
const std::string &pProperty)
const
1068 "Failed to find variable in GlobalSysSolnInfoList");
1070 std::string vProperty = boost::to_upper_copy(pProperty);
1071 auto iter1 = iter->second.find(vProperty);
1073 ASSERTL0(iter1 != iter->second.end(),
1074 "Failed to find property: " + vProperty +
1075 " in GlobalSysSolnInfoList");
1077 return iter1->second;
1103 TiXmlElement *xmlGeom =
1104 m_xmlDoc->FirstChildElement(
"NEKTAR")->FirstChildElement(
"GEOMETRY");
1105 ASSERTL1(xmlGeom,
"Failed to find a GEOMETRY section in m_xmlDoc");
1107 TiXmlAttribute *attr = xmlGeom->FirstAttribute();
1110 std::string attrName(attr->Name());
1111 if (attrName ==
"HDF5FILE")
1117 attr = attr->Next();
1122 TiXmlElement *element = xmlGeom->FirstChildElement(
"VERTEX");
1123 string IsCompressed;
1124 element->QueryStringAttribute(
"COMPRESSED", &IsCompressed);
1126 if (IsCompressed.size() > 0)
1128 return "XmlCompressed";
1174 std::string vName = boost::to_upper_copy(pName);
1182 const std::string &pVariable,
1183 const int pDomain)
const
1185 std::string vName = boost::to_upper_copy(pName);
1191 pair<std::string, int> key(pVariable, pDomain);
1192 pair<std::string, int> defkey(
"*", pDomain);
1193 bool varExists = it1->second.find(key) != it1->second.end() ||
1194 it1->second.find(defkey) != it1->second.end();
1204 const std::string &pVariable,
1205 const int pDomain)
const
1207 std::string vName = boost::to_upper_copy(pName);
1211 std::string(
"No such function '") + pName +
1212 std::string(
"' has been defined in the session file."));
1215 pair<std::string, int> key(pVariable, pDomain);
1216 pair<std::string, int> defkey(
"*", pDomain);
1218 auto it2 = it1->second.find(key);
1219 auto it3 = it1->second.find(defkey);
1220 bool specific = it2 != it1->second.end();
1221 bool wildcard = it3 != it1->second.end();
1225 "No such variable " + pVariable +
" in domain " +
1226 boost::lexical_cast<string>(pDomain) +
1227 " defined for function " + pName +
" in session file.");
1236 std::string(
"Function is defined by a file."));
1237 return it2->second.m_expression;
1244 const unsigned int &pVar,
1245 const int pDomain)
const
1255 const std::string &pVariable,
1256 const int pDomain)
const
1258 std::string vName = boost::to_upper_copy(pName);
1262 std::string(
"Function '") + pName + std::string(
"' not found."));
1265 pair<std::string, int> key(pVariable, pDomain);
1266 pair<std::string, int> defkey(
"*", pDomain);
1268 auto it2 = it1->second.find(key);
1269 auto it3 = it1->second.find(defkey);
1270 bool specific = it2 != it1->second.end();
1271 bool wildcard = it3 != it1->second.end();
1275 "No such variable " + pVariable +
" in domain " +
1276 boost::lexical_cast<string>(pDomain) +
1277 " defined for function " + pName +
" in session file.");
1285 return it2->second.m_type;
1292 const unsigned int &pVar,
1293 const int pDomain)
const
1303 const std::string &pVariable,
1304 const int pDomain)
const
1306 std::string vName = boost::to_upper_copy(pName);
1310 std::string(
"Function '") + pName + std::string(
"' not found."));
1313 pair<std::string, int> key(pVariable, pDomain);
1314 pair<std::string, int> defkey(
"*", pDomain);
1316 auto it2 = it1->second.find(key);
1317 auto it3 = it1->second.find(defkey);
1318 bool specific = it2 != it1->second.end();
1319 bool wildcard = it3 != it1->second.end();
1323 "No such variable " + pVariable +
" in domain " +
1324 boost::lexical_cast<string>(pDomain) +
1325 " defined for function " + pName +
" in session file.");
1333 return it2->second.m_filename;
1340 const unsigned int &pVar,
1341 const int pDomain)
const
1351 const std::string &pName,
const std::string &pVariable,
1352 const int pDomain)
const
1354 std::string vName = boost::to_upper_copy(pName);
1358 std::string(
"Function '") + pName + std::string(
"' not found."));
1361 pair<std::string, int> key(pVariable, pDomain);
1362 pair<std::string, int> defkey(
"*", pDomain);
1364 auto it2 = it1->second.find(key);
1365 auto it3 = it1->second.find(defkey);
1366 bool specific = it2 != it1->second.end();
1367 bool wildcard = it3 != it1->second.end();
1371 "No such variable " + pVariable +
" in domain " +
1372 boost::lexical_cast<string>(pDomain) +
1373 " defined for function " + pName +
" in session file.");
1381 return it2->second.m_fileVariable;
1389 std::string vName = boost::to_upper_copy(pName);
1398 std::string vName = boost::to_upper_copy(pName);
1407 std::string vName = boost::to_upper_copy(pName);
1408 auto vTagIterator =
m_tags.find(vName);
1409 ASSERTL0(vTagIterator !=
m_tags.end(),
"Requested tag does not exist.");
1410 return vTagIterator->second;
1433 const size_t timeLevel,
1434 const bool enableCheck)
1436 if (Element && Element->FirstChildElement(
"TIMELEVEL"))
1438 Element = Element->FirstChildElement(
"TIMELEVEL");
1439 std::string timeLevelStr;
1442 std::stringstream tagcontent;
1443 tagcontent << *Element;
1444 ASSERTL0(Element->Attribute(
"VALUE"),
1445 "Missing LEVEL attribute in solver info "
1446 "XML element: \n\t'" +
1447 tagcontent.str() +
"'");
1448 timeLevelStr = Element->Attribute(
"VALUE");
1450 "LEVEL attribute must be non-empty in XML "
1452 tagcontent.str() +
"'");
1453 if (stoi(timeLevelStr) == timeLevel)
1457 Element = Element->NextSiblingElement(
"TIMELEVEL");
1461 ASSERTL0(stoi(timeLevelStr) == timeLevel,
1462 "TIMELEVEL value " + std::to_string(timeLevel) +
1463 " not found in solver info "
1464 "XML element: \n\t'");
1473 TiXmlDocument *pDoc)
const
1475 if (pFilename.size() > 3 &&
1476 pFilename.substr(pFilename.size() - 3, 3) ==
".gz")
1478 ifstream file(pFilename.c_str(), ios_base::in | ios_base::binary);
1479 ASSERTL0(file.good(),
"Unable to open file: " + pFilename);
1481 io::filtering_streambuf<io::input> in;
1482 in.push(io::gzip_decompressor());
1489 catch (io::gzip_error &)
1492 "Error: File '" + pFilename +
"' is corrupt.");
1495 else if (pFilename.size() > 4 &&
1496 pFilename.substr(pFilename.size() - 4, 4) ==
"_xml")
1498 fs::path pdirname(pFilename);
1500 pad %
m_comm->GetSpaceComm()->GetRank();
1501 fs::path pRankFilename(pad.str());
1502 fs::path fullpath = pdirname / pRankFilename;
1505 ASSERTL0(file.good(),
"Unable to open file: " + fullpath.string());
1510 ifstream file(pFilename.c_str());
1511 ASSERTL0(file.good(),
"Unable to open file: " + pFilename);
1520 const std::vector<std::string> &pFilenames)
const
1522 ASSERTL0(pFilenames.size() > 0,
"No filenames for merging.");
1525 TiXmlDocument *vMainDoc =
new TiXmlDocument;
1526 LoadDoc(pFilenames[0], vMainDoc);
1528 TiXmlHandle vMainHandle(vMainDoc);
1529 TiXmlElement *vMainNektar =
1535 for (
int i = 1; i < pFilenames.size(); ++i)
1537 if ((pFilenames[i].compare(pFilenames[i].size() - 3, 3,
"xml") == 0) ||
1538 (pFilenames[i].compare(pFilenames[i].size() - 6, 6,
"xml.gz") ==
1540 (pFilenames[i].compare(pFilenames[i].size() - 3, 3,
"opt") == 0))
1542 TiXmlDocument *vTempDoc =
new TiXmlDocument;
1543 LoadDoc(pFilenames[i], vTempDoc);
1545 TiXmlHandle docHandle(vTempDoc);
1546 TiXmlElement *vTempNektar =
1548 TiXmlElement *
p = vTempNektar->FirstChildElement();
1552 TiXmlElement *vMainEntry =
1553 vMainNektar->FirstChildElement(
p->Value());
1557 if (!
p->FirstChild() && vMainEntry &&
1558 !boost::iequals(
p->Value(),
"COLLECTIONS"))
1560 std::string warningmsg =
1561 "File " + pFilenames[i] +
" contains " +
1562 "an empty XML element " + std::string(
p->Value()) +
1563 " which will be ignored.";
1570 vMainNektar->RemoveChild(vMainEntry);
1572 TiXmlElement *
q =
new TiXmlElement(*
p);
1573 vMainNektar->LinkEndChild(
q);
1575 p =
p->NextSiblingElement();
1595 e = docHandle.FirstChildElement(
"NEKTAR")
1596 .FirstChildElement(
"CONDITIONS")
1608 e = docHandle.FirstChildElement(
"NEKTAR")
1609 .FirstChildElement(
"FILTERS")
1627 string vCommModule(
"Serial");
1630 vCommModule =
"ParallelMPI";
1635 vCommModule =
"CWIPI";
1648 if (
m_comm->GetSize() > 1)
1657 nProcX = GetCmdLineArgument<int>(
"npx");
1661 nProcY = GetCmdLineArgument<int>(
"npy");
1665 nProcZ = GetCmdLineArgument<int>(
"npz");
1669 nStripZ = GetCmdLineArgument<int>(
"nsz");
1673 nTime = GetCmdLineArgument<int>(
"npt");
1676 "Cannot exactly partition time using npt value.");
1677 ASSERTL0((
m_comm->GetSize() / nTime) % (nProcZ * nProcY * nProcX) == 0,
1678 "Cannot exactly partition using PROC_Z value.");
1680 "Cannot exactly partition using PROC_Y value.");
1682 "Cannot exactly partition using PROC_X value.");
1685 int nProcSm = nProcZ * nProcY * nProcX;
1689 int nProcSem =
m_comm->GetSize() / nTime / nProcSm;
1691 m_comm->SplitComm(nProcSm, nProcSem, nTime);
1692 m_comm->GetColumnComm()->SplitComm(nProcZ / nStripZ, nStripZ);
1693 m_comm->GetColumnComm()->GetColumnComm()->SplitComm((nProcY * nProcX),
1695 m_comm->GetColumnComm()->GetColumnComm()->GetColumnComm()->SplitComm(
1712 TiXmlElement *parametersElement =
1713 conditions->FirstChildElement(
"PARAMETERS");
1718 if (parametersElement)
1720 TiXmlElement *parameter = parametersElement->FirstChildElement(
"P");
1728 stringstream tagcontent;
1729 tagcontent << *parameter;
1730 TiXmlNode *node = parameter->FirstChild();
1732 while (node && node->Type() != TiXmlNode::TINYXML_TEXT)
1734 node = node->NextSibling();
1740 std::string line = node->ToText()->Value(), lhs, rhs;
1749 "Syntax error in parameter expression '" + line +
1750 "' in XML element: \n\t'" + tagcontent.str() +
1757 if (!lhs.empty() && !rhs.empty())
1765 catch (
const std::runtime_error &)
1768 "Error evaluating parameter expression"
1770 rhs +
"' in XML element: \n\t'" +
1771 tagcontent.str() +
"'");
1774 caseSensitiveParameters[lhs] = value;
1775 boost::to_upper(lhs);
1779 parameter = parameter->NextSiblingElement();
1797 TiXmlElement *solverInfoElement =
1798 conditions->FirstChildElement(
"SOLVERINFO");
1801 if (solverInfoElement)
1803 TiXmlElement *solverInfo = solverInfoElement->FirstChildElement(
"I");
1807 std::stringstream tagcontent;
1808 tagcontent << *solverInfo;
1810 ASSERTL0(solverInfo->Attribute(
"PROPERTY"),
1811 "Missing PROPERTY attribute in solver info "
1812 "XML element: \n\t'" +
1813 tagcontent.str() +
"'");
1814 std::string solverProperty = solverInfo->Attribute(
"PROPERTY");
1816 "PROPERTY attribute must be non-empty in XML "
1818 tagcontent.str() +
"'");
1821 std::string solverPropertyUpper =
1822 boost::to_upper_copy(solverProperty);
1825 ASSERTL0(solverInfo->Attribute(
"VALUE"),
1826 "Missing VALUE attribute in solver info "
1827 "XML element: \n\t'" +
1828 tagcontent.str() +
"'");
1829 std::string solverValue = solverInfo->Attribute(
"VALUE");
1831 "VALUE attribute must be non-empty in XML "
1833 tagcontent.str() +
"'");
1837 solverInfo = solverInfo->NextSiblingElement(
"I");
1845 m_solverInfo[
"GLOBALSYSSOLN"] ==
"IterativeStaticCond" ||
1847 "IterativeMultiLevelStaticCond" ||
1850 m_solverInfo[
"GLOBALSYSSOLN"] ==
"XxtMultiLevelStaticCond" ||
1853 m_solverInfo[
"GLOBALSYSSOLN"] ==
"PETScMultiLevelStaticCond",
1854 "A parallel solver must be used when run in parallel.");
1870 TiXmlElement *GlobalSys =
1871 conditions->FirstChildElement(
"GLOBALSYSSOLNINFO");
1879 TiXmlElement *VarInfo = GlobalSys->FirstChildElement(
"V");
1883 std::stringstream tagcontent;
1884 tagcontent << *VarInfo;
1886 ASSERTL0(VarInfo->Attribute(
"VAR"),
1887 "Missing VAR attribute in GobalSysSolnInfo XML "
1889 tagcontent.str() +
"'");
1890 std::string VarList = VarInfo->Attribute(
"VAR");
1892 "VAR attribute must be non-empty in XML element:\n\t'" +
1893 tagcontent.str() +
"'");
1896 std::vector<std::string> varStrings;
1899 ASSERTL0(valid,
"Unable to process list of variable in XML "
1901 tagcontent.str() +
"'");
1903 if (varStrings.size())
1905 TiXmlElement *SysSolnInfo = VarInfo->FirstChildElement(
"I");
1910 tagcontent << *SysSolnInfo;
1912 ASSERTL0(SysSolnInfo->Attribute(
"PROPERTY"),
1913 "Missing PROPERTY attribute in "
1914 "GlobalSysSolnInfo for variable(s) '" +
1915 VarList +
"' in XML element: \n\t'" +
1916 tagcontent.str() +
"'");
1917 std::string SysSolnProperty =
1918 SysSolnInfo->Attribute(
"PROPERTY");
1920 "GlobalSysSolnIno properties must have a "
1921 "non-empty name for variable(s) : '" +
1922 VarList +
"' in XML element: \n\t'" +
1923 tagcontent.str() +
"'");
1926 std::string SysSolnPropertyUpper =
1927 boost::to_upper_copy(SysSolnProperty);
1930 ASSERTL0(SysSolnInfo->Attribute(
"VALUE"),
1931 "Missing VALUE attribute in GlobalSysSolnInfo "
1932 "for variable(s) '" +
1933 VarList +
"' in XML element: \n\t" +
1934 tagcontent.str() +
"'");
1935 std::string SysSolnValue = SysSolnInfo->Attribute(
"VALUE");
1937 "GlobalSysSolnInfo properties must have a "
1938 "non-empty value for variable(s) '" +
1939 VarList +
"' in XML element: \n\t'" +
1940 tagcontent.str() +
"'");
1943 for (
int i = 0; i < varStrings.size(); ++i)
1949 [SysSolnPropertyUpper] = SysSolnValue;
1953 x->second[SysSolnPropertyUpper] = SysSolnValue;
1956 SysSolnInfo = SysSolnInfo->NextSiblingElement(
"I");
1958 VarInfo = VarInfo->NextSiblingElement(
"V");
1964 if (
m_comm->GetRank() == 0)
1966 cout <<
"GlobalSysSoln Info:" << endl;
1970 cout <<
"\t Variable: " << x.first << endl;
1972 for (
auto &y : x.second)
1974 cout <<
"\t\t " << y.first <<
" = " << y.second << endl;
1992 TiXmlElement *timeInt =
1993 conditions->FirstChildElement(
"TIMEINTEGRATIONSCHEME");
2001 TiXmlElement *method = timeInt->FirstChildElement(
"METHOD");
2002 TiXmlElement *variant = timeInt->FirstChildElement(
"VARIANT");
2003 TiXmlElement *order = timeInt->FirstChildElement(
"ORDER");
2004 TiXmlElement *params = timeInt->FirstChildElement(
"FREEPARAMETERS");
2007 ASSERTL0(method,
"Missing METHOD tag inside "
2008 "TIMEINTEGRATIONSCHEME.");
2009 ASSERTL0(order,
"Missing ORDER tag inside "
2010 "TIMEINTEGRATIONSCHEME.");
2014 std::string orderStr = order->GetText();
2018 "Empty text inside METHOD tag in TIMEINTEGRATIONSCHEME.");
2020 "Empty text inside ORDER tag in TIMEINTEGRATIONSCHEME.");
2029 orderStr +
"' to an unsigned integer.");
2039 std::string paramsStr = params->GetText();
2041 "Empty text inside FREEPARAMETERS tag in "
2042 "TIMEINTEGRATIONSCHEME.");
2044 std::vector<std::string> pSplit;
2045 boost::split(pSplit, paramsStr, boost::is_any_of(
" "));
2048 for (
size_t i = 0; i < pSplit.size(); ++i)
2057 "unable to convert string '" +
2060 "to a floating-point value.");
2067 if (
m_comm->GetRank() == 0)
2069 cout <<
"Trying to use time integration scheme:" << endl;
2076 cout <<
"\t Params :";
2099 TiXmlElement *variablesElement = conditions->FirstChildElement(
"VARIABLES");
2104 if (variablesElement)
2106 TiXmlElement *varElement = variablesElement->FirstChildElement(
"V");
2109 int nextVariableNumber = -1;
2113 stringstream tagcontent;
2114 tagcontent << *varElement;
2118 nextVariableNumber++;
2121 int err = varElement->QueryIntAttribute(
"ID", &i);
2123 "Variables must have a unique ID number attribute "
2124 "in XML element: \n\t'" +
2125 tagcontent.str() +
"'");
2127 "ID numbers for variables must begin with zero and"
2128 " be sequential in XML element: \n\t'" +
2129 tagcontent.str() +
"'");
2131 TiXmlNode *varChild = varElement->FirstChild();
2136 while (varChild && varChild->Type() != TiXmlNode::TINYXML_TEXT)
2138 varChild = varChild->NextSibling();
2141 ASSERTL0(varChild,
"Unable to read variable definition body for "
2142 "variable with ID " +
2143 boost::lexical_cast<string>(i) +
2144 " in XML element: \n\t'" + tagcontent.str() +
2146 std::string variableName = varChild->ToText()->ValueStr();
2148 std::istringstream variableStrm(variableName);
2149 variableStrm >> variableName;
2153 "Variable with ID " + boost::lexical_cast<string>(i) +
2154 " in XML element \n\t'" + tagcontent.str() +
2155 "'\nhas already been defined.");
2159 varElement = varElement->NextSiblingElement(
"V");
2163 "Number of variables must be greater than zero.");
2180 TiXmlElement *function = conditions->FirstChildElement(
"FUNCTION");
2184 stringstream tagcontent;
2185 tagcontent << *function;
2188 ASSERTL0(function->Attribute(
"NAME"),
2189 "Functions must have a NAME attribute defined in XML "
2191 tagcontent.str() +
"'");
2192 std::string functionStr = function->Attribute(
"NAME");
2194 "Functions must have a non-empty name in XML "
2196 tagcontent.str() +
"'");
2199 boost::to_upper(functionStr);
2202 TiXmlElement *element = function;
2204 TiXmlElement *variable = element->FirstChildElement();
2213 std::string conditionType = variable->Value();
2216 std::string variableStr;
2217 if (!variable->Attribute(
"VAR"))
2223 variableStr = variable->Attribute(
"VAR");
2227 std::vector<std::string> variableList;
2231 std::string domainStr;
2232 if (!variable->Attribute(
"DOMAIN"))
2238 domainStr = variable->Attribute(
"DOMAIN");
2242 std::vector<std::string> varSplit;
2243 std::vector<unsigned int> domainList;
2247 std::string evarsStr =
"x y z t";
2248 if (variable->Attribute(
"EVARS"))
2251 evarsStr + std::string(
" ") + variable->Attribute(
"EVARS");
2255 if (conditionType ==
"E")
2260 ASSERTL0(variable->Attribute(
"VALUE"),
2261 "Attribute VALUE expected for function '" +
2262 functionStr +
"'.");
2263 std::string fcnStr = variable->Attribute(
"VALUE");
2265 (std::string(
"Expression for var: ") + variableStr +
2266 std::string(
" must be specified."))
2276 else if (conditionType ==
"F")
2279 if (variable->Attribute(
"TIMEDEPENDENT") &&
2280 boost::lexical_cast<bool>(
2281 variable->Attribute(
"TIMEDEPENDENT")))
2291 ASSERTL0(variable->Attribute(
"FILE"),
2292 "Attribute FILE expected for function '" +
2293 functionStr +
"'.");
2294 std::string filenameStr = variable->Attribute(
"FILE");
2296 "A filename must be specified for the FILE "
2297 "attribute of function '" +
2298 functionStr +
"'.");
2300 std::vector<std::string> fSplit;
2301 boost::split(fSplit, filenameStr, boost::is_any_of(
":"));
2302 ASSERTL0(fSplit.size() == 1 || fSplit.size() == 2,
2303 "Incorrect filename specification in function " +
2306 "Specify variables inside file as: "
2307 "filename:var1,var2");
2310 fs::path fullpath = fSplit[0];
2311 fs::path ftype = fullpath.extension();
2312 if (fullpath.parent_path().extension() ==
".pit")
2314 string filename = fullpath.stem().string();
2315 fullpath = fullpath.parent_path();
2316 size_t start = filename.find_last_of(
"_") + 1;
2318 atoi(filename.substr(start, filename.size()).c_str());
2319 fullpath /= filename.substr(0, start) +
2321 index +
m_comm->GetTimeComm()->GetRank()) +
2326 if (fSplit.size() == 2)
2329 "Filename variable mapping not valid "
2330 "when using * as a variable inside "
2332 functionStr +
"'.");
2334 boost::split(varSplit, fSplit[1], boost::is_any_of(
","));
2335 ASSERTL0(varSplit.size() == variableList.size(),
2336 "Filename variables should contain the "
2337 "same number of variables defined in "
2338 "VAR in function " +
2339 functionStr +
"'.");
2346 stringstream tagcontent;
2347 tagcontent << *variable;
2350 "Identifier " + conditionType +
" in function " +
2351 std::string(function->Attribute(
"NAME")) +
2352 " is not recognised in XML element: \n\t'" +
2353 tagcontent.str() +
"'");
2357 for (
unsigned int i = 0; i < variableList.size(); ++i)
2359 for (
unsigned int j = 0; j < domainList.size(); ++j)
2362 pair<std::string, int> key(variableList[i], domainList[j]);
2363 auto fcnsIter = functionVarMap.find(key);
2364 ASSERTL0(fcnsIter == functionVarMap.end(),
2365 "Error setting expression '" + variableList[i] +
2366 " in domain " + std::to_string(domainList[j]) +
2367 "' in function '" + functionStr +
2369 "Expression has already been defined.");
2371 if (varSplit.size() > 0)
2375 functionVarMap[key] = funcDef2;
2379 functionVarMap[key] = funcDef;
2383 variable = variable->NextSiblingElement();
2388 function = function->NextSiblingElement(
"FUNCTION");
2404 TiXmlElement *filter = filters->FirstChildElement(
"FILTER");
2408 ASSERTL0(filter->Attribute(
"TYPE"),
2409 "Missing attribute 'TYPE' for filter.");
2410 std::string typeStr = filter->Attribute(
"TYPE");
2412 std::map<std::string, std::string> vParams;
2414 TiXmlElement *element = filter;
2416 TiXmlElement *param = element->FirstChildElement(
"PARAM");
2420 "Missing attribute 'NAME' for parameter in filter " +
2422 std::string nameStr = param->Attribute(
"NAME");
2424 ASSERTL0(param->GetText(),
"Empty value string for param.");
2425 std::string valueStr = param->GetText();
2427 vParams[nameStr] = valueStr;
2429 param = param->NextSiblingElement(
"PARAM");
2433 std::pair<std::string, FilterParams>(typeStr, vParams));
2435 filter = filter->NextSiblingElement(
"FILTER");
2446 size_t beg = line.find_first_not_of(
" ");
2447 size_t end = line.find_first_of(
"=");
2454 if (end != line.find_last_of(
"="))
2459 if (end == std::string::npos)
2464 lhs = line.substr(line.find_first_not_of(
" "), end - beg);
2465 lhs = lhs.substr(0, lhs.find_last_not_of(
" ") + 1);
2466 rhs = line.substr(line.find_last_of(
"=") + 1);
2467 rhs = rhs.substr(rhs.find_first_not_of(
" "));
2468 rhs = rhs.substr(0, rhs.find_last_not_of(
" ") + 1);
2479 std::vector<std::string> solverInfoList =
2482 for (
size_t i = 0; i < solverInfoList.size(); ++i)
2484 std::string lhs, rhs;
2497 std::string lhsUpper = boost::to_upper_copy(lhs);
2504 std::vector<std::string> parametersList =
2507 for (
size_t i = 0; i < parametersList.size(); ++i)
2509 std::string lhs, rhs;
2522 std::string lhsUpper = boost::to_upper_copy(lhs);
2531 "to double value.");
2544 std::string solverProperty = x.first;
2545 std::string solverValue = x.second;
2550 auto valIt = propIt->second.find(solverValue);
2551 ASSERTL0(valIt != propIt->second.end(),
"Value '" + solverValue +
2552 "' is not valid for "
2554 solverProperty +
"'");
2572 std::string elementName,
2573 const TiXmlHandle &docHandle)
2575 TiXmlElement *element = docHandle.FirstChildElement(elementName).Element();
2580 "' 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< std::pair< std::string, FilterParams > > 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