00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef SOLVER2_H
00023 #define SOLVER2_H
00024
00025 #define SOLVER2_DEBUG
00026 #define SOLVER2BASE_DEBUG Solver2Base<FirstProp,SecondProp,FirstPropAlt,SecondPropAlt>::debug
00027
00028 #include "steamproperty.h"
00029 #include "units.h"
00030 #include "satcurve.h"
00031 #include <stdexcept>
00032 #include "convergencetest.h"
00033 #include "b23curve.h"
00034 #include "boundaries.h"
00035
00037
00053 template<class FirstProp,class SecondProp,int FirstPropAlt=0, int SecondPropAlt=0>
00054 class Solver2Base{
00055
00056 protected:
00057
00058 #ifdef SOLVER2_DEBUG
00059 Solver2Base(const bool debug=false){
00060 this->debug=debug;
00061 }
00062 #else
00063 Solver2Base(){}
00064 #endif
00065
00066 virtual ~Solver2Base(){}
00067
00068 virtual int whichRegion(const FirstProp &fp,const SecondProp &sp) = 0;
00069
00070 virtual SteamCalculator solve(const FirstProp &fp, const SecondProp &sp) = 0;
00071
00072 FirstProp getFirstProp(SteamCalculator &S){
00073 return SteamProperty<FirstProp,FirstPropAlt>::get(S);
00074 }
00075
00076 SecondProp getSecondProp(SteamCalculator &S){
00077 return SteamProperty<SecondProp,SecondPropAlt>::get(S);
00078 }
00079
00080 #ifdef SOLVER2_DEBUG
00081 bool debug;
00082 #endif
00083
00084 };
00085
00087
00116 template<class FirstProp,class SecondProp,int FirstPropAlt=0, int SecondPropAlt=0>
00117 class Solver2
00118 : public Solver2Base<FirstProp,SecondProp,FirstPropAlt,SecondPropAlt>{
00119
00120 private:
00121 static const int maxiter=30;
00122
00124
00131 SteamCalculator makeRegion1Guess(const FirstProp& f, const SecondProp &s){
00132 SteamCalculator S;
00133 S.set_pT(10.0 * bar, fromcelsius(100));
00134 return S;
00135 }
00136
00137
00139
00145 SteamCalculator makeRegion2Guess(const FirstProp& f, const SecondProp &s){
00146 SteamCalculator S;
00147 S.set_pT(6.0 * MPa, fromcelsius(400));
00148 return S;
00149 }
00150
00152
00158 SteamCalculator makeRegion3Guess(const FirstProp& f, const SecondProp &s){
00159 SteamCalculator S;
00160 S.setRegion3_rhoT(1 / 0.00317 * kg_m3, fromcelsius(400));
00161 return S;
00162 }
00163
00165
00171 SteamCalculator makeRegion4Guess(const FirstProp& f, const SecondProp &s){
00172 SteamCalculator S;
00173 S.setRegion4_Tx(fromcelsius(263.9),0.5);
00174 return S;
00175 }
00176
00177 public:
00178
00179 #ifdef SOLVER2_DEBUG
00180 Solver2(const bool debug=false)
00181 : Solver2Base<FirstProp,SecondProp,FirstPropAlt,SecondPropAlt>(debug){
00182 #else
00183 Solver2()
00184 : Solver2Base<FirstProp,SecondProp,FirstPropAlt,SecondPropAlt>(){
00185 #endif
00186
00187 }
00188
00189 ~Solver2(){
00190
00191
00192 }
00193
00195
00208 int whichRegion(const FirstProp &fp, const SecondProp &sp);
00209
00211
00217 SteamCalculator solve(const FirstProp &fp, const SecondProp &sp){
00218 int region = 0;
00219 SteamCalculator S,S2;
00220
00221 try{
00222
00223
00224 region = whichRegion(fp,sp);
00225
00226 }catch(std::exception &E){
00227 std::stringstream ss;
00228 ss << "Solver2<" << SteamProperty<FirstProp,FirstPropAlt>::name() << "," << SteamProperty<SecondProp,SecondPropAlt>::name() << ">::solve (no first guess): " << E.what();
00229 throw std::runtime_error(ss.str());
00230 }
00231
00232 try{
00233
00234 switch(region){
00235 case 1:
00236 S2 = solveRegion1(fp,sp,makeRegion1Guess(fp,sp));
00237 break;
00238 case 2:
00239 S2 = solveRegion2(fp,sp,makeRegion2Guess(fp,sp));
00240 break;
00241 case 3:
00242 S2 = solveRegion3(fp,sp,makeRegion3Guess(fp,sp));
00243 break;
00244 case 4:
00245 S2 = solveRegion4(fp,sp,makeRegion4Guess(fp,sp));
00246 break;
00247 default:
00248 std::stringstream ss;
00249 ss << "Invalid return from whichRegion(" << fp << "," << sp << "): region = " << region;
00250 throw std::runtime_error(ss.str());
00251 }
00252 }catch(std::exception &E){
00253 std::stringstream s;
00254 s << "Solver2<" << SteamProperty<FirstProp,FirstPropAlt>::name() << "," << SteamProperty<SecondProp,SecondPropAlt>::name() << ">::solve (no first guess; found region=" << region << "): " << E.what();
00255 throw std::runtime_error(s.str());
00256 }
00257
00258 return S2;
00259 }
00260
00262
00273 SteamCalculator solve(const FirstProp &fp, const SecondProp &sp, const SteamCalculator &firstguess){
00274 int region=0;
00275 try{
00276 region = whichRegion(fp,sp);
00277
00278 if(!firstguess.isSet() || firstguess.whichRegion()!=region){
00279 return solve(fp,sp);
00280 }
00281
00282 switch(region){
00283 case 1:
00284 return solveRegion1(fp,sp,firstguess);
00285 case 2:
00286 return solveRegion2(fp,sp,firstguess);
00287 case 3:
00288 return solveRegion3(fp,sp,firstguess);
00289 case 4:
00290 return solveRegion4(fp,sp,firstguess);
00291 default:
00292 std::stringstream s;
00293 s << "Invalid region returned, '" << region << "'";
00294 throw std::runtime_error(s.str());
00295 }
00296
00297 }catch(std::exception &E){
00298 std::stringstream ss;
00299 ss.flags(std::ios_base::showbase);
00300
00301 ss << "Solver2<" << SteamProperty<FirstProp,FirstPropAlt>::name() << "," << SteamProperty<SecondProp,SecondPropAlt>::name() << ">::solve (" << SteamProperty<FirstProp,FirstPropAlt>::name() << "=" << fp << ", " << SteamProperty<SecondProp,SecondPropAlt>::name() << "=" << sp;
00302
00303 ss << "; found region="<< region;
00304
00305 if(firstguess.isSet()){
00306 ss << "; given first guess with " << SteamProperty<FirstProp,FirstPropAlt>::name() << "=" << SteamProperty<FirstProp,FirstPropAlt>::get(firstguess) << ", " << SteamProperty<SecondProp,SecondPropAlt>::name() << "=" << SteamProperty<SecondProp,SecondPropAlt>::get(firstguess);
00307 }else{
00308 ss << "; given uninitialised first guess";
00309 }
00310
00311 ss << "): " << E.what();
00312
00313 throw std::runtime_error(ss.str());
00314 }
00315 }
00316
00317 private:
00318
00320 SteamCalculator solveRegion3(const FirstProp &f1, const SecondProp &s1,const SteamCalculator &firstguess){
00321 try{
00322
00323
00324
00325
00326
00327
00328 SteamCalculator guess = firstguess;
00329
00330
00331
00332 if(firstguess.whichRegion()!=3){
00333 throw std::runtime_error("Solver2::solveRegion3: First guess is not region3");
00334 }
00335
00336 SteamCalculator petT, petrho;
00337 Temperature T,dT;
00338 Density rho,drho;
00339 FirstProp f,Df, DfT, Dfrho;
00340 SecondProp s,Ds,DsT, Dsrho;
00341 Pressure p;
00342
00343
00344
00345
00346 int niter=0;
00347 while(1){
00348
00349 T = guess.temp();
00350 rho = guess.dens();
00351 p = guess.pres();
00352
00353
00354
00355 f = SteamProperty<FirstProp,FirstPropAlt>::get(guess);
00356 s = SteamProperty<SecondProp,SecondPropAlt>::get(guess);
00357
00358
00359
00360
00361 Df = f1 - f;
00362 Ds = s1 - s;
00363
00364
00365 if(
00366 ConvergenceTest<FirstProp,FirstPropAlt>::test(Df,p,T)
00367 && ConvergenceTest<SecondProp,SecondPropAlt>::test(Ds,p,T)
00368 ){
00369
00370 return guess;
00371 }
00372
00373 dT = T * 0.001;
00374
00375 if(T + dT > T_MAX){
00376 dT = -dT;
00377 }
00378
00379 petT.setRegion3_rhoT(rho, T + dT);
00380 ASSERT(petT.whichRegion()==3);
00381
00382
00383 drho = rho * 0.001;
00384 if(rho + drho > 50.0 * kg_m3){
00385 drho = -drho;
00386 }
00387
00388 petrho.setRegion3_rhoT(rho + drho, T);
00389 ASSERT(petrho.whichRegion()==3);
00390
00391 DfT = SteamProperty<FirstProp,FirstPropAlt>::get(petT) - f;
00392 DsT = SteamProperty<SecondProp,SecondPropAlt>::get(petT) - s;
00393
00394 Dfrho = SteamProperty<FirstProp,FirstPropAlt>::get(petrho) - f;
00395 Dsrho = SteamProperty<SecondProp,SecondPropAlt>::get(petrho) - s;
00396
00397 ASSERT(DfT * Dsrho != DsT * Dfrho);
00398
00399
00400 dT = dT * (Df*Dsrho - Ds*Dfrho) / (DfT*Dsrho - DsT*Dfrho);
00401 drho = drho * (DfT*Ds - DsT*Df) / (DfT*Dsrho - DsT*Dfrho);
00402
00403 ASSERT(!isnan(dT));
00404 ASSERT(!isnan(drho));
00405
00406
00407
00408 Temperature dTMax = 0.1 * T;
00409 Temperature dTAbs = fabs(dT);
00410 if(dTAbs > dTMax){
00411
00412 dT = dT * dTMax/dTAbs;
00413 }
00414
00415
00416
00417 Density drhoMax = 0.4 * rho;
00418 Density drhoAbs = fabs(drho);
00419 if(drhoAbs > drhoMax){
00420
00421 drho = drho * drhoMax/drhoAbs;
00422 }
00423
00424
00425 T = T + dT;
00426 rho = rho + drho;
00427
00428 if(T > T_MAX){
00429
00430
00431
00432 T = T_MAX;
00433 }
00434
00435 if(T < T_REG1_REG3){
00436
00437 T = T_REG1_REG3;
00438 }
00439
00440 Density rho_b134;
00441 SteamCalculator S;
00442 S.setSatWater_T(T_REG1_REG3);
00443 rho_b134 = S.dens();
00444 if(rho < rho_b134 && T < T_CRIT){
00445 if(rho < RHO_CRIT){
00446 Density rho_g = Boundaries::getSatDensSteam_T(T);
00447 if(rho > rho_g){
00448
00449 rho = rho_g;
00450 }
00451 }else if(rho > RHO_CRIT){
00452 Density rho_f = Boundaries::getSatDensWater_T(T);
00453 if(rho < rho_f){
00454
00455 rho = rho_f;
00456 }
00457 }
00458
00459 }
00460
00461 B23Curve<Density,Temperature> B23;
00462 Density rho_b23 = B23.solve(T);
00463 if(rho < rho_b23){
00464 rho = rho_b23;
00465 }
00466
00467 S.setRegion3_rhoT(rho,T);
00468 int pmaxiter = 0;
00469 if(S.pres() > P_MAX){
00470 do{
00471
00472
00473 drho *= 0.5001;
00474
00475 rho -= drho;
00476
00477 S.setRegion3_rhoT(rho,T);
00478
00479 if(++pmaxiter > 20){
00480 throw std::runtime_error("Solver2::solveRegion3: Failed to find rho of P_MAX");
00481 }
00482
00483 }while(S.pres() > P_MAX);
00484
00485 }
00486
00487 guess.setRegion3_rhoT(rho,T);
00488
00489 niter++;
00490
00491 if(niter > maxiter){
00492 throw std::runtime_error("Solver2::solveRegion3: Exceeded maximum iterations");
00493 }
00494 }
00495
00496 }catch(std::exception &E){
00497 std::stringstream s;
00498 s << "Solver2<" << SteamProperty<FirstProp,FirstPropAlt>::name() << "," << SteamProperty<SecondProp,SecondPropAlt>::name() << ">:solveRegion3: " << E.what();
00499 throw std::runtime_error(s.str());
00500 }
00501 }
00502
00504 SteamCalculator solveRegion4(const FirstProp &f1, const SecondProp &s1,const SteamCalculator &firstguess){
00505
00506 try{
00507
00508
00509
00510
00511 SteamCalculator guess = firstguess;
00512
00513
00514
00515 if(firstguess.whichRegion()!=4){
00516 throw std::runtime_error("Solver2::solveRegion4: First guess is not region 4");
00517 }
00518
00519 SteamCalculator petT, petx;
00520 Temperature T,dT;
00521 Num x,dx;
00522 FirstProp f,Df, DfT, Dfx;
00523 SecondProp s,Ds,DsT, Dsx;
00524 Pressure p;
00525
00526
00527
00528 int niter=0;
00529 while(1){
00530
00531 T = guess.temp();
00532 x = guess.quality();
00533 p = guess.pres();
00534
00535
00536
00537 f = SteamProperty<FirstProp,FirstPropAlt>::get(guess);
00538 s = SteamProperty<SecondProp,SecondPropAlt>::get(guess);
00539
00540
00541
00542
00543 Df = f1 - f;
00544 Ds = s1 - s;
00545
00546
00547 if(
00548 ConvergenceTest<FirstProp,FirstPropAlt>::test(Df,p,T)
00549 && ConvergenceTest<SecondProp,SecondPropAlt>::test(Ds,p,T)
00550 ){
00551
00552 return guess;
00553 }
00554
00555 dT = -T * 0.001;
00556
00557 if(T + dT < T_TRIPLE){
00558 dT = -dT;
00559 }
00560
00561 Boundaries::isSat_Tx(T+dT,x, true);
00562
00563 petT.setRegion4_Tx(T + dT, x);
00564 ASSERT(petT.whichRegion()==4);
00565
00566
00567 dx = 0.0001;
00568 if(x + dx > 1.0){
00569 dx = -dx;
00570 }
00571
00572 Boundaries::isSat_Tx(T, x+dx, true);
00573
00574 petx.setRegion4_Tx(T, x + dx);
00575 ASSERT(petx.whichRegion()==4);
00576
00577 DfT = SteamProperty<FirstProp,FirstPropAlt>::get(petT) - f;
00578 DsT = SteamProperty<SecondProp,SecondPropAlt>::get(petT) - s;
00579
00580 Dfx = SteamProperty<FirstProp,FirstPropAlt>::get(petx) - f;
00581 Dsx = SteamProperty<SecondProp,SecondPropAlt>::get(petx) - s;
00582
00583
00584
00585
00586
00587 ASSERT(DfT * Dsx != DsT * Dfx);
00588
00589
00590
00591
00592
00593
00594
00595 dT = dT * (Df*Dsx - Ds*Dfx) / (DfT*Dsx - DsT*Dfx);
00596 dx = dx * (DfT*Ds - DsT*Df) / (DfT*Dsx - DsT*Dfx);
00597
00598 ASSERT(!isnan(dT));
00599 ASSERT(!isnan(dx));
00600
00601
00602
00603 Temperature dTMax = 0.1 * T;
00604 Temperature dTAbs = fabs(dT);
00605 if(dTAbs > dTMax){
00606
00607 dT = dT * dTMax/dTAbs;
00608 }
00609
00610
00611
00612 Num dxMax = 0.2;
00613 Num dxAbs = fabs(dx);
00614 if(dxAbs > dxMax){
00615
00616 dx = dx * dxMax/dxAbs;
00617 }
00618
00619
00620 T = T + dT;
00621 x = x + dx;
00622
00623
00624 if(T > T_CRIT){
00625
00626 T = T_CRIT;
00627 }else if(T < T_TRIPLE){
00628
00629 T = T_TRIPLE;
00630 }
00631
00632
00633 if(x > 1){
00634
00635 x = 1;
00636 }else if(x < 0){
00637
00638 x = 0;
00639 }
00640
00641 Boundaries::isSat_Tx(T, x, true);
00642 guess.setRegion4_Tx(T,x);
00643
00644 niter++;
00645
00646 if(niter > maxiter){
00647 throw std::runtime_error("Solver2::solveRegion4: Exceeded maximum iterations");
00648 }
00649 }
00650 }catch(std::exception &E){
00651 std::stringstream s;
00652 s<< "Solver2::solveRegion4: " << E.what();
00653 throw std::runtime_error(s.str());
00654 }
00655 }
00656
00658 SteamCalculator solveRegion1(const FirstProp &f1, const SecondProp &s1,const SteamCalculator &firstguess){
00659
00660 SteamCalculator guess = firstguess;
00661
00662 if(firstguess.whichRegion()!=1){
00663 throw std::runtime_error("Solver2::solveRegion1: First guess is not region 1");
00664 }
00665
00666 SteamCalculator petT, petp;
00667 Temperature T,dT;
00668 Pressure p,dp;
00669 FirstProp f,Df, DfT, Dfp;
00670 SecondProp s,Ds,DsT, Dsp;
00671
00672 int niter=0;
00673
00674
00675 while(1){
00676
00677 T = guess.temp();
00678 p = guess.pres();
00679
00680
00681
00682 f = SteamProperty<FirstProp,FirstPropAlt>::get(guess);
00683 s = SteamProperty<SecondProp,SecondPropAlt>::get(guess);
00684
00685
00686
00687
00688 Df = f1 - f;
00689 Ds = s1 - s;
00690
00691
00692 if(
00693 ConvergenceTest<FirstProp,FirstPropAlt>::test(Df,p,T)
00694 && ConvergenceTest<SecondProp,SecondPropAlt>::test(Ds,p,T)
00695 ){
00696
00697 return guess;
00698 }
00699
00700 dT = -T * 0.001;
00701
00702 if(T + dT < T_TRIPLE){
00703 dT = -dT;
00704 }
00705
00706 petT.set_pT(p,T + dT);
00707 ASSERT(petT.whichRegion()==1);
00708
00709
00710 dp = p * 0.001;
00711 if(p > 99.0 * MPa){
00712 dp = -dp;
00713 }
00714
00715 petp.set_pT(p + dp, T);
00716 ASSERT(petp.whichRegion()==1);
00717
00718 DfT = SteamProperty<FirstProp,FirstPropAlt>::get(petT) - f;
00719 DsT = SteamProperty<SecondProp,SecondPropAlt>::get(petT) - s;
00720
00721 Dfp = SteamProperty<FirstProp,FirstPropAlt>::get(petp) - f;
00722 Dsp = SteamProperty<SecondProp,SecondPropAlt>::get(petp) - s;
00723
00724
00725 dT = dT * (Df*Dsp - Ds*Dfp) / (DfT*Dsp - DsT*Dfp);
00726 dp = dp * (DfT*Ds - DsT*Df) / (DfT*Dsp - DsT*Dfp);
00727
00728
00729
00730 Temperature dTMax = 0.1 * T;
00731 Temperature dTAbs = fabs(dT);
00732 if(dTAbs > dTMax){
00733
00734 dT = dT * dTMax/dTAbs;
00735 }
00736
00737
00738
00739 Pressure dpMax = 0.4 * p;
00740 Pressure dpAbs = fabs(dp);
00741 if(dpAbs > dpMax){
00742
00743 dp = dp * dpMax/dpAbs;
00744 }
00745
00746
00747 T = T + dT;
00748 p = p + dp;
00749
00750
00751 if(T > T_REG1_REG3){
00752
00753 T = T_REG1_REG3;
00754 }else if(T < T_TRIPLE){
00755
00756 T = T_TRIPLE;
00757 }
00758
00759
00760 if(p > P_MAX){
00761
00762 p = P_MAX;
00763 }else if(p < P_TRIPLE){
00764
00765 p = P_TRIPLE;
00766 }else if(p < PB_LOW){
00767 Pressure p_sat = Boundaries::getSatPres_T(T);
00768 if(p < p_sat){
00769
00770 p = p_sat;
00771 }
00772 }
00773
00774 ASSERT(guess.whichRegion()==1);
00775 ASSERT(Boundaries::isRegion1_pT(p,T));
00776
00777 guess.setRegion1_pT(p,T);
00778
00779 niter++;
00780
00781 if(niter > maxiter){
00782 throw std::runtime_error("Solver2::solveRegion1: Exceeded maximum iterations");
00783 }
00784 }
00785 }
00786
00788 SteamCalculator solveRegion2(const FirstProp &f1, const SecondProp &s1,const SteamCalculator &firstguess){
00789
00790
00791
00792 #ifdef SOLVER2_DEBUG
00793 if(SOLVER2BASE_DEBUG){
00794 std::cerr << std::endl << "---------------------------------" << std::endl << "SOLVE REGION 2";
00795 }
00796 #endif
00797
00798 SteamCalculator guess = firstguess;
00799
00800 if(firstguess.whichRegion()!=2){
00801 throw std::runtime_error("Solver2::solveRegion2: First guess is not region 2");
00802 }
00803
00804 SteamCalculator petT, petp;
00805 Temperature T,dT;
00806 Pressure p,dp;
00807 FirstProp f,Df, DfT, Dfp;
00808 SecondProp s,Ds,DsT, Dsp;
00809
00810 int niter=0;
00811
00812
00813 while(1){
00814
00815 T = guess.temp();
00816 p = guess.pres();
00817
00818 #ifdef SOLVER2_DEBUG
00819 if(SOLVER2BASE_DEBUG){
00820 std::cerr << std::endl << "Iter " << niter << ": p = " << p / MPa << " MPa, T = " << T << " (" << tocelsius(T) << "°C)";
00821 }
00822 #endif
00823
00824 f = SteamProperty<FirstProp,FirstPropAlt>::get(guess);
00825 s = SteamProperty<SecondProp,SecondPropAlt>::get(guess);
00826
00827 #ifdef SOLVER2_DEBUG
00828 if(SOLVER2BASE_DEBUG){
00829 std::cerr << ": " << SteamProperty<FirstProp,FirstPropAlt>::name() << " = " << f;
00830 std::cerr << ", " << SteamProperty<SecondProp,SecondPropAlt>::name() << " = " << s;
00831 }
00832 #endif
00833
00834 Df = f1 - f;
00835 Ds = s1 - s;
00836
00837 if(
00838 ConvergenceTest<FirstProp,FirstPropAlt>::test(Df,p,T)
00839 && ConvergenceTest<SecondProp,SecondPropAlt>::test(Ds,p,T)
00840 ){
00841
00842 return guess;
00843 }
00844
00845
00846 dT = T * 0.001;
00847 if(T + dT > T_MAX){
00848 dT = -dT;
00849 }
00850
00851 petT.set_pT(p,T+ dT);
00852 ASSERT(petT.whichRegion()==2);
00853
00854
00855 dp = -p * 0.001;
00856 if(p + dp < P_TRIPLE){
00857 dp = -dp;
00858 }
00859 petp.set_pT(p + dp, T);
00860 ASSERT(petp.whichRegion()==2);
00861
00862 DfT = SteamProperty<FirstProp,FirstPropAlt>::get(petT) - f;
00863 DsT = SteamProperty<SecondProp,SecondPropAlt>::get(petT) - s;
00864
00865 Dfp = SteamProperty<FirstProp,FirstPropAlt>::get(petp) - f;
00866 Dsp = SteamProperty<SecondProp,SecondPropAlt>::get(petp) - s;
00867
00868
00869 dT = dT * (Df*Dsp - Ds*Dfp) / (DfT*Dsp - DsT*Dfp);
00870 dp = dp * (DfT*Ds - DsT*Df) / (DfT*Dsp - DsT*Dfp);
00871
00872
00873
00874 Temperature dTMax = 0.2 * T;
00875 Temperature dTAbs = fabs(dT);
00876 if(dTAbs > dTMax){
00877
00878 dT = dT * dTMax/dTAbs;
00879 }
00880
00881
00882
00883 Pressure dpMax = 0.5 * p;
00884 Pressure dpAbs = fabs(dp);
00885 if(dpAbs > dpMax){
00886
00887 dp = dp * dpMax/dpAbs;
00888 }
00889
00890
00891 T = T + dT;
00892 p = p + dp;
00893
00894
00895 if(T > T_MAX){
00896
00897 T = T_MAX;
00898 }else if(T < T_TRIPLE){
00899
00900 T = T_TRIPLE;
00901 }
00902
00903
00904 if(p < P_TRIPLE){
00905
00906 p = P_TRIPLE;
00907 }else if(T > TB_LOW){
00908 Pressure pbound = Boundaries::getpbound_T(T);
00909 if(p > pbound){
00910
00911 p = pbound;
00912 }
00913 }else{
00914 Pressure psat = Boundaries::getSatPres_T(T);
00915 if(p > psat){
00916
00917 p = psat;
00918 }
00919 }
00920
00921 ASSERT(guess.whichRegion()==2);
00922 ASSERT(Boundaries::isRegion2_pT(p,T));
00923
00924 guess.setRegion2_pT(p,T);
00925
00926 niter++;
00927
00928 if(niter > maxiter){
00929 throw std::runtime_error("Solver2::solveRegion2: Exceeded maximum iterations");
00930 }
00931 }
00932
00933 }
00934 };
00935
00936 template<>
00937 SteamCalculator
00938 Solver2<Pressure,Temperature,0,0>::solveRegion3(
00939 const Pressure &p, const Temperature &T, const SteamCalculator &firstguess
00940 );
00941
00942 template<>
00943 SteamCalculator
00944 Solver2<Pressure,Temperature,0,0>::makeRegion1Guess(
00945 const Pressure& p, const Temperature &T
00946 );
00947
00948 template<>
00949 SteamCalculator
00950 Solver2<Pressure,Temperature,0,0>::makeRegion2Guess(
00951 const Pressure& p, const Temperature &T
00952 );
00953
00954 template<>
00955 SteamCalculator
00956 Solver2<Pressure,Temperature,0,0>::solveRegion3(
00957 const Pressure &p, const Temperature &T, const SteamCalculator &firstguess
00958 );
00959
00960 template<>
00961 int
00962 Solver2<Pressure, Temperature, 0, 0>::whichRegion(
00963 const Pressure &p, const Temperature &T
00964 );
00965
00966 template<>
00967 int
00968 Solver2<Temperature, SpecificEnergy, 0, SOLVE_ENTHALPY>::whichRegion(
00969 const Temperature &T, const SpecificEnergy &h
00970 );
00971
00972 template<>
00973 int
00974 Solver2<Temperature,SpecificEntropy,0,SOLVE_ENTROPY>::whichRegion(
00975 const Temperature &T, const SpecificEntropy &s
00976 );
00977
00978 template<>
00979 int
00980 Solver2<Pressure,SpecificEntropy,0,SOLVE_ENTROPY>::whichRegion(
00981 const Pressure &p, const SpecificEntropy &s
00982 );
00983
00984 template<>
00985 int
00986 Solver2<Pressure,SpecificEnergy,0,SOLVE_IENERGY>::whichRegion(
00987 const Pressure &p, const SpecificEnergy &u
00988 );
00989
00990 template<>
00991 int
00992 Solver2<Pressure, SpecificEnergy, 0, SOLVE_ENTHALPY>::whichRegion(
00993 const Pressure &p, const SpecificEnergy &h
00994 );
00995
00996 template<>
00997 int
00998 Solver2<SpecificEnergy,SpecificVolume,SOLVE_IENERGY,0>::whichRegion(const SpecificEnergy &u, const SpecificVolume &v);
00999
01000 #endif