00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __deal2__parameter_handler_h
00013 #define __deal2__parameter_handler_h
00014
00015
00016 #include <deal.II/base/config.h>
00017 #include <deal.II/base/exceptions.h>
00018 #include <deal.II/base/subscriptor.h>
00019 #include <deal.II/base/std_cxx1x/shared_ptr.h>
00020
00021 #include <boost/property_tree/ptree_fwd.hpp>
00022 #include <boost/serialization/split_member.hpp>
00023
00024 #include <map>
00025 #include <vector>
00026 #include <string>
00027 #include <memory>
00028
00029 DEAL_II_NAMESPACE_OPEN
00030
00031
00032
00033
00034
00035
00036 class ParameterHandler;
00037 class MultipleParameterLoop;
00038
00039
00040
00041
00042 class LogStream;
00043
00044
00045
00054 namespace Patterns
00055 {
00056
00068 class PatternBase
00069 {
00070 public:
00075 virtual ~PatternBase ();
00076
00081 virtual bool match (const std::string &test_string) const = 0;
00082
00087 virtual std::string description () const = 0;
00088
00107 virtual PatternBase * clone () const = 0;
00108
00146 virtual std::size_t memory_consumption () const;
00147 };
00148
00153 PatternBase * pattern_factory (const std::string& description);
00154
00189 class Integer : public PatternBase
00190 {
00191 public:
00202 static const int min_int_value;
00203
00214 static const int max_int_value;
00215
00228 Integer (const int lower_bound = min_int_value,
00229 const int upper_bound = max_int_value);
00230
00237 virtual bool match (const std::string &test_string) const;
00238
00249 virtual std::string description () const;
00250
00260 virtual PatternBase * clone () const;
00261
00269 static Integer* create (const std::string& description);
00270
00271 private:
00282 const int lower_bound;
00283
00294 const int upper_bound;
00295
00299 static const char* description_init;
00300 };
00301
00337 class Double : public PatternBase
00338 {
00339 public:
00350 static const double min_double_value;
00351
00362 static const double max_double_value;
00363
00376 Double (const double lower_bound = min_double_value,
00377 const double upper_bound = max_double_value);
00378
00385 virtual bool match (const std::string &test_string) const;
00386
00397 virtual std::string description () const;
00398
00408 virtual PatternBase * clone () const;
00409
00417 static Double* create (const std::string& description);
00418
00419 private:
00430 const double lower_bound;
00431
00442 const double upper_bound;
00443
00447 static const char* description_init;
00448 };
00449
00464 class Selection : public PatternBase
00465 {
00466 public:
00473 Selection (const std::string &seq);
00474
00481 virtual bool match (const std::string &test_string) const;
00482
00491 virtual std::string description () const;
00492
00502 virtual PatternBase * clone () const;
00503
00509 std::size_t memory_consumption () const;
00510
00518 static Selection* create (const std::string& description);
00519
00520 private:
00529 std::string sequence;
00530
00534 static const char* description_init;
00535 };
00536
00537
00548 class List : public PatternBase
00549 {
00550 public:
00561 static const unsigned int max_int_value;
00562
00574 List (const PatternBase &base_pattern,
00575 const unsigned int min_elements = 0,
00576 const unsigned int max_elements = max_int_value);
00577
00581 virtual ~List ();
00582
00590 virtual bool match (const std::string &test_string) const;
00591
00598 virtual std::string description () const;
00599
00609 virtual PatternBase * clone () const;
00610
00618 static List* create (const std::string& description);
00619
00625 std::size_t memory_consumption () const;
00626
00633 DeclException2 (ExcInvalidRange,
00634 int, int,
00635 << "The values " << arg1 << " and " << arg2
00636 << " do not form a valid range.");
00638 private:
00644 PatternBase *pattern;
00645
00650 const unsigned int min_elements;
00651
00656 const unsigned int max_elements;
00657
00661 static const char* description_init;
00662 };
00663
00686 class MultipleSelection : public PatternBase
00687 {
00688 public:
00695 MultipleSelection (const std::string &seq);
00696
00703 virtual bool match (const std::string &test_string) const;
00704
00713 virtual std::string description () const;
00714
00724 virtual PatternBase * clone () const;
00725
00733 static MultipleSelection* create (const std::string& description);
00734
00740 std::size_t memory_consumption () const;
00741
00748 DeclException1 (ExcCommasNotAllowed,
00749 int,
00750 << "A comma was found at position " << arg1
00751 << " of your input string, but commas are not allowed here.");
00753 private:
00762 std::string sequence;
00763
00767 static const char* description_init;
00768 };
00769
00776 class Bool : public Selection
00777 {
00778 public:
00782 Bool ();
00783
00790 virtual std::string description () const;
00791
00801 virtual PatternBase * clone () const;
00802
00810 static Bool* create (const std::string& description);
00811
00812 private:
00816 static const char* description_init;
00817 };
00818
00823 class Anything : public PatternBase
00824 {
00825 public:
00833 Anything ();
00834
00840 virtual bool match (const std::string &test_string) const;
00841
00849 virtual std::string description () const;
00850
00860 virtual PatternBase * clone () const;
00861
00869 static Anything* create (const std::string& description);
00870
00871 private:
00875 static const char* description_init;
00876 };
00877
00878
00903 class FileName : public PatternBase
00904 {
00905 public:
00912 enum FileType {input = 0, output = 1};
00913
00919 FileName (const FileType type = input);
00920
00926 virtual bool match (const std::string &test_string) const;
00927
00935 virtual std::string description () const;
00936
00946 virtual PatternBase * clone () const;
00947
00951 FileType file_type;
00952
00960 static FileName* create (const std::string& description);
00961
00962 private:
00966 static const char* description_init;
00967 };
00968
00969
00988 class DirectoryName : public PatternBase
00989 {
00990 public:
00994 DirectoryName ();
00995
01001 virtual bool match (const std::string &test_string) const;
01002
01010 virtual std::string description () const;
01011
01021 virtual PatternBase * clone () const;
01022
01030 static DirectoryName* create (const std::string& description);
01031
01032 private:
01036 static const char* description_init;
01037 };
01038 }
01039
01040
01649 class ParameterHandler : public Subscriptor
01650 {
01651 private:
01656 ParameterHandler (const ParameterHandler&);
01657
01662 ParameterHandler& operator= (const ParameterHandler&);
01663
01664 public:
01676 enum OutputStyle {
01683 Text = 1,
01688 LaTeX = 2,
01694 Description = 3,
01695
01706 XML = 4,
01707
01713 JSON = 5,
01714
01721 ShortText = 193
01722 };
01723
01724
01725
01729 ParameterHandler ();
01730
01739 virtual ~ParameterHandler ();
01740
01749 virtual bool read_input (std::istream &input);
01750
01770 virtual bool read_input (const std::string &filename,
01771 const bool optional = false,
01772 const bool write_stripped_file = false);
01773
01783 virtual bool read_input_from_string (const char *s);
01784
01800 virtual bool read_input_from_xml (std::istream &input);
01801
01805 void clear ();
01806
01807
01834 void declare_entry (const std::string &entry,
01835 const std::string &default_value,
01836 const Patterns::PatternBase &pattern = Patterns::Anything(),
01837 const std::string &documentation = std::string());
01838
01843 void enter_subsection (const std::string &subsection);
01844
01851 bool leave_subsection ();
01852
01863 std::string get (const std::string &entry_string) const;
01864
01872 long int get_integer (const std::string &entry_string) const;
01873
01879 double get_double (const std::string &entry_name) const;
01880
01888 bool get_bool (const std::string &entry_name) const;
01889
01905 void set (const std::string &entry_name,
01906 const std::string &new_value);
01907
01926 void set (const std::string &entry_name,
01927 const char *new_value);
01928
01944 void set (const std::string &entry_name,
01945 const long int &new_value);
01946
01970 void set (const std::string &entry_name,
01971 const double &new_value);
01972
01988 void set (const std::string &entry_name,
01989 const bool &new_value);
01990
01991
02060 std::ostream & print_parameters (std::ostream &out,
02061 const OutputStyle style);
02062
02081 void print_parameters_section (std::ostream &out,
02082 const OutputStyle style,
02083 const unsigned int indent_level);
02084
02093 void log_parameters (LogStream& out);
02094
02113 void log_parameters_section (LogStream& out);
02114
02121 std::size_t memory_consumption () const;
02122
02128 template <class Archive>
02129 void save (Archive & ar, const unsigned int version) const;
02130
02136 template <class Archive>
02137 void load (Archive & ar, const unsigned int version);
02138
02139 BOOST_SERIALIZATION_SPLIT_MEMBER()
02140
02141
02144 bool operator == (const ParameterHandler & prm2) const;
02145
02152 DeclException1 (ExcEntryAlreadyExists,
02153 std::string,
02154 << "The following entry already exists: " << arg1);
02158 DeclException2 (ExcValueDoesNotMatchPattern,
02159 std::string, std::string,
02160 << "The string <" << arg1
02161 << "> does not match the given pattern <" << arg2 << ">");
02165 DeclException0 (ExcAlreadyAtTopLevel);
02169 DeclException1 (ExcEntryUndeclared,
02170 std::string,
02171 << "You can't ask for entry <" << arg1 << "> you have not yet declared");
02175 DeclException1 (ExcConversionError,
02176 std::string,
02177 << "Error when trying to convert the following string: " << arg1);
02179 private:
02185 static const char path_separator = '.';
02186
02202 std::auto_ptr<boost::property_tree::ptree> entries;
02203
02211 std::vector<std_cxx1x::shared_ptr<const Patterns::PatternBase> > patterns;
02212
02218 static std::string mangle (const std::string &s);
02219
02224 static std::string demangle (const std::string &s);
02225
02231 static bool is_parameter_node (const boost::property_tree::ptree &);
02232
02238 std::vector<std::string> subsection_path;
02239
02248 std::string get_current_path () const;
02249
02257 std::string get_current_full_path (const std::string &name) const;
02258
02280 bool scan_line (std::string line,
02281 const unsigned int lineno);
02282
02283 friend class MultipleParameterLoop;
02284 };
02285
02286
02287
02498 class MultipleParameterLoop : public ParameterHandler
02499 {
02500 public:
02505 class UserClass
02506 {
02507 public:
02514 virtual ~UserClass ();
02515
02521 virtual void create_new (const unsigned int run_no) = 0;
02522
02528 virtual void declare_parameters (ParameterHandler &prm) = 0;
02529
02534 virtual void run (ParameterHandler &prm) = 0;
02535 };
02536
02540 MultipleParameterLoop ();
02541
02548 virtual ~MultipleParameterLoop ();
02549
02550 virtual bool read_input (std::istream &Input);
02551 virtual bool read_input (const std::string &FileName,
02552 const bool optional = false,
02553 const bool write_stripped_file = false);
02554
02560 virtual bool read_input_from_string (const char *s);
02561
02565 void loop (UserClass &uc);
02566
02573 std::size_t memory_consumption () const;
02574
02575 private:
02576
02581 class Entry
02582 {
02583 public:
02591 enum MultipleEntryType
02592 {
02593 variant, array
02594 };
02595
02599 Entry () : type (array) {}
02600
02607 Entry (const std::vector<std::string> &Path,
02608 const std::string &Name,
02609 const std::string &Value);
02610
02615 void split_different_values ();
02616
02620 std::vector<std::string> subsection_path;
02621
02625 std::string entry_name;
02626
02630 std::string entry_value;
02631
02637 std::vector<std::string> different_values;
02638
02643 MultipleEntryType type;
02644
02651 std::size_t memory_consumption () const;
02652 };
02653
02657 std::vector<Entry> multiple_choices;
02658
02667 unsigned int n_branches;
02668
02674 void init_branches ();
02675
02686 void init_branches_current_section ();
02687
02692 void fill_entry_values (const unsigned int run_no);
02693 };
02694
02695
02696 template <class Archive>
02697 inline
02698 void
02699 ParameterHandler::save (Archive & ar, const unsigned int) const
02700 {
02701
02702
02703 ar & static_cast<const Subscriptor &>(*this);
02704
02705 ar & *entries.get();
02706
02707 std::vector<std::string> descriptions;
02708
02709 for (unsigned int j=0; j<patterns.size(); ++j)
02710 descriptions.push_back (patterns[j]->description());
02711
02712 ar & descriptions;
02713 }
02714
02715
02716 template <class Archive>
02717 inline
02718 void
02719 ParameterHandler::load (Archive & ar, const unsigned int)
02720 {
02721
02722
02723 ar & static_cast<Subscriptor &>(*this);
02724
02725 ar & *entries.get();
02726
02727 std::vector<std::string> descriptions;
02728 ar & descriptions;
02729
02730 patterns.clear ();
02731 for (unsigned int j=0; j<descriptions.size(); ++j)
02732 patterns.push_back (std_cxx1x::shared_ptr<Patterns::PatternBase>(Patterns::pattern_factory(descriptions[j])));
02733 }
02734
02735
02736 DEAL_II_NAMESPACE_CLOSE
02737
02738 #endif
02739