Пример #1
0
TEST(LatticeSolidPhase, fromScratch)
{
    auto base = make_shared<StoichSubstance>();
    base->setName("Li7Si3(S)");
    base->setDensity(1390.0);
    auto sLi7Si3 = make_shomate2_species("Li7Si3(S)", "Li:7 Si:3", li7si3_shomate_coeffs);
    base->addSpecies(sLi7Si3);
    base->initThermo();

    auto interstital = make_shared<LatticePhase>();
    interstital->setName("Li7Si3_Interstitial");
    auto sLii = make_const_cp_species("Li(i)", "Li:1", 298.15, 0, 2e4, 2e4);
    auto sVac = make_const_cp_species("V(i)", "", 298.15, 8.98e4, 0, 0);
    sLii->extra["molar_volume"] = 0.2;
    interstital->setSiteDensity(10.46344);
    interstital->addSpecies(sLii);
    interstital->addSpecies(sVac);
    interstital->initThermo();
    interstital->setMoleFractionsByName("Li(i):0.01 V(i):0.99");

    LatticeSolidPhase p;
    p.addLattice(base);
    p.addLattice(interstital);
    p.setLatticeStoichiometry(parseCompString("Li7Si3(S):1.0 Li7Si3_Interstitial:1.0"));
    p.initThermo();
    p.setState_TP(725, 10 * OneAtm);

    // Regression test based on modified version of Li7Si3_ls.xml
    EXPECT_NEAR(p.enthalpy_mass(), -2077821.9295456698, 1e-6);
    double mu_ref[] = {-4.62717474e+08, -4.64248485e+07, 1.16370186e+05};
    double vol_ref[] = {0.09557086, 0.2, 0.09557086};
    vector_fp mu(p.nSpecies());
    vector_fp vol(p.nSpecies());
    p.getChemPotentials(mu.data());
    p.getPartialMolarVolumes(vol.data());

    for (size_t k = 0; k < p.nSpecies(); k++) {
        EXPECT_NEAR(mu[k], mu_ref[k], 1e-7*fabs(mu_ref[k]));
        EXPECT_NEAR(vol[k], vol_ref[k], 1e-7);
    }
}
Пример #2
0
//====================================================================================================================
FixedChemPotSSTP::FixedChemPotSSTP(std::string Ename, doublereal val) :
    SingleSpeciesTP(),
    chemPot_(0.0)
{

    std::string pname = Ename + "Fixed";
    setID(pname);
    setName(pname);
    setNDim(3);
    addUniqueElement(Ename, -12345.);
    freezeElements();
    vector_fp ecomp(nElements(), 0.0);
    ecomp[0] = 1.0;
    double chrg = 0.0;
    SpeciesThermo* spth = new SimpleThermo();
    setSpeciesThermo(spth);
    addUniqueSpecies(pname, &ecomp[0], chrg, 0.0);
    double c[4];
    c[0] = 298.15;
    c[1] = val;
    c[2] = 0.0;
    c[3] = 0.0;
    m_spthermo->install(pname, 0, SIMPLE, c, 0.0, 1.0E30, OneAtm);
    freezeSpecies();
    initThermo();
    m_p0 = OneAtm;
    m_tlast = 298.15;
    setChemicalPotential(val);

    // Create an XML_Node entry for this species
    XML_Node* s = new XML_Node("species", 0);
    s->addAttribute("name", pname);
    std::string aaS = Ename + ":1";
    s->addChild("atomArray", aaS);
    XML_Node& tt = s->addChild("thermo");
    XML_Node& ss = tt.addChild("Simple");
    ss.addAttribute("Pref", "1 bar");
    ss.addAttribute("Tmax", "5000.");
    ss.addAttribute("Tmin", "100.");
    ss.addChild("t0", "298.15");
    ss.addChild("cp0", "0.0");
    std::string sval = fp2str(val);
    ss.addChild("h", sval);
    ss.addChild("s", "0.0");
    saveSpeciesData(0, s);
    delete s;
    s = 0;
}
Пример #3
0
PDSS_Water::PDSS_Water(VPStandardStateTP* tp, int spindex,
                       const XML_Node& speciesNode,
                       const XML_Node& phaseRoot, bool spInstalled) :
    PDSS(tp, spindex),
    m_waterProps(&m_sub),
    m_dens(1000.0),
    m_iState(WATER_LIQUID),
    EW_Offset(0.0),
    SW_Offset(0.0),
    m_verbose(0),
    m_allowGasPhase(false)
{
    m_pdssType = cPDSS_WATER;
    std::string id= "";
    constructPDSSXML(tp, spindex, phaseRoot, id);
    initThermo();
    m_spthermo = 0;
    m_minTemp = 200.;
    m_maxTemp = 10000.;
}
Пример #4
0
TEST(IonsFromNeutralConstructor, fromScratch)
{
    auto neutral = make_shared<MargulesVPSSTP>();
    auto sKCl = make_shomate_species("KCl(L)", "K:1 Cl:1", kcl_shomate_coeffs);
    neutral->addSpecies(sKCl);
    std::unique_ptr<PDSS_ConstVol> ssKCl(new PDSS_ConstVol());
    ssKCl->setMolarVolume(0.03757);
    neutral->installPDSS(0, std::move(ssKCl));
    neutral->initThermo();

    IonsFromNeutralVPSSTP p;
    p.setNeutralMoleculePhase(neutral);

    auto sKp = make_shared<Species>("K+", parseCompString("K:1"), 1);
    auto sClm = make_shared<Species>("Cl-", parseCompString("Cl:1"), -1);
    sClm->extra["special_species"] = true;
    p.addSpecies(sKp);
    p.addSpecies(sClm);
    std::unique_ptr<PDSS_IonsFromNeutral> ssKp(new PDSS_IonsFromNeutral());
    std::unique_ptr<PDSS_IonsFromNeutral> ssClm(new PDSS_IonsFromNeutral());
    ssKp->setNeutralSpeciesMultiplier("KCl(L)", 1.2);
    ssClm->setNeutralSpeciesMultiplier("KCl(L)", 1.5);
    ssClm->setSpecialSpecies();
    p.installPDSS(0, std::move(ssKp));
    p.installPDSS(1, std::move(ssClm));
    p.initThermo();

    ASSERT_EQ((int) p.nSpecies(), 2);
    p.setState_TPX(500, 2e5, "K+:0.1, Cl-:0.1");
    vector_fp mu(p.nSpecies());
    p.getChemPotentials(mu.data());

    // Values for regression testing only -- same as XML test
    EXPECT_NEAR(p.density(), 1984.3225978174073, 1e-6);
    EXPECT_NEAR(p.enthalpy_mass(), -8035317241137.971, 1e-1);
    EXPECT_NEAR(mu[0], -4.66404010e+08, 1e1);
    EXPECT_NEAR(mu[1], -2.88157298e+06, 1e-1);
}
Пример #5
0
FixedChemPotSSTP::FixedChemPotSSTP(const std::string& Ename, doublereal val) :
    chemPot_(0.0)
{
    std::string pname = Ename + "Fixed";
    setID(pname);
    setName(pname);
    setNDim(3);
    addElement(Ename);
    auto sp = make_shared<Species>(pname, parseCompString(Ename + ":1.0"));
    double c[4] = {298.15, val, 0.0, 0.0};
    shared_ptr<SpeciesThermoInterpType> stit(
            newSpeciesThermoInterpType("const_cp", 0.1, 1e30, OneAtm, c));
    sp->thermo = stit;
    addSpecies(sp);
    initThermo();
    m_p0 = OneAtm;
    m_tlast = 298.15;
    setChemicalPotential(val);

    // Create an XML_Node entry for this species
    XML_Node s("species", 0);
    s.addAttribute("name", pname);
    std::string aaS = Ename + ":1";
    s.addChild("atomArray", aaS);
    XML_Node& tt = s.addChild("thermo");
    XML_Node& ss = tt.addChild("Simple");
    ss.addAttribute("Pref", "1 bar");
    ss.addAttribute("Tmax", "5000.");
    ss.addAttribute("Tmin", "100.");
    ss.addChild("t0", "298.15");
    ss.addChild("cp0", "0.0");
    std::string sval = fp2str(val);
    ss.addChild("h", sval);
    ss.addChild("s", "0.0");
    saveSpeciesData(0, &s);
}
/*!
  Constructor
  \param parent Parent widget
  \param name Object name
*/
QwtThermo::QwtThermo(QWidget *parent, const char *name):
    QWidget(parent, name)
{
    initThermo();
}
/*!
  Constructor
  \param parent Parent widget
*/
QwtThermo::QwtThermo(QWidget *parent):
    QWidget(parent)
{
    initThermo();
}
Пример #8
0
void WaterSSTP::initThermoXML(XML_Node& phaseNode, const std::string& id)
{
    /*
     * Do initializations that don't depend on knowing the XML file
     */
    initThermo();
    /*
     * Calculate the molecular weight. Note while there may
     * be a very good calculated weight in the steam table
     * class, using this weight may lead to codes exhibiting
     * mass loss issues. We need to grab the elemental
     * atomic weights used in the Element class and calculate
     * a consistent H2O molecular weight based on that.
     */
    size_t nH = elementIndex("H");
    if (nH == npos) {
        throw CanteraError("WaterSSTP::initThermo",
                           "H not an element");
    }
    double mw_H = atomicWeight(nH);
    size_t nO = elementIndex("O");
    if (nO == npos) {
        throw CanteraError("WaterSSTP::initThermo",
                           "O not an element");
    }
    double mw_O = atomicWeight(nO);
    m_mw = 2.0 * mw_H + mw_O;
    setMolecularWeight(0,m_mw);
    double one = 1.0;
    setMoleFractions(&one);

    /*
     * Set the baseline
     */
    doublereal T = 298.15;
    Phase::setDensity(7.0E-8);
    Phase::setTemperature(T);

    doublereal presLow = 1.0E-2;
    doublereal oneBar = 1.0E5;
    doublereal dd = m_sub.density(T, presLow, WATER_GAS, 7.0E-8);
    setDensity(dd);
    setTemperature(T);
    SW_Offset = 0.0;
    doublereal s = entropy_mole();
    s -= GasConstant * log(oneBar/presLow);
    if (s != 188.835E3) {
        SW_Offset = 188.835E3 - s;
    }
    s = entropy_mole();
    s -= GasConstant * log(oneBar/presLow);

    doublereal h = enthalpy_mole();
    if (h != -241.826E6) {
        EW_Offset = -241.826E6 - h;
    }
    h = enthalpy_mole();

    /*
     * Set the initial state of the system to 298.15 K and
     * 1 bar.
     */
    setTemperature(298.15);
    double rho0 = m_sub.density(298.15, OneAtm, WATER_LIQUID);
    setDensity(rho0);

    m_waterProps.reset(new WaterProps(&m_sub));

    /*
     * We have to do something with the thermo function here.
     */
    delete m_spthermo;
    m_spthermo = 0;

    /*
     * Set the flag to say we are ready to calculate stuff
     */
    m_ready = true;
}