Home > database >  Heat flow simulation C programming problem
Heat flow simulation C programming problem

Time:12-06

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 METHOD

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.

  • Related