www.mooseframework.org
MooseUtils.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 // MOOSE includes
11 #include "MooseUtils.h"
12 #include "MooseError.h"
13 #include "MaterialProperty.h"
14 #include "MultiMooseEnum.h"
15 #include "InputParameters.h"
16 #include "ExecFlagEnum.h"
17 #include "InfixIterator.h"
18 
19 #include "libmesh/elem.h"
20 
21 // External includes
22 #include "pcrecpp.h"
23 #include "tinydir.h"
24 
25 // C++ includes
26 #include <iostream>
27 #include <fstream>
28 #include <istream>
29 #include <iterator>
30 #include <ctime>
31 
32 // System includes
33 #include <sys/stat.h>
34 #include <numeric>
35 #include <unistd.h>
36 
37 std::string getLatestCheckpointFileHelper(const std::list<std::string> & checkpoint_files,
38  const std::vector<std::string> extensions,
39  bool keep_extension);
40 
41 namespace MooseUtils
42 {
43 
44 std::string
45 convertLatestCheckpoint(std::string orig, bool base_only)
46 {
47  auto slash_pos = orig.find_last_of("/");
48  auto path = orig.substr(0, slash_pos);
49  auto file = orig.substr(slash_pos + 1);
50  if (file != "LATEST")
51  return orig;
52 
54  if (!base_only)
56  else if (converted.empty())
57  mooseError("Unable to find suitable recovery file!");
58  return converted;
59 }
60 
61 // this implementation is copied from
62 // https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#C.2B.2B
63 int
64 levenshteinDist(const std::string & s1, const std::string & s2)
65 {
66  // To change the type this function manipulates and returns, change
67  // the return type and the types of the two variables below.
68  auto s1len = s1.size();
69  auto s2len = s2.size();
70 
71  auto column_start = (decltype(s1len))1;
72 
73  auto column = new decltype(s1len)[s1len + 1];
74  std::iota(column + column_start, column + s1len + 1, column_start);
75 
76  for (auto x = column_start; x <= s2len; x++)
77  {
78  column[0] = x;
79  auto last_diagonal = x - column_start;
80  for (auto y = column_start; y <= s1len; y++)
81  {
82  auto old_diagonal = column[y];
83  auto possibilities = {
84  column[y] + 1, column[y - 1] + 1, last_diagonal + (s1[y - 1] == s2[x - 1] ? 0 : 1)};
85  column[y] = std::min(possibilities);
86  last_diagonal = old_diagonal;
87  }
88  }
89  auto result = column[s1len];
90  delete[] column;
91  return result;
92 }
93 
94 void
95 escape(std::string & str)
96 {
97  std::map<char, std::string> escapes;
98  escapes['\a'] = "\\a";
99  escapes['\b'] = "\\b";
100  escapes['\f'] = "\\f";
101  escapes['\n'] = "\\n";
102  escapes['\t'] = "\\t";
103  escapes['\v'] = "\\v";
104  escapes['\r'] = "\\r";
105 
106  for (const auto & it : escapes)
107  for (size_t pos = 0; (pos = str.find(it.first, pos)) != std::string::npos;
108  pos += it.second.size())
109  str.replace(pos, 1, it.second);
110 }
111 
112 std::string
113 trim(const std::string & str, const std::string & white_space)
114 {
115  const auto begin = str.find_first_not_of(white_space);
116  if (begin == std::string::npos)
117  return ""; // no content
118  const auto end = str.find_last_not_of(white_space);
119  return str.substr(begin, end - begin + 1);
120 }
121 
122 bool
123 pathContains(const std::string & expression,
124  const std::string & string_to_find,
125  const std::string & delims)
126 {
127  std::vector<std::string> elements;
128  tokenize(expression, elements, 0, delims);
129 
130  std::vector<std::string>::iterator found_it =
131  std::find(elements.begin(), elements.end(), string_to_find);
132  if (found_it != elements.end())
133  return true;
134  else
135  return false;
136 }
137 
138 bool
139 pathExists(const std::string & path)
140 {
141  struct stat buffer;
142  return (stat(path.c_str(), &buffer) == 0);
143 }
144 
145 bool
146 checkFileReadable(const std::string & filename, bool check_line_endings, bool throw_on_unreadable)
147 {
148  std::ifstream in(filename.c_str(), std::ifstream::in);
149  if (in.fail())
150  {
151  if (throw_on_unreadable)
152  mooseError(
153  (std::string("Unable to open file \"") + filename +
154  std::string("\". Check to make sure that it exists and that you have read permission."))
155  .c_str());
156  else
157  return false;
158  }
159 
160  if (check_line_endings)
161  {
162  std::istream_iterator<char> iter(in);
163  std::istream_iterator<char> eos;
164  in >> std::noskipws;
165  while (iter != eos)
166  if (*iter++ == '\r')
167  mooseError(filename + " contains Windows(DOS) line endings which are not supported.");
168  }
169 
170  in.close();
171 
172  return true;
173 }
174 
175 bool
176 checkFileWriteable(const std::string & filename, bool throw_on_unwritable)
177 {
178  std::ofstream out(filename.c_str(), std::ofstream::out);
179  if (out.fail())
180  {
181  if (throw_on_unwritable)
182  mooseError(
183  (std::string("Unable to open file \"") + filename +
184  std::string("\". Check to make sure that it exists and that you have write permission."))
185  .c_str());
186  else
187  return false;
188  }
189 
190  out.close();
191 
192  return true;
193 }
194 
195 void
196 parallelBarrierNotify(const Parallel::Communicator & comm, bool messaging)
197 {
198  processor_id_type slave_processor_id;
199 
200  if (messaging)
201  Moose::out << "Waiting For Other Processors To Finish" << std::endl;
202  if (comm.rank() == 0)
203  {
204  // The master process is already through, so report it
205  if (messaging)
206  Moose::out << "Jobs complete: 1/" << comm.size() << (1 == comm.size() ? "\n" : "\r")
207  << std::flush;
208  for (unsigned int i = 2; i <= comm.size(); ++i)
209  {
210  comm.receive(MPI_ANY_SOURCE, slave_processor_id);
211  if (messaging)
212  Moose::out << "Jobs complete: " << i << "/" << comm.size()
213  << (i == comm.size() ? "\n" : "\r") << std::flush;
214  }
215  }
216  else
217  {
218  slave_processor_id = comm.rank();
219  comm.send(0, slave_processor_id);
220  }
221 
222  comm.barrier();
223 }
224 
225 void
226 serialBegin(const libMesh::Parallel::Communicator & comm, bool warn)
227 {
228  // unless we are the first processor...
229  if (comm.rank() > 0)
230  {
231  // ...wait for the previous processor to finish
232  int dummy = 0;
233  comm.receive(comm.rank() - 1, dummy);
234  }
235  else if (warn)
236  mooseWarning("Entering serial execution block (use only for debugging)");
237 }
238 
239 void
240 serialEnd(const libMesh::Parallel::Communicator & comm, bool warn)
241 {
242  // unless we are the last processor...
243  if (comm.rank() + 1 < comm.size())
244  {
245  // ...notify the next processor of its turn
246  int dummy = 0;
247  comm.send(comm.rank() + 1, dummy);
248  }
249 
250  comm.barrier();
251  if (comm.rank() == 0 && warn)
252  mooseWarning("Leaving serial execution block (use only for debugging)");
253 }
254 
255 bool
256 hasExtension(const std::string & filename, std::string ext, bool strip_exodus_ext)
257 {
258  // Extract the extension, w/o the '.'
259  std::string file_ext;
260  if (strip_exodus_ext)
261  {
262  pcrecpp::RE re(
263  ".*\\.([^\\.]*?)(?:-s\\d+)?\\s*$"); // capture the complete extension, ignoring -s*
264  re.FullMatch(filename, &file_ext);
265  }
266  else
267  {
268  pcrecpp::RE re(".*\\.([^\\.]*?)\\s*$"); // capture the complete extension
269  re.FullMatch(filename, &file_ext);
270  }
271 
272  // Perform the comparision
273  if (file_ext == ext)
274  return true;
275  else
276  return false;
277 }
278 
279 std::string
280 stripExtension(const std::string & s)
281 {
282  auto pos = s.rfind(".");
283  if (pos != std::string::npos)
284  return s.substr(0, pos);
285  return s;
286 }
287 
288 std::pair<std::string, std::string>
289 splitFileName(std::string full_file)
290 {
291  // Error if path ends with /
292  if (full_file.empty() || *full_file.rbegin() == '/')
293  mooseError("Invalid full file name: ", full_file);
294 
295  // Define the variables to output
296  std::string path;
297  std::string file;
298 
299  // Locate the / sepearting the file from path
300  std::size_t found = full_file.find_last_of("/");
301 
302  // If no / is found used "." for the path, otherwise seperate the two
303  if (found == std::string::npos)
304  {
305  path = ".";
306  file = full_file;
307  }
308  else
309  {
310  path = full_file.substr(0, found);
311  file = full_file.substr(found + 1);
312  }
313 
314  // Return the path and file as a pair
315  return std::pair<std::string, std::string>(path, file);
316 }
317 
318 std::string
319 camelCaseToUnderscore(const std::string & camel_case_name)
320 {
321  string replaced = camel_case_name;
322  // Put underscores in front of each contiguous set of capital letters
323  pcrecpp::RE("(?!^)(?<![A-Z_])([A-Z]+)").GlobalReplace("_\\1", &replaced);
324 
325  // Convert all capital letters to lower case
326  std::transform(replaced.begin(), replaced.end(), replaced.begin(), ::tolower);
327  return replaced;
328 }
329 
330 std::string
331 underscoreToCamelCase(const std::string & underscore_name, bool leading_upper_case)
332 {
333  pcrecpp::StringPiece input(underscore_name);
334  pcrecpp::RE re("([^_]*)(_|$)");
335 
336  std::string result;
337  std::string us, not_us;
338  bool make_upper = leading_upper_case;
339  while (re.Consume(&input, &not_us, &us))
340  {
341  if (not_us.length() > 0)
342  {
343  if (make_upper)
344  {
345  result += std::toupper(not_us[0]);
346  if (not_us.length() > 1)
347  result += not_us.substr(1);
348  }
349  else
350  result += not_us;
351  }
352  if (us == "")
353  break;
354 
355  // Toggle flag so next match is upper cased
356  make_upper = true;
357  }
358 
359  return result;
360 }
361 
362 std::string
363 shortName(const std::string & name)
364 {
365  return name.substr(name.find_last_of('/') != std::string::npos ? name.find_last_of('/') + 1 : 0);
366 }
367 
368 std::string
369 baseName(const std::string & name)
370 {
371  return name.substr(0, name.find_last_of('/') != std::string::npos ? name.find_last_of('/') : 0);
372 }
373 
374 std::string
376 {
377  // This is from: https://stackoverflow.com/a/505546
378  char hostname[1024];
379  hostname[1023] = '\0';
380 
381  auto failure = gethostname(hostname, 1023);
382 
383  if (failure)
384  mooseError("Failed to retrieve hostname!");
385 
386  return hostname;
387 }
388 
389 void
391  const HashMap<const libMesh::Elem *, HashMap<unsigned int, MaterialProperties>> & props)
392 {
393  // Loop through the elements
394  for (const auto & elem_it : props)
395  {
396  Moose::out << "Element " << elem_it.first->id() << '\n';
397 
398  // Loop through the sides
399  for (const auto & side_it : elem_it.second)
400  {
401  Moose::out << " Side " << side_it.first << '\n';
402 
403  // Loop over properties
404  unsigned int cnt = 0;
405  for (const auto & mat_prop : side_it.second)
406  {
407  MaterialProperty<Real> * mp = dynamic_cast<MaterialProperty<Real> *>(mat_prop);
408  if (mp)
409  {
410  Moose::out << " Property " << cnt << '\n';
411  cnt++;
412 
413  // Loop over quadrature points
414  for (unsigned int qp = 0; qp < mp->size(); ++qp)
415  Moose::out << " prop[" << qp << "] = " << (*mp)[qp] << '\n';
416  }
417  }
418  }
419  }
420 }
421 
422 std::string &
423 removeColor(std::string & msg)
424 {
425  pcrecpp::RE re("(\\33\\[3[0-7]m))", pcrecpp::DOTALL());
426  re.GlobalReplace(std::string(""), &msg);
427  return msg;
428 }
429 
430 void
431 indentMessage(const std::string & prefix,
432  std::string & message,
433  const char * color /*= COLOR_CYAN*/)
434 {
435  // First we need to see if the message we need to indent (with color) also contains color codes
436  // that span lines.
437  // The code matches all of the XTERM constants (see XTermConstants.h). If it does, then we'll work
438  // on formatting
439  // each colored multiline chunk one at a time with the right codes.
440  std::string colored_message;
441  std::string curr_color = COLOR_DEFAULT; // tracks last color code before newline
442  std::string line, color_code;
443 
444  std::istringstream iss(message);
445  for (std::string line; std::getline(iss, line);) // loop over each line
446  {
447  const static pcrecpp::RE match_color(".*(\\33\\[3\\dm)((?!\\33\\[3\\d)[^\n])*");
448  pcrecpp::StringPiece line_piece(line);
449  match_color.FindAndConsume(&line_piece, &color_code);
450  colored_message += color + prefix + ": " + curr_color + line + "\n";
451 
452  if (!color_code.empty())
453  curr_color = color_code; // remember last color of this line
454  }
455  message = colored_message;
456 }
457 
458 std::list<std::string>
459 listDir(const std::string path, bool files_only)
460 {
461  std::list<std::string> files;
462 
463  tinydir_dir dir;
464  dir.has_next = 0; // Avoid a garbage value in has_next (clang StaticAnalysis)
465  tinydir_open(&dir, path.c_str());
466 
467  while (dir.has_next)
468  {
469  tinydir_file file;
470  file.is_dir = 0; // Avoid a garbage value in is_dir (clang StaticAnalysis)
471  tinydir_readfile(&dir, &file);
472 
473  if (!files_only || !file.is_dir)
474  files.push_back(path + "/" + file.name);
475 
476  tinydir_next(&dir);
477  }
478 
479  tinydir_close(&dir);
480 
481  return files;
482 }
483 
484 std::list<std::string>
485 getFilesInDirs(const std::list<std::string> & directory_list)
486 {
487  std::list<std::string> files;
488 
489  for (const auto & dir_name : directory_list)
490  files.splice(files.end(), listDir(dir_name, true));
491 
492  return files;
493 }
494 
495 std::string
496 getLatestMeshCheckpointFile(const std::list<std::string> & checkpoint_files)
497 {
498  const static std::vector<std::string> extensions{"cpr"};
499 
500  return getLatestCheckpointFileHelper(checkpoint_files, extensions, true);
501 }
502 
503 std::string
504 getLatestAppCheckpointFileBase(const std::list<std::string> & checkpoint_files)
505 {
506  const static std::vector<std::string> extensions{"xda", "xdr"};
507 
508  return getLatestCheckpointFileHelper(checkpoint_files, extensions, false);
509 }
510 
511 bool
512 wildCardMatch(std::string name, std::string search_string)
513 {
514  // Assume that an empty string matches anything
515  if (search_string == "")
516  return true;
517 
518  // transform to lower for case insenstive matching
519  std::transform(name.begin(), name.end(), name.begin(), (int (*)(int))std::toupper);
520  std::transform(search_string.begin(),
521  search_string.end(),
522  search_string.begin(),
523  (int (*)(int))std::toupper);
524 
525  // exact match!
526  if (search_string.find("*") == std::string::npos)
527  return search_string == name;
528 
529  // wildcard
530  std::vector<std::string> tokens;
531  MooseUtils::tokenize(search_string, tokens, 1, "*");
532 
533  size_t pos = 0;
534  for (unsigned int i = 0; i < tokens.size() && pos != std::string::npos; ++i)
535  {
536  pos = name.find(tokens[i], pos);
537  // See if we have a leading wildcard
538  if (search_string[0] != '*' && i == 0 && pos != 0)
539  return false;
540  }
541 
542  if (pos != std::string::npos && tokens.size() > 0)
543  {
544  // Now see if we have a trailing wildcard
545  size_t last_token_length = tokens.back().length();
546  if (*search_string.rbegin() == '*' || pos == name.size() - last_token_length)
547  return true;
548  else
549  return false;
550  }
551  else
552  return false;
553 }
554 
555 template <typename T>
556 T
557 convertStringToInt(const std::string & str, bool throw_on_failure)
558 {
559  T val;
560 
561  // Let's try to read a double and see if we can cast it to an int
562  // This would be the case for scientific notation
563  long double double_val;
564  std::stringstream double_ss(str);
565 
566  if ((double_ss >> double_val).fail() || !double_ss.eof())
567  {
568  std::string msg =
569  std::string("Unable to convert '") + str + "' to type " + demangle(typeid(T).name());
570 
571  if (throw_on_failure)
572  throw std::invalid_argument(msg);
573  else
574  mooseError(msg);
575  }
576 
577  // Check to see if it's an integer (and within range of an integer
578  if (double_val == static_cast<T>(double_val))
579  val = double_val;
580  else // Still failure
581  {
582  std::string msg =
583  std::string("Unable to convert '") + str + "' to type " + demangle(typeid(T).name());
584 
585  if (throw_on_failure)
586  throw std::invalid_argument(msg);
587  else
588  mooseError(msg);
589  }
590 
591  return val;
592 }
593 
594 template <>
595 short int
596 convert<short int>(const std::string & str, bool throw_on_failure)
597 {
598  return convertStringToInt<short int>(str, throw_on_failure);
599 }
600 
601 template <>
602 unsigned short int
603 convert<unsigned short int>(const std::string & str, bool throw_on_failure)
604 {
605  return convertStringToInt<unsigned short int>(str, throw_on_failure);
606 }
607 
608 template <>
609 int
610 convert<int>(const std::string & str, bool throw_on_failure)
611 {
612  return convertStringToInt<int>(str, throw_on_failure);
613 }
614 
615 template <>
616 unsigned int
617 convert<unsigned int>(const std::string & str, bool throw_on_failure)
618 {
619  return convertStringToInt<unsigned int>(str, throw_on_failure);
620 }
621 
622 template <>
623 long int
624 convert<long int>(const std::string & str, bool throw_on_failure)
625 {
626  return convertStringToInt<long int>(str, throw_on_failure);
627 }
628 
629 template <>
630 unsigned long int
631 convert<unsigned long int>(const std::string & str, bool throw_on_failure)
632 {
633  return convertStringToInt<unsigned long int>(str, throw_on_failure);
634 }
635 
636 template <>
637 long long int
638 convert<long long int>(const std::string & str, bool throw_on_failure)
639 {
640  return convertStringToInt<long long int>(str, throw_on_failure);
641 }
642 
643 template <>
644 unsigned long long int
645 convert<unsigned long long int>(const std::string & str, bool throw_on_failure)
646 {
647  return convertStringToInt<unsigned long long int>(str, throw_on_failure);
648 }
649 
650 std::string
651 toUpper(const std::string & name)
652 {
653  std::string upper(name);
654  std::transform(upper.begin(), upper.end(), upper.begin(), ::toupper);
655  return upper;
656 }
657 
658 std::string
659 toLower(const std::string & name)
660 {
661  std::string lower(name);
662  std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
663  return lower;
664 }
665 
668 {
669  ExecFlagEnum exec_enum = ExecFlagEnum();
670  exec_enum.addAvailableFlags(EXEC_NONE,
671  EXEC_INITIAL,
672  EXEC_LINEAR,
676  EXEC_FINAL,
677  EXEC_CUSTOM);
678  return exec_enum;
679 }
680 
681 int
682 stringToInteger(const std::string & input, bool throw_on_failure)
683 {
684  return convert<int>(input, throw_on_failure);
685 }
686 
687 void
688 
689 linearPartitionItems(dof_id_type num_items,
690  dof_id_type num_chunks,
691  dof_id_type chunk_id,
692  dof_id_type & num_local_items,
693  dof_id_type & local_items_begin,
694  dof_id_type & local_items_end)
695 {
696  auto global_num_local_items = num_items / num_chunks;
697 
698  num_local_items = global_num_local_items;
699 
700  auto leftovers = num_items % num_chunks;
701 
702  if (chunk_id < leftovers)
703  {
704  num_local_items++;
705  local_items_begin = num_local_items * chunk_id;
706  }
707  else
708  local_items_begin =
709  (global_num_local_items + 1) * leftovers + global_num_local_items * (chunk_id - leftovers);
710 
711  local_items_end = local_items_begin + num_local_items;
712 }
713 
714 processor_id_type
715 linearPartitionChunk(dof_id_type num_items, dof_id_type num_chunks, dof_id_type item_id)
716 {
717  auto global_num_local_items = num_items / num_chunks;
718 
719  auto leftovers = num_items % num_chunks;
720 
721  auto first_item_past_first_part = leftovers * (global_num_local_items + 1);
722 
723  // Is it in the first section (that gets an extra item)
724  if (item_id < first_item_past_first_part)
725  return item_id / (global_num_local_items + 1);
726  else
727  {
728  auto new_item_id = item_id - first_item_past_first_part;
729 
730  // First chunk after the first section + the number of chunks after that
731  return leftovers + (new_item_id / global_num_local_items);
732  }
733 }
734 
735 std::vector<std::string>
736 split(const std::string & str, const std::string & delimiter)
737 {
738  std::vector<std::string> output;
739  size_t prev = 0, pos = 0;
740  do
741  {
742  pos = str.find(delimiter, prev);
743  output.push_back(str.substr(prev, pos - prev));
744  prev = pos + delimiter.length();
745  } while (pos != string::npos);
746  return output;
747 }
748 
749 template <typename T>
750 std::string
751 join(const T & strings, const std::string & delimiter)
752 {
753  std::ostringstream oss;
754  std::copy(
755  strings.begin(), strings.end(), infix_ostream_iterator<std::string>(oss, delimiter.c_str()));
756  return oss.str();
757 }
758 template std::string join<std::vector<std::string>>(const std::vector<std::string> &,
759  const std::string &);
760 template std::string join<std::set<std::string>>(const std::set<std::string> &,
761  const std::string &);
762 template std::string join<std::vector<MooseEnumItem>>(const std::vector<MooseEnumItem> &,
763  const std::string &);
764 template std::string join<std::set<MooseEnumItem>>(const std::set<MooseEnumItem> &,
765  const std::string &);
766 
767 void
768 createSymlink(const std::string & target, const std::string & link)
769 {
770  clearSymlink(link);
771  int err = symlink(target.c_str(), link.c_str());
772  if (err != 0)
773  mooseError("Failed to create symbolic link (via 'symlink') from ", target, " to ", link);
774 }
775 
776 void
777 clearSymlink(const std::string & link)
778 {
779  struct stat sbuf;
780  if (lstat(link.c_str(), &sbuf) == 0)
781  {
782  int err = unlink(link.c_str());
783  if (err != 0)
784  mooseError("Failed to remove symbolic link (via 'unlink') to ", link);
785  }
786 }
787 
788 std::size_t
789 fileSize(const std::string & filename)
790 {
791  struct stat buffer;
792  if (stat(filename.c_str(), &buffer))
793  return 0;
794 
795  return buffer.st_size;
796 }
797 } // MooseUtils namespace
798 
799 std::string
800 getLatestCheckpointFileHelper(const std::list<std::string> & checkpoint_files,
801  const std::vector<std::string> extensions,
802  bool keep_extension)
803 {
804  // Create storage for newest restart files
805  // Note that these might have the same modification time if the simulation was fast.
806  // In that case we're going to save all of the "newest" files and sort it out momentarily
807  std::time_t newest_time = 0;
808  std::list<std::string> newest_restart_files;
809 
810  // Loop through all possible files and store the newest
811  for (const auto & cp_file : checkpoint_files)
812  {
813  if (find_if(extensions.begin(), extensions.end(), [cp_file](const std::string & ext) {
814  return MooseUtils::hasExtension(cp_file, ext);
815  }) != extensions.end())
816  {
817  struct stat stats;
818  stat(cp_file.c_str(), &stats);
819 
820  std::time_t mod_time = stats.st_mtime;
821  if (mod_time > newest_time)
822  {
823  newest_restart_files.clear(); // If the modification time is greater, clear the list
824  newest_time = mod_time;
825  }
826 
827  if (mod_time == newest_time)
828  newest_restart_files.push_back(cp_file);
829  }
830  }
831 
832  // Loop through all of the newest files according the number in the file name
833  int max_file_num = -1;
834  std::string max_base;
835  std::string max_file;
836 
837  pcrecpp::RE re_file_num(".*?(\\d+)(?:_mesh)?$"); // Pull out the embedded number from the file
838 
839  // Now, out of the newest files find the one with the largest number in it
840  for (const auto & res_file : newest_restart_files)
841  {
842  auto dot_pos = res_file.find_last_of(".");
843  auto the_base = res_file.substr(0, dot_pos);
844  int file_num = 0;
845 
846  re_file_num.FullMatch(the_base, &file_num);
847 
848  if (file_num > max_file_num)
849  {
850  max_file_num = file_num;
851  max_base = the_base;
852  max_file = res_file;
853  }
854  }
855 
856  // Error if nothing was located
857  if (max_file_num == -1)
858  {
859  max_base.clear();
860  max_file.clear();
861  }
862 
863  return keep_extension ? max_file : max_base;
864 }
865 
866 void
867 removeSubstring(std::string & main, const std::string & sub)
868 {
869  std::string::size_type n = sub.length();
870  for (std::string::size_type i = main.find(sub); i != std::string::npos; i = main.find(sub))
871  main.erase(i, n);
872 }
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:24
void serialEnd(const libMesh::Parallel::Communicator &comm, bool warn=true)
Closes a section of code that is executed in serial rank by rank, and that was opened with a call to ...
Definition: MooseUtils.C:240
std::string toLower(const std::string &name)
Convert supplied string to lower case.
Definition: MooseUtils.C:659
void tokenize(const std::string &str, std::vector< T > &elements, unsigned int min_len=1, const std::string &delims="/")
This function will split the passed in string on a set of delimiters appending the substrings to the ...
Definition: MooseUtils.h:532
const ExecFlagType EXEC_CUSTOM
HashMap is an abstraction for dictionary data type, we make it thread-safe by locking inserts...
Definition: HashMap.h:18
int stringToInteger(const std::string &input, bool throw_on_failure=false)
Robust string to integer conversion that fails for cases such at "1foo".
Definition: MooseUtils.C:682
std::string toUpper(const std::string &name)
Convert supplied string to upper case.
Definition: MooseUtils.C:651
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:207
void MaterialPropertyStorageDump(const HashMap< const libMesh::Elem *, HashMap< unsigned int, MaterialProperties >> &props)
Function to dump the contents of MaterialPropertyStorage for debugging purposes.
Definition: MooseUtils.C:390
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
Definition: MooseError.h:219
const ExecFlagType EXEC_NONE
void indentMessage(const std::string &prefix, std::string &message, const char *color=COLOR_CYAN)
Indents the supplied message given the prefix and color.
Definition: MooseUtils.C:431
std::list< std::string > getFilesInDirs(const std::list< std::string > &directory_list)
Retrieves the names of all of the files contained within the list of directories passed into the rout...
Definition: MooseUtils.C:485
std::string stripExtension(const std::string &s)
Removes any file extension from the fiven string s (i.e.
Definition: MooseUtils.C:280
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
Add additional execute_on flags to the list of possible flags.
Definition: ExecFlagEnum.h:84
const ExecFlagType EXEC_TIMESTEP_END
void linearPartitionItems(dof_id_type num_items, dof_id_type num_chunks, dof_id_type chunk_id, dof_id_type &num_local_items, dof_id_type &local_items_begin, dof_id_type &local_items_end)
Linearly partition a number of items.
Definition: MooseUtils.C:689
static PetscErrorCode Vec x
std::string convertLatestCheckpoint(std::string orig, bool base_only=true)
Replaces "LATEST" placeholders with the latest checkpoint file name.
Definition: MooseUtils.C:45
std::string hostname()
Get the hostname the current process is running on.
Definition: MooseUtils.C:375
std::string camelCaseToUnderscore(const std::string &camel_case_name)
Function for converting a camel case name to a name containing underscores.
Definition: MooseUtils.C:319
std::string shortName(const std::string &name)
Function for stripping name after the file / in parser block.
Definition: MooseUtils.C:363
void removeSubstring(std::string &main, const std::string &sub)
find, erase, length algorithm for removing a substring from a string
Definition: MooseUtils.C:867
std::string getLatestAppCheckpointFileBase(const std::list< std::string > &checkpoint_files)
Definition: MooseUtils.C:504
ExecFlagEnum getDefaultExecFlagEnum()
Return the default ExecFlagEnum for MOOSE.
Definition: MooseUtils.C:667
T convertStringToInt(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:557
std::vector< std::string > split(const std::string &str, const std::string &delimiter)
Python like split function for strings.
Definition: MooseUtils.C:736
bool checkFileReadable(const std::string &filename, bool check_line_endings=false, bool throw_on_unreadable=true)
Checks to see if a file is readable (exists and permissions)
Definition: MooseUtils.C:146
std::pair< std::string, std::string > splitFileName(std::string full_file)
Function for splitting path and filename.
Definition: MooseUtils.C:289
int convert< int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:610
void parallelBarrierNotify(const libMesh::Parallel::Communicator &comm, bool messaging=true)
This function implements a parallel barrier function but writes progress to stdout.
const ExecFlagType EXEC_TIMESTEP_BEGIN
void serialBegin(const libMesh::Parallel::Communicator &comm, bool warn=true)
This function marks the begin of a section of code that is executed in serial rank by rank...
Definition: MooseUtils.C:226
std::string trim(const std::string &str, const std::string &white_space=" \\\)
Standard scripting language trim function.
Definition: MooseUtils.C:113
std::size_t fileSize(const std::string &filename)
Check the file size.
Definition: MooseUtils.C:789
unsigned int convert< unsigned int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:617
std::string underscoreToCamelCase(const std::string &underscore_name, bool leading_upper_case)
Function for converting an underscore name to a camel case name.
Definition: MooseUtils.C:331
bool hasExtension(const std::string &filename, std::string ext, bool strip_exodus_ext=false)
Function tests if the supplied filename as the desired extension.
Definition: MooseUtils.C:256
std::string & removeColor(std::string &msg)
remove ANSI escape sequences for teminal color from msg
Definition: MooseUtils.C:423
std::string getLatestMeshCheckpointFile(const std::list< std::string > &checkpoint_files)
Returns the most recent checkpoint or mesh file given a list of files.
Definition: MooseUtils.C:496
const ExecFlagType EXEC_LINEAR
bool checkFileWriteable(const std::string &filename, bool throw_on_unwritable=true)
Check if the file is writable (path exists and permissions)
Definition: MooseUtils.C:176
std::string getLatestCheckpointFileHelper(const std::list< std::string > &checkpoint_files, const std::vector< std::string > extensions, bool keep_extension)
Definition: MooseUtils.C:800
void clearSymlink(const std::string &link)
Remove a symbolic link, if the given filename is a link.
Definition: MooseUtils.C:777
long long int convert< long long int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:638
processor_id_type linearPartitionChunk(dof_id_type num_items, dof_id_type num_chunks, dof_id_type item_id)
Return the chunk_id that is assigned to handle item_id.
Definition: MooseUtils.C:715
const ExecFlagType EXEC_NONLINEAR
void createSymlink(const std::string &target, const std::string &link)
Create a symbolic link, if the link already exists it is replaced.
Definition: MooseUtils.C:768
short int convert< short int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:596
unsigned long int convert< unsigned long int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:631
std::string baseName(const std::string &name)
Function for string the information before the final / in a parser block.
Definition: MooseUtils.C:369
bool wildCardMatch(std::string name, std::string search_string)
Definition: MooseUtils.C:512
PetscInt n
MPI_Comm comm
std::list< std::string > listDir(const std::string path, bool files_only=false)
Definition: MooseUtils.C:459
int levenshteinDist(const std::string &s1, const std::string &s2)
Computes and returns the Levenshtein distance between strings s1 and s2.
Definition: MooseUtils.C:64
long int convert< long int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:624
unsigned short int convert< unsigned short int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:603
bool pathContains(const std::string &expression, const std::string &string_to_find, const std::string &delims="/")
This function tokenizes a path and checks to see if it contains the string to look for...
Definition: MooseUtils.C:123
bool pathExists(const std::string &path)
Definition: MooseUtils.C:139
virtual unsigned int size() const override
unsigned long long int convert< unsigned long long int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:645
const ExecFlagType EXEC_FINAL
std::string join(const T &strings, const std::string &delimiter)
Python like join function for strings.
Definition: MooseUtils.C:751
void escape(std::string &str)
This function will escape all of the standard C++ escape characters so that they can be printed...
Definition: MooseUtils.C:95
const ExecFlagType EXEC_INITIAL