Complementary task for topic: 8
M Nemeth · 2023-08-29 15:21:04.630218'
Dynamic arrays: Simple thermal simulation
Dynamic arrays: Simple thermal simulation
HARD!!!
Create a C program that can simulate the thermal heat propagation in 2D matterial. The user gives the number of cells and the number of "timesteps". The user gives the initial and ambient temperature and the one point source (other temperature) What you need to do:
> Create two 2D arrays to store the temperature according to the user's definition (one for the new one for the old)
> Initialize all the array elements with the ambient temperature, the source with the source temperature
> for every timestep the new temperature is calculated by
new_T[i][j] = T_old[i][j]+(T_old[i - 1][j] + T_old[i + 1][j] +
T_old[i][j - 1] + T_old[i][j + 1]-4*T_old[i][j]) / (k*4.0), where T_old is the previous result, k is the heat propagation coefficient. We use only the inner nodes to avoid out-of-range errors, also it defines a constant temperature boundary condition.
->print the results
->Do not forget to free the memory
Hint:
Solution
#include
#include
int main() {
int sizeX, sizeY, steps;
double sourceTemp, ambientTemp, k;
int sourceX, sourceY;
printf("Enter the size of the grid (X Y): ");
scanf("%d %d", &sizeX, &sizeY);
printf("Enter the number of simulation steps: ");
scanf("%d", &steps);
printf("Enter the heat source temperature: ");
scanf("%lf", &sourceTemp);
printf("Enter the ambient temperature: ");
scanf("%lf", &ambientTemp);
printf("Enter the heat propagation coefficient: ");
scanf("%lf", &k);
// Dynamically allocate memory for the grid
double **grid = (double **)malloc(sizeX * sizeof(double *));
for (int i = 0; i < sizeX; i++) {
grid[i] = (double *)malloc(sizeY * sizeof(double));
}
// Dynamically allocate memory for the new grid
double **newGrid = (double **)malloc(sizeX * sizeof(double *));
for (int i = 0; i < sizeX; i++) {
newGrid[i] = (double *)malloc(sizeY * sizeof(double));
}
// Initialize the grid with ambient temperature
for (int i = 0; i < sizeX; i++) {
for (int j = 0; j < sizeY; j++) {
grid[i][j] = ambientTemp;
newGrid[i][j]=ambientTemp; //on the borders there is no change, so it need to be initialized
}
}
// Get the position of the heat source
printf("Enter the position of the heat source (X Y): ");
scanf("%d %d", &sourceX, &sourceY);
// Set the heat source temperature
grid[sourceX][sourceY] = sourceTemp;
// Perform the thermal simulation
for (int step = 0; step < steps; step++) {
// Update the temperature at each point based on its neighbors
for (int i = 1; i < sizeX - 1; i++) {
for (int j = 1; j < sizeY - 1; j++) {
newGrid[i][j] = grid[i][j]+(grid[i - 1][j] + grid[i + 1][j] +
grid[i][j - 1] + grid[i][j + 1]-4*grid[i][j]) / (k*4.0);
}
}
// Update the current grid with the new grid
for (int i = 0; i < sizeX; i++) {
for (int j = 0; j < sizeY; j++) {
grid[i][j] = newGrid[i][j];
}
}
// Free the memory used by the new grid
}
// Print the final temperature distribution
printf("Final Temperature Distribution:\n");
for (int i = 0; i < sizeX; i++) {
for (int j = 0; j < sizeY; j++) {
printf("%.2f ", grid[i][j]);
}
printf("\n");
}
// Free the memory used by the grid and newgrid
for (int i = 0; i < sizeX; i++) {
free(newGrid[i]);
}
free(newGrid);
for (int i = 0; i < sizeX; i++) {
free(grid[i]);
}
free(grid);
return 0;
}
Explanation
We dynamically allocate memory for the 2D grid using a double pointer grid. The outer loop allocates memory for the rows, and the inner loop allocates memory for the columns. We initialize the grid with the ambient temperature by using two nested loops. We set each element of the grid to the ambientTemp. We prompt the user to enter the position of the heat source (x and y coordinates) and read the values using scanf. We set the temperature of the heat source in the grid by using the sourceX and sourceY coordinates provided by the user. We dynamically allocate memory for another 2D grid using a double pointer newGrid. This grid will be used to store the updated temperature values at each time step. We enter a loop that represents each time step of the thermal simulation. Inside the time step loop, we use nested loops to calculate the updated temperature at each point on the grid. The temperature at each point is the average of the temperatures of its four neighboring points (top, bottom, left, and right). After calculating the new temperatures, we copy the values from newGrid to the original grid to update the temperature distribution for the next time step. Once all the time steps are completed, we print the final temperature distribution by using nested loops to traverse the grid. Finally, we free the dynamically allocated memory used by both grid and newGrid to prevent memory leaks. Physicists and Electrical engineers should play a little with the code: ->what is the final temp. distribution? ->What if we updtae the "source" in every step (so it wont cool down)? ->How can we implement a heating source? So some power goes in every time-step? ->Finally, but it is really another problem, what if the matterial is not homogenous? For solve that you should define struct to hold the matterial parameters, and temperature, do the same with that. But the real scientific question is (as always): what exactly happens on the boundary?