-
Notifications
You must be signed in to change notification settings - Fork 0
/
oned_standing_wave.c
193 lines (170 loc) · 4.54 KB
/
oned_standing_wave.c
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
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// CPP Macros to control whether we truncate
// - initial conditions
// - time varying part
#define TRUNC_IC
#define TRUNC_VARYING
#define TRUNC_ON
// #undef TRUNC_ON
/* Helper macros */
#define HEX__(n) 0x##n##LU
#define B8__(x) ((x&0x0000000FLU)?1:0) \
+((x&0x000000F0LU)?2:0) \
+((x&0x00000F00LU)?4:0) \
+((x&0x0000F000LU)?8:0) \
+((x&0x000F0000LU)?16:0) \
+((x&0x00F00000LU)?32:0) \
+((x&0x0F000000LU)?64:0) \
+((x&0xF0000000LU)?128:0)
/* User macros */
#define B8(d) ((unsigned char)B8__(HEX__(d)))
#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \
+ B8(dlsb))
#define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \
+ ((unsigned long)B8(db2)<<16) \
+ ((unsigned long)B8(db3)<<8) \
+ B8(dlsb))
#define B64(dmsb,db2,db3,db4,db5,db6,db7,dlsb) ( \
((unsigned long)B8(dmsb)<<56) \
+ ((unsigned long)B8(db2)<<48) \
+ ((unsigned long)B8(db3)<<40) \
+ ((unsigned long)B8(db4)<<32) \
+ ((unsigned long)B8(db5)<<24) \
+ ((unsigned long)B8(db6)<<16) \
+ ((unsigned long)B8(db7)<<8) \
+ B8(dlsb) \
)
typedef union {
double f;
char fc[8];
} double_cast;
double bitTrunc(double var,int truncOff){
double_cast tmpVal;
tmpVal.f=var;
tmpVal.fc[0]=0;
tmpVal.fc[1]=0;
tmpVal.fc[2]=0;
tmpVal.fc[3]=0;
tmpVal.fc[4]=0;
tmpVal.fc[5]=0;
// tmpVal.fc[7]=0;
return tmpVal.f;
}
int main(int argc, char *argv[]){
int truncOff; // How far from end to truncate
int nread;
// Where to truncate from
truncOff = 0;
if ( argc > 1 ) {
nread=sscanf(argv[1],"%d",&truncOff);
if ( nread != 1 ) {
fprintf(stderr,"Usage: ./a.out truncOff\n");
exit(-1);
}
}
// Variables
// Problem size
int Nl=100;
int Nt=100;
int NtCycl=10; // Assumed to be integer when checking reference
// Index variables initial values
int jNM1orig;
int jNM1=0;
int jN=1;
int jNP1=2;
//
long unsigned const number = B64(00000000,
00000000,
00000000,
00000000,
00000000,
00000000,
00000001,
00000101);
printf("number %lu\n",number);
// Loop counters
int i, j;
// Scalars
double_cast dt2=(double_cast)pow((double)1.0/(double)Nt,(double)2);
double_cast dx2=(double_cast)pow((double)1.0/(double)Nl,(double)2);
double_cast c2=(double_cast)((double)1.0);
// Time steppig uVals array
double_cast uVals[3][Nl];
j=0;
double vTmp;
for (i=0;i<Nl;++i) {
vTmp=sin(2.*M_PI/((double)Nl)*(double)((double)i+0.5))*cos(2.*M_PI/(double)Nt*(double)(j));
#ifdef TRUNC_ON
vTmp=bitTrunc(vTmp,truncOff);
#endif
uVals[jNM1][i]=(double_cast)(vTmp);
}
j=1;
for (i=0;i<Nl;++i) {
vTmp=sin(2.*M_PI/((double)Nl)*(double)((double)i+0.5))*cos(2.*M_PI/(double)Nt*(double)(j));
#ifdef TRUNC_ON
vTmp=bitTrunc(vTmp,truncOff);
#endif
uVals[jN][i]=(double_cast)(vTmp);
}
printf("%le\n",M_PI);
for (i=0;i<Nl;++i) {
printf("%le\n",uVals[jN][i].f);
}
// Calculate reference solution (at end time)
// time runs fron 0 to dt*(Nt-1)
double uRef[Nl];
j=Nt-1;
for (i=0;i<Nl;++i) {
vTmp=sin(2.*M_PI/((double)Nl)*(double)((double)i+0.5))*cos(2.*M_PI/(double)Nt*(double)(j));
// vTmp=bitTrunc(vTmp,truncOff);
uRef[i]=(double)(vTmp);
}
// Calculate numerical solution
double_cast v1, v2;
int iM1, iP1;
for (j=2;j<Nt*NtCycl;++j) {
for (i=0;i<Nl;++i) {
iM1=i-1; if ( iM1 < 0 ) { iM1 = Nl-1; }
iP1=i+1; if ( iP1 == Nl ) { iP1 = 0; }
v1=(double_cast)(2.*uVals[jN][i].f-uVals[jNM1][i].f);
v2=(double_cast)(
dt2.f*c2.f*(
uVals[jN][iP1].f +
uVals[jN][iM1].f -
2.*uVals[jN][i].f
)/dx2.f
);
vTmp=v1.f+v2.f;
#ifdef TRUNC_ON
vTmp=bitTrunc(vTmp,truncOff);
#endif
uVals[jNP1][i].f=vTmp;
}
jNM1orig=jNM1;
jNM1=jN;
jN=jNP1;
jNP1=jNM1orig;
}
//calculate l1,l2 and infinity norm (Jenny)
double diff[Nl];
double l1, l2, infinity_norm;
for (i=0;i<Nl;++i) {
printf("%le %le %le\n",uVals[jN][i].f,uRef[i],uRef[i]-uVals[jN][i].f);
diff[i] = uRef[i]-uVals[jN][i].f;
}
l1 = 0.0;
l2 = 0.0;
infinity_norm = diff[0];
for (i=0;i<Nl;i++){
l1 = l1+fabs(diff[i]);
l2 = l2+pow(diff[i], 2);
if (fabs(diff[i])>infinity_norm){
infinity_norm = fabs(diff[i]);
}
}
l2 = pow(l2, 0.5);
printf("l1 =%le l2 =%le infinity_norm =%le\n", l1, l2, infinity_norm);
}