My Project
ParseContext.hpp
1/*
2 Copyright 2015 Statoil ASA.
3
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM 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 OPM 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 OPM. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20
21#ifndef OPM_PARSE_CONTEXT_HPP
22#define OPM_PARSE_CONTEXT_HPP
23
24#include <map>
25#include <optional>
26#include <set>
27#include <string>
28#include <vector>
29
30#include <opm/common/OpmLog/OpmLog.hpp>
31
32#include <opm/input/eclipse/Parser/InputErrorAction.hpp>
33
34namespace Opm {
35
36
37class KeywordLocation;
38
39
40 /*
41 The ParseContext class is meant to control the behavior of the
42 parsing and EclipseState construction phase when
43 errors/inconsistencies/... are encountered in the input.
44
45 For each of the possible problems encountered the possible
46 actions are goverened by the InputError::Action enum:
47
48 InputError::THROW_EXCEPTION
49 InputError::EXIT1
50 InputError::WARN
51 InputError::IGNORE
52
53 The internal datastructure is a map between string keys and
54 enum InputError::Action values. The string keys are meant to be
55 descriptive like:
56
57 "PARSE_RANDOMTEXT"
58
59
60 The constructor will consult the env variable
61 OPM_ERRORS_IGNORE, OPM_ERRORS_WARN and OPM_ERRORS_EXCEPTION
62 when initializing. The variables should be set as strings of
63 update syntax.
64
65 update_syntax: The main function for updating the policy of a
66 parseContext instance is the update() method. That takes a string
67 as input, and updates the matching flags. The string can
68 contain wildcards ('* and '?' mathced with fnmatch()) and is
69 split on ':' or '|' to allow multiple settings to be applied in
70 one go:
71
72 Just set one variable:
73 update("PARSE_RANDOM_SLASH" , InputError::IGNORE)
74
75 Ignore all unsupported features:
76 update("UNSUPPORTED_*" , InputError::IGNORE)
77
78 Set two variables:
79 update("UNSUPPORTED_INIITIAL_THPRES:PARSE_RANDOM_SLASH" , InputError::IGNORE)
80
81 The update function itself is quite tolerant, and will silently
82 ignore unknown keys. If you use the updateKey() function only
83 recognizd keys will be allowed.
84 */
85
86 class ErrorGuard;
87
89 public:
91 explicit ParseContext(InputError::Action default_action);
92 explicit ParseContext(const std::vector<std::pair<std::string , InputError::Action>>& initial);
93
94 void handleError( const std::string& errorKey, const std::string& msg, const std::optional<KeywordLocation>& location, ErrorGuard& errors) const;
95 void handleUnknownKeyword(const std::string& keyword, const std::optional<KeywordLocation>& location, ErrorGuard& errors) const;
96 bool hasKey(const std::string& key) const;
97 ParseContext withKey(const std::string& key, InputError::Action action = InputError::WARN) const;
98 ParseContext& withKey(const std::string& key, InputError::Action action = InputError::WARN);
99 void updateKey(const std::string& key , InputError::Action action);
100 void update(InputError::Action action);
101 void update(const std::string& keyString , InputError::Action action);
102 void ignoreKeyword(const std::string& keyword);
103 InputError::Action get(const std::string& key) const;
104 std::map<std::string,InputError::Action>::const_iterator begin() const;
105 std::map<std::string,InputError::Action>::const_iterator end() const;
106 /*
107 When the key is added it is inserted in 'strict mode',
108 i.e. with the value 'InputError::THROW_EXCEPTION. If you
109 want a different value you must subsequently call the update
110 method.
111 */
112 void addKey(const std::string& key, InputError::Action default_action);
113 /*
114 The PARSE_EXTRA_RECORDS field regulates how the parser
115 responds to keywords whose size has been defined in the
116 previous keyword.
117 Example:
118 EQLDIMS
119 2 100 20 1 1 /
120 EQUIL\n
121 2469 382.4 1705.0 0.0 500 0.0 1 1 20 /
122 2469 382.4 1705.0 0.0 500 0.0 1 1 20 /
123 2470 382.4 1705.0 0.0 500 0.0 1 1 20 /
124 EQLDIMS's first entry is 2 and defines the record size of the
125 EQUIL keyword. Since there are 3 records in EQUIL, this results
126 in an error that needs to be handled by the parser. By default,
127 an exception is thrown, or it may be specified in the
128 PARSE_EXTRA_RECORDS field that this error is to be ignored.
129 */
130 const static std::string PARSE_EXTRA_RECORDS;
131 /*
132 The unknownKeyword field regulates how the parser should
133 react when it encounters an unknwon keyword. Observe that
134 'keyword' in this context means:
135
136 o A string of 8 characters or less - starting in column
137 0.
138
139 o A string consisiting of UPPERCASE characters and
140 numerals, staring with an UPPERCASE character [Hmmm -
141 actually lowercase is also accepted?!]
142
143 Observe that unknownKeyword does *not* consult any global
144 collection of keywords to see if a particular string
145 corresponds to a known valid keyword which we just happen
146 to ignore for this particualar parse operation.
147
148 The 'unknownkeyword' and 'randomText' error situations are
149 not fully orthogonal, and in particualar if a unknown
150 keyword has been encountered - without halting the parser, a
151 subsequent piece of 'random text' might not be identified
152 correctly as such.
153 */
154 const static std::string PARSE_UNKNOWN_KEYWORD;
155
156 /*
157 With random text we mean a string in the input deck is not
158 correctly formatted as a keyword heading.
159 */
160 const static std::string PARSE_RANDOM_TEXT;
161
162 /*
163 It turns out that random '/' - i.e. typically an extra slash
164 which is not needed - is quite common. This is therefor a
165 special case treatment of the 'randomText' behaviour.
166 */
167 const static std::string PARSE_RANDOM_SLASH;
168
169
170 /*
171 For some keywords the number of records (i.e. size) is given
172 as an item in another keyword. A typical example is the
173 EQUIL keyword where the number of records is given by the
174 NTEQUL item of the EQLDIMS keyword. If the size defining
175 XXXDIMS keyword is not in the deck, we can use the default
176 values of the XXXDIMS keyword; this is regulated by the
177 'missingDIMskeyword' field.
178
179 Observe that a fully defaulted XXXDIMS keyword does not
180 trigger this behavior.
181 */
182 const static std::string PARSE_MISSING_DIMS_KEYWORD;
183
184 /*
185 If the number of elements in the input record exceeds the
186 number of items in the keyword configuration this error
187 situation will be triggered. Many keywords end with several
188 ECLIPSE300 only items - in some cases we have omitted those
189 items in the Json configuration; that will typically trigger
190 this error situation when encountering an ECLIPSE300 deck.
191 */
192 const static std::string PARSE_EXTRA_DATA;
193
194 /*
195 If an include file is not found we can configure the parser
196 to contine reading; of course the resulting deck can
197 obviously be quite broken.
198 */
199 const static std::string PARSE_MISSING_INCLUDE;
200
201 /*
202 For certain keywords, other, specific keywords are either
203 required or prohibited. When such keywords are found in an
204 invalid combination (missing required or present prohibited
205 keyword), this error situation occurs.
206 */
207 const static std::string PARSE_INVALID_KEYWORD_COMBINATION;
208
211 const static std::string RUNSPEC_NUMWELLS_TOO_LARGE;
212
215 const static std::string RUNSPEC_CONNS_PER_WELL_TOO_LARGE;
216
219 const static std::string RUNSPEC_NUMGROUPS_TOO_LARGE;
220
223 const static std::string RUNSPEC_GROUPSIZE_TOO_LARGE;
224
225 /*
226 Should we allow keywords of length more than eight characters? If the
227 keyword is too long it will be internalized using only the eight first
228 characters.
229 */
230 const static std::string PARSE_LONG_KEYWORD;
231
232 /*
233 The unit system specified via the FILEUNIT keyword is different from the unit
234 system used by the deck.
235 */
236 const static std::string UNIT_SYSTEM_MISMATCH;
237
238
239 /*
240 If the third item in the THPRES keyword is defaulted the
241 threshold pressure is inferred from the initial pressure;
242 this currently not supported.
243 */
244 const static std::string UNSUPPORTED_INITIAL_THPRES;
245
246 /*
247 If the second item in the WHISTCTL keyword is set to YES
248 The simulator is supposed to terminate if the well is
249 changed to BHP control. This feature is not yet supported.
250 */
251 const static std::string UNSUPPORTED_TERMINATE_IF_BHP;
252
253 const static std::string UDQ_PARSE_ERROR;
254 const static std::string UDQ_TYPE_ERROR;
255
256 /*
257 If the third item in the THPRES keyword is defaulted the
258 threshold pressure is inferred from the initial pressure -
259 if you still ask the ThresholdPressure instance for a
260 pressure value this error will be signalled. this currently
261 not supported.
262 */
263 const static std::string INTERNAL_ERROR_UNINITIALIZED_THPRES;
264
265 /*
266 If the deck is partial deck, and thus a full EclipseState is
267 meaningless, we can still construct a slim EclipseGrid.
268 */
269 const static std::string PARSE_MISSING_SECTIONS;
270
271 /*
272 When defining wells and groups with the WELSPECS and GRUPTREE keywords
273 we do not allow leading or trailing spaces. The code in Schedule.cpp
274 will *unconditionally* remove the spaces, but with PARSE_WGNAME_SPACE
275 setting you can additionally configure the normal IGNORE|WARN|ERROR
276 behavior.
277 */
278 const static std::string PARSE_WGNAME_SPACE;
279
280 /*
281 If you have configured a specific well in the summary section,
282 which is not recognized - how to handle.
283 */
284 const static std::string SUMMARY_UNKNOWN_WELL;
285 const static std::string SUMMARY_UNKNOWN_GROUP;
286 const static std::string SUMMARY_UNKNOWN_NODE;
287 const static std::string SUMMARY_UNKNOWN_AQUIFER;
288 const static std::string SUMMARY_UNHANDLED_KEYWORD;
289 const static std::string SUMMARY_UNDEFINED_UDQ;
290 const static std::string SUMMARY_UDQ_MISSING_UNIT;
291 const static std::string SUMMARY_INVALID_FIPNUM;
292 const static std::string SUMMARY_EMPTY_REGION;
293 const static std::string SUMMARY_REGION_TOO_LARGE;
294 /*
295 A well must be specified (e.g. WELSPECS) and have completions
296 (e.g. COMPDAT) to be able to set control mode (e.g. WCONPROD).
297 A well missing specification and/or completion(s) will throw.
298 */
299 const static std::string SCHEDULE_INVALID_NAME;
300
301
302 /*
303 Only keywords explicitly white-listed can be included in the ACTIONX
304 block. This error flag controls what should happen when an illegal
305 keyword is encountered in an ACTIONX block.
306 */
307 const static std::string ACTIONX_ILLEGAL_KEYWORD;
308
309
310 /*
311 The RPTSCH, RPTSOL and RPTSCHED keywords have two alternative forms,
312 in the old style all the items are set as integers, i.e. the RPTRST
313 keyword can be configured as:
314
315 RPTRST
316 0 0 0 1 0 1 0 2 0 0 0 0 0 1 0 0 2/
317
318 The new way is based on string mneomnics which can optionally have an
319 integer value, i.e something like:
320
321 RPTRST
322 BASIC=2 FLOWS ALLPROS /
323
324 It is strictly illegal to mix the two ways to configure keywords. A
325 situation with mixed input style is identified if any of the items are
326 integers. To avoid that the values in the assignments like BASIC=2 are
327 interpreted as integers it is essential that there are no spaces
328 around the '=', and that is also documented in the manual. However -
329 it turns out that Eclipse actually handles e.g.
330
331 RPTRST
332 BASIC = 2 /
333
334 So we have introduced a error mode RPT_MIXED_STYLE which tries to
335 handle this situation. Observe that really mixed input style is
336 impossible to handle, and will lead to a hard exception, but with the
337 RPT_MIXED_STYLE error mode it is possible to configure lenient
338 behavior towards interpreting the input as new style string mneomnics.
339 */
340 const static std::string RPT_MIXED_STYLE;
341
342 const static std::string RPT_UNKNOWN_MNEMONIC;
343
344 const static std::string SCHEDULE_GROUP_ERROR;
345 const static std::string SCHEDULE_IGNORED_GUIDE_RATE;
346
347 const static std::string SCHEDULE_COMPSEGS_INVALID;
348 const static std::string SCHEDULE_COMPSEGS_NOT_SUPPORTED;
349
350 /*
351 The SIMULATOR_KEYWORD_ errormodes are for the situation where the
352 parser recognizes, and correctly parses a keyword, but we know that
353 the simulator does not support the intended use of the keyword. These
354 errormodes are invoked from the simulator.
355 */
356 const static std::string SIMULATOR_KEYWORD_NOT_SUPPORTED;
357 const static std::string SIMULATOR_KEYWORD_NOT_SUPPORTED_CRITICAL;
358 const static std::string SIMULATOR_KEYWORD_ITEM_NOT_SUPPORTED;
359 const static std::string SIMULATOR_KEYWORD_ITEM_NOT_SUPPORTED_CRITICAL;
360
361 private:
362 void initDefault();
363 void initEnv();
364 void envUpdate( const std::string& envVariable , InputError::Action action );
365 void patternUpdate( const std::string& pattern , InputError::Action action);
366
367 std::map<std::string , InputError::Action> m_errorContexts;
368 std::set<std::string> ignore_keywords;
369 };
370}
371
372
373#endif
Definition: ErrorGuard.hpp:29
Definition: ParseContext.hpp:88
static const std::string RUNSPEC_NUMWELLS_TOO_LARGE
Dynamic number of wells exceeds maximum declared in RUNSPEC keyword WELLDIMS (item 1).
Definition: ParseContext.hpp:211
static const std::string RUNSPEC_CONNS_PER_WELL_TOO_LARGE
Dynamic number of connections per well exceeds maximum declared in RUNSPEC keyword WELLDIMS (item 2).
Definition: ParseContext.hpp:215
static const std::string RUNSPEC_GROUPSIZE_TOO_LARGE
Dynamic group size exceeds maximum number declared in RUNSPEC keyword WELLDIMS (item 4).
Definition: ParseContext.hpp:223
static const std::string RUNSPEC_NUMGROUPS_TOO_LARGE
Dynamic number of groups exceeds maximum number declared in RUNSPEC keyword WELLDIMS (item 3).
Definition: ParseContext.hpp:219
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29