8d4f0940
David Mayerich
ERROR in plane wa...
|
1
2
3
|
#ifndef RTS_EFIELD
#define RTS_EFIELD
|
a9275be5
David Mayerich
added vector fiel...
|
4
|
#include "../math/complex.h"
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
5
|
#include "../math/realfield.cuh"
|
a9275be5
David Mayerich
added vector fiel...
|
6
|
#include "../visualization/colormap.h"
|
a9275be5
David Mayerich
added vector fiel...
|
7
8
|
#include "../optics/planewave.h"
#include "../cuda/devices.h"
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
9
|
#include "../optics/beam.h"
|
ecfd14df
David Mayerich
implemented D fie...
|
10
|
#include "../math/rect.h"
|
a9275be5
David Mayerich
added vector fiel...
|
11
|
|
4d67ff4e
David Mayerich
started scalar fi...
|
12
|
|
8a86bd56
David Mayerich
changed rts names...
|
13
|
namespace stim{
|
4d67ff4e
David Mayerich
started scalar fi...
|
14
|
|
a9275be5
David Mayerich
added vector fiel...
|
15
16
|
template<typename T>
__global__ void gpu_planewave2efield(complex<T>* X, complex<T>* Y, complex<T>* Z, unsigned int r0, unsigned int r1,
|
d609550e
David Mayerich
fixed bug in plan...
|
17
|
planewave<T> w, rect<T> q)
|
a9275be5
David Mayerich
added vector fiel...
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
{
int iu = blockIdx.x * blockDim.x + threadIdx.x;
int iv = blockIdx.y * blockDim.y + threadIdx.y;
//make sure that the thread indices are in-bounds
if(iu >= r0 || iv >= r1) return;
//compute the index into the field
int i = iv*r0 + iu;
//get the current position
vec<T> p = q( (T)iu/(T)r0, (T)iv/(T)r1 );
vec<T> r(p[0], p[1], p[2]);
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
32
|
complex<T> x( 0.0f, w.k.dot(r) );
|
a9275be5
David Mayerich
added vector fiel...
|
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
|
if(Y == NULL) //if this is a scalar simulation
X[i] += w.E0.len() * exp(x); //use the vector magnitude as the plane wave amplitude
else
{
X[i] += w.E0[0] * exp(x);
Y[i] += w.E0[1] * exp(x);
Z[i] += w.E0[2] * exp(x);
}
}
template<typename T>
__global__ void gpu_efield_magnitude(complex<T>* X, complex<T>* Y, complex<T>* Z, unsigned int r0, unsigned int r1, T* M)
{
int iu = blockIdx.x * blockDim.x + threadIdx.x;
int iv = blockIdx.y * blockDim.y + threadIdx.y;
//make sure that the thread indices are in-bounds
if(iu >= r0 || iv >= r1) return;
//compute the index into the field
int i = iv*r0 + iu;
if(Y == NULL) //if this is a scalar simulation
M[i] = X[i].abs(); //compute the magnitude of the X component
else
{
M[i] = rts::vec<T>(X[i].abs(), Y[i].abs(), Z[i].abs()).len();
//M[i] = Z[i].abs();
}
}
template<typename T>
|
559d0fcb
David Mayerich
wave interactions...
|
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
__global__ void gpu_efield_real_magnitude(complex<T>* X, complex<T>* Y, complex<T>* Z, unsigned int r0, unsigned int r1, T* M)
{
int iu = blockIdx.x * blockDim.x + threadIdx.x;
int iv = blockIdx.y * blockDim.y + threadIdx.y;
//make sure that the thread indices are in-bounds
if(iu >= r0 || iv >= r1) return;
//compute the index into the field
int i = iv*r0 + iu;
if(Y == NULL) //if this is a scalar simulation
M[i] = X[i].abs(); //compute the magnitude of the X component
else
{
M[i] = rts::vec<T>(X[i].real(), Y[i].real(), Z[i].real()).len();
//M[i] = Z[i].abs();
}
}
template<typename T>
|
a9275be5
David Mayerich
added vector fiel...
|
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
__global__ void gpu_efield_polarization(complex<T>* X, complex<T>* Y, complex<T>* Z,
unsigned int r0, unsigned int r1,
T* Px, T* Py, T* Pz)
{
int iu = blockIdx.x * blockDim.x + threadIdx.x;
int iv = blockIdx.y * blockDim.y + threadIdx.y;
//make sure that the thread indices are in-bounds
if(iu >= r0 || iv >= r1) return;
//compute the index into the field
int i = iv*r0 + iu;
//compute the field polarization
Px[i] = X[i].abs();
Py[i] = Y[i].abs();
|
a9275be5
David Mayerich
added vector fiel...
|
103
|
Pz[i] = Z[i].abs();
|
ecfd14df
David Mayerich
implemented D fie...
|
104
|
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
105
106
107
108
109
110
111
112
113
|
}
/* This function computes the sum of two complex fields and stores the result in *dest
*/
template<typename T>
__global__ void gpu_efield_sum(complex<T>* dest, complex<T>* src, unsigned int r0, unsigned int r1)
{
int iu = blockIdx.x * blockDim.x + threadIdx.x;
int iv = blockIdx.y * blockDim.y + threadIdx.y;
|
a9275be5
David Mayerich
added vector fiel...
|
114
|
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
115
116
117
118
119
120
121
122
|
//make sure that the thread indices are in-bounds
if(iu >= r0 || iv >= r1) return;
//compute the index into the field
int i = iv*r0 + iu;
//sum the fields
dest[i] += src[i];
|
a9275be5
David Mayerich
added vector fiel...
|
123
124
|
}
|
4d67ff4e
David Mayerich
started scalar fi...
|
125
126
127
|
/* This class implements a discrete representation of an electromagnetic field
in 2D. The majority of this representation is done on the GPU.
*/
|
ecfd14df
David Mayerich
implemented D fie...
|
128
|
template<typename T>
|
4d67ff4e
David Mayerich
started scalar fi...
|
129
130
|
class efield
{
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
131
|
protected:
|
4d67ff4e
David Mayerich
started scalar fi...
|
132
|
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
133
|
bool vector;
|
4d67ff4e
David Mayerich
started scalar fi...
|
134
135
|
//gpu pointer to the field data
|
ecfd14df
David Mayerich
implemented D fie...
|
136
137
138
|
rts::complex<T>* X;
rts::complex<T>* Y;
rts::complex<T>* Z;
|
4d67ff4e
David Mayerich
started scalar fi...
|
139
140
141
142
|
//resolution of the discrete field
unsigned int R[2];
|
a9275be5
David Mayerich
added vector fiel...
|
143
|
//shape of the 2D field
|
ecfd14df
David Mayerich
implemented D fie...
|
144
|
rect<T> pos;
|
a9275be5
David Mayerich
added vector fiel...
|
145
|
|
ecfd14df
David Mayerich
implemented D fie...
|
146
|
void from_planewave(planewave<T> p)
|
a9275be5
David Mayerich
added vector fiel...
|
147
148
149
150
151
|
{
unsigned int SQRT_BLOCK = 16;
//create one thread for each detector pixel
dim3 dimBlock(SQRT_BLOCK, SQRT_BLOCK);
dim3 dimGrid((R[0] + SQRT_BLOCK -1)/SQRT_BLOCK, (R[1] + SQRT_BLOCK - 1)/SQRT_BLOCK);
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
152
|
|
a9275be5
David Mayerich
added vector fiel...
|
153
|
|
ecfd14df
David Mayerich
implemented D fie...
|
154
|
gpu_planewave2efield<T> <<<dimGrid, dimBlock>>> (X, Y, Z, R[0], R[1], p, pos);
|
a9275be5
David Mayerich
added vector fiel...
|
155
156
|
}
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
157
|
void init(unsigned int res0, unsigned int res1, bool _vector)
|
4d67ff4e
David Mayerich
started scalar fi...
|
158
|
{
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
159
|
vector = _vector; //initialize field type
|
a9275be5
David Mayerich
added vector fiel...
|
160
161
|
X = Y = Z = NULL; //initialize all pointers to NULL
|
4d67ff4e
David Mayerich
started scalar fi...
|
162
163
164
165
|
R[0] = res0;
R[1] = res1;
//allocate memory on the gpu
|
ecfd14df
David Mayerich
implemented D fie...
|
166
167
|
cudaMalloc(&X, sizeof(rts::complex<T>) * R[0] * R[1]);
cudaMemset(X, 0, sizeof(rts::complex<T>) * R[0] * R[1]);
|
4d67ff4e
David Mayerich
started scalar fi...
|
168
|
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
169
|
if(vector)
|
4d67ff4e
David Mayerich
started scalar fi...
|
170
|
{
|
ecfd14df
David Mayerich
implemented D fie...
|
171
172
|
cudaMalloc(&Y, sizeof(rts::complex<T>) * R[0] * R[1]);
cudaMemset(Y, 0, sizeof(rts::complex<T>) * R[0] * R[1]);
|
a9275be5
David Mayerich
added vector fiel...
|
173
|
|
ecfd14df
David Mayerich
implemented D fie...
|
174
175
|
cudaMalloc(&Z, sizeof(rts::complex<T>) * R[0] * R[1]);
cudaMemset(Z, 0, sizeof(rts::complex<T>) * R[0] * R[1]);
|
4d67ff4e
David Mayerich
started scalar fi...
|
176
177
178
|
}
}
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
179
180
181
182
183
184
185
|
void destroy()
{
if(X != NULL) cudaFree(X);
if(Y != NULL) cudaFree(Y);
if(Z != NULL) cudaFree(Z);
}
|
ecfd14df
David Mayerich
implemented D fie...
|
186
|
void shallowcpy(const rts::efield<T> & src)
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
187
188
189
190
191
192
|
{
vector = src.vector;
R[0] = src.R[0];
R[1] = src.R[1];
}
|
ecfd14df
David Mayerich
implemented D fie...
|
193
|
void deepcpy(const rts::efield<T> & src)
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
194
195
196
197
198
199
200
|
{
//perform a shallow copy
shallowcpy(src);
//allocate memory on the gpu
if(src.X != NULL)
{
|
ecfd14df
David Mayerich
implemented D fie...
|
201
202
|
cudaMalloc(&X, sizeof(rts::complex<T>) * R[0] * R[1]);
cudaMemcpy(X, src.X, sizeof(rts::complex<T>) * R[0] * R[1], cudaMemcpyDeviceToDevice);
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
203
204
205
|
}
if(src.Y != NULL)
{
|
ecfd14df
David Mayerich
implemented D fie...
|
206
207
|
cudaMalloc(&Y, sizeof(rts::complex<T>) * R[0] * R[1]);
cudaMemcpy(Y, src.Y, sizeof(rts::complex<T>) * R[0] * R[1], cudaMemcpyDeviceToDevice);
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
208
209
210
|
}
if(src.Z != NULL)
{
|
ecfd14df
David Mayerich
implemented D fie...
|
211
212
|
cudaMalloc(&Z, sizeof(rts::complex<T>) * R[0] * R[1]);
cudaMemcpy(Z, src.Z, sizeof(rts::complex<T>) * R[0] * R[1], cudaMemcpyDeviceToDevice);
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
213
214
215
216
217
218
219
|
}
}
public:
efield(unsigned int res0, unsigned int res1, bool _vector = true)
{
init(res0, res1, _vector);
|
ecfd14df
David Mayerich
implemented D fie...
|
220
|
//pos = rts::rect<T>(rts::vec<T>(-10, 0, -10), rts::vec<T>(-10, 0, 10), rts::vec<T>(10, 0, 10));
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
221
222
|
}
|
4d67ff4e
David Mayerich
started scalar fi...
|
223
224
225
|
//destructor
~efield()
{
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
226
227
228
229
230
231
|
destroy();
}
///Clear the field - set all points to zero
void clear()
{
|
ecfd14df
David Mayerich
implemented D fie...
|
232
|
cudaMemset(X, 0, sizeof(rts::complex<T>) * R[0] * R[1]);
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
233
234
235
|
if(vector)
{
|
ecfd14df
David Mayerich
implemented D fie...
|
236
237
|
cudaMemset(Y, 0, sizeof(rts::complex<T>) * R[0] * R[1]);
cudaMemset(Z, 0, sizeof(rts::complex<T>) * R[0] * R[1]);
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
238
|
}
|
4d67ff4e
David Mayerich
started scalar fi...
|
239
240
|
}
|
ecfd14df
David Mayerich
implemented D fie...
|
241
|
void position(rect<T> _p)
|
a9275be5
David Mayerich
added vector fiel...
|
242
243
244
245
|
{
pos = _p;
}
|
ecfd14df
David Mayerich
implemented D fie...
|
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
//access functions
complex<T>* x(){
return X;
}
complex<T>* y(){
return Y;
}
complex<T>* z(){
return Z;
}
unsigned int Ru(){
return R[0];
}
unsigned int Rv(){
return R[1];
}
rect<T> p(){
return pos;
}
|
a9275be5
David Mayerich
added vector fiel...
|
266
267
268
269
270
271
272
273
274
275
276
|
std::string str()
{
stringstream ss;
ss<<pos<<std::endl;
ss<<"X: "<<X<<std::endl;
ss<<"Y: "<<Y<<std::endl;
ss<<"Z: "<<Z;
return ss.str();
}
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
277
|
//assignment operator: assignment from another electric field
|
ecfd14df
David Mayerich
implemented D fie...
|
278
|
efield<T> & operator= (const efield<T> & rhs)
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
279
280
281
282
283
284
|
{
destroy(); //destroy any previous information about this field
deepcpy(rhs); //create a deep copy
return *this; //return the current object
}
|
a9275be5
David Mayerich
added vector fiel...
|
285
|
//assignment operator: build an electric field from a plane wave
|
ecfd14df
David Mayerich
implemented D fie...
|
286
|
efield<T> & operator= (const planewave<T> & rhs)
|
a9275be5
David Mayerich
added vector fiel...
|
287
288
289
290
|
{
clear(); //clear any previous field data
from_planewave(rhs); //create a field from the planewave
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
291
|
return *this; //return the current object
|
a9275be5
David Mayerich
added vector fiel...
|
292
293
|
}
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
294
|
//assignment operator: add an existing electric field
|
ecfd14df
David Mayerich
implemented D fie...
|
295
|
efield<T> & operator+= (const efield<T> & rhs)
|
a9275be5
David Mayerich
added vector fiel...
|
296
|
{
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
|
//if this field and the source field represent the same regions in space
if(R[0] == rhs.R[0] && R[1] == rhs.R[1] && pos == rhs.pos)
{
int maxThreads = rts::maxThreadsPerBlock(); //compute the optimal block size
int SQRT_BLOCK = (int)std::sqrt((float)maxThreads);
//create one thread for each detector pixel
dim3 dimBlock(SQRT_BLOCK, SQRT_BLOCK);
dim3 dimGrid((R[0] + SQRT_BLOCK -1)/SQRT_BLOCK, (R[1] + SQRT_BLOCK - 1)/SQRT_BLOCK);
//sum the fields
gpu_efield_sum <<<dimGrid, dimBlock>>> (X, rhs.X, R[0], R[1]);
if(Y != NULL)
{
gpu_efield_sum <<<dimGrid, dimBlock>>> (Y, rhs.Y, R[0], R[1]);
gpu_efield_sum <<<dimGrid, dimBlock>>> (Z, rhs.Z, R[0], R[1]);
}
}
else
{
std::cout<<"ERROR in efield: The two summed fields do not represent the same geometry."<<std::endl;
exit(1);
}
|
a9275be5
David Mayerich
added vector fiel...
|
320
|
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
321
|
return *this; //return this object
|
a9275be5
David Mayerich
added vector fiel...
|
322
323
|
}
|
559d0fcb
David Mayerich
wave interactions...
|
324
|
//assignment operator: build an electric field from a beam
|
ecfd14df
David Mayerich
implemented D fie...
|
325
|
efield<T> & operator= (const rts::beam<T> & rhs)
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
326
327
|
{
//get a vector of monte-carlo samples
|
ecfd14df
David Mayerich
implemented D fie...
|
328
|
std::vector< rts::planewave<T> > p_list = rhs.mc();
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
329
330
331
332
333
334
335
|
clear(); //clear any previous field data
for(unsigned int i = 0; i < p_list.size(); i++)
from_planewave(p_list[i]);
return *this;
}
|
a9275be5
David Mayerich
added vector fiel...
|
336
337
|
//return a scalar field representing field magnitude
|
ecfd14df
David Mayerich
implemented D fie...
|
338
|
realfield<T, 1, true> mag()
|
4d67ff4e
David Mayerich
started scalar fi...
|
339
|
{
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
340
341
|
int maxThreads = rts::maxThreadsPerBlock(); //compute the optimal block size
int SQRT_BLOCK = (int)std::sqrt((float)maxThreads);
|
4d67ff4e
David Mayerich
started scalar fi...
|
342
|
|
a9275be5
David Mayerich
added vector fiel...
|
343
|
//create a scalar field to store the result
|
ecfd14df
David Mayerich
implemented D fie...
|
344
|
realfield<T, 1, true> M(R[0], R[1]);
|
a9275be5
David Mayerich
added vector fiel...
|
345
|
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
346
347
348
|
//create one thread for each detector pixel
dim3 dimBlock(SQRT_BLOCK, SQRT_BLOCK);
dim3 dimGrid((R[0] + SQRT_BLOCK -1)/SQRT_BLOCK, (R[1] + SQRT_BLOCK - 1)/SQRT_BLOCK);
|
a9275be5
David Mayerich
added vector fiel...
|
349
|
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
350
351
|
//compute the magnitude and store it in a scalar field
gpu_efield_magnitude<float> <<<dimGrid, dimBlock>>> (X, Y, Z, R[0], R[1], M.ptr(0));
|
a9275be5
David Mayerich
added vector fiel...
|
352
353
|
return M;
|
4d67ff4e
David Mayerich
started scalar fi...
|
354
355
|
}
|
559d0fcb
David Mayerich
wave interactions...
|
356
|
//return a sacalar field representing the field magnitude at an infinitely small point in time
|
ecfd14df
David Mayerich
implemented D fie...
|
357
|
realfield<T, 1, true> real_mag()
|
559d0fcb
David Mayerich
wave interactions...
|
358
359
360
361
362
|
{
int maxThreads = rts::maxThreadsPerBlock(); //compute the optimal block size
int SQRT_BLOCK = (int)std::sqrt((float)maxThreads);
//create a scalar field to store the result
|
ecfd14df
David Mayerich
implemented D fie...
|
363
|
realfield<T, 1, true> M(R[0], R[1]);
|
559d0fcb
David Mayerich
wave interactions...
|
364
365
366
367
368
369
370
371
372
373
374
|
//create one thread for each detector pixel
dim3 dimBlock(SQRT_BLOCK, SQRT_BLOCK);
dim3 dimGrid((R[0] + SQRT_BLOCK -1)/SQRT_BLOCK, (R[1] + SQRT_BLOCK - 1)/SQRT_BLOCK);
//compute the magnitude and store it in a scalar field
gpu_efield_real_magnitude<float> <<<dimGrid, dimBlock>>> (X, Y, Z, R[0], R[1], M.ptr(0));
return M;
}
|
a9275be5
David Mayerich
added vector fiel...
|
375
|
//return a vector field representing field polarization
|
ecfd14df
David Mayerich
implemented D fie...
|
376
|
realfield<T, 3, true> polarization()
|
a9275be5
David Mayerich
added vector fiel...
|
377
|
{
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
378
|
if(!vector)
|
a9275be5
David Mayerich
added vector fiel...
|
379
380
381
382
383
384
385
386
387
388
389
390
|
{
std::cout<<"ERROR: Cannot compute polarization of a scalar field."<<std::endl;
exit(1);
}
int maxThreads = rts::maxThreadsPerBlock(); //compute the optimal block size
int SQRT_BLOCK = (int)std::sqrt((float)maxThreads);
//create one thread for each detector pixel
dim3 dimBlock(SQRT_BLOCK, SQRT_BLOCK);
dim3 dimGrid((R[0] + SQRT_BLOCK -1)/SQRT_BLOCK, (R[1] + SQRT_BLOCK - 1)/SQRT_BLOCK);
|
ecfd14df
David Mayerich
implemented D fie...
|
391
|
realfield<T, 3, true> Pol(R[0], R[1]); //create a vector field to store the result
|
a9275be5
David Mayerich
added vector fiel...
|
392
393
|
//compute the polarization and store it in the vector field
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
394
|
gpu_efield_polarization<float> <<<dimGrid, dimBlock>>> (X, Y, Z, R[0], R[1], Pol.ptr(0), Pol.ptr(1), Pol.ptr(2));
|
a9275be5
David Mayerich
added vector fiel...
|
395
396
397
398
|
return Pol; //return the vector field
}
|
559d0fcb
David Mayerich
wave interactions...
|
399
|
////////FRIENDSHIP
|
ecfd14df
David Mayerich
implemented D fie...
|
400
|
//friend void operator<< <T>(rts::efield<T> &ef, rts::halfspace<T> hs);
|
a9275be5
David Mayerich
added vector fiel...
|
401
|
|
4d67ff4e
David Mayerich
started scalar fi...
|
402
403
404
405
406
|
};
|
8d4f0940
David Mayerich
ERROR in plane wa...
|
407
408
|
} //end namespace rts
|
8a86bd56
David Mayerich
changed rts names...
|
409
|
#endif
|