3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
parameters.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
24#ifndef DUMUX_PARAMETERS_HH
25#define DUMUX_PARAMETERS_HH
26
27#include <iostream>
28#include <list>
29#include <sstream>
30#include <unordered_map>
31#include <fstream>
32
33#include <dune/common/parametertree.hh>
34#include <dune/common/parametertreeparser.hh>
35#include <dune/common/parallel/mpihelper.hh>
36
40
41namespace Dumux {
42
49
50 using DefaultParams = std::function<void (Dune::ParameterTree&)>;
51 using Usage = std::function<void (const char *, const std::string &)>;
52
53public:
54
56 static void init(int argc, char **argv, const Usage& usage)
57 {
58 init(argc, argv, [] (Dune::ParameterTree&) {}, "", usage);
59 }
60
62 static void init(int argc, char **argv,
63 std::string parameterFileName,
64 const Usage& usage = [](const char *, const std::string &){})
65 {
66 init(argc, argv, [] (Dune::ParameterTree&) {}, parameterFileName, usage);
67 }
68
70 static void init(int argc, char **argv,
71 const DefaultParams& defaultParams,
72 const Usage& usage)
73 {
74 init(argc, argv, defaultParams, "", usage);
75 }
76
93 static void init(int argc, char **argv,
94 const DefaultParams& defaultParams = [] (Dune::ParameterTree&) {},
95 std::string parameterFileName = "",
96 const Usage& usage = [](const char *, const std::string &){})
97 {
98 const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv);
99
100 // check whether the user wanted to see the help message
101 for (int i = 1; i < argc; ++i)
102 {
103 if (std::string("--help") == argv[i] || std::string("-h") == argv[i])
104 {
105 // return usage message and return;
106 if (mpiHelper.rank() == 0)
107 usage(argv[0], defaultUsageMessage(argv[0]));
108
109 exit(0);
110 }
111 }
112
113 // apply the default parameters
114 defaultParams(defaultParamTree_());
115 applyGlobalDefaults_(defaultParamTree_());
116
117 // parse paramters from the command line
118 const auto commandLineArgs = parseCommandLine(argc, argv);
119 mergeTree_(paramTree_(), commandLineArgs);
120
121 // overwrite parameter file if one was specified on the command line
122 parameterFileName = commandLineArgs.get<std::string>("ParameterFile", parameterFileName);
123
124 // otherwise use the default name (executable name + .input)
125 if (parameterFileName == "")
126 {
127 parameterFileName = [&](){
128 std::string defaultName = std::string(argv[0]) + ".input";
129 std::ifstream pFile(defaultName.c_str());
130 if (pFile.is_open())
131 return defaultName;
132
133 defaultName = "params.input";
134 pFile = std::ifstream(defaultName.c_str());
135 if (pFile.is_open())
136 return defaultName;
137 else
138 return std::string("");
139 }();
140
141 // if no parameter file was given and also no default names where found, continue without
142 if (parameterFileName == "")
143 {
144 if (mpiHelper.size() > 1)
145 std::cout << "Rank " << mpiHelper.rank() << ": ";
146 std::cout << "No parameter file found. Continuing without parameter file.\n";
147
148 return;
149 }
150 else
151 {
152 if (mpiHelper.size() > 1)
153 std::cout << "Rank " << mpiHelper.rank() << ": ";
154 std::cout << "No parameter file given. "
155 << "Defaulting to '"
156 << parameterFileName
157 << "' for input file.\n";
158 }
159 }
160
161 if (mpiHelper.size() > 1)
162 std::cout << "Rank " << mpiHelper.rank() << ": ";
163 std::cout << "Reading parameters from file " << parameterFileName << ".\n";
164
165 // read parameters from the file without overwriting the command line params
166 // because the command line arguments have precedence
167 // let Dune do the error checking if the file exists
168 Dune::ParameterTreeParser::readINITree(parameterFileName,
169 paramTree_(),
170 /*overwrite=*/false);
171 }
172
180 static void init(const DefaultParams& params = [] (Dune::ParameterTree&) {},
181 const DefaultParams& defaultParams = [] (Dune::ParameterTree&) {})
182 {
183 // apply the parameters
184 params(paramTree_());
185 // apply the default parameters
186 defaultParams(defaultParamTree_());
187 applyGlobalDefaults_(defaultParamTree_());
188 }
189
201 static void init(const std::string& parameterFileName,
202 const DefaultParams& params = [] (Dune::ParameterTree&) {},
203 bool inputFileOverwritesParams = true,
204 const DefaultParams& defaultParams = [] (Dune::ParameterTree&) {})
205 {
206 // apply the parameters
207 params(paramTree_());
208
209 // read parameters from the input file
210 Dune::ParameterTreeParser::readINITree(parameterFileName, paramTree_(), inputFileOverwritesParams);
211
212 // apply the default parameters
213 defaultParams(defaultParamTree_());
214 applyGlobalDefaults_(defaultParamTree_());
215 }
216
218 static void print()
219 {
220 getTree().reportAll();
221 }
222
224 static Dune::ParameterTree parseCommandLine(int argc, char **argv)
225 {
226 Dune::ParameterTree commandLineArgs;
227 for (int i = 1; i < argc; ++i)
228 {
229 if (argv[i][0] != '-' && i == 1)
230 {
231 // try to pass first argument as parameter file
232 commandLineArgs["ParameterFile"] = argv[1];
233 continue;
234 }
235
236 if (argv[i][0] != '-')
237 DUNE_THROW(ParameterException, "-> Command line argument " << i << " (='" << argv[i] << "') is invalid. <-");
238
239 if (i+1 == argc)
240 DUNE_THROW(ParameterException, "-> No argument given for parameter '" << argv[i] << "'! <-");
241
242 // check for the ParameterFile argument
243 if (argv[i]+1 == std::string("ParameterFile")) // +1 removes the '-'
244 {
245 commandLineArgs["ParameterFile"] = argv[i+1];
246 ++i;
247 }
248
249 // add all other options as key value pairs
250 else
251 {
252 // read a -MyOpt VALUE option
253 std::string paramName = argv[i]+1; // +1 removes the '-'
254 std::string paramValue = argv[i+1];
255 ++i; // In the case of '-MyOpt VALUE' each pair counts as two arguments
256
257 // Put the key=value pair into the parameter tree
258 commandLineArgs[paramName] = paramValue;
259 }
260 }
261 return commandLineArgs;
262 }
263
264 [[deprecated("parseCommandLineArguments is deprecated and will be removed after 3.1")]]
265 static std::string parseCommandLineArguments(int argc, char **argv,
266 std::string parameterFileName = "")
267 {
268 for (int i = 1; i < argc; ++i)
269 {
270 if (argv[i][0] != '-' && i == 1)
271 {
272 // try to pass first argument as parameter file
273 parameterFileName = argv[1];
274 continue;
275 }
276
277 if (argv[i][0] != '-')
278 DUNE_THROW(ParameterException, "-> Command line argument " << i << " (='" << argv[i] << "') is invalid. <-");
279
280 if (i+1 == argc)
281 DUNE_THROW(ParameterException, "-> No argument given for parameter '" << argv[i] << "'! <-");
282
283 // check for the ParameterFile argument
284 if (argv[i]+1 == std::string("ParameterFile")) // +1 removes the '-'
285 {
286 parameterFileName = argv[i+1];
287 ++i;
288 }
289
290 // add all other options as key value pairs
291 else
292 {
293 // read a -MyOpt VALUE option
294 std::string paramName = argv[i]+1; // +1 removes the '-'
295 std::string paramValue = argv[i+1];
296 ++i; // In the case of '-MyOpt VALUE' each pair counts as two arguments
297
298 // Put the key=value pair into the parameter tree
299 paramTree_()[paramName] = paramValue;
300 }
301 }
302 return parameterFileName;
303 }
304
311 {
312 static LoggingParameterTree tree(paramTree_(), defaultParamTree_());
313 return tree;
314 }
315
316private:
318 static Dune::ParameterTree& paramTree_()
319 {
320 static Dune::ParameterTree tree;
321 return tree;
322 }
323
325 static Dune::ParameterTree& defaultParamTree_()
326 {
327 static Dune::ParameterTree tree;
328 return tree;
329 }
330
333 static void applyGlobalDefaults_(Dune::ParameterTree& params)
334 {
335 // global defaults
336 Dune::ParameterTree defaultParams;
337
338 // parameters in the implicit group
339 defaultParams["Flux.UpwindWeight"] = "1.0";
340 defaultParams["Implicit.EnableJacobianRecycling"] = "false";
341
342 // parameters in the assembly group
343 defaultParams["Assembly.NumericDifferenceMethod"] = "1";
344
345 // parameters in the linear solver group
346 defaultParams["LinearSolver.GMResRestart"] = "10";
347 defaultParams["LinearSolver.MaxIterations"] = "250";
348 defaultParams["LinearSolver.PreconditionerIterations"] = "1";
349 defaultParams["LinearSolver.PreconditionerRelaxation"] = "1.0";
350 defaultParams["LinearSolver.ResidualReduction"] = "1e-13";
351 defaultParams["LinearSolver.Verbosity"] = "0";
352
353 // parameters in the problem group
354 defaultParams["Problem.EnableGravity"] = "true";
355 defaultParams["Problem.EnableInertiaTerms"] = "true";
356
357 // parameters in the Newton group
358 // MinSteps = 2 makes Newton more robust if converge criterion is not perfect
359 defaultParams["Newton.MinSteps"] = "2";
360 defaultParams["Newton.MaxSteps"] = "18";
361 defaultParams["Newton.TargetSteps"] = "10";
362 defaultParams["Newton.UseLineSearch"] = "false";
363 defaultParams["Newton.EnableChop"] = "false";
364 defaultParams["Newton.EnableShiftCriterion"] = "true";
365 defaultParams["Newton.MaxRelativeShift"] = "1e-8";
366 defaultParams["Newton.EnableResidualCriterion"] = "false";
367 defaultParams["Newton.ResidualReduction"] = "1e-5";
368 defaultParams["Newton.EnableAbsoluteResidualCriterion"] = "false";
369 defaultParams["Newton.MaxAbsoluteResidual"] = "1e-5";
370 defaultParams["Newton.SatisfyResidualAndShiftCriterion"] = "false";
371 defaultParams["Newton.EnablePartialReassembly"] = "false";
372
373 // parameters in the time loop group
374 defaultParams["TimeLoop.MaxTimeStepSize"] = "1e300";
375 defaultParams["TimeLoop.MaxTimeStepDivisions"] = "10";
376
377 // parameters in the vtk group
378 defaultParams["Vtk.AddVelocity"] = "false";
379 defaultParams["Vtk.AddProcessRank"] = "true";
380
381 // parameters in the mpfa group
382 defaultParams["Mpfa.Q"] = "0.0";
383
384 // merge the global default tree but do not overwrite if the parameter already exists
385 mergeTree_(params, defaultParams, false);
386 }
387
389 static void mergeTree_(Dune::ParameterTree& target, const Dune::ParameterTree& source, bool overwrite = true)
390 { mergeTreeImpl_(target, source, overwrite, ""); }
391
393 static void mergeTreeImpl_(Dune::ParameterTree& target, const Dune::ParameterTree& source, bool overwrite, const std::string& group)
394 {
395 const auto prefix = group == "" ? "" : group + ".";
396 for (const auto& key : source.getValueKeys())
397 if (overwrite || !target.hasKey(key))
398 target[prefix + key] = source[key];
399
400 for (const auto& subKey : source.getSubKeys())
401 mergeTreeImpl_(target, source.sub(subKey), overwrite, prefix + subKey);
402 }
403};
404
409[[deprecated("Setting parameters is deprecated and will be removed after 3.1")]]
410void setParam(Dune::ParameterTree& params,
411 const std::string& group,
412 const std::string& key,
413 const std::string& value)
414{
415 if(group == "")
416 params[key] = value;
417 else
418 params[group + "." + key] = value;
419}
420
427template<typename T, typename... Args>
428T getParam(Args&&... args)
429{ return Parameters::getTree().template get<T>(std::forward<Args>(args)... ); }
430
437template<typename T, typename... Args>
438T getParamFromGroup(Args&&... args)
439{ return Parameters::getTree().template getFromGroup<T>(std::forward<Args>(args)... ); }
440
446inline bool hasParam(const std::string& param)
447{ return Parameters::getTree().hasKey(param); }
448
454inline bool hasParamInGroup(const std::string& paramGroup, const std::string& param)
455{ return Parameters::getTree().hasKeyInGroup(param, paramGroup); }
456
457} // namespace Dumux
458
459#endif
Function printing a default usage message.
Some exceptions thrown in DuMux
A parameter tree that logs which parameters have been used.
void setParam(Dune::ParameterTree &params, const std::string &group, const std::string &key, const std::string &value)
a free function to set model- or problem-specific default parameters
Definition: parameters.hh:410
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition: parameters.hh:438
bool hasParamInGroup(const std::string &paramGroup, const std::string &param)
Check whether a key exists in the parameter tree with a model group prefix.
Definition: parameters.hh:454
bool hasParam(const std::string &param)
Check whether a key exists in the parameter tree.
Definition: parameters.hh:446
std::string defaultUsageMessage(const std::string &programName)
Provides a general text block, that is part of error/ help messages.
Definition: defaultusagemessage.hh:37
T getParam(Args &&... args)
A free function to get a parameter from the parameter tree singleton.
Definition: parameters.hh:428
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
Exception thrown if a run-time parameter is not specified correctly.
Definition: exceptions.hh:60
A parameter tree that logs which parameters have been used.
Definition: loggingparametertree.hh:41
void reportAll(std::ostream &stream=std::cout) const
print distinct substructure to stream
Definition: loggingparametertree.hh:109
bool hasKeyInGroup(const std::string &key, const std::string &groupPrefix) const
test for key in group
Definition: loggingparametertree.hh:76
bool hasKey(const std::string &key) const
test for key
Definition: loggingparametertree.hh:62
Parameter class managing runtime input parameters.
Definition: parameters.hh:48
static void init(int argc, char **argv, const DefaultParams &defaultParams=[](Dune::ParameterTree &) {}, std::string parameterFileName="", const Usage &usage=[](const char *, const std::string &){})
Initialize the parameter tree.
Definition: parameters.hh:93
static std::string parseCommandLineArguments(int argc, char **argv, std::string parameterFileName="")
Definition: parameters.hh:265
static void init(const std::string &parameterFileName, const DefaultParams &params=[](Dune::ParameterTree &) {}, bool inputFileOverwritesParams=true, const DefaultParams &defaultParams=[](Dune::ParameterTree &) {})
Initialize the parameter tree.
Definition: parameters.hh:201
static void init(int argc, char **argv, const DefaultParams &defaultParams, const Usage &usage)
Initialize the parameter tree singletons.
Definition: parameters.hh:70
static void init(const DefaultParams &params=[](Dune::ParameterTree &) {}, const DefaultParams &defaultParams=[](Dune::ParameterTree &) {})
Initialize the parameter tree.
Definition: parameters.hh:180
static const LoggingParameterTree & getTree()
Get the parameter tree.
Definition: parameters.hh:310
static void init(int argc, char **argv, std::string parameterFileName, const Usage &usage=[](const char *, const std::string &){})
Initialize the parameter tree singletons.
Definition: parameters.hh:62
static void init(int argc, char **argv, const Usage &usage)
Initialize the parameter tree singletons.
Definition: parameters.hh:56
static void print()
prints all used and unused parameters
Definition: parameters.hh:218
static Dune::ParameterTree parseCommandLine(int argc, char **argv)
Parse command line arguments into a parameter tree.
Definition: parameters.hh:224
void usage(const char *progName, const std::string &errorMsg)
Provides an interface for customizing error messages associated with reading in parameters.
Definition: freeflow/rans/main.cc:60