Reference documentation for deal.II version Git 409ee4b167 2020-08-14 09:46:12 -0400
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
MultipleParameterLoop Class Reference

#include <deal.II/base/parameter_handler.h>

Inheritance diagram for MultipleParameterLoop:


class  Entry
class  UserClass

Public Member Functions

 MultipleParameterLoop ()
virtual ~MultipleParameterLoop () override=default
virtual void parse_input (std::istream &input, const std::string &filename="input file", const std::string &last_line="", const bool skip_undefined=false) override
void loop (UserClass &uc)
std::size_t memory_consumption () const
- Public Member Functions inherited from ParameterHandler
 ParameterHandler ()
virtual ~ParameterHandler () override=default
 ParameterHandler (const ParameterHandler &)=delete
ParameterHandleroperator= (const ParameterHandler &)=delete
virtual void parse_input (const std::string &filename, const std::string &last_line="", const bool skip_undefined=false, const bool assert_mandatory_entries_are_found=false)
virtual void parse_input_from_string (const std::string &s, const std::string &last_line="", const bool skip_undefined=false)
virtual void parse_input_from_xml (std::istream &input, const bool skip_undefined=false)
virtual void parse_input_from_json (std::istream &input, const bool skip_undefined=false)
void clear ()
void declare_entry (const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation="", const bool has_to_be_set=false)
void add_action (const std::string &entry, const std::function< void(const std::string &value)> &action)
template<class ParameterType >
void add_parameter (const std::string &entry, ParameterType &parameter, const std::string &documentation="", const Patterns::PatternBase &pattern= *Patterns::Tools::Convert< ParameterType >::to_pattern(), const bool has_to_be_set=false)
void declare_alias (const std::string &existing_entry_name, const std::string &alias_name, const bool alias_is_deprecated=false)
void enter_subsection (const std::string &subsection)
void leave_subsection ()
bool subsection_path_exists (const std::vector< std::string > &sub_path) const
std::string get (const std::string &entry_string) const
std::string get (const std::vector< std::string > &entry_subsection_path, const std::string &entry_string) const
long int get_integer (const std::string &entry_string) const
long int get_integer (const std::vector< std::string > &entry_subsection_path, const std::string &entry_string) const
double get_double (const std::string &entry_name) const
double get_double (const std::vector< std::string > &entry_subsection_path, const std::string &entry_string) const
bool get_bool (const std::string &entry_name) const
bool get_bool (const std::vector< std::string > &entry_subsection_path, const std::string &entry_string) const
void set (const std::string &entry_name, const std::string &new_value)
void set (const std::string &entry_name, const char *new_value)
void set (const std::string &entry_name, const long int new_value)
void set (const std::string &entry_name, const double new_value)
void set (const std::string &entry_name, const bool new_value)
std::ostream & print_parameters (std::ostream &out, const OutputStyle style) const
void print_parameters (const std::string &filename, const OutputStyle style=DefaultStyle) const
void log_parameters (LogStream &out, const OutputStyle style=DefaultStyle)
void log_parameters_section (LogStream &out, const OutputStyle style=DefaultStyle)
std::size_t memory_consumption () const
template<class Archive >
void save (Archive &ar, const unsigned int version) const
template<class Archive >
void load (Archive &ar, const unsigned int version)
template<class Archive >
void serialize (Archive &archive, const unsigned int version)
bool operator== (const ParameterHandler &prm2) const
std::set< std::string > get_entries_wrongly_not_set () const
void assert_that_entries_have_been_set () const
- Public Member Functions inherited from Subscriptor
 Subscriptor ()
 Subscriptor (const Subscriptor &)
 Subscriptor (Subscriptor &&) noexcept
virtual ~Subscriptor ()
Subscriptoroperator= (const Subscriptor &)
Subscriptoroperator= (Subscriptor &&) noexcept
void subscribe (std::atomic< bool > *const validity, const std::string &identifier="") const
void unsubscribe (std::atomic< bool > *const validity, const std::string &identifier="") const
unsigned int n_subscriptions () const
template<typename StreamType >
void list_subscribers (StreamType &stream) const
void list_subscribers () const
template<class Archive >
void serialize (Archive &ar, const unsigned int version)

Private Member Functions

void init_branches ()
void init_branches_current_section ()
void fill_entry_values (const unsigned int run_no)

Private Attributes

std::vector< Entrymultiple_choices
unsigned int n_branches

Additional Inherited Members

- Public Types inherited from ParameterHandler
enum  OutputStyle {
  DefaultStyle = 0x0000, Short = 0x0001, KeepDeclarationOrder = 0x0002, PRM = 0x0010,
  Text = PRM, LaTeX = 0x0020, Description = 0x0040, XML = 0x0080,
  JSON = 0x0100, ShortPRM = PRM | Short, ShortText = ShortPRM, ShortXML = XML | Short,
  ShortJSON = JSON | Short, ShortLaTeX = LaTeX | Short
using ExcInvalidEntryForPatternXML = ExcValueDoesNotMatchPattern
- Static Public Member Functions inherited from ParameterHandler
static ::ExceptionBaseExcEntryAlreadyExists (std::string arg1)
static ::ExceptionBaseExcValueDoesNotMatchPattern (std::string arg1, std::string arg2)
static ::ExceptionBaseExcAlreadyAtTopLevel ()
static ::ExceptionBaseExcEntryUndeclared (std::string arg1)
static ::ExceptionBaseExcUnbalancedSubsections (std::string arg1, std::string arg2)
static ::ExceptionBaseExcNoSubsection (int arg1, std::string arg2, std::string arg3)
static ::ExceptionBaseExcCannotParseLine (int arg1, std::string arg2, std::string arg3)
static ::ExceptionBaseExcInvalidEntryForPattern (int arg1, std::string arg2, std::string arg3, std::string arg4, std::string arg5)
static ::ExceptionBaseExcInvalidXMLParameterFile ()
static ::ExceptionBaseExcCannotOpenIncludeStatementFile (int arg1, std::string arg2, std::string arg3)
- Static Public Member Functions inherited from Subscriptor
static ::ExceptionBaseExcInUse (int arg1, std::string arg2, std::string arg3)
static ::ExceptionBaseExcNoSubscriber (std::string arg1, std::string arg2)

Detailed Description

The class MultipleParameterLoop offers an easy possibility to test several parameter sets during one run of the program. For this it uses the ParameterHandler class to read in data in a standardized form, searches for variant entry values and performs a loop over all combinations of parameters.

Variant entry values are given like this:

*     set Time step size = { 0.1 | 0.2 | 0.3 }

The loop will then perform three runs of the program, one for each value of Time step size, while all other parameters are as specified or with their default value. If there are several variant entry values in the input, a loop is performed for each combination of variant values:

*     set Time step size = { 0.1 | 0.2 }
*     set Solver         = { CG  | GMRES }

will result in four runs of the programs, with time step 0.1 and 0.2 for each of the two solvers.

In addition to variant entries, this class also supports array entries that look like this:

*     set Output file = ofile.{{ 1 | 2 | 3 | 4 }}

This indicates that if there are variant entries producing a total of four different runs, then we will write their results to the files ofile.1, ofile.2, ofile.3 and ofile.4, respectively. Array entries do not generate multiple runs of the main loop themselves, but if there are variant entries, then in the nth run of the main loop, also the nth value of an array is returned.

Since the different variants are constructed in the order of declaration, not in the order in which the variant entries appear in the input file, it may be difficult to guess the mapping between the different variants and the appropriate entry in an array. You will have to check the order of declaration, or use only one variant entry.

It is guaranteed that only selections which match the regular expression (pattern) given upon declaration of an entry are given back to the program. If a variant value does not match the regular expression, the default value is stored and an error is issued. Before the first run of the loop, all possible values are checked for their conformance, so that the error is issued at the very beginning of the program.


The usage of this class is similar to the ParameterHandler class. First the entries and subsections have to be declared, then a loop is performed in which the different parameter sets are set, a new instance of a user class is created which is then called. Taking the classes of the example for the ParameterHandler class, the extended program would look like this:

class HelperClass : public MultipleParameterLoop::UserClass
HelperClass ();
virtual void create_new (const unsigned int run_no);
virtual void run (ParameterHandler &prm);
static void declare_parameters (ParameterHandler &prm);
std::unique_ptr<Problem> p;
HelperClass::HelperClass () : p(0) {}
void HelperClass::create_new (const unsigned int run_no)
p = std::make_unique<Problem>());
void HelperClass::declare_parameters (ParameterHandler &prm)
Problem::declare_parameters (prm);
p->get_parameters (prm);
p->do_useful_work ();
int main ()
HelperClass h;
HelperClass::declare_parameters (prm);
prm.parse_input ("prmtest.prm");
prm.loop (h);
return 0;

As can be seen, first a new helper class has to be set up. This must contain a virtual constructor for a problem class. You can also derive your problem class from MultipleParameterLoop::UserClass and let create_new clear all member variables. If you have access to all inherited member variables in some way this is the recommended procedure. A third possibility is to use multiple inheritance and derive a helper class from both the MultipleParameterLoop::UserClass and the problem class. In any case, create_new has to provide a clean problem object which is the problem in the second and third possibility.

The derived class also has to provide for member functions which declare the entries and which run the program. Running the program includes getting the parameters out of the ParameterHandler object.

After defining an object of this helper class and an object of the MultipleParameterLoop class, the entries have to be declared in the same way as for the ParameterHandler class. Then the input has to be read. Finally the loop is called. This executes the following steps:

for (each combination)
UserObject.create_new (run_no);
// set parameters for this run (*this);

UserObject is the parameter to the loop function. create_new is given the number of the run (starting from one) to enable naming output files differently for each run.

Syntax for variant and array entry values

Variant values are specified like prefix{ v1 | v2 | v3 | ... }postfix. Whitespace to the right of the opening brace { is ignored as well as to the left of the closing brace } while whitespace on the respectively other side is not ignored. Whitespace around the mid symbols | is also ignored. The empty selection prefix{ v1 | }postfix is also allowed and produces the strings prefixv1postfix and prefixpostfix.

The syntax for array values is equal, apart from the double braces: prefix{{ v1 | v2 | v3 }}postfix.

Worked example

Given the above extensions to the example program for the ParameterHandler and the following input file

*     set Equation 1 = Poisson
*     set Equation 2 = Navier-Stokes
*     set Output file= results.{{ 1 | 2 | 3 | 4 | 5 | 6 }}
*     subsection Equation 1
*       set Matrix type = Sparse
*       subsection Linear solver
*         set Solver                       = CG
*         set Maximum number of iterations = { 10 | 20 | 30 }
*       end
*     end
*     subsection Equation 2
*       set Matrix type = Full
*       subsection Linear solver
*         set Solver                       = { BiCGStab | GMRES }
*         set Maximum number of iterations = 100
*       end
*     end

this is the output:

*     LinEq: Method=CG, MaxIterations=10
*     LinEq: Method=BiCGStab, MaxIterations=100
*     Problem: outfile=results.1
*              eq1=Poisson, eq2=Navier-Stokes
*              Matrix1=Sparse, Matrix2=Full
*     LinEq: Method=CG, MaxIterations=20
*     LinEq: Method=BiCGStab, MaxIterations=100
*     Problem: outfile=results.2
*              eq1=Poisson, eq2=Navier-Stokes
*              Matrix1=Sparse, Matrix2=Full
*     LinEq: Method=CG, MaxIterations=30
*     LinEq: Method=BiCGStab, MaxIterations=100
*     Problem: outfile=results.3
*              eq1=Poisson, eq2=Navier-Stokes
*              Matrix1=Sparse, Matrix2=Full
*     LinEq: Method=CG, MaxIterations=10
*     LinEq: Method=GMRES, MaxIterations=100
*     Problem: outfile=results.4
*              eq1=Poisson, eq2=Navier-Stokes
*              Matrix1=Sparse, Matrix2=Full
*     LinEq: Method=CG, MaxIterations=20
*     LinEq: Method=GMRES, MaxIterations=100
*     Problem: outfile=results.5
*              eq1=Poisson, eq2=Navier-Stokes
*              Matrix1=Sparse, Matrix2=Full
*     LinEq: Method=CG, MaxIterations=30
*     LinEq: Method=GMRES, MaxIterations=100
*     Problem: outfile=results.6
*              eq1=Poisson, eq2=Navier-Stokes
*              Matrix1=Sparse, Matrix2=Full

Since create_new gets the number of the run it would also be possible to output the number of the run.

Definition at line 2077 of file parameter_handler.h.

Constructor & Destructor Documentation

◆ MultipleParameterLoop()

MultipleParameterLoop::MultipleParameterLoop ( )


Definition at line 2071 of file

◆ ~MultipleParameterLoop()

virtual MultipleParameterLoop::~MultipleParameterLoop ( )

Destructor. Declare this only to have a virtual destructor, which is safer as we have virtual functions. It actually does nothing spectacular.

Member Function Documentation

◆ parse_input()

void MultipleParameterLoop::parse_input ( std::istream &  input,
const std::string &  filename = "input file",
const std::string &  last_line = "",
const bool  skip_undefined = false 

Read input from a stream until the stream returns the eof condition or error. The second argument can be used to denote the name of the file (if that's what the input stream represents) we are reading from; this is only used when creating output for error messages.

If non-empty last_line is provided, the ParameterHandler object will stop parsing lines after encountering last_line . This is handy when adding extra data that shall be parsed manually.

If skip_undefined is true, the parameter handler will skip undefined sections and entries. This is useful for partially parsing a parameter file, for example to obtain only the spatial dimension of the problem. By default all entries and subsections are expected to be declared.

This is the only overload of the three parse_input functions implemented by ParameterHandler overridden with new behavior by this class. This is because the other two parse_input functions just reformat their inputs and then call this version.

Reimplemented from ParameterHandler.

Definition at line 2078 of file

◆ loop()

void MultipleParameterLoop::loop ( MultipleParameterLoop::UserClass uc)

run the central loop.

Definition at line 2095 of file

◆ memory_consumption()

std::size_t MultipleParameterLoop::memory_consumption ( ) const

Determine an estimate for the memory consumption (in bytes) of this object.

Definition at line 2229 of file

◆ init_branches()

void MultipleParameterLoop::init_branches ( )

Initialize the different branches, i.e. construct the combinations.

Definition at line 2109 of file

◆ init_branches_current_section()

void MultipleParameterLoop::init_branches_current_section ( )

Traverse the section currently set by enter_subsection()/leave_subsection() and see which of the entries are variant or array entries. Then fill the multiple_choices variable using this information.

Definition at line 2150 of file

◆ fill_entry_values()

void MultipleParameterLoop::fill_entry_values ( const unsigned int  run_no)

Transfer the entry values for one run to the entry tree.

Definition at line 2181 of file

Member Data Documentation

◆ multiple_choices

std::vector<Entry> MultipleParameterLoop::multiple_choices

List of variant entry values.

Definition at line 2250 of file parameter_handler.h.

◆ n_branches

unsigned int MultipleParameterLoop::n_branches

Number of branches constructed from the different combinations of the variants. This obviously equals the number of runs to be performed.

Definition at line 2256 of file parameter_handler.h.

The documentation for this class was generated from the following files: