ParameterGroup_impl.hpp
Go to the documentation of this file.
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
49
50namespace Opm {
51 template<>
53 static ParameterGroup
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 std::ostringstream os;
77 os << val;
78 return os.str();
79 }
80
81 template <>
82 inline std::string
83 ParameterGroup::to_string(const bool& b) {
84 if (b) {
85 return ID_true;
86 } else {
87 return ID_false;
88 }
89 }
90
91 template <>
92 inline std::string
93 ParameterGroup::to_string(const ParameterGroup&)
94 {
95 return std::string("<parameter group>");
96 }
97
98 inline std::pair<std::string, std::string>
99 ParameterGroup::filename_split(const std::string& filename)
100 {
101 int fpos = filename.rfind('.');
102 std::string name = filename.substr(0, fpos);
103 std::string type = filename.substr(fpos+1);
104 return std::make_pair(name, type);
105 }
106
107 template <typename StringArray>
108 ParameterGroup::ParameterGroup(int argc, StringArray argv, bool verify_syntax,
109 const bool enable_output)
110 : path_(ID_path_root), parent_(0), output_is_enabled_(enable_output)
111 {
112 if (verify_syntax && (argc < 2)) {
113 std::cerr << "Usage: " << argv[0] << " "
114 << "[paramfilename1.param] "
115 << "[paramfilename2.param] "
116 << "[overridden_arg1=value1] "
117 << "[overridden_arg2=value2] "
118 << "[...]" << std::endl;
119 exit(EXIT_FAILURE);
120 }
121 this->parseCommandLineArguments(argc, argv, verify_syntax);
122 }
123
124 template <typename StringArray>
125 void ParameterGroup::parseCommandLineArguments(int argc, StringArray argv, bool verify_syntax)
126 {
127 std::vector<std::string> files;
128 std::vector<std::pair<std::string, std::string> > assignments;
129 for (int i = 1; i < argc; ++i) {
130 std::string arg(argv[i]);
131 int fpos = arg.find(ID_delimiter_assignment);
132 if (fpos == int(std::string::npos)) {
133 std::string filename = arg.substr(0, fpos);
134 files.push_back(filename);
135 continue;
136 }
137 int pos = fpos + ID_delimiter_assignment.size();
138 int spos = arg.find(ID_delimiter_assignment, pos);
139 if (spos == int(std::string::npos)) {
140 std::string name = arg.substr(0, fpos);
141 std::string value = arg.substr(pos, spos);
142 assignments.push_back(std::make_pair(name, value));
143 continue;
144 }
145 OpmLog::warning("Too many assignements (' "
147 + "') detected in argument " + to_string(i));
148 }
149 for (int i = 0; i < int(files.size()); ++i) {
150 std::pair<std::string, std::string> file_type = filename_split(files[i]);
151 if (file_type.second == "param") {
152 this->readParam(files[i]);
153 } else {
154 if (verify_syntax) {
155 std::cerr << "ERROR: Input '" << files[i] << "' is not a valid name for a parameter file.\n";
156 std::cerr << " Valid filename extensions are 'param'.\n";
157 OPM_THROW(std::runtime_error, "ParameterGroup cannot handle argument: " << files[i]);
158 } else {
159 unhandled_arguments_.push_back(files[i]);
160 }
161 }
162 }
163 for (int i = 0; i < int(assignments.size()); ++i) {
164 this->insertParameter(assignments[i].first, assignments[i].second);
165 }
166 }
167
168
169 template<typename T>
170 inline T ParameterGroup::get(const std::string& name) const
171 {
172 return this->get<T>(name, ParameterRequirementNone());
173 }
174
175 template<typename T, class Requirement>
177 const Requirement& r) const
178 {
179 setUsed();
180 std::pair<std::string, std::string> name_path = splitParam(name);
181 map_type::const_iterator it = map_.find(name_path.first);
182 if (it == map_.end()) {
183 if (parent_ != 0) {
184 // If we have a parent, ask it instead.
185 if (output_is_enabled_) {
186 OpmLog::warning(name + "not found at " + path() + ID_delimiter_path + ", asking parent.");
187 }
188 return parent_->get<T>(name, r);
189 } else {
190 // We are at the top, name has not been found.
191 std::cerr << "ERROR: The group '"
192 << this->path()
193 << "' does not contain an element named '"
194 << name
195 << "'.\n";
196 throw NotFoundException();
197 }
198 }
199 if (name_path.second == "") {
200 T val = this->translate<T>(*it, r);
201 it->second->setUsed();
202 if (output_is_enabled_) {
203 OpmLog::debug(name + " found at " + path() + ID_delimiter_path + ", value is " + to_string(val));
204 }
205 return val;
206 } else {
207 ParameterGroup& pg = dynamic_cast<ParameterGroup&>(*(*it).second);
208 pg.setUsed();
209 return pg.get<T>(name_path.second, r);
210 }
211 }
212
213 template<typename T>
215 const T& default_value) const
216 {
217 return this->getDefault<T>(name, default_value, ParameterRequirementNone());
218 }
219
220 template<typename T, class Requirement>
222 const T& default_value,
223 const Requirement& r) const
224 {
225 setUsed();
226 std::pair<std::string, std::string> name_path = splitParam(name);
227 map_type::const_iterator it = map_.find(name_path.first);
228 if (it == map_.end()) {
229 if (parent_ != 0) {
230 // If we have a parent, ask it instead.
231 if (output_is_enabled_) {
232 OpmLog::warning(name + " not found at " + path() + ID_delimiter_path + ", asking parent.");
233 }
234 return parent_->getDefault<T>(name, default_value, r);
235 } else {
236 // We check the requirement for the default value
237 std::string requirement_result = r(default_value);
238 if (requirement_result != "") {
239 std::cerr << "ERROR: The default value for the "
240 << " element named '"
241 << name
242 << "' in the group '"
243 << this->path()
244 << "' failed to meet a requirenemt.\n";
245 std::cerr << "The requirement enforcer returned the following message:\n"
246 << requirement_result
247 << "\n";
249 }
250 }
251 if (output_is_enabled_) {
252 OpmLog::debug(name + " not found. Using default value '" + to_string(default_value) + "'.");
253 }
254 return default_value;
255 }
256 if (name_path.second == "") {
257 T val = this->translate<T>(*it, r);
258 it->second->setUsed();
259 if (output_is_enabled_) {
260 OpmLog::debug(name + " found at " + path() + ID_delimiter_path
261 + ", value is '" + to_string(val) + "'.");
262 }
263 return val;
264 } else {
265 ParameterGroup& pg = dynamic_cast<ParameterGroup&>(*(*it).second);
266 pg.setUsed();
267 return pg.getDefault<T>(name_path.second, default_value, r);
268 }
269 }
270
271 template<typename T, class Requirement>
272 inline T ParameterGroup::translate(const pair_type& named_data,
273 const Requirement& chk) const
274 {
275 const std::string& name = named_data.first;
276 const data_type data = named_data.second;
277 std::string conversion_error;
278 T value = ParameterMapItemTrait<T>::convert(*data, conversion_error,
279 output_is_enabled_);
280 if (conversion_error != "") {
281 std::cerr << "ERROR: Failed to convert the element named '"
282 << name
283 << "' in the group '"
284 << this->path()
285 << "' to the type '"
287 << "'.\n";
288 std::cerr << "The conversion routine returned the following message:\n"
289 << conversion_error
290 << "\n";
291 throw WrongTypeException();
292 }
293 std::string requirement_result = chk(value);
294 if (requirement_result != "") {
295 std::cerr << "ERROR: The element named '"
296 << name
297 << "' in the group '"
298 << this->path()
299 << "' of type '"
301 << "' failed to meet a requirenemt.\n";
302 std::cerr << "The requirement enforcer returned the following message:\n"
303 << requirement_result
304 << "\n";
305 throw RequirementFailedException<Requirement>();
306 }
307 return value;
308 }
309} // namespace Opm
310
311#endif // OPM_PARAMETERGROUP_IMPL_HEADER
#define OPM_THROW(Exception, message)
Definition: ErrorMacros.hpp:52
const cJSON *const b
Definition: cJSON.h:251
const char *const name
Definition: cJSON.h:258
cJSON * item
Definition: cJSON.h:218
const char *const string
Definition: cJSON.h:170
static void debug(const std::string &message)
static void warning(const std::string &message)
Definition: ParameterGroup.hpp:81
std::string path() const
Returns the path of the parameter group.
void insertParameter(const std::string &name, const std::string &value)
Insert a new parameter item into the group.
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:214
void readParam(const std::string &param_filename)
Reads the contents of the param file specified by param_filename into this ParameterGroup.
T get(const std::string &name) const
This method is used to read a parameter from the parameter group.
Definition: ParameterGroup_impl.hpp:170
std::ostream & cerr()
constexpr const double second
Definition: custom-opm-common/opm-common/opm/parser/eclipse/Units/Units.hpp:104
Definition: A.hpp:4
const std::string ID_true
Definition: ParameterStrings.hpp:42
const std::string ID_path_root
Definition: ParameterStrings.hpp:57
const std::string ID_delimiter_path
Definition: ParameterStrings.hpp:58
const std::string ID_xmltag__param_grp
Definition: ParameterStrings.hpp:45
const std::string ID_false
Definition: ParameterStrings.hpp:43
std::pair< std::string, std::string > splitParam(const std::string &name)
const std::string ID_delimiter_assignment
Definition: ParameterStrings.hpp:60
T value(details::expression_node< T > *n)
Definition: exprtk.hpp:12955
static std::string data()
Definition: exprtk.hpp:40022
Definition: ParameterGroup.hpp:83
Definition: ParameterGroup.hpp:88
Definition: ParameterMapItem.hpp:47
void setUsed() const
Definition: ParameterMapItem.hpp:57
static ParameterGroup convert(const ParameterMapItem &item, std::string &conversion_error, bool enable_output)
Definition: ParameterGroup_impl.hpp:54
static std::string type()
Definition: ParameterGroup_impl.hpp:69
Definition: ParameterMapItem.hpp:64
static std::string type()
static T convert(const ParameterMapItem &, std::string &conversion_error)
Definition: ParameterRequirement.hpp:51