diff --git a/modules/geochemistry/include/utils/GeochemicalDatabaseReader.h b/modules/geochemistry/include/utils/GeochemicalDatabaseReader.h index 38c677093232..719cf25eea1a 100644 --- a/modules/geochemistry/include/utils/GeochemicalDatabaseReader.h +++ b/modules/geochemistry/include/utils/GeochemicalDatabaseReader.h @@ -387,13 +387,15 @@ class GeochemicalDatabaseReader */ const FileName & filename() const; + /// Returns true if name is a "secondary species" or "free electron" in the database + bool isSecondarySpecies(const std::string & name) const; + /** * Checks if species is of given type * @param name species name * @return true iff species is of given type */ bool isBasisSpecies(const std::string & name) const; - bool isSecondarySpecies(const std::string & name) const; bool isRedoxSpecies(const std::string & name) const; bool isGasSpecies(const std::string & name) const; bool isMineralSpecies(const std::string & name) const; @@ -403,7 +405,7 @@ class GeochemicalDatabaseReader /// returns True iff name is the name of a sorbing mineral bool isSorbingMineral(const std::string & name) const; - /// Returns a list of all the names of the "secondary species" in the database + /// Returns a list of all the names of the "secondary species" and "free electron" in the database std::vector secondarySpeciesNames() const; /// Returns a list of all the names of the "redox couples" in the database @@ -441,7 +443,7 @@ class GeochemicalDatabaseReader std::map _elements; /// Basis species data read from the database std::map _basis_species; - /// Secondary equilibrium species data read from the database + /// Secondary equilibrium species and free electron data read from the database std::map _equilibrium_species; /// Mineral species data read from the database std::map _mineral_species; diff --git a/modules/geochemistry/python/database_converter.py b/modules/geochemistry/python/database_converter.py index 12ad7e312dc2..424c89cdb6f7 100755 --- a/modules/geochemistry/python/database_converter.py +++ b/modules/geochemistry/python/database_converter.py @@ -82,6 +82,8 @@ def main(): database['basis species'] = db.basis_species if db.secondary_species: database['secondary species'] = db.secondary_species + if db.free_electron: + database['free electron'] = db.free_electron if db.mineral_species: database['mineral species'] = db.mineral_species if db.gas_species: diff --git a/modules/geochemistry/python/dbclass.py b/modules/geochemistry/python/dbclass.py index 5e174324b791..f41c67f60ec2 100644 --- a/modules/geochemistry/python/dbclass.py +++ b/modules/geochemistry/python/dbclass.py @@ -25,6 +25,7 @@ def __init__(self): self._elements = None self._basis_species = None self._secondary_species = None + self._free_electron = None self._mineral_species = None self._gas_species = None self._redox_couples = None @@ -117,6 +118,15 @@ def secondary_species(self): def secondary_species(self, secondary_species): self._secondary_species = secondary_species + # Free electron data + @property + def free_electron(self): + return self._free_electron + + @free_electron.setter + def free_electron(self, free_electron): + self._free_electron = free_electron + # Mineral species data @property def mineral_species(self): diff --git a/modules/geochemistry/python/readers/gwb_reader.py b/modules/geochemistry/python/readers/gwb_reader.py index d6b6029b629d..7b02698ec063 100644 --- a/modules/geochemistry/python/readers/gwb_reader.py +++ b/modules/geochemistry/python/readers/gwb_reader.py @@ -601,6 +601,7 @@ def readDatabase(dblist): db.elements = elements db.basis_species = basis_species db.secondary_species = secondary_species + db.free_electron = free_electron db.mineral_species = mineral_species db.sorbing_minerals = sorbing_minerals db.gas_species = gas_species diff --git a/modules/geochemistry/python/tests/test_gwbreader.py b/modules/geochemistry/python/tests/test_gwbreader.py index cebfb3065d89..9fd035944257 100644 --- a/modules/geochemistry/python/tests/test_gwbreader.py +++ b/modules/geochemistry/python/tests/test_gwbreader.py @@ -137,6 +137,18 @@ def testSecondarySpecies(self): self.assertDictEqual(self.db.secondary_species, gold) + def testFreeElectron(self): + """ + Test that the free electron is correctly parsed + """ + self.readDatabase() + gold = {'e-': {'charge': '-1', 'radius': '0.0', 'molecular weight': '0.0000', + 'species': {'H2O': '.500', 'O2(g)': '-.250', 'H+': '-1.000'}, + 'logk': ['22.76135', '20.7757', '18.513025', '16.4658', + '14.473225', '12.92125', '11.68165', '10.67105']}} + + self.assertDictEqual(self.db.free_electron, gold) + def testMineralSpecies(self): """ Test that the mineral species are correctly parsed diff --git a/modules/geochemistry/python/tests/testdata/gwbtestdata.dat b/modules/geochemistry/python/tests/testdata/gwbtestdata.dat index b7557badcb59..3f99d1ce03bc 100644 --- a/modules/geochemistry/python/tests/testdata/gwbtestdata.dat +++ b/modules/geochemistry/python/tests/testdata/gwbtestdata.dat @@ -132,3 +132,16 @@ Cu2O -2.000 H+ 2.000 Cu+ 1.000 H2O -end- + + 1 free electron + +e- + charge= -1 ion size= 0.0 A mole wt.= 0.0000 g + 3 species in reaction + .500 H2O -.250 O2(g) -1.000 H+ + 22.76135 20.7757 18.513025 16.4658 + 14.473225 12.92125 11.68165 10.67105 + +-end- + + diff --git a/modules/geochemistry/src/utils/GeochemicalDatabaseReader.C b/modules/geochemistry/src/utils/GeochemicalDatabaseReader.C index c5b2225d76c1..0000e5f13e84 100644 --- a/modules/geochemistry/src/utils/GeochemicalDatabaseReader.C +++ b/modules/geochemistry/src/utils/GeochemicalDatabaseReader.C @@ -159,11 +159,13 @@ GeochemicalDatabaseReader::getEquilibriumSpecies(const std::vector { // Parse the secondary species specified in names for (const auto & species : names) - if (_root["secondary species"].isMember(species)) + if (_root["secondary species"].isMember(species) or _root["free electron"].isMember(species)) { GeochemistryEquilibriumSpecies dbs; - auto sec_species = _root["secondary species"][species]; + auto sec_species = _root["secondary species"].isMember(species) + ? _root["secondary species"][species] + : _root["free electron"][species]; dbs.name = species; dbs.radius = MooseUtils::convert(sec_species["radius"].asString()); dbs.charge = MooseUtils::convert(sec_species["charge"].asString()); @@ -610,6 +612,8 @@ std::vector GeochemicalDatabaseReader::secondarySpeciesNames() const { std::vector names(_root["secondary species"].getMemberNames()); + for (const auto nm : _root["free electron"].getMemberNames()) + names.push_back(nm); return names; } @@ -654,7 +658,7 @@ GeochemicalDatabaseReader::isSorbingMineral(const std::string & name) const bool GeochemicalDatabaseReader::isSecondarySpecies(const std::string & name) const { - return _root["secondary species"].isMember(name); + return _root["secondary species"].isMember(name) || _root["free electron"].isMember(name); } bool diff --git a/modules/geochemistry/unit/data/moose_testdb.json b/modules/geochemistry/unit/data/moose_testdb.json index e6f5ea2c9e47..3040dba85d3d 100644 --- a/modules/geochemistry/unit/data/moose_testdb.json +++ b/modules/geochemistry/unit/data/moose_testdb.json @@ -584,5 +584,27 @@ "log K": "1.7200", "dlogK/dT": "0.0000" } + }, + "free electron": { + "e-": { + "species": { + "H2O": ".500", + "O2(g)": "-.250", + "H+": "-1.000" + }, + "charge": "-1", + "radius": "0.0", + "molecular weight": "0.0000", + "logk": [ + "22.76135", + "20.7757", + "18.513025", + "16.4658", + "14.473225", + "12.92125", + "11.68165", + "10.67105" + ] + } } } diff --git a/modules/geochemistry/unit/src/GeochemicalDatabaseReaderTest.C b/modules/geochemistry/unit/src/GeochemicalDatabaseReaderTest.C index a18cd3ec14e9..2c69d88a3226 100644 --- a/modules/geochemistry/unit/src/GeochemicalDatabaseReaderTest.C +++ b/modules/geochemistry/unit/src/GeochemicalDatabaseReaderTest.C @@ -478,6 +478,7 @@ TEST(GeochemicalDatabaseReaderTest, isBasisSpecies) EXPECT_FALSE(database.isBasisSpecies("Fe+++")); EXPECT_FALSE(database.isBasisSpecies("Cu2O")); EXPECT_FALSE(database.isBasisSpecies(">(s)FeO-")); + EXPECT_FALSE(database.isBasisSpecies("e-")); } TEST(GeochemicalDatabaseReaderTest, isSecondarySpecies) @@ -496,6 +497,7 @@ TEST(GeochemicalDatabaseReaderTest, isSecondarySpecies) EXPECT_FALSE(database.isSecondarySpecies("Fe+++")); EXPECT_FALSE(database.isSecondarySpecies("Cu2O")); EXPECT_FALSE(database.isSecondarySpecies(">(s)FeO-")); + EXPECT_TRUE(database.isSecondarySpecies("e-")); } TEST(GeochemicalDatabaseReaderTest, isMineralSpecies) @@ -514,6 +516,7 @@ TEST(GeochemicalDatabaseReaderTest, isMineralSpecies) EXPECT_FALSE(database.isMineralSpecies("Fe+++")); EXPECT_FALSE(database.isMineralSpecies("Cu2O")); EXPECT_FALSE(database.isMineralSpecies(">(s)FeO-")); + EXPECT_FALSE(database.isMineralSpecies("e-")); } TEST(GeochemicalDatabaseReaderTest, isRedoxSpecies) @@ -532,6 +535,7 @@ TEST(GeochemicalDatabaseReaderTest, isRedoxSpecies) EXPECT_TRUE(database.isRedoxSpecies("Fe+++")); EXPECT_FALSE(database.isRedoxSpecies("Cu2O")); EXPECT_FALSE(database.isRedoxSpecies(">(s)FeO-")); + EXPECT_FALSE(database.isRedoxSpecies("e-")); } TEST(GeochemicalDatabaseReaderTest, isGasSpecies) @@ -550,6 +554,7 @@ TEST(GeochemicalDatabaseReaderTest, isGasSpecies) EXPECT_FALSE(database.isGasSpecies("Fe+++")); EXPECT_FALSE(database.isGasSpecies("Cu2O")); EXPECT_FALSE(database.isGasSpecies(">(s)FeO-")); + EXPECT_FALSE(database.isGasSpecies("e-")); } TEST(GeochemicalDatabaseReaderTest, isSorbingMineral) @@ -568,6 +573,7 @@ TEST(GeochemicalDatabaseReaderTest, isSorbingMineral) EXPECT_FALSE(database.isSorbingMineral("Fe+++")); EXPECT_FALSE(database.isSorbingMineral("Cu2O")); EXPECT_FALSE(database.isSorbingMineral(">(s)FeO-")); + EXPECT_FALSE(database.isSorbingMineral("e-")); } TEST(GeochemicalDatabaseReaderTest, isOxideSpecies) @@ -586,6 +592,7 @@ TEST(GeochemicalDatabaseReaderTest, isOxideSpecies) EXPECT_FALSE(database.isOxideSpecies("Fe+++")); EXPECT_TRUE(database.isOxideSpecies("Cu2O")); EXPECT_FALSE(database.isOxideSpecies(">(s)FeO-")); + EXPECT_FALSE(database.isOxideSpecies("e-")); } TEST(GeochemicalDatabaseReaderTest, isSurfaceSpecies) @@ -604,6 +611,7 @@ TEST(GeochemicalDatabaseReaderTest, isSurfaceSpecies) EXPECT_FALSE(database.isSurfaceSpecies("Fe+++")); EXPECT_FALSE(database.isSurfaceSpecies("Cu2O")); EXPECT_TRUE(database.isSurfaceSpecies(">(s)FeO-")); + EXPECT_FALSE(database.isSurfaceSpecies("e-")); } TEST(GeochemicalDatabaseReaderTest, secondarySpeciesNames) @@ -611,9 +619,9 @@ TEST(GeochemicalDatabaseReaderTest, secondarySpeciesNames) GeochemicalDatabaseReader database("data/moose_testdb.json"); std::vector names = database.secondarySpeciesNames(); - for (const auto & n : {"CO2(aq)", "CO3--", "CaCO3", "CaOH+", "OH-"}) + for (const auto & n : {"CO2(aq)", "CO3--", "CaCO3", "CaOH+", "OH-", "e-"}) EXPECT_TRUE(std::find(names.begin(), names.end(), n) != names.end()); - EXPECT_EQ(names.size(), 5); + EXPECT_EQ(names.size(), 6); } TEST(GeochemicalDatabaseReaderTest, redoxCoupleNames)