/[ascend]/branches/jacob/models/johnpye/fprops/mixtures/init_mixfuncs.c
ViewVC logotype

Contents of /branches/jacob/models/johnpye/fprops/mixtures/init_mixfuncs.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2988 - (show annotations) (download) (as text)
Tue Jun 30 04:00:24 2015 UTC (3 years, 4 months ago) by jacob
File MIME type: text/x-csrc
File size: 21045 byte(s)
expanded new library file to export mixture functions, and test .a4c file to check that the functions are exported correctly, and receive correct data.

minor changes to <ascend/compiler/instance_enum.h>, adding a few macro definitions of ASCEND data types for library file to be able to mention by name.

1 /* ASCEND modelling environment
2 Copyright (C) Carnegie Mellon University
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation --
17
18 Free Software Foundation, Inc.
19 59 Temple Place - Suite 330
20 Boston, MA 02111-1307, USA.
21 *//*
22 by Jacob Shealy, June 5-, 2015
23
24 Function definitions for initial model of ideal-solution mixing. Removed
25 these from the test files init_mix1, init_mix2, etc. to de-clutter them.
26 */
27
28 #include "mixture_generics.h"
29 #include "mixture_prepare.h"
30 #include "mixture_struct.h"
31 #include "init_mixfuncs.h"
32 #include "../helmholtz.h"
33 #include "../fluids.h"
34 #include "../fprops.h"
35 #include "../refstate.h"
36 #include "../sat.h"
37
38 #include <stdio.h>
39 #include <math.h>
40
41 /* Mixture-Preparation Functions */
42 /*
43 Calculate mass fractions from an array of numbers, with each mass fraction
44 sized proportionally to its corresponding number
45 */
46 void mixture_x_props(unsigned nPure, double *Xs, double *props){
47 unsigned i;
48 double x_total=0.0; /* sum of proportions */
49
50 for(i=0;i<nPure;i++){
51 x_total += props[i]; /* find sum of proportions */
52 }
53 /*
54 Each mass fraction is its corresponding proportion, divided by the sum
55 over all proportions.
56 */
57 for(i=0;i<nPure;i++){
58 Xs[i] = props[i] / x_total;
59 }
60 }
61
62 /*
63 Calculate last of (n) mass fractions given an array of (n-1) mass
64 fractions, such that the sum over all mass fractions will equal one.
65 */
66 double mixture_x_fill_in(unsigned nPure, double *Xs){
67 unsigned i;
68 double x_total;
69
70 for(i=0;i<(nPure-1);i++){ /* sum only for nPure-1 loops */
71 x_total += Xs[i];
72 }
73 if(x_total>0){
74 printf(MIX_ERROR "%.6f.", x_total);
75 }
76 return 1-x_total;
77 }
78
79 /*
80 Calculate ideal-gas densities `rho_out' from the temperature and pressure
81 (used as starting densities for other routines)
82
83 Specifically, these densities may be useful if T > T_c (critical
84 temperature), and P < P_c (sub-critical pressure).
85 */
86 void ig_rhos(MixtureState *M, double P, char **Names){
87 unsigned i; /* counter variable */
88
89 #define TT M->T
90 #define RHOS M->rhos
91 #define NPURE M->X->pures
92 #define PF M->X->PF
93 for(i=0;i<NPURE;i++){
94 RHOS[i] = P / PF[i]->data->R / TT;
95 printf("\n\t%s%s is : %.4f kg/m3", "The ideal-gas mass density of ",
96 Names[i], RHOS[i]);
97 } puts("");
98 #if 0
99 #undef PF
100 #undef NPURE
101 #undef RHOS
102 #undef TT
103 #endif
104 }
105
106 /*
107 Set initial densities for use in `pressure_rhos', given an initial
108 temperature and pressure. Considers whether a substance is in critical or
109 saturation regions.
110 */
111 void initial_rhos(MixtureState *M, double P, char **Names, FpropsError *err){
112 unsigned i;
113 int Region;
114 /* enum Region_Enum {SUPERCRIT, GASEOUS, LIQUID, VAPOR, SAT_VLE} Region; */
115 #define SAT_VLE LIQUID+VAPOR
116 char *region_names[] = {
117 "super-critical",
118 "gaseous",
119 "vapor",
120 "liquid",
121 "solid",
122 "vapor-liquid equilibrium (saturation)"
123 };
124
125 #if 0
126 #define TT M->T
127 #define RHOS M->rhos
128 #define NPURE M->X->pures
129 #define PF M->X->PF
130 #endif
131 #define D PF[i]->data
132 for(i=0;i<NPURE;i++){
133 if(TT >= D->T_c){ /* temperature >= critical temperature */
134 if(P >= D->p_c){ /* pressure >= critical pressure */
135 RHOS[i] = D->rho_c; /* super-critical fluid */
136 Region = SUPERCRIT;
137 }else{ /* true gas (as opposed to sub-critical vapor) */
138 RHOS[i] = P / D->R / TT; /* density from ideal gas */
139 Region = GAS;
140 }
141 }else{
142 if(P >= D->p_c){ /* pressure >= critical pressure -- liquid */
143 RHOS[i] = fprops_rhof_T_rackett(TT, D); /* density from saturation liquid */
144 Region = LIQUID;
145 }else{ /* now we're getting into hard conditions */
146 double T_sat, /* find saturation temperature, densities */
147 rho_liq,
148 rho_vap;
149 fprops_sat_p(P, &T_sat, &rho_liq, &rho_vap, PF[i], err);
150
151 if(TT > T_sat){ /* this is the last condition that we can precisely find */
152 RHOS[i] = rho_vap; /* vapor phase */
153 Region = VAPOR;
154 }else{
155 RHOS[i] = (rho_liq + rho_vap) / 2; /* both liquid and vapor */
156 /*
157 We are in vapor-liquid equilibrium, and the density
158 cannot be determined without knowing how much of the
159 substance is in the vapor and how much in the liquid.
160 */
161 /*printf("\n\tThe substance %s is in vapor-liquid equilibrium; "
162 "it has been assigned a provisional density %.5f kg/m3.",
163 Names[i], RHOS[i]);*/
164 Region = SAT_VLE;
165 }
166 }
167 }
168 printf("\n\tThe substance %s was assigned a density of %.5f kg/m3;\n"
169 "\t it is in the %s region, since\n"
170 "\t\tCritical temperature T_c=%.2f K \tand current temperature T=%.2f K;\n"
171 "\t\tCritical pressure P_c=%.0f Pa\tand current pressure P=%.0f Pa.",
172 Names[i], RHOS[i], region_names[Region], D->T_c, TT, D->p_c, P);
173 }
174 #undef D
175 #if 0
176 #undef NPURE
177 #undef RHOS
178 #undef TT
179 #undef PF
180 #endif
181 }
182
183 /*
184 Structure to hold auxiliary data for function to find the error in pressure
185 at a given density
186 */
187 typedef struct PressureRhoData_Struct {
188 double T;
189 double P;
190 PureFluid *pfl;
191 FpropsError *err;
192 } PRData;
193
194 SecantSubjectFunction pressure_rho_error;
195 double pressure_rho_error(double rho, void *user_data){
196 PRData *prd = (PRData *)user_data;
197 FluidState fst = {prd->T, rho, prd->pfl};
198
199 return fabs(prd->P - fprops_p(fst, prd->err));
200 }
201
202 /*
203 Calculate realistic densities `rho_out' in ideal-solution, such that
204 densities are consistent with the given temperature and pressure
205 */
206 void pressure_rhos(MixtureState *M, double P, double tol, /* char **Names, */ FpropsError *err){
207 /*
208 Find actual density by searching for the individual densities which
209 each satisfy the equation P_i(T, \rho_i) = P, starting from ideal-gas
210 density.
211
212 In production code, it might be advantageous to find several different
213 starting points for this search; e.g. if P > critical pressure, start
214 from critical density, etc. [NOTE: this is done in initial_rhos, above]
215
216 Compare with:
217 zeroin_solve in zeroin.c
218 helmholtz_sat in helmholtz.c
219 sat_p_resid, fprops_sat_p in sat.c (example of using zeroin_solve)
220 fprops_sat_hf in sat.c
221 fprops_solve_ph in solve_ph.c (uses fprops_sat_p from sat.c)
222 densities_to_mixture in init_mix.c or this file
223 densities_Ts_to_mixture in init_mix.c or this file
224 */
225 unsigned i1, i2; /* counter variables */
226 // double p1, p2, /* pressures */
227 // rho1, rho2, /* densities */
228 // delta_rho; /* change in density for one step */
229
230 for(i1=0;i1<NPURE;i1++){
231 PRData prd = {TT, P, PF[i1], err};
232 double rhos[] = {RHOS[i1], 1.01*RHOS[i1]};
233
234 secant_solve(&pressure_rho_error, &prd, rhos, tol);
235
236 RHOS[i1] = rhos[0];
237 }
238 }
239
240 /*
241 Structure to hold auxiliary data for function to find error in internal
242 energy at a given pressure.
243 */
244 typedef struct IntEnergyPressure_Struct {
245 double U;
246 double tol;
247 MixtureState *M;
248 FpropsError *err;
249 } IEData;
250
251 SecantSubjectFunction energy_p_error;
252 double energy_p_error(double P, void *user_data){
253 IEData *ied = (IEData *)user_data;
254 pressure_rhos(ied->M, P, ied->tol, ied->err);
255
256 return fabs(ied->U - mixture_u(ied->M, ied->err));
257 }
258
259 /*
260 Calculate realistic densities in ideal-solution, such that the internal
261 energy remains the same from pre-mixing to post-mixing conditions, starting
262 from a single temperature but disparate densities.
263
264 That is, if the component pure fluids for a solution are provided at
265 different/incompatible densities (which essentially means that they have
266 different pressures), find the set of solution densities that:
267 1. are `compatible' (result in the same pressure)
268 2. give the same overall internal energy as do the inconsistent
269 densities.
270
271 For now, I am using a secant[-like] method to find the pressure P that
272 satisfies the second condition above; densities are calculated using the
273 function pressure_rhos from fprops/mixtures/init_mixfuncs.c, and
274 averaged to see if the average density equals the original density.
275
276 The uniform-pressure condition (1) is satisfied automatically by using a
277 single pressure to find densities.
278 */
279 void densities_to_mixture(MixtureState *M, double tol, char **Names, FpropsError *err){
280 #define XS M->X->Xs
281 unsigned i;
282 double u_avg = mixture_u(M, err); /* original average internal energy */
283 double h_avg = mixture_h(M, err); /* original average enthalpy */
284
285 double p[]={0.0, 0.0};
286
287 /*
288 Find average pressure in the solution, and set p1 equal to that; set p2
289 */
290 for(i=0;i<NPURE;i++){
291 p[0] += fprops_p((FluidState){TT,RHOS[i],PF[i]}, err);
292 }
293 p[0] /= NPURE;
294 p[1] = 1.1 * p[0];
295
296 IEData ied = {u_avg, tol, M, err};
297 secant_solve(&energy_p_error, &ied, p, tol);
298
299 /* confirm that when internal energy does not change, neither does enthalpy */
300 if(fabs(h_avg - mixture_h(M,err)) < 2*tol){
301 printf("\n Average enthalpy remained constant at h=% .6g in mixing", h_avg);
302 }else{
303 printf("\n Average enthalpy did not remain constant:"
304 "\n\tthe average from before mixing is h=% .6g,"
305 "\n\tthe average from after mixing is h=% .6g",
306 h_avg, mixture_h(M, err));
307 } puts("");
308 /*
309 The check using enthalpy indicates that enthalpy does change if total
310 volume is held constant (h_before = 1.09477e6, h_after=1.09714e6 J/kg
311 with starting densities 2, 3, 2.5, 1.7 kg/m3 for N2, NH3, CO2, CH4). I
312 therefore changed from using the average pre-mixing volume to using
313 pre-mixing internal energy. This will also be checked with enthalpy.
314
315 With the same densities as before, solving with internal energy, the
316 enthalpy still changes, although much less (h_before = 1.09477e6,
317 h_after = 1.09479e6 J/kg). I judge that both methods seem to give
318 similar results, although solving with internal energy seems to do
319 better.
320 */
321 }
322
323 /* Mixture-Property Functions */
324 /*
325 Calculate overall mass density of a mixture of components
326
327 @param M MixtureState with number of components, mass fractions, densities
328
329 @return mass density of mixture
330 */
331 double mixture_rho(MixtureState *M){
332 unsigned i;
333 double x_total=0.0; /* sum over all mass fractions -- to check consistency */
334 double vol_mix=0.0; /* volume per unit mass of the mixture, iteratively summed */
335
336 #if 0
337 #define XS M->X->Xs
338 #endif
339 for(i=0;i<NPURE;i++){
340 vol_mix += XS[i] / RHOS[i];
341 x_total += XS[i];
342 }
343 if(fabs(x_total - 1) > MIX_XTOL){
344 printf(MIX_XSUM_ERROR, x_total);
345 }
346 return 1 / vol_mix;
347 #if 0
348 #undef XS
349 #undef PF
350 #undef NPURE
351 #undef RHOS
352 #undef TT
353 #endif
354 }
355
356 /*
357 Calculate overall ideal-solution internal energy per unit mass in a mixture
358 of pure components.
359
360 @param M MixtureState with temperature, mass fractions, component densities, etc.
361 @param err error argument
362
363 @return ideal-solution internal energy
364 */
365 double mixture_u(MixtureState *M, FpropsError *err){
366 unsigned i;
367 double x_total=0.0; /* sum over all mass fractions -- to check consistency */
368 double u_mix=0.0; /* internal energy of the mixture, iteratively summed */
369
370 for(i=0;i<NPURE;i++){
371 u_mix += XS[i] * fprops_u((FluidState){TT,RHOS[i],PF[i]}, err);
372 x_total += XS[i];
373 }
374 if(fabs(x_total - 1) > MIX_XTOL){
375 printf(MIX_XSUM_ERROR, x_total);
376 }
377 return u_mix;
378 }
379
380 /*
381 Calculate overall ideal-solution enthalpy per unit mass in a mixture of pure
382 components.
383
384 @param M MixtureState with temperature, mass fractions, component densities, etc.
385 @param err error argument
386
387 @return ideal-solution enthalpy
388 */
389 double mixture_h(MixtureState *M, FpropsError *err){
390 unsigned i;
391 double x_total=0.0; /* sum over all mass fractions -- to check consistency */
392 double h_mix=0.0; /* enthalpy of mixture, iteratively summed */
393
394 for(i=0;i<NPURE;i++){
395 h_mix += XS[i] * fprops_h((FluidState){TT,RHOS[i],PF[i]}, err);
396 x_total += XS[i];
397 }
398 if(fabs(x_total - 1) > MIX_XTOL){
399 printf(MIX_XSUM_ERROR, x_total);
400 }
401 return h_mix;
402 }
403
404 /*
405 Calculate overall ideal-solution constant-pressure heat capacity (per unit
406 of mass), in a mixture of pure components
407
408 @param M MixtureState with temperature, mass fractions, component densities, etc.
409 @param err error argument
410
411 @return ideal-solution heat capacity (constant-pressure)
412 */
413 double mixture_cp(MixtureState *M, FpropsError *err){
414 unsigned i;
415 double x_total=0.0; /* sum over all mass fractions -- to check consistency */
416 double cp_mix=0.0; /* constant-pressure heat capacity of mixture, iteratively summed */
417
418 for(i=0;i<NPURE;i++){
419 cp_mix += XS[i] * fprops_cp((FluidState){TT,RHOS[i],PF[i]}, err);
420 x_total += XS[i];
421 }
422 if(fabs(x_total - 1) > MIX_XTOL){
423 printf(MIX_XSUM_ERROR, x_total);
424 }
425 return cp_mix;
426 }
427
428 /*
429 Calculate overall ideal-solution constant-volume heat capacity (per unit of
430 mass), in a mixture of pure components
431
432 @param M MixtureState with temperature, mass fractions, component densities, etc.
433 @param err error argument
434
435 @return ideal-solution heat capacity (constant-volume)
436 */
437 double mixture_cv(MixtureState *M, FpropsError *err){
438 unsigned i;
439 double x_total=0.0; /* sum over all mass fractions -- to check consistency */
440 double cv_mix=0.0; /* constant-volume heat capacity of mixture, iteratively summed */
441
442 for(i=0;i<NPURE;i++){
443 cv_mix += XS[i] * fprops_cv((FluidState){TT,RHOS[i],PF[i]}, err);
444 x_total += XS[i];
445 }
446 if(fabs(x_total - 1) > MIX_XTOL){
447 printf(MIX_XSUM_ERROR, x_total);
448 }
449 return cv_mix;
450 }
451
452 /*
453 Calculate the value of the sum over all *mole* fractions x_i, of the mole
454 fraction times the natural logarithm of the mole fraction:
455 \sum\limits_i x_i \ln(x_i)
456
457 This quantity is used in calculating second-law mixture properties for ideal
458 solutions
459
460 @param nPure number of pure components
461 @param Xs array with mass fraction of each component
462 @param PFs array of pointers to PureFluid structures representing components
463
464 @return sum over all components of mole fraction times natural logarithm of
465 mole fraction.
466 */
467 double mixture_x_ln_x(unsigned nPure, double *x_mass, PureFluid **PFs){
468 unsigned i;
469 double x_total=0.0, /* sum over all mass fractions -- to check consistency */
470 x_mole, /* mole fraction of current component in the loop */
471 rM_avg=0.0, /* reciprocal average molar mass */
472 x_ln_x=0.0; /* sum of (x_i * ln(x_i)) over all `i' */
473
474 for(i=0;i<nPure;i++){ /* find the reciprocal average molar mass */
475 /* add mass fraction over molar mass */
476 rM_avg += x_mass[i] / PFs[i]->data->M;
477 x_total += x_mass[i];
478 }
479 /* return error if sum of mole fractions is not 1.00 */
480 if(fabs(x_total - 1) > MIX_XTOL){
481 printf(MIX_XSUM_ERROR, x_total);
482 }
483
484 for(i=0;i<nPure;i++){ /* Find the summation we came for */
485 x_mole = (x_mass[i] / PFs[i]->data->M) * rM_avg;
486 x_ln_x += x_mass[i] / PFs[i]->data->M * log(x_mole);
487 }
488 return x_ln_x;
489 }
490
491 /*
492 Calculate the average molar mass of the solution. This is useful in
493 converting mass-specific quantities (e.g. enthalpy in J/kg) into molar
494 quantities (e.g. enthalpy in J/kmol). The molar masses provided by
495 PureFluid structs in FPROPS have units of kg/kmol, so this molar mass will
496 have the same units.
497
498 @param nPure number of pure components
499 @param Xs array with mass fraction of each component
500 @param PFs array of pointers to PureFluid structures representing components
501
502 @return average molar mass of the solution
503 */
504 double mixture_M_avg(unsigned nPure, double *x_mass, PureFluid **PFs){
505 unsigned i;
506 double x_total=0.0; /* sum over all mass fractions -- to check consistency */
507 double rM_avg=0.0; /* reciprocal average molar mass */
508
509 for(i=0;i<nPure;i++){
510 rM_avg += x_mass[i] / PFs[i]->data->M;
511 x_total += x_mass[i];
512 }
513 if(fabs(x_total - 1) > MIX_XTOL){
514 printf(MIX_XSUM_ERROR, x_total);
515 }
516 return 1. / rM_avg;
517 } /* end of `mixture_M_avg' */
518
519 /*
520 Calculate the overall ideal-solution entropy per unit mass in a mixture of
521 pure components
522
523 @param M MixtureState with temperature, mass fractions, component densities, etc.
524 @param err error argument
525 */
526 double mixture_s(MixtureState *M, FpropsError *err){
527 #define D PF[0]->data
528 unsigned i;
529 double x_total=0.0, /* sum over all mass fractions -- to check consistency */
530 s_mix=0.0; /* entropy of mixture, iteratively summed */
531 double R = D->R * D->M; /* ideal gas constant */
532
533 for(i=0;i<NPURE;i++){
534 s_mix += XS[i] * fprops_s((FluidState){TT,RHOS[i],PF[i]}, err);
535 x_total += XS[i];
536 }
537 if(fabs(x_total - 1) > MIX_XTOL){
538 printf(MIX_XSUM_ERROR, x_total);
539 }
540 return s_mix - (R * mixture_x_ln_x(NPURE,XS,PF));
541 }
542
543 /*
544 Calculate overall ideal-solution Gibbs energy per unit mass in a mixture
545
546 @param M MixtureState with temperature, mass fractions, component densities, etc.
547 @param err error argument
548 */
549 double mixture_g(MixtureState *M, FpropsError *err){
550 unsigned i;
551 double x_total=0.0, /* sum over all mass fractions -- to check consistency */
552 g_mix=0.0; /* entropy of mixture, iteratively summed */
553 double R = D->R * D->M; /* ideal gas constant */
554
555 for(i=0;i<NPURE;i++){
556 g_mix += XS[i] * fprops_g((FluidState){TT,RHOS[i],PF[i]}, err);
557 x_total += XS[i];
558 }
559 if(fabs(x_total - 1) > MIX_XTOL){
560 printf(MIX_XSUM_ERROR, x_total);
561 }
562 return g_mix + (R * TT * mixture_x_ln_x(NPURE,XS,PF));
563 }
564
565 /*
566 Calculate overall ideal-solution Helmholtz energy per unit mass in a mixture
567
568 @param M MixtureState with temperature, mass fractions, component densities, etc.
569 @param err error argument
570 */
571 double mixture_a(MixtureState *M, FpropsError *err){
572 unsigned i;
573 double x_total=0.0, /* sum over all mass fractions -- to check consistency */
574 a_mix=0.0; /* entropy of mixture, iteratively summed */
575 double R = D->R * D->M; /* ideal gas constant */
576
577 for(i=0;i<NPURE;i++){
578 a_mix += XS[i] * fprops_a((FluidState){TT,RHOS[i],PF[i]}, err);
579 x_total += XS[i];
580 }
581 if(fabs(x_total - 1) > MIX_XTOL){
582 printf(MIX_XSUM_ERROR, x_total);
583 }
584 return a_mix + (R * TT * mixture_x_ln_x(NPURE,XS,PF));
585 #if 1
586 #undef D
587 #undef XS
588 #undef PF
589 #undef NPURE
590 #undef RHOS
591 #undef TT
592 #endif
593 }
594
595 /* Mixture-Display Functions */
596 /*
597 Print properties of a mixture, with correct formatting
598 */
599 void print_mixture_properties(char *how_calc, double rho, double u, double h, double cp, double cv, double s, double g, double a){
600 printf("\n %s %s"
601 "\n\t%s is\t\t: %.6f kg/m3"
602 "\n\t%s is\t: %g J/kg"
603 "\n\t%s is\t\t: %g J/kg"
604 "\n\t%s is\t: %g J/kg/K"
605 "\n\t%s is\t: %g J/kg/K"
606 "\n\t%s is\t\t: %g J/kg/K"
607 "\n\t%s is\t: %g J/kg"
608 "\n\t%s is\t: %g J/kg\n",
609 "For the mixture properties calculated", how_calc,
610 "The density of the mixture", rho,
611 "The internal energy of the mixture", u,
612 "The enthalpy of the mixture", h,
613 "The constant-pressure heat capacity", cp,
614 "The constant-volume heat capacity", cv,
615 "The entropy of the mixture", s,
616 "The Gibbs energy of the mixture", g,
617 "The Helmholtz energy of the mixture", a);
618 }
619
620 /*
621 Print table of properties for different substances
622 */
623 void print_substances_properties(const unsigned subst, char **headers, double *Xs, double *rhos, double *ps, double *us, double *hs, double *cps, double *cvs, double *ss, double *gs, double *as){
624 #define TBL_ROWS 11
625
626 unsigned i1,i2,i3;
627 unsigned col_width[20]={0};
628
629 double *vals[TBL_ROWS-1]={
630 Xs, rhos, ps, us, hs, cps, cvs, ss, gs, as
631 };
632
633 char *forms[TBL_ROWS-1]={
634 "% .6f", "% .6f", "%9.1f", "% .6g", "% .6g", "% .6g",
635 "% .6g", "% .6g", "% .6g", "% .6g"
636 };
637 char *sides[TBL_ROWS]={
638 "SUBSTANCES",
639 "MASS FRACTION",
640 "DENSITY (kg/m3)",
641 "PRESSURE (Pa)",
642 "INTERNAL ENERGY (J/kg)",
643 "ENTHALPY (J/kg)",
644 "C_P (J/kg/K)",
645 "C_V (J/kg/K)",
646 "ENTROPY (J/kg/K)",
647 "GIBBS ENERGY (J/kg)",
648 "HELMHOLTZ ENERGY (J/kg)"
649 };
650 char *cont[TBL_ROWS][subst+1];
651
652 PREPARE_TABLE(TBL_ROWS,subst+1,headers,sides,vals,forms,cont);
653 PRINT_STR_TABLE(TBL_ROWS,subst+1,col_width,cont);
654
655 #undef TBL_ROWS
656 }
657
658 /*
659 Print table of properties for different cases
660 */
661 void print_cases_properties(unsigned cases, char **headers, double *rhos, double *ps, double *us, double *hs, double *cps, double *cvs, double *ss, double *gs, double *as){
662 #define TBL_ROWS 10
663
664 unsigned i1,i2,i3;
665 unsigned col_width[20]={0};
666
667 double *vals[TBL_ROWS-1]={
668 rhos, ps, us, hs, cps, cvs, ss, gs, as
669 };
670
671 char *forms[TBL_ROWS-1]={
672 "% .6f", "%9.1f", "% .6g", "% .6g", "% .6g",
673 "% .6g", "% .6g", "% .6g", "% .6g"
674 };
675 char *sides[TBL_ROWS]={
676 "CASES",
677 "DENSITY (kg/m3)",
678 "PRESSURE (Pa)",
679 "INTERNAL ENERGY (J/kg)",
680 "ENTHALPY (J/kg)",
681 "C_P (J/kg/K)",
682 "C_V (J/kg/K)",
683 "ENTROPY (J/kg/K)",
684 "GIBBS ENERGY (J/kg)",
685 "HELMHOLTZ ENERGY (J/kg)"
686 };
687 char *cont[TBL_ROWS][cases+1];
688
689 PREPARE_TABLE(TBL_ROWS,cases+1,headers,sides,vals,forms,cont);
690 PRINT_STR_TABLE(TBL_ROWS,cases+1,col_width,cont);
691
692 #undef TBL_ROWS
693 }
694

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