-
-
Notifications
You must be signed in to change notification settings - Fork 346
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add RedlichKister tests and sample case for LiC6 electrode
See #293
- Loading branch information
1 parent
125d2e0
commit 1183479
Showing
5 changed files
with
389 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#include "cantera/thermo.h" | ||
#include "cantera/thermo/RedlichKisterVPSSTP.h" | ||
#include <fstream> | ||
|
||
using namespace Cantera; | ||
|
||
void calc_potentials() | ||
{ | ||
suppress_deprecation_warnings(); | ||
double Tk = 273.15 + 25.0; | ||
|
||
std::string filename = "LiC6_electrodebulk.xml"; | ||
std::string phasename = "LiC6_and_Vacancies"; | ||
std::unique_ptr<ThermoPhase> electrodebulk(newPhase(filename,phasename)); | ||
std::string intercalatingSpeciesName("Li(C6)"); | ||
size_t intercalatingSpeciesIdx = electrodebulk->speciesIndex(intercalatingSpeciesName); | ||
size_t nsp_tot = electrodebulk->nSpecies(); | ||
|
||
std::ofstream fout("potentials_output.dat", std::ofstream::out); | ||
fout << "x[LiC6] ChemPotential[LiC6] ChemPotential[C6] Uref ActCoeff[LiC6] ActCoeff[C6] dlnActCoeffdx[LiC6] dlnActCoeffdx[C6]" << std::endl; | ||
|
||
vector_fp spvals(nsp_tot); | ||
vector_fp actCoeff(nsp_tot); | ||
vector_fp dlnActCoeffdlnX_diag(nsp_tot); | ||
double xmin = 0.6; | ||
double xmax = 0.9; | ||
|
||
int numSteps = 9; | ||
double dx = (xmax-xmin)/(numSteps-1); | ||
|
||
size_t nsp_electrodeBulk = electrodebulk->nSpecies(); | ||
vector_fp xv(nsp_electrodeBulk, 0.0); | ||
|
||
for (int i = 0; i < numSteps; ++i) { | ||
double x = xmin + i*dx; | ||
|
||
vector_fp xv(nsp_electrodeBulk, 0.0); | ||
//Set the fraction of intercalted lithium | ||
xv[intercalatingSpeciesIdx] = x; | ||
|
||
//Set so that mole fractions sum to 1 | ||
for (size_t j = 0; j < nsp_electrodeBulk; ++j) { | ||
if (j != intercalatingSpeciesIdx) { | ||
xv[j] = (1.0 - xv[intercalatingSpeciesIdx]); | ||
} | ||
} | ||
|
||
electrodebulk->setState_TX(Tk, &xv[0]); | ||
electrodebulk->getChemPotentials(spvals.data()); | ||
|
||
//Calulate the open circuit potential | ||
double Uref = (spvals[1] - spvals[0])/Faraday; | ||
|
||
electrodebulk->getdlnActCoeffdlnX_diag(dlnActCoeffdlnX_diag.data()); | ||
electrodebulk->getActivityCoefficients(actCoeff.data()); | ||
|
||
fout << fmt::format("{} {} {} {} {} {} {} {}\n", | ||
xv[0], spvals[0], spvals[1], Uref, actCoeff[0], | ||
actCoeff[1], dlnActCoeffdlnX_diag[0], dlnActCoeffdlnX_diag[1]); | ||
} | ||
} | ||
|
||
int main(int argc, char** argv) | ||
{ | ||
try { | ||
calc_potentials(); | ||
return 0; | ||
} catch (CanteraError& err) { | ||
std::cout << err.what() << std::endl; | ||
return 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?xml version="1.0"?> | ||
<ctml> | ||
<validate reactions="yes" species="yes"/> | ||
|
||
<!-- phase LiC6_and_Vacancies --> | ||
<phase dim="3" id="LiC6_and_Vacancies"> | ||
<elementArray datasrc="elements.xml"> Li C </elementArray> | ||
<speciesArray datasrc="#species_data">Li(C6) V(C6)</speciesArray> | ||
<state> | ||
<temperature units="K">298.15</temperature> | ||
<pressure units="Pa">101325.0</pressure> | ||
<moleFractions>Li(C6):0.6,V(C6):0.4</moleFractions> | ||
</state> | ||
<thermo model="Redlich-Kister"> | ||
<density units="kg/m3">2000.0</density> | ||
|
||
<activityCoefficients model="Redlich-Kister"> | ||
|
||
<binaryNeutralSpeciesParameters speciesA="Li(C6)" speciesB="V(C6)"> | ||
<excessEnthalpy terms="15" units="J/kmol"> | ||
-3.268E6, | ||
3.955E6, | ||
-4.573E6, | ||
6.147E6, | ||
-3.339E6, | ||
1.117E7, | ||
2.997E5, | ||
-4.866E7, | ||
1.362E5, | ||
1.373E8, | ||
-2.129E7, | ||
-1.722E8, | ||
3.956E7, | ||
9.302E7, | ||
-3.280E7 | ||
</excessEnthalpy> | ||
<excessEntropy terms="1" units="J/kmol/K"> | ||
0.0 | ||
</excessEntropy> | ||
</binaryNeutralSpeciesParameters> | ||
|
||
</activityCoefficients> | ||
|
||
</thermo> | ||
<transport model="None"/> | ||
<kinetics model="none"/> | ||
</phase> | ||
|
||
|
||
<!-- species definitions --> | ||
<speciesData id="species_data"> | ||
|
||
<!-- species Li(C6) --> | ||
<species name="Li(C6)"> | ||
<atomArray>C:6 Li:1 </atomArray> | ||
<thermo> | ||
<const_cp Tmax="5000.0" Tmin="100.0"> | ||
<t0 units="K">298.15</t0> | ||
<h0 units="kJ/mol">-11.65</h0> | ||
<s0 units="J/mol/K">0.0</s0> | ||
<cp0 units="J/mol/K">0.0</cp0> | ||
</const_cp> | ||
</thermo> | ||
</species> | ||
|
||
<!-- species V(C6) --> | ||
<species name="V(C6)"> | ||
<atomArray>C:6 </atomArray> | ||
<thermo> | ||
<const_cp Tmax="5000.0" Tmin="100.0"> | ||
<t0 units="K">298.15</t0> | ||
<h0 units="kJ/mol">0.0</h0> | ||
<s0 units="J/mol/K">0.0</s0> | ||
<cp0 units="J/mol/K">0.0</cp0> | ||
</const_cp> | ||
</thermo> | ||
</species> | ||
</speciesData> | ||
<reactionData id="reaction_data"/> | ||
</ctml> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
x[LiC6] ChemPotential[LiC6] ChemPotential[C6] Uref ActCoeff[LiC6] ActCoeff[C6] dlnActCoeffdx[LiC6] dlnActCoeffdx[C6] | ||
0.6 -1.27915e+07 -4.0265e+06 0.0908429 1.05164 0.492638 0.0907127 0.0907127 | ||
0.6375 -1.26186e+07 -4.30768e+06 0.0861362 1.0613 0.48531 0.200612 0.200612 | ||
0.675 -1.24454e+07 -4.63856e+06 0.0809124 1.07484 0.473671 0.229316 0.229316 | ||
0.7125 -1.22826e+07 -5.00757e+06 0.0754005 1.08739 0.461396 0.193278 0.193278 | ||
0.75 -1.21341e+07 -5.41192e+06 0.0696706 1.0968 0.450748 0.142257 0.142257 | ||
0.7875 -1.19995e+07 -5.85996e+06 0.0636315 1.10287 0.442609 0.0766133 0.0766133 | ||
0.825 -1.18827e+07 -6.34599e+06 0.0573836 1.10353 0.441766 -0.0712113 -0.0712113 | ||
0.8625 -1.1793e+07 -6.82907e+06 0.0514475 1.09443 0.462697 -0.309379 -0.309379 | ||
0.9 -1.17309e+07 -7.28939e+06 0.046033 1.07544 0.528389 -0.492206 -0.492206 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?xml version="1.0"?> | ||
<ctml> | ||
<validate reactions="yes" species="yes"/> | ||
|
||
<!-- phase LiC6_and_Vacancies --> | ||
<phase dim="3" id="LiC6_and_Vacancies"> | ||
<elementArray datasrc="elements.xml"> Li C </elementArray> | ||
<speciesArray datasrc="#species_data">Li(C6) V(C6)</speciesArray> | ||
<state> | ||
<temperature units="K">298.15</temperature> | ||
<pressure units="Pa">101325.0</pressure> | ||
<moleFractions>Li(C6):0.6,V(C6):0.4</moleFractions> | ||
</state> | ||
<thermo model="Redlich-Kister"> | ||
<density units="kg/m3">2000.0</density> | ||
|
||
<activityCoefficients model="Redlich-Kister"> | ||
|
||
<binaryNeutralSpeciesParameters speciesA="Li(C6)" speciesB="V(C6)"> | ||
<excessEnthalpy terms="15" units="J/kmol"> | ||
-3.268E6, | ||
3.955E6, | ||
-4.573E6, | ||
6.147E6, | ||
-3.339E6, | ||
1.117E7, | ||
2.997E5, | ||
-4.866E7, | ||
1.362E5, | ||
1.373E8, | ||
-2.129E7, | ||
-1.722E8, | ||
3.956E7, | ||
9.302E7, | ||
-3.280E7 | ||
</excessEnthalpy> | ||
<excessEntropy terms="1" units="J/kmol/K"> | ||
0.0 | ||
</excessEntropy> | ||
</binaryNeutralSpeciesParameters> | ||
|
||
</activityCoefficients> | ||
|
||
</thermo> | ||
<transport model="None"/> | ||
<kinetics model="none"/> | ||
</phase> | ||
|
||
|
||
<!-- species definitions --> | ||
<speciesData id="species_data"> | ||
|
||
<!-- species Li(C6) --> | ||
<species name="Li(C6)"> | ||
<atomArray>C:6 Li:1 </atomArray> | ||
<thermo> | ||
<const_cp Tmax="5000.0" Tmin="100.0"> | ||
<t0 units="K">298.15</t0> | ||
<h0 units="kJ/mol">-11.65</h0> | ||
<s0 units="J/mol/K">0.0</s0> | ||
<cp0 units="J/mol/K">0.0</cp0> | ||
</const_cp> | ||
</thermo> | ||
</species> | ||
|
||
<!-- species V(C6) --> | ||
<species name="V(C6)"> | ||
<atomArray>C:6 </atomArray> | ||
<thermo> | ||
<const_cp Tmax="5000.0" Tmin="100.0"> | ||
<t0 units="K">298.15</t0> | ||
<h0 units="kJ/mol">0.0</h0> | ||
<s0 units="J/mol/K">0.0</s0> | ||
<cp0 units="J/mol/K">0.0</cp0> | ||
</const_cp> | ||
</thermo> | ||
</species> | ||
</speciesData> | ||
<reactionData id="reaction_data"/> | ||
</ctml> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
#include "gtest/gtest.h" | ||
#include "cantera/thermo/RedlichKisterVPSSTP.h" | ||
#include "cantera/thermo/ThermoFactory.h" | ||
|
||
namespace Cantera | ||
{ | ||
|
||
class RedlichKister_Test : public testing::Test | ||
{ | ||
public: | ||
RedlichKister_Test() { | ||
test_phase.reset(newPhase("../data/RedlichKisterVPSSTP_valid.xml")); | ||
} | ||
|
||
void set_r(const double r) { | ||
vector_fp moleFracs(2); | ||
moleFracs[0] = r; | ||
moleFracs[1] = 1-r; | ||
test_phase->setMoleFractions(&moleFracs[0]); | ||
} | ||
|
||
std::unique_ptr<ThermoPhase> test_phase; | ||
}; | ||
|
||
TEST_F(RedlichKister_Test, construct_from_xml) | ||
{ | ||
RedlichKisterVPSSTP* redlich_kister_phase = dynamic_cast<RedlichKisterVPSSTP*>(test_phase.get()); | ||
EXPECT_TRUE(redlich_kister_phase != NULL); | ||
} | ||
|
||
TEST_F(RedlichKister_Test, chem_potentials) | ||
{ | ||
test_phase->setState_TP(298.15, 101325.); | ||
|
||
const double expected_result[9] = { | ||
-1.2791500420236044e+007, | ||
-1.2618554504124604e+007, | ||
-1.2445418272766629e+007, | ||
-1.2282611679165890e+007, | ||
-1.2134110753109487e+007, | ||
-1.1999465396970615e+007, | ||
-1.1882669410525253e+007, | ||
-1.1792994839484975e+007, | ||
-1.1730895987035934e+007 | ||
}; | ||
|
||
double xmin = 0.6; | ||
double xmax = 0.9; | ||
int numSteps = 9; | ||
double dx = (xmax-xmin)/(numSteps-1); | ||
vector_fp chemPotentials(2); | ||
for(int i=0; i < 9; ++i) | ||
{ | ||
set_r(xmin + i*dx); | ||
test_phase->getChemPotentials(&chemPotentials[0]); | ||
EXPECT_NEAR(expected_result[i], chemPotentials[0], 1.e-6); | ||
} | ||
} | ||
|
||
TEST_F(RedlichKister_Test, dlnActivities) | ||
{ | ||
test_phase->setState_TP(298.15, 101325.); | ||
|
||
const double expected_result[9] = { | ||
0.0907127, | ||
0.200612, | ||
0.229316, | ||
0.193278, | ||
0.142257, | ||
0.0766133, | ||
-0.0712113, | ||
-0.309379, | ||
-0.492206 | ||
}; | ||
|
||
double xmin = 0.6; | ||
double xmax = 0.9; | ||
int numSteps = 9; | ||
double dx = (xmax-xmin)/(numSteps-1); | ||
vector_fp dlnActCoeffdx(2); | ||
for(int i=0; i < 9; ++i) | ||
{ | ||
const double r = xmin + i*dx; | ||
set_r(r); | ||
test_phase->getdlnActCoeffdlnX_diag(&dlnActCoeffdx[0]); | ||
EXPECT_NEAR(expected_result[i], dlnActCoeffdx[0], 1.e-6); | ||
} | ||
} | ||
|
||
TEST_F(RedlichKister_Test, activityCoeffs) | ||
{ | ||
test_phase->setState_TP(298., 1.); | ||
|
||
// Test that mu0 + RT log(activityCoeff * MoleFrac) == mu | ||
const double RT = GasConstant * 298.; | ||
vector_fp mu0(2); | ||
vector_fp activityCoeffs(2); | ||
vector_fp chemPotentials(2); | ||
double xmin = 0.6; | ||
double xmax = 0.9; | ||
int numSteps = 9; | ||
double dx = (xmax-xmin)/(numSteps-1); | ||
|
||
for(int i=0; i < numSteps; ++i) | ||
{ | ||
const double r = xmin + i*dx; | ||
set_r(r); | ||
test_phase->getChemPotentials(&chemPotentials[0]); | ||
test_phase->getActivityCoefficients(&activityCoeffs[0]); | ||
test_phase->getStandardChemPotentials(&mu0[0]); | ||
EXPECT_NEAR(chemPotentials[0], mu0[0] + RT*std::log(activityCoeffs[0] * r), 1.e-6); | ||
EXPECT_NEAR(chemPotentials[1], mu0[1] + RT*std::log(activityCoeffs[1] * (1-r)), 1.e-6); | ||
} | ||
} | ||
|
||
TEST_F(RedlichKister_Test, standardConcentrations) | ||
{ | ||
EXPECT_DOUBLE_EQ(1.0, test_phase->standardConcentration(0)); | ||
EXPECT_DOUBLE_EQ(1.0, test_phase->standardConcentration(1)); | ||
} | ||
|
||
TEST_F(RedlichKister_Test, activityConcentrations) | ||
{ | ||
// Check to make sure activityConcentration_i == standardConcentration_i * gamma_i * X_i | ||
vector_fp standardConcs(2); | ||
vector_fp activityCoeffs(2); | ||
vector_fp activityConcentrations(2); | ||
double xmin = 0.6; | ||
double xmax = 0.9; | ||
int numSteps = 9; | ||
double dx = (xmax-xmin)/(numSteps-1); | ||
|
||
for(int i=0; i < 9; ++i) | ||
{ | ||
const double r = xmin + i*dx; | ||
set_r(r); | ||
test_phase->getActivityCoefficients(&activityCoeffs[0]); | ||
standardConcs[0] = test_phase->standardConcentration(0); | ||
standardConcs[1] = test_phase->standardConcentration(1); | ||
test_phase->getActivityConcentrations(&activityConcentrations[0]); | ||
|
||
EXPECT_NEAR(standardConcs[0] * r * activityCoeffs[0], activityConcentrations[0], 1.e-6); | ||
EXPECT_NEAR(standardConcs[1] * (1-r) * activityCoeffs[1], activityConcentrations[1], 1.e-6); | ||
} | ||
} | ||
|
||
}; |