/* Copyright (C) 1998, 1999, 2000 Evgenii Rudnyi, rudnyi@comp.chem.msu.su http://www.chem.msu.su/~rudnyi/ This software is a copyrighted work licensed under the terms, described in the file "FREE_LICENSE". */ #include "cuox_or.h" void RegisterCuOx_ordered_plane() { phase::RegisterType("CuOx_ordered_plane", new CuOx_ordered_plane); } void CuOx_ordered_plane::read(const SGML &e_) { clear(); size_t i, k; SGML e = e_; ReadComponents(vf, e, ref); parser p(e); SGML el; if (ref.size() != 2) { p.GetSGML(el); el.compare("Reference"); ref.read(el); } if (p.GetToken() == "Gid") mul_ent = 2; else if (p.token == "2*R*T*") { mul_ent = 2; } else if (p.token == "R*T*") { mul_ent = 1; } else throw gError("CuOx_ordered_plane: expected ideal Gibbs energy"); p.SkipUntil('<'); while (!p.eof()) { p.GetSGML(el); el.compare("func_x"); parser p2(el); if (p2.GetToken() == "+1*" || p2.token == "+") i = 0; else if (p2.token == "+z*") { if (!p2.SkipUntil('^')) i = 1; else { p2.SkipChar('^'); k = p2.GetInt(); if (k == 0) throw gError("CuOx_ordered_plane: read: wrong token"); i = k + 1; if (k > na_) { f.insert(f.begin() + 2 + na_, k - na_, func_Tp()); na_ = k; } } } else throw gError("CuOx_ordered_plane: read: wrong token"); f[i].read(p.GetSGML(el)); } } void CuOx_ordered_plane::WriteBody(ostream& out, size_t shift) const { WriteComponents(out, shift); ref.write(out, &vf, shift); out << PutTab(shift); if (mul_ent != 1) { out << mul_ent << "*"; } out << "R*T*(z*log(z)+(1-z)*log(1-z))" << endl; out << PutTab(shift) << " + " << endl; fi(0).write(out, shift + 1); out << PutTab(shift) << " +z* " << endl; fi(1).write(out, shift); size_t i; for (i = 0; i < na_; ++i) { out << PutTab(shift) << " +z*(1-z)^" << i + 1 << "* " << endl; ai(i).write(out, shift); } } double CuOx_ordered_plane::Zmix(function f, const StateTp &Tp, const double &z) const { double sum = 0.; double lg; if (f == ::G || f == ::S) { lg = log_z(z); if (lg != -HUGE_VAL) sum += z*lg; lg = log_z(1. - z); if (lg != -HUGE_VAL) sum += (1. - z)*lg; if (f == ::G) sum *= global::R*Tp.T(); else sum *= -global::R; sum *= mul_ent; } int i; sum += fi(0).Z(f, Tp); sum += z*fi(1).Z(f, Tp); if (na_) { sum += z*(1. - z)*ai(0).Z(f, Tp); for (i = 1; i < na_; ++i) sum += z*(1. - z)*ai(i).Z(f, Tp)*pow(1. - z, i); } return sum; } double CuOx_ordered_plane::dZdz(function f, const StateTp &Tp, const double &z) const { double sum = 0.; if (f == ::G || f == ::S) { double lg; lg = log_z(z); if (lg != -HUGE_VAL) sum += lg; else goto M_HUGE; lg = log_z(1. - z); if (lg != -HUGE_VAL) sum -= lg; else goto P_HUGE; goto GOOD; M_HUGE: if (f == ::S) return HUGE_VAL; else return -HUGE_VAL; P_HUGE: if (f == ::S) return -HUGE_VAL; else return +HUGE_VAL; GOOD: if (f == ::G) sum *= global::R*Tp.T(); else sum *= -global::R; sum *= mul_ent; } sum += fi(1).Z(f, Tp); if (na_) sum += (1. - 2.*z)*ai(0).Z(f, Tp); if (na_ > 1) { sum += ai(1).Z(f, Tp)*((1. - 2*z)*(1. - z) - z*(1. - z)); for (int i = 2; i < na_; ++i) sum += ai(i).Z(f, Tp)* ((1. - 2*z)*pow(1. - z, i) - z*(1. - z)*i*pow(1. - z, i - 1)); } return sum; } const vec_double& CuOx_ordered_plane::dZdx(function f, index i, const StateTp &Tp, const StateX &x) const { vz[0] = vz[1] = 0.; if (i & ::ref) ref.dZdx(f, Tp, x, vz); if ((i & ::mix) == ::mix) vz[1] += dZdz(f, Tp, x[1]); return vz; } const vec_double& CuOx_ordered_plane::z(function f, index i, const StateTp &Tp, const StateX &x) const { vz[0] = vz[1] = 0.; if (i & ::ref) ref.dZdx(f, Tp, x, vz); if ((i & ::mix) == ::mix) { double Zm = Zmix(f, Tp, x[1]); double dZx = dZdz(f, Tp, x[1]); vz[0] += Zm - x[1]*dZx; vz[1] += Zm + (1. - x[1])*dZx; } return vz; }