I have been trying to solve a heat flow simulation where I have to change the temperature based on its sorrounding temperature.
If you are interested reading the problem then here is the screenshot
My input file is = Input file My output file should look like this Output file
So far I am doing pretty well but the last condition is, I have to stop the program if the stabilization criterion value exceeds 0.2.
(Remember that the stabilization criterion is a relative change, not a degree change. Relative change is defined as: |to – tn|/to where to is the old temperature and tn is the new temperature)
I am using a do while loop to check whether the value is exceeding 0.2 or not. But it is not workingf at all. I tried using while loop too but do while makes the most sense to me here.
- heatflow.h
#ifndef HEATFLOW_H
#define HEATFLOW_H
#define ROW 8 /* max rows */
#define COL 6 /* max columns */
#define TRUE 1
#define FALSE 0
#include <stdio.h>
#include <math.h>
void read_data(char filename[], double *, double *, double *, double *, double *);
void initialize_plate(double A[][COL], double , double );
void print_plate(double A[][COL],double,double);
int compute_plate( double A[][COL] , double B[][COL],double h1, double h2,double stab);
#endif
- Main.c
#include "heatflow.h"
#include <stdlib.h>
int main()
{
double plateA=0; //HEATER/COOLER A TEMPERATURE
double plateB=0; //HEATER/COOLER B TEMPERATURE:
double h1=0; //INITIAL PLATE TEMPERATURE #1:
double h2=0; //INITIAL PLATE TEMPERATURE #2:
double stab = 0; //stabilization criterion
char filename[30];
double A[ROW][COL];
double B[ROW][COL];
printf("Enter a filename = ");
scanf("%s", filename);
read_data(filename, &h1,&h2,&plateA,&plateB,&stab); //This function will read the data from the FILE
initialize_plate( A, plateA , plateB); // This function will initialize the plate
print_plate( A,h1, h2); // This function will print the plate
compute_plate(A, B, h1, h2, stab); // This function will compute the problem.
}
heatflow.c
#include "heatflow.h"
void read_data(char filename[], double *h1, double *h2, double *plateA, double *plateB, double *SCV)
{
FILE *obk ;
obk = fopen(filename, "r");
if(obk == NULL)
{
printf("There is no file like that\n");
}
else
printf("File has found\n");
fscanf(obk,"%lf %lf %lf %lf %lf", &*h1, &*h2, &*plateA, &*plateB, &*SCV);
printf("HEATER/COOLER A TEMPERATURE =%lf\n HEATER/COOLER B TEMPERATURE= %lf\nINITIAL PLATE TEMPERATURE #1: = %lf\nINITIAL PLATE TEMPERATURE #2:= %lf\n STABILIZE CRITERION: = %lf\n\n\n\n", *h1, *h2,*plateA, *plateB, *SCV);
}
void initialize_plate(double A[][COL], double plateA, double plateB )
{
printf("Initial plate\n\n\n\n");
int count = 0 ;
for (int i = 0 ; i < ROW; i )
{
for( int j = 0 ; j<COL ; j )
{
if(count < 4) //within 4 row, we will first print plateA and then plateB
{
if ( j <3)
{
A[i][j] = plateA;
}
if( (j>=3) && (j< COL))
{
A[i][j] = plateB ;
}
}
if (count >=4 && count < ROW) //After 4 row, we will print plateB and then plateA
{
if ( j <3)
{
A[i][j] =plateB;
}
if( j>=3 && j< COL )
{
A[i][j] = plateA ;
}
}
}
count ;
}
}
void print_plate(double A[][COL],double h1,double h2)
{
printf("`.2lf\n", h1) ;
int count = 0 ;
printf(" |-----------------------------------------------------------------------------------------------------|\n");
for (int i = 0 ; i <ROW ; i )
{
for (int j = 0; j < COL ; j )
{
printf(" | %5.2lf ", A[i][j]) ;
}
printf(" |");
printf("\n");
if (count==4)
{
printf("%0.2lf |-----------------------------------------------------------------------------------------------------| %0.2lf\n", h1,h2);
}
else {
printf(" |-----------------------------------------------------------------------------------------------------|\n");
}
count ;
}
printf("`.2lf\n", h2) ;
}
int compute_plate( double A[][COL] , double B[][COL],double h1, double h2,double
stab) {
double check = 0; //it will store the stabilization criterion value then compare with stab(0.2)
do {
for (int i = 0; i < ROW; i ) {
for (int j = 0; j < COL; j ) {
if (((A[i][j] - B[i][j]) / A[i][j]) > 0) {
check = ((A[i][j] - B[i][j]) / A[i][j]);
} else if (((A[i][j] - B[i][j]) / A[i][j]) < 0) {
check = (-1 * ((A[i][j] - B[i][j]) / A[i][j]));
}
if (i == 0 && j == 0) {
B[i][j] = (h1 h1 A[i][j 1] A[i 1][j]) / 4;
}
if (i == 0 && (1 <= j && j < 5)) {
B[i][j] = (h1 A[i][j - 1] A[i][j 1] A[i 1][j]) / 4;
}
if (i == 0 && j == 5) {
B[i][j] = (h1 h2 A[i][j - 1] A[i 1][j]) / 4;
}
if ((i > 0 && i < 7) && j == 0) {
B[i][j] = (h1 A[i - 1][j] A[i][j 1] A[i 1][j]) / 4;
}
if ((i > 0 && i < 7) && j == 5) {
B[i][j] = (h2 A[i - 1][j] A[i][j - 1] A[i 1][j]) / 4;
}
if ((i == 7) && (j == 0)) {
B[i][j] = (h1 h2 A[i - 1][j] A[i][j 1]) / 4;
}
if ((i == 7) && (j == 5)) {
B[i][j] = (h2 h2 A[i - 1][j] A[i][j - 1]) / 4;
}
if ((i == 7) && (j > 0 && j < 5)) {
B[i][j] = (h2 A[i][j - 1] A[i][j 1] A[i - 1][j]) / 4;
}
if ((i > 0 && i < 7) && (j > 0 && j < 5)) {
B[i][j] = (A[i 1][j] A[i - 1][j] A[i][j 1] A[i][j - 1]) / 4;
}
printf("%0.2lf\t", B[i][j]);
A[i][j] = B[i][j]; //this will store B array into A array for the future progression
} printf("\n");
}
} while( check > stab) ;
}
c
CodePudding user response:
I will try to help you with your assignment without actually doing it for you.
Before you start your program, you need to understand the problem thoroughly.
Make sure that compute_plate function give the same results whether we go from top-to-bottom, bottom-to-top, left-to-right, or right-to-left. Therefore, copy all elements from B array to A array after you finish calculations for all elements.
The simulation of traversals continues until no element in the array changes by a significant relative amount. MEANING: Check all elements
... element_flag = (check > stab); all_flags = all_flags | element_flag; ... } while (all_flags);
You must be able to justify each line in your program. Am I doing it correctly? And can I do it better?
Try to avoid hardcoded numbers as much as possible.
Use if, else if, else when possible. For example, change:
if(count < 4) { } if (count >=4 && count < ROW) { }
To:
if(count < 4) { } else { }
Try to simplify your if statements: Currently the if statements are 2-dimensional. Therefore, you have 9 complex cases:
if (i == 0 && j == 0) { B[i][j] = (h1 h1 A[i][j 1] A[i 1][j]) / 4; } if (i == 0 && (1 <= j && j < 5)) { B[i][j] = (h1 A[i][j - 1] A[i][j 1] A[i 1][j]) / 4; } ...
Change them to 6 simple one-dimensional cases:
if (i == 0) {
top = h1;
bottom = A[i 1][j];
} else if (i == (ROW - 1)) {
...
} else {
...
}
if (j == 0) {
left = ...;
right = ...;
} else if (...) {
...
} else {
...
}
B[i][j] = (top bottom right left) / 4;
Keep up the good work and have fun programming :-)
CodePudding user response:
This is not an answer to your question, but it's too large to put it in a comment.
Let's have a look at this excerpt in your code:
if (((A[i][j] - B[i][j]) / A[i][j]) > 0) {
check = ((A[i][j] - B[i][j]) / A[i][j]);
} else if (((A[i][j] - B[i][j]) / A[i][j]) < 0) {
check = (-1 * ((A[i][j] - B[i][j]) / A[i][j]));
}
First, let's say:
x = A[i][j]
y = B[i][j]
So you are checking:
(x - y) / x > 0 (which is the same as:)
1 - y/x > 0 (which is the same as:)
1 > y/x (which is the same as:)
x > y
So, instead of:
if (((A[i][j] - B[i][j]) / A[i][j]) > 0) {
... you can write:
if (A[i][j] > B[i][j]) {
Second, let's say that:
u = ((A[i][j] - B[i][j]) / A[i][j]);
Then you are saying:
if (u > 0) {
check = u;
} else { // if u <= 0
check = -u;
This can be simplified to:
check = abs(u); // I don't know exactly if you need
// to include some header file for this.
// Obviously, when you opt for this, no need for
// the x,y thing I mentioned first :-)
As you see, your code can be simplified, just by using some basic mathematical rules and functions.