Skip to content

Commit

Permalink
Add RedlichKister tests and sample case for LiC6 electrode
Browse files Browse the repository at this point in the history
See #293
  • Loading branch information
pwcnorthrop authored and speth committed Feb 18, 2016
1 parent 125d2e0 commit 1183479
Show file tree
Hide file tree
Showing 5 changed files with 389 additions and 0 deletions.
72 changes: 72 additions & 0 deletions samples/cxx/LiC6_electrode/LiC6_electrode.cpp
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;
}
}
80 changes: 80 additions & 0 deletions samples/cxx/LiC6_electrode/LiC6_electrodebulk.xml
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>
10 changes: 10 additions & 0 deletions samples/cxx/LiC6_electrode/potentials_blessed.dat
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
80 changes: 80 additions & 0 deletions test/data/RedlichKisterVPSSTP_valid.xml
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>
147 changes: 147 additions & 0 deletions test/thermo/RedlichKisterTest.cpp
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);
}
}

};

0 comments on commit 1183479

Please sign in to comment.