-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathheat_equation.cpp
146 lines (112 loc) · 4.12 KB
/
heat_equation.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iomanip>
#include <fstream>
#include <iostream>
#include <assert.h>
#include "dcl.h"
using namespace std;
#define NX 100 // Number of spatial grid points
#define NT 5000 // Number of time steps
#define L 1.0 // Length of the domain
#define T 5.0 // Total simulation time
#define DX (L / (NX - 1)) // Spatial step size
#define DT (T / NT) // Time step size
#define ALPHA 0.01 // Thermal diffusivity
/// Courant–Friedrichs–Lewy (CFL) condition:
/// (DT * ALPHA) / (DX * DX) <= 1/2
float u_prev[NX];
float u_curr[NX];
ofstream fp;
// Function to initialize the temperature profile
void initialize() {
for (int i = 0; i < NX; i++) {
float x = i * DX;
u_prev[i] = 2000*sin(M_PI * x);
}
}
// Function to solve the heat equation using explicit finite difference method
void solveHeatEquation() {
#pragma HLS INTERFACE s_axilite port=return
for (int n = 0; n < NT; n++) {
if(n == 0)
fp.open("temperature.txt");
else fp.open("temperature.txt", ios::app);
fp << "Time step " << n << "\n";
for (int i = 0; i < NX; i++) {
double x = i * DX;
fp << std::fixed << std::setprecision(16) << x << " " << u_prev[i] << "\n";
}
fp.close();
bool overflow = false;
float tmp1, tmp2, tmp3, tmp4, tmp5;
// Apply explicit finite difference scheme
for (int i = 1; i < NX - 1; i++) {
// original equation:
// u_curr[i] = u_prev[i] + ALPHA * DT / (DX * DX) * (u_prev[i - 1] - 2 * u_prev[i] + u_prev[i + 1]);
tmp1 = DX * DX;
tmp2 = (u_prev[i - 1] - 2 * u_prev[i] + u_prev[i + 1]);
tmp3 = ALPHA * DT;
tmp4 = tmp3 / tmp1;
// this is where the flexible multiplier is used
// removed the real code for simplicity
//tmp5 = flexible_float_multiply_retry(tmp4, tmp2, true);
tmp5 = tmp4 * tmp2;
u_curr[i] = u_prev[i] + tmp5;
}
// Approximate du/dx at boundaries using finite differences
// Neumann boundary condition: du/dx at x = 0
// u_curr[0] = u_prev[0] + ALPHA * DT / (DX * DX) * (u_prev[1] - u_prev[0]);
tmp1 = DX * DX;
tmp2 = (u_prev[1] - u_prev[0]);
tmp3 = ALPHA * DT;
tmp4 = tmp3 / tmp1;
// this is where the flexible multiplier is used
// removed the real code for simplicity
// tmp5 = flexible_float_multiply_retry(tmp4, tmp2, true);
tmp5 = tmp4 * tmp2;
u_curr[0] = u_prev[0] + tmp5;
// Neumann boundary condition: du/dx at x = L
// u_curr[NX - 1] = u_prev[NX - 1] + ALPHA * DT / (DX * DX) * (u_prev[NX - 2] - u_prev[NX - 1]);
tmp1 = DX * DX;
tmp2 = (u_prev[NX - 2] - u_prev[NX - 1]);
tmp3 = ALPHA * DT;
tmp4 = tmp3 / tmp1;
// this is where the flexible multiplier is used
// removed the real code for simplicity
// tmp5 = flexible_float_multiply_retry(tmp4, tmp2, true);
tmp5 = tmp4 * tmp2;
u_curr[NX - 1] = u_prev[NX - 1] + tmp5;
// Update the solution for the next time step
for (int i = 0; i < NX; i++) {
u_prev[i] = u_curr[i];
}
}
}
// Function to print the temperature profile
void printTemperature() {
// write results to file
fp.open("temperature.txt", ios::app);
for (int i = 0; i < NX; i++) {
float x = i * DX;
printf("%f %f\n", x, u_prev[i]);
float ff = u_prev[i];
//fp << std::fixed << std::setprecision(16) << x << " " << ff << "\n";
fp << x << " " << ff << "\n";
}
fp.close();
}
int main() {
// Check CFL condition:
// (DT * ALPHA) / (DX * DX) <= 1/2
printf("(DT * ALPHA) / (DX * DX): %f\n", (DT * ALPHA) / (DX * DX));
printf("(%f * %f) / (%f * %f)\n", DT, ALPHA, DX, DX);
// Initialize temperature profile
initialize();
// Solve the heat equation
solveHeatEquation();
// Print the final temperature profile
printTemperature();
return 0;
}