-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
196 lines (151 loc) · 5.31 KB
/
main.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#include <iostream>
#include <cmath>
#include "indexing.h"
#include "basis.h"
#include "EulerFlux.h"
#include "SpatialDiscretization.h"
using namespace std;
void veccopy(double* a, const double* b, size_t n){
for (int i=0; i<n; i++){
a[i] = b[i];
}
}
double Initialize(double x){
///This defines the intial state of the solution space
//Gaussian bump and step combo
if (x < 0.6) {
double beta = 0.005;
return 1 + exp(-(x-0.3)*(x-0.3) / beta);
} else {
if (x < 0.8) {
return 2.0;
} else {
return 1.0;
}
}
//return 2.0 + sin(2.0*M_PI*x);
//return 1.0 + exp(-40*(x-0.5)*(x-0.5));
if (x<0.5){
return 1.0;
} else {
return 0.0;
}
}
void InitializeEuler(double x, double* u){
double rho = 1.0;
double v = 1.0;
double p = 1.0;
//rho = Initialize(x) + 10.0;
if (x < 0.5){
rho = 1.0;
v = 0.0;
p = 1.0;
} else {
rho = 1.0 / 211.0 ;//0.125;
v = 0.0;
p = rho;
}
u[0] = rho; //rho
u[1] = rho * v; //rho V
u[2] = 0.5*rho*v*v + (p/(GAM-1.0)); //rho e
}
int main() {
///hardcoded inputs
int nx = 100; //Number of elements, nx+1 points
double dx = 1.0 / nx; //Implied domain from x=0 to x=1
int ndegr = 3; //Degrees of freedom per element
int nvar = NVAR; //Number of variables
int nu = nx * ndegr * nvar;
double cfl = 0.1/(ndegr*ndegr); //CFL Number
double tmax = 0.6;
double dt = (cfl * dx); // /a;
int niter = ceil(tmax/dt); //Guess number of iterations required to get to the given tmax //10*3*80
//Find the solution points in reference space
auto* xi = (double*)malloc(ndegr*sizeof(double));
GenerateLobattoPoints(ndegr, xi);
//Find the derivative matrix of the associated lagrange polynomials
//Derivatie of L_j at position x_i
auto* Dmatrix = (double*)malloc(ndegr*ndegr*sizeof(double));
GenerateLagrangeDMatrix(ndegr, xi, Dmatrix);
//Find the derivatives of the Radau polynomial of appropriate degree
auto* Dradau = (double*)malloc(2*(1+ndegr)*sizeof(double));
GenerateRadauDerivatives(ndegr, xi, Dradau);
//Allocate Arrays
auto* x = (double*)malloc(nx*sizeof(double));
auto* u = (double*)malloc(nu*sizeof(double));
auto* u0 = (double*)malloc(nu*sizeof(double));
auto* dudt = (double*)malloc(nu*sizeof(double));
//Generate Grid (currently uniform) & initialize solution
for (int i=0; i<nx; i++){
//defining x position of cell centers
x[i] = (i+0.5) * dx;
for (int j=0; j<ndegr; j++) {
//InitializeEuler(x[i], &u[iu3(i, j, 0, ndegr)]); //+ xi[j]*(0.5 * dx)
if (x[i] > 0.6) {
u[iu3(i, j, 0, ndegr)] = Initialize(x[i] + (0.0 * dx)); //enforce a sharp initial discon
} else {
u[iu3(i, j, 0, ndegr)] = Initialize(x[i] + xi[j]*(0.5 * dx));
}
//Initialize(x[i] + xi[j]*(0.5 * dx)); //will allow a slop initial cond.
}
}
veccopy(u0,u,nu);
// Begin Time Marching (3 stage TVD RK)
auto* u_tmp = (double*)malloc(nu*sizeof(double));
for (int iter=0; iter<niter; iter++){
veccopy(u_tmp, u, nu);
//1st stage
CalcDudt(nx, ndegr, nvar, dx, u, Dmatrix, Dradau, dudt);
for (int i=0; i<nu; i++){
//u_tmp[i] += dt * dudt[i];
u[i] += dt * dudt[i];
if (isnan(u[i])){
throw overflow_error("Kaboom!\n");
}
}
//2nd stage
CalcDudt(nx, ndegr, nvar, dx, u_tmp, Dmatrix, Dradau, dudt);
for (int i=0; i<nu; i++){
u_tmp[i] = 0.75*u[i] + 0.25*( u_tmp[i] + dt*dudt[i]);
}
//3rd stage
CalcDudt(nx, ndegr, nvar, dx, u_tmp, Dmatrix, Dradau, dudt);
for (int i=0; i<nu; i++){
u[i] = (1.0/3.0)*u[i] + (2.0/3.0)*(u_tmp[i] + dt*dudt[i]);
}
if (iter % 100 == 0){printf("iter:%10d\t%7.2f%% Complete\n",iter, 100.0*(double)iter/(double)niter);}
}
printf("iter=%d\tdt=%f\n", niter, dt);
//Printout Final Solution
FILE* fout = fopen("waveout.tec", "w");
fprintf(fout, "x\tu\tu0\n");
for (int i=0;i<nx;i++) {
for (int j=0; j<max(ndegr,2); j++) {
double xj;
if (nvar == 1) {
if (ndegr == 1) {
double xii = -1.0 + 2.0 * j;
xj = x[i] + xii * (0.5 * dx);
fprintf(fout, "%f\t%f\n", xj, u[iu3(i, 0, 0, ndegr)]);
} else {
xj = x[i] + xi[j] * (0.5 * dx);
fprintf(fout, "%f\t%f\n", xj, u[iu3(i, j, 0, ndegr)]);
}
} else {
xj = x[i] + xi[j] * (0.5 * dx);
fprintf(fout, "%f\t%f\t%f\t%f\t", xj, u[iu3(i, j, 0, ndegr)], u[iu3(i, j, 1, ndegr)],
u[iu3(i, j, 2, ndegr)]);
double rho, v, p, c, M;
getPrimativesPN(GAM, &u[iu3(i, j, 0, ndegr)], &rho, &v, &p, &c, &M);
fprintf(fout, "%f\t%f\t%f\n", p, c, M);
}
}
}
fclose(fout);
free(xi);
free(u);
free(u0);
free(dudt);
free(Dmatrix);
free(Dradau);
}