My Project
Loading...
Searching...
No Matches
ParameterGroup_impl.hpp
1//===========================================================================
2//
3// File: ParameterGroup_impl.hpp
4//
5// Created: Tue Jun 2 19:06:46 2009
6//
7// Author(s): Bård Skaflestad <bard.skaflestad@sintef.no>
8// Atgeirr F Rasmussen <atgeirr@sintef.no>
9//
10// $Date$
11//
12// $Revision$
13//
14//===========================================================================
15
16/*
17 Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
18 Copyright 2009, 2010 Statoil ASA.
19
20 This file is part of the Open Porous Media project (OPM).
21
22 OPM is free software: you can redistribute it and/or modify
23 it under the terms of the GNU General Public License as published by
24 the Free Software Foundation, either version 3 of the License, or
25 (at your option) any later version.
26
27 OPM is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public License
33 along with OPM. If not, see <http://www.gnu.org/licenses/>.
34*/
35
36#ifndef OPM_PARAMETERGROUP_IMPL_HEADER
37#define OPM_PARAMETERGROUP_IMPL_HEADER
38
39#include <iostream>
40#include <string>
41#include <stdexcept>
42
43#include <opm/common/utility/parameters/ParameterGroup.hpp>
44#include <opm/common/utility/parameters/ParameterStrings.hpp>
45#include <opm/common/utility/parameters/ParameterTools.hpp>
46#include <opm/common/utility/parameters/Parameter.hpp>
47#include <opm/common/ErrorMacros.hpp>
48#include <opm/common/OpmLog/OpmLog.hpp>
49
50namespace Opm {
51 template<>
53 static ParameterGroup
54 convert(const ParameterMapItem& item,
55 std::string& conversion_error,
56 bool enable_output)
57 {
58 std::string tag = item.getTag();
59 if (tag != ID_xmltag__param_grp) {
60 conversion_error = "The XML tag was '" + tag +
61 "' but should be '" +
62 ID_xmltag__param_grp + "'.\n";
63 return ParameterGroup("", 0, enable_output);
64 }
65 conversion_error = "";
66 const ParameterGroup& pg = dynamic_cast<const ParameterGroup&>(item);
67 return pg;
68 }
69 static std::string type() {return "ParameterGroup";}
70 };
71
72 template <typename T>
73 inline std::string
74 ParameterGroup::to_string(const T& val)
75 {
76 return std::to_string(val);
77 }
78
79 template <>
80 inline std::string
81 ParameterGroup::to_string<std::string>(const std::string& val)
82 {
83 return val;
84 }
85
86 template <>
87 inline std::string
88 ParameterGroup::to_string(const bool& b) {
89 if (b) {
90 return ID_true;
91 } else {
92 return ID_false;
93 }
94 }
95
96 template <>
97 inline std::string
98 ParameterGroup::to_string(const ParameterGroup&)
99 {
100 return std::string("<parameter group>");
101 }
102
103 inline std::pair<std::string, std::string>
104 ParameterGroup::filename_split(const std::string& filename)
105 {
106 int fpos = filename.rfind('.');
107 std::string name = filename.substr(0, fpos);
108 std::string type = filename.substr(fpos+1);
109 return std::make_pair(name, type);
110 }
111
112 template <typename StringArray>
113 ParameterGroup::ParameterGroup(int argc, StringArray argv, bool verify_syntax,
114 const bool enable_output)
115 : path_(ID_path_root), parent_(0), output_is_enabled_(enable_output)
116 {
117 if (verify_syntax && (argc < 2)) {
118 std::cerr << "Usage: " << argv[0] << " "
119 << "[paramfilename1.param] "
120 << "[paramfilename2.param] "
121 << "[overridden_arg1=value1] "
122 << "[overridden_arg2=value2] "
123 << "[...]" << std::endl;
124 exit(EXIT_FAILURE);
125 }
126 this->parseCommandLineArguments(argc, argv, verify_syntax);
127 }
128
129 template <typename StringArray>
130 void ParameterGroup::parseCommandLineArguments(int argc, StringArray argv, bool verify_syntax)
131 {
132 std::vector<std::string> files;
133 std::vector<std::pair<std::string, std::string> > assignments;
134 for (int i = 1; i < argc; ++i) {
135 std::string arg(argv[i]);
136 int fpos = arg.find(ID_delimiter_assignment);
137 if (fpos == int(std::string::npos)) {
138 std::string filename = arg.substr(0, fpos);
139 files.push_back(filename);
140 continue;
141 }
142 int pos = fpos + ID_delimiter_assignment.size();
143 int spos = arg.find(ID_delimiter_assignment, pos);
144 if (spos == int(std::string::npos)) {
145 std::string name = arg.substr(0, fpos);
146 std::string value = arg.substr(pos, spos);
147 assignments.push_back(std::make_pair(name, value));
148 continue;
149 }
150 OpmLog::warning("Too many assignments (' "
151 + ID_delimiter_assignment
152 + "') detected in argument " + to_string(i));
153 }
154 for (int i = 0; i < int(files.size()); ++i) {
155 std::pair<std::string, std::string> file_type = filename_split(files[i]);
156 if (file_type.second == "param") {
157 this->readParam(files[i]);
158 } else {
159 if (verify_syntax) {
160 std::cerr << "ERROR: Input '" << files[i] << "' is not a valid name for a parameter file.\n";
161 std::cerr << " Valid filename extensions are 'param'.\n";
162 OPM_THROW(std::runtime_error, "ParameterGroup cannot handle argument: " + files[i]);
163 } else {
164 unhandled_arguments_.push_back(files[i]);
165 }
166 }
167 }
168 for (int i = 0; i < int(assignments.size()); ++i) {
169 this->insertParameter(assignments[i].first, assignments[i].second);
170 }
171 }
172
173
174 template<typename T>
175 inline T ParameterGroup::get(const std::string& name) const
176 {
177 return this->get<T>(name, ParameterRequirementNone());
178 }
179
180 template<typename T, class Requirement>
181 inline T ParameterGroup::get(const std::string& name,
182 const Requirement& r) const
183 {
184 setUsed();
185 std::pair<std::string, std::string> name_path = splitParam(name);
186 map_type::const_iterator it = map_.find(name_path.first);
187 if (it == map_.end()) {
188 if (parent_ != 0) {
189 // If we have a parent, ask it instead.
190 if (output_is_enabled_) {
191 OpmLog::warning(name + "not found at " + path() + ID_delimiter_path + ", asking parent.");
192 }
193 return parent_->get<T>(name, r);
194 } else {
195 // We are at the top, name has not been found.
196 std::cerr << "ERROR: The group '"
197 << this->path()
198 << "' does not contain an element named '"
199 << name
200 << "'.\n";
201 throw NotFoundException();
202 }
203 }
204 if (name_path.second == "") {
205 T val = this->translate<T>(*it, r);
206 it->second->setUsed();
207 if (output_is_enabled_) {
208 OpmLog::debug(name + " found at " + path() + ID_delimiter_path + ", value is " + to_string(val));
209 }
210 return val;
211 } else {
212 ParameterGroup& pg = dynamic_cast<ParameterGroup&>(*(*it).second);
213 pg.setUsed();
214 return pg.get<T>(name_path.second, r);
215 }
216 }
217
218 template<typename T>
219 inline T ParameterGroup::getDefault(const std::string& name,
220 const T& default_value) const
221 {
222 return this->getDefault<T>(name, default_value, ParameterRequirementNone());
223 }
224
225 template<typename T, class Requirement>
226 inline T ParameterGroup::getDefault(const std::string& name,
227 const T& default_value,
228 const Requirement& r) const
229 {
230 setUsed();
231 std::pair<std::string, std::string> name_path = splitParam(name);
232 map_type::const_iterator it = map_.find(name_path.first);
233 if (it == map_.end()) {
234 if (parent_ != 0) {
235 // If we have a parent, ask it instead.
236 if (output_is_enabled_) {
237 OpmLog::warning(name + " not found at " + path() + ID_delimiter_path + ", asking parent.");
238 }
239 return parent_->getDefault<T>(name, default_value, r);
240 } else {
241 // We check the requirement for the default value
242 std::string requirement_result = r(default_value);
243 if (requirement_result != "") {
244 std::cerr << "ERROR: The default value for the "
245 << " element named '"
246 << name
247 << "' in the group '"
248 << this->path()
249 << "' failed to meet a requirenemt.\n";
250 std::cerr << "The requirement enforcer returned the following message:\n"
251 << requirement_result
252 << "\n";
253 throw RequirementFailedException<Requirement>();
254 }
255 }
256 if (output_is_enabled_) {
257 OpmLog::debug(name + " not found. Using default value '" + to_string(default_value) + "'.");
258 }
259 return default_value;
260 }
261 if (name_path.second == "") {
262 T val = this->translate<T>(*it, r);
263 it->second->setUsed();
264 if (output_is_enabled_) {
265 OpmLog::debug(name + " found at " + path() + ID_delimiter_path
266 + ", value is '" + to_string(val) + "'.");
267 }
268 return val;
269 } else {
270 ParameterGroup& pg = dynamic_cast<ParameterGroup&>(*(*it).second);
271 pg.setUsed();
272 return pg.getDefault<T>(name_path.second, default_value, r);
273 }
274 }
275
276 template<typename T, class Requirement>
277 inline T ParameterGroup::translate(const pair_type& named_data,
278 const Requirement& chk) const
279 {
280 const std::string& name = named_data.first;
281 const data_type data = named_data.second;
282 std::string conversion_error;
283 T value = ParameterMapItemTrait<T>::convert(*data, conversion_error,
284 output_is_enabled_);
285 if (conversion_error != "") {
286 std::cerr << "ERROR: Failed to convert the element named '"
287 << name
288 << "' in the group '"
289 << this->path()
290 << "' to the type '"
291 << ParameterMapItemTrait<T>::type()
292 << "'.\n";
293 std::cerr << "The conversion routine returned the following message:\n"
294 << conversion_error
295 << "\n";
296 throw WrongTypeException();
297 }
298 std::string requirement_result = chk(value);
299 if (requirement_result != "") {
300 std::cerr << "ERROR: The element named '"
301 << name
302 << "' in the group '"
303 << this->path()
304 << "' of type '"
305 << ParameterMapItemTrait<T>::type()
306 << "' failed to meet a requirenemt.\n";
307 std::cerr << "The requirement enforcer returned the following message:\n"
308 << requirement_result
309 << "\n";
310 throw RequirementFailedException<Requirement>();
311 }
312 return value;
313 }
314} // namespace Opm
315
316#endif // OPM_PARAMETERGROUP_IMPL_HEADER
ParameterGroup is a class that is used to provide run-time parameters.
Definition ParameterGroup.hpp:81
std::string path() const
Returns the path of the parameter group.
Definition ParameterGroup.cpp:82
void insertParameter(const std::string &name, const std::string &value)
Insert a new parameter item into the group.
Definition ParameterGroup.cpp:200
T getDefault(const std::string &name, const T &default_value) const
This method is used to read a parameter from the parameter group.
Definition ParameterGroup_impl.hpp:219
void readParam(const std::string &param_filename)
Reads the contents of the param file specified by param_filename into this ParameterGroup.
Definition ParameterGroup.cpp:106
T get(const std::string &name) const
This method is used to read a parameter from the parameter group.
Definition ParameterGroup_impl.hpp:175
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Definition ParameterMapItem.hpp:64
The parameter handlig system is structured as a tree, where each node inhertis from ParameterMapItem.
Definition ParameterMapItem.hpp:47
virtual std::string getTag() const =0
This function returns a string describing the ParameterMapItem.
Definition ParameterRequirement.hpp:48