GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/common/loggingparametertree.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 112 120 93.3%
Functions: 83 106 78.3%
Branches: 197 478 41.2%

Line Branch Exec Source
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 // SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 /*!
8 * \file
9 * \ingroup Parameter
10 * \brief A parameter tree that logs which parameters have been used
11 */
12 #ifndef DUMUX_LOGGING_PARAMETER_TREE_HH
13 #define DUMUX_LOGGING_PARAMETER_TREE_HH
14
15 #include <iomanip>
16 #include <iostream>
17 #include <string>
18 #include <memory>
19 #include <mutex>
20
21 #include <dune/common/parametertree.hh>
22 #include <dumux/common/exceptions.hh>
23
24 namespace Dumux {
25
26 /*!
27 * \ingroup Parameter
28 * \brief A parameter tree that logs which parameters have been used
29 */
30 class LoggingParameterTree
31 {
32
33 public:
34 /*
35 * \brief A logging parameter tree is always attached to an existingparameter tree
36 */
37 LoggingParameterTree() = delete;
38
39 /*
40 * \brief Create LoggingParameterTree from ParameterTree
41 */
42 636 LoggingParameterTree(const Dune::ParameterTree& params, const Dune::ParameterTree& defaultParams)
43 636 : params_(params)
44 , defaultParams_(defaultParams)
45 , usedRuntimeParams_(std::make_unique<Dune::ParameterTree>())
46
1/4
✓ Branch 2 taken 636 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
636 , usedDefaultParams_(std::make_unique<Dune::ParameterTree>())
47 636 {}
48
49 /** \brief test for key
50 *
51 * Tests whether given key exists.
52 *
53 * \note This ignores defaults. Hence, if the
54 * the specified key only exists in the defaults, this
55 * function returns false
56 *
57 * \param key key name
58 * \return true if key exists in structure, otherwise false
59 */
60 bool hasKey(const std::string& key) const
61
5/90
✓ Branch 1 taken 599 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5774 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 418466 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 433 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
425274 { return params_.hasKey(key); }
62
63 /** \brief test for key in group
64 *
65 * Tests whether given key exists in a group.
66 * Given a group this function starts to look from the back
67 * for dots. In G1.G2.G3 the function first looks if the key
68 * "G3.Key" exists, then "G2.Key", ...
69 *
70 * \note This ignores defaults. Hence, if the
71 * the specified key only exists in the defaults, this
72 * function returns false
73 *
74 * \param key key name
75 * \param groupPrefix the group prefix name
76 * \return true if key exists in structure, otherwise false
77 */
78 2639 bool hasKeyInGroup(const std::string& key,
79 const std::string& groupPrefix) const
80 {
81
4/4
✓ Branch 0 taken 1735 times.
✓ Branch 1 taken 904 times.
✓ Branch 2 taken 1735 times.
✓ Branch 3 taken 904 times.
5278 if (groupPrefix.empty())
82 1735 return hasKey(key);
83
84
2/2
✓ Branch 1 taken 690 times.
✓ Branch 2 taken 214 times.
904 if (hasKey(key))
85 return true;
86
87
3/6
✓ Branch 2 taken 690 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 640 times.
✓ Branch 5 taken 50 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1380 auto compoundKey = groupPrefix + "." + key;
88
3/4
✓ Branch 1 taken 690 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 538 times.
✓ Branch 4 taken 152 times.
690 if (params_.hasKey(compoundKey))
89 return true;
90
91
2/4
✓ Branch 1 taken 538 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 538 times.
538 compoundKey = findKeyInGroup(params_, key, groupPrefix);
92
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 538 times.
538 if (compoundKey != "")
93 return true;
94
95 return false;
96 }
97
98 /** \brief obtain a vector of all full group names for a specified subgroup name
99 *
100 * Example:
101 * ------------
102 * For the parameter tree
103 *
104 * [G1]
105 * MyParam1 = 1
106 * [G2.G1]
107 * MyParam2 = 2
108 * [G3.G2.G1]
109 * MyParam3 = 3
110 *
111 * and groupPrefix="G3.G2" and subGroupName="G1"
112 * this returns a vector with the entries {"G3.G2.G1", "G2.G1", "G1"}.
113 * If groupPrefix = "G2", it returns {"G2.G1", "G1"}.
114 * If groupPrefix = "" the returned vector has size 1 (containing subGroupName),
115 * or size 0 if the subgroup does not exist in the parameter tree.
116 *
117 * \param subGroupName the sub group to look for
118 * \param groupPrefix the group prefix name (potentially prefixing the subgroup)
119 * \return a vector of fully qualified groups ordered by decreasing tree depth
120 */
121 403 std::vector<std::string> getSubGroups(const std::string& subGroupName,
122 std::string groupPrefix) const
123 {
124
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 399 times.
403 std::vector<std::string> groupNames;
125
126
4/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 399 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 399 times.
806 if (!groupPrefix.empty())
127 {
128
4/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 1 times.
11 auto compoundGroup = groupPrefix + "." + subGroupName;
129
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (std::string::size_type dotPos = 0; dotPos != std::string::npos; dotPos = groupPrefix.rfind("."))
130 {
131
2/8
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
4 if (params_.hasSub(compoundGroup) || defaultParams_.hasSub(compoundGroup))
132
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 groupNames.push_back(compoundGroup);
133
134
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 groupPrefix = groupPrefix.substr(0, dotPos);
135
4/12
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
4 compoundGroup = groupPrefix + "." + subGroupName;
136 }
137 }
138
139
5/8
✓ Branch 1 taken 403 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 305 times.
✓ Branch 4 taken 98 times.
✓ Branch 6 taken 305 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 305 times.
403 if (params_.hasSub(subGroupName) || defaultParams_.hasSub(subGroupName))
140
1/2
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
98 groupNames.push_back(subGroupName);
141
142 403 return groupNames;
143 }
144
145 /** \brief print the hierarchical parameter tree to stream
146 *
147 * \param stream the output stream to print to
148 */
149 void report(std::ostream& stream = std::cout) const
150 { params_.report(stream); }
151
152 /** \brief print distinct substructure to stream
153 *
154 * Prints all entries with given prefix.
155 *
156 * \param stream Stream to print to
157 */
158 410 void reportAll(std::ostream& stream = std::cout) const
159 {
160 820 stream << "\n# Runtime-specified parameters used:" << std::endl;
161
5/12
✓ Branch 1 taken 410 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 410 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 410 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 410 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 410 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
1230 usedRuntimeParams_->report(stream);
162
163 820 stream << "\n# Global default parameters used:" << std::endl;
164
5/12
✓ Branch 1 taken 410 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 410 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 410 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 410 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 410 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
1230 usedDefaultParams_->report(stream);
165
166 820 const auto unusedParams = getUnusedKeys();
167
4/4
✓ Branch 0 taken 223 times.
✓ Branch 1 taken 187 times.
✓ Branch 2 taken 223 times.
✓ Branch 3 taken 187 times.
820 if (!unusedParams.empty())
168 {
169
1/2
✓ Branch 2 taken 223 times.
✗ Branch 3 not taken.
446 stream << "\n# Unused parameters:" << std::endl;
170
4/4
✓ Branch 0 taken 615 times.
✓ Branch 1 taken 223 times.
✓ Branch 2 taken 615 times.
✓ Branch 3 taken 223 times.
1899 for (const auto& key : unusedParams)
171
4/8
✓ Branch 1 taken 615 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 615 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 615 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 615 times.
✗ Branch 13 not taken.
1845 stream << key << " = \"" << params_[key] << "\"" << std::endl;
172 }
173 410 }
174
175 /*! \brief Do a backwards hierarchical search for a key in a group
176 *
177 * \note Given a group this function starts to look from the back
178 * for dots. In G1.G2.G3 the function first looks if the key
179 * "G3.Key" exists, then "G2.Key", ...
180 * The first compound key that is found is returned. If no
181 * compound key is found an empty string is returned.
182 * \param tree The tree to look in for keys
183 * \param key The key
184 * \param groupPrefix the group prefix attached to the key
185 */
186 7572 std::string findKeyInGroup(const Dune::ParameterTree& tree,
187 const std::string& key,
188 const std::string& groupPrefix) const
189 {
190 // search backwards until key is found
191
2/2
✓ Branch 1 taken 701 times.
✓ Branch 2 taken 6871 times.
15845 std::string prefix = groupPrefix;
192 7572 auto dot = prefix.rfind(".");
193
2/2
✓ Branch 0 taken 1019 times.
✓ Branch 1 taken 7490 times.
8509 while (dot != std::string::npos)
194 {
195
2/4
✓ Branch 1 taken 1019 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1019 times.
1019 prefix = prefix.substr(0, dot);
196
2/6
✓ Branch 1 taken 1019 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1019 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1956 std::string compoundKey = prefix + "." + key;
197
198
3/4
✓ Branch 1 taken 1019 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 82 times.
✓ Branch 4 taken 937 times.
1019 if (tree.hasKey(compoundKey))
199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
246 return compoundKey;
200
201 // look for the next dot in the current prefix
202
2/2
✓ Branch 1 taken 932 times.
✓ Branch 2 taken 5 times.
1874 dot = prefix.rfind(".");
203
204 }
205
206 // the key was not found
207
2/6
✓ Branch 1 taken 7490 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7490 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
14980 return "";
208 }
209
210 /** \brief get value as string
211 *
212 * Returns pure string value for given key.
213 *
214 * \param key key name
215 * \param defaultValue default if key does not exist
216 * \return value as string
217 * \note This might be quite slow so call it only once,
218 * e.g. on initialization of the class configured by runtime parameters
219 */
220 std::string get(const std::string& key, const std::string& defaultValue) const
221 {
222 if (params_.hasKey(key))
223 {
224 // log that we used this parameter
225 const auto returnValue = params_[key];
226 logUsedRuntimeParam_(key, returnValue);
227 return returnValue;
228 }
229
230 return defaultValue;
231 }
232
233 /** \brief get value as string, preferably from the sub-tree corresponding
234 * to a given prefix. The sub-tree is searched backwards for the parameter
235 * until its "first" occurrence.
236 *
237 * Returns pure string value for given key.
238 *
239 * \param groupPrefix The prefix of the sub tree the search should start in
240 * \param key key name
241 * \param defaultValue default if key does not exist
242 * \return value as string
243 * \note This might be quite slow so call it only once,
244 * e.g. on initialization of the class configured by runtime parameters
245 */
246 std::string getFromGroup(const std::string& groupPrefix,
247 const std::string& key,
248 const std::string& defaultValue) const
249 {
250 if (groupPrefix.empty())
251 return get(key, defaultValue);
252
253 // first, look for the compound key
254 std::string compoundKey = groupPrefix + "." + key;
255 if (params_.hasKey(compoundKey))
256 {
257 // log that we used this parameter
258 const auto returnValue = params_[compoundKey];
259 logUsedRuntimeParam_(compoundKey, returnValue);
260 return returnValue;
261 }
262
263 // search backwards until key is found
264 compoundKey = findKeyInGroup(params_, key, groupPrefix);
265 if (compoundKey != "")
266 {
267 // log that we used this parameter
268 const auto returnValue = params_[compoundKey];
269 logUsedRuntimeParam_(compoundKey, returnValue);
270 return returnValue;
271 }
272
273 // finally, look for the key without prefix
274 return get(key, defaultValue);
275 }
276
277 /** \brief get value as string
278 *
279 * Returns pure string value for given key.
280 *
281 * \todo This is a hack so get("my_key", "xyz") compiles
282 * (without this method "xyz" resolves to bool instead of std::string)
283 * \param key key name
284 * \param defaultValue default if key does not exist
285 * \return value as string
286 * \note This might be quite slow so call it only once,
287 * e.g. on initialization of the class configured by runtime parameters
288 */
289 std::string get(const std::string& key, const char* defaultValue) const
290 {
291 const std::string dv = defaultValue;
292 return get(key, dv);
293 }
294
295 /** \brief get value as string, preferably from the sub-tree corresponding
296 * to a given prefix. The sub-tree is searched for the parameter
297 * recursively until its "first" occurrence.
298 *
299 * Returns pure string value for given key.
300 *
301 * \param groupPrefix The prefix of the sub tree the search should start in
302 * \param key key name
303 * \param defaultValue default if key does not exist
304 * \return value as string
305 * \note This might be quite slow so call it only once,
306 * e.g. on initialization of the class configured by runtime parameters
307 */
308 std::string getFromGroup(const std::string& groupPrefix,
309 const std::string& key,
310 const char* defaultValue) const
311 {
312 const std::string dv = defaultValue;
313 return getFromGroup(groupPrefix, key, dv);
314 }
315
316
317 /** \brief get value converted to a certain type
318 *
319 * Returns value as type T for given key.
320 *
321 * \tparam T type of returned value.
322 * \param key key name
323 * \param defaultValue default if key does not exist
324 * \return value converted to T
325 * \note This might be quite slow so call it only once,
326 * e.g. on initialization of the class configured by runtime parameters
327 */
328 template<typename T>
329 63728 T get(const std::string& key, const T& defaultValue) const
330 {
331
2/2
✓ Branch 1 taken 3770 times.
✓ Branch 2 taken 28100 times.
63728 if (params_.hasKey(key))
332 {
333 // log that we used this parameter
334 7537 logUsedRuntimeParam_(key, params_[key]);
335 7537 return params_.template get<T>(key);
336 }
337
338 56191 return defaultValue;
339 }
340
341 /** \brief get value as string, preferably from the sub-tree corresponding
342 * to a given prefix. The sub-tree is searched for the parameter
343 * recursively until its "first" occurrence.
344 *
345 * Returns pure string value for given key.
346 *
347 * \param groupPrefix The prefix of the sub tree the search should start in
348 * \param key key name
349 * \param defaultValue default if key does not exist
350 * \return value as string
351 * \note This might be quite slow so call it only once,
352 * e.g. on initialization of the class configured by runtime parameters
353 */
354 template<typename T>
355 50701 T getFromGroup(const std::string& groupPrefix,
356 const std::string& key,
357 const T& defaultValue) const
358 {
359
4/4
✓ Branch 0 taken 20168 times.
✓ Branch 1 taken 5186 times.
✓ Branch 2 taken 20168 times.
✓ Branch 3 taken 5186 times.
101402 if (groupPrefix.empty())
360 40335 return get<T>(key, defaultValue);
361
362 // first, look for the compound key
363
3/6
✓ Branch 2 taken 5186 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5165 times.
✓ Branch 5 taken 21 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
20732 std::string compoundKey = groupPrefix + "." + key;
364
3/4
✓ Branch 1 taken 5186 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1169 times.
✓ Branch 4 taken 4017 times.
10366 if (params_.hasKey(compoundKey))
365 {
366 // log that we used this parameter
367
2/4
✓ Branch 1 taken 1169 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1169 times.
✗ Branch 5 not taken.
2337 logUsedRuntimeParam_(compoundKey, params_[compoundKey]);
368
1/2
✓ Branch 1 taken 1169 times.
✗ Branch 2 not taken.
2337 return params_.template get<T>(compoundKey);
369 }
370
371 // search backwards until key is found
372
3/4
✓ Branch 1 taken 4017 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 54 times.
✓ Branch 5 taken 3963 times.
8029 compoundKey = findKeyInGroup(params_, key, groupPrefix);
373
2/2
✓ Branch 1 taken 54 times.
✓ Branch 2 taken 3963 times.
8029 if (compoundKey != "")
374 {
375 // log that we used this parameter
376
2/4
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 54 times.
✗ Branch 5 not taken.
108 logUsedRuntimeParam_(compoundKey, params_[compoundKey]);
377
1/2
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
108 return params_.template get<T>(compoundKey);
378 }
379
380 // finally, look for the key without prefix
381
1/2
✓ Branch 1 taken 3963 times.
✗ Branch 2 not taken.
7921 return get<T>(key, defaultValue);
382 }
383
384 /** \brief Get value
385 *
386 * \tparam T Type of the value
387 * \param key Key name
388 * \throws RangeError if key does not exist
389 * \throws NotImplemented Type is not supported
390 * \return value as T
391 * \note This might be quite slow so call it only once,
392 * e.g. on initialization of the class configured by runtime parameters
393 */
394 template <class T>
395 14971 T get(const std::string& key) const
396 {
397
2/2
✓ Branch 1 taken 5608 times.
✓ Branch 2 taken 1887 times.
14971 if (params_.hasKey(key))
398 {
399 // log that we used this parameter
400 11201 logUsedRuntimeParam_(key, params_[key]);
401 11201 return params_.template get<T>(key);
402 }
403
404
1/2
✓ Branch 1 taken 1887 times.
✗ Branch 2 not taken.
3770 else if(defaultParams_.hasKey(key))
405 {
406 // use the default
407 3770 logUsedDefaultParam_(key, defaultParams_[key]);
408 3770 return defaultParams_.template get<T>(key);
409 }
410
411 DUNE_THROW(Dumux::ParameterException, "Key " << key << " not found in the parameter tree");
412 }
413
414 /** \brief get value as string, preferably from the sub-tree corresponding
415 * to a given prefix. The sub-tree is searched for the parameter
416 * recursively until its "first" occurrence.
417 *
418 * Returns pure string value for given key.
419 *
420 * \param groupPrefix The prefix of the sub tree the search should start in
421 * \param key key name
422 * \return value as string
423 * \note This might be quite slow so call it only once,
424 * e.g. on initialization of the class configured by runtime parameters
425 */
426 template<typename T>
427 13050 T getFromGroup(const std::string& groupPrefix,
428 const std::string& key) const
429 {
430
4/4
✓ Branch 0 taken 3102 times.
✓ Branch 1 taken 3467 times.
✓ Branch 2 taken 3102 times.
✓ Branch 3 taken 3467 times.
26100 if (groupPrefix.empty())
431 6135 return get<T>(key);
432
433 // first, look for the compound key
434
3/4
✓ Branch 2 taken 3467 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3436 times.
✓ Branch 5 taken 31 times.
13830 std::string compoundKey = groupPrefix + "." + key;
435
3/4
✓ Branch 1 taken 3467 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1414 times.
✓ Branch 4 taken 2053 times.
6915 if (params_.hasKey(compoundKey))
436 {
437 // log that we used this parameter
438
2/4
✓ Branch 1 taken 1414 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1414 times.
✗ Branch 5 not taken.
2823 logUsedRuntimeParam_(compoundKey, params_[compoundKey]);
439
1/2
✓ Branch 1 taken 1414 times.
✗ Branch 2 not taken.
2823 return params_.template get<T>(compoundKey);
440 }
441
442 // search backwards until key is found
443
3/4
✓ Branch 1 taken 2053 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 2025 times.
4092 compoundKey = findKeyInGroup(params_, key, groupPrefix);
444
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 2025 times.
4092 if (compoundKey != "")
445 {
446 // log that we used this parameter
447
2/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
56 logUsedRuntimeParam_(compoundKey, params_[compoundKey]);
448
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
56 return params_.template get<T>(compoundKey);
449 }
450
451 // reset the compoundKey
452
4/12
✓ Branch 1 taken 2025 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2025 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2025 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 2025 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
8072 compoundKey = groupPrefix + "." + key;
453
454 // if the backward search did not succeed, try the bare key without any prefix
455
3/4
✓ Branch 1 taken 2025 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1061 times.
✓ Branch 4 taken 964 times.
4036 if (params_.hasKey(key))
456 {
457 // log that we used this parameter
458
2/4
✓ Branch 1 taken 1061 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1061 times.
✗ Branch 5 not taken.
2108 logUsedRuntimeParam_(key, params_[key]);
459
1/2
✓ Branch 1 taken 1061 times.
✗ Branch 2 not taken.
2108 return params_.template get<T>(key);
460 }
461
462 // if this did not work, repeat the procedure using the default parameters
463
2/4
✓ Branch 1 taken 964 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 964 times.
1928 else if(defaultParams_.hasKey(compoundKey))
464 {
465 // use the default
466 logUsedDefaultParam_(compoundKey, defaultParams_[compoundKey]);
467 return defaultParams_.template get<T>(compoundKey);
468 }
469
470 else
471 {
472 // search backwards until key is found
473
2/4
✓ Branch 1 taken 964 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 964 times.
1928 compoundKey = findKeyInGroup(defaultParams_, key, groupPrefix);
474
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 964 times.
1928 if (compoundKey != "")
475 {
476 // log that we used this parameter
477 logUsedDefaultParam_(compoundKey, defaultParams_[compoundKey]);
478 return defaultParams_.template get<T>(compoundKey);
479 }
480
481
2/4
✓ Branch 1 taken 964 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 964 times.
✗ Branch 4 not taken.
1928 if(defaultParams_.hasKey(key))
482 {
483 // use the default
484
2/4
✓ Branch 1 taken 964 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 964 times.
✗ Branch 5 not taken.
1928 logUsedDefaultParam_(key, defaultParams_[key]);
485
1/2
✓ Branch 1 taken 964 times.
✗ Branch 2 not taken.
1928 return defaultParams_.template get<T>(key);
486 }
487
488 DUNE_THROW(Dumux::ParameterException, "Key " << key << " not found in the parameter tree with group prefix " << groupPrefix);
489 }
490 }
491
492 /** \brief Find the keys that haven't been used yet
493 *
494 * \return unusedParams Container storing unused keys
495 * \note Useful for debugging purposes
496 */
497 411 std::vector<std::string> getUnusedKeys() const
498 {
499
1/2
✓ Branch 1 taken 411 times.
✗ Branch 2 not taken.
411 std::vector<std::string> unusedParams;
500
4/10
✓ Branch 1 taken 411 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 411 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 411 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 411 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
822 findUnusedKeys_(params_, unusedParams);
501 411 return unusedParams;
502 }
503
504 private:
505 /** \brief Find the keys that haven't been used yet recursively
506 *
507 * \param tree The tree to look in for unused keys
508 * \param unusedParams Container to store unused keys
509 * \param prefix the prefix attached to the key
510 */
511 3684 void findUnusedKeys_(const Dune::ParameterTree& tree,
512 std::vector<std::string>& unusedParams,
513 const std::string& prefix = "") const
514 {
515 // loop over all keys of the current tree
516 // store keys which were not accessed
517 3684 const auto& keys = tree.getValueKeys();
518
4/4
✓ Branch 0 taken 8006 times.
✓ Branch 1 taken 3684 times.
✓ Branch 2 taken 8006 times.
✓ Branch 3 taken 3684 times.
19058 for (const auto& key : keys)
519
13/20
✓ Branch 1 taken 7646 times.
✓ Branch 2 taken 360 times.
✓ Branch 4 taken 7646 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7646 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7646 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 7030 times.
✓ Branch 13 taken 616 times.
✓ Branch 14 taken 7030 times.
✓ Branch 15 taken 360 times.
✓ Branch 16 taken 5627 times.
✓ Branch 17 taken 2019 times.
✓ Branch 18 taken 616 times.
✓ Branch 19 taken 7390 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
15652 if (key != "ParameterFile" && !usedRuntimeParams_->hasKey(prefix + key))
520
2/6
✓ Branch 2 taken 616 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 616 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
616 unusedParams.push_back(prefix + key);
521
522 // recursively loop over all subtrees
523 3684 const auto& subTreeKeys = tree.getSubKeys();
524
4/4
✓ Branch 0 taken 3273 times.
✓ Branch 1 taken 3684 times.
✓ Branch 2 taken 3273 times.
✓ Branch 3 taken 3684 times.
17598 for (const auto& key : subTreeKeys)
525
6/14
✓ Branch 2 taken 3273 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3273 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3273 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 461 times.
✓ Branch 11 taken 2812 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 3273 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
3734 findUnusedKeys_(tree.sub(key), unusedParams, prefix + key + ".");
526 3684 }
527
528 /** \brief Log the key value pair as used runtime param
529 */
530 13587 void logUsedRuntimeParam_(const std::string& key, const std::string& value) const
531 {
532
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
13587 std::scoped_lock lock{ usedRuntimeMutex_ };
533
4/8
✓ Branch 1 taken 13587 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13587 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13587 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 13587 times.
✗ Branch 10 not taken.
27174 usedRuntimeParams_->operator[](key) = value;
534 13587 }
535
536 /** \brief Log the key value pair as used default param
537 */
538 2851 void logUsedDefaultParam_(const std::string& key, const std::string& value) const
539 {
540
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
2851 std::scoped_lock lock{ usedDefaultMutex_ };
541
4/8
✓ Branch 1 taken 2851 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2851 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2851 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2851 times.
✗ Branch 10 not taken.
5702 usedDefaultParams_->operator[](key) = value;
542 2851 }
543
544 const Dune::ParameterTree& params_;
545 const Dune::ParameterTree& defaultParams_;
546
547 // logging caches (externally stored)
548 std::unique_ptr<Dune::ParameterTree> usedRuntimeParams_;
549 std::unique_ptr<Dune::ParameterTree> usedDefaultParams_;
550
551 // access to the caches have to be protected for thread-safety
552 mutable std::mutex usedRuntimeMutex_;
553 mutable std::mutex usedDefaultMutex_;
554 };
555
556 } // end namespace Dumux
557
558 #endif
559