https://mooseframework.inl.gov
GeochemicalDatabaseValidator.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
11 
12 #include "Conversion.h"
13 #include "MooseUtils.h"
14 #include "string"
15 
17  const nlohmann::json & db)
18  : _filename(filename), _root(db)
19 {
20 }
21 
22 void
24 {
25  // Check that the database has a Header key (required)
26  if (!_root.contains("Header"))
27  mooseError("The MOOSE database ", _filename, " does not have a required \"Header\" field");
28 
29  // Check that temperatures are present
30  checkHeaderField("temperatures");
31 
32  // The size of the temperature array is used to check all other arrays, which must
33  // have the same number of elements
34  _temperature_size = _root["Header"]["temperatures"].size();
35 
36  // Now check that the values are all Real
37  checkHeaderArray("temperatures");
38 
39  // Check the pressure values are present and are Reals
40  checkHeaderField("pressures");
41  checkHeaderArray("pressures");
42 
43  // Check activity model coefficients
44  checkHeaderField("activity model");
45 
46  // If the activity model is Debye-Huckel, test the coefficients are also present
47  // and are Reals
48  if (_root["Header"]["activity model"] == "debye-huckel")
49  {
50  checkHeaderField("adh");
51  checkHeaderArray("adh");
52 
53  checkHeaderField("bdh");
54  checkHeaderArray("bdh");
55 
56  checkHeaderField("bdot");
57  checkHeaderArray("bdot");
58  }
59 
60  // Check fugacity model is specified
61  checkHeaderField("fugacity model");
62 
63  // If there are neutral species, check their arrays of coefficients
64  if (_root["Header"].contains("neutral species"))
65  for (auto & ns : _root["Header"]["neutral species"].items())
66  for (auto & coeffs : ns.value().items())
67  {
68  if (coeffs.key() == "note")
69  continue;
70 
71  // Check that there are a correct number of values and that they are real numbers
72  auto values = coeffs.value();
73  checkArraySize(values, "Header:neutral species:" + ns.key() + ":" + coeffs.key());
74  checkArrayValues(values, "Header:neutral species:" + ns.key() + ":" + coeffs.key());
75  }
76 
77  // Check the element data
78  for (auto & el : _root["elements"].items())
79  checkElements(el.key());
80 
81  // Check the basis species data
82  for (auto & species : _root["basis species"].items())
83  checkBasisSpecies(species.key());
84 
85  // Check the secondary species data
86  if (_root.contains("secondary species"))
87  for (auto & species : _root["secondary species"].items())
88  checkSecondarySpecies(species.key());
89 
90  // Check the mineral species data
91  if (_root.contains("mineral species"))
92  for (auto & species : _root["mineral species"].items())
93  checkMineralSpecies(species.key());
94 
95  // Check the sorbing mineral species data
96  if (_root.contains("sorbing minerals"))
97  for (auto & species : _root["sorbing minerals"].items())
98  checkSorbingMineralSpecies(species.key());
99 
100  // Check the gas species data
101  if (_root.contains("gas species"))
102  for (auto & species : _root["gas species"].items())
103  checkGasSpecies(species.key());
104 
105  // Check the redox couple data
106  if (_root.contains("redox couples"))
107  for (auto & species : _root["redox couples"].items())
108  checkRedoxSpecies(species.key());
109 
110  // Check the oxide species data
111  if (_root.contains("oxides"))
112  for (auto & species : _root["oxides"].items())
113  checkOxideSpecies(species.key());
114 
115  // Check the surface species data
116  if (_root.contains("surface species"))
117  for (auto & species : _root["surface species"].items())
118  checkSurfaceSpecies(species.key());
119 }
120 
121 bool
122 GeochemicalDatabaseValidator::isValueReal(const nlohmann::json & value) const
123 {
124  if (value.is_number())
125  return true;
126  try
127  {
128  MooseUtils::convert<Real>(value, true);
129  }
130  catch (const std::invalid_argument & err)
131  {
132  return false;
133  }
134 
135  return true;
136 }
137 
138 void
140  const std::string field) const
141 {
142  // Check each value in the array can be successfully converted to a Real
143  for (auto & item : array.items())
144  if (!isValueReal(item.value()))
145  mooseError("Array value ",
146  nlohmann::to_string(item.value()),
147  " in the ",
148  field,
149  " field of ",
150  _filename,
151  " cannot be converted to Real");
152 }
153 
154 void
156  const std::string species,
157  const std::string field) const
158 {
159  // Check each value in the array can be successfully converted to a Real
160  for (auto & item : _root[type][species][field].items())
161  if (!isValueReal(item.value()))
162  mooseError("Array value ",
163  nlohmann::to_string(item.value()),
164  " in the ",
165  field,
166  " field of ",
167  type,
168  " ",
169  species,
170  " in ",
171  _filename,
172  " cannot be converted to Real");
173 }
174 
175 void
176 GeochemicalDatabaseValidator::checkArraySize(const nlohmann::json & array,
177  const std::string field) const
178 {
179  if (array.size() != _temperature_size)
180  mooseError("The number of values in the ",
181  field,
182  " field of ",
183  _filename,
184  " is not equal to the number of temperature values");
185 }
186 
187 void
189  const std::string species,
190  const std::string field) const
191 {
192  if (_root[type][species][field].size() != _temperature_size)
193  mooseError("The number of values in the ",
194  field,
195  " field of ",
196  type,
197  " ",
198  species,
199  " in ",
200  _filename,
201  " is not equal to the number of temperature values");
202 }
203 
204 void
206 {
207  if (!_root["Header"].contains(field))
208  mooseError(
209  "The MOOSE database ", _filename, " does not have a required \"Header:", field, "\" field");
210 }
211 
212 void
214 {
215  // Check that all values are real numbers and of size equal to the temperature
216  checkArraySize(_root["Header"][field], "Header:" + field);
217  checkArrayValues(_root["Header"][field], "Header:" + field);
218 }
219 
220 void
222  const std::string species,
223  const std::string field) const
224 {
225  if (!_root[type].contains(species) || !_root[type][species].contains(field))
226  mooseError("The ", type, " ", species, " in ", _filename, " does not have a ", field);
227 
228  // The field value should be a real number
229  if (!isValueReal(_root[type][species][field]))
230  mooseError(field,
231  " value ",
232  nlohmann::to_string(_root[type][species][field]),
233  " of the ",
234  type,
235  " ",
236  species,
237  " in ",
238  _filename,
239  " cannot be converted to Real");
240 }
241 
242 void
244  const std::string species,
245  const std::string field) const
246 {
247  if (!_root[type].contains(species) || !_root[type][species].contains(field))
248  mooseError("The ", type, " ", species, " in ", _filename, " does not have a ", field);
249 
250  // Each weight value for each constituent should be a real number
251  for (auto & item : _root[type][species][field].items())
252  if (!isValueReal(item.value()))
253  mooseError("Weight value ",
254  nlohmann::to_string(item.value()),
255  " of constituent ",
256  item.key(),
257  " of the ",
258  type,
259  " ",
260  species,
261  " in ",
262  _filename,
263  " cannot be converted to Real");
264 }
265 
266 void
267 GeochemicalDatabaseValidator::checkElements(const std::string element) const
268 {
269  // Check molecular weight can be converted to a Real
270  checkSpeciesValue("elements", element, "molecular weight");
271 }
272 
273 void
274 GeochemicalDatabaseValidator::checkBasisSpecies(const std::string species) const
275 {
276  // Check molecular weight can be converted to a Real
277  checkSpeciesValue("basis species", species, "molecular weight");
278 
279  // Check charge can be converted to a Real
280  checkSpeciesValue("basis species", species, "charge");
281 
282  // Check ionic radius can be converted to a Real
283  checkSpeciesValue("basis species", species, "radius");
284 
285  // Check element weights can be converted to a Real
286  checkSpeciesWeightValue("basis species", species, "elements");
287 }
288 
289 void
291 {
292  // Check molecular weight can be converted to a Real
293  checkSpeciesValue("secondary species", species, "molecular weight");
294 
295  // Check charge can be converted to a Real
296  checkSpeciesValue("secondary species", species, "charge");
297 
298  // Check ionic radius can be converted to a Real
299  checkSpeciesValue("secondary species", species, "radius");
300 
301  // Check basis species weights can be converted to a Real
302  checkSpeciesWeightValue("secondary species", species, "species");
303 
304  // Check the number of logk values and whether they can be converted to a Real
305  checkArraySize("secondary species", species, "logk");
306  checkArrayValues("secondary species", species, "logk");
307 }
308 
309 void
311 {
312  // Check molecular weight can be converted to a Real
313  checkSpeciesValue("mineral species", species, "molecular weight");
314 
315  // Check molar volume can be converted to a Real
316  checkSpeciesValue("mineral species", species, "molar volume");
317 
318  // Check basis species weights can be converted to a Real
319  checkSpeciesWeightValue("mineral species", species, "species");
320 
321  // Check the number of logk values and whether they can be converted to a Real
322  checkArraySize("mineral species", species, "logk");
323  checkArrayValues("mineral species", species, "logk");
324 }
325 
326 void
328 {
329  // Check surface area can be converted to a Real
330  checkSpeciesValue("sorbing minerals", species, "surface area");
331 
332  // Check sorbing site weights can be converted to a Real
333  checkSpeciesWeightValue("sorbing minerals", species, "sorbing sites");
334 }
335 
336 void
337 GeochemicalDatabaseValidator::checkGasSpecies(const std::string species) const
338 {
339  // Check molecular weight can be converted to a Real
340  checkSpeciesValue("gas species", species, "molecular weight");
341 
342  // Check basis species weights can be converted to a Real
343  checkSpeciesWeightValue("gas species", species, "species");
344 
345  // Check the number of logk values and whether they can be converted to a Real
346  checkArraySize("gas species", species, "logk");
347  checkArrayValues("gas species", species, "logk");
348 
349  // Check optional fugacity coefficients
350  if (_root["gas species"][species].contains("chi"))
351  checkArrayValues("gas species", species, "chi");
352 
353  if (_root["gas species"][species].contains("Pcrit"))
354  checkSpeciesValue("gas species", species, "Pcrit");
355 
356  if (_root["gas species"][species].contains("Tcrit"))
357  checkSpeciesValue("gas species", species, "Tcrit");
358 
359  if (_root["gas species"][species].contains("omega"))
360  checkSpeciesValue("gas species", species, "omega");
361 }
362 
363 void
364 GeochemicalDatabaseValidator::checkRedoxSpecies(const std::string species) const
365 {
366  // Check molecular weight can be converted to a Real
367  checkSpeciesValue("redox couples", species, "molecular weight");
368 
369  // Check charge can be converted to a Real
370  checkSpeciesValue("redox couples", species, "charge");
371 
372  // Check ionic radius can be converted to a Real
373  checkSpeciesValue("redox couples", species, "radius");
374 
375  // Check basis species weights can be converted to a Real
376  checkSpeciesWeightValue("redox couples", species, "species");
377 
378  // Check the number of logk values and whether they can be converted to a Real
379  checkArraySize("redox couples", species, "logk");
380  checkArrayValues("redox couples", species, "logk");
381 }
382 
383 void
384 GeochemicalDatabaseValidator::checkOxideSpecies(const std::string species) const
385 {
386  // Check molecular weight can be converted to a Real
387  checkSpeciesValue("oxides", species, "molecular weight");
388 
389  // Check basis species weights can be converted to a Real
390  checkSpeciesWeightValue("oxides", species, "species");
391 }
392 
393 void
395 {
396  // Check molecular weight can be converted to a Real
397  checkSpeciesValue("surface species", species, "molecular weight");
398 
399  // Check charge can be converted to a Real
400  checkSpeciesValue("surface species", species, "charge");
401 
402  // Check basis species weights can be converted to a Real
403  checkSpeciesWeightValue("surface species", species, "species");
404 
405  // Check equilibrium constants can be converted to a Real
406  checkSpeciesValue("surface species", species, "log K");
407  checkSpeciesValue("surface species", species, "dlogK/dT");
408 }
OStreamProxy err
void checkHeaderArray(const std::string field) const
Check arrays in field can be converted to Reals.
void validate()
Validate the thermodynamic database.
void mooseError(Args &&... args)
GeochemicalDatabaseValidator(const FileName filename, const nlohmann::json &db)
void checkMineralSpecies(const std::string species) const
Check mineral species in the database Each mineral species should have a real number as their molecul...
void checkOxideSpecies(const std::string species) const
Check oxide species in the database Each oxide species should have a real number as their molecular w...
void checkElements(const std::string element) const
Check elements in the database Each elemenent should have a real number as their molecular weights...
const GeochemicalDatabaseReader db("database/moose_testdb.json", true, true, false)
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void checkSecondarySpecies(const std::string species) const
Check secondary species in the database Each secondary species should have a real number as their mol...
unsigned int _temperature_size
Number of temperature points.
void checkSpeciesWeightValue(const std::string type, const std::string species, const std::string field) const
Check given species stoichiometric weigth values can be converted to a Real.
const FileName _filename
Database filename.
void checkSorbingMineralSpecies(const std::string species) const
Check sorbing mineral species in the database Each sorbing mineral species should have a real number ...
void checkSpeciesValue(const std::string type, const std::string species, const std::string field) const
Check given species field value can be converted to a Real.
bool isValueReal(const nlohmann::json &value) const
Check Json::Value can be converted to a Real.
const nlohmann::json & _root
JSON database.
void checkArrayValues(const nlohmann::json &array, const std::string field) const
Check Json::Value array is comprised of Reals.
void checkSurfaceSpecies(const std::string species) const
Check surface species in the database Each surface species should have a real number as their molecul...
void checkGasSpecies(const std::string species) const
Check gas species in the database Each gas species should have a real number as their molecular weigh...
void checkBasisSpecies(const std::string species) const
Check basis species in the database Each basis species should have a real number as their molecular w...
void checkArraySize(const nlohmann::json &array, const std::string field) const
Check Json::Value array is the correct size.
void checkHeaderField(const std::string field) const
Check fields are present in the Header section.
void checkRedoxSpecies(const std::string species) const
Check redox couple species in the database Each redox couple species should have a real number as the...