Code:
#include <stdio.h>
#include "gng1106plplot.h" // gives definition to use the library PLplot
#include <math.h>
#include <float.h>
#include "plplot.h"
#define EPSILON 0.00000000001
#define NUM 100 // Number of points
#define N 100
#define BINFILE « FileProjectGng.bin »
// Structure
typedef struct
{
double roughness;
double diameter;
double density;
double velocity;
double viscosity;
int state ;
} INPUTS;
// Prototypes of functions
void findInterval(INPUTS pipe,double *, double *);
int findRoot(INPUTS pipe, double, double, double *);
void plotFunc(INPUTS pipe, double, double, int, double []);
double func(INPUTS* pipe, double);
void plot(int, double[], double[], int, double[], double[]);
double getMin(double *, int );
double getMax(double *, int );
void CreatFile(INPUTS allInputs[5]);
void ShowFileContent();//INPUTS* allInputs[5],FILE* file
int UserChoice(INPUTS* pipe,INPUTS allInputs[5]);
int GetInput(INPUTS* pipe);
void SaveInputs(INPUTS* allInputs, INPUTS* pipe, FILE* file);
/*---------------------------------------------------------------------
Fonction: main
Description: This function is called to fins the values of the friction and draw the curve.
It also tests if the file is empty or full and fills it zith the vakues of the
array.
------------------------------------------------------------------------*/
int main(void)
{
// variable declaration
double start, end;
double root;
int n; // number of roots found
// Déclarations des variables
int choicefile;
int choiceSave;
INPUTS pipe;
INPUTS allInputs[5] = {{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}};
FILE* file;
file = fopen("BINFILE", "rb");
if(file != NULL)
{
//calling ShowFileContent
ShowFileContent(allInputs[5], file);
//calling choicefile
choicefile = UserChoice(&pipe, &allInputs[5]);
if (choicefile== 0) //The user doesn't want data from file
{
choiceSave = GetInput(&pipe);//canal est rempli!
if (choiceSave== 1)
SaveInputs(&allInputs[5], &pipe, file);
}
//else, the user doesn't want to register these values
//else, the file pipe is full
else
{
pipe.roughness = allInputs[choicefile-1].roughness;
pipe.diameter = allInputs[choicefile-1].diameter;
pipe.density = allInputs[choicefile-1].density;
pipe.velocity = allInputs[choicefile-1].velocity;
pipe.viscosity =allInputs[choicefile-1].viscosity;
pipe.state =allInputs[choicefile-1].state;
}
}
else
{
//Call to creat file
CreatFile(allInputs);
choiceSave = GetInput(&pipe);//canal est remplie
if (choiceSave == 1)
SaveInputs(&allInputs[5], &pipe, file);
//else, the user doesn't want to register these data
//else, the pipe is full
}
// det interval from user
findInterval(pipe,&start, &end);
printf("Finding root for interval between %.4f and %.4f\n",
start, end);
if(findRoot(pipe,start, end, &root))
{
printf("Found root at: %.8f (f(x) = %.8f)\n",root);//, func(root));
n = 1;
}
else
{
printf("Did not find root in interval.");
n = 0;
}
plotFunc(pipe, start, end, n, &root);
return 0;
}
/*----------------------------------------------------------
Function: ShowFileContent
Parameters:
allInputs- reference to an array of structures
file - pointer to the file
Returns
nothing
Description: prints the content of the file if the value of the state is different of 0
----------------------------------------------------------------*/
void ShowFileContent(INPUTS *allInputs[5],FILE *file)
{
file = fopen("BINFILE", "rb");
if(file == NULL)
printf("ERROR");
else
{
fread(allInputs, sizeof(INPUTS), 5, file);//
//To initialize the array of structures
//Print the array
if (allInputs[0]->state == 0)
printf("pipe 1 available");
else
printf("\npipe 1:\n%lf, %lf, %lf, %lf, %lf\n",allInputs[0]->roughness,
allInputs[0]->diameter, allInputs[0]->density, allInputs[0]->velocity,allInputs[0]->viscosity,
allInputs[0]->state);
if (allInputs[1]->state == 0)
printf("pipe 2 is available");
else
printf("\npipe 2:\n%lf, %lf, %lf, %lf, %lf\n",allInputs[1]->roughness,
allInputs[1]->diameter, allInputs[1]->density, allInputs[1]->velocity,allInputs[1]->viscosity,
allInputs[1]->state);
if (allInputs[2]->state == 0)
printf("pipe 3 is available ");
else
printf("\npipe 3:\n%lf, %lf, %lf, %lf, %lf, %lf\n",allInputs[2]->roughness,
allInputs[2]->diameter, allInputs[2]->density, allInputs[2]->velocity,allInputs[2]->viscosity,
allInputs[2]->state);
if (allInputs[3]->state == 0)
printf("pipe 4 available");
else
printf("\npipe 4:\n%lf, %lf, %lf, %lf, %lf, %lf\n",allInputs[3]->roughness,
allInputs[3]->diameter, allInputs[3]->density, allInputs[3]->velocity,allInputs[3]->viscosity,
allInputs[3]->state);
if (allInputs[4]->state== 0)
printf("pipe 5 available");
else
printf("\npipe 5:\n%lf, %lf, %lf, %lf, %lf, %lf\n" ,allInputs[4]->roughness,
allInputs[4]->diameter,allInputs[4]->density,allInputs[4]->velocity, allInputs[4]->viscosity,
allInputs[4]->state );
fclose(file);
}
}
/*----------------------------------------------------------
Function: UserChoice
Parameters:
pipe- pointer to the structure INPUTS
allInputs- reference to array of strucutres
Returns
choice ; an integer variable that shows the choice of the user
Description: Asks the user if he is satisfied zith the current values or if he wishes to change them
----------------------------------------------------------------*/
int UserChoice(INPUTS* pipe,INPUTS allInputs[5])
{
//declaring variables
int choice;
printf("Do you want to use the present data?\n"
"if yes, enter the number of the canal of your choice."
"otherwise, enter the number 0");
scanf("%d", &choice);
do
{
printf("The choice is invalid");
printf("Do you want to chose the present data?\n"
"if yes, enter the value of the chosed pipe"
"if not, enter the number 0");
scanf("%d", &choice);
}while (choice <0 && choice >5);
return(choice);
}
/*----------------------------------------------------------
Function: GetInput
Parameters:
pipe- pointer to structure
Returns
choice -the choice of the user
Description: gets input from the user and tests if the that values
of roughness ,density and viscosity belong to the right interval.
----------------------------------------------------------------*/
int GetInput(INPUTS* pipe)
{
//declaring variables
int choice;
printf("you have chosen to enter your own values.\n");
printf("enter the values of the roughness, diameter, density, velocity, viscosity:");
scanf("%lf %lf %lf %lf %lf", &pipe->roughness, &pipe->diameter, &pipe->density, &pipe->velocity, &pipe->viscosity);
pipe->state = 1;
while (pipe->roughness <0.0001 || pipe->roughness>3.0 || pipe->density<0.5 || pipe->density>2000 || pipe->viscosity >300.0 || pipe->viscosity <0.000001)
{
printf("The values of the rooughness,density and viscosity are invalid");
printf("Enter other values of the roughness , density and viscosity:");
scanf("%lf %lf %lf", pipe->roughness, pipe->density, pipe->viscosity);
}
printf("Do you want to register these data? (1 for yes and 0 for no");
scanf("%d", &choice);
return(choice);
}
/*----------------------------------------------------------
Function: SaveInputs
Parameters:
allInputs- reference to an array of strucutres
pipe - pointer to strucutre
file- pointer to the file
Returns
nothing
Description: fills the the values of the array with the elements
of the structure and saves them
----------------------------------------------------------------*/
void SaveInputs(INPUTS* allInputs, INPUTS* pipe, FILE* file)
{
//declaring variables
int newchoice = 6;
file = fopen("BINFILE", "wb");
if (file == NULL){
printf("ERROR");
}
else
{
if (allInputs[0].state == 0)
{
allInputs[0].roughness = pipe->roughness;
allInputs[0].density = pipe->density;
allInputs[0].diameter = pipe->diameter;;
allInputs[0].velocity = pipe->velocity;
allInputs[0].viscosity = pipe->viscosity;
allInputs[0].state = pipe->state;
}
else if (allInputs[1].state == 0)
{
allInputs[1].roughness = pipe->roughness;
allInputs[1].density = pipe->density;
allInputs[1].diameter = pipe->diameter;;
allInputs[1].velocity = pipe->velocity;
allInputs[1].viscosity = pipe->viscosity;
allInputs[1].state = pipe->state;
}
else if (allInputs[2].state == 0)
{
allInputs[2].roughness = pipe->roughness;
allInputs[2].density = pipe->density;
allInputs[2].diameter = pipe->diameter;;
allInputs[2].velocity = pipe->velocity;
allInputs[2].viscosity = pipe->viscosity;
allInputs[2].state = pipe->state;
}
else if (allInputs[3].state == 0)
{
allInputs[3].roughness = pipe->roughness;
allInputs[3].density = pipe->density;
allInputs[3].diameter = pipe->diameter;
allInputs[3].velocity = pipe->velocity;
allInputs[3].viscosity = pipe->viscosity;
allInputs[3].state = pipe->state;
}
else if (allInputs[4].state == 0)
{
allInputs[4].roughness = pipe->roughness;
allInputs[4].density = pipe->density;
allInputs[4].diameter = pipe->diameter;;
allInputs[4].velocity = pipe->velocity;
allInputs[4].viscosity = pipe->viscosity;
allInputs[4].state = pipe->state;
}
else
{
printf("The file is full, chose a set of data from 1 to 5 to erase to replace ");
scanf("%d", &newchoice);
allInputs[newchoice - 1].roughness = pipe->roughness;
allInputs[newchoice - 1].density = pipe->density;
allInputs[newchoice - 1].diameter = pipe->diameter;
allInputs[newchoice - 1].velocity = pipe->velocity;
allInputs[newchoice - 1].viscosity = pipe->viscosity;
allInputs[newchoice- 1].state = 1;
}
//find a way to write everything in the array
fwrite(allInputs, sizeof(INPUTS), 5, file);
fclose(file);
}
}
/*----------------------------------------------------------
Function: CreatFile
Parameters:
allInputs - reference to the array of structures
Returns
nothing
Description: creats a file and opens it in writing binary mode
----------------------------------------------------------------*/
void CreatFile(INPUTS allInputs[5])
{
FILE* file;
file= fopen("BINFILE", "wb");
fwrite(allInputs, sizeof(INPUTS), 5, file);
}
/*----------------------------------------------------------
Function: getMax
Parameters:
array - reference to an array with double values
n - number of elements in the array
Returns
max: the maximum value found in the array
Description: Traverses the array to find its maximum value.
----------------------------------------------------------------*/
int findRoot(INPUTS pipe, double lower, double upper, double *root)
{
int retVal=0;
double coe;
double mid;
double gf_mid,check;
while(retVal == 0)
{
mid=(lower+upper)/2;
if (func(&pipe, mid)*func(&pipe, lower)<0)
{
upper=mid;
// mid=(lower+upper)/2;
}
if (func(&pipe,mid)*func(&pipe,lower)>0)
{
lower=mid;
// mid=(lower+upper)/2;
}
check = fabs(func(&pipe, upper)*func(&pipe, lower));
if (check<EPSILON)
{
retVal=1;
*root=mid;
printf("the root has been found\n");
}
}
return(retVal);
}
/*----------------------------------------------------------
Function: func
Parameters:
x - x value function f(x)
Returns: value y of function f(x)
Description: Plots the value of the function:
f(x) = 50 - x^2 |cos(sqrt(x)| , x must be positive, if x
negative return 0.
-----------------------------------------------------------*/
double func(INPUTS *pipe, double x)
{
double gf,f;
double Re;
Re= ((pipe->density)*(pipe->velocity)*(pipe->diameter))/pipe->viscosity;
gf = (1/sqrt(f)) +2.0*(log((pipe->roughness/(3.7*pipe->diameter))))+(2.51/(Re*sqrt(f)));
return(gf);
}
/*----------------------------------------------------------
Function: findInterval
Parameters:
begin, end: pointers to double variables for storing selected
begin and end values of x for the desired interval
Description: Repeatedly plot the graph of the function for the
intervals given by the user until the user
has made a selection of the interval for root
finding.
---------------------------------------------------------------*/
void findInterval(INPUTS pipe,double *begin, double *end)
{
//Variables declarations
char answer; // sentinal
do
{
printf("Please give start and end values for plotting: ");
fflush(stdin);
scanf("%lf %lf",begin,end);
plotFunc(pipe,*begin, *end, 0, NULL);
printf("Are you happy with this interval: ");
fflush(stdin);
scanf("%c",&answer);
}
while(answer != 'y');
}
/*----------------------------------------------------------
Function: plotFunc
Parameters:
begin, end: beginning and end of interval (x values) to plot
flag - set to TRUE when root was found and needs to be plotted
root - value of root when flag is TRUE.
Description: Plot the function on the
interval between begin and end. Plots an x at the roots
if nRoots > 0.
---------------------------------------------------------------*/
void plotFunc(INPUTS pipe,double begin, double end, int nRoots, double roots[])
{
double x[N];
double y[N];
double inc; // increment for incrementing x
double yRoots[nRoots];
int ix;
// Calculate function points
inc = (end - begin)/N;
x[0] = begin;
//y[0] = func(&pipe, &x[0]); // Compute first point
for(ix = 1; ix < N; ix = ix + 1)
{
x[ix] = x[ix -1] + inc;
y[ix] = func( &pipe,x[ix]);
}
// Calculate y points at the root
for(ix = 0; ix < nRoots; ix = ix +1)
{
yRoots[ix] = func(&pipe, roots[ix]);
}
// Plot
plot(N, x, y, nRoots, roots, yRoots);
}
/*-------------------------------------------------
Function: plot()
Parameters:
n: number of points in the arrays
xPtr: pointer to x values (horizontal axis).
yPtr: pointer to y values (vertical axis).
Return value: none.
Description: Initialises the plot. The following values
in the referenced structure are used to setup
the plot:
x[0], x[n-1] - assume that x values are sequential
miny, maxy - vertical axis range (add 10% to min/max value)
Sets up white background and black forground
colors.
Then plots the curve accessed using xPtr and yPtr.
-------------------------------------------------*/
void plot(int n, double *xPtr, double *yPtr, int nRoots, double *xRoots, double *yRoots)
{
double miny, maxy;
double range; // range of vertical axix
// Setup plot configuration
plsdev("wingcc"); // Sets device to wingcc - CodeBlocks compiler
// Initialise the plot
plinit();
// Configure the axis and labels
plwidth(3); // select the width of the pen
// Find range for axis
miny = getMin(yPtr, n);
maxy = getMax(yPtr, n);
range = maxy - miny; // the width of the range
maxy = maxy + 0.1*range;
miny = miny - 0.1*range;
plenv0(xPtr[0], xPtr[n-1], miny, maxy,
0, 1);
plcol0(GREEN); // Select color for labels
pllab("x", "f(x)", "Function");
// Plot the velocity.
plcol0(BLUE); // Color for plotting curve
plline(n, xPtr, yPtr);
// Plot the points
if(nRoots > 0)
{
plcol0(RED);
plpoin(nRoots,xRoots, yRoots, 'x');
}
plend();
}
/*----------------------------------------------------------
Function: getMin
Parameters:
array - reference to an array with double values
n - number of elements in the array
Returns
min: the minimum value found in the array
Description: Traverses the array to find its minimum value.
----------------------------------------------------------------*/
double getMin(double *array, int n)
{
int ix;
double min = array[0];
for(ix = 1; ix < n; ix = ix +1){
if(min > array[ix])
{
min = array[ix];
}
}
return(min);
}
/*----------------------------------------------------------
Function: getMax
Parameters:
array - reference to an array with double values
n - number of elements in the array
Returns
max: the maximum value found in the array
Description: Traverses the array to find its maximum value.
----------------------------------------------------------------*/
double getMax(double *array, int n)
{
int ix;
double max = array[0];
for(ix = 1; ix < n; ix = ix +1)
if(max < array[ix]) max = array[ix];
return(max);
}