Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
/**
	This function will never return region 4, because it's not possible
	to 'sit on the knife' of saturation. If you need to set saturated states,
	you should use another function such as freesteam_region1_set_Tx.
*/
SteamState freesteam_set_pT(double p, double T){
	SteamState S;
	if(T < REGION1_TMAX){
		if(p > freesteam_region4_psat_T(T)){
			S.region = 1;
			S.R1.T = T;
			S.R1.p = p;
		}else{
			S.region = 2;
			S.R2.T = T;
			S.R2.p = p;
		}
	}else{
		//fprintf(stderr,"%s: T = %g >= REGION1_TMAX = %g\n",__func__,T,REGION1_TMAX);
		/* FIXME some optimisation possiblxe here with test for lower pressures */
		double T23 = freesteam_b23_T_p(p);
		double p23min = freesteam_b23_p_T(REGION1_TMAX);
		if(p < p23min || T > T23){
			//fprintf(stderr,"%s: T = %g > T23 =  %g\n",__func__,T,T23);
			S.region = 2;
			S.R2.T = T;
			S.R2.p = p;
		}else{
			/* FIXME the limit values are all wrong here! */
			//fprintf(stderr,"%s: region 3\n",__func__);
			SteamPTData D = {p,T};
			double ub = 1./freesteam_region1_v_pT(IAPWS97_PMAX,REGION1_TMAX);
			double lb = 1./freesteam_region2_v_pT(freesteam_b23_p_T(T),T);
			/* if we're in the little wee area around the critical pt... */
			if(T < IAPWS97_TCRIT){
				double psat = freesteam_region4_psat_T(T);
				if(p < psat){
					ub = freesteam_region4_rhog_T(T);
					assert(lb<ub);
				}else{
					lb = freesteam_region4_rhof_T(T);
					//fprintf(stderr,"lb = %g, ub = %g\n",lb,ub);
					assert(lb<ub);
				}
			}
			double tol = 1e-7;
			double sol, err = 0;
			if(zeroin_solve(&pT_region3_fn, &D, lb, ub, tol, &sol, &err)){
				fprintf(stderr,"%s (%s:%d): failed to solve for rho\n",__func__,__FILE__,__LINE__);
				exit(1);
			}
			S.region = 3;
			S.R3.T = T;
			S.R3.rho = sol;
			//assert(fabs((freesteam_p(S) - p)/p) < tol);
		}
	}
	//fprintf(stderr,"%s: region %d\n",__func__,S.region);
	return S;
}		
Exemplo n.º 3
0
/**
	This function will always return saturated mixtures; no negative or >1
	values of x are being 'understood' here (although one can give them meaning
	based on extrapolated values of u or h of v, for example...)
*/
SteamState freesteam_set_Tx(double T, double x) {
    SteamState S;

    if(T >= IAPWS97_TCRIT) {
        /* region 3 supercritical. just return a state with the specified
        temperature and the critical point entropy. arbitrary. */
        SolveTSData D = {T, freesteam_region3_s_rhoT(IAPWS97_RHOCRIT, IAPWS97_TCRIT)};
        double ub = 1./freesteam_region1_v_pT(IAPWS97_PMAX,REGION1_TMAX);
        double lb = 1./freesteam_region2_v_pT(freesteam_b23_p_T(T),T);
        double tol = 1e-7;
        double sol, err = 0;
        if(zeroin_solve(&Ts_region3_fn, &D, lb, ub, tol, &sol, &err)) {
            fprintf(stderr,"%s (%s:%d): failed to solve for rho\n",__func__,__FILE__,__LINE__);
            exit(1);
        }
        S.region = 3;
        S.R3.T = T;
        S.R3.rho = sol;
    } else if(x <= 0) {
        if(T > REGION1_TMAX) {
            S.region = 3;
            S.R3.T = T;
            S.R3.rho = freesteam_region4_rhof_T(T);
            /* FIXME iteratively refine the value */
        } else {
            S.region = 1;
            S.R1.p = freesteam_region4_psat_T(T);
            S.R1.T = T;
        }
    } else if(x >= 1) {
        if(T > REGION1_TMAX) {
            S.region = 3;
            S.R3.T = T;
            S.R3.rho = freesteam_region4_rhog_T(T);
            /* FIXME iteratively refine the value */
        } else {
            S.region = 2;
            S.R1.p = freesteam_region4_psat_T(T);
            S.R1.T = T;
        }
    } else {
        /* finally! */
        S.region = 4;
        S.R4.T = T;
        S.R4.x = x;
    }

    return S;
}
Exemplo n.º 4
0
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;
}