This is legal syntax, but it doesn't really help a human being who looks at it:

Code:

float calc_psat (float, float, float, float, float, float);
float calc_gamma_e(float, float, float, float);
float calc_gamma_w(float, float, float, float);
float calc_abv(float);
float calc_abw(float, float, float, float);

You should leave the parameter names in the function declarations so that someone looking at the function declaration has an idea what the parameters are for.

It is good to have named constants rather than magic numbers, but in theory you could accidentally modify them, resulting in a bug that might be hard to find:

Code:

/*Antoine Coefficients (C)*/
float eA = 8.13484;
float eB = 1662.48;
float eC = 238.131;
float wA = 8.05573;
float wB = 1723.64;
float wC = 233.076;
/*Van Laar activity model constants*/
float A12 = 1.68811;
float A21 = 0.95268;
float density_w = 0.998; /*Density of water at 20C */
float density_e = 0.785;
float mm_w = 18.0153;
float mm_e = 46.0684;

To avoid this, they should be declared const, or changed into macro constants.

This is an off-by-one error:

Code:

float boil_pt[100];
for ( a = 0; a < 101; a++ )
boil_pt[a] = 0;

On the last iteration of the loop, you assign 0 to boil_pt[100], but as there are only 100 float elements in boil_pt, boil_pt[100] does not exist. It's related to my observation that when you wrote that "0% ethanol-100% water, 1% ethnol-99% water... 100% ethanol-0% water. 100 fractions each with a different boil point", you made an off-by-one error: there are 101 fractions, not 100 fractions. To solve this, I would first declare a macro constant before the main function, e.g.

Code:

#define NUM_MIXTURE_PERCENTAGES 101

Then I would use it:

Code:

float boil_pt[NUM_MIXTURE_PERCENTAGES];
for ( a = 0; a < NUM_MIXTURE_PERCENTAGES; a++ )
boil_pt[a] = 0;

Having said that, because this is a special case where you want to set all the elements of the array of the initial value of 0, you don't actually need a loop:

Code:

float boil_pt[NUM_MIXTURE_PERCENTAGES] = {0};

This way, you initialise the first element to 0, then the remaining elements are initialised to 0 by default. This only works for 0 though: if you tried it with 1, you would initialise the first element to 1, then the remaining elements would still be initialised to 0 by default.

Anyway, the same goes for boiler_abv and vapor_abv.

Originally Posted by

**Buckeye Bing**
And I'm trying to get my head around a FOR outer loop the way my program is currently constructed.

Let's take a look at your current loop with proper indentation:

Code:

int index = 0;
/* ...
lots of code/declarations in between obscuring what the value of index is just before the loop
... */
while (index < 101)
{
float seed_temp = 70;
float atm_press = 760;
float gamma_e = calc_gamma_e(x1, x2, A12, A21);
float gamma_w = calc_gamma_w(x1, x2, A12, A21);
do {
psat1 = calc_psat(eA, eB, eC, seed_temp, gamma_e, x1);
psat2 = calc_psat(wA, wB, wC, seed_temp, gamma_w, x2);
seed_temp = seed_temp + 0.0001;
}
while (psat1 + psat2 < 760);
boil_pt[index] = seed_temp;
y1 = psat1 / atm_press;
y2 = psat2 / atm_press;
boiler_abw = calc_abw(mm_e, mm_w, x1, x2);
vapor_abw = calc_abw(mm_e, mm_w, y1, y2);
printf("\npercent \tboil pt \tpressure \tpsat1 \tpsat2\n");
printf("%1.2f \t%2.5f \t%3.4f \t%3.2f \t%3.2f\n",
x1, boil_pt[index], psat1+psat2, psat1, psat2);
boiler_abv[index] = calc_abv(boiler_abw);
vapor_abv[index] = calc_abv(vapor_abw);
x1 = x1 + 0.01;
x2 = 1-x1;
y1 = y1 + 0.01;
y2 = 1 - y1;
index++;
}

So, it turns out that you are modifying index in the loop after all: right at the end. It would hence be clearer if you wrote this:

Code:

/* ...
lots of code/declarations
... */
for (int index = 0; index < NUM_MIXTURE_PERCENTAGES; index++)
{
float seed_temp = 70;
float atm_press = 760;
float gamma_e = calc_gamma_e(x1, x2, A12, A21);
float gamma_w = calc_gamma_w(x1, x2, A12, A21);
do {
psat1 = calc_psat(eA, eB, eC, seed_temp, gamma_e, x1);
psat2 = calc_psat(wA, wB, wC, seed_temp, gamma_w, x2);
seed_temp = seed_temp + 0.0001;
}
while (psat1 + psat2 < 760);
boil_pt[index] = seed_temp;
y1 = psat1 / atm_press;
y2 = psat2 / atm_press;
boiler_abw = calc_abw(mm_e, mm_w, x1, x2);
vapor_abw = calc_abw(mm_e, mm_w, y1, y2);
printf("\npercent \tboil pt \tpressure \tpsat1 \tpsat2\n");
printf("%1.2f \t%2.5f \t%3.4f \t%3.2f \t%3.2f\n",
x1, boil_pt[index], psat1+psat2, psat1, psat2);
boiler_abv[index] = calc_abv(boiler_abw);
vapor_abv[index] = calc_abv(vapor_abw);
x1 = x1 + 0.01;
x2 = 1-x1;
y1 = y1 + 0.01;
y2 = 1 - y1;
}

Are these constants a to j well known names in the literature?

Code:

float calc_abv(float abw)
{
float abv = 0;
float a = -0.000039705486746795932;
float b = 1.2709666849144778;
float c = -0.40926819348115739;
float d = 2.0463351302912738;
float f = -7.8964816507513707;
float g = 15.009692673927390;
float h = -15.765836469736477;
float i = 8.8142267038252680;
float j = -2.0695760421183493;
float temp = j;
temp = temp * abw +i;
temp = temp * abw +h;
temp = temp * abw +g;
temp = temp * abw +f;
temp = temp * abw +d;
temp = temp * abw +c;
temp = temp * abw +b;
abv = temp * abw +a;
return (abv);
}

If they are, keeping them is okay, though you might want to place a comment with some explanation. If they are not, then you're just naming constants for the sake of naming them without providing descriptive names, so there's no point. I would prefer to use a static array and a loop instead:

Code:

float calc_abv(float abw)
{
static const float modifiers[] = {
-2.0695760421183493,
8.8142267038252680,
-15.765836469736477,
15.009692673927390,
-7.8964816507513707,
2.0463351302912738,
-0.40926819348115739,
1.2709666849144778,
-0.000039705486746795932
};
float abv = 0.0f;
for (size_t i = 0; i < sizeof(modifiers) / sizeof(modifiers[0]); ++i)
{
abv = abv * abw + modifiers[i];
}
return abv;
}

Then again, even if the constants a to j are well known names in the literature, you might use this array+loop approach anyway and just write the domain-specific constant names as comments next to the array elements.