oomph_utilities.h
Go to the documentation of this file.
1 // LIC// ====================================================================
2 // LIC// This file forms part of oomph-lib, the object-oriented,
3 // LIC// multi-physics finite-element library, available
4 // LIC// at http://www.oomph-lib.org.
5 // LIC//
6 // LIC// Copyright (C) 2006-2023 Matthias Heil and Andrew Hazel
7 // LIC//
8 // LIC// This library is free software; you can redistribute it and/or
9 // LIC// modify it under the terms of the GNU Lesser General Public
10 // LIC// License as published by the Free Software Foundation; either
11 // LIC// version 2.1 of the License, or (at your option) any later version.
12 // LIC//
13 // LIC// This library is distributed in the hope that it will be useful,
14 // LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // LIC// Lesser General Public License for more details.
17 // LIC//
18 // LIC// You should have received a copy of the GNU Lesser General Public
19 // LIC// License along with this library; if not, write to the Free Software
20 // LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // LIC// 02110-1301 USA.
22 // LIC//
23 // LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 // LIC//
25 // LIC//====================================================================
26 // A header containing useful utility classes, functions and constants
27 
28 // Include guard to prevent multiple inclusions of the header
29 #ifndef OOMPH_UTILITIES_HEADER
30 #define OOMPH_UTILITIES_HEADER
31 
32 // Config header generated by autoconfig
33 #ifdef HAVE_CONFIG_H
34 #include <oomph-lib-config.h>
35 #endif
36 
37 
38 #ifdef OOMPH_HAS_MPI
39 // mpi headers
40 #include "mpi.h"
41 #endif
42 
43 // Standard libray headers
44 #include <string>
45 #include <sstream>
46 #include <fstream>
47 #include <cmath>
48 #include <map>
49 #include <ctime>
50 #include <complex>
51 
52 // oomph-lib headers
53 #include "Vector.h"
54 #include "oomph_definitions.h"
55 #include "communicator.h"
56 
57 /* // Header for cxx-prettyprint: A C++ Container Pretty-Printer. If the */
58 /* // standard in use is older than C++11 then use a special older version of */
59 /* // the header. Header is from here: */
60 /* // http://louisdx.github.io/cxx-prettyprint/ */
61 /* #if __cplusplus <= 199711L */
62 /* #include "prettyprint98.h" */
63 /* #else */
64 /* #include "prettyprint.h" */
65 /* #endif */
66 
67 // Header for name demangling
68 #include <cxxabi.h>
69 
70 namespace oomph
71 {
72  //======start_of_ANSIEscapeCode_namespace=================
73  /// Contains an enumeration of the ANSI escape codes used for
74  /// colouring text (when piped to the command line). Adapted from
75  /// the guide on:
76  /// https://stackoverflow.com/questions/2616906/how-do-i-output-
77  /// coloured-text-to-a-linux-terminal?utm_medium=organic&utm_source=
78  /// google_rich_qa&utm_campaign=google_rich_qa
79  /// Here, \033 is the ESC character, ASCII 27. It is followed by [,
80  /// then zero or more numbers separated by ;, and finally the letter
81  /// m. The numbers describe the colour and format to switch to from
82  /// that point onwards.
83  //====================================================================
84  namespace ANSIEscapeCode
85  {
86  /// Function to change text effect. NOTE: This assumes the user
87  /// knows what they're doing/assigning; no error checking done here...
88  extern void set_text_effect(std::string text_effect);
89 
90  /// Variable to decide on effects
91  extern std::string Text_effect;
92 
93  /// The code for each type of colour
94  extern std::string Black;
95  extern std::string Red;
96  extern std::string Green;
97  extern std::string Yellow;
98  extern std::string Blue;
99  extern std::string Magenta;
100  extern std::string Cyan;
101  extern std::string Reset;
102  } // namespace ANSIEscapeCode
103 
104  //=====================================================================
105  /// Namespace for debugging helpers. Currently only contains a
106  /// function to prett-ify file name and line numbers (in red) to use
107  /// when debugging. Makes it easy to identify where a std::cout
108  /// statement was called.
109  //=====================================================================
110  namespace DebugHelpers
111  {
112  /// Return the concaternation of the initials of the input
113  /// file name and line number. The make_new_line flag indicates
114  /// whether the string starts on a new line or not
115  extern std::string debug_string(const std::string& filename,
116  const int& line,
117  const bool& make_new_line = false);
118  } // namespace DebugHelpers
119 
120  // Forward declaration needed for second invariant helper
121  template<class TYPE>
122  class DenseMatrix;
123 
124  //=====================================================================
125  /// Helper namespace containing function that computes second invariant
126  /// of tensor
127  //=====================================================================
128  namespace SecondInvariantHelper
129  {
130  /// Compute second invariant of tensor
131  extern double second_invariant(const DenseMatrix<double>& tensor);
132 
133  } // namespace SecondInvariantHelper
134 
135 
136  //==============================================
137  /// Namespace for error messages for broken
138  /// copy constructors and assignment operators
139  //==============================================
140  namespace BrokenCopy
141  {
142  /// Issue error message and terminate execution
143  extern void broken_assign(const std::string& class_name);
144 
145  /// Issue error message and terminate execution
146  extern void broken_copy(const std::string& class_name);
147 
148  } // namespace BrokenCopy
149 
150  //========================================
151  /// Namespace for mathematical constants
152  ///
153  //=======================================
154  namespace MathematicalConstants
155  {
156  /// 50 digits from maple
157  const double Pi = 3.1415926535897932384626433832795028841971693993751;
158 
159  /// The imaginary unit
160  const std::complex<double> I(0.0, 1.0);
161  } // namespace MathematicalConstants
162 
163 
164  //================================================================
165  /// Function-type-object to perform absolute comparison of objects.
166  /// Apparently this inlines better
167  //================================================================
168  template<class T>
169  class AbsCmp
170  {
171  public:
172  /// Comparison. Are the values identical or not?
173  bool operator()(const T& x, const T& y) const
174  {
175  return std::abs(x) < std::abs(y);
176  }
177  };
178 
179 
180  // =================================================================
181  /// Conversion functions for easily making strings (e.g. for filenames - to
182  /// avoid stack smashing problems with cstrings and long filenames).
183  // =================================================================
184  namespace StringConversion
185  {
186  /// Conversion function that should work for anything with
187  /// operator<< defined (at least all basic types).
188  template<class T>
189  std::string to_string(T object, unsigned float_precision = 8)
190  {
191  std::stringstream ss;
192  ss.precision(float_precision);
193  ss << object;
194  return ss.str();
195  }
196 
197  /// Convert a string to lower case (outputs a copy).
198  std::string to_lower(const std::string& input);
199 
200  /// Convert a string to upper case (outputs a copy).
201  std::string to_upper(const std::string& input);
202 
203  /// Split a string, s, into a vector of strings where ever there is
204  /// an instance of delimiter (i.e. is delimiter is " " will give a list of
205  /// words). Note that multiple delimiters in a row will give empty
206  /// strings.
207  void split_string(const std::string& s,
208  char delim,
209  Vector<std::string>& elems);
210 
211  /// Split a string, s, into a vector of strings where ever there is
212  /// an instance of delimiter (i.e. is delimiter is " " will give a list of
213  /// words). Note that multiple delimiters in a row will give empty
214  /// strings. Return by value.
215  Vector<std::string> split_string(const std::string& s, char delim);
216 
217  } // namespace StringConversion
218 
219 
220  namespace TypeNames
221  {
222  /// Get the type name of an object. Only for use in debugging, do
223  /// not write real code using this function as it is implementation
224  /// dependant!
225  template<class T>
227  {
228  using namespace StringConversion;
229 
230  int status;
231  std::string typestr =
232  to_string(abi::__cxa_demangle(typeid(obj).name(), 0, 0, &status));
233 
234  // Throw if there was an error
235  if (status != 0)
236  {
237  std::string err = "Error code " + to_string(status) +
238  " in demangler, see documentation of "
239  "abi::__cxa_demangle for the meaning";
240  throw OomphLibError(
241  err, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
242  }
243 
244  return typestr;
245  }
246 
247  /// Get the type name of an object from a pointer to the object (we
248  /// usually want the type of the object itself not the pointer because the
249  /// type of the pointer may be a base class). Only for use in debugging,
250  /// do not write real code using this function as it is implementation
251  /// dependant!
252  template<class T>
254  {
255  return get_type_name(*obj);
256  }
257 
258  } // namespace TypeNames
259 
260  /// ///////////////////////////////////////////////////////////////
261  /// ///////////////////////////////////////////////////////////////
262  /// ///////////////////////////////////////////////////////////////
263 
264 
265  //====================================================================
266  /// Namespace for global (cumulative) timings
267  //====================================================================
268  namespace CumulativeTimings
269  {
270  /// (Re-)start i-th timer
271  extern void start(const unsigned& i);
272 
273  /// Halt i-th timer
274  extern void halt(const unsigned& i);
275 
276  /// Reset i-th timer
277  extern void reset(const unsigned& i);
278 
279  /// Reset all timers
280  extern void reset();
281 
282  /// Report time accumulated by i-th timer
283  extern double cumulative_time(const unsigned& i);
284 
285  /// Set number of timings that can be recorded in parallel
286  extern void set_ntimers(const unsigned& ntimers);
287 
288  /// Cumulative timings
289  extern Vector<clock_t> Timing;
290 
291  /// Start times of active timers
292  extern Vector<clock_t> Start_time;
293 
294  } // namespace CumulativeTimings
295 
296 
297  // ============================================================
298  // Automatically checked casting functions (from boost)
299  // ============================================================
300 
301  /// Runtime checked dynamic cast. This is the safe but slightly slower
302  /// cast. Use it in any of these cases:
303  /// - You aren't entirely sure the cast is always safe.
304  /// - You have strange inheritance structures (e.g. the "Diamond of Death" in
305  /// element inheritance).
306  /// - Efficiency is not critical.
307  /// Note that if you just want to check if a pointer can be converted to
308  /// some type you will need to use a plain dynamic_cast. Adapted from
309  /// polymorphic_cast in boost/cast.hpp, see
310  /// http://www.boost.org/doc/libs/1_52_0/libs/conversion/cast.htm for more
311  /// details.
312  template<class Target, class Source>
313  inline Target checked_dynamic_cast(Source* x)
314  {
315  Target tmp = dynamic_cast<Target>(x);
316 #ifdef PARANOID
317  if (tmp == 0)
318  {
319  throw OomphLibError(
320  "Bad cast.", OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
321  }
322 #endif
323  return tmp;
324  }
325 
326  /// Checked static cast. Only use this cast if ALL of these are true:
327  /// - You are sure that the cast will always succeed.
328  /// - You aren't using any strange inheritance structures (e.g. the "Diamond
329  /// of Death" in element inheritance, if you aren't sure just try compiling).
330  /// - You need efficiency.
331  /// Adapted from polymorphic_downcast in boost/cast.hpp, See
332  /// http://www.boost.org/doc/libs/1_52_0/libs/conversion/cast.htm for more
333  /// details.
334  template<class Target, class Source>
335  inline Target checked_static_cast(Source* x)
336  {
337 #ifdef PARANOID
338  // Check that the cast will work as expected.
339  if (dynamic_cast<Target>(x) != x)
340  {
341  throw OomphLibError(
342  "Bad cast.", OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
343  }
344 #endif
345  return static_cast<Target>(x);
346  }
347 
348  /// ///////////////////////////////////////////////////////////////
349  /// ///////////////////////////////////////////////////////////////
350  /// ///////////////////////////////////////////////////////////////
351 
352  //====================================================================
353  /// Timer
354  //====================================================================
355  class Timer
356  {
357  public:
358  /// Constructor: Specify number of timers
359  Timer(const unsigned& n_timer)
360  {
361  set_ntimers(n_timer);
362  }
363 
364  /// (Re-)start i-th timer
365  void start(const unsigned& i)
366  {
367  Start_time[i] = clock();
368  }
369 
370  /// Halt i-th timer
371  void halt(const unsigned& i)
372  {
373  Timing[i] += clock() - Start_time[i];
374  }
375 
376  /// Report time accumulated by i-th timer
377  double cumulative_time(const unsigned& i)
378  {
379  return double(Timing[i]) / CLOCKS_PER_SEC;
380  }
381 
382  /// Reset i-th timer
383  void reset(const unsigned& i)
384  {
385  Timing[i] = clock_t(0.0);
386  }
387 
388  /// Reset all timers
389  void reset()
390  {
391  unsigned n = Timing.size();
392  for (unsigned i = 0; i < n; i++)
393  {
394  Timing[i] = clock_t(0.0);
395  }
396  }
397 
398  /// Set number of timings that can be recorded in parallel
399  void set_ntimers(const unsigned& ntimers)
400  {
401  Timing.resize(ntimers, clock_t(0.0));
402  Start_time.resize(ntimers, clock_t(0.0));
403  }
404 
405  private:
406  /// Cumulative timings
408 
409  /// Start times of active timers
411  };
412 
413 
414  //====================================================================
415  /// Collection of data structures for storing information about
416  /// linear solves. Currently only contains storage for the
417  /// iteration counts and the linear solver time.
418  //====================================================================
420  {
421  public:
422  /// Constructor. Initialised the Iterations_and_times vector of
423  /// vector of pairs.
424  DocLinearSolverInfo() : Iterations_and_times() {}
425 
426  /// Set up a new vector of pairs for a new time step.
428  {
429  // For each new time step, we have a new vector consisting of pairs of
430  // unsigned (for the iteration) and double (for the timing results).
431  Iterations_and_times.push_back(Vector<Vector<double>>());
432  }
433 
435  {
436  Iterations_and_times.pop_back();
437  setup_new_time_step();
438  }
439 
440  /// Add a new iteration and time pair.
441  void add_iteration_and_time(unsigned iter,
442  double prec_setup_time,
443  double linear_solver_time)
444  {
445 #ifdef PARANOID
446  if (Iterations_and_times.size() == 0)
447  {
448  std::ostringstream error_message;
449  error_message << "Iterations_and_times is empty. "
450  << "Call setup_new_time_step()\n";
451  throw OomphLibError(error_message.str(),
452  OOMPH_CURRENT_FUNCTION,
453  OOMPH_EXCEPTION_LOCATION);
454  }
455 #endif
456  Vector<double> tmp_iter_time_vec(3, 0);
457  tmp_iter_time_vec[0] = (double)iter;
458  tmp_iter_time_vec[1] = prec_setup_time;
459  tmp_iter_time_vec[2] = linear_solver_time;
460  Iterations_and_times.back().push_back(tmp_iter_time_vec);
461  }
462 
463  /// The number of time steps
464  unsigned current_ntime_step() const
465  {
466  return Iterations_and_times.size();
467  }
468 
469  /// The number of Newton steps.
470  unsigned current_nnewton_step() const
471  {
472  return Iterations_and_times.back().size();
473  }
474 
475  /// Accessor function for the iteration and times.
477  {
478  return Iterations_and_times;
479  }
480 
481  /// Accessor function for the iteration and times (const version).
483  {
484  return Iterations_and_times;
485  }
486 
487  private:
488  /// Storage for number of iterations during Newton steps
490  };
491 
492  //====================================================================
493  /// Information for documentation of results:
494  /// Directory and file number to enable output
495  /// in the form RESLT/filename11.dat, say.
496  /// Documentation can be switched on and off.
497  //====================================================================
498  class DocInfo
499  {
500  public:
501  /// Constructor. Default settings: Current directory, step `0',
502  /// label="", full documentation enabled and output directory is
503  /// required to exist when set_directory() is called.
505  : Directory("."),
506  Doc_flag(true),
507  Number(0),
508  Label(""),
509  Directory_must_exist(true)
510  {
511  }
512 
513  /// Constructor with specific directory.
514  DocInfo(const std::string& directory)
515  : Directory(directory),
516  Doc_flag(true),
517  Number(0),
518  Label(""),
519  Directory_must_exist(true)
520  {
521  }
522 
523  /// Output directory
525  {
526  return Directory;
527  }
528 
529  /// Set output directory (we try to open a file in it
530  /// to see if the directory exists -- if it doesn't we'll
531  /// issue a warning -- or, if directory_must_exist()==true,
532  /// throw and OomphLibError
533  void set_directory(const std::string& directory);
534 
535  /// Enable documentation
536  void enable_doc()
537  {
538  Doc_flag = true;
539  }
540 
541  /// Disable documentation
542  void disable_doc()
543  {
544  Doc_flag = false;
545  }
546 
547  /// Are we documenting?
548  bool is_doc_enabled() const
549  {
550  return Doc_flag;
551  }
552 
553  /// Number used (e.g.) for labeling output files
554  unsigned& number()
555  {
556  return Number;
557  }
558 
559  /// Number used (e.g.) for labeling output files. Const version.
560  unsigned number() const
561  {
562  return Number;
563  }
564 
565  /// Get number as a string (useful to completely avoid C-strings).
567  {
569  }
570 
571  /// String used (e.g.) for labeling output files
573  {
574  return Label;
575  }
576 
577  /// String used (e.g.) for labeling output files. Const version.
579  {
580  return Label;
581  }
582 
583  /// Call to throw an error if directory does not exist
585  {
586  Directory_must_exist = true;
587  }
588 
589  /// Call to issue a warning if the directory does not exists
591  {
592  Directory_must_exist = false;
593  }
594 
595  private:
596  /// Directory name
598 
599  /// Doc or don't?
600  bool Doc_flag;
601 
602  /// Number to label output file, say
603  unsigned Number;
604 
605  /// String to label output file, say
607 
608  /// Boolean flag to decide response if an output
609  /// directory doesn't exist: If true, we terminate
610  /// code execution by throwing an OomphLibError rather than
611  /// just issuing a warning.
613  };
614 
615 
616  //====================================================================
617  // Namespace for command line arguments
618  //====================================================================
619  namespace CommandLineArgs
620  {
621  /// Structure to store information on a command line argument
622  template<class T>
623  struct ArgInfo
624  {
625  /// Proper constructor
626  ArgInfo(const bool& is_set, T* arg_pt, const std::string& doc)
627  {
628  this->is_set = is_set;
629  this->arg_pt = arg_pt;
630  this->doc = doc;
631  }
632 
633  /// Default constructor. We need this to be able to store these things in
634  /// maps.
636  {
637  this->is_set = false;
638  this->arg_pt = 0;
639  this->doc = "";
640  }
641 
642  // /// Assignment operator. We need this to be able to store these things
643  // in
644  // /// maps.
645  // void operator=(const ArgInfo& that)
646  // {
647  // this->is_set = that.is_set;
648  // this->arg_pt = that.arg_pt;
649  // this->doc = that.doc;
650  // }
651 
652  /// Has this argument been set?
653  bool is_set;
654 
655  /// The place to put the argument's value when it is set
657 
658  /// Information about what the argument does
660  };
661 
662  // Number of arguments + 1
663  extern int Argc;
664 
665  // Arguments themselves
666  extern char** Argv;
667 
668  /// Map to indicate an input flag as having been set
669  extern std::map<std::string, ArgInfo<bool>> Specified_command_line_flag;
670 
671  /// Map to associate an input flag with a double -- specified via pointer
672  extern std::map<std::string, ArgInfo<double>>
674 
675  /// Map to associate an input flag with an int -- specified via pointer
676  extern std::map<std::string, ArgInfo<int>> Specified_command_line_int_pt;
677 
678  /// Map to associate an input flag with an unsigned -- specified via pointer
679  extern std::map<std::string, ArgInfo<unsigned>>
681 
682  /// Map to associate an input flag with a string -- specified via pointer
683  extern std::map<std::string, ArgInfo<std::string>>
685 
686  // Set values
687  extern void setup(int argc, char** argv);
688 
689  // Doc the command line arguments
690  extern void output();
691 
692  /// Specify possible argument-free command line flag
693  extern void specify_command_line_flag(
694  const std::string& command_line_flag,
695  const std::string& documentation = "Undocumented");
696 
697  /// Specify possible command line flag that specifies a double,
698  /// accessed via pointer
699  extern void specify_command_line_flag(
700  const std::string& command_line_flag,
701  double* arg_pt,
702  const std::string& documentation = "Undocumented");
703 
704  /// Specify possible command line flag that specifies an int,
705  /// accessed via pointer
706  extern void specify_command_line_flag(
707  const std::string& command_line_flag,
708  int* arg_pt,
709  const std::string& documentation = "Undocumented");
710 
711  /// Specify possible command line flag that specifies an unsigned,
712  /// accessed via pointer
713  extern void specify_command_line_flag(
714  const std::string& command_line_flag,
715  unsigned* arg_pt,
716  const std::string& documentation = "Undocumented");
717 
718  /// Specify possible command line flag that specifies a string,
719  /// accessed via pointer
720  extern void specify_command_line_flag(
721  const std::string& command_line_flag,
722  std::string* arg_pt,
723  const std::string& documentation = "Undocumented");
724 
725  /// Check if specified flag has been set (the associated
726  /// value will have been assigned directly)
727  extern bool command_line_flag_has_been_set(const std::string& flag);
728 
729  /// Document the values of all flags (specified or not)
730  extern void doc_all_flags(
731  std::ostream& outstream = *oomph_info.stream_pt());
732 
733  /// Document specified command line flags
734  extern void doc_specified_flags();
735 
736  /// Document available command line flags
737  extern void doc_available_flags();
738 
739  /// Helper function to check if command line index is legal
740  extern void check_arg_index(const int& argc, const int& arg_index);
741 
742  /// Parse command line, check for recognised flags and assign
743  /// associated values
744  extern void parse_and_assign(
745  int argc, char* argv[], const bool& throw_on_unrecognised_args = false);
746 
747  /// Parse previously specified command line, check for
748  /// recognised flags and assign associated values
749  extern void parse_and_assign(
750  const bool& throw_on_unrecognised_args = false);
751 
752  } // namespace CommandLineArgs
753 
754  // forward declaration of OomphCommunicator class
755  class OomphCommunicator;
756 
757 #ifdef OOMPH_HAS_MPI
758  //========================================================================
759  /// MPI output modifier: Precedes every output by
760  /// specification of the processor ID. Output can be restricted
761  /// to a single processor.
762  //========================================================================
764  {
765  private:
766  /// Rank of single processor that produces output (only used
767  /// if Output_from_single_processor=true
768  unsigned Output_rank;
769 
770  /// Boolean to control if output is performed only on a single
771  /// processor (default: false)
773 
774  /// Communicator
776 
777  public:
778  /// Constructor -- initialise flags for output from all processors
779  MPIOutputModifier() : Output_rank(0), Output_from_single_processor(false) {}
780 
781  /// Return pointer to communicator
783  {
784  return Communicator_pt;
785  }
786 
787  /// Precede the output by the processor ID but output everything
788  virtual bool operator()(std::ostream& stream);
789 
790  /// Switch to ensure output is only produced from a single
791  /// processor (default: Master node, i.e. rank 0)
792  void restrict_output_to_single_processor(const unsigned& output_rank = 0)
793  {
794  Output_from_single_processor = true;
795  Output_rank = output_rank;
796  }
797 
798 
799  /// Switch to ensure output is only produced from a single
800  /// processor (default: Master node, i.e. rank 0)
802  {
803  Output_from_single_processor = false;
804  }
805  };
806 
807 
808  //========================================================================
809  /// Single (global) instantiation of the mpi output modifier
810  //========================================================================
811  extern MPIOutputModifier oomph_mpi_output;
812 
813  //=== Forward DenseMatrix class
814  template<class T>
815  class DenseMatrix;
816 
817  // forward declaration of oomph-communicator class
818  // class OomphCommunicator;
819 
820 #endif
821 
822 
823  //======================================================================
824  /// MPI_Helpers class contains static helper methods to support MPI
825  /// within oomph-lib. The methods init(...) and finalize() initialize and
826  /// finalize MPI in oomph-lib and manage the oomph-libs global communicator
827  /// communicator_pt().
828  /// NOTE: This class encapsulates static helper methods and instances of it
829  /// CANNOT be instantiated.
830  //=====================================================================
832  {
833  public:
834  /// initialise mpi (oomph-libs equivalent of MPI_Init(...))
835  /// Initialises MPI and creates the global oomph-lib communicator.
836  /// If optional boolean flag is set to false, we use
837  /// MPI_COMM_WORLD itself as oomph-lib's communicator. Defaults to true.
838  static void init(int argc,
839  char** argv,
840  const bool& make_duplicate_of_mpi_comm_world = true);
841 
842  /// finalize mpi (oomph-lib equivalent of MPI_Finalize())
843  /// Deletes the global oomph-lib communicator and finalizes MPI.
844  static void finalize();
845 
846  /// access to global communicator. This is the oomph-lib equivalent of
847  /// MPI_COMM_WORLD
848  static OomphCommunicator* communicator_pt();
849 
850  /// return true if MPI has been initialised
852  {
853  return MPI_has_been_initialised;
854  }
855 
856  private:
857  /// private default constructor definition (to prevent instances of
858  /// the class being instantiated)
860 
861  /// private copy constructor definition (to prevent instances of
862  /// the class being instantiated)
864 
865  /// Bool set to true if MPI has been initialised
867 
868  /// the global communicator
870  };
871 
872 
873  //====================================================================
874  // Namespace for flagging up obsolete parts of the code
875  //====================================================================
876  namespace ObsoleteCode
877  {
878  // Flag up obsolete parts of the code
879  extern bool FlagObsoleteCode;
880 
881  // Output warning message
882  extern void obsolete();
883 
884  // Output specified warning message
885  extern void obsolete(const std::string& message);
886 
887  } // namespace ObsoleteCode
888 
889  //====================================================================
890  // Namespace for tecplot stuff
891  //====================================================================
892  namespace TecplotNames
893  {
894  // Tecplot colours
895  extern Vector<std::string> colour;
896 
897  // Setup tecplot colours namespace
898  extern void setup();
899 
900  } // namespace TecplotNames
901 
902 
903 #ifdef LEAK_CHECK
904 
905  //====================================================================
906  // Namespace for leak check: Keep a running count of all instantiated
907  // objects -- add your own if you want to...
908  //====================================================================
909  namespace LeakCheckNames
910  {
911  extern long QuadTree_build;
912  extern long OcTree_build;
913  extern long QuadTreeForest_build;
914  extern long OcTreeForest_build;
915  extern long RefineableQElement<2> _build;
916  extern long RefineableQElement<3> _build;
917  extern long MacroElement_build;
918  extern long HangInfo_build;
919  extern long Node_build;
920  extern long GeomReference_build;
922  extern long AlgebraicNode_build;
923 
924  // Reset counters
925  extern void reset();
926 
927  // Doc counters
928  extern void doc();
929  } // namespace LeakCheckNames
930 
931 #endif
932 
933  //====================================================================
934  // Namespace for pause() command
935  //====================================================================
936  namespace PauseFlags
937  {
938  // Flag to enable pausing code
939  extern bool PauseFlag;
940 
941  } // namespace PauseFlags
942 
943  /// Pause and dump out message
944  void pause(std::string message);
945 
946 
947  //=============================================================================
948  /// Helper for recording execution time.
949  //=============================================================================
950  namespace TimingHelpers
951  {
952  /// returns the time in seconds after some point in past
953  double timer();
954 
955  /// Returns a nicely formatted string from an input time in seconds;
956  /// the format depends on the size of time, e.g.:
957  /// 86510 will be printed as 1d 1m:50
958  /// 3710 will be printed as 1h:01:50
959  /// 700 will be printed as 11m:40
960  /// 59.15 will be printed as 59.2s
961  std::string convert_secs_to_formatted_string(const double& time_in_sec);
962 
963  } // end of namespace TimingHelpers
964 
965 
966  /// /////////////////////////////////////////////////////////////////
967  /// /////////////////////////////////////////////////////////////////
968  /// /////////////////////////////////////////////////////////////////
969 
970 
971  //===============================================================
972  /// Namespace with helper functions to assess total memory usage
973  /// on the fly using system() -- details are very machine specific! This just
974  /// provides the overall machinery with default settings for
975  /// our own (linux machines). Uses the system command
976  /// to spawn a command that computes the total memory usage
977  /// on the machine where this is called. [Disclaimer: works
978  /// on my machine(s) -- no guarantees for any other platform;
979  /// Linux or not. MH]
980  //===============================================================
981  namespace MemoryUsage
982  {
983  /// Boolean to suppress synchronisation of doc memory
984  /// usage on processors (via mpi barriers). True (i.e. sync is
985  /// is suppressed by default because not all processors may
986  /// execute the reach the relevant doc memory usage statements
987  /// causing the code to hang).
988  extern bool Suppress_mpi_synchronisation;
989 
990  /// String containing system command that obtains memory usage
991  /// of all processes.
992  /// Default assignment for Linux. [Disclaimer: works on my machine(s) --
993  /// no guarantees for any other platform; Linux or not. MH]
995 
996  /// Bool allowing quick bypassing of ALL operations related
997  /// to memory usage monitoring -- this allows the code to remain
998  /// "instrumented" without incurring the heavy penalties associated
999  /// with the system calls and i/o. Default setting: false.
1001 
1002  /// String containing name of file in which we document
1003  /// my memory usage -- you may want to change this to allow different
1004  /// processors to write to separate files (especially in mpi
1005  /// context). Note that file is appended to
1006  /// so it ought to be emptied (either manually or by calling
1007  /// helper function empty_memory_usage_file()
1009 
1010  /// Function to empty file that records my memory usage in
1011  /// file whose name is specified by My_memory_usage_filename.
1013 
1014 #ifdef OOMPH_HAS_UNISTDH
1015 
1016  /// Doc my memory usage, prepended by string (which allows
1017  /// identification from where the function is called, say) that records
1018  /// memory usage in file whose name is specified by
1019  /// My_memory_usage_filename. Data is appended to that file; wipe it with
1020  /// empty_my_memory_usage_file(). Note: This requires getpid() which is
1021  /// defined in unistd.h so if you don't have that we won't build that
1022  /// function!
1023  void doc_my_memory_usage(const std::string& prefix_string = 0);
1024 
1025 #endif
1026 
1027  /// String containing system command that obtains total memory usage.
1028  /// Default assignment for Linux. [Disclaimer: works on my machine(s) --
1029  /// no guarantees for any other platform; Linux or not. MH]
1031 
1032  /// String containing name of file in which we document total
1033  /// memory usage -- you may want to change this to allow different
1034  /// processors to write to separate files (especially in mpi
1035  /// context). Note that file is appended to
1036  /// so it ought to be emptied (either manually or by calling
1037  /// helper function empty_memory_usage_file()
1039 
1040  /// Function to empty file that records total memory usage in
1041  /// file whose name is specified by Total_memory_usage_filename.
1043 
1044  /// Doc total memory usage, prepended by string (which allows
1045  /// identification from where the function is called, say) that records
1046  /// mem usage in file whose name is specified by
1047  /// Total_memory_usage_filename. Data is appended to that file; wipe it with
1048  /// empty_memory_usage_file().
1049  void doc_total_memory_usage(const std::string& prefix_string = "");
1050 
1051  /// Function to empty file that records total and local memory usage
1052  /// in appropriate files
1053  void empty_memory_usage_files();
1054 
1055  /// Doc total and local memory usage, prepended by string (which
1056  /// allows identification from where the function is called, say)
1057  void doc_memory_usage(const std::string& prefix_string = "");
1058 
1059  /// String containing system command that runs "top" (or equivalent)
1060  /// "indefinitely" and writes to file specified in Top_output_filename.
1061  /// Default assignment for Linux. [Disclaimer: works on my machine(s) --
1062  /// no guarantees for any other platform; Linux or not. MH]
1064 
1065  /// String containing name of file in which we document "continuous"
1066  /// output from "top" (or equivalent)-- you may want to change this to
1067  /// allow different processors to write to separate files (especially in mpi
1068  /// context). Note that file is appended to
1069  /// so it ought to be emptied (either manually or by calling
1070  /// helper function empty_top_file()
1072 
1073  /// Function to empty file that records continuous output from top in
1074  /// file whose name is specified by Top_output_filename
1075  void empty_top_file();
1076 
1077  /// Start running top continuously and output (append) into
1078  /// file specified by Top_output_filename. Wipe that file with
1079  /// empty_top_file() first if you wish. Note that this is again
1080  /// quite Linux specific and unlikely to work on other operating systems.
1081  /// Insert optional comment into output file before starting.
1082  void run_continous_top(const std::string& comment = "");
1083 
1084  /// Stop running top continuously. Note that this is
1085  /// again quite Linux specific and unlikely to work on other operating
1086  /// systems.
1087  /// Insert optional comment into output file before stopping.
1088  void stop_continous_top(const std::string& comment = "");
1089 
1090  /// Insert comment into running continuous top output
1091  void insert_comment_to_continous_top(const std::string& comment);
1092 
1093  } // end of namespace MemoryUsage
1094 
1095 
1096  /// /////////////////////////////////////////////////////////////
1097  /// /////////////////////////////////////////////////////////////
1098  /// /////////////////////////////////////////////////////////////
1099 
1100  // Forward decl.
1101  class Problem;
1102  template<class T>
1103  class DenseMatrix;
1104 
1105  /// Function base class for exact solutions/initial conditions/boundary
1106  /// conditions. This is needed so that we can have solutions that depend
1107  /// on problem parameters with resorting to global variables.
1109  {
1110  public:
1111  // Some typedefs first:
1112 
1113  /// General function of space and time which returns a double.
1114  typedef double (*TimeSpaceToDoubleFctPt)(const double& t,
1115  const Vector<double>& x);
1116 
1117  /// General function of space and time which returns a vector of doubles.
1118  typedef Vector<double> (*TimeSpaceToDoubleVectFctPt)(
1119  const double& t, const Vector<double>& x);
1120 
1121  /// General function of time, space and a value vector which returns a
1122  /// vector of doubles.
1123  typedef Vector<double> (*TimeSpaceValueToDoubleVectFctPt)(
1124  const double& t, const Vector<double>& x, const Vector<double>& u);
1125 
1126  /// Virtual destructor
1128 
1129  /// Call the function.
1130  virtual Vector<double> operator()(const double& t,
1131  const Vector<double>& x) const = 0;
1132 
1133  /// Call the derivative function.
1134  virtual Vector<double> derivative(const double& t,
1135  const Vector<double>& x,
1136  const Vector<double>& u) const = 0;
1137 
1138  /// The derivatives of the derivative function with respect to u (note
1139  /// that this is not quite the jacobian of the residuals for an ODE
1140  /// problem defined by this solution: you also need the time derivative
1141  /// part there). Broken virtual function because not often needed.
1142  virtual void jacobian(const double& t,
1143  const Vector<double>& x,
1144  const Vector<double>& u,
1145  DenseMatrix<double>& jacobian) const
1146  {
1147  std::string err = "No Jacobian function implemented";
1148  throw OomphLibError(
1149  err, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1150  }
1151 
1152  /// Is a jacobian function implemented?
1153  virtual bool have_jacobian() const
1154  {
1155  return false;
1156  }
1157 
1158  /// Overload to grab data from the problem.
1159  virtual void initialise_from_problem(const Problem* problem_pt) {}
1160  };
1161 
1162 
1163  /// Function class for a simple function with no external parameters (just
1164  /// stores a function pointer, only needed for compatability).
1166  {
1167  // This could easily be extended to take
1168  // FiniteElement::UnsteadyExactSolutionFctPt function (i.e. functions
1169  // where the output is placed into a given vector rather than returned)
1170  // as well--just add the appropriate storage pointers and constructors.
1171 
1172  public:
1173  // Constructors:
1174 
1176  {
1177  Solution_fpt = 0;
1178  Derivative_fpt = 0;
1179  }
1180 
1181  SolutionFunctor(TimeSpaceToDoubleVectFctPt solution_fpt)
1182  {
1183  Solution_fpt = solution_fpt;
1184  Derivative_fpt = 0;
1185  }
1186 
1187  SolutionFunctor(TimeSpaceToDoubleVectFctPt solution_fpt,
1188  TimeSpaceValueToDoubleVectFctPt derivative_fpt)
1189  {
1190  Solution_fpt = solution_fpt;
1191  Derivative_fpt = derivative_fpt;
1192  }
1193 
1194  virtual ~SolutionFunctor() {}
1195 
1197  {
1198  Solution_fpt = that.Solution_fpt;
1199  Derivative_fpt = that.Derivative_fpt;
1200  }
1201 
1202  void operator=(const SolutionFunctor& that)
1203  {
1204  this->Solution_fpt = that.Solution_fpt;
1205  this->Derivative_fpt = that.Derivative_fpt;
1206  }
1207 
1208  /// Call the function.
1209  virtual Vector<double> operator()(const double& t,
1210  const Vector<double>& x) const
1211  {
1212 #ifdef PARANOID
1213  if (Solution_fpt == 0)
1214  {
1215  std::string err = "Solution_fpt is null!";
1216  throw OomphLibError(
1217  err, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1218  }
1219 #endif
1220  return Solution_fpt(t, x);
1221  }
1222 
1223  /// Call the derivative function.
1224  virtual Vector<double> derivative(const double& t,
1225  const Vector<double>& x,
1226  const Vector<double>& u) const
1227  {
1228 #ifdef PARANOID
1229  if (Derivative_fpt == 0)
1230  {
1231  std::string err = "Derivative_fpt is null!";
1232  throw OomphLibError(
1233  err, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1234  }
1235 #endif
1236  return Derivative_fpt(t, x, u);
1237  }
1238 
1239  /// Storage for solution
1240  TimeSpaceToDoubleVectFctPt Solution_fpt;
1241 
1242  /// Storage for derivative
1243  TimeSpaceValueToDoubleVectFctPt Derivative_fpt;
1244  };
1245 
1246 
1247 } // namespace oomph
1248 #endif
static char t char * s
Definition: cfortran.h:568
cstr elem_len * i
Definition: cfortran.h:603
char t
Definition: cfortran.h:568
Function-type-object to perform absolute comparison of objects. Apparently this inlines better.
bool operator()(const T &x, const T &y) const
Comparison. Are the values identical or not?
Information for documentation of results: Directory and file number to enable output in the form RESL...
std::string label() const
String used (e.g.) for labeling output files. Const version.
unsigned Number
Number to label output file, say.
void enable_doc()
Enable documentation.
bool Doc_flag
Doc or don't?
unsigned number() const
Number used (e.g.) for labeling output files. Const version.
bool is_doc_enabled() const
Are we documenting?
bool Directory_must_exist
Boolean flag to decide response if an output directory doesn't exist: If true, we terminate code exec...
void disable_doc()
Disable documentation.
std::string & label()
String used (e.g.) for labeling output files.
void disable_error_if_directory_does_not_exist()
Call to issue a warning if the directory does not exists.
std::string directory() const
Output directory.
std::string Directory
Directory name.
void enable_error_if_directory_does_not_exist()
Call to throw an error if directory does not exist.
DocInfo(const std::string &directory)
Constructor with specific directory.
std::string number_as_string() const
Get number as a string (useful to completely avoid C-strings).
std::string Label
String to label output file, say.
DocInfo()
Constructor. Default settings: Current directory, step ‘0’, label="", full documentation enabled and ...
unsigned & number()
Number used (e.g.) for labeling output files.
Collection of data structures for storing information about linear solves. Currently only contains st...
void setup_new_time_step()
Set up a new vector of pairs for a new time step.
Vector< Vector< Vector< double > > > & iterations_and_times()
Accessor function for the iteration and times.
Vector< Vector< Vector< double > > > Iterations_and_times
Storage for number of iterations during Newton steps.
unsigned current_nnewton_step() const
The number of Newton steps.
DocLinearSolverInfo()
Constructor. Initialised the Iterations_and_times vector of vector of pairs.
void add_iteration_and_time(unsigned iter, double prec_setup_time, double linear_solver_time)
Add a new iteration and time pair.
unsigned current_ntime_step() const
The number of time steps.
Vector< Vector< Vector< double > > > iterations_and_times() const
Accessor function for the iteration and times (const version).
MPI output modifier: Precedes every output by specification of the processor ID. Output can be restri...
OomphCommunicator *& communicator_pt()
Return pointer to communicator.
MPIOutputModifier()
Constructor – initialise flags for output from all processors.
void restrict_output_to_single_processor(const unsigned &output_rank=0)
Switch to ensure output is only produced from a single processor (default: Master node,...
OomphCommunicator * Communicator_pt
Communicator.
bool Output_from_single_processor
Boolean to control if output is performed only on a single processor (default: false)
unsigned Output_rank
Rank of single processor that produces output (only used if Output_from_single_processor=true.
void allow_output_from_all_processors()
Switch to ensure output is only produced from a single processor (default: Master node,...
MPI_Helpers class contains static helper methods to support MPI within oomph-lib. The methods init(....
static OomphCommunicator * Communicator_pt
the global communicator
static bool mpi_has_been_initialised()
return true if MPI has been initialised
static bool MPI_has_been_initialised
Bool set to true if MPI has been initialised.
MPI_Helpers(const MPI_Helpers &)
private copy constructor definition (to prevent instances of the class being instantiated)
MPI_Helpers()
private default constructor definition (to prevent instances of the class being instantiated)
An oomph-lib wrapper to the MPI_Comm communicator object. Just contains an MPI_Comm object (which is ...
Definition: communicator.h:54
std::ostream *& stream_pt()
Access function for the stream pointer.
An OomphLibError object which should be thrown when an run-time error is encountered....
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
////////////////////////////////////////////////////////////////// //////////////////////////////////...
Definition: problem.h:151
Function base class for exact solutions/initial conditions/boundary conditions. This is needed so tha...
virtual void initialise_from_problem(const Problem *problem_pt)
Overload to grab data from the problem.
virtual void jacobian(const double &t, const Vector< double > &x, const Vector< double > &u, DenseMatrix< double > &jacobian) const
The derivatives of the derivative function with respect to u (note that this is not quite the jacobia...
virtual ~SolutionFunctorBase()
Virtual destructor.
virtual Vector< double > derivative(const double &t, const Vector< double > &x, const Vector< double > &u) const =0
Call the derivative function.
virtual Vector< double > operator()(const double &t, const Vector< double > &x) const =0
Call the function.
virtual bool have_jacobian() const
Is a jacobian function implemented?
Function class for a simple function with no external parameters (just stores a function pointer,...
virtual Vector< double > derivative(const double &t, const Vector< double > &x, const Vector< double > &u) const
Call the derivative function.
void operator=(const SolutionFunctor &that)
TimeSpaceValueToDoubleVectFctPt Derivative_fpt
Storage for derivative.
SolutionFunctor(TimeSpaceToDoubleVectFctPt solution_fpt, TimeSpaceValueToDoubleVectFctPt derivative_fpt)
TimeSpaceToDoubleVectFctPt Solution_fpt
Storage for solution.
SolutionFunctor(const SolutionFunctor &that)
virtual Vector< double > operator()(const double &t, const Vector< double > &x) const
Call the function.
SolutionFunctor(TimeSpaceToDoubleVectFctPt solution_fpt)
/////////////////////////////////////////////////////////////// /////////////////////////////////////...
Vector< clock_t > Timing
Cumulative timings.
double cumulative_time(const unsigned &i)
Report time accumulated by i-th timer.
void set_ntimers(const unsigned &ntimers)
Set number of timings that can be recorded in parallel.
Timer(const unsigned &n_timer)
Constructor: Specify number of timers.
Vector< clock_t > Start_time
Start times of active timers.
void reset(const unsigned &i)
Reset i-th timer.
void reset()
Reset all timers.
void start(const unsigned &i)
(Re-)start i-th timer
void halt(const unsigned &i)
Halt i-th timer.
void set_text_effect(std::string text_effect)
Function to change text effect. NOTE: This assumes the user knows what they're doing/assigning; no er...
std::string Text_effect
Variable to decide on effects.
std::string Black
The code for each type of colour.
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
void doc_available_flags()
Document available command line flags.
std::map< std::string, ArgInfo< bool > > Specified_command_line_flag
Map to indicate an input flag as having been set.
char ** Argv
Arguments themselves.
bool command_line_flag_has_been_set(const std::string &flag)
Check if command line flag has been set (value will have been assigned directly).
void specify_command_line_flag(const std::string &command_line_flag, const std::string &doc)
Specify possible argument-free command line flag.
void check_arg_index(const int &argc, const int &arg_index)
Helper function to check if command line index is legal.
void doc_all_flags(std::ostream &outstream)
Document the values of all flags (specified or not).
std::map< std::string, ArgInfo< std::string > > Specified_command_line_string_pt
Map to associate an input flag with a string – specified via pointer.
std::map< std::string, ArgInfo< int > > Specified_command_line_int_pt
Map to associate an input flag with an int – specified via pointer.
void parse_and_assign(int argc, char *argv[], const bool &throw_on_unrecognised_args)
Parse command line, check for recognised flags and assign associated values.
std::map< std::string, ArgInfo< double > > Specified_command_line_double_pt
Map to associate an input flag with a double – specified via pointer.
int Argc
Number of arguments + 1.
void output()
Doc the command line arguments.
std::map< std::string, ArgInfo< unsigned > > Specified_command_line_unsigned_pt
Map to associate an input flag with an unsigned – specified via pointer.
void doc_specified_flags()
Document specified command line flags.
double cumulative_time(const unsigned &i)
Report time accumulated by i-th timer.
void set_ntimers(const unsigned &ntimers)
Set number of timings that can be recorded in parallel.
void reset(const unsigned &i)
Reset i-th timer.
Vector< clock_t > Timing
Cumulative timings.
void halt(const unsigned &i)
Halt i-th timer.
Vector< clock_t > Start_time
Start times of active timers.
void start(const unsigned &i)
(Re-)start i-th timer
std::string debug_string(const std::string &filename, const int &line, const bool &make_new_line)
Return the concaternation of the initials of the input file name and line number. The make_new_line f...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
unsigned Number
The unsigned.
long AlgebraicNodeNodeUpdateInfo_build
long RefineableQElement< 2 > _build
const double Pi
50 digits from maple
const std::complex< double > I(0.0, 1.0)
The imaginary unit.
void empty_top_file()
Function to empty file that records continuous output from top in file whose name is specified by Top...
std::string Top_output_filename
String containing name of file in which we document "continuous" output from "top" (or equivalent)– y...
bool Bypass_all_memory_usage_monitoring
Bool allowing quick bypassing of ALL operations related to memory usage monitoring – this allows the ...
void doc_total_memory_usage(const std::string &prefix_string)
Doc total memory usage, prepended by string (which allows identification from where the function is c...
void insert_comment_to_continous_top(const std::string &comment)
Insert comment into running continuous top output.
void doc_my_memory_usage(const std::string &prefix_string)
Doc my memory usage, prepended by string (which allows identification from where the function is call...
void empty_memory_usage_files()
Function to empty file that records total and local memory usage in appropriate files.
void run_continous_top(const std::string &comment)
Start running top continuously and output (append) into file specified by Top_output_filename....
std::string Top_system_string
String containing system command that runs "top" (or equivalent) "indefinitely" and writes to file sp...
void stop_continous_top(const std::string &comment)
Stop running top continuously. Note that this is again quite Linux specific and unlikely to work on o...
bool Suppress_mpi_synchronisation
Boolean to suppress synchronisation of doc memory usage on processors (via mpi barriers)....
void empty_total_memory_usage_file()
Function to empty file that records total memory usage in file whose name is specified by Total_memor...
std::string Total_memory_usage_system_string
String containing system command that obtains total memory usage. Default assignment for linux....
void doc_memory_usage(const std::string &prefix_string)
Doc total and local memory usage, prepended by string (which allows identification from where the fun...
std::string My_memory_usage_filename
String containing name of file in which we document my memory usage – you may want to change this to ...
void empty_my_memory_usage_file()
Function to empty file that records my memory usage in file whose name is specified by My_memory_usag...
std::string My_memory_usage_system_string
String containing system command that obtains memory usage of all processes. Default assignment for l...
std::string Total_memory_usage_filename
String containing name of file in which we document total memory usage – you may want to change this ...
void obsolete()
Output warning message.
bool FlagObsoleteCode
Flag up obsolete parts of the code.
bool PauseFlag
Flag to enable pausing code – pause the code by default.
double second_invariant(const DenseMatrix< double > &tensor)
Compute second invariant of tensor.
void split_string(const std::string &s, char delim, Vector< std::string > &elems)
Split a string, s, into a vector of strings where ever there is an instance of delimiter (i....
std::string to_string(T object, unsigned float_precision=8)
Conversion function that should work for anything with operator<< defined (at least all basic types).
std::string to_lower(const std::string &input)
Convert a string to lower case (outputs a copy).
std::string to_upper(const std::string &input)
Convert a string to upper case (outputs a copy).
Vector< std::string > colour
Tecplot colours.
void setup()
Setup terminate helper.
double timer()
returns the time in seconds after some point in past
std::string convert_secs_to_formatted_string(const double &time_in_sec)
Returns a nicely formatted string from an input time in seconds; the format depends on the size of ti...
std::string get_type_name(T &obj)
Get the type name of an object. Only for use in debugging, do not write real code using this function...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
Target checked_static_cast(Source *x)
Checked static cast. Only use this cast if ALL of these are true:
void pause(std::string message)
Pause and display message.
Target checked_dynamic_cast(Source *x)
Runtime checked dynamic cast. This is the safe but slightly slower cast. Use it in any of these cases...
MPIOutputModifier oomph_mpi_output
Single (global) instantiation of the mpi output modifier.
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...
Structure to store information on a command line argument.
ArgInfo()
Default constructor. We need this to be able to store these things in maps.
T * arg_pt
The place to put the argument's value when it is set.
std::string doc
Information about what the argument does.
ArgInfo(const bool &is_set, T *arg_pt, const std::string &doc)
Proper constructor.
bool is_set
Has this argument been set?