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