Reputation:
Problem: To measure the volume of liquid in the tank, a depth gauge (measuring stick) can be used. It is inserted into an opening at the top and the level of liquid on the gauge can be used to determine the amount of liquid in the tank.
The tank has width w, height h and length len (in m). In the example output shown below, we take w=8, h=4 and len=7. Your programs should work for any values of w, h and len, not just these specific values.
We look at inserting a measuring stick that is already calibrated in units of 10 centimeters. This measuring gauge can be inserted into an opening at the top of the tank and used to measure the depth of the liquid in the tank.
Your task will be to write a C program to produce a table of values showing the volume of liquid in the tank for each of the points on the gauge.
The output of your program (for the example above) should look like:
Depth 10 cm : Volume 1.188814 cubic meters
Depth 20 cm : Volume 3.336448 cubic meters
Depth 30 cm : Volume 5.992683 cubic meters . . .
Depth 380 cm : Volume 172.547399 cubic meters
Depth 390 cm : Volume 174.657114 cubic meters
Depth 400 cm : Volume 175.743037 cubic meters
Methodology: If the tank has width W and height H (in centimeters), the focal radii of the cross section are A = W/2 and B = H/2. Then the equation of the ellipse is: X^2/A^2 + Y^2/B^2 = 1
To find the volume at given depth you should compute the cross-sectional area of the tank for each given depth using a numerical integration algorithm such as the trapezoidal method.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
double WIDTH;
double HEIGHT;
double LENGTH;
//Function: y in terms of x
typedef double (*DFD) (double);
double f (double x)
{
double a = HEIGHT / 2.0;
double b = WIDTH / 2.0;
double y = (b / a) * sqrt (a * a - x * x);
return y;
}
//Integrating the function -> Area
double trapezoidal_int (DFD f ,double a, double b, int n){
double x, dx, sum=0.0;
int i=0;
dx = (b-a)/ n;
sum = (f(a) + f(b))/2;
for (i=1, x = a + dx; i < n; i++, x += dx)
sum += f(x);
return 2.0 * sum * dx;
}
int main ()
{
int h_cm;
printf ("Enter Width of the tank (in m):\n");
scanf ("%lf",&WIDTH);
printf ("Enter Height of the tank (in m):\n");
scanf ("%lf",&HEIGHT);
printf ("Enter Length of the tank(in m):\n");
scanf ("%lf",&LENGTH);
for (h_cm = 0; h_cm <= HEIGHT * 100; h_cm += 10) {
double h = h_cm / 100.0;
double area = trapezoidal_int (&f, HEIGHT / 2 - h, HEIGHT / 2, 100);
double volume = area * LENGTH;
printf ("Depth %d cm: Volume %.6lf cubic metres\n",
h_cm, volume);
}
return 0;
}
Upvotes: 0
Views: 1501
Reputation:
There are a few mistakes here and there. First, let's use global variables for the dimensions of the tank so that function f() can use them:
double WIDTH;
double HEIGHT;
double LENGTH;
You function f() had the height and width reversed:
double f (double x)
{
double a = HEIGHT / 2.0;
double b = WIDTH / 2.0;
double y = (b / a) * sqrt (a * a - x * x);
return y;
}
The doubling of the value of the integral, which is necessary to measure both sides of the major axis, should be done in main() and not in trapezoidal_int(). It is bad practice to have a function that does not do what it's name suggests.
The bounds of integration were also wrong:
int main ()
{
int h_cm;
WIDTH = 8.0;
HEIGHT = 4.0;
LENGTH = 7.0;
for (h_cm = 0; h_cm <= HEIGHT * 100; h_cm += 10) {
double h = h_cm / 100.0;
double area = 2.0 * trapezoidal_int (&f, HEIGHT / 2 - h,
HEIGHT / 2, 100);
double volume = area * LENGTH;
printf ("Depth %d cm: Volume %.6lf cubic metres\n",
h_cm, volume);
}
return 0;
}
Upvotes: 1