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)
2053 boost::lexical_cast<NekDouble>(pSplit[i]);
2058 "unable to convert string '" +
2061 "to a floating-point value.");
2068 if (
m_comm->GetRank() == 0)
2070 cout <<
"Trying to use time integration scheme:" << endl;
2077 cout <<
"\t Params :";
2100 TiXmlElement *variablesElement = conditions->FirstChildElement(
"VARIABLES");
2105 if (variablesElement)
2107 TiXmlElement *varElement = variablesElement->FirstChildElement(
"V");
2110 int nextVariableNumber = -1;
2114 stringstream tagcontent;
2115 tagcontent << *varElement;
2119 nextVariableNumber++;
2122 int err = varElement->QueryIntAttribute(
"ID", &i);
2124 "Variables must have a unique ID number attribute "
2125 "in XML element: \n\t'" +
2126 tagcontent.str() +
"'");
2128 "ID numbers for variables must begin with zero and"
2129 " be sequential in XML element: \n\t'" +
2130 tagcontent.str() +
"'");
2132 TiXmlNode *varChild = varElement->FirstChild();
2137 while (varChild && varChild->Type() != TiXmlNode::TINYXML_TEXT)
2139 varChild = varChild->NextSibling();
2142 ASSERTL0(varChild,
"Unable to read variable definition body for "
2143 "variable with ID " +
2144 boost::lexical_cast<string>(i) +
2145 " in XML element: \n\t'" + tagcontent.str() +
2147 std::string variableName = varChild->ToText()->ValueStr();
2149 std::istringstream variableStrm(variableName);
2150 variableStrm >> variableName;
2154 "Variable with ID " + boost::lexical_cast<string>(i) +
2155 " in XML element \n\t'" + tagcontent.str() +
2156 "'\nhas already been defined.");
2160 varElement = varElement->NextSiblingElement(
"V");
2164 "Number of variables must be greater than zero.");
2181 TiXmlElement *function = conditions->FirstChildElement(
"FUNCTION");
2185 stringstream tagcontent;
2186 tagcontent << *function;
2189 ASSERTL0(function->Attribute(
"NAME"),
2190 "Functions must have a NAME attribute defined in XML "
2192 tagcontent.str() +
"'");
2193 std::string functionStr = function->Attribute(
"NAME");
2195 "Functions must have a non-empty name in XML "
2197 tagcontent.str() +
"'");
2200 boost::to_upper(functionStr);
2203 TiXmlElement *element = function;
2205 TiXmlElement *variable = element->FirstChildElement();
2214 std::string conditionType = variable->Value();
2217 std::string variableStr;
2218 if (!variable->Attribute(
"VAR"))
2224 variableStr = variable->Attribute(
"VAR");
2228 std::vector<std::string> variableList;
2232 std::string domainStr;
2233 if (!variable->Attribute(
"DOMAIN"))
2239 domainStr = variable->Attribute(
"DOMAIN");
2243 std::vector<std::string> varSplit;
2244 std::vector<unsigned int> domainList;
2248 std::string evarsStr =
"x y z t";
2249 if (variable->Attribute(
"EVARS"))
2252 evarsStr + std::string(
" ") + variable->Attribute(
"EVARS");
2256 if (conditionType ==
"E")
2261 ASSERTL0(variable->Attribute(
"VALUE"),
2262 "Attribute VALUE expected for function '" +
2263 functionStr +
"'.");
2264 std::string fcnStr = variable->Attribute(
"VALUE");
2266 (std::string(
"Expression for var: ") + variableStr +
2267 std::string(
" must be specified."))
2277 else if (conditionType ==
"F")
2280 if (variable->Attribute(
"TIMEDEPENDENT") &&
2281 boost::lexical_cast<bool>(
2282 variable->Attribute(
"TIMEDEPENDENT")))
2292 ASSERTL0(variable->Attribute(
"FILE"),
2293 "Attribute FILE expected for function '" +
2294 functionStr +
"'.");
2295 std::string filenameStr = variable->Attribute(
"FILE");
2297 "A filename must be specified for the FILE "
2298 "attribute of function '" +
2299 functionStr +
"'.");
2301 std::vector<std::string> fSplit;
2302 boost::split(fSplit, filenameStr, boost::is_any_of(
":"));
2303 ASSERTL0(fSplit.size() == 1 || fSplit.size() == 2,
2304 "Incorrect filename specification in function " +
2307 "Specify variables inside file as: "
2308 "filename:var1,var2");
2311 fs::path fullpath = fSplit[0];
2312 fs::path ftype = fullpath.extension();
2313 if (fullpath.parent_path().extension() ==
".pit")
2315 string filename = fullpath.stem().string();
2316 fullpath = fullpath.parent_path();
2317 size_t start = filename.find_last_of(
"_") + 1;
2319 atoi(filename.substr(start, filename.size()).c_str());
2320 fullpath /= filename.substr(0, start) +
2322 index +
m_comm->GetTimeComm()->GetRank()) +
2327 if (fSplit.size() == 2)
2330 "Filename variable mapping not valid "
2331 "when using * as a variable inside "
2333 functionStr +
"'.");
2335 boost::split(varSplit, fSplit[1], boost::is_any_of(
","));
2336 ASSERTL0(varSplit.size() == variableList.size(),
2337 "Filename variables should contain the "
2338 "same number of variables defined in "
2339 "VAR in function " +
2340 functionStr +
"'.");
2347 stringstream tagcontent;
2348 tagcontent << *variable;
2351 "Identifier " + conditionType +
" in function " +
2352 std::string(function->Attribute(
"NAME")) +
2353 " is not recognised in XML element: \n\t'" +
2354 tagcontent.str() +
"'");
2358 for (
unsigned int i = 0; i < variableList.size(); ++i)
2360 for (
unsigned int j = 0; j < domainList.size(); ++j)
2363 pair<std::string, int> key(variableList[i], domainList[j]);
2364 auto fcnsIter = functionVarMap.find(key);
2365 ASSERTL0(fcnsIter == functionVarMap.end(),
2366 "Error setting expression '" + variableList[i] +
2367 " in domain " + std::to_string(domainList[j]) +
2368 "' in function '" + functionStr +
2370 "Expression has already been defined.");
2372 if (varSplit.size() > 0)
2376 functionVarMap[key] = funcDef2;
2380 functionVarMap[key] = funcDef;
2384 variable = variable->NextSiblingElement();
2389 function = function->NextSiblingElement(
"FUNCTION");
2405 TiXmlElement *filter = filters->FirstChildElement(
"FILTER");
2409 ASSERTL0(filter->Attribute(
"TYPE"),
2410 "Missing attribute 'TYPE' for filter.");
2411 std::string typeStr = filter->Attribute(
"TYPE");
2413 std::map<std::string, std::string> vParams;
2415 TiXmlElement *element = filter;
2417 TiXmlElement *param = element->FirstChildElement(
"PARAM");
2421 "Missing attribute 'NAME' for parameter in filter " +
2423 std::string nameStr = param->Attribute(
"NAME");
2425 ASSERTL0(param->GetText(),
"Empty value string for param.");
2426 std::string valueStr = param->GetText();
2428 vParams[nameStr] = valueStr;
2430 param = param->NextSiblingElement(
"PARAM");
2434 std::pair<std::string, FilterParams>(typeStr, vParams));
2436 filter = filter->NextSiblingElement(
"FILTER");
2447 size_t beg = line.find_first_not_of(
" ");
2448 size_t end = line.find_first_of(
"=");
2455 if (end != line.find_last_of(
"="))
2460 if (end == std::string::npos)
2465 lhs = line.substr(line.find_first_not_of(
" "), end - beg);
2466 lhs = lhs.substr(0, lhs.find_last_not_of(
" ") + 1);
2467 rhs = line.substr(line.find_last_of(
"=") + 1);
2468 rhs = rhs.substr(rhs.find_first_not_of(
" "));
2469 rhs = rhs.substr(0, rhs.find_last_not_of(
" ") + 1);
2480 std::vector<std::string> solverInfoList =
2483 for (
size_t i = 0; i < solverInfoList.size(); ++i)
2485 std::string lhs, rhs;
2498 std::string lhsUpper = boost::to_upper_copy(lhs);
2505 std::vector<std::string> parametersList =
2508 for (
size_t i = 0; i < parametersList.size(); ++i)
2510 std::string lhs, rhs;
2523 std::string lhsUpper = boost::to_upper_copy(lhs);
2527 m_parameters[lhsUpper] = boost::lexical_cast<NekDouble>(rhs);
2532 "to double value.");
2545 std::string solverProperty = x.first;
2546 std::string solverValue = x.second;
2551 auto valIt = propIt->second.find(solverValue);
2552 ASSERTL0(valIt != propIt->second.end(),
"Value '" + solverValue +
2553 "' is not valid for "
2555 solverProperty +
"'");
2573 std::string elementName,
2574 const TiXmlHandle &docHandle)
2576 TiXmlElement *element = docHandle.FirstChildElement(elementName).Element();
2581 "' 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