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 (
"verbose,v",
"be verbose")
449 (
"version,V",
"print version information")
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 (
"npx", po::value<int>(),
456 "number of procs in X-dir")
457 (
"npy", po::value<int>(),
458 "number of procs in Y-dir")
459 (
"npz", po::value<int>(),
460 "number of procs in Z-dir")
461 (
"nsz", po::value<int>(),
462 "number of slices in Z-dir")
463 (
"npt", po::value<int>(),
464 "number of procs in T-dir (parareal)")
465 (
"part-only", po::value<int>(),
466 "only partition mesh into N partitions.")
467 (
"part-only-overlapping", po::value<int>(),
468 "only partition mesh into N overlapping partitions.")
469 (
"part-info",
"output partition information")
470 (
"force-output,f",
"disables backups files and forces output to be "
471 "written without any checks")
472 (
"write-opt-file",
"write an optimisation file")
473 (
"use-opt-file", po::value<std::string>(),
474 "use an optimisation file");
477#ifdef NEKTAR_USE_CWIPI
478 desc.add_options()(
"cwipi", po::value<std::string>(),
"set CWIPI name");
483 std::string names = cmdIt.first;
484 if (cmdIt.second.shortName !=
"")
486 names +=
"," + cmdIt.second.shortName;
488 if (cmdIt.second.isFlag)
490 desc.add_options()(names.c_str(), cmdIt.second.description.c_str());
494 desc.add_options()(names.c_str(), po::value<std::string>(),
495 cmdIt.second.description.c_str());
501 std::map<std::string, std::string> deprecated = {
502 {
"forceoutput",
"force-output"},
503 {
"writeoptfile",
"write-opt-file"},
504 {
"useoptfile",
"use-opt-file"}};
506 for (
auto &
d : deprecated)
508 std::string
description =
"Deprecated: use --" +
d.second;
509 dep.add_options()(
d.first.c_str(),
description.c_str());
514 po::options_description hidden(
"Hidden options");
516 hidden.add_options()(
"input-file", po::value<vector<string>>(),
520 po::options_description all(
"All options");
521 all.add(desc).add(dep).add(hidden);
524 po::positional_options_description
p;
525 p.add(
"input-file", -1);
528 po::parsed_options parsed = po::command_line_parser(argc, argv)
531 .allow_unregistered()
554 boost::replace_all(branch,
"refs/heads/",
"");
556 cout <<
" (git changeset " <<
sha1.substr(0, 8) <<
", ";
560 cout <<
"detached head";
564 cout <<
"head " << branch;
575 for (
auto &
d : deprecated)
579 std::cerr <<
"Warning: --" <<
d.first <<
" deprecated: use --"
580 <<
d.second << std::endl;
617 for (
auto &x : parsed.options)
621 cout <<
"Warning: Unknown option: " << x.string_key << endl;
632 return std::vector<std::string>();
641 ASSERTL0(!filenames.empty(),
"At least one filename expected.");
643 std::string retval =
"";
646 std::string fname = filenames[0];
649 if (fname.size() > 4 && fname.substr(fname.size() - 4, 4) ==
"_xml")
651 retval = fname.substr(0, fname.find_last_of(
"_"));
654 else if (fname.size() > 4 && fname.substr(fname.size() - 4, 4) ==
".xml")
656 retval = fname.substr(0, fname.find_last_of(
"."));
659 else if (fname.size() > 7 && fname.substr(fname.size() - 7, 7) ==
".xml.gz")
661 retval = fname.substr(0, fname.find_last_of(
"."));
662 retval = retval.substr(0, retval.find_last_of(
"."));
701 std::string vPath = boost::to_upper_copy(pPath);
702 std::vector<std::string> st;
703 boost::split(st, vPath, boost::is_any_of(
"\\/ "));
704 ASSERTL0(st.size() > 0,
"No path given in XML element request.");
706 TiXmlElement *vReturn =
m_xmlDoc->FirstChildElement(st[0].c_str());
708 std::string(
"Cannot find element '") + st[0] + std::string(
"'."));
709 for (
int i = 1; i < st.size(); ++i)
711 vReturn = vReturn->FirstChildElement(st[i].c_str());
712 ASSERTL0(vReturn, std::string(
"Cannot find element '") + st[i] +
723 std::string vPath = boost::to_upper_copy(pPath);
724 std::vector<std::string> st;
725 boost::split(st, vPath, boost::is_any_of(
"\\/ "));
726 ASSERTL0(st.size() > 0,
"No path given in XML element request.");
728 TiXmlElement *vReturn =
m_xmlDoc->FirstChildElement(st[0].c_str());
730 std::string(
"Cannot find element '") + st[0] + std::string(
"'."));
731 for (
int i = 1; i < st.size(); ++i)
733 vReturn = vReturn->FirstChildElement(st[i].c_str());
787 std::string vName = boost::to_upper_copy(pName);
801 std::string vName = boost::to_upper_copy(pName);
805 "Unable to find requested parameter: " + pName);
807 return paramIter->second;
815 std::string vName = boost::to_upper_copy(pName);
818 "Required parameter '" + pName +
"' not specified in session.");
819 NekDouble param = round(paramIter->second);
820 pVar = checked_cast<int>(param);
827 const int &pDefault)
const
829 std::string vName = boost::to_upper_copy(pName);
833 NekDouble param = round(paramIter->second);
834 pVar = checked_cast<int>(param);
847 std::string vName = boost::to_upper_copy(pName);
850 "Required parameter '" + pName +
"' not specified in session.");
851 NekDouble param = round(paramIter->second);
852 pVar = checked_cast<int>(param);
859 const size_t &pDefault)
const
861 std::string vName = boost::to_upper_copy(pName);
865 NekDouble param = round(paramIter->second);
866 pVar = checked_cast<int>(param);
880 std::string vName = boost::to_upper_copy(pName);
883 "Required parameter '" + pName +
"' not specified in session.");
884 pVar = paramIter->second;
893 std::string vName = boost::to_upper_copy(pName);
897 pVar = paramIter->second;
910 std::string vName = boost::to_upper_copy(pName);
919 std::string vName = boost::to_upper_copy(pName);
928 std::string vName = boost::to_upper_copy(pName);
937 std::string vName = boost::to_upper_copy(pName);
946 const std::string &pProperty)
const
948 std::string vProperty = boost::to_upper_copy(pProperty);
952 "Unable to find requested property: " + pProperty);
961 const std::string &pValue)
963 std::string vProperty = boost::to_upper_copy(pProperty);
967 "Unable to find requested property: " + pProperty);
969 iter->second = pValue;
976 const std::string &pDefault)
const
978 std::string vName = boost::to_upper_copy(pName);
982 pVar = infoIter->second;
994 const std::string &pTrueVal,
bool &pVar,
995 const bool &pDefault)
const
997 std::string vName = boost::to_upper_copy(pName);
1001 pVar = boost::iequals(infoIter->second, pTrueVal);
1013 const std::string &pTrueVal)
const
1017 std::string vName = boost::to_upper_copy(pName);
1021 return boost::iequals(iter->second, pTrueVal);
1031 const std::string &pProperty)
const
1039 std::string vProperty = boost::to_upper_copy(pProperty);
1041 auto iter1 = iter->second.find(vProperty);
1042 if (iter1 == iter->second.end())
1054 const std::string &pVariable,
const std::string &pProperty)
const
1058 "Failed to find variable in GlobalSysSolnInfoList");
1060 std::string vProperty = boost::to_upper_copy(pProperty);
1061 auto iter1 = iter->second.find(vProperty);
1063 ASSERTL0(iter1 != iter->second.end(),
1064 "Failed to find property: " + vProperty +
1065 " in GlobalSysSolnInfoList");
1067 return iter1->second;
1093 TiXmlElement *xmlGeom =
1094 m_xmlDoc->FirstChildElement(
"NEKTAR")->FirstChildElement(
"GEOMETRY");
1095 ASSERTL1(xmlGeom,
"Failed to find a GEOMETRY section in m_xmlDoc");
1097 TiXmlAttribute *attr = xmlGeom->FirstAttribute();
1100 std::string attrName(attr->Name());
1101 if (attrName ==
"HDF5FILE")
1107 attr = attr->Next();
1112 TiXmlElement *element = xmlGeom->FirstChildElement(
"VERTEX");
1113 string IsCompressed;
1114 element->QueryStringAttribute(
"COMPRESSED", &IsCompressed);
1116 if (IsCompressed.size() > 0)
1118 return "XmlCompressed";
1164 std::string vName = boost::to_upper_copy(pName);
1172 const std::string &pVariable,
1173 const int pDomain)
const
1175 std::string vName = boost::to_upper_copy(pName);
1181 pair<std::string, int> key(pVariable, pDomain);
1182 pair<std::string, int> defkey(
"*", pDomain);
1183 bool varExists = it1->second.find(key) != it1->second.end() ||
1184 it1->second.find(defkey) != it1->second.end();
1194 const std::string &pVariable,
1195 const int pDomain)
const
1197 std::string vName = boost::to_upper_copy(pName);
1201 std::string(
"No such function '") + pName +
1202 std::string(
"' has been defined in the session file."));
1205 pair<std::string, int> key(pVariable, pDomain);
1206 pair<std::string, int> defkey(
"*", pDomain);
1208 auto it2 = it1->second.find(key);
1209 auto it3 = it1->second.find(defkey);
1210 bool specific = it2 != it1->second.end();
1211 bool wildcard = it3 != it1->second.end();
1215 "No such variable " + pVariable +
" in domain " +
1216 boost::lexical_cast<string>(pDomain) +
1217 " defined for function " + pName +
" in session file.");
1226 std::string(
"Function is defined by a file."));
1227 return it2->second.m_expression;
1234 const unsigned int &pVar,
1235 const int pDomain)
const
1245 const std::string &pVariable,
1246 const int pDomain)
const
1248 std::string vName = boost::to_upper_copy(pName);
1252 std::string(
"Function '") + pName + std::string(
"' not found."));
1255 pair<std::string, int> key(pVariable, pDomain);
1256 pair<std::string, int> defkey(
"*", pDomain);
1258 auto it2 = it1->second.find(key);
1259 auto it3 = it1->second.find(defkey);
1260 bool specific = it2 != it1->second.end();
1261 bool wildcard = it3 != it1->second.end();
1265 "No such variable " + pVariable +
" in domain " +
1266 boost::lexical_cast<string>(pDomain) +
1267 " defined for function " + pName +
" in session file.");
1275 return it2->second.m_type;
1282 const unsigned int &pVar,
1283 const int pDomain)
const
1293 const std::string &pVariable,
1294 const int pDomain)
const
1296 std::string vName = boost::to_upper_copy(pName);
1300 std::string(
"Function '") + pName + std::string(
"' not found."));
1303 pair<std::string, int> key(pVariable, pDomain);
1304 pair<std::string, int> defkey(
"*", pDomain);
1306 auto it2 = it1->second.find(key);
1307 auto it3 = it1->second.find(defkey);
1308 bool specific = it2 != it1->second.end();
1309 bool wildcard = it3 != it1->second.end();
1313 "No such variable " + pVariable +
" in domain " +
1314 boost::lexical_cast<string>(pDomain) +
1315 " defined for function " + pName +
" in session file.");
1323 return it2->second.m_filename;
1330 const unsigned int &pVar,
1331 const int pDomain)
const
1341 const std::string &pName,
const std::string &pVariable,
1342 const int pDomain)
const
1344 std::string vName = boost::to_upper_copy(pName);
1348 std::string(
"Function '") + pName + std::string(
"' not found."));
1351 pair<std::string, int> key(pVariable, pDomain);
1352 pair<std::string, int> defkey(
"*", pDomain);
1354 auto it2 = it1->second.find(key);
1355 auto it3 = it1->second.find(defkey);
1356 bool specific = it2 != it1->second.end();
1357 bool wildcard = it3 != it1->second.end();
1361 "No such variable " + pVariable +
" in domain " +
1362 boost::lexical_cast<string>(pDomain) +
1363 " defined for function " + pName +
" in session file.");
1371 return it2->second.m_fileVariable;
1379 std::string vName = boost::to_upper_copy(pName);
1388 std::string vName = boost::to_upper_copy(pName);
1397 std::string vName = boost::to_upper_copy(pName);
1398 auto vTagIterator =
m_tags.find(vName);
1399 ASSERTL0(vTagIterator !=
m_tags.end(),
"Requested tag does not exist.");
1400 return vTagIterator->second;
1423 const size_t timeLevel,
1424 const bool enableCheck)
1426 if (Element && Element->FirstChildElement(
"TIMELEVEL"))
1428 Element = Element->FirstChildElement(
"TIMELEVEL");
1429 std::string timeLevelStr;
1432 std::stringstream tagcontent;
1433 tagcontent << *Element;
1434 ASSERTL0(Element->Attribute(
"VALUE"),
1435 "Missing LEVEL attribute in solver info "
1436 "XML element: \n\t'" +
1437 tagcontent.str() +
"'");
1438 timeLevelStr = Element->Attribute(
"VALUE");
1440 "LEVEL attribute must be non-empty in XML "
1442 tagcontent.str() +
"'");
1443 if (stoi(timeLevelStr) == timeLevel)
1447 Element = Element->NextSiblingElement(
"TIMELEVEL");
1451 ASSERTL0(stoi(timeLevelStr) == timeLevel,
1452 "TIMELEVEL value " + std::to_string(timeLevel) +
1453 " not found in solver info "
1454 "XML element: \n\t'");
1463 TiXmlDocument *pDoc)
const
1465 if (pFilename.size() > 3 &&
1466 pFilename.substr(pFilename.size() - 3, 3) ==
".gz")
1468 ifstream file(pFilename.c_str(), ios_base::in | ios_base::binary);
1469 ASSERTL0(file.good(),
"Unable to open file: " + pFilename);
1471 io::filtering_streambuf<io::input> in;
1472 in.push(io::gzip_decompressor());
1479 catch (io::gzip_error &)
1482 "Error: File '" + pFilename +
"' is corrupt.");
1485 else if (pFilename.size() > 4 &&
1486 pFilename.substr(pFilename.size() - 4, 4) ==
"_xml")
1488 fs::path pdirname(pFilename);
1490 pad %
m_comm->GetSpaceComm()->GetRank();
1491 fs::path pRankFilename(pad.str());
1492 fs::path fullpath = pdirname / pRankFilename;
1495 ASSERTL0(file.good(),
"Unable to open file: " + fullpath.string());
1500 ifstream file(pFilename.c_str());
1501 ASSERTL0(file.good(),
"Unable to open file: " + pFilename);
1510 const std::vector<std::string> &pFilenames)
const
1512 ASSERTL0(pFilenames.size() > 0,
"No filenames for merging.");
1515 TiXmlDocument *vMainDoc =
new TiXmlDocument;
1516 LoadDoc(pFilenames[0], vMainDoc);
1518 TiXmlHandle vMainHandle(vMainDoc);
1519 TiXmlElement *vMainNektar =
1525 for (
int i = 1; i < pFilenames.size(); ++i)
1527 if ((pFilenames[i].compare(pFilenames[i].size() - 3, 3,
"xml") == 0) ||
1528 (pFilenames[i].compare(pFilenames[i].size() - 6, 6,
"xml.gz") ==
1530 (pFilenames[i].compare(pFilenames[i].size() - 3, 3,
"opt") == 0))
1532 TiXmlDocument *vTempDoc =
new TiXmlDocument;
1533 LoadDoc(pFilenames[i], vTempDoc);
1535 TiXmlHandle docHandle(vTempDoc);
1536 TiXmlElement *vTempNektar =
1538 TiXmlElement *
p = vTempNektar->FirstChildElement();
1542 TiXmlElement *vMainEntry =
1543 vMainNektar->FirstChildElement(
p->Value());
1547 if (!
p->FirstChild() && vMainEntry &&
1548 !boost::iequals(
p->Value(),
"COLLECTIONS"))
1550 std::string warningmsg =
1551 "File " + pFilenames[i] +
" contains " +
1552 "an empty XML element " + std::string(
p->Value()) +
1553 " which will be ignored.";
1560 vMainNektar->RemoveChild(vMainEntry);
1562 TiXmlElement *
q =
new TiXmlElement(*
p);
1563 vMainNektar->LinkEndChild(
q);
1565 p =
p->NextSiblingElement();
1585 e = docHandle.FirstChildElement(
"NEKTAR")
1586 .FirstChildElement(
"CONDITIONS")
1598 e = docHandle.FirstChildElement(
"NEKTAR")
1599 .FirstChildElement(
"FILTERS")
1617 string vCommModule(
"Serial");
1620 vCommModule =
"ParallelMPI";
1625 vCommModule =
"CWIPI";
1638 if (
m_comm->GetSize() > 1)
1647 nProcX = GetCmdLineArgument<int>(
"npx");
1651 nProcY = GetCmdLineArgument<int>(
"npy");
1655 nProcZ = GetCmdLineArgument<int>(
"npz");
1659 nStripZ = GetCmdLineArgument<int>(
"nsz");
1663 nTime = GetCmdLineArgument<int>(
"npt");
1666 "Cannot exactly partition time using npt value.");
1667 ASSERTL0((
m_comm->GetSize() / nTime) % (nProcZ * nProcY * nProcX) == 0,
1668 "Cannot exactly partition using PROC_Z value.");
1670 "Cannot exactly partition using PROC_Y value.");
1672 "Cannot exactly partition using PROC_X value.");
1675 int nProcSm = nProcZ * nProcY * nProcX;
1679 int nProcSem =
m_comm->GetSize() / nTime / nProcSm;
1681 m_comm->SplitComm(nProcSm, nProcSem, nTime);
1682 m_comm->GetColumnComm()->SplitComm(nProcZ / nStripZ, nStripZ);
1683 m_comm->GetColumnComm()->GetColumnComm()->SplitComm((nProcY * nProcX),
1685 m_comm->GetColumnComm()->GetColumnComm()->GetColumnComm()->SplitComm(
1702 TiXmlElement *parametersElement =
1703 conditions->FirstChildElement(
"PARAMETERS");
1708 if (parametersElement)
1710 TiXmlElement *parameter = parametersElement->FirstChildElement(
"P");
1718 stringstream tagcontent;
1719 tagcontent << *parameter;
1720 TiXmlNode *node = parameter->FirstChild();
1722 while (node && node->Type() != TiXmlNode::TINYXML_TEXT)
1724 node = node->NextSibling();
1730 std::string line = node->ToText()->Value(), lhs, rhs;
1739 "Syntax error in parameter expression '" + line +
1740 "' in XML element: \n\t'" + tagcontent.str() +
1747 if (!lhs.empty() && !rhs.empty())
1755 catch (
const std::runtime_error &)
1758 "Error evaluating parameter expression"
1760 rhs +
"' in XML element: \n\t'" +
1761 tagcontent.str() +
"'");
1764 caseSensitiveParameters[lhs] = value;
1765 boost::to_upper(lhs);
1769 parameter = parameter->NextSiblingElement();
1787 TiXmlElement *solverInfoElement =
1788 conditions->FirstChildElement(
"SOLVERINFO");
1791 if (solverInfoElement)
1793 TiXmlElement *solverInfo = solverInfoElement->FirstChildElement(
"I");
1797 std::stringstream tagcontent;
1798 tagcontent << *solverInfo;
1800 ASSERTL0(solverInfo->Attribute(
"PROPERTY"),
1801 "Missing PROPERTY attribute in solver info "
1802 "XML element: \n\t'" +
1803 tagcontent.str() +
"'");
1804 std::string solverProperty = solverInfo->Attribute(
"PROPERTY");
1806 "PROPERTY attribute must be non-empty in XML "
1808 tagcontent.str() +
"'");
1811 std::string solverPropertyUpper =
1812 boost::to_upper_copy(solverProperty);
1815 ASSERTL0(solverInfo->Attribute(
"VALUE"),
1816 "Missing VALUE attribute in solver info "
1817 "XML element: \n\t'" +
1818 tagcontent.str() +
"'");
1819 std::string solverValue = solverInfo->Attribute(
"VALUE");
1821 "VALUE attribute must be non-empty in XML "
1823 tagcontent.str() +
"'");
1827 solverInfo = solverInfo->NextSiblingElement(
"I");
1835 m_solverInfo[
"GLOBALSYSSOLN"] ==
"IterativeStaticCond" ||
1837 "IterativeMultiLevelStaticCond" ||
1840 m_solverInfo[
"GLOBALSYSSOLN"] ==
"XxtMultiLevelStaticCond" ||
1843 m_solverInfo[
"GLOBALSYSSOLN"] ==
"PETScMultiLevelStaticCond",
1844 "A parallel solver must be used when run in parallel.");
1860 TiXmlElement *GlobalSys =
1861 conditions->FirstChildElement(
"GLOBALSYSSOLNINFO");
1869 TiXmlElement *VarInfo = GlobalSys->FirstChildElement(
"V");
1873 std::stringstream tagcontent;
1874 tagcontent << *VarInfo;
1876 ASSERTL0(VarInfo->Attribute(
"VAR"),
1877 "Missing VAR attribute in GobalSysSolnInfo XML "
1879 tagcontent.str() +
"'");
1880 std::string VarList = VarInfo->Attribute(
"VAR");
1882 "VAR attribute must be non-empty in XML element:\n\t'" +
1883 tagcontent.str() +
"'");
1886 std::vector<std::string> varStrings;
1889 ASSERTL0(valid,
"Unable to process list of variable in XML "
1891 tagcontent.str() +
"'");
1893 if (varStrings.size())
1895 TiXmlElement *SysSolnInfo = VarInfo->FirstChildElement(
"I");
1900 tagcontent << *SysSolnInfo;
1902 ASSERTL0(SysSolnInfo->Attribute(
"PROPERTY"),
1903 "Missing PROPERTY attribute in "
1904 "GlobalSysSolnInfo for variable(s) '" +
1905 VarList +
"' in XML element: \n\t'" +
1906 tagcontent.str() +
"'");
1907 std::string SysSolnProperty =
1908 SysSolnInfo->Attribute(
"PROPERTY");
1910 "GlobalSysSolnIno properties must have a "
1911 "non-empty name for variable(s) : '" +
1912 VarList +
"' in XML element: \n\t'" +
1913 tagcontent.str() +
"'");
1916 std::string SysSolnPropertyUpper =
1917 boost::to_upper_copy(SysSolnProperty);
1920 ASSERTL0(SysSolnInfo->Attribute(
"VALUE"),
1921 "Missing VALUE attribute in GlobalSysSolnInfo "
1922 "for variable(s) '" +
1923 VarList +
"' in XML element: \n\t" +
1924 tagcontent.str() +
"'");
1925 std::string SysSolnValue = SysSolnInfo->Attribute(
"VALUE");
1927 "GlobalSysSolnInfo properties must have a "
1928 "non-empty value for variable(s) '" +
1929 VarList +
"' in XML element: \n\t'" +
1930 tagcontent.str() +
"'");
1933 for (
int i = 0; i < varStrings.size(); ++i)
1939 [SysSolnPropertyUpper] = SysSolnValue;
1943 x->second[SysSolnPropertyUpper] = SysSolnValue;
1946 SysSolnInfo = SysSolnInfo->NextSiblingElement(
"I");
1948 VarInfo = VarInfo->NextSiblingElement(
"V");
1954 if (
m_comm->GetRank() == 0)
1956 cout <<
"GlobalSysSoln Info:" << endl;
1960 cout <<
"\t Variable: " << x.first << endl;
1962 for (
auto &y : x.second)
1964 cout <<
"\t\t " << y.first <<
" = " << y.second << endl;
1982 TiXmlElement *timeInt =
1983 conditions->FirstChildElement(
"TIMEINTEGRATIONSCHEME");
1991 TiXmlElement *method = timeInt->FirstChildElement(
"METHOD");
1992 TiXmlElement *variant = timeInt->FirstChildElement(
"VARIANT");
1993 TiXmlElement *order = timeInt->FirstChildElement(
"ORDER");
1994 TiXmlElement *params = timeInt->FirstChildElement(
"FREEPARAMETERS");
1997 ASSERTL0(method,
"Missing METHOD tag inside "
1998 "TIMEINTEGRATIONSCHEME.");
1999 ASSERTL0(order,
"Missing ORDER tag inside "
2000 "TIMEINTEGRATIONSCHEME.");
2004 std::string orderStr = order->GetText();
2008 "Empty text inside METHOD tag in TIMEINTEGRATIONSCHEME.");
2010 "Empty text inside ORDER tag in TIMEINTEGRATIONSCHEME.");
2019 orderStr +
"' to an unsigned integer.");
2029 std::string paramsStr = params->GetText();
2031 "Empty text inside FREEPARAMETERS tag in "
2032 "TIMEINTEGRATIONSCHEME.");
2034 std::vector<std::string> pSplit;
2035 boost::split(pSplit, paramsStr, boost::is_any_of(
" "));
2038 for (
size_t i = 0; i < pSplit.size(); ++i)
2043 boost::lexical_cast<NekDouble>(pSplit[i]);
2048 "unable to convert string '" +
2051 "to a floating-point value.");
2058 if (
m_comm->GetRank() == 0)
2060 cout <<
"Trying to use time integration scheme:" << endl;
2067 cout <<
"\t Params :";
2090 TiXmlElement *variablesElement = conditions->FirstChildElement(
"VARIABLES");
2095 if (variablesElement)
2097 TiXmlElement *varElement = variablesElement->FirstChildElement(
"V");
2100 int nextVariableNumber = -1;
2104 stringstream tagcontent;
2105 tagcontent << *varElement;
2109 nextVariableNumber++;
2112 int err = varElement->QueryIntAttribute(
"ID", &i);
2114 "Variables must have a unique ID number attribute "
2115 "in XML element: \n\t'" +
2116 tagcontent.str() +
"'");
2118 "ID numbers for variables must begin with zero and"
2119 " be sequential in XML element: \n\t'" +
2120 tagcontent.str() +
"'");
2122 TiXmlNode *varChild = varElement->FirstChild();
2127 while (varChild && varChild->Type() != TiXmlNode::TINYXML_TEXT)
2129 varChild = varChild->NextSibling();
2132 ASSERTL0(varChild,
"Unable to read variable definition body for "
2133 "variable with ID " +
2134 boost::lexical_cast<string>(i) +
2135 " in XML element: \n\t'" + tagcontent.str() +
2137 std::string variableName = varChild->ToText()->ValueStr();
2139 std::istringstream variableStrm(variableName);
2140 variableStrm >> variableName;
2144 "Variable with ID " + boost::lexical_cast<string>(i) +
2145 " in XML element \n\t'" + tagcontent.str() +
2146 "'\nhas already been defined.");
2150 varElement = varElement->NextSiblingElement(
"V");
2154 "Number of variables must be greater than zero.");
2171 TiXmlElement *function = conditions->FirstChildElement(
"FUNCTION");
2175 stringstream tagcontent;
2176 tagcontent << *function;
2179 ASSERTL0(function->Attribute(
"NAME"),
2180 "Functions must have a NAME attribute defined in XML "
2182 tagcontent.str() +
"'");
2183 std::string functionStr = function->Attribute(
"NAME");
2185 "Functions must have a non-empty name in XML "
2187 tagcontent.str() +
"'");
2190 boost::to_upper(functionStr);
2193 TiXmlElement *element = function;
2195 TiXmlElement *variable = element->FirstChildElement();
2204 std::string conditionType = variable->Value();
2207 std::string variableStr;
2208 if (!variable->Attribute(
"VAR"))
2214 variableStr = variable->Attribute(
"VAR");
2218 std::vector<std::string> variableList;
2222 std::string domainStr;
2223 if (!variable->Attribute(
"DOMAIN"))
2229 domainStr = variable->Attribute(
"DOMAIN");
2233 std::vector<std::string> varSplit;
2234 std::vector<unsigned int> domainList;
2238 std::string evarsStr =
"x y z t";
2239 if (variable->Attribute(
"EVARS"))
2242 evarsStr + std::string(
" ") + variable->Attribute(
"EVARS");
2246 if (conditionType ==
"E")
2251 ASSERTL0(variable->Attribute(
"VALUE"),
2252 "Attribute VALUE expected for function '" +
2253 functionStr +
"'.");
2254 std::string fcnStr = variable->Attribute(
"VALUE");
2256 (std::string(
"Expression for var: ") + variableStr +
2257 std::string(
" must be specified."))
2267 else if (conditionType ==
"F")
2270 if (variable->Attribute(
"TIMEDEPENDENT") &&
2271 boost::lexical_cast<bool>(
2272 variable->Attribute(
"TIMEDEPENDENT")))
2282 ASSERTL0(variable->Attribute(
"FILE"),
2283 "Attribute FILE expected for function '" +
2284 functionStr +
"'.");
2285 std::string filenameStr = variable->Attribute(
"FILE");
2287 "A filename must be specified for the FILE "
2288 "attribute of function '" +
2289 functionStr +
"'.");
2291 std::vector<std::string> fSplit;
2292 boost::split(fSplit, filenameStr, boost::is_any_of(
":"));
2293 ASSERTL0(fSplit.size() == 1 || fSplit.size() == 2,
2294 "Incorrect filename specification in function " +
2297 "Specify variables inside file as: "
2298 "filename:var1,var2");
2301 fs::path fullpath = fSplit[0];
2302 fs::path ftype = fullpath.extension();
2303 if (fullpath.parent_path().extension() ==
".pit")
2305 string filename = fullpath.stem().string();
2306 fullpath = fullpath.parent_path();
2307 size_t start = filename.find_last_of(
"_") + 1;
2309 atoi(filename.substr(start, filename.size()).c_str());
2310 fullpath /= filename.substr(0, start) +
2312 index +
m_comm->GetTimeComm()->GetRank()) +
2317 if (fSplit.size() == 2)
2320 "Filename variable mapping not valid "
2321 "when using * as a variable inside "
2323 functionStr +
"'.");
2325 boost::split(varSplit, fSplit[1], boost::is_any_of(
","));
2326 ASSERTL0(varSplit.size() == variableList.size(),
2327 "Filename variables should contain the "
2328 "same number of variables defined in "
2329 "VAR in function " +
2330 functionStr +
"'.");
2337 stringstream tagcontent;
2338 tagcontent << *variable;
2341 "Identifier " + conditionType +
" in function " +
2342 std::string(function->Attribute(
"NAME")) +
2343 " is not recognised in XML element: \n\t'" +
2344 tagcontent.str() +
"'");
2348 for (
unsigned int i = 0; i < variableList.size(); ++i)
2350 for (
unsigned int j = 0; j < domainList.size(); ++j)
2353 pair<std::string, int> key(variableList[i], domainList[j]);
2354 auto fcnsIter = functionVarMap.find(key);
2355 ASSERTL0(fcnsIter == functionVarMap.end(),
2356 "Error setting expression '" + variableList[i] +
2357 " in domain " + std::to_string(domainList[j]) +
2358 "' in function '" + functionStr +
2360 "Expression has already been defined.");
2362 if (varSplit.size() > 0)
2366 functionVarMap[key] = funcDef2;
2370 functionVarMap[key] = funcDef;
2374 variable = variable->NextSiblingElement();
2379 function = function->NextSiblingElement(
"FUNCTION");
2395 TiXmlElement *filter = filters->FirstChildElement(
"FILTER");
2399 ASSERTL0(filter->Attribute(
"TYPE"),
2400 "Missing attribute 'TYPE' for filter.");
2401 std::string typeStr = filter->Attribute(
"TYPE");
2403 std::map<std::string, std::string> vParams;
2405 TiXmlElement *element = filter;
2407 TiXmlElement *param = element->FirstChildElement(
"PARAM");
2411 "Missing attribute 'NAME' for parameter in filter " +
2413 std::string nameStr = param->Attribute(
"NAME");
2415 ASSERTL0(param->GetText(),
"Empty value string for param.");
2416 std::string valueStr = param->GetText();
2418 vParams[nameStr] = valueStr;
2420 param = param->NextSiblingElement(
"PARAM");
2424 std::pair<std::string, FilterParams>(typeStr, vParams));
2426 filter = filter->NextSiblingElement(
"FILTER");
2437 size_t beg = line.find_first_not_of(
" ");
2438 size_t end = line.find_first_of(
"=");
2445 if (end != line.find_last_of(
"="))
2450 if (end == std::string::npos)
2455 lhs = line.substr(line.find_first_not_of(
" "), end - beg);
2456 lhs = lhs.substr(0, lhs.find_last_not_of(
" ") + 1);
2457 rhs = line.substr(line.find_last_of(
"=") + 1);
2458 rhs = rhs.substr(rhs.find_first_not_of(
" "));
2459 rhs = rhs.substr(0, rhs.find_last_not_of(
" ") + 1);
2470 std::vector<std::string> solverInfoList =
2473 for (
size_t i = 0; i < solverInfoList.size(); ++i)
2475 std::string lhs, rhs;
2488 std::string lhsUpper = boost::to_upper_copy(lhs);
2495 std::vector<std::string> parametersList =
2498 for (
size_t i = 0; i < parametersList.size(); ++i)
2500 std::string lhs, rhs;
2513 std::string lhsUpper = boost::to_upper_copy(lhs);
2517 m_parameters[lhsUpper] = boost::lexical_cast<NekDouble>(rhs);
2522 "to double value.");
2535 std::string solverProperty = x.first;
2536 std::string solverValue = x.second;
2541 auto valIt = propIt->second.find(solverValue);
2542 ASSERTL0(valIt != propIt->second.end(),
"Value '" + solverValue +
2543 "' is not valid for "
2545 solverProperty +
"'");
2563 std::string elementName,
2564 const TiXmlHandle &docHandle)
2566 TiXmlElement *element = docHandle.FirstChildElement(elementName).Element();
2571 "' 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.
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