O P A R - Open Architecture Particle in Cell Simulation - Version 3.0
Plasma simulations with dust particles
Main Page
Related Pages
Modules
Classes
Files
File List
File Members
•
All
Classes
Files
Functions
Variables
Friends
Macros
Groups
Pages
numeric.h
Go to the documentation of this file.
1
5
#ifndef NUMERIC_H
6
#define NUMERIC_H
7
#include "
dimensionality.h
"
8
#include <fstream>
9
#include <cmath>
10
#include <cassert>
11
#include <valarray>
12
#include <iostream>
13
//---------------------------------------------------------------------------------------------------------------------
14
20
inline
double
frand
() {
return
rand()/double(RAND_MAX);}
21
inline
double
srand() {
// Give a random number of 1 or -1
22
double
dr;
23
double
fr =
frand
();
24
if
(fr < 0.5) dr = -1.0;
else
dr = 1.0;
25
return
dr;
26
}
27
template
<
typename
T>
28
inline
T sqr(T val) {
29
return
val*val;
30
}
31
template
<
typename
T>
32
inline
T max(T a, T b) {
33
return
a>b?a:b;
34
}
35
44
//---------------------------------------------------------------------------------------------------------------------
45
#ifndef ONE_DIMENSIONAL
46
template
<
class
T>
47
class
grid
{
48
protected
:
50
T *
G
;
52
GridPosition
size
;
53
int
gsize;
54
public
:
56
grid
() :
G
(0),
size
(
Position
(0)), gsize(0) { }
58
grid
(
GridPosition
size_) :
G
(0),
size
(size_), gsize((size_+UnitGrid).volume()) {newData();}
59
// Copy constructor
60
grid
(
const
grid
&agrid) :
G
(0),
size
(agrid.
size
), gsize(agrid.gsize) {
61
newData();
62
for
(
int
i=0; i<gsize; ++i)
G
[i] = agrid.
G
[i];
63
}
64
~
grid
() {
65
static
int
ic = 0;
66
static
int
im = 3;
67
ic += 1;
68
if
(ic==im) {
69
//std::cout << "Hier kommt jetzt der Destructor! " << ic << std::endl;
70
im += 1;
71
if
(
G
)
delete
[]
G
;
72
//std::cout << "Fertig!" << std::endl;
73
}
74
}
76
const
GridPosition
&
Size
()
const
{
return
size
;}
77
81
void
Resize
(
const
GridPosition
&asize) {
82
size
= asize;
83
gsize = (
size
+UnitGrid).volume();
84
newData();
85
}
86
91
const
grid
&
operator=
(
const
std::valarray<T> arr) {
92
assert (arr.size()==
G
.size());
93
for
(
int
i=0; i<gsize; ++i)
G
[i] = arr[i];
94
return
*
this
;
95
}
96
const
grid
&
operator=
(
const
T val) {
97
for
(
int
i=0; i<gsize; ++i)
G
[i] = val;
98
return
*
this
;
99
}
100
106
const
grid
&
operator+=
(
const
std::valarray<T> arr) {
107
assert (arr.size()==
G
.size());
108
for
(
int
i=0; i<gsize; ++i)
G
[i] += arr[i];
109
return
*
this
;
110
}
111
const
grid
&
operator+=
(
const
grid
& arr) {
112
assert (arr.
size
==
size
);
113
for
(
int
i=0; i<gsize; ++i)
G
[i] += arr.
G
[i];
114
return
*
this
;
115
}
116
const
grid
& operator-=(
const
std::valarray<T> arr) {
117
assert (arr.size()==
G
.size());
118
for
(
int
i=0; i<gsize; ++i)
G
[i] -= arr[i];
119
return
*
this
;
120
}
121
const
grid
& operator-=(
const
grid
& arr) {
122
assert (arr.
size
==
size
);
123
for
(
int
i=0; i<gsize; ++i)
G
[i] -= arr.
G
[i];
124
return
*
this
;
125
}
126
const
grid
& operator*=(
const
T val) {
127
for
(
int
i = 0; i < gsize; ++i)
G
[i] *= val;
128
return
*
this
;
129
}
130
const
grid
& operator/=(
const
T val) {
131
for
(
int
i=0; i<gsize; ++i)
G
[i] /= val;
132
return
*
this
;
133
}
134
//operator std::valarray<T>& () { // Get a reference of the valarray (dirty!)
135
// return G;
136
//}
137
T& operator[] (
const
GridPosition
&i) {
138
int
pos = i.
arraypos
(
size
);
139
//if ((pos >= gsize) || (pos < 0)) {
140
// std::cerr << i << " Index out of bounds (1)" << std::endl;
141
// exit(-1);
142
//}
143
return
G
[pos];
144
}
145
// Returns reference/value at grid position
146
T operator[] (
const
GridPosition
&i)
const
{
147
int
pos = i.
arraypos
(
size
);
148
//if ((pos>=gsize) || (pos<0)) {
149
// std::cerr << i << " Index out of bounds (2)" << std::endl;
150
// exit(-1);
151
//}
152
return
G
[pos];
153
}
154
// The linearly interpolated value at a position between the grid points
155
T operator() (
const
Position
&X)
const
{
156
GridPosition
p =
GridPosition
(X);
157
p.
limitto
(
size
- 1);
158
GridPosition
pp = p + 1;
159
Position
a =
Position
(pp) - X;
160
Position
b = X -
Position
(p);
161
return
WeightedSum
(*
this
,p,pp,a,b);
162
}
163
// Returns the derivative. Assumes that type T can be cast to a double
164
grid<Position>
derive(
Position
ddx);
165
// Sets the values in the grid with the use of a function that takes no arguments, eg frand()
166
void
apply(T fkt());
167
private
:
168
void
newData() {
169
if
(
G
)
delete
[]
G
;
170
G
=
new
T[gsize];
171
}
172
};
173
template
<
class
T>
174
void
grid<T>::apply
(T fkt()) {
175
for
(
int
i = 0; i < gsize; i++) {
176
T tmp = fkt();
177
G[i] = tmp;
178
}
179
}
180
#endif
181
//---------------------------------------------------------------------------------------------------------------------
182
#ifdef ONE_DIMENSIONAL
183
template
<
class
T>
184
class
grid
{
185
protected
:
187
std::valarray<T>
G
;
189
GridPosition
size
;
190
public
:
192
grid
() :
G
(),
size
(
Position
(0)) { }
194
grid
(
GridPosition
size_) :
G
(0.0, size_.volume()),
size
(size_) { }
196
grid
(
const
grid
&agrid) :
G
(agrid.
G
),
size
(agrid.
size
) { }
197
~
grid
() { }
199
const
GridPosition
&
Size
()
const
{
return
size
;}
200
204
void
Resize
(
const
GridPosition
&asize) {
205
size
= asize;
206
G
.resize((
size
+UnitGrid).volume());
207
}
208
213
const
grid
&
operator=
(
const
std::valarray<T> arr) {
214
assert (arr.size()==
G
.size());
215
G
= arr;
216
return
*
this
;
217
}
218
const
grid
&
operator=
(
const
T val) {
219
G
= val;
220
return
*
this
;
221
}
222
224
const
grid
&
operator+=
(
const
std::valarray<T> arr) {
225
assert (arr.size()==
G
.size());
226
G
+= arr;
227
return
*
this
;
228
}
229
const
grid
& operator-=(
const
std::valarray<T> arr) {
230
assert (arr.size()==
G
.size());
231
G
-= arr;
232
return
*
this
;
233
}
234
const
grid
& operator*=(
const
T val) {
235
G
*= val;
236
return
*
this
;
237
}
238
const
grid
& operator/=(
const
T val) {
239
G
/= val;
240
return
*
this
;
241
}
242
248
249
operator
std::valarray<T>& () {
// Get a reference of the valarray (dirty!)
250
return
G
;
251
}
252
254
T& operator[] (
const
GridPosition
&i) {
255
int
pos = i.
arraypos
(
size
);
256
return
G
[i.
arraypos
(pos)];
257
}
258
// Returns reference/value at grid position
259
T operator[] (
const
GridPosition
&i)
const
{
260
int
pos = i.
arraypos
(
size
);
261
return
G
[i.
arraypos
(pos)];
262
}
264
265
// The linearly interpolated value at a position between the grid
266
T operator() (
const
Position
&X)
const
{
267
GridPosition
p =
GridPosition
(X);
268
p.
limitto
(
size
- 1);
269
GridPosition
pp = p + 1;
270
Position
a =
Position
(pp) - X;
271
Position
b = X -
Position
(p);
272
return
WeightedSum
(*
this
,p,pp,a,b);
273
}
274
// Returns the derivative. Assumes that type T can be cast to a double
275
grid<Position>
derive(
Position
ddx);
276
// Sets the values in the grid with the use of a function that takes no arguments, eg frand()
277
void
apply(T fkt());
278
};
279
template
<
class
T>
280
void
grid<T>::apply
(T fkt()) {
281
for
(
int
i=0; i<G.size(); i++) {
282
T tmp = fkt();
283
G[i] = tmp;
284
}
285
}
286
template
<
class
T>
287
grid<Position>
grid<T>::derive
(
Position
ddx) {
288
int
i;
289
grid<Position>
D;
290
GridPosition
NG = Size();
291
D.
Resize
(NG);
292
ddx *= 2.0;
293
grid<T>
&G = *
this
;
294
// Derivative in the volume
295
#pragma omp parallel for private(i) default(shared)
296
for
(i=NG[0]-2; i>0; i--) D[i] = (G[i-1] - G[i+1]) / ddx[0];
297
// Derivative at the boundaries
298
D[0] = 2.0 * (G[0] - G[1]) / ddx[0];
// First cell
299
D[NG[0]-1] = 2.0 * (G[NG[0]-2] - G[NG[0]-1]) / ddx[0];
// Last cell
300
return
D;
301
}
302
314
void
TriMatrixSolver(std::valarray<double> &a, std::valarray<double> &b, std::valarray<double> &c, std::valarray<double> &r, std::valarray<double> &u,
int
nt);
315
template
<
class
T>
316
T
WeightedSum
(
const
grid<T>
&g,
GridPosition
p1,
GridPosition
p2,
const
Position
& wa,
const
Position
& wb) {
317
return
(g[p1]*wa.
P
[0] + g[p2]*wb.
P
[0]);
318
}
319
#endif
320
//---------------------------------------------------------------------------------------------------------------------
321
#ifdef TWO_DIMENSIONAL
322
template
<
class
T>
323
T
WeightedSum
(
const
grid<T>
&g,
GridPosition
p1,
GridPosition
p2,
const
Position
& wa,
const
Position
& wb) {
324
T sum = g[p1]*wa.
P
[0]*wa.
P
[1] + g[p2]*wb.
P
[0]*wb.
P
[1];
325
++p1.
P
[0];
326
--p2.
P
[0];
327
return
(sum + g[p1]*wb.
P
[0]*wa.
P
[1] + g[p2]*wa.
P
[0]*wb.
P
[1]);
328
}
329
#endif
330
//---------------------------------------------------------------------------------------------------------------------
331
#ifdef THREE_DIMENSIONAL
332
template
<
class
T>
333
T
WeightedSum
(
const
grid<T>
&g,
GridPosition
p1,
GridPosition
p2,
const
Position
& wa,
const
Position
& wb) {
334
T sum = g[p1]*wa.
P
[0]*wa.
P
[1]*wa.
P
[2] + g[p2]*wb.
P
[0]*wb.
P
[1]*wb.
P
[2];
335
++p1.
P
[0];
336
--p2.
P
[0];
337
sum += g[p1]*wb.
P
[0]*wa.
P
[1]*wa.
P
[2] + g[p2]*wa.
P
[0]*wb.
P
[1]*wb.
P
[2];
338
++p1.
P
[1];
339
--p2.
P
[1];
340
sum += g[p1]*wb.
P
[0]*wb.
P
[1]*wa.
P
[2] + g[p2]*wa.
P
[0]*wa.
P
[1]*wb.
P
[2];
341
--p1.
P
[0];
342
++p2.
P
[0];
343
return
sum + g[p1]*wa.
P
[0]*wb.
P
[1]*wa.
P
[2] + g[p2]*wb.
P
[0]*wa.
P
[1]*wb.
P
[2];
344
}
345
#endif
346
//---------------------------------------------------------------------------------------------------------------------
347
#endif
Generated by
1.8.1.1