46 #include <boost/iostreams/filtering_streambuf.hpp>
47 #include <boost/iostreams/copy.hpp>
48 #include <boost/iostreams/filter/gzip.hpp>
49 #include <boost/algorithm/string.hpp>
61 #include <boost/program_options.hpp>
62 #include <boost/format.hpp>
64 #ifndef NEKTAR_VERSION
65 #define NEKTAR_VERSION "Unknown"
70 namespace po = boost::program_options;
71 namespace io = boost::iostreams;
75 namespace LibUtilities
131 return solverInfoEnums;
146 return solverInfoMap;
162 return gloSysSolnInfoList;
176 return cmdLineArguments;
188 SessionReader::SessionReader(
int argc,
char *argv[])
191 m_filenames = ParseCommandLineArguments(argc, argv);
193 ASSERTL0(m_filenames.size() > 0,
"No session file(s) given.");
195 m_sessionName = ParseSessionName(m_filenames);
198 CreateComm(argc, argv);
200 TestSharedFilesystem();
204 if (m_comm->GetSize() > 1)
206 GetSolverInfoDefaults()[
"GLOBALSYSSOLN"] =
207 "IterativeStaticCond";
211 m_interpreter->SetRandomSeed((m_comm->GetRank() + 1)
212 * (
unsigned int)time(NULL));
222 SessionReader::SessionReader(
225 const std::vector<std::string> &pFilenames,
228 ASSERTL0(pFilenames.size() > 0,
"No filenames specified.");
230 ParseCommandLineArguments(argc, argv);
232 m_filenames = pFilenames;
234 m_sessionName = ParseSessionName(m_filenames);
239 CreateComm(argc, argv);
246 TestSharedFilesystem();
250 if (m_comm->GetSize() > 1)
252 GetSolverInfoDefaults()[
"GLOBALSYSSOLN"] =
253 "IterativeStaticCond";
257 m_interpreter->SetRandomSeed((m_comm->GetRank() + 1)
258 * (
unsigned int)time(NULL));
268 SessionReader::~SessionReader()
283 void SessionReader::InitSession(
284 const std::vector<std::string> &filenames)
287 if (filenames.size() > 0)
289 m_filenames = filenames;
298 m_xmlDoc = MergeDoc(m_filenames);
311 if (m_verbose && m_comm)
313 if (m_comm->TreatAsRankZero() && m_parameters.size() > 0)
315 cout <<
"Parameters:" << endl;
316 for (
auto &x : m_parameters)
318 cout <<
"\t" << x.first <<
" = " << x.second << endl;
323 if (m_comm->TreatAsRankZero() && m_solverInfo.size() > 0)
325 cout <<
"Solver Info:" << endl;
326 for (
auto &x : m_solverInfo)
328 cout <<
"\t" << x.first <<
" = " << x.second << endl;
335 void SessionReader::TestSharedFilesystem()
337 m_sharedFilesystem =
false;
339 if (m_comm->GetSize() > 1)
341 if (m_comm->GetRank() == 0)
343 std::ofstream testfile(
"shared-fs-testfile");
344 testfile <<
"" << std::endl;
345 ASSERTL1(!testfile.fail(),
"Test file creation failed");
350 int exists = (bool)boost::filesystem::exists(
"shared-fs-testfile");
353 m_sharedFilesystem = (exists == m_comm->GetSize());
355 if ((m_sharedFilesystem && m_comm->GetRank() == 0) ||
358 std::remove(
"shared-fs-testfile");
363 m_sharedFilesystem =
false;
366 if (m_verbose && m_comm->GetRank() == 0 && m_sharedFilesystem)
368 cout <<
"Shared filesystem detected" << endl;
377 std::vector<std::string> SessionReader::ParseCommandLineArguments(
378 int argc,
char *argv[])
381 po::options_description desc(
"Allowed options");
383 (
"verbose,v",
"be verbose")
384 (
"version,V",
"print version information")
385 (
"help,h",
"print this help message")
386 (
"solverinfo,I", po::value<vector<std::string> >(),
387 "override a SOLVERINFO property")
388 (
"parameter,P", po::value<vector<std::string> >(),
389 "override a parameter")
390 (
"npx", po::value<int>(),
391 "number of procs in X-dir")
392 (
"npy", po::value<int>(),
393 "number of procs in Y-dir")
394 (
"npz", po::value<int>(),
395 "number of procs in Z-dir")
396 (
"nsz", po::value<int>(),
397 "number of slices in Z-dir")
398 (
"part-only", po::value<int>(),
399 "only partition mesh into N partitions.")
400 (
"part-only-overlapping", po::value<int>(),
401 "only partition mesh into N overlapping partitions.")
402 (
"part-info",
"Output partition information")
403 #ifdef NEKTAR_USE_CWIPI
404 (
"cwipi", po::value<std::string>(),
409 for (
auto &cmdIt : GetCmdLineArgMap())
411 std::string names = cmdIt.first;
412 if (cmdIt.second.shortName !=
"")
414 names +=
"," + cmdIt.second.shortName;
416 if (cmdIt.second.isFlag)
419 (names.c_str(), cmdIt.second.description.c_str())
425 (names.c_str(), po::value<std::string>(),
426 cmdIt.second.description.c_str())
433 po::options_description hidden(
"Hidden options");
435 (
"input-file", po::value< vector<string> >(),
440 po::options_description all(
"All options");
441 all.add(desc).add(hidden);
444 po::positional_options_description
p;
445 p.add(
"input-file", -1);
448 po::parsed_options parsed = po::command_line_parser(argc, argv).
451 allow_unregistered().
455 po::store(parsed, m_cmdLineOptions);
456 po::notify(m_cmdLineOptions);
459 if (m_cmdLineOptions.count(
"help"))
466 if (m_cmdLineOptions.count(
"version"))
474 boost::replace_all(branch,
"refs/heads/",
"");
476 cout <<
" (git changeset " << sha1.substr(0, 8) <<
", ";
480 cout <<
"detached head";
484 cout <<
"head " << branch;
495 if (m_cmdLineOptions.count(
"verbose"))
505 for (
auto &x : parsed.options)
509 cout <<
"Warning: Unknown option: " << x.string_key
515 if (m_cmdLineOptions.count(
"input-file"))
517 return m_cmdLineOptions[
"input-file"].as<
518 std::vector<std::string> >();
522 return std::vector<std::string>();
530 std::string SessionReader::ParseSessionName(
531 std::vector<std::string> &filenames)
534 "At least one filename expected.");
536 std::string retval =
"";
539 std::string fname = filenames[0];
542 if (fname.size() > 4 &&
543 fname.substr(fname.size() - 4, 4) ==
"_xml")
545 retval = fname.substr(0, fname.find_last_of(
"_"));
548 else if (fname.size() > 4 &&
549 fname.substr(fname.size() - 4, 4) ==
".xml")
551 retval = fname.substr(0, fname.find_last_of(
"."));
554 else if (fname.size() > 7 &&
555 fname.substr(fname.size() - 7, 7) ==
".xml.gz")
557 retval = fname.substr(0, fname.find_last_of(
"."));
558 retval = retval.substr(0, retval.find_last_of(
"."));
568 TiXmlDocument& SessionReader::GetDocument()
570 ASSERTL1(m_xmlDoc,
"XML Document not defined.");
597 TiXmlElement* SessionReader::GetElement(
const string& pPath)
599 std::string vPath = boost::to_upper_copy(pPath);
600 std::vector<std::string> st;
601 boost::split(st, vPath, boost::is_any_of(
"\\/ "));
602 ASSERTL0(st.size() > 0,
"No path given in XML element request.");
604 TiXmlElement* vReturn = m_xmlDoc->FirstChildElement(st[0].c_str());
605 ASSERTL0(vReturn, std::string(
"Cannot find element '")
606 + st[0] + std::string(
"'."));
607 for (
int i = 1; i < st.size(); ++i)
609 vReturn = vReturn->FirstChildElement(st[i].c_str());
610 ASSERTL0(vReturn, std::string(
"Cannot find element '")
611 + st[i] + std::string(
"'."));
620 bool SessionReader::DefinesElement(
const std::string &pPath)
const
622 std::string vPath = boost::to_upper_copy(pPath);
623 std::vector<std::string> st;
624 boost::split(st, vPath, boost::is_any_of(
"\\/ "));
625 ASSERTL0(st.size() > 0,
"No path given in XML element request.");
627 TiXmlElement* vReturn = m_xmlDoc->FirstChildElement(st[0].c_str());
628 ASSERTL0(vReturn, std::string(
"Cannot find element '")
629 + st[0] + std::string(
"'."));
630 for (
int i = 1; i < st.size(); ++i)
632 vReturn = vReturn->FirstChildElement(st[i].c_str());
633 if (!vReturn)
return false;
642 const std::vector<std::string>& SessionReader::GetFilenames()
const
651 const std::string& SessionReader::GetSessionName()
const
653 return m_sessionName;
661 const std::string SessionReader::GetSessionNameRank()
const
663 std::string dirname = m_sessionName +
"_xml";
664 fs::path pdirname(dirname);
666 std::string vFilename =
"P" + boost::lexical_cast<std::string>(m_comm->GetRowComm()->GetRank());
667 fs::path pFilename(vFilename);
669 fs::path fullpath = pdirname / pFilename;
682 bool SessionReader::GetSharedFilesystem()
684 return m_sharedFilesystem;
702 bool SessionReader::DefinesParameter(
const std::string& pName)
const
704 std::string vName = boost::to_upper_copy(pName);
705 return m_parameters.find(vName) != m_parameters.end();
718 const std::string& pName)
const
720 std::string vName = boost::to_upper_copy(pName);
721 auto paramIter = m_parameters.find(vName);
723 ASSERTL0(paramIter != m_parameters.end(),
724 "Unable to find requested parameter: " + pName);
726 return paramIter->second;
733 void SessionReader::LoadParameter(
734 const std::string &pName,
int &pVar)
const
736 std::string vName = boost::to_upper_copy(pName);
737 auto paramIter = m_parameters.find(vName);
738 ASSERTL0(paramIter != m_parameters.end(),
"Required parameter '" +
739 pName +
"' not specified in session.");
740 NekDouble param = round(paramIter->second);
741 pVar = checked_cast<int>(param);
748 void SessionReader::LoadParameter(
749 const std::string &pName,
int &pVar,
const int &pDefault)
const
751 std::string vName = boost::to_upper_copy(pName);
752 auto paramIter = m_parameters.find(vName);
753 if(paramIter != m_parameters.end())
755 NekDouble param = round(paramIter->second);
756 pVar = checked_cast<int>(param);
768 void SessionReader::LoadParameter(
769 const std::string &pName,
NekDouble& pVar)
const
771 std::string vName = boost::to_upper_copy(pName);
772 auto paramIter = m_parameters.find(vName);
773 ASSERTL0(paramIter != m_parameters.end(),
"Required parameter '" +
774 pName +
"' not specified in session.");
775 pVar = paramIter->second;
782 void SessionReader::LoadParameter(
783 const std::string &pName,
787 std::string vName = boost::to_upper_copy(pName);
788 auto paramIter = m_parameters.find(vName);
789 if(paramIter != m_parameters.end())
791 pVar = paramIter->second;
804 void SessionReader::SetParameter(
const std::string &pName,
int &pVar)
806 std::string vName = boost::to_upper_copy(pName);
807 m_parameters[vName] = pVar;
814 void SessionReader::SetParameter(
815 const std::string &pName,
NekDouble& pVar)
817 std::string vName = boost::to_upper_copy(pName);
818 m_parameters[vName] = pVar;
826 bool SessionReader::DefinesSolverInfo(
const std::string &pName)
const
828 std::string vName = boost::to_upper_copy(pName);
829 auto infoIter = m_solverInfo.find(vName);
830 return (infoIter != m_solverInfo.end());
837 const std::string& SessionReader::GetSolverInfo(
838 const std::string &pProperty)
const
840 std::string vProperty = boost::to_upper_copy(pProperty);
841 auto iter = m_solverInfo.find(vProperty);
843 ASSERTL1(iter != m_solverInfo.end(),
844 "Unable to find requested property: " + pProperty);
852 void SessionReader::SetSolverInfo(
853 const std::string &pProperty,
const std::string &pValue)
855 std::string vProperty = boost::to_upper_copy(pProperty);
856 auto iter = m_solverInfo.find(vProperty);
858 ASSERTL1(iter != m_solverInfo.end(),
859 "Unable to find requested property: " + pProperty);
861 iter->second = pValue;
867 void SessionReader::LoadSolverInfo(
868 const std::string &pName,
870 const std::string &pDefault)
const
872 std::string vName = boost::to_upper_copy(pName);
873 auto infoIter = m_solverInfo.find(vName);
874 if(infoIter != m_solverInfo.end())
876 pVar = infoIter->second;
888 void SessionReader::MatchSolverInfo(
889 const std::string &pName,
890 const std::string &pTrueVal,
892 const bool &pDefault)
const
894 std::string vName = boost::to_upper_copy(pName);
895 auto infoIter = m_solverInfo.find(vName);
896 if(infoIter != m_solverInfo.end())
898 pVar = boost::iequals(infoIter->second, pTrueVal);
910 bool SessionReader::MatchSolverInfo(
911 const std::string &pName,
912 const std::string &pTrueVal)
const
914 if (DefinesSolverInfo(pName))
916 std::string vName = boost::to_upper_copy(pName);
917 auto iter = m_solverInfo.find(vName);
918 if(iter != m_solverInfo.end())
920 return boost::iequals(iter->second, pTrueVal);
930 bool SessionReader::DefinesGlobalSysSolnInfo(
const std::string &pVariable,
931 const std::string &pProperty)
const
933 auto iter = GetGloSysSolnList().find(pVariable);
934 if(iter == GetGloSysSolnList().end())
939 std::string vProperty = boost::to_upper_copy(pProperty);
941 auto iter1 = iter->second.find(vProperty);
942 if(iter1 == iter->second.end())
954 const std::string &SessionReader::GetGlobalSysSolnInfo(
const std::string &pVariable,
const std::string &pProperty)
const
956 auto iter = GetGloSysSolnList().find(pVariable);
957 ASSERTL0(iter != GetGloSysSolnList().end(),
958 "Failed to find variable in GlobalSysSolnInfoList");
960 std::string vProperty = boost::to_upper_copy(pProperty);
961 auto iter1 = iter->second.find(vProperty);
963 ASSERTL0(iter1 != iter->second.end(),
964 "Failed to find property: " + vProperty +
" in GlobalSysSolnInfoList");
966 return iter1->second;
969 std::string SessionReader::GetGeometryType()
const
971 TiXmlElement *xmlGeom = m_xmlDoc->FirstChildElement(
"NEKTAR")
972 ->FirstChildElement(
"GEOMETRY");
973 TiXmlAttribute *attr = xmlGeom->FirstAttribute();
976 std::string attrName(attr->Name());
977 if (attrName ==
"HDF5FILE")
988 TiXmlElement *element = xmlGeom->FirstChildElement(
"VERTEX");
990 element->QueryStringAttribute(
"COMPRESSED", &IsCompressed);
992 if (IsCompressed.size() > 0)
994 return "XmlCompressed";
1004 bool SessionReader::DefinesGeometricInfo(
const std::string &pName)
const
1006 std::string vName = boost::to_upper_copy(pName);
1007 return m_geometricInfo.find(vName) != m_geometricInfo.end();
1014 void SessionReader::LoadGeometricInfo(
1015 const std::string &pName,
1017 const std::string &pDefault)
const
1019 std::string vName = boost::to_upper_copy(pName);
1020 auto iter = m_geometricInfo.find(vName);
1021 if(iter != m_geometricInfo.end())
1023 pVar = iter->second;
1035 void SessionReader::LoadGeometricInfo(
1036 const std::string &pName,
1038 const bool &pDefault)
const
1040 std::string vName = boost::to_upper_copy(pName);
1041 auto iter = m_geometricInfo.find(vName);
1042 if(iter != m_geometricInfo.end())
1044 if (iter->second ==
"TRUE")
1063 void SessionReader::LoadGeometricInfo(
1064 const std::string &pName,
1068 std::string vName = boost::to_upper_copy(pName);
1069 auto iter = m_geometricInfo.find(vName);
1070 if(iter != m_geometricInfo.end())
1072 pVar = std::atoi(iter->second.c_str());
1084 void SessionReader::MatchGeometricInfo(
1085 const std::string &pName,
1086 const std::string &pTrueVal,
1088 const bool &pDefault)
const
1090 std::string vName = boost::to_upper_copy(pName);
1091 auto iter = m_geometricInfo.find(vName);
1092 if(iter != m_geometricInfo.end())
1094 pVar = boost::iequals(iter->second, pTrueVal);
1106 const std::string& SessionReader::GetVariable(
1107 const unsigned int &idx)
const
1109 ASSERTL0(idx < m_variables.size(),
"Variable index out of range.");
1110 return m_variables[idx];
1118 void SessionReader::SetVariable(
const unsigned int &idx,
1119 std::string newname)
1121 ASSERTL0(idx < m_variables.size(),
"Variable index out of range.");
1122 m_variables[idx] = newname;
1129 std::vector<std::string> SessionReader::GetVariables()
const
1138 bool SessionReader::DefinesFunction(
const std::string &pName)
const
1140 std::string vName = boost::to_upper_copy(pName);
1141 return m_functions.find(vName) != m_functions.end();
1148 bool SessionReader::DefinesFunction(
1149 const std::string &pName,
1150 const std::string &pVariable,
1151 const int pDomain)
const
1153 std::string vName = boost::to_upper_copy(pName);
1156 auto it1 = m_functions.find(vName);
1157 if (it1 != m_functions.end())
1159 pair<std::string, int> key(pVariable,pDomain);
1160 pair<std::string, int> defkey(
"*",pDomain);
1162 it1->second.find(key) != it1->second.end() ||
1163 it1->second.find(defkey) != it1->second.end();
1174 const std::string &pName,
1175 const std::string &pVariable,
1176 const int pDomain)
const
1178 std::string vName = boost::to_upper_copy(pName);
1179 auto it1 = m_functions.find(vName);
1182 std::string(
"No such function '") + pName
1183 + std::string(
"' has been defined in the session file."));
1186 pair<std::string,int> key(pVariable,pDomain);
1187 pair<std::string,int> defkey(
"*",pDomain);
1189 auto it2 = it1->second.find(key);
1190 auto it3 = it1->second.find(defkey);
1191 bool specific = it2 != it1->second.end();
1192 bool wildcard = it3 != it1->second.end();
1196 "No such variable " + pVariable
1197 +
" in domain " + boost::lexical_cast<string>(pDomain)
1198 +
" defined for function " + pName
1199 +
" in session file.");
1208 std::string(
"Function is defined by a file."));
1209 return it2->second.m_expression;
1217 const std::string &pName,
1218 const unsigned int &pVar,
1219 const int pDomain)
const
1221 ASSERTL0(pVar < m_variables.size(),
"Variable index out of range.");
1222 return GetFunction(pName, m_variables[pVar],pDomain);
1230 const std::string &pName,
1231 const std::string &pVariable,
1232 const int pDomain)
const
1234 std::string vName = boost::to_upper_copy(pName);
1235 auto it1 = m_functions.find(vName);
1237 ASSERTL0 (it1 != m_functions.end(),
1238 std::string(
"Function '") + pName
1239 + std::string(
"' not found."));
1242 pair<std::string,int> key(pVariable,pDomain);
1243 pair<std::string,int> defkey(
"*",pDomain);
1245 auto it2 = it1->second.find(key);
1246 auto it3 = it1->second.find(defkey);
1247 bool specific = it2 != it1->second.end();
1248 bool wildcard = it3 != it1->second.end();
1252 "No such variable " + pVariable
1253 +
" in domain " + boost::lexical_cast<string>(pDomain)
1254 +
" defined for function " + pName
1255 +
" in session file.");
1263 return it2->second.m_type;
1271 const std::string &pName,
1272 const unsigned int &pVar,
1273 const int pDomain)
const
1275 ASSERTL0(pVar < m_variables.size(),
"Variable index out of range.");
1276 return GetFunctionType(pName, m_variables[pVar],pDomain);
1283 std::string SessionReader::GetFunctionFilename(
1284 const std::string &pName,
1285 const std::string &pVariable,
1286 const int pDomain)
const
1288 std::string vName = boost::to_upper_copy(pName);
1289 auto it1 = m_functions.find(vName);
1291 ASSERTL0 (it1 != m_functions.end(),
1292 std::string(
"Function '") + pName
1293 + std::string(
"' not found."));
1296 pair<std::string,int> key(pVariable,pDomain);
1297 pair<std::string,int> defkey(
"*",pDomain);
1299 auto it2 = it1->second.find(key);
1300 auto it3 = it1->second.find(defkey);
1301 bool specific = it2 != it1->second.end();
1302 bool wildcard = it3 != it1->second.end();
1306 "No such variable " + pVariable
1307 +
" in domain " + boost::lexical_cast<string>(pDomain)
1308 +
" defined for function " + pName
1309 +
" in session file.");
1317 return it2->second.m_filename;
1324 std::string SessionReader::GetFunctionFilename(
1325 const std::string &pName,
1326 const unsigned int &pVar,
1327 const int pDomain)
const
1329 ASSERTL0(pVar < m_variables.size(),
"Variable index out of range.");
1330 return GetFunctionFilename(pName, m_variables[pVar],pDomain);
1337 std::string SessionReader::GetFunctionFilenameVariable(
1338 const std::string &pName,
1339 const std::string &pVariable,
1340 const int pDomain)
const
1342 std::string vName = boost::to_upper_copy(pName);
1343 auto it1 = m_functions.find(vName);
1345 ASSERTL0 (it1 != m_functions.end(),
1346 std::string(
"Function '") + pName
1347 + std::string(
"' not found."));
1350 pair<std::string,int> key(pVariable,pDomain);
1351 pair<std::string,int> defkey(
"*",pDomain);
1353 auto it2 = it1->second.find(key);
1354 auto it3 = it1->second.find(defkey);
1355 bool specific = it2 != it1->second.end();
1356 bool wildcard = it3 != it1->second.end();
1360 "No such variable " + pVariable
1361 +
" in domain " + boost::lexical_cast<string>(pDomain)
1362 +
" defined for function " + pName
1363 +
" in session file.");
1371 return it2->second.m_fileVariable;
1378 bool SessionReader::DefinesTag(
const std::string &pName)
const
1380 std::string vName = boost::to_upper_copy(pName);
1381 return m_tags.find(vName) != m_tags.end();
1388 void SessionReader::SetTag(
1389 const std::string &pName,
1390 const std::string &pValue)
1392 std::string vName = boost::to_upper_copy(pName);
1393 m_tags[vName] = pValue;
1400 const std::string &SessionReader::GetTag(
const std::string& pName)
const
1402 std::string vName = boost::to_upper_copy(pName);
1403 auto vTagIterator = m_tags.find(vName);
1404 ASSERTL0(vTagIterator != m_tags.end(),
1405 "Requested tag does not exist.");
1406 return vTagIterator->second;
1422 bool SessionReader::DefinesCmdLineArgument(
1423 const std::string& pName)
const
1425 return (m_cmdLineOptions.find(pName) != m_cmdLineOptions.end());
1432 void SessionReader::SubstituteExpressions(std::string& pExpr)
1434 for (
auto &exprIter : m_expressions)
1436 boost::replace_all(pExpr, exprIter.first, exprIter.second);
1443 void SessionReader::LoadDoc(
1444 const std::string &pFilename,
1445 TiXmlDocument* pDoc)
const
1447 if (pFilename.size() > 3 &&
1448 pFilename.substr(pFilename.size() - 3, 3) ==
".gz")
1450 ifstream file(pFilename.c_str(),
1451 ios_base::in | ios_base::binary);
1452 ASSERTL0(file.good(),
"Unable to open file: " + pFilename);
1454 io::filtering_streambuf<io::input> in;
1455 in.push(io::gzip_decompressor());
1462 catch (io::gzip_error&)
1465 "Error: File '" + pFilename +
"' is corrupt.");
1468 else if (pFilename.size() > 4 &&
1469 pFilename.substr(pFilename.size() - 4, 4) ==
"_xml")
1471 fs::path pdirname(pFilename);
1473 pad % m_comm->GetRank();
1474 fs::path pRankFilename(pad.str());
1475 fs::path fullpath = pdirname / pRankFilename;
1478 ASSERTL0(file.good(),
"Unable to open file: " + fullpath.string());
1483 ifstream file(pFilename.c_str());
1484 ASSERTL0(file.good(),
"Unable to open file: " + pFilename);
1492 TiXmlDocument *SessionReader::MergeDoc(
1493 const std::vector<std::string> &pFilenames)
const
1495 ASSERTL0(pFilenames.size() > 0,
"No filenames for merging.");
1498 TiXmlDocument *vMainDoc =
new TiXmlDocument;
1499 LoadDoc(pFilenames[0], vMainDoc);
1501 TiXmlHandle vMainHandle(vMainDoc);
1502 TiXmlElement* vMainNektar =
1503 vMainHandle.FirstChildElement(
"NEKTAR").Element();
1508 for (
int i = 1; i < pFilenames.size(); ++i)
1510 if((pFilenames[i].compare(pFilenames[i].size()-3,3,
"xml") == 0)
1511 ||(pFilenames[i].compare(pFilenames[i].size()-6,6,
"xml.gz") == 0))
1513 TiXmlDocument* vTempDoc =
new TiXmlDocument;
1514 LoadDoc(pFilenames[i], vTempDoc);
1516 TiXmlHandle docHandle(vTempDoc);
1517 TiXmlElement* vTempNektar;
1518 vTempNektar = docHandle.FirstChildElement(
"NEKTAR").Element();
1519 ASSERTL0(vTempNektar,
"Unable to find NEKTAR tag in file.");
1520 TiXmlElement*
p = vTempNektar->FirstChildElement();
1524 TiXmlElement *vMainEntry =
1525 vMainNektar->FirstChildElement(
p->Value());
1528 if (!
p->FirstChild() && vMainEntry)
1530 std::string warningmsg =
1531 "File " + pFilenames[i] +
" contains " +
1532 "an empty XML element " +
1533 std::string(
p->Value()) +
1534 " which will be ignored.";
1535 NEKERROR(ErrorUtil::ewarning, warningmsg.c_str());
1541 vMainNektar->RemoveChild(vMainEntry);
1543 TiXmlElement *q =
new TiXmlElement(*
p);
1544 vMainNektar->LinkEndChild(q);
1546 p =
p->NextSiblingElement();
1559 void SessionReader::ParseDocument()
1562 ASSERTL0(m_xmlDoc,
"No XML document loaded.");
1565 TiXmlHandle docHandle(m_xmlDoc);
1567 e = docHandle.FirstChildElement(
"NEKTAR").
1568 FirstChildElement(
"CONDITIONS").Element();
1573 ReadGlobalSysSolnInfo (e);
1574 ReadExpressions (e);
1578 e = docHandle.FirstChildElement(
"NEKTAR").
1579 FirstChildElement(
"FILTERS").Element();
1588 void SessionReader::CreateComm(
1598 string vCommModule(
"Serial");
1601 vCommModule =
"ParallelMPI";
1603 if (m_cmdLineOptions.count(
"cwipi") &&
GetCommFactory().ModuleExists(
"CWIPI"))
1605 vCommModule =
"CWIPI";
1619 void SessionReader::PartitionComm()
1621 if (m_comm->GetSize() > 1)
1627 if (DefinesCmdLineArgument(
"npx")) {
1628 nProcX = GetCmdLineArgument<int>(
"npx");
1630 if (DefinesCmdLineArgument(
"npy")) {
1631 nProcY = GetCmdLineArgument<int>(
"npy");
1633 if (DefinesCmdLineArgument(
"npz")) {
1634 nProcZ = GetCmdLineArgument<int>(
"npz");
1636 if (DefinesCmdLineArgument(
"nsz")) {
1637 nStripZ = GetCmdLineArgument<int>(
"nsz");
1639 ASSERTL0(m_comm->GetSize() % (nProcZ*nProcY*nProcX) == 0,
1640 "Cannot exactly partition using PROC_Z value.");
1642 "Cannot exactly partition using PROC_Y value.");
1644 "Cannot exactly partition using PROC_X value.");
1647 int nProcSm = nProcZ * nProcY * nProcX;
1651 int nProcSem = m_comm->GetSize() / nProcSm;
1653 m_comm->SplitComm(nProcSm,nProcSem);
1654 m_comm->GetColumnComm()->SplitComm(nProcZ/nStripZ,nStripZ);
1655 m_comm->GetColumnComm()->GetColumnComm()->SplitComm(
1656 (nProcY*nProcX),nProcZ/nStripZ);
1657 m_comm->GetColumnComm()->GetColumnComm()->GetColumnComm()
1658 ->SplitComm(nProcX,nProcY);
1666 void SessionReader::ReadParameters(TiXmlElement *conditions)
1668 m_parameters.clear();
1675 TiXmlElement *parametersElement = conditions->FirstChildElement(
1680 if (parametersElement)
1682 TiXmlElement *parameter =
1683 parametersElement->FirstChildElement(
"P");
1691 stringstream tagcontent;
1692 tagcontent << *parameter;
1693 TiXmlNode *node = parameter->FirstChild();
1695 while (node && node->Type() != TiXmlNode::TINYXML_TEXT)
1697 node = node->NextSibling();
1703 std::string line = node->ToText()->Value(),
lhs,
rhs;
1706 ParseEquals(line,
lhs,
rhs);
1711 "Syntax error in parameter expression '"
1712 + line +
"' in XML element: \n\t'"
1713 + tagcontent.str() +
"'");
1719 if (!
lhs.empty() && !
rhs.empty())
1725 m_interpreter,
rhs);
1728 catch (
const std::runtime_error &)
1731 "Error evaluating parameter expression"
1732 " '" +
rhs +
"' in XML element: \n\t'"
1733 + tagcontent.str() +
"'");
1735 m_interpreter->SetParameter(
lhs, value);
1736 caseSensitiveParameters[
lhs] = value;
1737 boost::to_upper(
lhs);
1738 m_parameters[
lhs] = value;
1742 parameter = parameter->NextSiblingElement();
1751 void SessionReader::ReadSolverInfo(TiXmlElement *conditions)
1753 m_solverInfo.clear();
1754 m_solverInfo = GetSolverInfoDefaults();
1761 TiXmlElement *solverInfoElement =
1762 conditions->FirstChildElement(
"SOLVERINFO");
1764 if (solverInfoElement)
1766 TiXmlElement *solverInfo =
1767 solverInfoElement->FirstChildElement(
"I");
1771 std::stringstream tagcontent;
1772 tagcontent << *solverInfo;
1774 ASSERTL0(solverInfo->Attribute(
"PROPERTY"),
1775 "Missing PROPERTY attribute in solver info "
1776 "XML element: \n\t'" + tagcontent.str() +
"'");
1777 std::string solverProperty =
1778 solverInfo->Attribute(
"PROPERTY");
1780 "PROPERTY attribute must be non-empty in XML "
1781 "element: \n\t'" + tagcontent.str() +
"'");
1784 std::string solverPropertyUpper =
1785 boost::to_upper_copy(solverProperty);
1788 ASSERTL0(solverInfo->Attribute(
"VALUE"),
1789 "Missing VALUE attribute in solver info "
1790 "XML element: \n\t'" + tagcontent.str() +
"'");
1791 std::string solverValue = solverInfo->Attribute(
"VALUE");
1793 "VALUE attribute must be non-empty in XML "
1794 "element: \n\t'" + tagcontent.str() +
"'");
1797 m_solverInfo[solverPropertyUpper] = solverValue;
1798 solverInfo = solverInfo->NextSiblingElement(
"I");
1802 if (m_comm && m_comm->GetRowComm()->GetSize() > 1)
1805 m_solverInfo[
"GLOBALSYSSOLN"] ==
"IterativeFull" ||
1806 m_solverInfo[
"GLOBALSYSSOLN"] ==
"IterativeStaticCond" ||
1807 m_solverInfo[
"GLOBALSYSSOLN"] ==
1808 "IterativeMultiLevelStaticCond" ||
1809 m_solverInfo[
"GLOBALSYSSOLN"] ==
"XxtFull" ||
1810 m_solverInfo[
"GLOBALSYSSOLN"] ==
"XxtStaticCond" ||
1811 m_solverInfo[
"GLOBALSYSSOLN"] ==
1812 "XxtMultiLevelStaticCond" ||
1813 m_solverInfo[
"GLOBALSYSSOLN"] ==
"PETScFull" ||
1814 m_solverInfo[
"GLOBALSYSSOLN"] ==
"PETScStaticCond" ||
1815 m_solverInfo[
"GLOBALSYSSOLN"] ==
1816 "PETScMultiLevelStaticCond",
1817 "A parallel solver must be used when run in parallel.");
1826 void SessionReader::ReadGlobalSysSolnInfo(TiXmlElement *conditions)
1828 GetGloSysSolnList().clear();
1835 TiXmlElement *GlobalSys =
1836 conditions->FirstChildElement(
"GLOBALSYSSOLNINFO");
1843 TiXmlElement *VarInfo = GlobalSys->FirstChildElement(
"V");
1847 std::stringstream tagcontent;
1848 tagcontent << *VarInfo;
1849 ASSERTL0(VarInfo->Attribute(
"VAR"),
1850 "Missing VAR attribute in GobalSysSolnInfo XML "
1851 "element: \n\t'" + tagcontent.str() +
"'");
1853 std::string VarList = VarInfo->Attribute(
"VAR");
1855 "VAR attribute must be non-empty in XML element:\n\t'"
1856 + tagcontent.str() +
"'");
1859 std::vector<std::string> varStrings;
1860 bool valid = ParseUtils::GenerateVector(VarList, varStrings);
1862 ASSERTL0(valid,
"Unable to process list of variable in XML "
1863 "element \n\t'" + tagcontent.str() +
"'");
1865 if(varStrings.size())
1867 TiXmlElement *SysSolnInfo = VarInfo->FirstChildElement(
"I");
1872 tagcontent << *SysSolnInfo;
1874 ASSERTL0(SysSolnInfo->Attribute(
"PROPERTY"),
1875 "Missing PROPERTY attribute in "
1876 "GlobalSysSolnInfo for variable(s) '"
1877 + VarList +
"' in XML element: \n\t'"
1878 + tagcontent.str() +
"'");
1880 std::string SysSolnProperty =
1881 SysSolnInfo->Attribute(
"PROPERTY");
1884 "GlobalSysSolnIno properties must have a "
1885 "non-empty name for variable(s) : '"
1886 + VarList +
"' in XML element: \n\t'"
1887 + tagcontent.str() +
"'");
1890 std::string SysSolnPropertyUpper =
1891 boost::to_upper_copy(SysSolnProperty);
1894 ASSERTL0(SysSolnInfo->Attribute(
"VALUE"),
1895 "Missing VALUE attribute in GlobalSysSolnInfo "
1896 "for variable(s) '" + VarList
1897 +
"' in XML element: \n\t"
1898 + tagcontent.str() +
"'");
1900 std::string SysSolnValue =
1901 SysSolnInfo->Attribute(
"VALUE");
1903 "GlobalSysSolnInfo properties must have a "
1904 "non-empty value for variable(s) '"
1905 + VarList +
"' in XML element: \n\t'"
1906 + tagcontent.str() +
"'");
1909 for(
int i = 0; i < varStrings.size(); ++i)
1911 auto x = GetGloSysSolnList().find(varStrings[i]);
1912 if (x == GetGloSysSolnList().end())
1914 (GetGloSysSolnList()[varStrings[i]])[
1915 SysSolnPropertyUpper] = SysSolnValue;
1919 x->second[SysSolnPropertyUpper] = SysSolnValue;
1923 SysSolnInfo = SysSolnInfo->NextSiblingElement(
"I");
1925 VarInfo = VarInfo->NextSiblingElement(
"V");
1929 if (m_verbose && GetGloSysSolnList().size() > 0 && m_comm)
1931 if(m_comm->GetRank() == 0)
1933 cout <<
"GlobalSysSoln Info:" << endl;
1935 for (
auto &x : GetGloSysSolnList())
1937 cout <<
"\t Variable: " << x.first << endl;
1939 for (
auto &y : x.second)
1941 cout <<
"\t\t " << y.first <<
" = " << y.second
1954 void SessionReader::ReadExpressions(TiXmlElement *conditions)
1956 m_expressions.clear();
1963 TiXmlElement *expressionsElement =
1964 conditions->FirstChildElement(
"EXPRESSIONS");
1966 if (expressionsElement)
1968 TiXmlElement *expr = expressionsElement->FirstChildElement(
"E");
1972 stringstream tagcontent;
1973 tagcontent << *expr;
1975 "Missing NAME attribute in expression "
1976 "definition: \n\t'" + tagcontent.str() +
"'");
1977 std::string nameString = expr->Attribute(
"NAME");
1979 "Expressions must have a non-empty name: \n\t'"
1980 + tagcontent.str() +
"'");
1983 "Missing VALUE attribute in expression "
1984 "definition: \n\t'" + tagcontent.str() +
"'");
1985 std::string valString = expr->Attribute(
"VALUE");
1987 "Expressions must have a non-empty value: \n\t'"
1988 + tagcontent.str() +
"'");
1990 auto exprIter = m_expressions.find(nameString);
1991 ASSERTL0(exprIter == m_expressions.end(),
1992 std::string(
"Expression '") + nameString
1993 + std::string(
"' already specified."));
1995 m_expressions[nameString] = valString;
1996 expr = expr->NextSiblingElement(
"E");
2005 void SessionReader::ReadVariables(TiXmlElement *conditions)
2007 m_variables.clear();
2014 TiXmlElement *variablesElement =
2015 conditions->FirstChildElement(
"VARIABLES");
2019 if (variablesElement)
2021 TiXmlElement *varElement =
2022 variablesElement->FirstChildElement(
"V");
2025 int nextVariableNumber = -1;
2029 stringstream tagcontent;
2030 tagcontent << *varElement;
2034 nextVariableNumber++;
2037 int err = varElement->QueryIntAttribute(
"ID", &i);
2039 "Variables must have a unique ID number attribute "
2040 "in XML element: \n\t'" + tagcontent.str() +
"'");
2042 "ID numbers for variables must begin with zero and"
2043 " be sequential in XML element: \n\t'"
2044 + tagcontent.str() +
"'");
2046 TiXmlNode* varChild = varElement->FirstChild();
2051 while(varChild && varChild->Type() != TiXmlNode::TINYXML_TEXT)
2053 varChild = varChild->NextSibling();
2057 "Unable to read variable definition body for "
2059 + boost::lexical_cast<string>(i)
2060 +
" in XML element: \n\t'"
2061 + tagcontent.str() +
"'");
2062 std::string variableName = varChild->ToText()->ValueStr();
2064 std::istringstream variableStrm(variableName);
2065 variableStrm >> variableName;
2068 variableName) == m_variables.end(),
2070 + boost::lexical_cast<string>(i)
2071 +
" in XML element \n\t'" + tagcontent.str()
2072 +
"'\nhas already been defined.");
2074 m_variables.push_back(variableName);
2076 varElement = varElement->NextSiblingElement(
"V");
2080 "Number of variables must be greater than zero.");
2088 void SessionReader::ReadFunctions(TiXmlElement *conditions)
2090 m_functions.clear();
2098 TiXmlElement *
function = conditions->FirstChildElement(
"FUNCTION");
2101 stringstream tagcontent;
2102 tagcontent << *
function;
2105 ASSERTL0(function->Attribute(
"NAME"),
2106 "Functions must have a NAME attribute defined in XML "
2107 "element: \n\t'" + tagcontent.str() +
"'");
2108 std::string functionStr =
function->Attribute(
"NAME");
2110 "Functions must have a non-empty name in XML "
2111 "element: \n\t'" + tagcontent.str() +
"'");
2114 boost::to_upper(functionStr);
2117 TiXmlElement *variable =
function->FirstChildElement();
2126 std::string conditionType = variable->Value();
2129 std::string variableStr;
2130 if (!variable->Attribute(
"VAR"))
2136 variableStr = variable->Attribute(
"VAR");
2140 std::vector<std::string> variableList;
2141 ParseUtils::GenerateVector(variableStr, variableList);
2144 std::string domainStr;
2145 if (!variable->Attribute(
"DOMAIN"))
2151 domainStr = variable->Attribute(
"DOMAIN");
2155 std::string evarsStr =
"x y z t";
2156 if (variable->Attribute(
"EVARS"))
2158 evarsStr = evarsStr + std::string(
" ") + variable->Attribute(
"EVARS");
2162 std::vector<std::string> varSplit;
2163 std::vector<unsigned int> domainList;
2164 ParseUtils::GenerateSeqVector(domainStr, domainList);
2167 if (conditionType ==
"E")
2172 ASSERTL0(variable->Attribute(
"VALUE"),
2173 "Attribute VALUE expected for function '"
2174 + functionStr +
"'.");
2175 std::string fcnStr = variable->Attribute(
"VALUE");
2178 (std::string(
"Expression for var: ")
2180 + std::string(
" must be specified.")).c_str());
2182 SubstituteExpressions(fcnStr);
2190 else if (conditionType ==
"F")
2192 if (variable->Attribute(
"TIMEDEPENDENT") &&
2193 boost::lexical_cast<bool>(variable->Attribute(
"TIMEDEPENDENT")))
2203 ASSERTL0(variable->Attribute(
"FILE"),
2204 "Attribute FILE expected for function '"
2205 + functionStr +
"'.");
2206 std::string filenameStr = variable->Attribute(
"FILE");
2209 "A filename must be specified for the FILE "
2210 "attribute of function '" + functionStr
2213 std::vector<std::string> fSplit;
2214 boost::split(fSplit, filenameStr, boost::is_any_of(
":"));
2216 ASSERTL0(fSplit.size() == 1 || fSplit.size() == 2,
2217 "Incorrect filename specification in function "
2218 + functionStr +
"'. "
2219 "Specify variables inside file as: "
2220 "filename:var1,var2");
2225 if (fSplit.size() == 2)
2228 "Filename variable mapping not valid "
2229 "when using * as a variable inside "
2230 "function '" + functionStr +
"'.");
2233 varSplit, fSplit[1], boost::is_any_of(
","));
2234 ASSERTL0(varSplit.size() == variableList.size(),
2235 "Filename variables should contain the "
2236 "same number of variables defined in "
2237 "VAR in function " + functionStr +
"'.");
2244 stringstream tagcontent;
2245 tagcontent << *variable;
2248 "Identifier " + conditionType +
" in function "
2249 + std::string(function->Attribute(
"NAME"))
2250 +
" is not recognised in XML element: \n\t'"
2251 + tagcontent.str() +
"'");
2257 for (
unsigned int i = 0; i < variableList.size(); ++i)
2259 for(
unsigned int j = 0; j < domainList.size(); ++j)
2262 pair<std::string,int> key(variableList[i],domainList[j]);
2263 auto fcnsIter = functionVarMap.find(key);
2264 ASSERTL0(fcnsIter == functionVarMap.end(),
2265 "Error setting expression '" + variableList[i]
2267 + boost::lexical_cast<std::string>(domainList[j])
2268 +
"' in function '" + functionStr +
"'. "
2269 "Expression has already been defined.");
2271 if (varSplit.size() > 0)
2275 functionVarMap[key] = funcDef2;
2279 functionVarMap[key] = funcDef;
2284 variable = variable->NextSiblingElement();
2287 m_functions[functionStr] = functionVarMap;
2288 function =
function->NextSiblingElement(
"FUNCTION");
2296 void SessionReader::ReadFilters(TiXmlElement *filters)
2305 TiXmlElement *filter = filters->FirstChildElement(
"FILTER");
2308 ASSERTL0(filter->Attribute(
"TYPE"),
2309 "Missing attribute 'TYPE' for filter.");
2310 std::string typeStr = filter->Attribute(
"TYPE");
2312 std::map<std::string, std::string> vParams;
2314 TiXmlElement *param = filter->FirstChildElement(
"PARAM");
2318 "Missing attribute 'NAME' for parameter in filter "
2320 std::string nameStr = param->Attribute(
"NAME");
2322 ASSERTL0(param->GetText(),
"Empty value string for param.");
2323 std::string valueStr = param->GetText();
2325 vParams[nameStr] = valueStr;
2327 param = param->NextSiblingElement(
"PARAM");
2330 m_filters.push_back(
2331 std::pair<std::string, FilterParams>(typeStr, vParams));
2333 filter = filter->NextSiblingElement(
"FILTER");
2337 void SessionReader::ParseEquals(
2338 const std::string &line,
2343 size_t beg = line.find_first_not_of(
" ");
2344 size_t end = line.find_first_of(
"=");
2346 if (beg == end)
throw 1;
2348 if (end != line.find_last_of(
"="))
throw 1;
2350 if (end == std::string::npos)
throw 1;
2352 lhs = line.substr(line.find_first_not_of(
" "),
2354 lhs =
lhs .substr(0,
lhs.find_last_not_of(
" ")+1);
2355 rhs = line.substr(line.find_last_of(
"=")+1);
2356 rhs =
rhs .substr(
rhs.find_first_not_of(
" "));
2357 rhs =
rhs .substr(0,
rhs.find_last_not_of(
" ")+1);
2363 void SessionReader::CmdLineOverride()
2366 if (m_cmdLineOptions.count(
"solverinfo"))
2368 std::vector<std::string> solverInfoList =
2369 m_cmdLineOptions[
"solverinfo"].as<
2370 std::vector<std::string> >();
2372 for (
size_t i = 0; i < solverInfoList.size(); ++i)
2378 ParseEquals(solverInfoList[i],
lhs,
rhs);
2383 "Parse error with command line "
2384 "option: "+solverInfoList[i]);
2387 std::string lhsUpper = boost::to_upper_copy(
lhs);
2388 m_solverInfo[lhsUpper] =
rhs;
2392 if (m_cmdLineOptions.count(
"parameter"))
2394 std::vector<std::string> parametersList =
2395 m_cmdLineOptions[
"parameter"].as<
2396 std::vector<std::string> >();
2398 for (
size_t i = 0; i < parametersList.size(); ++i)
2404 ParseEquals(parametersList[i],
lhs,
rhs);
2409 "Parse error with command line "
2410 "option: "+parametersList[i]);
2413 std::string lhsUpper = boost::to_upper_copy(
lhs);
2417 m_parameters[lhsUpper] =
2418 boost::lexical_cast<NekDouble>(
rhs);
2423 "Unable to convert string: "+
rhs+
2424 "to double value.");
2430 void SessionReader::VerifySolverInfo()
2432 for (
auto &x : m_solverInfo)
2434 std::string solverProperty = x.first;
2435 std::string solverValue = x.second;
2437 auto propIt = GetSolverInfoEnums().find(solverProperty);
2438 if (propIt != GetSolverInfoEnums().end())
2440 auto valIt = propIt->second.find(solverValue);
2441 ASSERTL0(valIt != propIt->second.end(),
2442 "Value '" + solverValue +
"' is not valid for "
2443 "property '" + solverProperty +
"'");
2449 void SessionReader::SetUpXmlDoc(
void)
2451 m_xmlDoc = MergeDoc(m_filenames);
2456 return m_interpreter;
#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.
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static void Finalise(gs_data *pGsh)
Deallocates the GSLib mapping data.
std::shared_ptr< Interpreter > InterpreterSharedPtr
std::map< std::string, std::string > SolverInfoMap
std::map< std::string, GloSysInfoMap > GloSysSolnInfoList
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
std::vector< std::pair< std::string, FilterParams > > FilterMap
std::map< std::string, EnumMap > EnumMapList
CommFactory & GetCommFactory()
std::map< std::string, CmdLineArg > CmdLineArgMap
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
@ eFunctionTypeExpression
@ eFunctionTypeTransientFile
std::map< std::pair< std::string, int >, FunctionVariableDefinition > FunctionVariableMap
const std::string kGitBranch
const std::string kGitSha1
InputIterator find(InputIterator first, InputIterator last, InputIterator startingpoint, const EqualityComparable &value)
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs
EquationSharedPtr m_expression
std::string m_fileVariable