https://mooseframework.inl.gov
GeochemicalDatabaseReaderTest.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 
10 #include "gtest/gtest.h"
11 #include <algorithm>
12 
14 
15 TEST(GeochemicalDatabaseReaderTest, filename)
16 {
17  GeochemicalDatabaseReader database("database/moose_testdb.json");
18 
19  EXPECT_EQ(database.filename(), "database/moose_testdb.json");
20 }
21 
22 TEST(GeochemicalDatabaseReaderTest, faultyDB)
23 {
24  // Test that the database validator throws an error when a faulty
25  // database is read (the full range of validation errors are tested
26  // in GeochemicalDatabaseValidatorTest.C)
27  try
28  {
29  GeochemicalDatabaseReader database("database/faultydbs/missing_header.json");
30  }
31  catch (const std::exception & err)
32  {
33  const std::string msg = "The MOOSE database database/faultydbs/missing_header.json does not "
34  "have a required \"Header\" field";
35 
36  std::size_t pos = std::string(err.what()).find(msg);
37  ASSERT_TRUE(pos != std::string::npos);
38  }
39 }
40 
41 TEST(GeochemicalDatabaseReaderTest, getActivityModel)
42 {
43  GeochemicalDatabaseReader database("database/moose_testdb.json");
44 
45  EXPECT_EQ(database.getActivityModel(), "debye-huckel");
46 }
47 
48 TEST(GeochemicalDatabaseReaderTest, getFugacityModel)
49 {
50  GeochemicalDatabaseReader database("database/moose_testdb.json");
51 
52  EXPECT_EQ(database.getFugacityModel(), "tsonopoulos");
53 }
54 
55 TEST(GeochemicalDatabaseReaderTest, getLogKModel)
56 {
57  GeochemicalDatabaseReader database("database/moose_testdb.json");
58 
59  EXPECT_EQ(database.getLogKModel(), "fourth-order");
60 
61  GeochemicalDatabaseReader database2("database/moose_testdb.json", true);
62 
63  EXPECT_EQ(database2.getLogKModel(), "fourth-order");
64 
65  GeochemicalDatabaseReader database3("database/moose_testdb.json", false, true);
66 
67  EXPECT_EQ(database3.getLogKModel(), "piecewise-linear");
68 }
69 
70 TEST(GeochemicalDatabaseReaderTest, getTemperatures)
71 {
72  GeochemicalDatabaseReader database("database/moose_testdb.json");
73 
74  // Get the temperature points from the database and compare with the expected
75  // valules
76  auto temperature_points = database.getTemperatures();
77 
78  std::vector<Real> temperature_points_gold{0.0, 25.0, 60.0, 100.0, 150.0, 200.0, 250.0, 300.0};
79  EXPECT_EQ(temperature_points, temperature_points_gold);
80 }
81 
82 TEST(GeochemicalDatabaseReaderTest, getPressures)
83 {
84  GeochemicalDatabaseReader database("database/moose_testdb.json");
85 
86  // Get the pressure points from the database and compare with the expected
87  // valules
88  auto pressure_points = database.getPressures();
89 
90  std::vector<Real> pressure_points_gold{
91  1.0134, 1.0134, 1.0134, 1.0134, 4.7600, 15.5490, 39.7760, 85.9270};
92  EXPECT_EQ(pressure_points, pressure_points_gold);
93 }
94 
95 TEST(GeochemicalDatabaseReaderTest, getDebyeHuckel)
96 {
97  GeochemicalDatabaseReader database("database/moose_testdb.json");
98 
99  // Get the Debye-Huckel from the database and compare with the expected
100  // valules
101  auto dh = database.getDebyeHuckel();
102 
103  std::vector<Real> adh_gold{.4913, .5092, .5450, .5998, .6898, .8099, .9785, 1.2555};
104  std::vector<Real> bdh_gold{.3247, .3283, .3343, .3422, .3533, .3655, .3792, .3965};
105  std::vector<Real> bdot_gold{.0174, .0410, .0440, .0460, .0470, .0470, .0340, 0.0000};
106 
107  EXPECT_EQ(dh.adh, adh_gold);
108  EXPECT_EQ(dh.bdh, bdh_gold);
109  EXPECT_EQ(dh.bdot, bdot_gold);
110 }
111 
112 TEST(GeochemicalDatabaseReaderTest, getNeutralSpeciesActivity)
113 {
114  GeochemicalDatabaseReader database("database/moose_testdb.json");
115 
116  // Get the neutral species activity coefficients from the database
117  // and compare with the expected values
118  auto nsa = database.getNeutralSpeciesActivity();
119 
120  auto ns = nsa["co2"];
121  std::vector<Real> a_gold{.1224, .1127, .09341, .08018, .08427, .09892, .1371, .1967};
122  std::vector<Real> b_gold{-.004679, -.01049, -.0036, -.001503, -.01184, -.0104, -.007086, -.01809};
123  std::vector<Real> c_gold{
124  -0.0004114, 0.001545, 9.609e-05, 0.0005009, 0.003118, 0.001386, -0.002887, -0.002497};
125  std::vector<Real> d_gold(8);
126 
127  EXPECT_EQ(ns.a, a_gold);
128  EXPECT_EQ(ns.b, b_gold);
129  EXPECT_EQ(ns.c, c_gold);
130  EXPECT_TRUE(ns.d.empty());
131 
132  ns = nsa["h2o"];
133  a_gold = {1.4203, 1.45397, 1.5012, 1.5551, 1.6225, 1.6899, 1.7573, 1.8247};
134  b_gold = {0.0177, 0.022357, 0.0289, 0.036478, 0.045891, 0.0553, 0.0647, 0.0741};
135  c_gold = {0.0103, 0.0093804, 0.008, 0.0064366, 0.0045221, 0.0026, 0.0006, -0.0013};
136  d_gold = {-0.0005, -0.0005362, -0.0006, -0.0007132, -0.0008312, -0.0009, -0.0011, -0.0012};
137 
138  EXPECT_EQ(ns.a, a_gold);
139  EXPECT_EQ(ns.b, b_gold);
140  EXPECT_EQ(ns.c, c_gold);
141  EXPECT_EQ(ns.d, d_gold);
142 
143  // check error is thrown if database has no neutral species
144  GeochemicalDatabaseReader database_non("database/faultydbs/no_neutral_species.json");
145  try
146  {
147  auto nsa = database_non.getNeutralSpeciesActivity();
148  FAIL() << "Missing expected exception.";
149  }
150  catch (const std::exception & e)
151  {
152  std::string msg(e.what());
153  ASSERT_TRUE(msg.find("No neutral species activity coefficients in database") !=
154  std::string::npos)
155  << "Failed with unexpected error message: " << msg;
156  }
157 }
158 
159 TEST(GeochemicalDatabaseReaderTest, getElements)
160 {
161  GeochemicalDatabaseReader database("database/moose_testdb.json");
162 
163  // Get the elements from the database and compare with the expected
164  // valules
165  auto els = database.getElements();
166  auto el = els["Ag"];
167 
168  EXPECT_EQ(el.name, "Silver");
169  EXPECT_EQ(el.molecular_weight, 107.8680);
170 
171  el = els["Al"];
172 
173  EXPECT_EQ(el.name, "Aluminum");
174  EXPECT_EQ(el.molecular_weight, 26.9815);
175 }
176 
177 TEST(GeochemicalDatabaseReaderTest, getBasisSpecies)
178 {
179  GeochemicalDatabaseReader database("database/moose_testdb.json");
180 
181  // Vector of primary species
182  std::vector<std::string> bs_names{"Ca++", "HCO3-", "H+"};
183 
184  // Check the basis species
185  auto bs = database.getBasisSpecies(bs_names);
186 
187  // Check that only the species in bs_names are returned
188  std::vector<std::string> bs_names_returned;
189  for (auto b : bs)
190  bs_names_returned.push_back(b.first);
191 
192  std::sort(bs_names_returned.begin(), bs_names_returned.end());
193  std::sort(bs_names.begin(), bs_names.end());
194  EXPECT_EQ(bs_names_returned, bs_names);
195 
196  // Check each species
197  auto species = bs["Ca++"];
198 
199  std::map<std::string, Real> els_gold = {{"Ca", 1}};
200  EXPECT_EQ(species.radius, 6);
201  EXPECT_EQ(species.charge, 2);
202  EXPECT_EQ(species.molecular_weight, 40.08);
203  EXPECT_EQ(species.elements, els_gold);
204 
205  species = bs["HCO3-"];
206 
207  els_gold = {{"C", 1}, {"H", 1}, {"O", 3}};
208  EXPECT_EQ(species.radius, 4.5);
209  EXPECT_EQ(species.charge, -1);
210  EXPECT_EQ(species.molecular_weight, 61.0171);
211  EXPECT_EQ(species.elements, els_gold);
212 
213  species = bs["H+"];
214 
215  els_gold = {{"H", 1}};
216  EXPECT_EQ(species.radius, 9);
217  EXPECT_EQ(species.charge, 1);
218  EXPECT_EQ(species.molecular_weight, 1.0079);
219  EXPECT_EQ(species.elements, els_gold);
220 
221  // check that an error is thrown if the species does not exist
222  try
223  {
224  auto bs_not = database.getBasisSpecies({"does_not_exist"});
225  FAIL() << "Missing expected exception.";
226  }
227  catch (const std::exception & e)
228  {
229  std::string msg(e.what());
230  ASSERT_TRUE(msg.find("does_not_exist does not exist in database database/moose_testdb.json") !=
231  std::string::npos)
232  << "Failed with unexpected error message: " << msg;
233  }
234 }
235 
236 TEST(GeochemicalDatabaseReaderTest, getEquilibriumSpecies)
237 {
238  GeochemicalDatabaseReader database("database/moose_testdb.json");
239 
240  // Vector of secondary species
241  std::vector<std::string> ss_names{"CO2(aq)", "CO3--", "CaCO3", "CaOH+", "OH-"};
242 
243  // Check the secondary species
244  auto ss = database.getEquilibriumSpecies(ss_names);
245 
246  // Check that only the species in ss_names are returned
247  std::vector<std::string> ss_names_returned;
248  for (auto s : ss)
249  ss_names_returned.push_back(s.first);
250 
251  std::sort(ss_names_returned.begin(), ss_names_returned.end());
252  std::sort(ss_names.begin(), ss_names.end());
253  EXPECT_EQ(ss_names_returned, ss_names);
254 
255  // Check each species
256  auto sspecies = ss["CO2(aq)"];
257  std::vector<Real> logk_gold{
258  -6.5570, -6.3660, -6.3325, -6.4330, -6.7420, -7.1880, -7.7630, -8.4650};
259  std::map<std::string, Real> bs_gold = {{"H2O", -1}, {"H+", 1}, {"HCO3-", 1}};
260 
261  EXPECT_EQ(sspecies.radius, 4);
262  EXPECT_EQ(sspecies.charge, 0);
263  EXPECT_EQ(sspecies.molecular_weight, 44.0098);
264  EXPECT_EQ(sspecies.basis_species, bs_gold);
265  EXPECT_EQ(sspecies.equilibrium_const, logk_gold);
266 
267  sspecies = ss["CO3--"];
268  logk_gold = {10.6169, 10.3439, 10.2092, 10.2793, 10.5131, 10.8637, 11.2860, 11.6319};
269  bs_gold = {{"H+", -1}, {"HCO3-", 1}};
270 
271  EXPECT_EQ(sspecies.radius, 4.5);
272  EXPECT_EQ(sspecies.charge, -2);
273  EXPECT_EQ(sspecies.molecular_weight, 60.0092);
274  EXPECT_EQ(sspecies.basis_species, bs_gold);
275  EXPECT_EQ(sspecies.equilibrium_const, logk_gold);
276 
277  sspecies = ss["CaCO3"];
278  logk_gold = {7.5520, 7.1280, 6.7340, 6.4350, 6.1810, 5.9320, 5.5640, 4.7890};
279  bs_gold = {{"Ca++", 1}, {"HCO3-", 1}, {"H+", -1}};
280 
281  EXPECT_EQ(sspecies.radius, 4);
282  EXPECT_EQ(sspecies.charge, 0);
283  EXPECT_EQ(sspecies.molecular_weight, 100.0892);
284  EXPECT_EQ(sspecies.basis_species, bs_gold);
285  EXPECT_EQ(sspecies.equilibrium_const, logk_gold);
286 
287  sspecies = ss["CaOH+"];
288  logk_gold = {13.7095, 12.6887, 11.5069, 10.4366, 9.3958, 8.5583, 7.8155, 7.0306};
289  bs_gold = {{"Ca++", 1}, {"H2O", 1}, {"H+", -1}};
290 
291  EXPECT_EQ(sspecies.radius, 4);
292  EXPECT_EQ(sspecies.charge, 1);
293  EXPECT_EQ(sspecies.molecular_weight, 57.0873);
294  EXPECT_EQ(sspecies.basis_species, bs_gold);
295  EXPECT_EQ(sspecies.equilibrium_const, logk_gold);
296 
297  sspecies = ss["OH-"];
298  logk_gold = {14.9325, 13.9868, 13.0199, 12.2403, 11.5940, 11.2191, 11.0880, 1001.2844};
299  bs_gold = {{"H2O", 1}, {"H+", -1}};
300 
301  EXPECT_EQ(sspecies.radius, 3.5);
302  EXPECT_EQ(sspecies.charge, -1);
303  EXPECT_EQ(sspecies.molecular_weight, 17.0073);
304  EXPECT_EQ(sspecies.basis_species, bs_gold);
305  EXPECT_EQ(sspecies.equilibrium_const, logk_gold);
306 
307  // check that an error is thrown if the species does not exist
308  try
309  {
310  auto bs_not = database.getEquilibriumSpecies({"does_not_exist"});
311  FAIL() << "Missing expected exception.";
312  }
313  catch (const std::exception & e)
314  {
315  std::string msg(e.what());
316  ASSERT_TRUE(msg.find("does_not_exist does not exist in database database/moose_testdb.json") !=
317  std::string::npos)
318  << "Failed with unexpected error message: " << msg;
319  }
320 }
321 
322 TEST(GeochemicalDatabaseReaderTest, getMineralSpecies)
323 {
324  GeochemicalDatabaseReader database("database/moose_testdb.json");
325 
326  // Vector of mineral species to be read
327  std::vector<std::string> ms_names{"Calcite", "Fe(OH)3(ppd)"};
328 
329  // Check the mineral species
330  auto ms = database.getMineralSpecies(ms_names);
331 
332  // Check that only the species in ms_names are returned
333  std::vector<std::string> ms_names_returned;
334  for (auto s : ms)
335  ms_names_returned.push_back(s.first);
336 
337  std::sort(ms_names_returned.begin(), ms_names_returned.end());
338  std::sort(ms_names.begin(), ms_names.end());
339  EXPECT_EQ(ms_names_returned, ms_names);
340 
341  auto mspecies = ms["Calcite"];
342  std::vector<Real> logk_gold = {2.0683, 1.7130, 1.2133, .6871, .0762, -.5349, -1.2301, -2.2107};
343  std::map<std::string, Real> bs_gold = {{"Ca++", 1}, {"H+", -1}, {"HCO3-", 1}};
344 
345  EXPECT_EQ(mspecies.molecular_volume, 36.934);
346  EXPECT_EQ(mspecies.molecular_weight, 100.0892);
347  EXPECT_EQ(mspecies.basis_species, bs_gold);
348  EXPECT_EQ(mspecies.equilibrium_const, logk_gold);
349  EXPECT_EQ(mspecies.surface_area, 0.0);
350 
351  mspecies = ms["Fe(OH)3(ppd)"];
352  logk_gold = {6.1946, 4.8890, 3.4608, 2.2392, 1.1150, .2446, -.5504, -1.5398};
353  bs_gold = {{"H+", -3}, {"Fe+++", 1}, {"H2O", 3}};
354 
355  EXPECT_EQ(mspecies.molecular_volume, 34.32);
356  EXPECT_EQ(mspecies.molecular_weight, 106.8689);
357  EXPECT_EQ(mspecies.basis_species, bs_gold);
358  EXPECT_EQ(mspecies.equilibrium_const, logk_gold);
359  EXPECT_EQ(mspecies.surface_area, 600.0);
360  bs_gold = {{">(s)FeOH", 0.005}, {">(w)FeOH", 0.2}};
361  EXPECT_EQ(mspecies.sorption_sites, bs_gold);
362 
363  // check that an error is thrown if the species does not exist
364  try
365  {
366  auto bs_not = database.getMineralSpecies({"does_not_exist"});
367  FAIL() << "Missing expected exception.";
368  }
369  catch (const std::exception & e)
370  {
371  std::string msg(e.what());
372  ASSERT_TRUE(msg.find("does_not_exist does not exist in database database/moose_testdb.json") !=
373  std::string::npos)
374  << "Failed with unexpected error message: " << msg;
375  }
376 }
377 
378 TEST(GeochemicalDatabaseReaderTest, getGasSpecies)
379 {
380  GeochemicalDatabaseReader database("database/moose_testdb.json");
381 
382  // Vector of gas species to be read
383  std::vector<std::string> gs_names{"N2(g)", "CH4(g)"};
384 
385  // Check the gas species
386  auto gs = database.getGasSpecies(gs_names);
387 
388  // Check that only the species in gs_names are returned
389  std::vector<std::string> gs_names_returned;
390  for (auto s : gs)
391  gs_names_returned.push_back(s.first);
392 
393  std::sort(gs_names_returned.begin(), gs_names_returned.end());
394  std::sort(gs_names.begin(), gs_names.end());
395  EXPECT_EQ(gs_names_returned, gs_names);
396 
397  auto gspecies = gs["N2(g)"];
398  std::vector<Real> logk_gold = {
399  -2.9620, -3.1848, -3.3320, -3.2902, -3.1631, -2.9499, -2.7827, -2.3699};
400  std::map<std::string, Real> bs_gold = {{"N2(aq)", 1}};
401 
402  EXPECT_EQ(gspecies.molecular_weight, 28.0134);
403  EXPECT_EQ(gspecies.basis_species, bs_gold);
404  EXPECT_EQ(gspecies.equilibrium_const, logk_gold);
405  EXPECT_TRUE(gspecies.chi.empty());
406  EXPECT_EQ(gspecies.Pcrit, 33.9);
407  EXPECT_EQ(gspecies.Tcrit, 126.2);
408  EXPECT_EQ(gspecies.omega, .039);
409 
410  gspecies = gs["CH4(g)"];
411  logk_gold = {-2.6487, -2.8202, -2.9329, -2.9446, -2.9163, -2.7253, -2.4643, -2.1569};
412  bs_gold = {{"CH4(aq)", 1}};
413  std::vector<Real> chi_gold = {-537.779, 1.54946, -.000927827, 1.20861, -.00370814, 3.33804e-6};
414 
415  EXPECT_EQ(gspecies.molecular_weight, 16.0426);
416  EXPECT_EQ(gspecies.basis_species, bs_gold);
417  EXPECT_EQ(gspecies.equilibrium_const, logk_gold);
418  EXPECT_EQ(gspecies.chi, chi_gold);
419  EXPECT_EQ(gspecies.Pcrit, 46.0);
420  EXPECT_EQ(gspecies.Tcrit, 190.4);
421  EXPECT_EQ(gspecies.omega, .011);
422 
423  // check that an error is thrown if the species does not exist
424  try
425  {
426  auto bs_not = database.getGasSpecies({"does_not_exist"});
427  FAIL() << "Missing expected exception.";
428  }
429  catch (const std::exception & e)
430  {
431  std::string msg(e.what());
432  ASSERT_TRUE(msg.find("does_not_exist does not exist in database database/moose_testdb.json") !=
433  std::string::npos)
434  << "Failed with unexpected error message: " << msg;
435  }
436 }
437 
438 TEST(GeochemicalDatabaseReaderTest, getRedoxSpecies)
439 {
440  GeochemicalDatabaseReader database("database/moose_testdb.json");
441 
442  // Vector of redox species
443  std::vector<std::string> rs_names{"Am++++"};
444 
445  // Check the secondary species
446  auto rs = database.getRedoxSpecies(rs_names);
447 
448  // Check that only the species in ss_names are returned
449  std::vector<std::string> rs_names_returned;
450  for (auto s : rs)
451  rs_names_returned.push_back(s.first);
452 
453  std::sort(rs_names_returned.begin(), rs_names_returned.end());
454  std::sort(rs_names.begin(), rs_names.end());
455  EXPECT_EQ(rs_names_returned, rs_names);
456 
457  auto rspecies = rs["Am++++"];
458  std::vector<Real> logk_gold = {
459  18.7967, 18.0815, 17.2698, 16.5278, 15.8024, 15.2312, 14.7898, 14.4250};
460  std::map<std::string, Real> bs_gold = {{"H2O", -0.5}, {"H+", 1}, {"Am+++", 1}, {"O2(aq)", 0.250}};
461 
462  EXPECT_EQ(rspecies.radius, 11);
463  EXPECT_EQ(rspecies.charge, 4);
464  EXPECT_EQ(rspecies.molecular_weight, 241.0600);
465  EXPECT_EQ(rspecies.basis_species, bs_gold);
466  EXPECT_EQ(rspecies.equilibrium_const, logk_gold);
467 
468  // check that an error is thrown if the species does not exist
469  try
470  {
471  auto bs_not = database.getRedoxSpecies({"does_not_exist"});
472  FAIL() << "Missing expected exception.";
473  }
474  catch (const std::exception & e)
475  {
476  std::string msg(e.what());
477  ASSERT_TRUE(msg.find("does_not_exist does not exist in database database/moose_testdb.json") !=
478  std::string::npos)
479  << "Failed with unexpected error message: " << msg;
480  }
481 }
482 
483 TEST(GeochemicalDatabaseReaderTest, getOxideSpecies)
484 {
485  GeochemicalDatabaseReader database("database/moose_testdb.json");
486 
487  // Vector of gas species to be read
488  std::vector<std::string> os_names{"Cu2O"};
489 
490  // Check the oxide species
491  auto os = database.getOxideSpecies(os_names);
492 
493  // Check that only the species in gs_names are returned
494  std::vector<std::string> os_names_returned;
495  for (auto s : os)
496  os_names_returned.push_back(s.first);
497 
498  EXPECT_EQ(os_names_returned, os_names);
499 
500  auto ospecies = os["Cu2O"];
501  std::map<std::string, Real> bs_gold = {{"H+", -2}, {"Cu+", 2}, {"H2O", 1}};
502 
503  EXPECT_EQ(ospecies.molecular_weight, 143.0929);
504  EXPECT_EQ(ospecies.basis_species, bs_gold);
505 
506  // check that an error is thrown if the species does not exist
507  try
508  {
509  auto bs_not = database.getOxideSpecies({"does_not_exist"});
510  FAIL() << "Missing expected exception.";
511  }
512  catch (const std::exception & e)
513  {
514  std::string msg(e.what());
515  ASSERT_TRUE(msg.find("does_not_exist does not exist in database database/moose_testdb.json") !=
516  std::string::npos)
517  << "Failed with unexpected error message: " << msg;
518  }
519 }
520 
521 TEST(GeochemicalDatabaseReaderTest, getSurfaceSpecies)
522 {
523  GeochemicalDatabaseReader database("database/moose_testdb.json");
524 
525  std::vector<std::string> ss_names{">(s)FeO-"};
526 
527  auto ss = database.getSurfaceSpecies(ss_names);
528 
529  // Check that only the species in ss_names are returned
530  std::vector<std::string> ss_names_returned;
531  for (auto s : ss)
532  ss_names_returned.push_back(s.first);
533 
534  EXPECT_EQ(ss_names_returned, ss_names);
535 
536  auto sspecies = ss[">(s)FeO-"];
537  std::map<std::string, Real> ss_gold = {{">(s)FeOH", 1}, {"H+", -1}};
538 
539  EXPECT_EQ(sspecies.basis_species, ss_gold);
540 
541  // check that an error is thrown if the species does not exist
542  try
543  {
544  auto bs_not = database.getSurfaceSpecies({"does_not_exist"});
545  FAIL() << "Missing expected exception.";
546  }
547  catch (const std::exception & e)
548  {
549  std::string msg(e.what());
550  ASSERT_TRUE(msg.find("does_not_exist does not exist in database database/moose_testdb.json") !=
551  std::string::npos)
552  << "Failed with unexpected error message: " << msg;
553  }
554 }
555 
556 TEST(GeochemicalDatabaseReaderTest, equilibriumReactions)
557 {
558  GeochemicalDatabaseReader database("database/moose_testdb.json");
559 
560  // Secondary equilibrium species
561  std::vector<std::string> names{"CO2(aq)", "CO3--", "CaCO3", "CaOH+", "OH-"};
562 
563  auto reactions = database.equilibriumReactions(names);
564 
565  EXPECT_EQ(reactions[0], "CO2(aq) = H+ - H2O + HCO3-");
566  EXPECT_EQ(reactions[1], "CO3-- = - H+ + HCO3-");
567  EXPECT_EQ(reactions[2], "CaCO3 = Ca++ - H+ + HCO3-");
568  EXPECT_EQ(reactions[3], "CaOH+ = Ca++ - H+ + H2O");
569  EXPECT_EQ(reactions[4], "OH- = - H+ + H2O");
570 
571  // check that an error is thrown if the species does not exist
572  try
573  {
574  auto reactions_not = database.equilibriumReactions({"does_not_exist"});
575  FAIL() << "Missing expected exception.";
576  }
577  catch (const std::exception & e)
578  {
579  std::string msg(e.what());
580  ASSERT_TRUE(msg.find("does_not_exist does not exist in database database/moose_testdb.json") !=
581  std::string::npos)
582  << "Failed with unexpected error message: " << msg;
583  }
584 }
585 
586 TEST(GeochemicalDatabaseReaderTest, mineralReactions)
587 {
588  GeochemicalDatabaseReader database("database/moose_testdb.json");
589 
590  // Secondary mineral species
591  std::vector<std::string> names{"Calcite"};
592 
593  auto reactions = database.mineralReactions(names);
594 
595  EXPECT_EQ(reactions[0], "Calcite = Ca++ - H+ + HCO3-");
596 
597  // check that an error is thrown if the species does not exist
598  try
599  {
600  auto reactions_not = database.mineralReactions({"does_not_exist"});
601  FAIL() << "Missing expected exception.";
602  }
603  catch (const std::exception & e)
604  {
605  std::string msg(e.what());
606  ASSERT_TRUE(msg.find("does_not_exist does not exist in database database/moose_testdb.json") !=
607  std::string::npos)
608  << "Failed with unexpected error message: " << msg;
609  }
610 }
611 
612 TEST(GeochemicalDatabaseReaderTest, gasReactions)
613 {
614  GeochemicalDatabaseReader database("database/moose_testdb.json");
615 
616  // Secondary gas species
617  std::vector<std::string> names{"CH4(g)", "N2(g)"};
618 
619  auto reactions = database.gasReactions(names);
620 
621  EXPECT_EQ(reactions[0], "CH4(g) = CH4(aq)");
622  EXPECT_EQ(reactions[1], "N2(g) = N2(aq)");
623 
624  // check that an error is thrown if the species does not exist
625  try
626  {
627  auto reactions_not = database.gasReactions({"does_not_exist"});
628  FAIL() << "Missing expected exception.";
629  }
630  catch (const std::exception & e)
631  {
632  std::string msg(e.what());
633  ASSERT_TRUE(msg.find("does_not_exist does not exist in database database/moose_testdb.json") !=
634  std::string::npos)
635  << "Failed with unexpected error message: " << msg;
636  }
637 }
638 
639 TEST(GeochemicalDatabaseReaderTest, redoxReactions)
640 {
641  GeochemicalDatabaseReader database("database/moose_testdb.json");
642 
643  // Secondary redox couples
644  std::vector<std::string> names{"(O-phth)--", "Am++++"};
645 
646  auto reactions = database.redoxReactions(names);
647 
648  EXPECT_EQ(reactions[0], "(O-phth)-- = 6H+ -5H2O + 8HCO3- -7.5O2(aq)");
649  EXPECT_EQ(reactions[1], "Am++++ = Am+++ + H+ -0.5H2O + 0.25O2(aq)");
650 
651  // check that an error is thrown if the species does not exist
652  try
653  {
654  auto reactions_not = database.redoxReactions({"does_not_exist"});
655  FAIL() << "Missing expected exception.";
656  }
657  catch (const std::exception & e)
658  {
659  std::string msg(e.what());
660  ASSERT_TRUE(msg.find("does_not_exist does not exist in database database/moose_testdb.json") !=
661  std::string::npos)
662  << "Failed with unexpected error message: " << msg;
663  }
664 }
665 
666 TEST(GeochemicalDatabaseReaderTest, oxideReactions)
667 {
668  GeochemicalDatabaseReader database("database/moose_testdb.json");
669 
670  // Secondary oxide species
671  std::vector<std::string> names{"Cu2O"};
672 
673  auto reactions = database.oxideReactions(names);
674 
675  EXPECT_EQ(reactions[0], "Cu2O = 2Cu+ -2H+ + H2O");
676 
677  // check that an error is thrown if the species does not exist
678  try
679  {
680  auto reactions_not = database.oxideReactions({"does_not_exist"});
681  FAIL() << "Missing expected exception.";
682  }
683  catch (const std::exception & e)
684  {
685  std::string msg(e.what());
686  ASSERT_TRUE(msg.find("does_not_exist does not exist in database database/moose_testdb.json") !=
687  std::string::npos)
688  << "Failed with unexpected error message: " << msg;
689  }
690 }
691 
692 TEST(GeochemicalDatabaseReaderTest, isBasisSpecies)
693 {
694  GeochemicalDatabaseReader database("database/moose_testdb.json");
695 
696  EXPECT_TRUE(database.isBasisSpecies("Ca++"));
697  EXPECT_TRUE(database.isBasisSpecies("H2O"));
698  EXPECT_FALSE(database.isBasisSpecies("Ag"));
699  EXPECT_FALSE(database.isBasisSpecies("CO2(aq)"));
700  EXPECT_FALSE(database.isBasisSpecies("CO3--"));
701  EXPECT_FALSE(database.isBasisSpecies("Calcite"));
702  EXPECT_FALSE(database.isBasisSpecies("Fe(OH)3(ppd)"));
703  EXPECT_FALSE(database.isBasisSpecies("CH4(g)"));
704  EXPECT_FALSE(database.isBasisSpecies("(O-phth)--"));
705  EXPECT_FALSE(database.isBasisSpecies("Fe+++"));
706  EXPECT_FALSE(database.isBasisSpecies("Cu2O"));
707  EXPECT_FALSE(database.isBasisSpecies(">(s)FeO-"));
708  EXPECT_FALSE(database.isBasisSpecies("e-"));
709 }
710 
711 TEST(GeochemicalDatabaseReaderTest, isSecondarySpecies)
712 {
713  GeochemicalDatabaseReader database("database/moose_testdb.json");
714 
715  EXPECT_FALSE(database.isSecondarySpecies("Ca++"));
716  EXPECT_FALSE(database.isSecondarySpecies("H2O"));
717  EXPECT_FALSE(database.isSecondarySpecies("Ag"));
718  EXPECT_TRUE(database.isSecondarySpecies("CO2(aq)"));
719  EXPECT_TRUE(database.isSecondarySpecies("CO3--"));
720  EXPECT_TRUE(database.isSecondarySpecies("OH-"));
721  EXPECT_FALSE(database.isSecondarySpecies("Calcite"));
722  EXPECT_FALSE(database.isSecondarySpecies("Fe(OH)3(ppd)"));
723  EXPECT_FALSE(database.isSecondarySpecies("CH4(g)"));
724  EXPECT_FALSE(database.isSecondarySpecies("(O-phth)--"));
725  EXPECT_FALSE(database.isSecondarySpecies("Fe+++"));
726  EXPECT_FALSE(database.isSecondarySpecies("Cu2O"));
727  EXPECT_FALSE(database.isSecondarySpecies(">(s)FeO-"));
728  EXPECT_TRUE(database.isSecondarySpecies("e-"));
729 }
730 
731 TEST(GeochemicalDatabaseReaderTest, isMineralSpecies)
732 {
733  GeochemicalDatabaseReader database("database/moose_testdb.json");
734 
735  EXPECT_FALSE(database.isMineralSpecies("Ca++"));
736  EXPECT_FALSE(database.isMineralSpecies("H2O"));
737  EXPECT_FALSE(database.isMineralSpecies("Ag"));
738  EXPECT_FALSE(database.isMineralSpecies("CO2(aq)"));
739  EXPECT_FALSE(database.isMineralSpecies("CO3--"));
740  EXPECT_TRUE(database.isMineralSpecies("Calcite"));
741  EXPECT_TRUE(database.isMineralSpecies("Fe(OH)3(ppd)"));
742  EXPECT_FALSE(database.isMineralSpecies("CH4(g)"));
743  EXPECT_FALSE(database.isMineralSpecies("(O-phth)--"));
744  EXPECT_FALSE(database.isMineralSpecies("Fe+++"));
745  EXPECT_FALSE(database.isMineralSpecies("Cu2O"));
746  EXPECT_FALSE(database.isMineralSpecies(">(s)FeO-"));
747  EXPECT_FALSE(database.isMineralSpecies("e-"));
748 }
749 
750 TEST(GeochemicalDatabaseReaderTest, isRedoxSpecies)
751 {
752  GeochemicalDatabaseReader database("database/moose_testdb.json");
753 
754  EXPECT_FALSE(database.isRedoxSpecies("Ca++"));
755  EXPECT_FALSE(database.isRedoxSpecies("H2O"));
756  EXPECT_FALSE(database.isRedoxSpecies("Ag"));
757  EXPECT_FALSE(database.isRedoxSpecies("CO2(aq)"));
758  EXPECT_FALSE(database.isRedoxSpecies("CO3--"));
759  EXPECT_FALSE(database.isRedoxSpecies("Calcite"));
760  EXPECT_FALSE(database.isRedoxSpecies("Fe(OH)3(ppd)"));
761  EXPECT_FALSE(database.isRedoxSpecies("CH4(g)"));
762  EXPECT_TRUE(database.isRedoxSpecies("(O-phth)--"));
763  EXPECT_TRUE(database.isRedoxSpecies("Fe+++"));
764  EXPECT_FALSE(database.isRedoxSpecies("Cu2O"));
765  EXPECT_FALSE(database.isRedoxSpecies(">(s)FeO-"));
766  EXPECT_FALSE(database.isRedoxSpecies("e-"));
767 }
768 
769 TEST(GeochemicalDatabaseReaderTest, isGasSpecies)
770 {
771  GeochemicalDatabaseReader database("database/moose_testdb.json");
772 
773  EXPECT_FALSE(database.isGasSpecies("Ca++"));
774  EXPECT_FALSE(database.isGasSpecies("H2O"));
775  EXPECT_FALSE(database.isGasSpecies("Ag"));
776  EXPECT_FALSE(database.isGasSpecies("CO2(aq)"));
777  EXPECT_FALSE(database.isGasSpecies("CO3--"));
778  EXPECT_FALSE(database.isGasSpecies("Calcite"));
779  EXPECT_FALSE(database.isGasSpecies("Fe(OH)3(ppd)"));
780  EXPECT_TRUE(database.isGasSpecies("CH4(g)"));
781  EXPECT_FALSE(database.isGasSpecies("(O-phth)--"));
782  EXPECT_FALSE(database.isGasSpecies("Fe+++"));
783  EXPECT_FALSE(database.isGasSpecies("Cu2O"));
784  EXPECT_FALSE(database.isGasSpecies(">(s)FeO-"));
785  EXPECT_FALSE(database.isGasSpecies("e-"));
786 }
787 
788 TEST(GeochemicalDatabaseReaderTest, isSorbingMineral)
789 {
790  GeochemicalDatabaseReader database("database/moose_testdb.json");
791 
792  EXPECT_FALSE(database.isSorbingMineral("Ca++"));
793  EXPECT_FALSE(database.isSorbingMineral("H2O"));
794  EXPECT_FALSE(database.isSorbingMineral("Ag"));
795  EXPECT_FALSE(database.isSorbingMineral("CO2(aq)"));
796  EXPECT_FALSE(database.isSorbingMineral("CO3--"));
797  EXPECT_FALSE(database.isSorbingMineral("Calcite"));
798  EXPECT_TRUE(database.isSorbingMineral("Fe(OH)3(ppd)"));
799  EXPECT_FALSE(database.isSorbingMineral("CH4(g)"));
800  EXPECT_FALSE(database.isSorbingMineral("(O-phth)--"));
801  EXPECT_FALSE(database.isSorbingMineral("Fe+++"));
802  EXPECT_FALSE(database.isSorbingMineral("Cu2O"));
803  EXPECT_FALSE(database.isSorbingMineral(">(s)FeO-"));
804  EXPECT_FALSE(database.isSorbingMineral("e-"));
805 }
806 
807 TEST(GeochemicalDatabaseReaderTest, isOxideSpecies)
808 {
809  GeochemicalDatabaseReader database("database/moose_testdb.json");
810 
811  EXPECT_FALSE(database.isOxideSpecies("Ca++"));
812  EXPECT_FALSE(database.isOxideSpecies("H2O"));
813  EXPECT_FALSE(database.isOxideSpecies("Ag"));
814  EXPECT_FALSE(database.isOxideSpecies("CO2(aq)"));
815  EXPECT_FALSE(database.isOxideSpecies("CO3--"));
816  EXPECT_FALSE(database.isOxideSpecies("Calcite"));
817  EXPECT_FALSE(database.isOxideSpecies("Fe(OH)3(ppd)"));
818  EXPECT_FALSE(database.isOxideSpecies("CH4(g)"));
819  EXPECT_FALSE(database.isOxideSpecies("(O-phth)--"));
820  EXPECT_FALSE(database.isOxideSpecies("Fe+++"));
821  EXPECT_TRUE(database.isOxideSpecies("Cu2O"));
822  EXPECT_FALSE(database.isOxideSpecies(">(s)FeO-"));
823  EXPECT_FALSE(database.isOxideSpecies("e-"));
824 }
825 
826 TEST(GeochemicalDatabaseReaderTest, isSurfaceSpecies)
827 {
828  GeochemicalDatabaseReader database("database/moose_testdb.json");
829 
830  EXPECT_FALSE(database.isSurfaceSpecies("Ca++"));
831  EXPECT_FALSE(database.isSurfaceSpecies("H2O"));
832  EXPECT_FALSE(database.isSurfaceSpecies("Ag"));
833  EXPECT_FALSE(database.isSurfaceSpecies("CO2(aq)"));
834  EXPECT_FALSE(database.isSurfaceSpecies("CO3--"));
835  EXPECT_FALSE(database.isSurfaceSpecies("Calcite"));
836  EXPECT_FALSE(database.isSurfaceSpecies("Fe(OH)3(ppd)"));
837  EXPECT_FALSE(database.isSurfaceSpecies("CH4(g)"));
838  EXPECT_FALSE(database.isSurfaceSpecies("(O-phth)--"));
839  EXPECT_FALSE(database.isSurfaceSpecies("Fe+++"));
840  EXPECT_FALSE(database.isSurfaceSpecies("Cu2O"));
841  EXPECT_TRUE(database.isSurfaceSpecies(">(s)FeO-"));
842  EXPECT_FALSE(database.isSurfaceSpecies("e-"));
843 }
844 
845 TEST(GeochemicalDatabaseReaderTest, mineralSpeciesNames)
846 {
847  GeochemicalDatabaseReader database("database/moose_testdb.json");
848 
849  std::vector<std::string> names = database.mineralSpeciesNames();
850  for (const auto & n : {"Calcite",
851  "Calcite_asdf",
852  "Fe(OH)3(ppd)",
853  "Fe(OH)3(ppd)fake",
854  "Goethite",
855  "Something",
856  "problematic_sorber"})
857  EXPECT_TRUE(std::find(names.begin(), names.end(), n) != names.end());
858  EXPECT_EQ(names.size(), (std::size_t)7);
859 }
860 
861 TEST(GeochemicalDatabaseReaderTest, secondarySpeciesNames)
862 {
863  GeochemicalDatabaseReader database("database/moose_testdb.json");
864 
865  std::vector<std::string> names = database.secondarySpeciesNames();
866  for (const auto & n : {"CO2(aq)", "CO3--", "CaCO3", "CaOH+", "OH-", "e-", "seq_radius_neg1"})
867  EXPECT_TRUE(std::find(names.begin(), names.end(), n) != names.end());
868  EXPECT_EQ(names.size(), (std::size_t)8);
869 }
870 
871 TEST(GeochemicalDatabaseReaderTest, redoxCoupleNames)
872 {
873  GeochemicalDatabaseReader database("database/moose_testdb.json");
874 
875  std::vector<std::string> names = database.redoxCoupleNames();
876  for (const auto & n : {"(O-phth)--", "Am++++", "CH4(aq)", "Fe+++", "StoiCheckRedox"})
877  EXPECT_TRUE(std::find(names.begin(), names.end(), n) != names.end());
878  EXPECT_EQ(names.size(), (std::size_t)5);
879 }
880 
881 TEST(GeochemicalDatabaseReaderTest, surfaceSpeciesNames)
882 {
883  GeochemicalDatabaseReader database("database/moose_testdb.json");
884 
885  std::vector<std::string> names = database.surfaceSpeciesNames();
886  for (const auto & n : {">(s)FeO-", ">(s)FeOCa+"})
887  EXPECT_TRUE(std::find(names.begin(), names.end(), n) != names.end());
888  EXPECT_EQ(names.size(), (std::size_t)2);
889 }
890 
891 TEST(GeochemicalDatabaseReaderTest, getSpeciesData)
892 {
893  GeochemicalDatabaseReader database("database/moose_testdb.json");
894 
895  std::string data = database.getSpeciesData("Ca++");
896  std::string gold = "Ca++:\n{\n \"charge\": 2,\n \"elements\": {\n \"Ca\": 1.0\n "
897  "},\n \"molecular weight\": 40.08,\n \"radius\": 6.0\n}";
898  EXPECT_EQ(data, gold);
899 
900  // check that an error is thrown if the species does not exist
901  try
902  {
903  auto reactions_not = database.getSpeciesData({"does_not_exist"});
904  FAIL() << "Missing expected exception.";
905  }
906  catch (const std::exception & e)
907  {
908  std::string msg(e.what());
909  ASSERT_TRUE(msg.find("does_not_exist is not a species in the database") != std::string::npos)
910  << "Failed with unexpected error message: " << msg;
911  }
912 }
913 
915 TEST(GeochemicalDatabaseReaderTest, freeElectron)
916 {
917  GeochemicalDatabaseReader database("database/moose_testdb.json");
918 
919  auto fe = database.getEquilibriumSpecies({"e-"})["e-"];
920 
921  std::vector<Real> logk_gold{
922  23.4266, 21.50045, 19.277525, 17.24705, 15.238975, 13.64975, 12.34665, 11.27355};
923  std::map<std::string, Real> bs_gold = {{"H2O", 0.5}, {"H+", -1}, {"O2(aq)", -0.25}};
924  EXPECT_EQ(fe.charge, -1.0);
925  EXPECT_EQ(fe.radius, 0.0);
926  EXPECT_EQ(fe.molecular_weight, 0.0);
927  EXPECT_EQ(fe.basis_species, bs_gold);
928  EXPECT_EQ(fe.equilibrium_const, logk_gold);
929 }
930 
932 TEST(GeochemicalDatabaseReaderTest, freeElectronNoReexpress)
933 {
934  GeochemicalDatabaseReader database("database/moose_testdb.json", false);
935 
936  auto fe = database.getEquilibriumSpecies({"e-"})["e-"];
937 
938  std::vector<Real> logk_gold{
939  22.76135, 20.7757, 18.513025, 16.4658, 14.473225, 12.92125, 11.68165, 10.67105};
940  std::map<std::string, Real> bs_gold = {{"H2O", 0.5}, {"H+", -1}, {"O2(g)", -0.25}};
941  EXPECT_EQ(fe.charge, -1.0);
942  EXPECT_EQ(fe.radius, 0.0);
943  EXPECT_EQ(fe.molecular_weight, 0.0);
944  EXPECT_EQ(fe.basis_species, bs_gold);
945  EXPECT_EQ(fe.equilibrium_const, logk_gold);
946 }
947 
949 TEST(GeochemicalDatabaseReaderTest, isSecondarySpecies_noextrap)
950 {
951  GeochemicalDatabaseReader database("database/moose_testdb.json", true, false, true);
952 
953  EXPECT_FALSE(database.isSecondarySpecies("Ca++"));
954  EXPECT_FALSE(database.isSecondarySpecies("H2O"));
955  EXPECT_FALSE(database.isSecondarySpecies("Ag"));
956  EXPECT_TRUE(database.isSecondarySpecies("CO2(aq)"));
957  EXPECT_TRUE(database.isSecondarySpecies("CO3--"));
958  EXPECT_FALSE(database.isSecondarySpecies("OH-"));
959  EXPECT_FALSE(database.isSecondarySpecies("Calcite"));
960  EXPECT_FALSE(database.isSecondarySpecies("Fe(OH)3(ppd)"));
961  EXPECT_FALSE(database.isSecondarySpecies("CH4(g)"));
962  EXPECT_FALSE(database.isSecondarySpecies("(O-phth)--"));
963  EXPECT_FALSE(database.isSecondarySpecies("Fe+++"));
964  EXPECT_FALSE(database.isSecondarySpecies("Cu2O"));
965  EXPECT_FALSE(database.isSecondarySpecies(">(s)FeO-"));
966  EXPECT_TRUE(database.isSecondarySpecies("e-"));
967 }
OStreamProxy err
std::map< std::string, GeochemistrySurfaceSpecies > getSurfaceSpecies(const std::vector< std::string > &names)
Get the surface sorbing species information.
std::map< std::string, GeochemistryEquilibriumSpecies > getEquilibriumSpecies(const std::vector< std::string > &names)
Get the secondary equilibrium species information.
std::vector< Real > getPressures()
Get the pressure points that the equilibrium constant is defined at.
std::string getActivityModel() const
Get the activity model type.
const GeochemistryDebyeHuckel & getDebyeHuckel() const
Get the Debye-Huckel activity coefficients.
std::vector< std::string > redoxCoupleNames() const
Returns a list of all the names of the "redox couples" in the database.
std::map< std::string, GeochemistryMineralSpecies > getMineralSpecies(const std::vector< std::string > &names)
Get the mineral species information.
std::map< std::string, GeochemistryGasSpecies > getGasSpecies(const std::vector< std::string > &names)
Get the gas species information.
std::vector< std::string > redoxReactions(const std::vector< std::string > &names) const
Generates a formatted vector of strings representing all redox reactions.
const FileName & filename() const
Filename of database.
std::string getLogKModel() const
Get the equilibrium constant model type.
std::string getFugacityModel() const
Get the fugacity model type.
std::basic_ostream< charT, traits > * os
std::string getSpeciesData(const std::string name) const
String representation of JSON species object contents.
const GeochemicalDatabaseReader database("database/moose_testdb.json", true, true, false)
bool isSorbingMineral(const std::string &name) const
returns True iff name is the name of a sorbing mineral
std::vector< std::string > mineralSpeciesNames() const
Returns a list of all the names of the "mineral species" in the database.
bool isOxideSpecies(const std::string &name) const
const std::vector< Real > & getTemperatures() const
Get the temperature points that the equilibrium constant is defined at.
std::vector< std::string > surfaceSpeciesNames() const
Returns a list of all the names of the "surface species" in the database.
TEST(GeochemicalDatabaseReaderTest, filename)
std::map< std::string, GeochemistryBasisSpecies > getBasisSpecies(const std::vector< std::string > &names)
Get the basis (primary) species information.
bool isGasSpecies(const std::string &name) const
std::map< std::string, GeochemistryElements > getElements()
Get all the elements.
std::vector< std::string > equilibriumReactions(const std::vector< std::string > &names) const
Generates a formatted vector of strings representing all aqueous equilibrium reactions.
bool isSecondarySpecies(const std::string &name) const
Returns true if name is a "secondary species" or "free electron" in the database. ...
std::vector< std::string > secondarySpeciesNames() const
Returns a list of all the names of the "secondary species" and "free electron" in the database...
bool isSurfaceSpecies(const std::string &name) const
std::vector< std::string > oxideReactions(const std::vector< std::string > &names) const
Generates a formatted vector of strings representing all oxide reactions.
std::map< std::string, GeochemistryOxideSpecies > getOxideSpecies(const std::vector< std::string > &names)
Get the oxide species information.
bool isMineralSpecies(const std::string &name) const
const std::map< std::string, GeochemistryNeutralSpeciesActivity > & getNeutralSpeciesActivity() const
Get the neutral species activity coefficients.
std::map< std::string, GeochemistryRedoxSpecies > getRedoxSpecies(const std::vector< std::string > &names)
Get the redox species (couples) information.
std::vector< std::string > gasReactions(const std::vector< std::string > &names) const
Generates a formatted vector of strings representing all gas reactions.
Class for reading geochemical reactions from a MOOSE geochemical database.
bool isRedoxSpecies(const std::string &name) const
std::vector< std::string > mineralReactions(const std::vector< std::string > &names) const
Generates a formatted vector of strings representing all mineral reactions.
bool isBasisSpecies(const std::string &name) const
Checks if species is of given type.