/[ascend]/trunk/models/johnpye/fprops/helmholtz.c
ViewVC logotype

Diff of /trunk/models/johnpye/fprops/helmholtz.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1828 by jpye, Fri Aug 22 00:48:31 2008 UTC revision 1829 by jpye, Fri Aug 22 05:00:53 2008 UTC
# Line 35  Line 35 
35  #endif  #endif
36    
37  /* Property data for Ammonia, from Tillner-Roth, Harms-Watzenberg and  /* Property data for Ammonia, from Tillner-Roth, Harms-Watzenberg and
38  Baehr, Eine neue Fundamentalgleichung für Ammoniak, DKV-Tagungsbericht,  Baehr, 'Eine neue Fundamentalgleichung für Ammoniak', DKV-Tagungsbericht,
39  20:167-181, 1993. This is the ammmonia property correlation recommended  20:167-181, 1993. This is the ammmonia property correlation recommended
40  by NIST in its program REFPROP 7.0. */  by NIST in its program REFPROP 7.0. */
41  const HelmholtzData helmholtz_data_ammonia = {  const HelmholtzData helmholtz_data_ammonia = {
# Line 130  double helmholtz_u(double T, double rho, Line 130  double helmholtz_u(double T, double rho,
130    
131      @param T temperature in K      @param T temperature in K
132      @param rho mass density in kg/m³      @param rho mass density in kg/m³
133      @return enthalpy in ????      @return enthalpy in J/kg
134  */  */
135  double helmholtz_h(double T, double rho, const HelmholtzData *data){  double helmholtz_h(double T, double rho, const HelmholtzData *data){
136            
# Line 140  double helmholtz_h(double T, double rho, Line 140  double helmholtz_h(double T, double rho,
140      return data->R * T * (1 + tau * (helm_ideal_tau(tau,delta,data) + helm_resid_tau(tau,delta,data)) + delta*helm_resid_del(tau,delta,data));      return data->R * T * (1 + tau * (helm_ideal_tau(tau,delta,data) + helm_resid_tau(tau,delta,data)) + delta*helm_resid_del(tau,delta,data));
141  }  }
142    
143    /**
144        Function to calculate entropy from Helmholtz free energy EOS, given
145        temperature and mass density.
146    
147        @param T temperature in K
148        @param rho mass density in kg/m³
149        @return entropy in J/kgK
150    */
151    double helmholtz_s(double T, double rho, const HelmholtzData *data){
152        
153        double tau = data->T_star / T;
154        double delta = rho / data->rho_star;
155    
156        return data->R * (
157            tau * (helm_ideal_tau(tau,delta,data) + helm_resid_tau(tau,delta,data))
158            - helm_ideal(tau,delta,data) - helm_resid(tau,delta,data)
159        );
160    }
161    
162  /*---------------------------------------------  /*---------------------------------------------
163    UTILITY FUNCTION(S)    UTILITY FUNCTION(S)
164  */  */
# Line 148  double helmholtz_h(double T, double rho, Line 167  double helmholtz_h(double T, double rho,
167  static double ipow(double x, int n){  static double ipow(double x, int n){
168      double t = 1.0;      double t = 1.0;
169    
170      if(!n)return t;    /* At the top. 0^0 = 1 */      if(!n)return 1.0;    /* At the top. x^0 = 1 */
171    
172      if (n < 0){      if (n < 0){
173          n = -n;          n = -n;
# Line 266  double helm_resid_del(double tau,double Line 285  double helm_resid_del(double tau,double
285      const HelmholtzATD *atd = &(data->atd[0]);      const HelmholtzATD *atd = &(data->atd[0]);
286            
287      for(i=0; i<5; ++i){      for(i=0; i<5; ++i){
288          //fprintf(stderr,"i = %d, a = %e, t = %f, d = %d\n",i+1, atd->a, atd->t, atd->d);          fprintf(stderr,"i = %d, a = %e, t = %f, d = %d\n",i+1, atd->a, atd->t, atd->d);
289          phir += atd->a * pow(tau, atd->t) * ipow(delta, atd->d - 1) * atd->d;          phir += atd->a * pow(tau, atd->t) * pow(delta, atd->d - 1) * atd->d;
290          ++atd;          ++atd;
291      }      }
292    
293      sum = 0;      sum = 0;
294      XdelX = delta;      XdelX = delta;
295      for(i=5; i<10; ++i){      for(i=5; i<10; ++i){
296          //fprintf(stderr,"i = %d, a = %e, t = %f, d = %d\n",i+1, atd->a, atd->t, atd->d);          fprintf(stderr,"i = %d, a = %e, t = %f, d = %d\n",i+1, atd->a, atd->t, atd->d);
297          sum += atd->a * pow(tau, atd->t) * ipow(delta, atd->d - 1) * (atd->d - XdelX);          sum += atd->a * pow(tau, atd->t) * pow(delta, atd->d - 1) * (atd->d - delta);
298          ++atd;          ++atd;
299      }      }
300        //fprintf(stderr,"sum = %f\n",sum);
301      phir += exp(-delta) * sum;      phir += exp(-delta) * sum;
302    
303      sum = 0;      sum = 0;
304      XdelX = 2*delta*delta;      XdelX = 2.*delta*delta;
305      for(i=10; i<17; ++i){      for(i=10; i<17; ++i){
306          sum += atd->a * pow(tau, atd->t) * ipow(delta, atd->d - 1) * (atd->d - XdelX);          fprintf(stderr,"i = %d, a = %e, t = %f, d = %d\n",i+1, atd->a, atd->t, atd->d);
307            sum += atd->a * pow(tau, atd->t) * pow(delta, atd->d - 1) * (atd->d - XdelX);
308          ++atd;          ++atd;
309      }      }
310        //fprintf(stderr,"sum = %f\n",sum);
311      phir += exp(-delta*delta) * sum;      phir += exp(-delta*delta) * sum;
312    
313      sum = 0;      sum = 0;
314      XdelX = 3*delta*delta*delta;      XdelX = 3.*delta*delta*delta;
315      for(i=17; i<21; ++i){      for(i=17; i<21; ++i){
316          sum += atd->a * pow(tau, atd->t) * ipow(delta, atd->d - 1) * (atd->d - XdelX);          fprintf(stderr,"i = %d, a = %e, t = %f, d = %d\n",i+1, atd->a, atd->t, atd->d);
317            sum += atd->a * pow(tau, atd->t) * pow(delta, atd->d - 1) * (atd->d - XdelX);
318          ++atd;          ++atd;
319      }      }
320        //fprintf(stderr,"sum = %f\n",sum);
321      phir += exp(-delta*delta*delta) * sum;      phir += exp(-delta*delta*delta) * sum;
322    
323      return phir;      return phir;
# Line 462  double helm_resid_deldel(double tau,doub Line 486  double helm_resid_deldel(double tau,doub
486  #ifdef TEST  #ifdef TEST
487    
488  /* a simple macro to actually do the testing */  /* a simple macro to actually do the testing */
489  #define ASSERT_TOL(EXPR,VAL,TOL) if(abs((EXPR)-(VAL))>TOL){\  #define ASSERT_TOL(EXPR,VAL,TOL) {\
490          fprintf(stderr,"ERROR: value of '%s' = %f, should be %f, error is %f (%.2f%%)!\n", #EXPR, EXPR, VAL,(EXPR)-(VAL),((EXPR)-(VAL))/(VAL)*100);exit(1);\          double cval; cval = (EXPR);\
491      }else{\          double err; err = cval - (double)(VAL);\
492          fprintf(stderr,"    OK, %s = %8.2e within %.2f%% err\n",#EXPR,VAL,((EXPR)-(VAL))/(VAL)*100);\          double relerrpc = (cval-(VAL))/(VAL)*100;\
493            if(fabs(err)>TOL){\
494                fprintf(stderr,"ERROR in line %d: value of '%s' = %f, should be %f, error is %f (%.2f%%)!\n"\
495                    , __LINE__, #EXPR, cval, VAL,cval-(VAL),relerrpc);\
496                exit(1);\
497            }else{\
498                fprintf(stderr,"    OK, %s = %8.2e with %.2f%% err.\n",#EXPR,VAL,relerrpc);\
499                /*fprintf(stderr,"        (err = %8.2e, tol = %8.2e, calc = %8.2e)\n",fabs(err),TOL,cval);*/\
500            }\
501      }      }
502    
503  int main(void){  int main(void){
# Line 474  int main(void){ Line 506  int main(void){
506    
507      d = &helmholtz_data_ammonia;      d = &helmholtz_data_ammonia;
508    
     //ASSERT_TOL(helmholtz_p(273.15+-40.,694.67,d), 10E6, 1E3);  
     //ASSERT_TOL(helmholtz_p(273.15+-20.,670.55,d), 10E6, 1E3);  
     //ASSERT_TOL(helmholtz_p(273.15+50,573.07,d), 10E6, 1E3);  
     //ASSERT_TOL(helmholtz_p(273.15+110,441.77,d), 10E6, 1E3);  
509    
510    #if 0
511      fprintf(stderr,"PRESSURE TESTS\n");      fprintf(stderr,"PRESSURE TESTS\n");
512    
513        fprintf(stderr,"p(T,rho) = 0.1 MPa\n");
514        ASSERT_TOL(helmholtz_p(273.15+-70,724.75,d), 0.1E6,  7E3);
515        ASSERT_TOL(helmholtz_p(273.15+-60,713.65,d), 0.1E6,  7E3);
516        ASSERT_TOL(helmholtz_p(273.15+-50,702.11,d), 0.1E6,  7E3);
517        ASSERT_TOL(helmholtz_p(273.15+-40,690.16,d), 0.1E6,   7E3);
518        ASSERT_TOL(helmholtz_p(273.15+-33.588,682.29,d), 0.1E6,   7E3);
519        ASSERT_TOL(helmholtz_p(273.15+  0,0.74124,d), 0.1E6, 5E3);
520        ASSERT_TOL(helmholtz_p(273.15+100,0.55135,d), 0.1E6, 5E3);
521        ASSERT_TOL(helmholtz_p(273.15+250,0.39203,d), 0.1E6, 5E3);
522        ASSERT_TOL(helmholtz_p(273.15+420,0.29562,d), 0.1E6, 5E3);
523      fprintf(stderr,"p(T,rho) = 1 MPa\n");      fprintf(stderr,"p(T,rho) = 1 MPa\n");
524        ASSERT_TOL(helmholtz_p(273.15+-70,725.06,d), 1E6, 1E3);
525        ASSERT_TOL(helmholtz_p(273.15+  0,638.97,d), 1E6, 1E3);
526        ASSERT_TOL(helmholtz_p(273.15+ 30,7.5736,d), 1E6, 1E3);
527      ASSERT_TOL(helmholtz_p(273.15+150,4.9817,d), 1E6, 1E3);      ASSERT_TOL(helmholtz_p(273.15+150,4.9817,d), 1E6, 1E3);
528      ASSERT_TOL(helmholtz_p(273.15+200,4.4115,d), 1E6, 1E3);      ASSERT_TOL(helmholtz_p(273.15+200,4.4115,d), 1E6, 1E3);
529      ASSERT_TOL(helmholtz_p(273.15+350,3.3082,d), 1E6, 1E3);      ASSERT_TOL(helmholtz_p(273.15+350,3.3082,d), 1E6, 1E3);
530      ASSERT_TOL(helmholtz_p(273.15+420,2.9670,d), 1E6, 1E3);      ASSERT_TOL(helmholtz_p(273.15+420,2.9670,d), 1E6, 1E3);
531    
532      fprintf(stderr,"p(T,rho) = 10 MPa\n");      fprintf(stderr,"p(T,rho) = 10 MPa\n");
533        //ASSERT_TOL(helmholtz_p(273.15+-40.,694.67,d), 10E6, 1E3);
534        //ASSERT_TOL(helmholtz_p(273.15+-20.,670.55,d), 10E6, 1E3);
535        //ASSERT_TOL(helmholtz_p(273.15+50,573.07,d), 10E6, 1E3);
536        //ASSERT_TOL(helmholtz_p(273.15+110,441.77,d), 10E6, 1E3);
537      ASSERT_TOL(helmholtz_p(273.15+150,74.732,d), 10E6, 1E3);      ASSERT_TOL(helmholtz_p(273.15+150,74.732,d), 10E6, 1E3);
538      ASSERT_TOL(helmholtz_p(273.15+200,54.389,d), 10E6, 1E3);      ASSERT_TOL(helmholtz_p(273.15+200,54.389,d), 10E6, 1E3);
539      ASSERT_TOL(helmholtz_p(273.15+350,35.072,d), 10E6, 1E3);      ASSERT_TOL(helmholtz_p(273.15+350,35.072,d), 10E6, 1E3);
# Line 502  int main(void){ Line 548  int main(void){
548      //fprintf(stderr,"IDEAL HELMHOLTZ COMPONENT\n");      //fprintf(stderr,"IDEAL HELMHOLTZ COMPONENT\n");
549      //ASSERT_TOL(helm_ideal(273.15, 0)      //ASSERT_TOL(helm_ideal(273.15, 0)
550    
551        /* this offset is required to attain agreement with values from REFPROP */
552      double Z = -1635.7e3 + 1492.411e3;      double Z = -1635.7e3 + 1492.411e3;
553    
554      fprintf(stderr,"ENTHALPY TESTS\n");      fprintf(stderr,"ENTHALPY TESTS\n");
# Line 542  int main(void){ Line 589  int main(void){
589      ASSERT_TOL(helmholtz_h(273.15+250,437.69,d), Z+1506.6e3, 1e3);      ASSERT_TOL(helmholtz_h(273.15+250,437.69,d), Z+1506.6e3, 1e3);
590      ASSERT_TOL(helmholtz_h(273.15+420,298.79,d), Z+2252.3e3, 1e3);      ASSERT_TOL(helmholtz_h(273.15+420,298.79,d), Z+2252.3e3, 1e3);
591    
592    #endif
593    
594        fprintf(stderr,"ENTROPY TESTS\n");
595    
596        /* offset required to attain agreement with REFPROP */
597        double Y = -471.596704;
598    
599        fprintf(stderr,"s(T,rho) at p = 0.1 MPa\n");
600        ASSERT_TOL(helmholtz_s(273.15+-60, 713.65,d), Y+0.36737e3, 0.5);
601        ASSERT_TOL(helmholtz_s(273.15+  0,0.76124,d), Y+6.8900e3, 0.5);
602        ASSERT_TOL(helmholtz_s(273.15+ 50,0.63869,d), Y+7.2544e3, 0.5);
603        ASSERT_TOL(helmholtz_s(273.15+200,0.43370,d), Y+8.1232e3, 0.5);
604        ASSERT_TOL(helmholtz_s(273.15+300,0.35769,d), Y+8.6084e3, 1);
605        ASSERT_TOL(helmholtz_s(273.15+420,0.29562,d), Y+9.1365e3, 1);
606    
607        fprintf(stderr,"s(T,rho) at p = 1 MPa\n");
608        ASSERT_TOL(helmholtz_s(273.15+-50,702.49,d), Y+0.56381e3, 0.5);
609        ASSERT_TOL(helmholtz_s(273.15+150,4.9817,d), Y+6.7008e3, 0.5);
610        ASSERT_TOL(helmholtz_s(273.15+200,4.4115,d), Y+6.9770e3, 0.5);
611        ASSERT_TOL(helmholtz_s(273.15+350,3.3082,d), Y+7.7012e3, 0.5);
612        ASSERT_TOL(helmholtz_s(273.15+420,2.9670,d), Y+8.0059e3, 0.5);
613    
614        fprintf(stderr,"s(T,rho) at p = 10 MPa\n");
615        ASSERT_TOL(helmholtz_s(273.15+-70,728.11,d), Y+0.14196e3, 1);
616        ASSERT_TOL(helmholtz_s(273.15+-50,706.21,d), Y+0.54289e3, 1);
617        ASSERT_TOL(helmholtz_s(273.15+-20,670.55,d), Y+1.0975e3, 1);
618        ASSERT_TOL(helmholtz_s(273.15+  0,645.04,d), Y+1.4403e3, 1);
619        ASSERT_TOL(helmholtz_s(273.15+125.17,356.70,d), Y+3.5463e3, 1);
620    
621        ASSERT_TOL(helmholtz_s(273.15+125.17,121.58,d), Y+4.5150e3, 1);
622        ASSERT_TOL(helmholtz_s(273.15+200,54.389,d), Y+5.5906e3, 1);
623        ASSERT_TOL(helmholtz_s(273.15+350,35.072,d), Y+6.4850e3, 1);
624        ASSERT_TOL(helmholtz_s(273.15+420,30.731,d), Y+6.8171e3, 1);
625    
626        fprintf(stderr,"s(T,rho) at p = 20 MPa\n");
627        ASSERT_TOL(helmholtz_s(273.15+-50,710.19,d), Y+0.52061e3, 1);
628        ASSERT_TOL(helmholtz_s(273.15+ 30,612.22,d), Y+1.8844e3, 1);
629        ASSERT_TOL(helmholtz_s(273.15+150,359.41,d), Y+3.7164e3, 1);
630        ASSERT_TOL(helmholtz_s(273.15+200,152.83,d), Y+4.8376e3, 1);
631        ASSERT_TOL(helmholtz_s(273.15+350,74.590,d), Y+6.0407e3, 1);
632        ASSERT_TOL(helmholtz_s(273.15+420,63.602,d), Y+6.4066e3, 1);
633    
634        fprintf(stderr,"s(T,rho) at p = 100 MPa\n");
635        ASSERT_TOL(helmholtz_s(273.15+  0,690.41,d), Y+1.2158e3, 1);
636        ASSERT_TOL(helmholtz_s(273.15+100,591.07,d), Y+2.5499e3, 1);
637        ASSERT_TOL(helmholtz_s(273.15+250,437.69,d), Y+4.0264e3, 1);
638        ASSERT_TOL(helmholtz_s(273.15+420,298.79,d), Y+5.2620e3, 1);
639    
640    
641      fprintf(stderr,"Tests completed OK\n");      fprintf(stderr,"Tests completed OK\n");
642      exit(0);      exit(0);

Legend:
Removed from v.1828  
changed lines
  Added in v.1829

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22