int freesteam_region_pv(double p, double v){ double p13 = freesteam_region4_psat_T(REGION1_TMAX); if(p > p13){ double v13 = freesteam_region1_v_pT(p, REGION1_TMAX); if(v < v13) return 1; /* region 2-3 */ double T23 = freesteam_b23_T_p(p); double v23 = freesteam_region2_v_pT(p,T23); if(v > v23) return 2; /* region 3? or high-pressure part of region 4? */ if(p >= IAPWS97_PCRIT) return 3; double Tsat = freesteam_region4_Tsat_p(p); double vf = 1./ freesteam_region4_rhof_T(Tsat); if(v < vf) return 3; double vg = 1./ freesteam_region4_rhog_T(Tsat); if(v > vg) return 3; return 4; }else{ double Tsat = freesteam_region4_Tsat_p(p); double vf = freesteam_region1_v_pT(p,Tsat); if(v < vf) return 1; double vg = freesteam_region2_v_pT(p,Tsat); if(v > vg) return 2; return 4; } }
int freesteam_region_pu(double p, double u){ double p13 = freesteam_region4_psat_T(REGION1_TMAX); if(p < p13){ double Tsat = freesteam_region4_Tsat_p(p); double uf = freesteam_region1_u_pT(p,Tsat); if(u < uf)return 1; double ug = freesteam_region2_u_pT(p,Tsat); if(u > ug)return 2; return 4; } double u13 = freesteam_region1_u_pT(p,REGION1_TMAX); if(u < u13){ return 1; } double T23 = freesteam_b23_T_p(p); double u23 = freesteam_region2_u_pT(p,T23); if(u > u23){ return 2; } if(p > IAPWS97_PCRIT)return 3; /* FIXME what we really need here is a psat(u) function! The current method is singular. */ double Tsat = freesteam_region4_Tsat_p(p); double rhof = freesteam_region4_rhof_T(Tsat); double uf = freesteam_region3_u_rhoT(rhof,Tsat); if(u<uf) return 3; double rhog = freesteam_region4_rhog_T(Tsat); double ug = freesteam_region3_u_rhoT(rhog,Tsat); if(u>ug)return 3; return 4; }
SteamState freesteam_set_pu(double p, double u){ double lb, ub, tol, sol, err; SolvePUData D = {p, u, 0.}; SteamState S; int region = freesteam_region_pu(p,u); switch(region){ case 1: lb = IAPWS97_TMIN; ub = REGION1_TMAX; tol = 1e-9; /* ??? */ zeroin_solve(&pu_region1_fn, &D, lb, ub, tol, &sol, &err); S = freesteam_region1_set_pT(p,sol); break; case 2: lb = IAPWS97_TMIN; ub = REGION2_TMAX; tol = 1e-9; /* ??? */ zeroin_solve(&pu_region2_fn, &D, lb, ub, tol, &sol, &err); S = freesteam_region2_set_pT(p,sol); break; case 4: lb = 0.; ub = 1.; tol = 1e-9; /* ??? */ D.T = freesteam_region4_Tsat_p(p); //fprintf(stderr,"%s: (%s:%d): p = %g\n",__func__,__FILE__,__LINE__,D.p); zeroin_solve(&pu_region4_fn, &D, lb, ub, tol, &sol, &err); S = freesteam_region4_set_Tx(D.T,sol); break; case 3: /* FIXME looks like a problem with the derivative routines here? */ { int status; SteamState guess = freesteam_region3_set_rhoT(IAPWS97_RHOCRIT,IAPWS97_TCRIT); S = freesteam_solver2_region3('p','u', p, u, guess, &status); if(status){ fprintf(stderr,"%s (%s:%d): Failed solve in region 3 for (p = %g MPa, u = %g kJ/kg\n" ,__func__,__FILE__,__LINE__,p/1e6,u/1e3); //exit(1); } } break; default: fprintf(stderr,"%s (%s:%d): Region '%d' not implemented\n",__func__,__FILE__,__LINE__,region); exit(1); } return S; }
SteamState freesteam_set_pv(double p, double v){ SteamState S; S.region = (char)freesteam_region_pv(p,v); #if 0 int status; #endif switch(S.region){ case 1: /* iterate T to get correct value of v */ S.R1.p = p; S.R1.T = freesteam_region4_Tsat_p(p); { double lb = IAPWS97_TMIN; double ub = REGION1_TMAX; double tol = 1e-9; /* ??? */ double sol, err; SolvePVData D = {p, v}; zeroin_solve(&pv_region1_fn, &D, lb, ub, tol, &sol, &err); S.R1.T = sol; /* FIXME check convergence! */ } #if 0 S = freesteam_solver2_region1('p','v', p, v, S, &status); if(status){ fprintf(stderr,"%s: WARNING: Failed to converge in region 1\n",__func__); } #endif break; case 2: /* iterate T to get correct value of v */ S.R2.p = p; S.R2.T = freesteam_region4_Tsat_p(p); { double lb = IAPWS97_TMIN; double ub = IAPWS97_TMAX; double tol = 1e-9; /* ??? */ double sol, err; SolvePVData D = {p, v}; zeroin_solve(&pv_region2_fn, &D, lb, ub, tol, &sol, &err); S.R2.T = sol; /* FIXME check convergence! */ } #if 0 S.R2.p = p; S.R2.T = freesteam_region4_Tsat_p(p); S = freesteam_solver2_region2('p','v', p, v, S, &status); if(status){ fprintf(stderr,"%s: WARNING: Failed to converge in region 2\n",__func__); } #endif break; case 3: S.R3.rho = 1./ v; S.R3.T = REGION1_TMAX; { double lb = REGION1_TMAX; double ub = IAPWS97_TMAX; double tol = 1e-12; /* ??? */ double sol, err; SolvePRhoData D = {p, S.R3.rho}; zeroin_solve(&pv_region3_fn, &D, lb, ub, tol, &sol, &err); S.R3.T = sol; //fprintf(stderr,"%s: (p = %f MPa,v = %f m3/kg) region 3, error in p = %f\n",__func__,p,v, err); /* FIXME check convergence! */ } #if 0 S = freesteam_solver2_region3('p','v', p, v, S, &status); if(status){ fprintf(stderr,"%s: WARNING: Failed to converge in region 3\n",__func__); } #endif break; case 4: S.R4.T = freesteam_region4_Tsat_p(p); //fprintf(stderr,"%s: region 4, Tsat = %g\n",__func__,S.R4.T); double vf, vg; if(S.R4.T <= REGION1_TMAX){ vf = freesteam_region1_v_pT(p,S.R4.T); vg = freesteam_region2_v_pT(p,S.R4.T); }else{ /* TODO iteratively improve estimate of T */ vf = 1./ freesteam_region4_rhof_T(S.R4.T); vg = 1./ freesteam_region4_rhog_T(S.R4.T); } S.R4.x = (v - vf)/(vg - vf); } return S; }
int eval_state (TableData *data) { double var1, var2; int active_sol_class; int active_sol; /* read input without units conversion */ var1 = atof (gtk_entry_get_text (data->indep_var1_entry) ); var2 = atof (gtk_entry_get_text (data->indep_var2_entry) ); active_sol_class = gtk_combo_box_get_active (data->SolverClassCombo); active_sol = gtk_combo_box_get_active (data->IndVariablesCombo); /* single phase state */ /**********************/ if( active_sol_class == SINGLE_PHASE_SOLVER ) { switch (active_sol) { case SOLVER_PT: if (1) data->S = freesteam_set_pT (var1*1e+5, var2+273.15); else return DOMAIN_ERROR; break; case SOLVER_PH: if (!freesteam_bounds_ph (var1*1e+5, var2*1e+3, VERBOSE)) { data->S = freesteam_set_ph (var1 * 1e+5, var2 * 1e+3); if (data->S.region == REGION_4) { var1 = freesteam_region4_Tsat_p (var1 * 1e+5); /* T in K */ data->SLiq = freesteam_set_Tx (var1, 0.0); data->SVap = freesteam_set_Tx (var1, 1.0); data->SMix = data->S; } } else return DOMAIN_ERROR; break; case SOLVER_PS: if (!freesteam_bounds_ps (var1*1e+5, var2*1e+3, VERBOSE)) { data->S = freesteam_set_ps (var1 * 1e+5, var2 * 1e+3); } else return DOMAIN_ERROR; break; case SOLVER_PU: data->S = freesteam_set_pu (var1 * 1e+5, var2 * 1e+3); break; case SOLVER_PV: if (freesteam_bounds_pv (var1 * 1e+5, var2, VERBOSE)) { data->S = freesteam_set_pv (var1 * 1e+5, var2); } else return DOMAIN_ERROR; break; case SOLVER_TS: if (!freesteam_bounds_Ts (var1+273.15, var2*1e+3, VERBOSE)) { data->S = freesteam_set_Ts( var1 + 273.15, var2 * 1e+3); } else return DOMAIN_ERROR; } /* switch */ } /* saturation state */ /********************/ else if (active_sol_class == SATURATION_SOLVER) { data->S.region = REGION_4; switch (active_sol) { case SAT_SOLVER_TX: if (!freesteam_bounds_Tx (var1 + 273.15, var2, 1)) { data->SLiq = freesteam_set_Tx (var1 + 273.15, 0.0); data->SVap = freesteam_set_Tx (var1 + 273.15, 1.0); data->SMix = freesteam_set_Tx (var1 + 273.15, var2); } else return DOMAIN_ERROR; break; case SAT_SOLVER_PX: if (1) { var1 = freesteam_region4_Tsat_p (var1 * 1e+5); /* T in K */ data->SLiq = freesteam_set_Tx (var1, 0.0); data->SVap = freesteam_set_Tx (var1, 1.0); data->SMix = freesteam_set_Tx (var1, var2); } else return DOMAIN_ERROR; break; } } /* solution found for new state */ switch (data->S.region) { case REGION_1: update_table_liststore( COL_LIQUID, 1, data, &data->S ); break; case REGION_2: update_table_liststore( COL_VAPOUR, 1, data, &data->S ); break; case REGION_3: update_table_liststore( COL_LIQUID, 1, data, &data->S ); break; case REGION_4: update_table_liststore (COL_VAPOUR, 0, data, &data->SVap); update_table_liststore (COL_LIQUID, 0, data, &data->SLiq); update_table_liststore (COL_MIXED , 0, data, &data->SMix); break; case REGION_5: update_table_liststore( COL_VAPOUR, 1, data, &data->S ); break; } return 0; }