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-2022 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
70namespace 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
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.
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).
432 }
433
435 {
436 Iterations_and_times.pop_back();
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 {
479 }
480
481 /// Accessor function for the iteration and times (const version).
483 {
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 //====================================================================
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(""),
510 {
511 }
512
513 /// Constructor with specific directory.
516 Doc_flag(true),
517 Number(0),
518 Label(""),
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
534
535 /// Enable documentation
537 {
538 Doc_flag = true;
539 }
540
541 /// Disable documentation
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 {
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?
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
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 {
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 {
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
849
850 /// return true if MPI has been initialised
852 {
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).
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
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.
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.
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,
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
1182 {
1183 Solution_fpt = solution_fpt;
1184 Derivative_fpt = 0;
1185 }
1186
1188 TimeSpaceValueToDoubleVectFctPt derivative_fpt)
1189 {
1190 Solution_fpt = solution_fpt;
1191 Derivative_fpt = derivative_fpt;
1192 }
1193
1194 virtual ~SolutionFunctor() {}
1195
1197 {
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
1241
1242 /// Storage for derivative
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()
String used (e.g.) for labeling output files.
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.
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 set_directory(const std::string &directory)
Set output directory (we try to open a file in it to see if the directory exists – if it doesn't we'l...
unsigned & number()
Number used (e.g.) for labeling output files.
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 ...
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
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.
Vector< Vector< Vector< double > > > & iterations_and_times()
Accessor function for the iteration and times.
void add_iteration_and_time(unsigned iter, double prec_setup_time, double linear_solver_time)
Add a new iteration and time pair.
Vector< Vector< Vector< double > > > iterations_and_times() const
Accessor function for the iteration and times (const version).
unsigned current_ntime_step() const
The number of time steps.
MPI output modifier: Precedes every output by specification of the processor ID. Output can be restri...
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()
Return pointer to communicator.
OomphCommunicator * Communicator_pt
Communicator.
virtual bool operator()(std::ostream &stream)
Precede the output by the processor ID but output everything.
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 void finalize()
finalize mpi (oomph-lib equivalent of MPI_Finalize()) Deletes the global oomph-lib communicator and f...
static void init(int argc, char **argv, const bool &make_duplicate_of_mpi_comm_world=true)
initialise mpi (oomph-libs equivalent of MPI_Init(...)) Initialises MPI and creates the global oomph-...
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.
static OomphCommunicator * communicator_pt()
access to global communicator. This is the oomph-lib equivalent of MPI_COMM_WORLD
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 Vector< double > operator()(const double &t, const Vector< double > &x) const =0
Call the function.
virtual void initialise_from_problem(const Problem *problem_pt)
Overload to grab data from the problem.
Vector< double >(* TimeSpaceValueToDoubleVectFctPt)(const double &t, const Vector< double > &x, const Vector< double > &u)
General function of time, space and a value vector which returns a vector of doubles.
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.
double(* TimeSpaceToDoubleFctPt)(const double &t, const Vector< double > &x)
General function of space and time which returns a double.
virtual Vector< double > derivative(const double &t, const Vector< double > &x, const Vector< double > &u) const =0
Call the derivative function.
Vector< double >(* TimeSpaceToDoubleVectFctPt)(const double &t, const Vector< double > &x)
General function of space and time which returns a vector of doubles.
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,...
void operator=(const SolutionFunctor &that)
TimeSpaceValueToDoubleVectFctPt Derivative_fpt
Storage for derivative.
virtual Vector< double > operator()(const double &t, const Vector< double > &x) const
Call the function.
SolutionFunctor(TimeSpaceToDoubleVectFctPt solution_fpt, TimeSpaceValueToDoubleVectFctPt derivative_fpt)
TimeSpaceToDoubleVectFctPt Solution_fpt
Storage for solution.
virtual Vector< double > derivative(const double &t, const Vector< double > &x, const Vector< double > &u) const
Call the derivative function.
SolutionFunctor(const SolutionFunctor &that)
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.
A slight extension to the standard template vector class so that we can include "graceful" array rang...
Definition: Vector.h:58
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 setup(int argc, char **argv)
Set values.
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.
long AlgebraicNodeNodeUpdateInfo_build
long RefineableQElement< 2 > _build
const std::complex< double > I(0.0, 1.0)
The imaginary unit.
const double Pi
50 digits from maple
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 namespace.
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?