3.3.0
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
66 bool hasKey(const std::string& key) const
67 { return params_.hasKey(key); }
68
84 bool hasKeyInGroup(const std::string& key,
85 const std::string& groupPrefix) const
86 {
87 if (groupPrefix.empty())
88 return hasKey(key);
89
90 if (hasKey(key))
91 return true;
92
93 auto compoundKey = groupPrefix + "." + key;
94 if (params_.hasKey(compoundKey))
95 return true;
96
97 compoundKey = findKeyInGroup(params_, key, groupPrefix);
98 if (compoundKey != "")
99 return true;
100
101 return false;
102 }
103
127 std::vector<std::string> getSubGroups(const std::string& subGroupName,
128 std::string groupPrefix) const
129 {
130 std::vector<std::string> groupNames;
131
132 if (!groupPrefix.empty())
133 {
134 auto compoundGroup = groupPrefix + "." + subGroupName;
135 for (std::string::size_type dotPos = 0; dotPos != std::string::npos; dotPos = groupPrefix.rfind("."))
136 {
137 if (params_.hasSub(compoundGroup) || defaultParams_.hasSub(compoundGroup))
138 groupNames.push_back(compoundGroup);
139
140 groupPrefix = groupPrefix.substr(0, dotPos);
141 compoundGroup = groupPrefix + "." + subGroupName;
142 }
143 }
144
145 if (params_.hasSub(subGroupName) || defaultParams_.hasSub(subGroupName))
146 groupNames.push_back(subGroupName);
147
148 return groupNames;
149 }
150
155 void report(std::ostream& stream = std::cout) const
156 { params_.report(stream); }
157
164 void reportAll(std::ostream& stream = std::cout) const
165 {
166 stream << "\n# Runtime-specified parameters used:" << std::endl;
167 usedRuntimeParams_.report(stream);
168
169 stream << "\n# Global default parameters used:" << std::endl;
170 usedDefaultParams_.report(stream);
171
172 const auto unusedParams = getUnusedKeys();
173 if (!unusedParams.empty())
174 {
175 stream << "\n# Unused parameters:" << std::endl;
176 for (const auto& key : unusedParams)
177 stream << key << " = \"" << params_[key] << "\"" << std::endl;
178 }
179 }
180
192 std::string findKeyInGroup(const Dune::ParameterTree& tree,
193 const std::string& key,
194 const std::string& groupPrefix) const
195 {
196 // search backwards until key is found
197 std::string prefix = groupPrefix;
198 auto dot = prefix.rfind(".");
199 while (dot != std::string::npos)
200 {
201 prefix = prefix.substr(0, dot);
202 std::string compoundKey = prefix + "." + key;
203
204 if (tree.hasKey(compoundKey))
205 return compoundKey;
206
207 // look for the next dot in the current prefix
208 dot = prefix.rfind(".");
209
210 }
211
212 // the key was not found
213 return "";
214 }
215
226 std::string get(const std::string& key, const std::string& defaultValue) const
227 {
228 if (params_.hasKey(key))
229 {
230 // log that we used this parameter
231 const auto returnValue = params_[key];
232 usedRuntimeParams_[key] = returnValue;
233 return returnValue;
234 }
235
236 return defaultValue;
237 }
238
252 std::string getFromGroup(const std::string& groupPrefix,
253 const std::string& key,
254 const std::string& defaultValue) const
255 {
256 if (groupPrefix.empty())
257 return get(key, defaultValue);
258
259 // first, look for the compound key
260 std::string compoundKey = groupPrefix + "." + key;
261 if (params_.hasKey(compoundKey))
262 {
263 // log that we used this parameter
264 const auto returnValue = params_[compoundKey];
265 usedRuntimeParams_[compoundKey] = returnValue;
266 return returnValue;
267 }
268
269 // search backwards until key is found
270 compoundKey = findKeyInGroup(params_, key, groupPrefix);
271 if (compoundKey != "")
272 {
273 // log that we used this parameter
274 const auto returnValue = params_[compoundKey];
275 usedRuntimeParams_[compoundKey] = returnValue;
276 return returnValue;
277 }
278
279 // finally, look for the key without prefix
280 return get(key, defaultValue);
281 }
282
295 std::string get(const std::string& key, const char* defaultValue) const
296 {
297 const std::string dv = defaultValue;
298 return get(key, dv);
299 }
300
314 std::string getFromGroup(const std::string& groupPrefix,
315 const std::string& key,
316 const char* defaultValue) const
317 {
318 const std::string dv = defaultValue;
319 return getFromGroup(groupPrefix, key, dv);
320 }
321
322
334 template<typename T>
335 T get(const std::string& key, const T& defaultValue) const
336 {
337 if (params_.hasKey(key))
338 {
339 // log that we used this parameter
340 usedRuntimeParams_[key] = params_[key];
341 return params_.template get<T>(key);
342 }
343
344 return defaultValue;
345 }
346
360 template<typename T>
361 T getFromGroup(const std::string& groupPrefix,
362 const std::string& key,
363 const T& defaultValue) const
364 {
365 if (groupPrefix.empty())
366 return get<T>(key, defaultValue);
367
368 // first, look for the compound key
369 std::string compoundKey = groupPrefix + "." + key;
370 if (params_.hasKey(compoundKey))
371 {
372 // log that we used this parameter
373 usedRuntimeParams_[compoundKey] = params_[compoundKey];
374 return params_.template get<T>(compoundKey);
375 }
376
377 // search backwards until key is found
378 compoundKey = findKeyInGroup(params_, key, groupPrefix);
379 if (compoundKey != "")
380 {
381 // log that we used this parameter
382 usedRuntimeParams_[compoundKey] = params_[compoundKey];
383 return params_.template get<T>(compoundKey);
384 }
385
386 // finally, look for the key without prefix
387 return get<T>(key, defaultValue);
388 }
389
400 template <class T>
401 T get(const std::string& key) const
402 {
403 if (params_.hasKey(key))
404 {
405 // log that we used this parameter
406 usedRuntimeParams_[key] = params_[key];
407 return params_.template get<T>(key);
408 }
409
410 else if(defaultParams_.hasKey(key))
411 {
412 // use the default
413 usedDefaultParams_[key] = defaultParams_[key];
414 return defaultParams_.template get<T>(key);
415 }
416
417 DUNE_THROW(Dumux::ParameterException, "Key " << key << " not found in the parameter tree");
418 }
419
432 template<typename T>
433 T getFromGroup(const std::string& groupPrefix,
434 const std::string& key) const
435 {
436 if (groupPrefix.empty())
437 return get<T>(key);
438
439 // first, look for the compound key
440 std::string compoundKey = groupPrefix + "." + key;
441 if (params_.hasKey(compoundKey))
442 {
443 // log that we used this parameter
444 usedRuntimeParams_[compoundKey] = params_[compoundKey];
445 return params_.template get<T>(compoundKey);
446 }
447
448 // search backwards until key is found
449 compoundKey = findKeyInGroup(params_, key, groupPrefix);
450 if (compoundKey != "")
451 {
452 // log that we used this parameter
453 usedRuntimeParams_[compoundKey] = params_[compoundKey];
454 return params_.template get<T>(compoundKey);
455 }
456
457 // reset the compoundKey
458 compoundKey = groupPrefix + "." + key;
459
460 // if the backward search did not succeed, try the bare key without any prefix
461 if (params_.hasKey(key))
462 {
463 // log that we used this parameter
464 usedRuntimeParams_[key] = params_[key];
465 return params_.template get<T>(key);
466 }
467
468 // if this did not work, repeat the procedure using the default parameters
469 else if(defaultParams_.hasKey(compoundKey))
470 {
471 // use the default
472 usedDefaultParams_[compoundKey] = defaultParams_[compoundKey];
473 return defaultParams_.template get<T>(compoundKey);
474 }
475
476 else
477 {
478 // search backwards until key is found
479 compoundKey = findKeyInGroup(defaultParams_, key, groupPrefix);
480 if (compoundKey != "")
481 {
482 // log that we used this parameter
483 usedDefaultParams_[compoundKey] = defaultParams_[compoundKey];
484 return defaultParams_.template get<T>(compoundKey);
485 }
486
487 if(defaultParams_.hasKey(key))
488 {
489 // use the default
490 usedDefaultParams_[key] = defaultParams_[key];
491 return defaultParams_.template get<T>(key);
492 }
493
494 DUNE_THROW(Dumux::ParameterException, "Key " << key << " not found in the parameter tree");
495 }
496 }
497
503 std::vector<std::string> getUnusedKeys() const
504 {
505 std::vector<std::string> unusedParams;
506 findUnusedKeys_(params_, unusedParams);
507 return unusedParams;
508 }
509
510private:
517 void findUnusedKeys_(const Dune::ParameterTree& tree,
518 std::vector<std::string>& unusedParams,
519 const std::string& prefix = "") const
520 {
521 // loop over all keys of the current tree
522 // store keys which were not accessed
523 const auto& keys = tree.getValueKeys();
524 for (const auto& key : keys)
525 if (key != "ParameterFile" && !usedRuntimeParams_.hasKey(prefix + key))
526 unusedParams.push_back(prefix + key);
527
528 // recursively loop over all subtrees
529 const auto& subTreeKeys = tree.getSubKeys();
530 for (const auto& key : subTreeKeys)
531 findUnusedKeys_(tree.sub(key), unusedParams, prefix + key + ".");
532 }
533
534 const Dune::ParameterTree& params_;
535 const Dune::ParameterTree& defaultParams_;
536
537 // logging caches
538 mutable Dune::ParameterTree usedRuntimeParams_;
539 mutable Dune::ParameterTree usedDefaultParams_;
540};
541
542} // end namespace Dumux
543
544#endif
Some exceptions thrown in DuMux
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:252
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:361
void report(std::ostream &stream=std::cout) const
print the hierarchical parameter tree to stream
Definition: loggingparametertree.hh:155
std::string get(const std::string &key, const std::string &defaultValue) const
get value as string
Definition: loggingparametertree.hh:226
void reportAll(std::ostream &stream=std::cout) const
print distinct substructure to stream
Definition: loggingparametertree.hh:164
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:192
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:314
std::vector< std::string > getSubGroups(const std::string &subGroupName, std::string groupPrefix) const
obtain a vector of all full group names for a specified subgroup name
Definition: loggingparametertree.hh:127
bool hasKeyInGroup(const std::string &key, const std::string &groupPrefix) const
test for key in group
Definition: loggingparametertree.hh:84
std::string get(const std::string &key, const char *defaultValue) const
get value as string
Definition: loggingparametertree.hh:295
T get(const std::string &key) const
Get value.
Definition: loggingparametertree.hh:401
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:503
T get(const std::string &key, const T &defaultValue) const
get value converted to a certain type
Definition: loggingparametertree.hh:335
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:433
bool hasKey(const std::string &key) const
test for key
Definition: loggingparametertree.hh:66