-
Notifications
You must be signed in to change notification settings - Fork 0
/
divergence.cpp
138 lines (125 loc) · 3.45 KB
/
divergence.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
#include <iostream>
#include <fstream>
#include <sys/time.h>
#include "timer/timer.hpp"
#include "divergence.hpp"
template <int np, typename real>
void readVelocity(real v[np][np][2], std::istream *input) {
for(int i = 0; i < 2; i++) {
for(int j = 0; j < np; j++) {
for(int k = 0; k < np; k++) {
(*input) >> v[k][j][i];
}
}
}
}
template <int np, typename real>
void readElement(element<np, real> &elem,
std::istream *input) {
for(int i = 0; i < np; i++) {
for(int j = 0; j < np; j++) {
(*input) >> elem.metdet[i][j];
elem.rmetdet[i][j] = 1 / elem.metdet[i][j];
}
}
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 2; j++) {
for(int k = 0; k < np; k++) {
for(int l = 0; l < np; l++) {
(*input) >> elem.Dinv[l][k][i][j];
}
}
}
}
}
template <int np, typename real>
void readDerivative(derivative<np, real> &deriv,
std::istream *input) {
for(int i = 0; i < np; i++) {
for(int j = 0; j < np; j++) {
(*input) >> deriv.Dvv[j][i];
}
}
}
template <int np, typename real>
void readDivergence(real divergence[np][np],
std::istream *input) {
for(int i = 0; i < np; i++) {
for(int j = 0; j < np; j++) {
(*input) >> divergence[i][j];
}
}
}
constexpr const int DIMS = 2;
template <int np, typename real>
void compareDivergences(const real v[np][np][DIMS],
const element<np, real> &elem,
const derivative<np, real> &deriv,
const real divergence_e[np][np],
const int numtests) {
Timer::Timer time_c;
/* Initial run to prevent cache timing from affecting us
*/
real divergence_c[np][np];
for(int i = 0; i < numtests; i++) {
divergence_sphere<np, real>(v, deriv, elem,
divergence_c);
}
time_c.startTimer();
for(int i = 0; i < numtests; i++) {
divergence_sphere<np, real>(v, deriv, elem,
divergence_c);
}
time_c.stopTimer();
Timer::Timer time_f;
real divergence_f[np][np];
for(int i = 0; i < numtests; i++) {
divergence_sphere_fortran(v, deriv, elem, divergence_f);
}
time_f.startTimer();
for(int i = 0; i < numtests; i++) {
divergence_sphere_fortran(v, deriv, elem, divergence_f);
}
time_f.stopTimer();
std::cout << "Divergence Errors\n";
for(int i = 0; i < np; i++) {
for(int j = 0; j < np; j++) {
std::cout << divergence_c[i][j] - divergence_e[i][j]
<< " "
<< divergence_f[i][j] - divergence_e[i][j]
<< "\n";
}
std::cout << "\n";
}
std::cout << "C++ Time:\n" << time_c
<< "\n\nFortran Time:\n" << time_f << "\n";
}
int main(int argc, char **argv) {
using real = double;
constexpr const int NP = 4;
real v[NP][NP][DIMS];
element<NP, real> elem;
derivative<NP, real> deriv;
real divergence_e[NP][NP];
{
std::istream *input;
if(argc > 1) {
input = new std::ifstream(argv[1]);
} else {
input = &std::cin;
}
readVelocity(v, input);
readElement(elem, input);
readDerivative(deriv, input);
readDivergence(divergence_e, input);
if(argc > 1) {
delete input;
}
}
constexpr const int defNumTests = 1e5;
const int numtests =
(argc > 2) ? std::stoi(argv[2]) : defNumTests;
compareDivergences(v, elem, deriv, divergence_e,
numtests);
return 0;
}