3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
loggingparametertree.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_LOGGING_PARAMETER_TREE_HH
25#define DUMUX_LOGGING_PARAMETER_TREE_HH
26
27#include <iomanip>
28#include <iostream>
29#include <string>
30
31#include <dune/common/parametertree.hh>
33
34namespace Dumux {
35
41{
42
43public:
44 /*
45 * \brief A logging parameter tree is always attached to an existingparameter tree
46 */
48
49 /*
50 * \brief Create LoggingParameterTree from ParameterTree
51 */
52 LoggingParameterTree(const Dune::ParameterTree& params, const Dune::ParameterTree& defaultParams)
53 : params_(params), defaultParams_(defaultParams) {}
54
62 bool hasKey(const std::string& key) const
63 { return params_.hasKey(key); }
64
76 bool hasKeyInGroup(const std::string& key,
77 const std::string& groupPrefix) const
78 {
79 if (groupPrefix == "")
80 return hasKey(key);
81
82 if (hasKey(key))
83 return true;
84
85 auto compoundKey = groupPrefix + "." + key;
86 if (params_.hasKey(compoundKey) || defaultParams_.hasKey(compoundKey))
87 return true;
88
89 compoundKey = findKeyInGroup(params_, key, groupPrefix);
90 if (compoundKey != "")
91 return true;
92
93 return false;
94 }
95
100 void report(std::ostream& stream = std::cout) const
101 { params_.report(stream); }
102
109 void reportAll(std::ostream& stream = std::cout) const
110 {
111 stream << "\n# Runtime-specified parameters used:" << std::endl;
112 usedRuntimeParams_.report(stream);
113
114 stream << "\n# Global default parameters used:" << std::endl;
115 usedDefaultParams_.report(stream);
116
117 const auto unusedParams = getUnusedKeys();
118 if (!unusedParams.empty())
119 {
120 stream << "\n# Unused parameters:" << std::endl;
121 for (const auto& key : unusedParams)
122 stream << key << " = \"" << params_[key] << "\"" << std::endl;
123 }
124 }
125
137 std::string findKeyInGroup(const Dune::ParameterTree& tree,
138 const std::string& key,
139 const std::string& groupPrefix) const
140 {
141 // search backwards until key is found
142 std::string prefix = groupPrefix;
143 auto dot = prefix.rfind(".");
144 while (dot != std::string::npos)
145 {
146 prefix = prefix.substr(0, dot);
147 std::string compoundKey = prefix + "." + key;
148
149 if (tree.hasKey(compoundKey))
150 return compoundKey;
151
152 // look for the next dot in the current prefix
153 dot = prefix.rfind(".");
154
155 }
156
157 // the key was not found
158 return "";
159 }
160
171 std::string get(const std::string& key, const std::string& defaultValue) const
172 {
173 if (params_.hasKey(key))
174 {
175 // log that we used this parameter
176 const auto returnValue = params_[key];
177 usedRuntimeParams_[key] = returnValue;
178 return returnValue;
179 }
180
181 return defaultValue;
182 }
183
197 std::string getFromGroup(const std::string& groupPrefix,
198 const std::string& key,
199 const std::string& defaultValue) const
200 {
201 if (groupPrefix == "")
202 return get(key, defaultValue);
203
204 // first, look for the compound key
205 std::string compoundKey = groupPrefix + "." + key;
206 if (params_.hasKey(compoundKey))
207 {
208 // log that we used this parameter
209 const auto returnValue = params_[compoundKey];
210 usedRuntimeParams_[compoundKey] = returnValue;
211 return returnValue;
212 }
213
214 // search backwards until key is found
215 compoundKey = findKeyInGroup(params_, key, groupPrefix);
216 if (compoundKey != "")
217 {
218 // log that we used this parameter
219 const auto returnValue = params_[compoundKey];
220 usedRuntimeParams_[compoundKey] = returnValue;
221 return returnValue;
222 }
223
224 // finally, look for the key without prefix
225 return get(key, defaultValue);
226 }
227
240 std::string get(const std::string& key, const char* defaultValue) const
241 {
242 const std::string dv = defaultValue;
243 return get(key, dv);
244 }
245
259 std::string getFromGroup(const std::string& groupPrefix,
260 const std::string& key,
261 const char* defaultValue) const
262 {
263 const std::string dv = defaultValue;
264 return getFromGroup(groupPrefix, key, dv);
265 }
266
267
279 template<typename T>
280 T get(const std::string& key, const T& defaultValue) const
281 {
282 if (params_.hasKey(key))
283 {
284 // log that we used this parameter
285 usedRuntimeParams_[key] = params_[key];
286 return params_.template get<T>(key);
287 }
288
289 return defaultValue;
290 }
291
305 template<typename T>
306 T getFromGroup(const std::string& groupPrefix,
307 const std::string& key,
308 const T& defaultValue) const
309 {
310 if (groupPrefix == "")
311 return get<T>(key, defaultValue);
312
313 // first, look for the compound key
314 std::string compoundKey = groupPrefix + "." + key;
315 if (params_.hasKey(compoundKey))
316 {
317 // log that we used this parameter
318 usedRuntimeParams_[compoundKey] = params_[compoundKey];
319 return params_.template get<T>(compoundKey);
320 }
321
322 // search backwards until key is found
323 compoundKey = findKeyInGroup(params_, key, groupPrefix);
324 if (compoundKey != "")
325 {
326 // log that we used this parameter
327 usedRuntimeParams_[compoundKey] = params_[compoundKey];
328 return params_.template get<T>(compoundKey);
329 }
330
331 // finally, look for the key without prefix
332 return get<T>(key, defaultValue);
333 }
334
345 template <class T>
346 T get(const std::string& key) const
347 {
348 if (params_.hasKey(key))
349 {
350 // log that we used this parameter
351 usedRuntimeParams_[key] = params_[key];
352 return params_.template get<T>(key);
353 }
354
355 else if(defaultParams_.hasKey(key))
356 {
357 // use the default
358 usedDefaultParams_[key] = defaultParams_[key];
359 return defaultParams_.template get<T>(key);
360 }
361
362 DUNE_THROW(Dumux::ParameterException, "Key " << key << " not found in the parameter tree");
363 }
364
377 template<typename T>
378 T getFromGroup(const std::string& groupPrefix,
379 const std::string& key) const
380 {
381 if (groupPrefix == "")
382 return get<T>(key);
383
384 // first, look for the compound key
385 std::string compoundKey = groupPrefix + "." + key;
386 if (params_.hasKey(compoundKey))
387 {
388 // log that we used this parameter
389 usedRuntimeParams_[compoundKey] = params_[compoundKey];
390 return params_.template get<T>(compoundKey);
391 }
392
393 // search backwards until key is found
394 compoundKey = findKeyInGroup(params_, key, groupPrefix);
395 if (compoundKey != "")
396 {
397 // log that we used this parameter
398 usedRuntimeParams_[compoundKey] = params_[compoundKey];
399 return params_.template get<T>(compoundKey);
400 }
401
402 // reset the compoundKey
403 compoundKey = groupPrefix + "." + key;
404
405 // if the backward search did not succeed, try the bare key without any prefix
406 if (params_.hasKey(key))
407 {
408 // log that we used this parameter
409 usedRuntimeParams_[key] = params_[key];
410 return params_.template get<T>(key);
411 }
412
413 // if this did not work, repeat the procedure using the default parameters
414 else if(defaultParams_.hasKey(compoundKey))
415 {
416 // use the default
417 usedDefaultParams_[compoundKey] = defaultParams_[compoundKey];
418 return defaultParams_.template get<T>(compoundKey);
419 }
420
421 else
422 {
423 // search backwards until key is found
424 compoundKey = findKeyInGroup(defaultParams_, key, groupPrefix);
425 if (compoundKey != "")
426 {
427 // log that we used this parameter
428 usedDefaultParams_[compoundKey] = defaultParams_[compoundKey];
429 return defaultParams_.template get<T>(compoundKey);
430 }
431
432 if(defaultParams_.hasKey(key))
433 {
434 // use the default
435 usedDefaultParams_[key] = defaultParams_[key];
436 return defaultParams_.template get<T>(key);
437 }
438
439 DUNE_THROW(Dumux::ParameterException, "Key " << key << " not found in the parameter tree");
440 }
441 }
442
448 std::vector<std::string> getUnusedKeys() const
449 {
450 std::vector<std::string> unusedParams;
451 findUnusedKeys(params_, unusedParams);
452 return unusedParams;
453 }
454
455private:
462 void findUnusedKeys(const Dune::ParameterTree& tree,
463 std::vector<std::string>& unusedParams,
464 const std::string& prefix = "") const
465 {
466 // loop over all keys of the current tree
467 // store keys which were not accessed
468 const auto& keys = tree.getValueKeys();
469 for (const auto& key : keys)
470 if (key != "ParameterFile" && !usedRuntimeParams_.hasKey(prefix + key))
471 unusedParams.push_back(prefix + key);
472
473 // recursively loop over all subtrees
474 const auto& subTreeKeys = tree.getSubKeys();
475 for (const auto& key : subTreeKeys)
476 findUnusedKeys(tree.sub(key), unusedParams, prefix + key + ".");
477 }
478
479 const Dune::ParameterTree& params_;
480 const Dune::ParameterTree& defaultParams_;
481
482 // logging caches
483 mutable Dune::ParameterTree usedRuntimeParams_;
484 mutable Dune::ParameterTree usedDefaultParams_;
485};
486
487} // end namespace Dumux
488
489#endif
Some exceptions thrown in DuMux
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
std::string getFromGroup(const std::string &groupPrefix, const std::string &key, const std::string &defaultValue) const
get value as string, preferably from the sub-tree corresponding to a given prefix....
Definition: loggingparametertree.hh:197
T getFromGroup(const std::string &groupPrefix, const std::string &key, const T &defaultValue) const
get value as string, preferably from the sub-tree corresponding to a given prefix....
Definition: loggingparametertree.hh:306
void report(std::ostream &stream=std::cout) const
print the hierarchical parameter tree to stream
Definition: loggingparametertree.hh:100
std::string get(const std::string &key, const std::string &defaultValue) const
get value as string
Definition: loggingparametertree.hh:171
void reportAll(std::ostream &stream=std::cout) const
print distinct substructure to stream
Definition: loggingparametertree.hh:109
std::string findKeyInGroup(const Dune::ParameterTree &tree, const std::string &key, const std::string &groupPrefix) const
Do a backwards hierarchical search for a key in a group.
Definition: loggingparametertree.hh:137
std::string getFromGroup(const std::string &groupPrefix, const std::string &key, const char *defaultValue) const
get value as string, preferably from the sub-tree corresponding to a given prefix....
Definition: loggingparametertree.hh:259
bool hasKeyInGroup(const std::string &key, const std::string &groupPrefix) const
test for key in group
Definition: loggingparametertree.hh:76
std::string get(const std::string &key, const char *defaultValue) const
get value as string
Definition: loggingparametertree.hh:240
T get(const std::string &key) const
Get value.
Definition: loggingparametertree.hh:346
LoggingParameterTree(const Dune::ParameterTree &params, const Dune::ParameterTree &defaultParams)
Definition: loggingparametertree.hh:52
std::vector< std::string > getUnusedKeys() const
Find the keys that haven't been used yet.
Definition: loggingparametertree.hh:448
T get(const std::string &key, const T &defaultValue) const
get value converted to a certain type
Definition: loggingparametertree.hh:280
T getFromGroup(const std::string &groupPrefix, const std::string &key) const
get value as string, preferably from the sub-tree corresponding to a given prefix....
Definition: loggingparametertree.hh:378
bool hasKey(const std::string &key) const
test for key
Definition: loggingparametertree.hh:62