00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "vcs_MultiPhaseEquil.h"
00015 #include "vcs_prob.h"
00016 #include "vcs_internal.h"
00017 #include "vcs_VolPhase.h"
00018 #include "vcs_species_thermo.h"
00019 #include "vcs_SpeciesProperties.h"
00020 #include "vcs_VolPhase.h"
00021
00022 #include "vcs_solve.h"
00023
00024 #include "ct_defs.h"
00025 #include "mix_defs.h"
00026 #include "clockWC.h"
00027 #include "ThermoPhase.h"
00028 #include "speciesThermoTypes.h"
00029 #ifdef WITH_IDEAL_SOLUTIONS
00030 #include "IdealSolidSolnPhase.h"
00031 #endif
00032 #ifdef WITH_ELECTROLYTES
00033 #include "IdealMolalSoln.h"
00034 #endif
00035 #include "ChemEquil.h"
00036
00037 #include <string>
00038 #include <vector>
00039
00040 using namespace Cantera;
00041 using namespace std;
00042
00043
00044 namespace VCSnonideal {
00045
00046
00047 vcs_MultiPhaseEquil::vcs_MultiPhaseEquil() :
00048 m_vprob(0),
00049 m_mix(0),
00050 m_printLvl(0),
00051 m_vsolvePtr(0)
00052 {
00053 }
00054
00055 vcs_MultiPhaseEquil::vcs_MultiPhaseEquil(mix_t* mix, int printLvl) :
00056 m_vprob(0),
00057 m_mix(0),
00058 m_printLvl(printLvl),
00059 m_vsolvePtr(0)
00060 {
00061
00062
00063 int nsp = mix->nSpecies();
00064 int nel = mix->nElements();
00065 int nph = mix->nPhases();
00066
00067
00068
00069
00070
00071 m_vprob = new VCS_PROB(nsp, nel, nph);
00072 m_mix = mix;
00073 m_vprob->m_printLvl = m_printLvl;
00074
00075
00076
00077
00078 int res = vcs_Cantera_to_vprob(mix, m_vprob);
00079 if (res != 0) {
00080 plogf("problems\n");
00081 }
00082 }
00083
00084 vcs_MultiPhaseEquil::~vcs_MultiPhaseEquil() {
00085 delete m_vprob;
00086 m_vprob = 0;
00087 if (m_vsolvePtr) {
00088 delete m_vsolvePtr;
00089 m_vsolvePtr = 0;
00090 }
00091 }
00092
00093 int vcs_MultiPhaseEquil::equilibrate_TV(int XY, doublereal xtarget,
00094 int estimateEquil,
00095 int printLvl, doublereal err,
00096 int maxsteps, int loglevel) {
00097
00098 addLogEntry("problem type","fixed T, V");
00099
00100 doublereal Vtarget = m_mix->volume();
00101 doublereal dVdP;
00102 if ((XY != TV) && (XY != HV) && (XY != UV) && (XY != SV)) {
00103 throw CanteraError("vcs_MultiPhaseEquil::equilibrate_TV",
00104 "Wrong XY flag:" + int2str(XY));
00105 }
00106 int maxiter = 100;
00107 int iSuccess = 0;
00108 int innerXY;
00109 double Pnow;
00110 if (XY == TV) {
00111 m_mix->setTemperature(xtarget);
00112 }
00113 double Pnew;
00114 int strt = estimateEquil;
00115 double P1 = 0.0;
00116 double V1 = 0.0;
00117 double V2 = 0.0;
00118 double P2 = 0.0;
00119 doublereal Tlow = 0.5 * m_mix->minTemp();;
00120 doublereal Thigh = 2.0 * m_mix->maxTemp();
00121 doublereal Vnow, Verr;
00122 int printLvlSub = MAX(0, printLvl - 1);
00123 for (int n = 0; n < maxiter; n++) {
00124 Pnow = m_mix->pressure();
00125
00126 beginLogGroup("iteration "+int2str(n));
00127 switch(XY) {
00128 case TV:
00129 iSuccess = equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
00130 break;
00131 case HV:
00132 innerXY = HP;
00133 iSuccess = equilibrate_HP(xtarget, innerXY, Tlow, Thigh, strt,
00134 printLvlSub, err, maxsteps, loglevel);
00135 break;
00136 case UV:
00137 innerXY = UP;
00138 iSuccess = equilibrate_HP(xtarget, innerXY, Tlow, Thigh, strt,
00139 printLvlSub, err, maxsteps, loglevel);
00140 break;
00141 case SV:
00142 innerXY = SP;
00143 iSuccess = equilibrate_SP(xtarget, Tlow, Thigh, strt,
00144 printLvlSub, err, maxsteps, loglevel);
00145 break;
00146 default:
00147 break;
00148 }
00149 strt = false;
00150 Vnow = m_mix->volume();
00151 if (n == 0) {
00152 V2 = Vnow;
00153 P2 = Pnow;
00154 } else if (n == 1) {
00155 V1 = Vnow;
00156 P1 = Pnow;
00157 } else {
00158 P2 = P1;
00159 V2 = V1;
00160 P1 = Pnow;
00161 V1 = Vnow;
00162 }
00163
00164 Verr = fabs((Vtarget - Vnow)/Vtarget);
00165 addLogEntry("P",fp2str(Pnow));
00166 addLogEntry("V rel error",fp2str(Verr));
00167 endLogGroup();
00168
00169 if (Verr < err) {
00170 addLogEntry("P iterations",int2str(n));
00171 addLogEntry("Final P",fp2str(Pnow));
00172 addLogEntry("V rel error",fp2str(Verr));
00173 goto done;
00174 }
00175
00176 if (n > 1) {
00177 dVdP = (V2 - V1) / (P2 - P1);
00178 if (dVdP == 0.0) {
00179 throw CanteraError("vcs_MultiPhase::equilibrate_TV",
00180 "dVdP == 0.0");
00181 } else {
00182 Pnew = Pnow + (Vtarget - Vnow) / dVdP;
00183 if (Pnew < 0.2 * Pnow) {
00184 Pnew = 0.2 * Pnow;
00185 }
00186 if (Pnew > 3.0 * Pnow) {
00187 Pnew = 3.0 * Pnow;
00188 }
00189 }
00190
00191 } else {
00192 m_mix->setPressure(Pnow*1.01);
00193 dVdP = (m_mix->volume() - Vnow)/(0.01*Pnow);
00194 Pnew = Pnow + 0.5*(Vtarget - Vnow)/dVdP;
00195 if (Pnew < 0.5* Pnow) {
00196 Pnew = 0.5 * Pnow;
00197 }
00198 if (Pnew > 1.7 * Pnow) {
00199 Pnew = 1.7 * Pnow;
00200 }
00201
00202 }
00203 m_mix->setPressure(Pnew);
00204 }
00205 throw CanteraError("vcs_MultiPhase::equilibrate_TV",
00206 "No convergence for V");
00207
00208 done:;
00209 return iSuccess;
00210 }
00211
00212
00213 int vcs_MultiPhaseEquil::equilibrate_HP(doublereal Htarget,
00214 int XY, double Tlow, double Thigh,
00215 int estimateEquil,
00216 int printLvl, doublereal err,
00217 int maxsteps, int loglevel) {
00218 int maxiter = 100;
00219 int iSuccess;
00220 if (XY != HP && XY != UP) {
00221 throw CanteraError("vcs_MultiPhaseEquil::equilibrate_HP",
00222 "Wrong XP" + XY);
00223 }
00224 int strt = estimateEquil;
00225
00226
00227 if (Tlow <= 0.0) {
00228 Tlow = 0.5 * m_mix->minTemp();
00229 }
00230
00231 if (Thigh <= 0.0 || Thigh > 1.0E6) {
00232 Thigh = 2.0 * m_mix->maxTemp();
00233 }
00234 addLogEntry("problem type","fixed H,P");
00235 addLogEntry("H target",fp2str(Htarget));
00236
00237 doublereal cpb = 1.0, dT, dTa, dTmax, Tnew;
00238 doublereal Hnow;
00239 doublereal Hlow = Undef;
00240 doublereal Hhigh = Undef;
00241 doublereal Herr, HConvErr;
00242 doublereal Tnow = m_mix->temperature();
00243 int printLvlSub = MAX(printLvl - 1, 0);
00244
00245 for (int n = 0; n < maxiter; n++) {
00246
00247
00248
00249
00250 beginLogGroup("iteration "+int2str(n));
00251
00252 try {
00253 Tnow = m_mix->temperature();
00254 iSuccess = equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
00255 strt = 0;
00256 if (XY == UP) {
00257 Hnow = m_mix->IntEnergy();
00258 } else {
00259 Hnow = m_mix->enthalpy();
00260 }
00261 double pmoles[10];
00262 pmoles[0] = m_mix->phaseMoles(0);
00263 double Tmoles = pmoles[0];
00264 double HperMole = Hnow/Tmoles;
00265 if (printLvl > 0) {
00266 plogf("T = %g, Hnow = %g ,Tmoles = %g, HperMole = %g",
00267 Tnow, Hnow, Tmoles, HperMole);
00268 plogendl();
00269 }
00270
00271
00272
00273
00274
00275
00276 if (Hnow < Htarget) {
00277 if (Tnow > Tlow) {
00278 Tlow = Tnow;
00279 Hlow = Hnow;
00280 }
00281 }
00282
00283
00284 else {
00285 if (Tnow < Thigh) {
00286 Thigh = Tnow;
00287 Hhigh = Hnow;
00288 }
00289 }
00290 if (Hlow != Undef && Hhigh != Undef) {
00291 cpb = (Hhigh - Hlow)/(Thigh - Tlow);
00292 dT = (Htarget - Hnow)/cpb;
00293 dTa = fabs(dT);
00294 dTmax = 0.5*fabs(Thigh - Tlow);
00295 if (dTa > dTmax) dT *= dTmax/dTa;
00296 }
00297 else {
00298 Tnew = sqrt(Tlow*Thigh);
00299 dT = Tnew - Tnow;
00300 if (dT < -200.) dT = 200;
00301 if (dT > 200.) dT = 200.;
00302 }
00303 double acpb = MAX(fabs(cpb), 1.0E-6);
00304 double denom = MAX(fabs(Htarget), acpb);
00305 Herr = Htarget - Hnow;
00306 HConvErr = fabs((Herr)/denom);
00307 addLogEntry("T",fp2str(m_mix->temperature()));
00308 addLogEntry("H",fp2str(Hnow));
00309 addLogEntry("Herr",fp2str(Herr));
00310 addLogEntry("H rel error",fp2str(HConvErr));
00311 addLogEntry("lower T bound",fp2str(Tlow));
00312 addLogEntry("upper T bound",fp2str(Thigh));
00313 endLogGroup();
00314 if (printLvl > 0) {
00315 plogf(" equilibrate_HP: It = %d, Tcurr = %g Hcurr = %g, Htarget = %g\n",
00316 n, Tnow, Hnow, Htarget);
00317 plogf(" H rel error = %g, cp = %g, HConvErr = %g\n",
00318 Herr, cpb, HConvErr);
00319 }
00320
00321 if (HConvErr < err) {
00322 addLogEntry("T iterations",int2str(n));
00323 addLogEntry("Final T",fp2str(m_mix->temperature()));
00324 addLogEntry("H rel error",fp2str(Herr));
00325 if (printLvl > 0) {
00326 plogf(" equilibrate_HP: CONVERGENCE: Hfinal = %g Tfinal = %g, Its = %d \n",
00327 Hnow, Tnow, n);
00328 plogf(" H rel error = %g, cp = %g, HConvErr = %g\n",
00329 Herr, cpb, HConvErr);
00330 }
00331 goto done;
00332 }
00333 Tnew = Tnow + dT;
00334 if (Tnew < 0.0) Tnew = 0.5*Tnow;
00335 m_mix->setTemperature(Tnew);
00336
00337 }
00338 catch (CanteraError err) {
00339 if (!estimateEquil) {
00340 addLogEntry("no convergence",
00341 "try estimating composition at the start");
00342 strt = -1;
00343 }
00344 else {
00345 Tnew = 0.5*(Tnow + Thigh);
00346 if (fabs(Tnew - Tnow) < 1.0) Tnew = Tnow + 1.0;
00347 m_mix->setTemperature(Tnew);
00348 addLogEntry("no convergence",
00349 "trying T = "+fp2str(Tnow));
00350 }
00351 endLogGroup();
00352 }
00353
00354 }
00355 addLogEntry("reached max number of T iterations",int2str(maxiter));
00356 endLogGroup();
00357 throw CanteraError("MultiPhase::equilibrate_HP",
00358 "No convergence for T");
00359 done:;
00360 return iSuccess;
00361 }
00362
00363 int vcs_MultiPhaseEquil::equilibrate_SP(doublereal Starget,
00364 double Tlow, double Thigh,
00365 int estimateEquil,
00366 int printLvl, doublereal err,
00367 int maxsteps, int loglevel) {
00368 int maxiter = 100;
00369 int iSuccess;
00370 int strt = estimateEquil;
00371
00372
00373 if (Tlow <= 0.0) {
00374 Tlow = 0.5 * m_mix->minTemp();
00375 }
00376
00377 if (Thigh <= 0.0 || Thigh > 1.0E6) {
00378 Thigh = 2.0 * m_mix->maxTemp();
00379 }
00380 addLogEntry("problem type","fixed S,P");
00381 addLogEntry("S target",fp2str(Starget));
00382
00383 doublereal cpb = 1.0, dT, dTa, dTmax, Tnew;
00384 doublereal Snow;
00385 doublereal Slow = Undef;
00386 doublereal Shigh = Undef;
00387 doublereal Serr, SConvErr;
00388 doublereal Tnow = m_mix->temperature();
00389 if (Tnow < Tlow) {
00390 Tlow = Tnow;
00391 }
00392 if (Tnow > Thigh) {
00393 Thigh = Tnow;
00394 }
00395 int printLvlSub = MAX(printLvl - 1, 0);
00396
00397 for (int n = 0; n < maxiter; n++) {
00398
00399
00400
00401 beginLogGroup("iteration "+int2str(n));
00402
00403 try {
00404 Tnow = m_mix->temperature();
00405 iSuccess = equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
00406 strt = 0;
00407 Snow = m_mix->entropy();
00408 double pmoles[10];
00409 pmoles[0] = m_mix->phaseMoles(0);
00410 double Tmoles = pmoles[0];
00411 double SperMole = Snow/Tmoles;
00412 plogf("T = %g, Snow = %g ,Tmoles = %g, SperMole = %g\n",
00413 Tnow, Snow, Tmoles, SperMole);
00414
00415
00416
00417
00418
00419
00420 if (Snow < Starget) {
00421 if (Tnow > Tlow) {
00422 Tlow = Tnow;
00423 Slow = Snow;
00424 } else {
00425 if (Slow > Starget) {
00426 if (Snow < Slow) {
00427 Thigh = Tlow;
00428 Shigh = Slow;
00429 Tlow = Tnow;
00430 Slow = Snow;
00431 }
00432 }
00433 }
00434 }
00435
00436
00437 else {
00438 if (Tnow < Thigh) {
00439 Thigh = Tnow;
00440 Shigh = Snow;
00441 }
00442 }
00443 if (Slow != Undef && Shigh != Undef) {
00444 cpb = (Shigh - Slow)/(Thigh - Tlow);
00445 dT = (Starget - Snow)/cpb;
00446 Tnew = Tnow + dT;
00447 dTa = fabs(dT);
00448 dTmax = 0.5*fabs(Thigh - Tlow);
00449 if (Tnew > Thigh || Tnew < Tlow) {
00450 dTmax = 1.5*fabs(Thigh - Tlow);
00451 }
00452 dTmax = MIN(dTmax, 300.);
00453 if (dTa > dTmax) dT *= dTmax/dTa;
00454 } else {
00455 Tnew = sqrt(Tlow*Thigh);
00456 dT = Tnew - Tnow;
00457 }
00458
00459 double acpb = MAX(fabs(cpb), 1.0E-6);
00460 double denom = MAX(fabs(Starget), acpb);
00461 Serr = Starget - Snow;
00462 SConvErr = fabs((Serr)/denom);
00463 addLogEntry("T",fp2str(m_mix->temperature()));
00464 addLogEntry("S",fp2str(Snow));
00465 addLogEntry("Serr",fp2str(Serr));
00466 addLogEntry("S rel error",fp2str(SConvErr));
00467 addLogEntry("lower T bound",fp2str(Tlow));
00468 addLogEntry("upper T bound",fp2str(Thigh));
00469 endLogGroup();
00470 if (printLvl > 0) {
00471 plogf(" equilibrate_SP: It = %d, Tcurr = %g Scurr = %g, Starget = %g\n",
00472 n, Tnow, Snow, Starget);
00473 plogf(" S rel error = %g, cp = %g, SConvErr = %g\n",
00474 Serr, cpb, SConvErr);
00475 }
00476
00477 if (SConvErr < err) {
00478 addLogEntry("T iterations",int2str(n));
00479 addLogEntry("Final T",fp2str(m_mix->temperature()));
00480 addLogEntry("S rel error",fp2str(Serr));
00481 if (printLvl > 0) {
00482 plogf(" equilibrate_SP: CONVERGENCE: Sfinal = %g Tfinal = %g, Its = %d \n",
00483 Snow, Tnow, n);
00484 plogf(" S rel error = %g, cp = %g, HConvErr = %g\n",
00485 Serr, cpb, SConvErr);
00486 }
00487 goto done;
00488 }
00489 Tnew = Tnow + dT;
00490 if (Tnew < 0.0) Tnew = 0.5*Tnow;
00491 m_mix->setTemperature(Tnew);
00492
00493 }
00494 catch (CanteraError err) {
00495 if (!estimateEquil) {
00496 addLogEntry("no convergence",
00497 "try estimating composition at the start");
00498 strt = -1;
00499 }
00500 else {
00501 Tnew = 0.5*(Tnow + Thigh);
00502 if (fabs(Tnew - Tnow) < 1.0) Tnew = Tnow + 1.0;
00503 m_mix->setTemperature(Tnew);
00504 addLogEntry("no convergence",
00505 "trying T = "+fp2str(Tnow));
00506 }
00507 endLogGroup();
00508 }
00509
00510 }
00511 addLogEntry("reached max number of T iterations",int2str(maxiter));
00512 endLogGroup();
00513 throw CanteraError("MultiPhase::equilibrate_SP",
00514 "No convergence for T");
00515 done:;
00516 return iSuccess;
00517 }
00518
00519
00520
00521
00522
00523 int vcs_MultiPhaseEquil::equilibrate(int XY, int estimateEquil,
00524 int printLvl, doublereal err,
00525 int maxsteps, int loglevel) {
00526 int iSuccess;
00527 doublereal xtarget;
00528 if (XY == TP) {
00529 iSuccess = equilibrate_TP(estimateEquil, printLvl, err, maxsteps, loglevel);
00530 } else if (XY == HP || XY == UP) {
00531 if (XY == HP) {
00532 xtarget = m_mix->enthalpy();
00533 } else {
00534 xtarget = m_mix->IntEnergy();
00535 }
00536 double Tlow = 0.5 * m_mix->minTemp();
00537 double Thigh = 2.0 * m_mix->maxTemp();
00538 iSuccess = equilibrate_HP(xtarget, XY, Tlow, Thigh,
00539 estimateEquil, printLvl, err, maxsteps, loglevel);
00540 } else if (XY == SP) {
00541 xtarget = m_mix->entropy();
00542 double Tlow = 0.5 * m_mix->minTemp();
00543 double Thigh = 2.0 * m_mix->maxTemp();
00544 iSuccess = equilibrate_SP(xtarget, Tlow, Thigh,
00545 estimateEquil, printLvl, err, maxsteps, loglevel);
00546
00547 } else if (XY == TV) {
00548 xtarget = m_mix->temperature();
00549 iSuccess = equilibrate_TV(XY, xtarget,
00550 estimateEquil, printLvl, err, maxsteps, loglevel);
00551 } else if (XY == HV) {
00552 xtarget = m_mix->enthalpy();
00553 iSuccess = equilibrate_TV(XY, xtarget,
00554 estimateEquil, printLvl, err, maxsteps, loglevel);
00555 } else if (XY == UV) {
00556 xtarget = m_mix->IntEnergy();
00557 iSuccess = equilibrate_TV(XY, xtarget,
00558 estimateEquil, printLvl, err, maxsteps, loglevel);
00559 } else if (XY == SV) {
00560 xtarget = m_mix->entropy();
00561 iSuccess = equilibrate_TV(XY, xtarget, estimateEquil,
00562 printLvl, err, maxsteps, loglevel);
00563 } else {
00564 throw CanteraError(" vcs_MultiPhaseEquil::equilibrate",
00565 "Unsupported Option");
00566 }
00567 return iSuccess;
00568 }
00569
00570
00571
00572
00573 int vcs_MultiPhaseEquil::equilibrate_TP(int estimateEquil,
00574 int printLvl, doublereal err,
00575 int maxsteps, int loglevel) {
00576
00577
00578 int maxit = maxsteps;;
00579 clockWC tickTock;
00580 int nsp = m_mix->nSpecies();
00581 int nel = m_mix->nElements();
00582 int nph = m_mix->nPhases();
00583 if (m_vprob == 0) {
00584 m_vprob = new VCS_PROB(nsp, nel, nph);
00585 }
00586 m_printLvl = printLvl;
00587 m_vprob->m_printLvl = printLvl;
00588
00589
00590
00591
00592
00593
00594
00595 int res = vcs_Cantera_update_vprob(m_mix, m_vprob);
00596 if (res != 0) {
00597 plogf("problems\n");
00598 }
00599
00600
00601
00602 if (estimateEquil) {
00603 m_vprob->iest = estimateEquil;
00604 } else {
00605 m_vprob->iest = 0;
00606 }
00607
00608
00609
00610
00611 double T = m_mix->temperature();
00612 if (T <= 0.0) {
00613 throw CanteraError("vcs_MultiPhaseEquil::equilibrate",
00614 "Temperature less than zero on input");
00615 }
00616 double pres = m_mix->pressure();
00617 if (pres <= 0.0) {
00618 throw CanteraError("vcs_MultiPhaseEquil::equilibrate",
00619 "Pressure less than zero on input");
00620 }
00621
00622 beginLogGroup("vcs_MultiPhaseEquil::equilibrate_TP", loglevel);
00623 addLogEntry("problem type","fixed T,P");
00624 addLogEntry("Temperature", T);
00625 addLogEntry("Pressure", pres);
00626
00627
00628
00629
00630
00631
00632 m_vprob->prob_report(m_printLvl);
00633
00634
00635
00636
00637 int ip1 = m_printLvl;
00638 int ipr = MAX(0, m_printLvl-1);
00639 if (m_printLvl >= 3) {
00640 ip1 = m_printLvl - 2;
00641 } else {
00642 ip1 = 0;
00643 }
00644 if (!m_vsolvePtr) {
00645 m_vsolvePtr = new VCS_SOLVE();
00646 }
00647 int iSuccess = m_vsolvePtr->vcs(m_vprob, 0, ipr, ip1, maxit);
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 m_mix->uploadMoleFractionsFromPhases();
00658 int kGlob = 0;
00659 for (int ip = 0; ip < m_vprob->NPhase; ip++) {
00660 double phaseMole = 0.0;
00661 Cantera::ThermoPhase &tref = m_mix->phase(ip);
00662 int nspPhase = tref.nSpecies();
00663 for (int k = 0; k < nspPhase; k++, kGlob++) {
00664 phaseMole += m_vprob->w[kGlob];
00665 }
00666
00667 m_mix->setPhaseMoles(ip, phaseMole);
00668 }
00669
00670 double te = tickTock.secondsWC();
00671 if (printLvl > 0) {
00672 plogf("\n Results from vcs:\n");
00673 if (iSuccess != 0) {
00674 plogf("\nVCS FAILED TO CONVERGE!\n");
00675 }
00676 plogf("\n");
00677 plogf("Temperature = %g Kelvin\n", m_vprob->T);
00678 plogf("Pressure = %g Pa\n", m_vprob->PresPA);
00679 plogf("\n");
00680 plogf("----------------------------------------"
00681 "---------------------\n");
00682 plogf(" Name Mole_Number");
00683 if (m_vprob->m_VCS_UnitsFormat == VCS_UNITS_MKS) {
00684 plogf("(kmol)");
00685 } else {
00686 plogf("(gmol)");
00687 }
00688 plogf(" Mole_Fraction Chem_Potential");
00689 if (m_vprob->m_VCS_UnitsFormat == VCS_UNITS_KCALMOL)
00690 plogf(" (kcal/mol)\n");
00691 else if (m_vprob->m_VCS_UnitsFormat == VCS_UNITS_UNITLESS)
00692 plogf(" (Dimensionless)\n");
00693 else if (m_vprob->m_VCS_UnitsFormat == VCS_UNITS_KJMOL)
00694 plogf(" (kJ/mol)\n");
00695 else if (m_vprob->m_VCS_UnitsFormat == VCS_UNITS_KELVIN)
00696 plogf(" (Kelvin)\n");
00697 else if (m_vprob->m_VCS_UnitsFormat == VCS_UNITS_MKS)
00698 plogf(" (J/kmol)\n");
00699 plogf("--------------------------------------------------"
00700 "-----------\n");
00701 for (int i = 0; i < m_vprob->nspecies; i++) {
00702 plogf("%-12s", m_vprob->SpName[i].c_str());
00703 if (m_vprob->SpeciesUnknownType[i] == VCS_SPECIES_TYPE_INTERFACIALVOLTAGE) {
00704 plogf(" %15.3e %15.3e ", 0.0, m_vprob->mf[i]);
00705 plogf("%15.3e\n", m_vprob->m_gibbsSpecies[i]);
00706 } else {
00707 plogf(" %15.3e %15.3e ", m_vprob->w[i], m_vprob->mf[i]);
00708 if (m_vprob->w[i] <= 0.0) {
00709 int iph = m_vprob->PhaseID[i];
00710 vcs_VolPhase *VPhase = m_vprob->VPhaseList[iph];
00711 if (VPhase->nSpecies() > 1) {
00712 plogf(" -1.000e+300\n");
00713 } else {
00714 plogf("%15.3e\n", m_vprob->m_gibbsSpecies[i]);
00715 }
00716 } else {
00717 plogf("%15.3e\n", m_vprob->m_gibbsSpecies[i]);
00718 }
00719 }
00720 }
00721 plogf("------------------------------------------"
00722 "-------------------\n");
00723 if (printLvl > 2) {
00724 if (m_vsolvePtr->m_timing_print_lvl > 0) {
00725 plogf("Total time = %12.6e seconds\n", te);
00726 }
00727 }
00728 }
00729 if (loglevel > 0) {
00730 endLogGroup();
00731 }
00732 return iSuccess;
00733 }
00734
00735
00736
00737
00738
00739
00740
00741 void vcs_MultiPhaseEquil::reportCSV(const std::string &reportFile) {
00742 int k;
00743 int istart;
00744 int nSpecies;
00745
00746 double vol = 0.0;
00747 string sName;
00748 int nphase = m_vprob->NPhase;
00749
00750 FILE * FP = fopen(reportFile.c_str(), "w");
00751 if (!FP) {
00752 plogf("Failure to open file\n");
00753 exit(EXIT_FAILURE);
00754 }
00755 double Temp = m_mix->temperature();
00756 double pres = m_mix->pressure();
00757 double *mf = VCS_DATA_PTR(m_vprob->mf);
00758 #ifdef DEBUG_MODE
00759 double *fe = VCS_DATA_PTR(m_vprob->m_gibbsSpecies);
00760 #endif
00761 std::vector<double> VolPM;
00762 std::vector<double> activity;
00763 std::vector<double> ac;
00764 std::vector<double> mu;
00765 std::vector<double> mu0;
00766 std::vector<double> molalities;
00767
00768
00769 vol = 0.0;
00770 for (int iphase = 0; iphase < nphase; iphase++) {
00771 istart = m_mix->speciesIndex(0, iphase);
00772 Cantera::ThermoPhase &tref = m_mix->phase(iphase);
00773 nSpecies = tref.nSpecies();
00774 VolPM.resize(nSpecies, 0.0);
00775 tref.getPartialMolarVolumes(VCS_DATA_PTR(VolPM));
00776 vcs_VolPhase *volP = m_vprob->VPhaseList[iphase];
00777
00778 double TMolesPhase = volP->totalMoles();
00779 double VolPhaseVolumes = 0.0;
00780 for (k = 0; k < nSpecies; k++) {
00781 VolPhaseVolumes += VolPM[k] * mf[istart + k];
00782 }
00783 VolPhaseVolumes *= TMolesPhase;
00784 vol += VolPhaseVolumes;
00785 }
00786
00787 fprintf(FP,"--------------------- VCS_MULTIPHASE_EQUIL FINAL REPORT"
00788 " -----------------------------\n");
00789 fprintf(FP,"Temperature = %11.5g kelvin\n", Temp);
00790 fprintf(FP,"Pressure = %11.5g Pascal\n", pres);
00791 fprintf(FP,"Total Volume = %11.5g m**3\n", vol);
00792 fprintf(FP,"Number Basis optimizations = %d\n", m_vprob->m_NumBasisOptimizations);
00793 fprintf(FP,"Number VCS iterations = %d\n", m_vprob->m_Iterations);
00794
00795 for (int iphase = 0; iphase < nphase; iphase++) {
00796 istart = m_mix->speciesIndex(0, iphase);
00797 Cantera::ThermoPhase &tref = m_mix->phase(iphase);
00798 Cantera::ThermoPhase *tp = &tref;
00799 string phaseName = tref.name();
00800 vcs_VolPhase *volP = m_vprob->VPhaseList[iphase];
00801 double TMolesPhase = volP->totalMoles();
00802
00803 nSpecies = tref.nSpecies();
00804 activity.resize(nSpecies, 0.0);
00805 ac.resize(nSpecies, 0.0);
00806
00807 mu0.resize(nSpecies, 0.0);
00808 mu.resize(nSpecies, 0.0);
00809 VolPM.resize(nSpecies, 0.0);
00810 molalities.resize(nSpecies, 0.0);
00811
00812 int actConvention = tp->activityConvention();
00813 tp->getActivities(VCS_DATA_PTR(activity));
00814 tp->getActivityCoefficients(VCS_DATA_PTR(ac));
00815 tp->getStandardChemPotentials(VCS_DATA_PTR(mu0));
00816
00817 tp->getPartialMolarVolumes(VCS_DATA_PTR(VolPM));
00818 tp->getChemPotentials(VCS_DATA_PTR(mu));
00819 double VolPhaseVolumes = 0.0;
00820 for (k = 0; k < nSpecies; k++) {
00821 VolPhaseVolumes += VolPM[k] * mf[istart + k];
00822 }
00823 VolPhaseVolumes *= TMolesPhase;
00824 vol += VolPhaseVolumes;
00825
00826
00827 if (actConvention == 1) {
00828 #ifdef WITH_ELECTROLYTES
00829 MolalityVPSSTP *mTP = static_cast<MolalityVPSSTP *>(tp);
00830 mTP->getMolalities(VCS_DATA_PTR(molalities));
00831 #endif
00832 tp->getChemPotentials(VCS_DATA_PTR(mu));
00833
00834 if (iphase == 0) {
00835 fprintf(FP," Name, Phase, PhaseMoles, Mole_Fract, "
00836 "Molalities, ActCoeff, Activity,"
00837 "ChemPot_SS0, ChemPot, mole_num, PMVol, Phase_Volume\n");
00838
00839 fprintf(FP," , , (kmol), , "
00840 " , , ,"
00841 " (J/kmol), (J/kmol), (kmol), (m**3/kmol), (m**3)\n");
00842 }
00843 for (k = 0; k < nSpecies; k++) {
00844 sName = tp->speciesName(k);
00845 fprintf(FP,"%12s, %11s, %11.3e, %11.3e, %11.3e, %11.3e, %11.3e,"
00846 "%11.3e, %11.3e, %11.3e, %11.3e, %11.3e\n",
00847 sName.c_str(),
00848 phaseName.c_str(), TMolesPhase,
00849 mf[istart + k], molalities[k], ac[k], activity[k],
00850 mu0[k]*1.0E-6, mu[k]*1.0E-6,
00851 mf[istart + k] * TMolesPhase,
00852 VolPM[k], VolPhaseVolumes );
00853 }
00854
00855 } else {
00856 if (iphase == 0) {
00857 fprintf(FP," Name, Phase, PhaseMoles, Mole_Fract, "
00858 "Molalities, ActCoeff, Activity,"
00859 " ChemPotSS0, ChemPot, mole_num, PMVol, Phase_Volume\n");
00860
00861 fprintf(FP," , , (kmol), , "
00862 " , , ,"
00863 " (J/kmol), (J/kmol), (kmol), (m**3/kmol), (m**3)\n");
00864 }
00865 for (k = 0; k < nSpecies; k++) {
00866 molalities[k] = 0.0;
00867 }
00868 for (k = 0; k < nSpecies; k++) {
00869 sName = tp->speciesName(k);
00870 fprintf(FP,"%12s, %11s, %11.3e, %11.3e, %11.3e, %11.3e, %11.3e, "
00871 "%11.3e, %11.3e,% 11.3e, %11.3e, %11.3e\n",
00872 sName.c_str(),
00873 phaseName.c_str(), TMolesPhase,
00874 mf[istart + k], molalities[k], ac[k],
00875 activity[k], mu0[k]*1.0E-6, mu[k]*1.0E-6,
00876 mf[istart + k] * TMolesPhase,
00877 VolPM[k], VolPhaseVolumes );
00878 }
00879 }
00880
00881 #ifdef DEBUG_MODE
00882
00883
00884
00885 tp->getChemPotentials(fe+istart);
00886 for (k = 0; k < nSpecies; k++) {
00887 if (!vcs_doubleEqual(fe[istart+k], mu[k])) {
00888 fprintf(FP,"ERROR: incompatibility!\n");
00889 fclose(FP);
00890 plogf("ERROR: incompatibility!\n");
00891 exit(EXIT_FAILURE);
00892 }
00893 }
00894 #endif
00895
00896 }
00897 fclose(FP);
00898 }
00899
00900
00901 static void print_char(const char letter, const int num) {
00902 for (int i = 0; i < num; i++) plogf("%c", letter);
00903 }
00904
00905
00906
00907
00908
00909
00910
00911 int vcs_Cantera_to_vprob(Cantera::MultiPhase *mphase,
00912 VCSnonideal::VCS_PROB *vprob) {
00913 int k;
00914 VCS_SPECIES_THERMO *ts_ptr = 0;
00915
00916
00917
00918
00919 int totNumPhases = mphase->nPhases();
00920 int totNumSpecies = mphase->nSpecies();
00921
00922
00923 vprob->prob_type = 0;
00924 vprob->nspecies = totNumSpecies;
00925 vprob->ne = 0;
00926 vprob->NPhase = totNumPhases;
00927 vprob->m_VCS_UnitsFormat = VCS_UNITS_MKS;
00928
00929
00930 vprob->iest = -1;
00931 vprob->T = mphase->temperature();
00932 vprob->PresPA = mphase->pressure();
00933 vprob->Vol = mphase->volume();
00934 vprob->Title = "MultiPhase Object";
00935
00936 Cantera::ThermoPhase *tPhase = 0;
00937
00938 int iSurPhase = -1;
00939 bool gasPhase;
00940 int printLvl = vprob->m_printLvl;
00941
00942
00943
00944
00945 int kT = 0;
00946 for (int iphase = 0; iphase < totNumPhases; iphase++) {
00947
00948
00949
00950
00951 iSurPhase = -1;
00952 tPhase = &(mphase->phase(iphase));
00953 int nelem = tPhase->nElements();
00954
00955
00956
00957
00958
00959 int eos = tPhase->eosType();
00960 if (eos == cIdealGas) gasPhase = true;
00961 else gasPhase = false;
00962
00963
00964
00965
00966 int nSpPhase = tPhase->nSpecies();
00967
00968
00969
00970 string phaseName = tPhase->name();
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982 vcs_VolPhase *VolPhase = vprob->VPhaseList[iphase];
00983 VolPhase->resize(iphase, nSpPhase, nelem, phaseName.c_str(), 0.0);
00984 VolPhase->m_gasPhase = gasPhase;
00985
00986
00987
00988 VolPhase->p_VCS_UnitsFormat = vprob->m_VCS_UnitsFormat;
00989 VolPhase->setPtrThermoPhase(tPhase);
00990 VolPhase->setTotalMoles(0.0);
00991
00992
00993
00994
00995 VolPhase->setElectricPotential(tPhase->electricPotential());
00996
00997
00998
00999
01000 VolPhase->p_activityConvention = tPhase->activityConvention();
01001
01002
01003
01004
01005 switch (eos) {
01006 case cIdealGas:
01007 VolPhase->m_eqnState = VCS_EOS_IDEAL_GAS;
01008 break;
01009 case cIncompressible:
01010 VolPhase->m_eqnState = VCS_EOS_CONSTANT;
01011 break;
01012 case cSurf:
01013 plogf("cSurf not handled yet\n");
01014 exit(EXIT_FAILURE);
01015 case cStoichSubstance:
01016 VolPhase->m_eqnState = VCS_EOS_STOICH_SUB;
01017 break;
01018 case cPureFluid:
01019 if (printLvl > 1) {
01020 plogf("cPureFluid not recognized yet by VCSnonideal\n");
01021 }
01022 break;
01023 case cEdge:
01024 plogf("cEdge not handled yet\n");
01025 exit(EXIT_FAILURE);
01026 case cIdealSolidSolnPhase0:
01027 case cIdealSolidSolnPhase1:
01028 case cIdealSolidSolnPhase2:
01029 VolPhase->m_eqnState = VCS_EOS_IDEAL_SOLN;
01030 break;
01031 default:
01032 if (printLvl > 1) {
01033 plogf("Unknown Cantera EOS to VCSnonideal: %d\n", eos);
01034 }
01035 VolPhase->m_eqnState = VCS_EOS_UNK_CANTERA;
01036 if (!VolPhase->usingCanteraCalls()) {
01037 plogf("vcs functions asked for, but unimplemented\n");
01038 exit(EXIT_FAILURE);
01039 }
01040 break;
01041 }
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053 VolPhase->transferElementsFM(tPhase);
01054
01055
01056
01057
01058
01059 vprob->addPhaseElements(VolPhase);
01060
01061 VolPhase->setState_TP(vprob->T, vprob->PresPA);
01062 vector<double> muPhase(tPhase->nSpecies(),0.0);
01063 tPhase->getChemPotentials(&muPhase[0]);
01064 double tMoles = 0.0;
01065
01066
01067
01068 for (k = 0; k < nSpPhase; k++) {
01069
01070
01071
01072
01073 vprob->WtSpecies[kT] = tPhase->molecularWeight(k);
01074
01075
01076
01077
01078
01079 vprob->Charge[kT] = tPhase->charge(k);
01080
01081
01082
01083
01084 vprob->PhaseID[kT] = iphase;
01085
01086
01087
01088
01089 string stmp = mphase->speciesName(kT);
01090 vprob->SpName[kT] = stmp;
01091
01092
01093
01094
01095
01096
01097 vprob->w[kT] = mphase->speciesMoles(kT);
01098 tMoles += vprob->w[kT];
01099 vprob->mf[kT] = mphase->moleFraction(kT);
01100
01101
01102
01103
01104 vprob->m_gibbsSpecies[kT] = muPhase[k];
01105
01106
01107
01108 vprob->SpeciesUnknownType[kT] = VolPhase->speciesUnknownType(k);
01109
01110
01111
01112
01113
01114
01115
01116 vprob->addOnePhaseSpecies(VolPhase, k, kT);
01117
01118
01119
01120
01121 ts_ptr = vprob->SpeciesThermo[kT];
01122
01123
01124
01125 vcs_SpeciesProperties *sProp = VolPhase->speciesProperty(k);
01126 sProp->NumElements = vprob->ne;
01127 sProp->SpName = vprob->SpName[kT];
01128 sProp->SpeciesThermo = ts_ptr;
01129 sProp->WtSpecies = tPhase->molecularWeight(k);
01130 sProp->FormulaMatrixCol.resize(vprob->ne, 0.0);
01131 for (int e = 0; e < vprob->ne; e++) {
01132 sProp->FormulaMatrixCol[e] = vprob->FormulaMatrix[e][kT];
01133 }
01134 sProp->Charge = tPhase->charge(k);
01135 sProp->SurfaceSpecies = false;
01136 sProp->VolPM = 0.0;
01137
01138
01139
01140
01141
01142 ts_ptr->UseCanteraCalls = VolPhase->usingCanteraCalls();
01143 ts_ptr->m_VCS_UnitsFormat = VolPhase->p_VCS_UnitsFormat;
01144
01145
01146
01147 ts_ptr->IndexPhase = iphase;
01148 ts_ptr->IndexSpeciesPhase = k;
01149 ts_ptr->OwningPhase = VolPhase;
01150
01151
01152
01153 SpeciesThermo &sp = tPhase->speciesThermo();
01154
01155 int spType;
01156 double c[150];
01157 double minTemp, maxTemp, refPressure;
01158 sp.reportParams(k, spType, c, minTemp, maxTemp, refPressure);
01159
01160 if (spType == SIMPLE) {
01161 ts_ptr->SS0_Model = VCS_SS0_CONSTANT;
01162 ts_ptr->SS0_T0 = c[0];
01163 ts_ptr->SS0_H0 = c[1];
01164 ts_ptr->SS0_S0 = c[2];
01165 ts_ptr->SS0_Cp0 = c[3];
01166 if (gasPhase) {
01167 ts_ptr->SSStar_Model = VCS_SSSTAR_IDEAL_GAS;
01168 ts_ptr->SSStar_Vol_Model = VCS_SSVOL_IDEALGAS;
01169 } else {
01170 ts_ptr->SSStar_Model = VCS_SSSTAR_CONSTANT;
01171 ts_ptr->SSStar_Vol_Model = VCS_SSVOL_CONSTANT;
01172 }
01173 ts_ptr->Activity_Coeff_Model = VCS_AC_CONSTANT;
01174 ts_ptr->Activity_Coeff_Params = NULL;
01175 } else {
01176 if (vprob->m_printLvl > 2) {
01177 plogf("vcs_Cantera_convert: Species Type %d not known \n",
01178 spType);
01179 }
01180 ts_ptr->SS0_Model = VCS_SS0_NOTHANDLED;
01181 ts_ptr->SSStar_Model = VCS_SSSTAR_NOTHANDLED;
01182 if (!(ts_ptr->UseCanteraCalls )) {
01183 plogf("Cantera calls not being used -> exiting\n");
01184 exit(EXIT_FAILURE);
01185 }
01186 }
01187
01188
01189
01190
01191 if (gasPhase) {
01192 ts_ptr->SSStar_Vol_Model = VCS_SSVOL_IDEALGAS;
01193 ts_ptr->SSStar_Vol_Params = NULL;
01194 ts_ptr->SSStar_Vol0 = 82.05 * 273.15 / 1.0;
01195
01196 } else {
01197 std::vector<double> phaseTermCoeff(nSpPhase, 0.0);
01198 int nCoeff;
01199 tPhase->getParameters(nCoeff, VCS_DATA_PTR(phaseTermCoeff));
01200 ts_ptr->SSStar_Vol_Model = VCS_SSVOL_CONSTANT;
01201 ts_ptr->SSStar_Vol0 = phaseTermCoeff[k];
01202 }
01203 kT++;
01204 }
01205
01206
01207
01208
01209
01210
01211 if (tMoles > 0.0) {
01212 for (k = 0; k < nSpPhase; k++) {
01213 int kTa = VolPhase->spGlobalIndexVCS(k);
01214 vprob->mf[kTa] = vprob->w[kTa] / tMoles;
01215 }
01216 } else {
01217
01218
01219
01220
01221 for (k = 0; k < nSpPhase; k++) {
01222 int kTa = VolPhase->spGlobalIndexVCS(k);
01223 vprob->mf[kTa]= 1.0 / (double) nSpPhase;
01224 }
01225 }
01226
01227 VolPhase->setMolesFromVCS(VCS_STATECALC_OLD, VCS_DATA_PTR(vprob->w));
01228
01229
01230
01231
01232 double R = vcsUtil_gasConstant(vprob->m_VCS_UnitsFormat);
01233 for (k = 0; k < nSpPhase; k++) {
01234 vcs_SpeciesProperties *sProp = VolPhase->speciesProperty(k);
01235 ts_ptr = sProp->SpeciesThermo;
01236 ts_ptr->SS0_feSave = VolPhase->G0_calc_one(k)/ R;
01237 ts_ptr->SS0_TSave = vprob->T;
01238 }
01239
01240 }
01241
01242
01243
01244
01245
01246
01247 vprob->gai.resize(vprob->ne, 0.0);
01248 vprob->set_gai();
01249
01250
01251
01252
01253 if (vprob->m_printLvl > 1) {
01254 plogf("\n"); print_char('=', 80); plogf("\n");
01255 print_char('=', 16);
01256 plogf(" Cantera_to_vprob: START OF PROBLEM STATEMENT ");
01257 print_char('=', 20); plogf("\n");
01258 print_char('=', 80); plogf("\n");
01259 plogf(" Phase IDs of species\n");
01260 plogf(" species phaseID phaseName ");
01261 plogf(" Initial_Estimated_kMols\n");
01262 for (int i = 0; i < vprob->nspecies; i++) {
01263 int iphase = vprob->PhaseID[i];
01264
01265 vcs_VolPhase *VolPhase = vprob->VPhaseList[iphase];
01266 plogf("%16s %5d %16s", vprob->SpName[i].c_str(), iphase,
01267 VolPhase->PhaseName.c_str());
01268 plogf(" %-10.5g\n", vprob->w[i]);
01269 }
01270
01271
01272
01273
01274 plogf("\n"); print_char('-', 80); plogf("\n");
01275 plogf(" Information about phases\n");
01276 plogf(" PhaseName PhaseNum SingSpec GasPhase EqnState NumSpec");
01277 plogf(" TMolesInert Tmoles(kmol)\n");
01278
01279 for (int iphase = 0; iphase < vprob->NPhase; iphase++) {
01280 vcs_VolPhase *VolPhase = vprob->VPhaseList[iphase];
01281 std::string sEOS = string16_EOSType(VolPhase->m_eqnState);
01282 plogf("%16s %5d %5d %8d %16s %8d %16e ", VolPhase->PhaseName.c_str(),
01283 VolPhase->VP_ID, VolPhase->m_singleSpecies,
01284 VolPhase->m_gasPhase, sEOS.c_str(),
01285 VolPhase->nSpecies(), VolPhase->totalMolesInert() );
01286 plogf("%16e\n", VolPhase->totalMoles());
01287 }
01288
01289 plogf("\n"); print_char('=', 80); plogf("\n");
01290 print_char('=', 16);
01291 plogf(" Cantera_to_vprob: END OF PROBLEM STATEMENT ");
01292 print_char('=', 20); plogf("\n");
01293 print_char('=', 80); plogf("\n\n");
01294 }
01295
01296 return VCS_SUCCESS;
01297 }
01298
01299
01300
01301
01302
01303 int vcs_Cantera_update_vprob(Cantera::MultiPhase *mphase,
01304 VCSnonideal::VCS_PROB *vprob) {
01305 int totNumPhases = mphase->nPhases();
01306 int kT = 0;
01307 std::vector<double> tmpMoles;
01308
01309 vprob->prob_type = 0;
01310
01311
01312 vprob->iest = -1;
01313 vprob->T = mphase->temperature();
01314 vprob->PresPA = mphase->pressure();
01315 vprob->Vol = mphase->volume();
01316 Cantera::ThermoPhase *tPhase = 0;
01317
01318 for (int iphase = 0; iphase < totNumPhases; iphase++) {
01319 tPhase = &(mphase->phase(iphase));
01320 vcs_VolPhase *volPhase = vprob->VPhaseList[iphase];
01321
01322
01323
01324
01325 volPhase->setElectricPotential(tPhase->electricPotential());
01326
01327 volPhase->setState_TP(vprob->T, vprob->PresPA);
01328 vector<double> muPhase(tPhase->nSpecies(),0.0);
01329 tPhase->getChemPotentials(&muPhase[0]);
01330
01331
01332
01333 int nSpPhase = tPhase->nSpecies();
01334
01335 tmpMoles.resize(nSpPhase);
01336 for (int k = 0; k < nSpPhase; k++) {
01337 tmpMoles[k] = mphase->speciesMoles(kT);
01338 vprob->w[kT] = mphase->speciesMoles(kT);
01339 vprob->mf[kT] = mphase->moleFraction(kT);
01340
01341
01342
01343
01344 vprob->m_gibbsSpecies[kT] = muPhase[k];
01345
01346 kT++;
01347 }
01348 if (volPhase->phiVarIndex() >= 0) {
01349 int kphi = volPhase->phiVarIndex();
01350 int kglob = volPhase->spGlobalIndexVCS(kphi);
01351 vprob->w[kglob] = tPhase->electricPotential();
01352 }
01353 volPhase->setMolesFromVCS(VCS_STATECALC_OLD, VCS_DATA_PTR(vprob->w));
01354 if ((nSpPhase == 1) && (volPhase->phiVarIndex() == 0)) {
01355 volPhase->setExistence(VCS_PHASE_EXIST_ALWAYS);
01356 } else if (volPhase->totalMoles() > 0.0) {
01357 volPhase->setExistence(VCS_PHASE_EXIST_YES);
01358 } else {
01359 volPhase->setExistence(VCS_PHASE_EXIST_NO);
01360 }
01361
01362 }
01363
01364
01365
01366
01367
01368
01369
01370 vprob->set_gai();
01371
01372
01373
01374
01375 if (vprob->m_printLvl > 1) {
01376 plogf("\n"); print_char('=', 80); plogf("\n");
01377 print_char('=', 20);
01378 plogf(" Cantera_to_vprob: START OF PROBLEM STATEMENT ");
01379 print_char('=', 20); plogf("\n");
01380 print_char('=', 80); plogf("\n\n");
01381 plogf(" Phase IDs of species\n");
01382 plogf(" species phaseID phaseName ");
01383 plogf(" Initial_Estimated_kMols\n");
01384 for (int i = 0; i < vprob->nspecies; i++) {
01385 int iphase = vprob->PhaseID[i];
01386
01387 vcs_VolPhase *VolPhase = vprob->VPhaseList[iphase];
01388 plogf("%16s %5d %16s", vprob->SpName[i].c_str(), iphase,
01389 VolPhase->PhaseName.c_str());
01390 plogf(" %-10.5g\n", vprob->w[i]);
01391 }
01392
01393
01394
01395
01396 plogf("\n"); print_char('-', 80); plogf("\n");
01397 plogf(" Information about phases\n");
01398 plogf(" PhaseName PhaseNum SingSpec GasPhase EqnState NumSpec");
01399 plogf(" TMolesInert Tmoles(kmol)\n");
01400
01401 for (int iphase = 0; iphase < vprob->NPhase; iphase++) {
01402 vcs_VolPhase *VolPhase = vprob->VPhaseList[iphase];
01403 std::string sEOS = string16_EOSType(VolPhase->m_eqnState);
01404 plogf("%16s %5d %5d %8d %16s %8d %16e ", VolPhase->PhaseName.c_str(),
01405 VolPhase->VP_ID, VolPhase->m_singleSpecies,
01406 VolPhase->m_gasPhase, sEOS.c_str(),
01407 VolPhase->nSpecies(), VolPhase->totalMolesInert() );
01408 plogf("%16e\n", VolPhase->totalMoles() );
01409 }
01410
01411 plogf("\n"); print_char('=', 80); plogf("\n");
01412 print_char('=', 20);
01413 plogf(" Cantera_to_vprob: END OF PROBLEM STATEMENT ");
01414 print_char('=', 20); plogf("\n");
01415 print_char('=', 80); plogf("\n\n");
01416 }
01417
01418 return VCS_SUCCESS;
01419 }
01420
01421
01422 void vcs_MultiPhaseEquil::getStoichVector(index_t rxn, Cantera::vector_fp& nu) {
01423 int nsp = m_vsolvePtr->m_numSpeciesTot;
01424 nu.resize(nsp, 0.0);
01425 for (int i = 0; i < nsp; i++) {
01426 nu[i] = 0.0;
01427 }
01428 int nc = numComponents();
01429
01430 const DoubleStarStar &scMatrix = m_vsolvePtr->m_stoichCoeffRxnMatrix;
01431 const std::vector<int> indSpecies = m_vsolvePtr->m_speciesMapIndex;
01432 if ((int) rxn > nsp - nc) return;
01433 int j = indSpecies[rxn + nc];
01434 nu[j] = 1.0;
01435 for (int kc = 0; kc < nc; kc++) {
01436 j = indSpecies[kc];
01437 nu[j] = scMatrix[rxn][kc];
01438 }
01439
01440 }
01441
01442 int vcs_MultiPhaseEquil::numComponents() const {
01443 int nc = -1;
01444 if (m_vsolvePtr) {
01445 nc = m_vsolvePtr->m_numComponents;
01446 }
01447 return nc;
01448 }
01449
01450 int vcs_MultiPhaseEquil::numElemConstraints() const {
01451 int nec = -1;
01452 if (m_vsolvePtr) {
01453 nec = m_vsolvePtr->m_numElemConstraints;
01454 }
01455 return nec;
01456 }
01457
01458
01459 int vcs_MultiPhaseEquil::component(int m) const {
01460 int nc = numComponents();
01461 if (m < nc) return m_vsolvePtr->m_speciesMapIndex[m];
01462 else return -1;
01463 }
01464
01465 }