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;
131 return solverInfoEnums;
145 return solverInfoMap;
160 return gloSysSolnInfoList;
174 return cmdLineArguments;
201 if (
m_comm->GetSize() > 1)
208 (
unsigned int)time(NULL));
218 const std::vector<std::string> &pFilenames,
221 ASSERTL0(pFilenames.size() > 0,
"No filenames specified.");
243 if (
m_comm->GetSize() > 1)
250 (
unsigned int)time(NULL));
279 if (filenames.size() > 0)
284 bool ParallelInTime =
294 exists = (bool)boost::filesystem::exists(optfile.c_str());
295 ASSERTL0(exists,
"A valid .opt file was not specified "
296 "with the --useoptfile command line option");
308 exists = (bool)boost::filesystem::exists(optfile.c_str());
311 if (exists && ParallelInTime)
314 doc.LoadFile(optfile);
315 TiXmlElement *xmlTag = doc.FirstChildElement(
"NEKTAR")
316 ->FirstChildElement(
"COLLECTIONS")
317 ->FirstChildElement(
"TIMELEVEL");
326 if (
m_timeLevel == stoi(xmlTag->Attribute(
"VALUE")))
331 xmlTag = xmlTag->NextSiblingElement();
369 if (std::getenv(
"NEKTAR_DISABLE_BACKUPS") !=
nullptr)
379 cout <<
"Parameters:" << endl;
382 cout <<
"\t" << x.first <<
" = " << x.second << endl;
389 cout <<
"Solver Info:" << endl;
392 cout <<
"\t" << x.first <<
" = " << x.second << endl;
403 if (
m_comm->GetSize() > 1)
405 if (
m_comm->GetRank() == 0)
407 std::ofstream testfile(
"shared-fs-testfile");
408 testfile <<
"" << std::endl;
409 ASSERTL1(!testfile.fail(),
"Test file creation failed");
414 int exists = (bool)boost::filesystem::exists(
"shared-fs-testfile");
422 std::remove(
"shared-fs-testfile");
432 cout <<
"Shared filesystem detected" << endl;
444 po::options_description desc(
"Allowed 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 (
"forceoutput,f",
"Disables backups files and forces output to be "
471 "written without any checks")
472 (
"writeoptfile",
"write an optimisation file")
473 (
"useoptfile", po::value<std::string>(),
474 "use an optimisation file");
476#ifdef NEKTAR_USE_CWIPI
477 desc.add_options()(
"cwipi", po::value<std::string>(),
"set CWIPI name");
482 std::string names = cmdIt.first;
483 if (cmdIt.second.shortName !=
"")
485 names +=
"," + cmdIt.second.shortName;
487 if (cmdIt.second.isFlag)
489 desc.add_options()(names.c_str(), cmdIt.second.description.c_str());
493 desc.add_options()(names.c_str(), po::value<std::string>(),
494 cmdIt.second.description.c_str());
500 po::options_description hidden(
"Hidden options");
502 hidden.add_options()(
"input-file", po::value<vector<string>>(),
506 po::options_description all(
"All options");
507 all.add(desc).add(hidden);
510 po::positional_options_description
p;
511 p.add(
"input-file", -1);
514 po::parsed_options parsed = po::command_line_parser(argc, argv)
517 .allow_unregistered()
540 boost::replace_all(branch,
"refs/heads/",
"");
542 cout <<
" (git changeset " <<
sha1.substr(0, 8) <<
", ";
546 cout <<
"detached head";
550 cout <<
"head " << branch;
591 for (
auto &x : parsed.options)
595 cout <<
"Warning: Unknown option: " << x.string_key << endl;
606 return std::vector<std::string>();
615 ASSERTL0(!filenames.empty(),
"At least one filename expected.");
617 std::string retval =
"";
620 std::string fname = filenames[0];
623 if (fname.size() > 4 && fname.substr(fname.size() - 4, 4) ==
"_xml")
625 retval = fname.substr(0, fname.find_last_of(
"_"));
628 else if (fname.size() > 4 && fname.substr(fname.size() - 4, 4) ==
".xml")
630 retval = fname.substr(0, fname.find_last_of(
"."));
633 else if (fname.size() > 7 && fname.substr(fname.size() - 7, 7) ==
".xml.gz")
635 retval = fname.substr(0, fname.find_last_of(
"."));
636 retval = retval.substr(0, retval.find_last_of(
"."));
675 std::string vPath = boost::to_upper_copy(pPath);
676 std::vector<std::string> st;
677 boost::split(st, vPath, boost::is_any_of(
"\\/ "));
678 ASSERTL0(st.size() > 0,
"No path given in XML element request.");
680 TiXmlElement *vReturn =
m_xmlDoc->FirstChildElement(st[0].c_str());
682 std::string(
"Cannot find element '") + st[0] + std::string(
"'."));
683 for (
int i = 1; i < st.size(); ++i)
685 vReturn = vReturn->FirstChildElement(st[i].c_str());
686 ASSERTL0(vReturn, std::string(
"Cannot find element '") + st[i] +
697 std::string vPath = boost::to_upper_copy(pPath);
698 std::vector<std::string> st;
699 boost::split(st, vPath, boost::is_any_of(
"\\/ "));
700 ASSERTL0(st.size() > 0,
"No path given in XML element request.");
702 TiXmlElement *vReturn =
m_xmlDoc->FirstChildElement(st[0].c_str());
704 std::string(
"Cannot find element '") + st[0] + std::string(
"'."));
705 for (
int i = 1; i < st.size(); ++i)
707 vReturn = vReturn->FirstChildElement(st[i].c_str());
737 fs::path pdirname(dirname);
739 std::string vFilename =
740 "P" + boost::lexical_cast<std::string>(
m_comm->GetRowComm()->GetRank());
741 fs::path pFilename(vFilename);
743 fs::path fullpath = pdirname / pFilename;
777 std::string vName = boost::to_upper_copy(pName);
791 std::string vName = boost::to_upper_copy(pName);
795 "Unable to find requested parameter: " + pName);
797 return paramIter->second;
805 std::string vName = boost::to_upper_copy(pName);
808 "Required parameter '" + pName +
"' not specified in session.");
809 NekDouble param = round(paramIter->second);
810 pVar = checked_cast<int>(param);
817 const int &pDefault)
const
819 std::string vName = boost::to_upper_copy(pName);
823 NekDouble param = round(paramIter->second);
824 pVar = checked_cast<int>(param);
837 std::string vName = boost::to_upper_copy(pName);
840 "Required parameter '" + pName +
"' not specified in session.");
841 NekDouble param = round(paramIter->second);
842 pVar = checked_cast<int>(param);
849 const size_t &pDefault)
const
851 std::string vName = boost::to_upper_copy(pName);
855 NekDouble param = round(paramIter->second);
856 pVar = checked_cast<int>(param);
870 std::string vName = boost::to_upper_copy(pName);
873 "Required parameter '" + pName +
"' not specified in session.");
874 pVar = paramIter->second;
883 std::string vName = boost::to_upper_copy(pName);
887 pVar = paramIter->second;
900 std::string vName = boost::to_upper_copy(pName);
909 std::string vName = boost::to_upper_copy(pName);
918 std::string vName = boost::to_upper_copy(pName);
927 std::string vName = boost::to_upper_copy(pName);
936 const std::string &pProperty)
const
938 std::string vProperty = boost::to_upper_copy(pProperty);
942 "Unable to find requested property: " + pProperty);
951 const std::string &pValue)
953 std::string vProperty = boost::to_upper_copy(pProperty);
957 "Unable to find requested property: " + pProperty);
959 iter->second = pValue;
966 const std::string &pDefault)
const
968 std::string vName = boost::to_upper_copy(pName);
972 pVar = infoIter->second;
984 const std::string &pTrueVal,
bool &pVar,
985 const bool &pDefault)
const
987 std::string vName = boost::to_upper_copy(pName);
991 pVar = boost::iequals(infoIter->second, pTrueVal);
1003 const std::string &pTrueVal)
const
1007 std::string vName = boost::to_upper_copy(pName);
1011 return boost::iequals(iter->second, pTrueVal);
1021 const std::string &pProperty)
const
1029 std::string vProperty = boost::to_upper_copy(pProperty);
1031 auto iter1 = iter->second.find(vProperty);
1032 if (iter1 == iter->second.end())
1044 const std::string &pVariable,
const std::string &pProperty)
const
1048 "Failed to find variable in GlobalSysSolnInfoList");
1050 std::string vProperty = boost::to_upper_copy(pProperty);
1051 auto iter1 = iter->second.find(vProperty);
1053 ASSERTL0(iter1 != iter->second.end(),
1054 "Failed to find property: " + vProperty +
1055 " in GlobalSysSolnInfoList");
1057 return iter1->second;
1080 TiXmlElement *xmlGeom =
1081 m_xmlDoc->FirstChildElement(
"NEKTAR")->FirstChildElement(
"GEOMETRY");
1082 ASSERTL1(xmlGeom,
"Failed to find a GEOMETRY section in m_xmlDoc");
1084 TiXmlAttribute *attr = xmlGeom->FirstAttribute();
1087 std::string attrName(attr->Name());
1088 if (attrName ==
"HDF5FILE")
1094 attr = attr->Next();
1099 TiXmlElement *element = xmlGeom->FirstChildElement(
"VERTEX");
1100 string IsCompressed;
1101 element->QueryStringAttribute(
"COMPRESSED", &IsCompressed);
1103 if (IsCompressed.size() > 0)
1105 return "XmlCompressed";
1117 std::string vName = boost::to_upper_copy(pName);
1126 const std::string &pDefault)
const
1128 std::string vName = boost::to_upper_copy(pName);
1132 pVar = iter->second;
1144 const bool &pDefault)
const
1146 std::string vName = boost::to_upper_copy(pName);
1150 if (iter->second ==
"TRUE")
1171 std::string vName = boost::to_upper_copy(pName);
1175 pVar = std::atoi(iter->second.c_str());
1187 const std::string &pTrueVal,
bool &pVar,
1188 const bool &pDefault)
const
1190 std::string vName = boost::to_upper_copy(pName);
1194 pVar = boost::iequals(iter->second, pTrueVal);
1241 std::string vName = boost::to_upper_copy(pName);
1249 const std::string &pVariable,
1250 const int pDomain)
const
1252 std::string vName = boost::to_upper_copy(pName);
1258 pair<std::string, int> key(pVariable, pDomain);
1259 pair<std::string, int> defkey(
"*", pDomain);
1260 bool varExists = it1->second.find(key) != it1->second.end() ||
1261 it1->second.find(defkey) != it1->second.end();
1271 const std::string &pVariable,
1272 const int pDomain)
const
1274 std::string vName = boost::to_upper_copy(pName);
1278 std::string(
"No such function '") + pName +
1279 std::string(
"' has been defined in the session file."));
1282 pair<std::string, int> key(pVariable, pDomain);
1283 pair<std::string, int> defkey(
"*", pDomain);
1285 auto it2 = it1->second.find(key);
1286 auto it3 = it1->second.find(defkey);
1287 bool specific = it2 != it1->second.end();
1288 bool wildcard = it3 != it1->second.end();
1292 "No such variable " + pVariable +
" in domain " +
1293 boost::lexical_cast<string>(pDomain) +
1294 " defined for function " + pName +
" in session file.");
1303 std::string(
"Function is defined by a file."));
1304 return it2->second.m_expression;
1311 const unsigned int &pVar,
1312 const int pDomain)
const
1322 const std::string &pVariable,
1323 const int pDomain)
const
1325 std::string vName = boost::to_upper_copy(pName);
1329 std::string(
"Function '") + pName + std::string(
"' not found."));
1332 pair<std::string, int> key(pVariable, pDomain);
1333 pair<std::string, int> defkey(
"*", pDomain);
1335 auto it2 = it1->second.find(key);
1336 auto it3 = it1->second.find(defkey);
1337 bool specific = it2 != it1->second.end();
1338 bool wildcard = it3 != it1->second.end();
1342 "No such variable " + pVariable +
" in domain " +
1343 boost::lexical_cast<string>(pDomain) +
1344 " defined for function " + pName +
" in session file.");
1352 return it2->second.m_type;
1359 const unsigned int &pVar,
1360 const int pDomain)
const
1370 const std::string &pVariable,
1371 const int pDomain)
const
1373 std::string vName = boost::to_upper_copy(pName);
1377 std::string(
"Function '") + pName + std::string(
"' not found."));
1380 pair<std::string, int> key(pVariable, pDomain);
1381 pair<std::string, int> defkey(
"*", pDomain);
1383 auto it2 = it1->second.find(key);
1384 auto it3 = it1->second.find(defkey);
1385 bool specific = it2 != it1->second.end();
1386 bool wildcard = it3 != it1->second.end();
1390 "No such variable " + pVariable +
" in domain " +
1391 boost::lexical_cast<string>(pDomain) +
1392 " defined for function " + pName +
" in session file.");
1400 return it2->second.m_filename;
1407 const unsigned int &pVar,
1408 const int pDomain)
const
1418 const std::string &pName,
const std::string &pVariable,
1419 const int pDomain)
const
1421 std::string vName = boost::to_upper_copy(pName);
1425 std::string(
"Function '") + pName + std::string(
"' not found."));
1428 pair<std::string, int> key(pVariable, pDomain);
1429 pair<std::string, int> defkey(
"*", pDomain);
1431 auto it2 = it1->second.find(key);
1432 auto it3 = it1->second.find(defkey);
1433 bool specific = it2 != it1->second.end();
1434 bool wildcard = it3 != it1->second.end();
1438 "No such variable " + pVariable +
" in domain " +
1439 boost::lexical_cast<string>(pDomain) +
1440 " defined for function " + pName +
" in session file.");
1448 return it2->second.m_fileVariable;
1456 std::string vName = boost::to_upper_copy(pName);
1465 std::string vName = boost::to_upper_copy(pName);
1474 std::string vName = boost::to_upper_copy(pName);
1475 auto vTagIterator =
m_tags.find(vName);
1476 ASSERTL0(vTagIterator !=
m_tags.end(),
"Requested tag does not exist.");
1477 return vTagIterator->second;
1500 const size_t timeLevel,
1501 const bool disableCheck)
1503 if (Element && Element->FirstChildElement(
"TIMELEVEL"))
1505 Element = Element->FirstChildElement(
"TIMELEVEL");
1506 std::string timeLevelStr;
1509 std::stringstream tagcontent;
1510 tagcontent << *Element;
1511 ASSERTL0(Element->Attribute(
"VALUE"),
1512 "Missing LEVEL attribute in solver info "
1513 "XML element: \n\t'" +
1514 tagcontent.str() +
"'");
1515 timeLevelStr = Element->Attribute(
"VALUE");
1517 "LEVEL attribute must be non-empty in XML "
1519 tagcontent.str() +
"'");
1520 if (stoi(timeLevelStr) == timeLevel)
1524 Element = Element->NextSiblingElement(
"TIMELEVEL");
1528 ASSERTL0(stoi(timeLevelStr) == timeLevel,
1529 "TIMELEVEL value " + std::to_string(timeLevel) +
1530 " not found in solver info "
1531 "XML element: \n\t'");
1540 TiXmlDocument *pDoc)
const
1542 if (pFilename.size() > 3 &&
1543 pFilename.substr(pFilename.size() - 3, 3) ==
".gz")
1545 ifstream file(pFilename.c_str(), ios_base::in | ios_base::binary);
1546 ASSERTL0(file.good(),
"Unable to open file: " + pFilename);
1548 io::filtering_streambuf<io::input> in;
1549 in.push(io::gzip_decompressor());
1556 catch (io::gzip_error &)
1559 "Error: File '" + pFilename +
"' is corrupt.");
1562 else if (pFilename.size() > 4 &&
1563 pFilename.substr(pFilename.size() - 4, 4) ==
"_xml")
1565 fs::path pdirname(pFilename);
1567 pad %
m_comm->GetSpaceComm()->GetRank();
1568 fs::path pRankFilename(pad.str());
1569 fs::path fullpath = pdirname / pRankFilename;
1572 ASSERTL0(file.good(),
"Unable to open file: " + fullpath.string());
1577 ifstream file(pFilename.c_str());
1578 ASSERTL0(file.good(),
"Unable to open file: " + pFilename);
1587 const std::vector<std::string> &pFilenames)
const
1589 ASSERTL0(pFilenames.size() > 0,
"No filenames for merging.");
1592 TiXmlDocument *vMainDoc =
new TiXmlDocument;
1593 LoadDoc(pFilenames[0], vMainDoc);
1595 TiXmlHandle vMainHandle(vMainDoc);
1596 TiXmlElement *vMainNektar =
1602 for (
int i = 1; i < pFilenames.size(); ++i)
1604 if ((pFilenames[i].compare(pFilenames[i].size() - 3, 3,
"xml") == 0) ||
1605 (pFilenames[i].compare(pFilenames[i].size() - 6, 6,
"xml.gz") ==
1607 (pFilenames[i].compare(pFilenames[i].size() - 3, 3,
"opt") == 0))
1609 TiXmlDocument *vTempDoc =
new TiXmlDocument;
1610 LoadDoc(pFilenames[i], vTempDoc);
1612 TiXmlHandle docHandle(vTempDoc);
1613 TiXmlElement *vTempNektar =
1615 TiXmlElement *
p = vTempNektar->FirstChildElement();
1619 TiXmlElement *vMainEntry =
1620 vMainNektar->FirstChildElement(
p->Value());
1625 if (!
p->FirstChild() && vMainEntry &&
1626 !boost::iequals(
p->Value(),
"COLLECTIONS"))
1628 std::string warningmsg =
1629 "File " + pFilenames[i] +
" contains " +
1630 "an empty XML element " + std::string(
p->Value()) +
1631 " which will be ignored.";
1638 vMainNektar->RemoveChild(vMainEntry);
1640 TiXmlElement *
q =
new TiXmlElement(*
p);
1641 vMainNektar->LinkEndChild(
q);
1643 p =
p->NextSiblingElement();
1663 e = docHandle.FirstChildElement(
"NEKTAR")
1664 .FirstChildElement(
"CONDITIONS")
1675 e = docHandle.FirstChildElement(
"NEKTAR")
1676 .FirstChildElement(
"FILTERS")
1693 string vCommModule(
"Serial");
1696 vCommModule =
"ParallelMPI";
1701 vCommModule =
"CWIPI";
1717 if (
m_comm->GetSize() > 1)
1726 nProcX = GetCmdLineArgument<int>(
"npx");
1730 nProcY = GetCmdLineArgument<int>(
"npy");
1734 nProcZ = GetCmdLineArgument<int>(
"npz");
1738 nStripZ = GetCmdLineArgument<int>(
"nsz");
1742 nTime = GetCmdLineArgument<int>(
"npt");
1745 "Cannot exactly partition time using npt value.");
1746 ASSERTL0((
m_comm->GetSize() / nTime) % (nProcZ * nProcY * nProcX) == 0,
1747 "Cannot exactly partition using PROC_Z value.");
1749 "Cannot exactly partition using PROC_Y value.");
1751 "Cannot exactly partition using PROC_X value.");
1754 int nProcSm = nProcZ * nProcY * nProcX;
1758 int nProcSem =
m_comm->GetSize() / nTime / nProcSm;
1760 m_comm->SplitComm(nProcSm, nProcSem, nTime);
1761 m_comm->GetColumnComm()->SplitComm(nProcZ / nStripZ, nStripZ);
1762 m_comm->GetColumnComm()->GetColumnComm()->SplitComm((nProcY * nProcX),
1764 m_comm->GetColumnComm()->GetColumnComm()->GetColumnComm()->SplitComm(
1781 TiXmlElement *parametersElement =
1782 conditions->FirstChildElement(
"PARAMETERS");
1787 if (parametersElement)
1789 TiXmlElement *parameter = parametersElement->FirstChildElement(
"P");
1797 stringstream tagcontent;
1798 tagcontent << *parameter;
1799 TiXmlNode *node = parameter->FirstChild();
1801 while (node && node->Type() != TiXmlNode::TINYXML_TEXT)
1803 node = node->NextSibling();
1809 std::string line = node->ToText()->Value(), lhs, rhs;
1818 "Syntax error in parameter expression '" + line +
1819 "' in XML element: \n\t'" + tagcontent.str() +
1826 if (!lhs.empty() && !rhs.empty())
1834 catch (
const std::runtime_error &)
1837 "Error evaluating parameter expression"
1839 rhs +
"' in XML element: \n\t'" +
1840 tagcontent.str() +
"'");
1843 caseSensitiveParameters[lhs] = value;
1844 boost::to_upper(lhs);
1849 parameter = parameter->NextSiblingElement();
1867 TiXmlElement *solverInfoElement =
1868 conditions->FirstChildElement(
"SOLVERINFO");
1871 if (solverInfoElement)
1873 TiXmlElement *solverInfo = solverInfoElement->FirstChildElement(
"I");
1877 std::stringstream tagcontent;
1878 tagcontent << *solverInfo;
1880 ASSERTL0(solverInfo->Attribute(
"PROPERTY"),
1881 "Missing PROPERTY attribute in solver info "
1882 "XML element: \n\t'" +
1883 tagcontent.str() +
"'");
1884 std::string solverProperty = solverInfo->Attribute(
"PROPERTY");
1886 "PROPERTY attribute must be non-empty in XML "
1888 tagcontent.str() +
"'");
1891 std::string solverPropertyUpper =
1892 boost::to_upper_copy(solverProperty);
1895 ASSERTL0(solverInfo->Attribute(
"VALUE"),
1896 "Missing VALUE attribute in solver info "
1897 "XML element: \n\t'" +
1898 tagcontent.str() +
"'");
1899 std::string solverValue = solverInfo->Attribute(
"VALUE");
1901 "VALUE attribute must be non-empty in XML "
1903 tagcontent.str() +
"'");
1907 solverInfo = solverInfo->NextSiblingElement(
"I");
1915 m_solverInfo[
"GLOBALSYSSOLN"] ==
"IterativeStaticCond" ||
1917 "IterativeMultiLevelStaticCond" ||
1920 m_solverInfo[
"GLOBALSYSSOLN"] ==
"XxtMultiLevelStaticCond" ||
1923 m_solverInfo[
"GLOBALSYSSOLN"] ==
"PETScMultiLevelStaticCond",
1924 "A parallel solver must be used when run in parallel.");
1940 TiXmlElement *GlobalSys =
1941 conditions->FirstChildElement(
"GLOBALSYSSOLNINFO");
1949 TiXmlElement *VarInfo = GlobalSys->FirstChildElement(
"V");
1953 std::stringstream tagcontent;
1954 tagcontent << *VarInfo;
1955 ASSERTL0(VarInfo->Attribute(
"VAR"),
1956 "Missing VAR attribute in GobalSysSolnInfo XML "
1958 tagcontent.str() +
"'");
1960 std::string VarList = VarInfo->Attribute(
"VAR");
1962 "VAR attribute must be non-empty in XML element:\n\t'" +
1963 tagcontent.str() +
"'");
1966 std::vector<std::string> varStrings;
1969 ASSERTL0(valid,
"Unable to process list of variable in XML "
1971 tagcontent.str() +
"'");
1973 if (varStrings.size())
1975 TiXmlElement *SysSolnInfo = VarInfo->FirstChildElement(
"I");
1980 tagcontent << *SysSolnInfo;
1982 ASSERTL0(SysSolnInfo->Attribute(
"PROPERTY"),
1983 "Missing PROPERTY attribute in "
1984 "GlobalSysSolnInfo for variable(s) '" +
1985 VarList +
"' in XML element: \n\t'" +
1986 tagcontent.str() +
"'");
1988 std::string SysSolnProperty =
1989 SysSolnInfo->Attribute(
"PROPERTY");
1992 "GlobalSysSolnIno properties must have a "
1993 "non-empty name for variable(s) : '" +
1994 VarList +
"' in XML element: \n\t'" +
1995 tagcontent.str() +
"'");
1998 std::string SysSolnPropertyUpper =
1999 boost::to_upper_copy(SysSolnProperty);
2002 ASSERTL0(SysSolnInfo->Attribute(
"VALUE"),
2003 "Missing VALUE attribute in GlobalSysSolnInfo "
2004 "for variable(s) '" +
2005 VarList +
"' in XML element: \n\t" +
2006 tagcontent.str() +
"'");
2008 std::string SysSolnValue = SysSolnInfo->Attribute(
"VALUE");
2010 "GlobalSysSolnInfo properties must have a "
2011 "non-empty value for variable(s) '" +
2012 VarList +
"' in XML element: \n\t'" +
2013 tagcontent.str() +
"'");
2016 for (
int i = 0; i < varStrings.size(); ++i)
2022 [SysSolnPropertyUpper] = SysSolnValue;
2026 x->second[SysSolnPropertyUpper] = SysSolnValue;
2030 SysSolnInfo = SysSolnInfo->NextSiblingElement(
"I");
2032 VarInfo = VarInfo->NextSiblingElement(
"V");
2038 if (
m_comm->GetRank() == 0)
2040 cout <<
"GlobalSysSoln Info:" << endl;
2044 cout <<
"\t Variable: " << x.first << endl;
2046 for (
auto &y : x.second)
2048 cout <<
"\t\t " << y.first <<
" = " << y.second << endl;
2066 TiXmlElement *timeInt =
2067 conditions->FirstChildElement(
"TIMEINTEGRATIONSCHEME");
2075 TiXmlElement *method = timeInt->FirstChildElement(
"METHOD");
2076 TiXmlElement *variant = timeInt->FirstChildElement(
"VARIANT");
2077 TiXmlElement *order = timeInt->FirstChildElement(
"ORDER");
2078 TiXmlElement *params = timeInt->FirstChildElement(
"FREEPARAMETERS");
2081 ASSERTL0(method,
"Missing METHOD tag inside "
2082 "TIMEINTEGRATIONSCHEME.");
2083 ASSERTL0(order,
"Missing ORDER tag inside "
2084 "TIMEINTEGRATIONSCHEME.");
2088 std::string orderStr = order->GetText();
2092 "Empty text inside METHOD tag in TIMEINTEGRATIONSCHEME.");
2094 "Empty text inside ORDER tag in TIMEINTEGRATIONSCHEME.");
2103 orderStr +
"' to an unsigned integer.");
2113 std::string paramsStr = params->GetText();
2115 "Empty text inside FREEPARAMETERS tag in "
2116 "TIMEINTEGRATIONSCHEME.");
2118 std::vector<std::string> pSplit;
2119 boost::split(pSplit, paramsStr, boost::is_any_of(
" "));
2122 for (
size_t i = 0; i < pSplit.size(); ++i)
2127 boost::lexical_cast<NekDouble>(pSplit[i]);
2132 "unable to convert string '" +
2135 "to a floating-point value.");
2142 if (
m_comm->GetRank() == 0)
2144 cout <<
"Trying to use time integration scheme:" << endl;
2151 cout <<
"\t Params :";
2174 TiXmlElement *variablesElement = conditions->FirstChildElement(
"VARIABLES");
2179 if (variablesElement)
2181 TiXmlElement *varElement = variablesElement->FirstChildElement(
"V");
2184 int nextVariableNumber = -1;
2188 stringstream tagcontent;
2189 tagcontent << *varElement;
2193 nextVariableNumber++;
2196 int err = varElement->QueryIntAttribute(
"ID", &i);
2198 "Variables must have a unique ID number attribute "
2199 "in XML element: \n\t'" +
2200 tagcontent.str() +
"'");
2202 "ID numbers for variables must begin with zero and"
2203 " be sequential in XML element: \n\t'" +
2204 tagcontent.str() +
"'");
2206 TiXmlNode *varChild = varElement->FirstChild();
2211 while (varChild && varChild->Type() != TiXmlNode::TINYXML_TEXT)
2213 varChild = varChild->NextSibling();
2216 ASSERTL0(varChild,
"Unable to read variable definition body for "
2217 "variable with ID " +
2218 boost::lexical_cast<string>(i) +
2219 " in XML element: \n\t'" + tagcontent.str() +
2221 std::string variableName = varChild->ToText()->ValueStr();
2223 std::istringstream variableStrm(variableName);
2224 variableStrm >> variableName;
2228 "Variable with ID " + boost::lexical_cast<string>(i) +
2229 " in XML element \n\t'" + tagcontent.str() +
2230 "'\nhas already been defined.");
2234 varElement = varElement->NextSiblingElement(
"V");
2238 "Number of variables must be greater than zero.");
2255 TiXmlElement *function = conditions->FirstChildElement(
"FUNCTION");
2259 stringstream tagcontent;
2260 tagcontent << *function;
2263 ASSERTL0(function->Attribute(
"NAME"),
2264 "Functions must have a NAME attribute defined in XML "
2266 tagcontent.str() +
"'");
2267 std::string functionStr = function->Attribute(
"NAME");
2269 "Functions must have a non-empty name in XML "
2271 tagcontent.str() +
"'");
2274 boost::to_upper(functionStr);
2277 TiXmlElement *element = function;
2279 TiXmlElement *variable = element->FirstChildElement();
2288 std::string conditionType = variable->Value();
2291 std::string variableStr;
2292 if (!variable->Attribute(
"VAR"))
2298 variableStr = variable->Attribute(
"VAR");
2302 std::vector<std::string> variableList;
2306 std::string domainStr;
2307 if (!variable->Attribute(
"DOMAIN"))
2313 domainStr = variable->Attribute(
"DOMAIN");
2317 std::string evarsStr =
"x y z t";
2318 if (variable->Attribute(
"EVARS"))
2321 evarsStr + std::string(
" ") + variable->Attribute(
"EVARS");
2325 std::vector<std::string> varSplit;
2326 std::vector<unsigned int> domainList;
2330 if (conditionType ==
"E")
2335 ASSERTL0(variable->Attribute(
"VALUE"),
2336 "Attribute VALUE expected for function '" +
2337 functionStr +
"'.");
2338 std::string fcnStr = variable->Attribute(
"VALUE");
2341 (std::string(
"Expression for var: ") + variableStr +
2342 std::string(
" must be specified."))
2352 else if (conditionType ==
"F")
2354 if (variable->Attribute(
"TIMEDEPENDENT") &&
2355 boost::lexical_cast<bool>(
2356 variable->Attribute(
"TIMEDEPENDENT")))
2366 ASSERTL0(variable->Attribute(
"FILE"),
2367 "Attribute FILE expected for function '" +
2368 functionStr +
"'.");
2369 std::string filenameStr = variable->Attribute(
"FILE");
2372 "A filename must be specified for the FILE "
2373 "attribute of function '" +
2374 functionStr +
"'.");
2376 std::vector<std::string> fSplit;
2377 boost::split(fSplit, filenameStr, boost::is_any_of(
":"));
2379 ASSERTL0(fSplit.size() == 1 || fSplit.size() == 2,
2380 "Incorrect filename specification in function " +
2383 "Specify variables inside file as: "
2384 "filename:var1,var2");
2387 fs::path fullpath = fSplit[0];
2388 fs::path ftype = fullpath.extension();
2389 if (fullpath.parent_path().extension() ==
".pit")
2391 string filename = fullpath.stem().string();
2392 fullpath = fullpath.parent_path();
2393 size_t start = filename.find_last_of(
"_") + 1;
2395 atoi(filename.substr(start, filename.size()).c_str());
2396 fullpath /= filename.substr(0, start) +
2398 index +
m_comm->GetTimeComm()->GetRank()) +
2403 if (fSplit.size() == 2)
2406 "Filename variable mapping not valid "
2407 "when using * as a variable inside "
2409 functionStr +
"'.");
2411 boost::split(varSplit, fSplit[1], boost::is_any_of(
","));
2412 ASSERTL0(varSplit.size() == variableList.size(),
2413 "Filename variables should contain the "
2414 "same number of variables defined in "
2415 "VAR in function " +
2416 functionStr +
"'.");
2423 stringstream tagcontent;
2424 tagcontent << *variable;
2427 "Identifier " + conditionType +
" in function " +
2428 std::string(function->Attribute(
"NAME")) +
2429 " is not recognised in XML element: \n\t'" +
2430 tagcontent.str() +
"'");
2434 for (
unsigned int i = 0; i < variableList.size(); ++i)
2436 for (
unsigned int j = 0; j < domainList.size(); ++j)
2439 pair<std::string, int> key(variableList[i], domainList[j]);
2440 auto fcnsIter = functionVarMap.find(key);
2442 fcnsIter == functionVarMap.end(),
2443 "Error setting expression '" + variableList[i] +
2445 boost::lexical_cast<std::string>(domainList[j]) +
2446 "' in function '" + functionStr +
2448 "Expression has already been defined.");
2450 if (varSplit.size() > 0)
2454 functionVarMap[key] = funcDef2;
2458 functionVarMap[key] = funcDef;
2463 variable = variable->NextSiblingElement();
2467 function = function->NextSiblingElement(
"FUNCTION");
2483 TiXmlElement *filter = filters->FirstChildElement(
"FILTER");
2487 ASSERTL0(filter->Attribute(
"TYPE"),
2488 "Missing attribute 'TYPE' for filter.");
2489 std::string typeStr = filter->Attribute(
"TYPE");
2491 std::map<std::string, std::string> vParams;
2493 TiXmlElement *element = filter;
2495 TiXmlElement *param = element->FirstChildElement(
"PARAM");
2499 "Missing attribute 'NAME' for parameter in filter " +
2501 std::string nameStr = param->Attribute(
"NAME");
2503 ASSERTL0(param->GetText(),
"Empty value string for param.");
2504 std::string valueStr = param->GetText();
2506 vParams[nameStr] = valueStr;
2508 param = param->NextSiblingElement(
"PARAM");
2512 std::pair<std::string, FilterParams>(typeStr, vParams));
2514 filter = filter->NextSiblingElement(
"FILTER");
2522 size_t beg = line.find_first_not_of(
" ");
2523 size_t end = line.find_first_of(
"=");
2528 if (end != line.find_last_of(
"="))
2531 if (end == std::string::npos)
2534 lhs = line.substr(line.find_first_not_of(
" "), end - beg);
2535 lhs = lhs.substr(0, lhs.find_last_not_of(
" ") + 1);
2536 rhs = line.substr(line.find_last_of(
"=") + 1);
2537 rhs = rhs.substr(rhs.find_first_not_of(
" "));
2538 rhs = rhs.substr(0, rhs.find_last_not_of(
" ") + 1);
2549 std::vector<std::string> solverInfoList =
2552 for (
size_t i = 0; i < solverInfoList.size(); ++i)
2554 std::string lhs, rhs;
2567 std::string lhsUpper = boost::to_upper_copy(lhs);
2574 std::vector<std::string> parametersList =
2577 for (
size_t i = 0; i < parametersList.size(); ++i)
2579 std::string lhs, rhs;
2592 std::string lhsUpper = boost::to_upper_copy(lhs);
2596 m_parameters[lhsUpper] = boost::lexical_cast<NekDouble>(rhs);
2601 "to double value.");
2611 std::string solverProperty = x.first;
2612 std::string solverValue = x.second;
2617 auto valIt = propIt->second.find(solverValue);
2618 ASSERTL0(valIt != propIt->second.end(),
"Value '" + solverValue +
2619 "' is not valid for "
2621 solverProperty +
"'");
2636 std::string elementName,
2637 const TiXmlHandle &docHandle)
2639 TiXmlElement *element = docHandle.FirstChildElement(elementName).Element();
2647 "' 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.
GeometricInfoMap m_geometricInfo
Geometric information properties.
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.
bool DefinesGeometricInfo(const std::string &name) const
Checks if a geometric info property is defined.
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 MatchGeometricInfo(const std::string &name, const std::string &trueval, bool &var, const bool &def=false) const
Check if the value of a geometric info string property matches.
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.
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.
static void GetXMLElementTimeLevel(TiXmlElement *&element, const size_t timeLevel, const bool disableCheck=true)
Get XML elment time level (Parallel-in-Time)
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 std::string GetSessionNameRank() const
Returns the session name with process rank.
const TimeIntScheme & GetTimeIntScheme() const
Returns the time integration scheme structure m_timeIntScheme from the session file.
void LoadGeometricInfo(const std::string &name, std::string &var, const std::string &def="") const
Checks for and load a geometric info string property.
FilterMap m_filters
Filters map.
void SetTag(const std::string &pName, const std::string &pValue)
Sets a specified tag.
boost::program_options::variables_map m_cmdLineOptions
std::string m_sessionName
Session name of the loaded XML document (filename minus ext).
CommSharedPtr m_comm
Communication object.
void MatchSolverInfo(const std::string &name, const std::string &trueval, bool &var, const bool &def=false) const
Check if the value of a solver info property matches.
void CreateComm(int &argc, char *argv[])
Loads the given XML document and instantiates an appropriate communication object.
const std::string & GetSolverInfo(const std::string &pProperty) const
Returns the value of the specified solver info property.
void ParseEquals(const std::string &line, std::string &lhs, std::string &rhs)
Parse a string in the form lhs = rhs.
bool DefinesTimeIntScheme() const
Returns true if the TIMEINTEGRATIONSCHEME section is defined in the session file.
const std::vector< std::string > & GetFilenames() const
Returns the filename of the loaded XML document.
bool GetSharedFilesystem()
Returns if file system shared.
static GloSysSolnInfoList & GetGloSysSolnList()
GlobalSysSoln Info map.
void PartitionComm()
Partitions the comm object based on session parameters.
bool DefinesCmdLineArgument(const std::string &pName) const
Checks if a specified cmdline argument has been given.
TiXmlDocument * m_xmlDoc
Pointer to the loaded XML document.
void ReadParameters(TiXmlElement *conditions)
Reads the PARAMETERS section of the XML document.
void LoadSolverInfo(const std::string &name, std::string &var, const std::string &def="") const
Check for and load a solver info property.
std::string GetGeometryType() const
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector.
std::shared_ptr< Interpreter > InterpreterSharedPtr
std::map< std::string, std::string > SolverInfoMap
std::map< std::string, GloSysInfoMap > GloSysSolnInfoList
std::map< std::pair< std::string, int >, FunctionVariableDefinition > FunctionVariableMap
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
std::map< std::string, NekDouble > ParameterMap
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 > q(NPUPPER *NPUPPER)
The above copyright notice and this permission notice shall be included.
EquationSharedPtr m_expression
std::string m_fileVariable
std::vector< NekDouble > freeParams