10 #include "gtest/gtest.h" 17 {
"H2O",
"H+",
"HCO3-",
"O2(aq)",
"Ca++"},
32 {
"H2O",
"OH-",
"O2(aq)",
"CO2(aq)",
"CaCO3"},
33 {3.0, 3.1, 3.2, 3.3, 3.4},
34 {0.0, 0.0, 0.0, 0.0, 0.0},
35 {0.0, 0.0, 0.0, 0.0, 0.0},
52 {
"H2O",
"OH-",
"O2(aq)",
"CO2(aq)",
"CaCO3"},
53 {3.0, 3.1, 3.2, 3.3, 3.4},
54 {0.0, 0.0, 0.0, 0.0, 0.0},
55 {0.0, 0.0, 0.0, 0.0, 0.0},
72 {
"H2O",
"OH-",
"O2(aq)",
"CO2(aq)",
"CaCO3"},
73 {3.0, 3.1, 3.2, 3.3, 3.4},
74 {0.0, 0.0, 0.0, 0.0, 0.0},
75 {0.0, 0.0, 0.0, 0.0, 0.0},
92 {
"H2O",
"OH-",
"O2(aq)",
"CO2(aq)",
"CaCO3"},
93 {3.0, 3.1, 3.2, 3.3, 3.4},
94 {0.0, 0.0, 0.0, 0.0, 0.0},
95 {0.0, 0.0, 0.0, 0.0, 0.0},
112 {
"H2O",
"OH-",
"O2(aq)",
"CO2(aq)",
"CaCO3"},
113 {3.0, 3.1, 3.2, 3.3, 3.4},
114 {0.0, 0.0, 0.0, 0.0, 0.0},
115 {0.0, 0.0, 0.0, 0.0, 0.0},
132 {
"H2O",
"OH-",
"O2(aq)",
"CO2(aq)",
"CaCO3"},
133 {3.0, 3.1, 3.2, 3.3, 3.4},
134 {0.0, 0.0, 0.0, 0.0, 0.0},
135 {0.0, 0.0, 0.0, 0.0, 0.0},
152 {
"H2O",
"OH-",
"O2(aq)",
"CO2(aq)",
"CaCO3"},
153 {3.0, 3.1, 3.2, 3.3, 3.4},
154 {0.0, 0.0, 0.0, 0.0, 0.0},
155 {0.0, 0.0, 0.0, 0.0, 0.0},
288 TEST(KineticRateUserDescriptionTest, exceptions)
312 FAIL() <<
"Missing expected exception.";
314 catch (
const std::exception & e)
316 std::string msg(e.what());
318 msg.find(
"The promoting_species and promoting_indices vectors must be the same size") !=
320 <<
"Failed with unexpected error message: " << msg;
345 FAIL() <<
"Missing expected exception.";
347 catch (
const std::exception & e)
349 std::string msg(e.what());
352 "The promoting_species and promoting_monod_indices vectors must be the same size") !=
354 <<
"Failed with unexpected error message: " << msg;
379 FAIL() <<
"Missing expected exception.";
381 catch (
const std::exception & e)
383 std::string msg(e.what());
386 "The promoting_species and promoting_half_saturation vectors must be the same size") !=
388 <<
"Failed with unexpected error message: " << msg;
400 {
"H2O",
"OH-",
"H2O"},
413 FAIL() <<
"Missing expected exception.";
415 catch (
const std::exception & e)
417 std::string msg(e.what());
418 ASSERT_TRUE(msg.find(
"Promoting species H2O has already been provided with an exponent") !=
420 <<
"Failed with unexpected error message: " << msg;
425 TEST(GeochemistryKineticRateCalculatorTest, exceptions)
428 const std::vector<Real> promoting_indices(5 + 6, 0.0);
429 const std::vector<std::string> basis_name = {
"H2O",
"H+",
"HCO3-",
"O2(aq)",
"Ca++"};
431 const std::vector<Real> basis_molality = {1.0, 2.0, 3.0, 4.0, 5.0};
432 const std::vector<Real> basis_activity = {0.1, 0.2, 0.3, 0.4, 0.5};
433 const std::vector<bool> basis_activity_known(5,
false);
436 const std::vector<Real> eqm_molality = {1.5, 2.5, 3.5, 4.5, 5.5, 7.5};
437 const std::vector<Real> eqm_activity = {1.1, 1.2, 1.3, 1.4, 1.5, 1.7};
443 std::vector<Real> drate_dmol(5);
448 std::vector<Real>(5 + 6, 0),
449 std::vector<Real>(5 + 6, 0),
455 basis_activity_known,
471 FAIL() <<
"Missing expected exception.";
473 catch (
const std::exception & e)
475 std::string msg(e.what());
476 ASSERT_TRUE(msg.find(
"kinetic_rate: promoting_indices incorrectly sized 0") !=
478 <<
"Failed with unexpected error message: " << msg;
485 std::vector<Real>(5 + 6, 0),
491 basis_activity_known,
507 FAIL() <<
"Missing expected exception.";
509 catch (
const std::exception & e)
511 std::string msg(e.what());
512 ASSERT_TRUE(msg.find(
"kinetic_rate: promoting_monod_indices incorrectly sized 0") !=
514 <<
"Failed with unexpected error message: " << msg;
520 std::vector<Real>(5 + 6, 0),
527 basis_activity_known,
543 FAIL() <<
"Missing expected exception.";
545 catch (
const std::exception & e)
547 std::string msg(e.what());
548 ASSERT_TRUE(msg.find(
"kinetic_rate: promoting_half_saturation incorrectly sized 0") !=
550 <<
"Failed with unexpected error message: " << msg;
556 std::vector<Real>(5 + 6, 0),
557 std::vector<Real>(5 + 6, 0),
563 basis_activity_known,
579 FAIL() <<
"Missing expected exception.";
581 catch (
const std::exception & e)
583 std::string msg(e.what());
584 ASSERT_TRUE(msg.find(
"kinetic_rate: incorrectly sized basis-species vectors 5 0 5 5 5 5") !=
586 <<
"Failed with unexpected error message: " << msg;
592 std::vector<Real>(5 + 6, 0),
593 std::vector<Real>(5 + 6, 0),
599 basis_activity_known,
615 FAIL() <<
"Missing expected exception.";
617 catch (
const std::exception & e)
619 std::string msg(e.what());
620 ASSERT_TRUE(msg.find(
"kinetic_rate: incorrectly sized basis-species vectors 5 5 0 5 5 5") !=
622 <<
"Failed with unexpected error message: " << msg;
628 std::vector<Real>(5 + 6, 0),
629 std::vector<Real>(5 + 6, 0),
635 basis_activity_known,
651 FAIL() <<
"Missing expected exception.";
653 catch (
const std::exception & e)
655 std::string msg(e.what());
656 ASSERT_TRUE(msg.find(
"kinetic_rate: incorrectly sized basis-species vectors 5 5 5 0 5 5") !=
658 <<
"Failed with unexpected error message: " << msg;
664 std::vector<Real>(5 + 6, 0),
665 std::vector<Real>(5 + 6, 0),
687 FAIL() <<
"Missing expected exception.";
689 catch (
const std::exception & e)
691 std::string msg(e.what());
692 ASSERT_TRUE(msg.find(
"kinetic_rate: incorrectly sized basis-species vectors 5 5 5 5 0 5") !=
694 <<
"Failed with unexpected error message: " << msg;
699 std::vector<Real> drdm(4);
701 std::vector<Real>(5 + 6, 0),
702 std::vector<Real>(5 + 6, 0),
708 basis_activity_known,
724 FAIL() <<
"Missing expected exception.";
726 catch (
const std::exception & e)
728 std::string msg(e.what());
729 ASSERT_TRUE(msg.find(
"kinetic_rate: incorrectly sized basis-species vectors 5 5 5 5 5 4") !=
731 <<
"Failed with unexpected error message: " << msg;
737 std::vector<Real>(5 + 6, 0),
738 std::vector<Real>(5 + 6, 0),
744 basis_activity_known,
760 FAIL() <<
"Missing expected exception.";
762 catch (
const std::exception & e)
764 std::string msg(e.what());
765 ASSERT_TRUE(msg.find(
"kinetic_rate: incorrectly sized equilibrium-species vectors 6 0 6 6") !=
767 <<
"Failed with unexpected error message: " << msg;
773 std::vector<Real>(5 + 6, 0),
774 std::vector<Real>(5 + 6, 0),
780 basis_activity_known,
796 FAIL() <<
"Missing expected exception.";
798 catch (
const std::exception & e)
800 std::string msg(e.what());
801 ASSERT_TRUE(msg.find(
"kinetic_rate: incorrectly sized equilibrium-species vectors 6 6 0 6") !=
803 <<
"Failed with unexpected error message: " << msg;
809 std::vector<Real>(5 + 6, 0),
810 std::vector<Real>(5 + 6, 0),
816 basis_activity_known,
832 FAIL() <<
"Missing expected exception.";
834 catch (
const std::exception & e)
836 std::string msg(e.what());
837 ASSERT_TRUE(msg.find(
"kinetic_rate: incorrectly sized equilibrium-species vectors 6 6 6 0") !=
839 <<
"Failed with unexpected error message: " << msg;
846 std::vector<Real>(5 + 6, 0),
847 std::vector<Real>(5 + 6, 0),
853 basis_activity_known,
869 FAIL() <<
"Missing expected exception.";
871 catch (
const std::exception & e)
873 std::string msg(e.what());
874 ASSERT_TRUE(msg.find(
"kinetic_rate: incorrectly sized eqm stoichiometry matrix 7 4") !=
876 <<
"Failed with unexpected error message: " << msg;
883 std::vector<Real>(5 + 6, 0),
884 std::vector<Real>(5 + 6, 0),
890 basis_activity_known,
906 FAIL() <<
"Missing expected exception.";
908 catch (
const std::exception & e)
910 std::string msg(e.what());
911 ASSERT_TRUE(msg.find(
"kinetic_rate: incorrectly sized eqm stoichiometry matrix 4 5") !=
913 <<
"Failed with unexpected error message: " << msg;
920 std::vector<Real>(5 + 6, 0),
921 std::vector<Real>(5 + 6, 0),
927 basis_activity_known,
943 FAIL() <<
"Missing expected exception.";
945 catch (
const std::exception & e)
947 std::string msg(e.what());
948 ASSERT_TRUE(msg.find(
"kinetic_rate: incorrectly sized kinetic stoichiometry matrix 1 5") !=
950 <<
"Failed with unexpected error message: " << msg;
957 std::vector<Real>(5 + 6, 0),
958 std::vector<Real>(5 + 6, 0),
964 basis_activity_known,
980 FAIL() <<
"Missing expected exception.";
982 catch (
const std::exception & e)
984 std::string msg(e.what());
985 ASSERT_TRUE(msg.find(
"kinetic_rate: incorrectly sized kinetic stoichiometry matrix 1 4") !=
987 <<
"Failed with unexpected error message: " << msg;
992 TEST(GeochemistryKineticRateCalculatorTest, rate1)
1000 std::vector<Real> promoting_indices(5 + 7, 0.0);
1001 const std::vector<std::string> basis_name = {
"H2O",
"H+",
"HCO3-",
"O2(aq)",
"Ca++"};
1002 const std::vector<bool> basis_species_gas = {
false,
false,
false,
true,
false};
1003 std::vector<Real> basis_molality = {1.5, 2.0, 3.0, 4.0, 5.0};
1004 const std::vector<Real> basis_activity = {0.1, 0.2, 0.3, 0.4, 0.5};
1005 const std::vector<bool> basis_activity_known = {
false,
false,
false,
true,
true};
1006 const std::vector<std::string> eqm_name = {
"OH-",
"n2",
"n3",
"n4",
"n5",
"n6",
"n7"};
1007 const std::vector<bool> eqm_species_gas = {
false,
false,
false,
true,
false,
false,
false};
1008 const std::vector<Real> eqm_molality = {1.5, 2.5, 2.3, 2.1, 1.9, 1.7, 1.3};
1009 const std::vector<Real> eqm_activity = {1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7};
1015 std::vector<Real> drate_dmol(5, 1.0);
1018 std::vector<Real>(12, 0),
1019 std::vector<Real>(12, 0),
1025 basis_activity_known,
1042 -1.5 * 2.0 * 1.25 * 2.25 *
1047 EXPECT_NEAR(drate_dkin,
1053 for (
unsigned i = 0; i < 5; ++i)
1054 ASSERT_EQ(drate_dmol[i], 0.0);
1059 std::vector<Real>(12, 0),
1060 std::vector<Real>(12, 0),
1066 basis_activity_known,
1082 EXPECT_EQ(rate, 0.0);
1083 EXPECT_EQ(drate_dkin, 0.0);
1084 for (
unsigned i = 0; i < 5; ++i)
1085 ASSERT_EQ(drate_dmol[i], 0.0);
1089 std::vector<Real>(12, 0),
1090 std::vector<Real>(12, 0),
1096 basis_activity_known,
1113 1.5 * 2.0 * 1.25 * 2.25 *
1118 EXPECT_NEAR(drate_dkin,
1124 for (
unsigned i = 0; i < 5; ++i)
1125 ASSERT_EQ(drate_dmol[i], 0.0);
1130 std::vector<Real>(12, 0),
1131 std::vector<Real>(12, 0),
1137 basis_activity_known,
1154 -1.5 * 2.0 * 1.25 * 2.25 *
1159 EXPECT_NEAR(drate_dkin,
1165 for (
unsigned i = 0; i < 5; ++i)
1166 ASSERT_EQ(drate_dmol[i], 0.0);
1171 std::vector<Real>(12, 0),
1172 std::vector<Real>(12, 0),
1178 basis_activity_known,
1194 EXPECT_EQ(rate, 0.0);
1195 EXPECT_EQ(drate_dkin, 0.0);
1196 for (
unsigned i = 0; i < 5; ++i)
1197 ASSERT_EQ(drate_dmol[i], 0.0);
1201 std::vector<Real>(12, 0),
1202 std::vector<Real>(12, 0),
1208 basis_activity_known,
1225 1.5 * 2.0 * 1.25 * 2.25 *
1230 EXPECT_NEAR(drate_dkin,
1236 for (
unsigned i = 0; i < 5; ++i)
1237 ASSERT_EQ(drate_dmol[i], 0.0);
1241 std::vector<Real>(12, 0),
1242 std::vector<Real>(12, 0),
1248 basis_activity_known,
1265 1.5 * 2.0 * 1.25 * 2.25 *
1270 EXPECT_NEAR(drate_dkin,
1276 for (
unsigned i = 0; i < 5; ++i)
1277 ASSERT_EQ(drate_dmol[i], 0.0);
1280 std::vector<Real>(12, 0),
1281 std::vector<Real>(12, 0),
1287 basis_activity_known,
1304 1.5 * 2.0 * 1.25 * 2.25 *
1309 EXPECT_NEAR(drate_dkin,
1315 for (
unsigned i = 0; i < 5; ++i)
1316 ASSERT_EQ(drate_dmol[i], 0.0);
1318 for (
unsigned i = 0; i < 5; ++i)
1319 promoting_indices[i] = 0.5 * (i + 1);
1321 std::vector<Real>(12, 0),
1322 std::vector<Real>(12, 0),
1328 basis_activity_known,
1351 EXPECT_EQ(drate_dkin, 0.0);
1352 EXPECT_NEAR(drate_dmol[0], 0.5 * rate / 1.5, 1.0E-6);
1353 EXPECT_NEAR(drate_dmol[1], 1.0 * rate / 2.0, 1.0E-6);
1354 EXPECT_NEAR(drate_dmol[2], 1.5 * rate / 3.0, 1.0E-6);
1355 EXPECT_EQ(drate_dmol[3], 0.0);
1356 EXPECT_NEAR(drate_dmol[4], 2.5 * rate / 5.0, 1.0E-6);
1358 for (
unsigned i = 5; i < 12; ++i)
1359 promoting_indices[i] = -0.1 * (i + 1);
1361 std::vector<Real>(12, 0),
1362 std::vector<Real>(12, 0),
1368 basis_activity_known,
1393 EXPECT_EQ(drate_dkin, 0.0);
1394 EXPECT_NEAR(drate_dmol[0], 0.5 * rate / 1.5, 1.0E-6);
1395 EXPECT_NEAR(drate_dmol[1], 1.0 * rate / 2.0, 1.0E-6);
1396 EXPECT_NEAR(drate_dmol[2], 1.5 * rate / 3.0, 1.0E-6);
1397 EXPECT_EQ(drate_dmol[3], 0.0);
1398 EXPECT_NEAR(drate_dmol[4], 2.5 * rate / 5.0, 1.0E-6);
1401 eqm_stoichiometry(0, 0) = 1.0;
1402 eqm_stoichiometry(0, 1) = -1.25;
1403 eqm_stoichiometry(0, 2) = 1.5;
1404 eqm_stoichiometry(0, 3) = 3.5;
1405 eqm_stoichiometry(3, 0) = 2.0;
1406 eqm_stoichiometry(3, 1) = -2.25;
1407 eqm_stoichiometry(3, 2) = -2.5;
1408 eqm_stoichiometry(3, 3) = -33.5;
1410 std::vector<Real>(12, 0),
1411 std::vector<Real>(12, 0),
1417 basis_activity_known,
1442 EXPECT_EQ(drate_dkin, 0.0);
1443 EXPECT_NEAR(drate_dmol[0], 0.5 * rate / 1.5, 1.0E-6);
1444 EXPECT_NEAR(drate_dmol[1],
1445 1.0 * rate / 2.0 - 0.6 * (-1.25) * rate / 2.0 - 0.9 * (-2.25) * rate / 2.0,
1447 EXPECT_NEAR(drate_dmol[2],
1448 1.5 * rate / 3.0 - 0.6 * (1.5) * rate / 3.0 - 0.9 * (-2.5) * rate / 3.0,
1450 EXPECT_EQ(drate_dmol[3], 0.0);
1451 EXPECT_NEAR(drate_dmol[4], 2.5 * rate / 5.0, 1.0E-6);
1454 eqm_stoichiometry.
zero();
1455 kin_stoichiometry(0, 0) = -1.0;
1456 kin_stoichiometry(0, 1) = 1.25;
1457 kin_stoichiometry(0, 2) = -1.5;
1458 kin_stoichiometry(0, 3) = 1.75;
1459 kin_stoichiometry(1, 1) = -11.0;
1461 std::vector<Real>(12, 0),
1462 std::vector<Real>(12, 0),
1468 basis_activity_known,
1490 std::pow(std::abs(1 - theta_term), 0.8) *
1494 EXPECT_EQ(drate_dkin, 0.0);
1495 EXPECT_NEAR(drate_dmol[0], 0.5 * rate / 1.5, 1.0E-6);
1496 EXPECT_NEAR(drate_dmol[1],
1498 0.8 * rate / std::abs(1 - theta_term) * (-1) * (-2.5) * theta_term * 1.25 / 2.0,
1500 EXPECT_NEAR(drate_dmol[2],
1502 0.8 * rate / std::abs(1 - theta_term) * (-1) * (-2.5) * theta_term * (-1.5 / 3.0),
1504 EXPECT_EQ(drate_dmol[3], 0.0);
1505 EXPECT_NEAR(drate_dmol[4], 2.5 * rate / 5.0, 1.0E-6);
1512 std::vector<Real>(12, 0),
1513 std::vector<Real>(12, 0),
1519 basis_activity_known,
1536 basis_molality[2] +=
eps;
1541 std::vector<Real>(12, 0),
1542 std::vector<Real>(12, 0),
1548 basis_activity_known,
1564 EXPECT_NEAR(drate_dmol[2], (rate_new - rate) /
eps, 1E-5);
1568 TEST(GeochemistryKineticRateCalculatorTest, rate_monod)
1573 std::vector<Real> promoting_indices(5 + 7, 0.0);
1574 std::vector<Real> promoting_monod(5 + 7, 0.0);
1575 std::vector<Real> half_saturation(5 + 7, 0.0);
1576 const std::vector<std::string> basis_name = {
"H2O",
"H+",
"HCO3-",
"O2(aq)",
"Ca++"};
1577 const std::vector<bool> basis_species_gas = {
false,
false,
false,
true,
false};
1578 const std::vector<Real> basis_molality = {1.5, 2.0, 3.0, 4.0, 5.0};
1579 const std::vector<Real> basis_activity = {0.1, 0.2, 0.3, 0.4, 0.5};
1580 const std::vector<bool> basis_activity_known = {
false,
false,
false,
true,
true};
1581 const std::vector<std::string> eqm_name = {
"OH-",
"n2",
"n3",
"n4",
"n5",
"n6",
"n7"};
1582 const std::vector<bool> eqm_species_gas = {
false,
false,
false,
true,
false,
false,
false};
1583 std::vector<Real> eqm_molality = {1.5, 2.5, 2.3, 2.1, 1.9, 1.7, 1.3};
1584 std::vector<Real> eqm_activity = {1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7};
1590 std::vector<Real> drate_dmol(5, 1.0);
1594 std::vector<Real>(12, 0),
1595 std::vector<Real>(12, 0),
1601 basis_activity_known,
1618 -1.5 * 2.0 * 1.25 * 2.25 *
std::pow(1.25 / 1.5, 1.75) /
1624 EXPECT_NEAR(drate_dkin,
1628 1.25 * 1.75 *
std::pow(1.25 / 1.5, 1.75 - 1.0) / 1.5 /
1630 1.25 *
std::pow(1.25 / 1.5, 1.75) * (-2.125) /
1632 1.75 *
std::pow(1.25 / 1.5, 1.75 - 1.0) / 1.5) *
1637 EXPECT_NEAR(drate_dmol[0],
1638 -1.5 * 2.0 * 1.25 * 2.25 *
1639 (1.75 *
std::pow(1.25 / 1.5, 1.75 - 1.0) * (-1.25 / 1.5 / 1.5) /
1641 std::pow(1.25 / 1.5, 1.75) * (-2.125) /
1643 1.75 *
std::pow(1.25 / 1.5, 1.75 - 1.0) * (-1.25 / 1.5 / 1.5)) *
1648 for (
unsigned i = 1; i < 5; ++i)
1649 ASSERT_EQ(drate_dmol[i], 0.0);
1652 for (
unsigned i = 0; i < 5; ++i)
1654 promoting_indices[i] = 0.5 * (i + 1);
1655 promoting_monod[i] = 0.25 * i;
1656 half_saturation[i] = 0.125 * i;
1666 basis_activity_known,
1693 EXPECT_EQ(drate_dkin, 0.0);
1694 EXPECT_NEAR(drate_dmol[0], 0.5 * rate / 1.5, 1.0E-6);
1695 EXPECT_NEAR(drate_dmol[1],
1696 1.0 * rate / 2.0 + (-0.25) / (
std::pow(0.2, 1.0) +
std::pow(0.125, 1.0)) * rate *
1697 1.0 *
std::pow(0.2, 1.0 - 1.0) * 0.2 / 2.0,
1699 EXPECT_NEAR(drate_dmol[2],
1700 1.5 * rate / 3.0 + (-0.5) / (
std::pow(3.0, 1.5) +
std::pow(0.25, 1.5)) * rate * 1.5 *
1703 EXPECT_EQ(drate_dmol[3], 0.0);
1704 EXPECT_NEAR(drate_dmol[4],
1705 2.5 * rate / 5.0 + (-1.0) / (
std::pow(5.0, 2.5) +
std::pow(0.5, 2.5)) * rate * 2.5 *
1710 for (
unsigned i = 5; i < 12; ++i)
1712 promoting_indices[i] = -0.1 * (i + 1);
1713 promoting_monod[i] = 0.25 * i;
1714 half_saturation[i] = 0.125 * i;
1724 basis_activity_known,
1758 EXPECT_EQ(drate_dkin, 0.0);
1759 EXPECT_NEAR(drate_dmol[0], 0.5 * rate / 1.5, 1.0E-6);
1760 EXPECT_NEAR(drate_dmol[1],
1761 1.0 * rate / 2.0 + (-0.25) / (
std::pow(0.2, 1.0) +
std::pow(0.125, 1.0)) * rate *
1762 1.0 *
std::pow(0.2, 1.0 - 1.0) * 0.2 / 2.0,
1764 EXPECT_NEAR(drate_dmol[2],
1765 1.5 * rate / 3.0 + (-0.5) / (
std::pow(3.0, 1.5) +
std::pow(0.25, 1.5)) * rate * 1.5 *
1768 EXPECT_EQ(drate_dmol[3], 0.0);
1769 EXPECT_NEAR(drate_dmol[4],
1770 2.5 * rate / 5.0 + (-1.0) / (
std::pow(5.0, 2.5) +
std::pow(0.5, 2.5)) * rate * 2.5 *
1777 for (
unsigned i = 0; i < 5; ++i)
1781 if (basis_species_gas[i])
1785 std::vector<Real> fd_basis_molality = basis_molality;
1786 std::vector<Real> fd_basis_activity =
1796 basis_activity_known,
1813 fd_basis_molality[i] +=
eps;
1814 fd_basis_activity = fd_basis_molality;
1823 basis_activity_known,
1839 const Real fd = (rate_new - rate) /
eps;
1840 EXPECT_TRUE(std::abs(drate_dmol[i] / fd - 1.0) < 1E-4);
1844 eqm_stoichiometry(0, 0) = 1.0;
1845 eqm_stoichiometry(0, 1) = -1.25;
1846 eqm_stoichiometry(0, 2) = 1.5;
1847 eqm_stoichiometry(0, 3) = 3.5;
1848 eqm_stoichiometry(1, 0) = 1.25;
1849 eqm_stoichiometry(1, 1) = 2.75;
1850 eqm_stoichiometry(1, 2) = 0.75;
1851 eqm_stoichiometry(1, 3) = -1.5;
1852 eqm_stoichiometry(3, 0) = 2.0;
1853 eqm_stoichiometry(3, 1) = -2.25;
1854 eqm_stoichiometry(3, 2) = -2.5;
1855 eqm_stoichiometry(3, 3) = -33.5;
1864 basis_activity_known,
1898 EXPECT_EQ(drate_dkin, 0.0);
1899 EXPECT_NEAR(drate_dmol[0], 0.5 * rate / 1.5, 1.0E-6);
1902 (1.0 * rate / 2.0 + (-0.25) / (
std::pow(0.2, 1.0) +
std::pow(0.125, 1.0)) * rate * 1.0 *
1903 std::pow(0.2, 1.0 - 1.0) * 0.2 / 2.0) +
1905 (-0.6 * rate / 2.0 + (-1.25) / (
std::pow(1.1, -0.6) +
std::pow(0.625, -0.6)) * rate *
1906 (-0.6) *
std::pow(1.1, -0.6 - 1.0) * 1.1 / 2.0)) +
1907 (2.75 * (-0.7 * rate / 2.0 + (-1.5) / (
std::pow(2.5, -0.7) +
std::pow(0.75, -0.7)) *
1908 rate * (-0.7) *
std::pow(2.5, -0.7 - 1.0) * 2.5 / 2.0)) +
1909 (-2.25 * (-0.9 * rate / 2.0 + (-2.0) / (
std::pow(1.4, -0.9) +
std::pow(1.0, -0.9)) *
1910 rate * (-0.9) *
std::pow(1.4, -0.9 - 1.0) * 1.4 / 2.0)),
1914 (1.5 * rate / 3.0 + (-0.5) / (
std::pow(3.0, 1.5) +
std::pow(0.25, 1.5)) * rate * 1.5 *
1917 (-0.6 * rate / 1.1 * 1.1 / 1.5 +
1919 std::pow(1.1, -0.6 - 1.0) * 1.1 / 1.5) *
1921 (0.75 * (-0.7 * rate / 3.0 + (-1.5) / (
std::pow(2.5, -0.7) +
std::pow(0.75, -0.7)) *
1922 rate * (-0.7) *
std::pow(2.5, -0.7 - 1.0) * 2.5 / 3.0)) +
1924 (-0.9 * rate / 1.4 + (-2.0) / (
std::pow(1.4, -0.9) +
std::pow(1.0, -0.9)) * rate *
1925 (-0.9) *
std::pow(1.4, -0.9 - 1.0)) *
1929 EXPECT_EQ(drate_dmol[3], 0.0);
1930 EXPECT_NEAR(drate_dmol[4],
1931 2.5 * rate / 5.0 + (-1.0) / (
std::pow(5.0, 2.5) +
std::pow(0.5, 2.5)) * rate * 2.5 *
1938 for (
unsigned i = 0; i < 5; ++i)
1942 if (basis_species_gas[i])
1946 std::vector<Real> fd_basis_molality = basis_molality;
1947 std::vector<Real> fd_basis_activity =
1949 for (
unsigned j = 0;
j < 7; ++
j)
1951 eqm_molality[
j] =
std::pow(fd_basis_activity[0], eqm_stoichiometry(
j, 0));
1952 for (
unsigned basis = 1; basis < 5; ++basis)
1954 if (basis_species_gas[basis])
1956 eqm_molality[
j] *=
std::pow(fd_basis_molality[basis], eqm_stoichiometry(
j, basis));
1959 eqm_activity = eqm_molality;
1968 basis_activity_known,
1985 fd_basis_molality[i] +=
eps;
1986 for (
unsigned basis = 1; basis < 5; ++basis)
1987 fd_basis_activity[basis] =
1988 fd_basis_molality[basis];
1990 for (
unsigned j = 0;
j < 7; ++
j)
1992 eqm_molality[
j] =
std::pow(fd_basis_activity[0], eqm_stoichiometry(
j, 0));
1993 for (
unsigned basis = 1; basis < 5; ++basis)
1995 if (basis_species_gas[basis])
1997 eqm_molality[
j] *=
std::pow(fd_basis_molality[basis], eqm_stoichiometry(
j, basis));
2000 eqm_activity = eqm_molality;
2009 basis_activity_known,
2025 const Real fd = (rate_new - rate) /
eps;
2026 EXPECT_TRUE(std::abs(drate_dmol[i] / fd - 1.0) < 1E-4);
2031 TEST(GeochemistryKineticRateCalculatorTest, rate_energy_captured)
2034 std::vector<Real> promoting_indices(5 + 7, 0.0);
2035 const std::vector<std::string> basis_name = {
"H2O",
"H+",
"HCO3-",
"O2(aq)",
"Ca++"};
2036 const std::vector<bool> basis_species_gas = {
false,
false,
false,
true,
false};
2037 const std::vector<Real> basis_molality = {1.5, 2.0, 3.0, 4.0, 5.0};
2038 const std::vector<Real> basis_activity = {0.1, 0.2, 0.3, 0.4, 0.5};
2039 const std::vector<bool> basis_activity_known = {
false,
false,
false,
true,
true};
2040 const std::vector<std::string> eqm_name = {
"OH-",
"n2",
"n3",
"n4",
"n5",
"n6",
"n7"};
2041 const std::vector<bool> eqm_species_gas = {
false,
false,
false,
true,
false,
false,
false};
2042 const std::vector<Real> eqm_molality = {1.5, 2.5, 2.3, 2.1, 1.9, 1.7, 1.3};
2043 const std::vector<Real> eqm_activity = {1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7};
2049 std::vector<Real> drate_dmol(5, 1.0);
2052 std::vector<Real>(12, 0),
2053 std::vector<Real>(12, 0),
2059 basis_activity_known,
2077 -1.5 * 2.0 * 1.25 * 2.25 *
2105 for (
unsigned i = 0; i < 5; ++i)
2106 ASSERT_EQ(drate_dmol[i], 0.0);
2110 TEST(GeochemistryKineticRateCalculatorTest, rate_eta_theta)
2117 std::vector<Real> promoting_indices(5 + 7, 0.0);
2118 const std::vector<std::string> basis_name = {
"H2O",
"H+",
"HCO3-",
"O2(aq)",
"Ca++"};
2119 const std::vector<bool> basis_species_gas = {
false,
false,
false,
true,
false};
2120 const std::vector<Real> basis_molality = {1.5, 2.0, 3.0, 4.0, 5.0};
2121 const std::vector<Real> basis_activity = {0.1, 0.2, 0.3, 0.4, 0.5};
2122 const std::vector<bool> basis_activity_known = {
false,
false,
false,
true,
true};
2123 const std::vector<std::string> eqm_name = {
"OH-",
"n2",
"n3",
"n4",
"n5",
"n6",
"n7"};
2124 const std::vector<bool> eqm_species_gas = {
false,
false,
false,
true,
false,
false,
false};
2125 const std::vector<Real> eqm_molality = {1.5, 2.5, 2.3, 2.1, 1.9, 1.7, 1.3};
2126 const std::vector<Real> eqm_activity = {1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7};
2132 std::vector<Real> drate_dmol(5, 1.0);
2134 for (
unsigned i = 0; i < 5; ++i)
2135 promoting_indices[i] = 0.5 * (i + 1);
2137 kin_stoichiometry(0, 0) = -1.0;
2138 kin_stoichiometry(0, 1) = 1.25;
2139 kin_stoichiometry(0, 2) = -1.5;
2140 kin_stoichiometry(0, 3) = 1.75;
2141 kin_stoichiometry(1, 1) = -11.0;
2142 kin_stoichiometry(1, 2) = 0.5;
2143 kin_stoichiometry(1, 3) = 4.0;
2147 std::vector<Real>(12, 0),
2148 std::vector<Real>(12, 0),
2154 basis_activity_known,
2170 EXPECT_EQ(rate, 0.0);
2171 EXPECT_EQ(drate_dkin, 0.0);
2172 EXPECT_NEAR(drate_dmol[0], 0.5 * rate / 1.5, 1.0E-6);
2173 EXPECT_NEAR(drate_dmol[1], 1.0 * rate / 2.0 + 0.0, 1E-6);
2174 EXPECT_NEAR(drate_dmol[2], 1.5 * rate / 3.0 + 0.0, 1E-6);
2175 EXPECT_EQ(drate_dmol[3], 0.0);
2176 EXPECT_NEAR(drate_dmol[4], 2.5 * rate / 5.0, 1.0E-6);
2180 std::vector<Real>(12, 0),
2181 std::vector<Real>(12, 0),
2187 basis_activity_known,
2203 EXPECT_EQ(rate, 0.0);
2204 EXPECT_EQ(drate_dkin, 0.0);
2205 for (
unsigned i = 0; i < 5; ++i)
2206 EXPECT_EQ(drate_dmol[i], 0.0);
2210 std::vector<Real>(12, 0),
2211 std::vector<Real>(12, 0),
2217 basis_activity_known,
2233 EXPECT_EQ(rate, 0.0);
2234 EXPECT_EQ(drate_dkin, 0.0);
2243 EXPECT_EQ(drate_dmol[0], 0.0);
2244 EXPECT_NEAR(drate_dmol[1], 0.0, 1E-6);
2245 EXPECT_NEAR(drate_dmol[2], 0.0, 1E-6);
2246 EXPECT_EQ(drate_dmol[3], 0.0);
2247 EXPECT_EQ(drate_dmol[4], 0.0);
2251 std::vector<Real>(12, 0),
2252 std::vector<Real>(12, 0),
2258 basis_activity_known,
2280 EXPECT_EQ(drate_dkin, 0.0);
2281 EXPECT_NEAR(drate_dmol[0], 0.5 * rate / 1.5, 1.0E-6);
2282 EXPECT_NEAR(drate_dmol[1], 1.0 * rate / 2.0 + 0.0, 1E-6);
2283 EXPECT_NEAR(drate_dmol[2], 1.5 * rate / 3.0 + 0.0, 1E-6);
2284 EXPECT_EQ(drate_dmol[3], 0.0);
2285 EXPECT_NEAR(drate_dmol[4], 2.5 * rate / 5.0, 1.0E-6);
2289 std::vector<Real>(12, 0),
2290 std::vector<Real>(12, 0),
2296 basis_activity_known,
2312 EXPECT_EQ(rate, 0.0);
2313 EXPECT_EQ(drate_dkin, 0.0);
2314 EXPECT_NEAR(drate_dmol[0], 0.5 * rate / 1.5, 1.0E-6);
2315 EXPECT_LE(drate_dmol[1], -std::numeric_limits<Real>::max());
2316 EXPECT_GE(drate_dmol[2], 0.1 * std::numeric_limits<Real>::max());
2317 EXPECT_EQ(drate_dmol[3], 0.0);
2318 EXPECT_NEAR(drate_dmol[4], 2.5 * rate / 5.0, 1.0E-6);
constexpr Real CELSIUS_TO_KELVIN
virtual void zero() override final
std::vector< bool > eqm_species_gas
eqm_species_gas[i] = true iff the i^th equilibrium species is a gas
DenseMatrix< Real > kin_stoichiometry
kin_stoichiometry(i, j) = stoichiometric coefficient for kinetic species "i" in terms of the basis sp...
KineticRateUserDescription rate_ch4_raw("CH4(aq)", 1.5, 2.0, true, 0.0, 0.0, 0.0, {"H2O", "OH-", "O2(aq)", "CO2(aq)", "CaCO3"}, {3.0, 3.1, 3.2, 3.3, 3.4}, {0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}, 0.8, 2.5, 66.0, 0.003, DirectionChoiceEnum::RAW, "H2O", 0.0, -1.0, 0.0)
KineticRateUserDescription rate_cal_theta0_eta0("Calcite", 7.0, 6.0, false, 0.0, 0.0, 0.0, {"H+"}, {-3.0}, {0.0}, {0.0}, 0.0, 0.0, 55.0, 0.00315, DirectionChoiceEnum::BOTH, "H2O", 0.0, -1.0, 0.0)
void calculateRate(const std::vector< Real > &promoting_indices, const std::vector< Real > &promoting_monod_indices, const std::vector< Real > &promoting_half_saturation, const KineticRateUserDescription &description, const std::vector< std::string > &basis_species_name, const std::vector< bool > &basis_species_gas, const std::vector< Real > &basis_molality, const std::vector< Real > &basis_activity, const std::vector< bool > &basis_activity_known, const std::vector< std::string > &eqm_species_name, const std::vector< bool > &eqm_species_gas, const std::vector< Real > &eqm_molality, const std::vector< Real > &eqm_activity, const DenseMatrix< Real > &eqm_stoichiometry, Real kin_moles, Real kin_species_molecular_weight, Real log10K, Real log10_activity_product, const DenseMatrix< Real > &kin_stoichiometry, unsigned kin, Real temp_degC, Real &rate, Real &drate_dkin, std::vector< Real > &drate_dmol)
Calclates a kinetic rate and its derivative.
KineticRateUserDescription rate_ch4_kin_mon("CH4(aq)", 1.5, 2.0, true, 1.75, 2.125, 0.875, {"H2O", "OH-", "O2(aq)", "CO2(aq)", "CaCO3"}, {3.0, 3.1, 3.2, 3.3, 3.4}, {0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}, 0.8, 2.5, 66.0, 0.003, DirectionChoiceEnum::BOTH, "H2O", 0.0, -1.0, 0.0)
DenseMatrix< Real > eqm_stoichiometry
eqm_stoichiometry(i, j) = stoichiometric coefficient for equilibrium species "i" in terms of the basi...
KineticRateUserDescription rate_ch4("CH4(aq)", 1.5, 2.0, true, 0.0, 0.0, 0.0, {"H2O", "OH-", "O2(aq)", "CO2(aq)", "CaCO3"}, {3.0, 3.1, 3.2, 3.3, 3.4}, {0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}, 0.8, 2.5, 66.0, 0.003, DirectionChoiceEnum::BOTH, "H2O", 0.0, -1.0, 0.0)
const ModelGeochemicalDatabase & mgd_kin
PertinentGeochemicalSystem model_kin(db_kin, {"H2O", "H+", "HCO3-", "O2(aq)", "Ca++"}, {}, {}, {"Calcite"}, {"CH4(aq)"}, {}, "O2(aq)", "e-")
const ModelGeochemicalDatabase & modelGeochemicalDatabase() const
Return a reference to the ModelGeochemicalDatabase structure.
void addKineticRate(const KineticRateUserDescription &description)
Adds a rate description for kinetic_species.
Constructs and stores a minimal amount of information that is pertinent to the user-defined geochemic...
KineticRateUserDescription rate_cal_theta2_eta1("Calcite", 7.0, 6.0, false, 0.0, 0.0, 0.0, {"H+"}, {-3.0}, {0.0}, {0.0}, 2.0, 1.0, 55.0, 0.00315, DirectionChoiceEnum::BOTH, "H2O", 0.0, -1.0, 0.0)
KineticRateUserDescription rate_cal_theta0_eta05("Calcite", 7.0, 6.0, false, 0.0, 0.0, 0.0, {"H+"}, {-3.0}, {0.0}, {0.0}, 0.0, 0.5, 55.0, 0.00315, DirectionChoiceEnum::BOTH, "H2O", 0.0, -1.0, 0.0)
TEST(KineticRateUserDescriptionTest, exceptions)
Test exceptions in KineticRateUserDescription.
KineticRateUserDescription rate_cal("Calcite", 7.0, 6.0, false, 0.0, 0.0, 0.0, {"H+"}, {-3.0}, {0.0}, {0.0}, 2.5, 0.8, 55.0, 0.00315, DirectionChoiceEnum::BOTH, "H2O", 0.0, -1.0, 0.0)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const GeochemicalDatabaseReader db_kin("database/moose_testdb.json")
constexpr Real GAS_CONSTANT
Holds a user-specified description of a kinetic rate.
std::vector< bool > basis_species_gas
basis_species_gas[j] = true iff the j^th basis species is a gas
Data structure to hold all relevant information from the database file.
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
KineticRateUserDescription rate_ch4_death("CH4(aq)", 1.5, 2.0, true, 0.0, 0.0, 0.0, {"H2O", "OH-", "O2(aq)", "CO2(aq)", "CaCO3"}, {3.0, 3.1, 3.2, 3.3, 3.4}, {0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}, 0.8, 2.5, 66.0, 0.003, DirectionChoiceEnum::DEATH, "H2O", 0.0, -1.0, 0.0)
KineticRateUserDescription rate_ch4_precipitation("CH4(aq)", 1.5, 2.0, true, 0.0, 0.0, 0.0, {"H2O", "OH-", "O2(aq)", "CO2(aq)", "CaCO3"}, {3.0, 3.1, 3.2, 3.3, 3.4}, {0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}, 0.8, 2.5, 66.0, 0.003, DirectionChoiceEnum::PRECIPITATION, "H2O", 0.0, -1.0, 0.0)
KineticRateUserDescription rate_ch4_dissolution("CH4(aq)", 1.5, 2.0, true, 0.0, 0.0, 0.0, {"H2O", "OH-", "O2(aq)", "CO2(aq)", "CaCO3"}, {3.0, 3.1, 3.2, 3.3, 3.4}, {0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}, 0.8, 2.5, 66.0, 0.003, DirectionChoiceEnum::DISSOLUTION, "H2O", 0.0, -1.0, 0.0)
KineticRateUserDescription rate_cal_theta0_eta1("Calcite", 7.0, 6.0, false, 0.0, 0.0, 0.0, {"H+"}, {-3.0}, {0.0}, {0.0}, 0.0, 1.0, 55.0, 0.00315, DirectionChoiceEnum::BOTH, "H2O", 0.0, -1.0, 0.0)
MooseUnits pow(const MooseUnits &, int)
KineticRateUserDescription rate_ch4_energy_captured("CH4(aq)", 1.5, 2.0, true, 0.0, 0.0, 0.0, {"H2O", "OH-", "O2(aq)", "CO2(aq)", "CaCO3"}, {3.0, 3.1, 3.2, 3.3, 3.4}, {0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}, 0.8, 2.5, 66.0, 0.003, DirectionChoiceEnum::BOTH, "H2O", 0.0, -1.0, 1.0)
std::vector< std::string > eqm_species_name
eqm_species_name[i] = name of the i^th eqm species
Class for reading geochemical reactions from a MOOSE geochemical database.
KineticRateUserDescription rate_cal_theta0_eta2("Calcite", 7.0, 6.0, false, 0.0, 0.0, 0.0, {"H+"}, {-3.0}, {0.0}, {0.0}, 0.0, 2.0, 55.0, 0.00315, DirectionChoiceEnum::BOTH, "H2O", 0.0, -1.0, 0.0)