9 #define M_PI 3.14159265358979323846
34 template<
typename T,
typename U,
typename V>
51 template<
typename T,
typename U,
typename V>
64 T
pdfGauss(std::vector<T> vars, std::vector<T> scales);
87 template<
typename T,
typename U,
typename V,
typename W,
typename G>
88 void initGauss(T gdict, U refldict, V *res_field, V *res_current);
115 template<
typename T,
typename U,
typename V,
typename W,
typename G>
116 void initGaussBeam(T gdict, U refldict, V *res_field, V *res_current);
136 template<
typename T,
typename U,
typename V,
typename W,
typename G>
156 template<
typename T,
typename U,
typename V,
typename W>
157 void calcJM(T *res_field, T *res_current, V refldict,
int mode);
159 template<
typename T,
typename U,
typename V>
162 std::array<V, 3> nomChief = {0, 0, 1};
163 std::array<V, 3> zero = {0, 0, 0};
167 int nTot = 1 + rdict.nRing * 4 * rdict.nRays;
174 if (rdict.nRays > 0) {d_alpha = 2 * M_PI / (4 * rdict.nRays);}
178 std::array<V, 3> rotation;
179 std::array<V, 3> direction;
189 std::array<V, 3> pos;
191 for (
int i=1; i<nTot; i++)
193 fr->x[i] = rdict.x0 * cos(alpha) / rdict.nRing * n;
194 fr->y[i] = rdict.y0 * sin(alpha) / rdict.nRing * n;
197 rotation[0] = rdict.angy0 * sin(alpha) / rdict.nRing * n;
198 rotation[1] = rdict.angx0 * cos(alpha) / rdict.nRing * n;
199 rotation[2] = 2 * alpha;
201 ut.
matRot(rotation, nomChief, zero, direction);
203 fr->dx[i] = direction[0];
204 fr->dy[i] = direction[1];
205 fr->dz[i] = direction[2];
208 if (i ==
int(nTot / rdict.nRing) * n)
216 template<
typename T,
typename U,
typename V>
220 std::array<V, 3> nomChief = {0, 0, 1};
221 std::array<V, 3> zero = {0, 0, 0};
225 if (grdict.seed != -1) {
Random<V> rando(grdict.seed);}
227 fr->size = grdict.nRays;
229 std::array<V, 3> rotation;
230 std::array<V, 3> direction;
231 std::array<V, 3> pos;
234 std::vector<V> scales{grdict.x0, grdict.y0, grdict.angx0, grdict.angy0};
247 std::vector<V> xi(4, 0);
250 while (n_suc < grdict.nRays)
258 for (
int k = 0; k<4; k++) {xi[k] = xi[k] * thres * scales[k];}
259 if (pdfGauss<V>(xi, scales) > yi)
262 rotation = {xi[3], xi[2], 0};
263 ut.
matRot(rotation, nomChief, zero, direction);
264 pos = {xi[0], xi[1], 0};
266 fr->x[n_suc] = pos[0];
267 fr->y[n_suc] = pos[1];
268 fr->z[n_suc] = pos[2];
270 fr->dx[n_suc] = direction[0];
271 fr->dy[n_suc] = direction[1];
272 fr->dz[n_suc] = direction[2];
279 T
pdfGauss(std::vector<T> vars, std::vector<T> scales)
281 T norm = 1 / (M_PI*M_PI * scales[0] * scales[1] * scales[2] * scales[3]);
283 return norm * exp(-vars[0]*vars[0] / (scales[0]*scales[0])) * exp(-vars[1]*vars[1] / (scales[1]*scales[1])) *
284 exp(-vars[2]*vars[2] / (scales[2]*scales[2])) * exp(-vars[3]*vars[3] / (scales[3]*scales[3]));
288 template<
typename T,
typename U,
typename V,
typename W,
typename G>
289 void initGauss(T gdict, U refldict, V *res_field, V *res_current)
291 int nTot = refldict.n_cells[0] * refldict.n_cells[1];
297 reflc.x =
new G[nTot];
298 reflc.y =
new G[nTot];
299 reflc.z =
new G[nTot];
301 reflc.nx =
new G[nTot];
302 reflc.ny =
new G[nTot];
303 reflc.nz =
new G[nTot];
305 reflc.area =
new G[nTot];
309 bool transform =
true;
312 G zRx = M_PI * gdict.w0x*gdict.w0x * gdict.n / gdict.lam;
313 G zRy = M_PI * gdict.w0y*gdict.w0y * gdict.n / gdict.lam;
314 G k = 2 * M_PI / gdict.lam;
323 std::complex<G> j(0, 1);
325 std::complex<G> field_atPoint;
326 std::array<std::complex<G>, 3> efield;
327 std::array<G, 3> n_source;
328 std::array<std::complex<G>, 3> m;
330 for (
int i=0; i<nTot; i++)
332 wzx = gdict.w0x * sqrt(1 + (reflc.z[i] / zRx)*(reflc.z[i] / zRx));
333 wzy = gdict.w0y * sqrt(1 + ((reflc.z[i] - gdict.dxyz) / zRy)*((reflc.z[i] - gdict.dxyz) / zRy));
334 Rzx_inv = reflc.z[i] / (reflc.z[i]*reflc.z[i] + zRx*zRx);
335 Rzy_inv = (reflc.z[i] - gdict.dxyz) / ((reflc.z[i] - gdict.dxyz)*(reflc.z[i] - gdict.dxyz) + zRy*zRy);
336 phizx = atan(reflc.z[i] / zRx);
337 phizy = atan((reflc.z[i] - gdict.dxyz) / zRy);
342 field_atPoint = gdict.E0 * exp(-(reflc.x[i]/wzx)*(reflc.x[i]/wzx) - (reflc.y[i]/wzy)*(reflc.y[i]/wzy) -
343 j*M_PI/gdict.lam * (reflc.x[i]*reflc.x[i]*Rzx_inv + reflc.y[i]*reflc.y[i]*Rzy_inv) - j*k*reflc.z[i] + j*(phizx - phizy)*0.5);
345 efield[0] = field_atPoint * gdict.pol[0];
346 efield[1] = field_atPoint * gdict.pol[1];
347 efield[2] = field_atPoint * gdict.pol[2];
349 n_source[0] = reflc.nx[i];
350 n_source[1] = reflc.ny[i];
351 n_source[2] = reflc.nz[i];
353 ut.
ext(n_source, efield, m);
355 res_field->r1x[i] = efield[0].real();
356 res_field->i1x[i] = efield[0].imag();
358 res_field->r1y[i] = efield[1].real();
359 res_field->i1y[i] = efield[1].imag();
361 res_field->r1z[i] = efield[2].real();
362 res_field->i1z[i] = efield[2].imag();
365 res_field->r2x[i] = 0;
366 res_field->i2x[i] = 0;
368 res_field->r2y[i] = 0;
369 res_field->i2y[i] = 0;
371 res_field->r2z[i] = 0;
372 res_field->i2z[i] = 0;
375 res_current->r1x[i] = 0;
376 res_current->i1x[i] = 0;
378 res_current->r1y[i] = 0;
379 res_current->i1y[i] = 0;
381 res_current->r1z[i] = 0;
382 res_current->i1z[i] = 0;
385 res_current->r2x[i] = -2*m[0].real();
386 res_current->i2x[i] = -2*m[0].imag();
388 res_current->r2y[i] = -2*m[1].real();
389 res_current->i2y[i] = -2*m[1].imag();
391 res_current->r2z[i] = -2*m[2].real();
392 res_current->i2z[i] = -2*m[2].imag();
407 template<
typename T,
typename U,
typename V,
typename W,
typename G>
410 int nTot = refldict.n_cells[0] * refldict.n_cells[1];
417 reflc.x =
new G[nTot];
418 reflc.y =
new G[nTot];
419 reflc.z =
new G[nTot];
421 reflc.nx =
new G[nTot];
422 reflc.ny =
new G[nTot];
423 reflc.nz =
new G[nTot];
425 reflc.area =
new G[nTot];
427 bool transform =
true;
436 G k = 2* M_PI / gdict.lam;
438 G zc = k*gdict.w0*gdict.w0/2.0;
443 std::array<std::complex <G>, 3> R;
445 std::complex <G> rsq;
448 std::complex <G> expo;
449 G prefactor = gdict.w0*k * sqrt(gdict.power / (8*M_PI));
451 std::complex <G> kr_inv;
452 std::complex <G> kr_sum_1;
453 std::complex <G> kr_sum_2;
454 std::complex <G> kr_sum_3;
456 std::complex<G> j(0, 1);
459 std::array<std::complex<G>, 3> efield;
460 std::array<std::complex<G>, 3> hfield;
463 std::array<G, 3> n_source;
464 std::array<std::complex<G>, 3> J;
465 std::array<std::complex<G>, 3> M;
468 for (
int i=0; i<nTot; i++)
471 R[0] = std::complex<G>(reflc.x[i], 0.0);
472 R[1] = std::complex<G>(reflc.y[i], 0.0);
473 R[2] = reflc.z[i] + gdict.z + j*zc;
475 r = sqrt(R[0]*R[0] + R[1]*R[1] + R[2]*R[2]);
478 expo = exp(-j*k*r - k*k*gdict.w0*gdict.w0/2.0);
483 kr_sum_1 = (-j*kr_inv - kr_inv*kr_inv + j*kr_inv*kr_inv*kr_inv);
484 kr_sum_2 = (j*kr_inv + 3.0*kr_inv*kr_inv - 3.0*j*kr_inv*kr_inv*kr_inv);
485 kr_sum_3 = (j*kr_inv + kr_inv*kr_inv);
488 efield[0] = prefactor*expo*(kr_sum_1 + kr_sum_2*(R[0]*R[0] / (r*r)) - kr_sum_3*(R[2] / r));
489 efield[1] = prefactor*expo*kr_sum_2*R[0]*R[1]/(r*r);
490 efield[2] = prefactor*expo*(kr_sum_2*R[0]*R[2]/(r*r) - kr_sum_3*R[0]/r);
492 hfield[0] = prefactor*expo*kr_sum_2*R[0]*R[1]/(r*r);
493 hfield[1] = prefactor*expo*(kr_sum_1 + kr_sum_2*(R[1]*R[1] / (r*r)) - kr_sum_3*(R[2] / r));
494 hfield[2] = prefactor*expo*(kr_sum_2*R[1]*R[2]/(r*r) - kr_sum_3*R[1]/r);
497 n_source[0] = reflc.nx[i];
498 n_source[1] = reflc.ny[i];
499 n_source[2] = reflc.nz[i];
501 ut.
ext(n_source, efield, M);
502 ut.
ext(n_source, hfield, J);
506 res_field->r1x[i] = efield[0].real();
507 res_field->i1x[i] = efield[0].imag();
509 res_field->r1y[i] = efield[1].real();
510 res_field->i1y[i] = efield[1].imag();
512 res_field->r1z[i] = efield[2].real();
513 res_field->i1z[i] = efield[2].imag();
516 res_field->r2x[i] = hfield[0].real();
517 res_field->i2x[i] = hfield[0].imag();
519 res_field->r2y[i] = hfield[1].real();
520 res_field->i2y[i] = hfield[1].imag();
522 res_field->r2z[i] = hfield[2].real();
523 res_field->i2z[i] = hfield[2].imag();
526 if ((gdict.mode == 0) or (gdict.mode == 2))
533 if ((gdict.mode == 0) or (gdict.mode == 2))
535 res_current->r1x[i] = Factor*J[0].real();
536 res_current->i1x[i] = Factor*J[0].imag();
538 res_current->r1y[i] = Factor*J[1].real();
539 res_current->i1y[i] = Factor*J[1].imag();
541 res_current->r1z[i] = Factor*J[2].real();
542 res_current->i1z[i] = Factor*J[2].imag();
544 res_current->r1x[i] = 0.0;
545 res_current->i1x[i] = 0.0;
547 res_current->r1y[i] = 0.0;
548 res_current->i1y[i] = 0.0;
550 res_current->r1z[i] = 0.0;
551 res_current->i1z[i] = 0.0;
555 if ((gdict.mode == 0) or (gdict.mode == 1))
557 res_current->r2x[i] = -Factor*M[0].real();
558 res_current->i2x[i] = -Factor*M[0].imag();
560 res_current->r2y[i] = -Factor*M[1].real();
561 res_current->i2y[i] = -Factor*M[1].imag();
563 res_current->r2z[i] = -Factor*M[2].real();
564 res_current->i2z[i] = -Factor*M[2].imag();
566 res_current->r2x[i] = 0.0;
567 res_current->i2x[i] = 0.0;
569 res_current->r2y[i] = 0.0;
570 res_current->i2y[i] = 0.0;
572 res_current->r2z[i] = 0.0;
573 res_current->i2z[i] = 0.0;
589 template<
typename T,
typename U,
typename V,
typename W,
typename G>
592 int nTot = refldict.n_cells[0] * refldict.n_cells[1];
596 reflc.x =
new G[nTot];
597 reflc.y =
new G[nTot];
598 reflc.z =
new G[nTot];
600 reflc.nx =
new G[nTot];
601 reflc.ny =
new G[nTot];
602 reflc.nz =
new G[nTot];
604 reflc.area =
new G[nTot];
607 bool transform =
true;
610 G zRx = M_PI * sgdict.w0x*sgdict.w0x * sgdict.n / sgdict.lam;
611 G zRy = M_PI * sgdict.w0y*sgdict.w0y * sgdict.n / sgdict.lam;
612 G k = 2 * M_PI / sgdict.lam;
620 std::complex<G> j(0, 1);
622 std::complex<G> efield;
624 for (
int i=0; i<nTot; i++)
626 wzx = sgdict.w0x * sqrt(1 + (reflc.z[i] / zRx)*(reflc.z[i] / zRx));
627 wzy = sgdict.w0y * sqrt(1 + ((reflc.z[i] - sgdict.dxyz) / zRy)*((reflc.z[i] - sgdict.dxyz) / zRy));
628 Rzx_inv = reflc.z[i] / (reflc.z[i]*reflc.z[i] + zRx*zRx);
629 Rzy_inv = (reflc.z[i] - sgdict.dxyz) / ((reflc.z[i] - sgdict.dxyz)*(reflc.z[i] - sgdict.dxyz) + zRy*zRy);
630 phizx = atan(reflc.z[i] / zRx);
631 phizy = atan((reflc.z[i] - sgdict.dxyz) / zRy);
633 efield = sgdict.E0 * sqrt(2 / (M_PI * wzx * wzy)) * exp(-(reflc.x[i]/wzx)*(reflc.x[i]/wzx) - (reflc.y[i]/wzy)*(reflc.y[i]/wzy) -
634 j*M_PI/sgdict.lam * (reflc.x[i]*reflc.x[i]*Rzx_inv + reflc.y[i]*reflc.y[i]*Rzy_inv) - j*k*reflc.z[i] + j*(phizx - phizy)*0.5);
636 res_field->x[i] = efield.real();
637 res_field->y[i] = efield.imag();
651 template<
typename T,
typename U,
typename V,
typename W>
652 void calcJM(T *res_field, T *res_current, V refldict,
int mode)
655 int nTot = refldict.n_cells[0] * refldict.n_cells[1];
659 reflc.x =
new U[nTot];
660 reflc.y =
new U[nTot];
661 reflc.z =
new U[nTot];
663 reflc.nx =
new U[nTot];
664 reflc.ny =
new U[nTot];
665 reflc.nz =
new U[nTot];
667 reflc.area =
new U[nTot];
669 bool transform =
true;
674 std::array<std::complex<U>, 3> field;
675 std::array<U, 3> n_source;
677 std::array<std::complex<U>, 3> js;
678 std::array<std::complex<U>, 3> ms;
683 for (
int i=0; i<nTot; i++)
685 field[0] = {res_field->r1x[i], res_field->i1x[i]};
686 field[1] = {res_field->r1y[i], res_field->i1y[i]};
687 field[2] = {res_field->r1z[i], res_field->i1z[i]};
689 n_source[0] = reflc.nx[i];
690 n_source[1] = reflc.ny[i];
691 n_source[2] = reflc.nz[i];
693 ut.
ext(n_source, field, ms);
695 res_current->r2x[i] = -ms[0].real();
696 res_current->i2x[i] = -ms[0].imag();
698 res_current->r2y[i] = -ms[1].real();
699 res_current->i2y[i] = -ms[1].imag();
701 res_current->r2z[i] = -ms[2].real();
702 res_current->i2z[i] = -ms[2].imag();
704 field[0] = {res_field->r2x[i], res_field->i2x[i]};
705 field[1] = {res_field->r2y[i], res_field->i2y[i]};
706 field[2] = {res_field->r2z[i], res_field->i2z[i]};
708 ut.
ext(n_source, field, js);
710 res_current->r1x[i] = js[0].real();
711 res_current->i1x[i] = js[0].imag();
713 res_current->r1y[i] = js[1].real();
714 res_current->i1y[i] = js[1].imag();
716 res_current->r1z[i] = js[2].real();
717 res_current->i1z[i] = js[2].imag();
724 for (
int i=0; i<nTot; i++)
726 field[0] = {res_field->r1x[i], res_field->i1x[i]};
727 field[1] = {res_field->r1y[i], res_field->i1y[i]};
728 field[2] = {res_field->r1z[i], res_field->i1z[i]};
730 n_source[0] = reflc.nx[i];
731 n_source[1] = reflc.ny[i];
732 n_source[2] = reflc.nz[i];
734 ut.
ext(n_source, field, ms);
736 res_current->r2x[i] = -2*ms[0].real();
737 res_current->i2x[i] = -2*ms[0].imag();
739 res_current->r2y[i] = -2*ms[1].real();
740 res_current->i2y[i] = -2*ms[1].imag();
742 res_current->r2z[i] = -2*ms[2].real();
743 res_current->i2z[i] = -2*ms[2].imag();
745 res_current->r1x[i] = 0;
746 res_current->i1x[i] = 0;
748 res_current->r1y[i] = 0;
749 res_current->i1y[i] = 0;
751 res_current->r1z[i] = 0;
752 res_current->i1z[i] = 0;
759 for (
int i=0; i<nTot; i++)
761 field[0] = {res_field->r2x[i], res_field->i2x[i]};
762 field[1] = {res_field->r2y[i], res_field->i2y[i]};
763 field[2] = {res_field->r2z[i], res_field->i2z[i]};
765 n_source[0] = reflc.nx[i];
766 n_source[1] = reflc.ny[i];
767 n_source[2] = reflc.nz[i];
769 ut.
ext(n_source, field, js);
771 res_current->r1x[i] = 2*js[0].real();
772 res_current->i1x[i] = 2*js[0].imag();
774 res_current->r1y[i] = 2*js[1].real();
775 res_current->i1y[i] = 2*js[1].imag();
777 res_current->r1z[i] = 2*js[2].real();
778 res_current->i1z[i] = 2*js[2].imag();
780 res_current->r2x[i] = 0;
781 res_current->i2x[i] = 0;
783 res_current->r2y[i] = 0;
784 res_current->i2y[i] = 0;
786 res_current->r2z[i] = 0;
787 res_current->i2z[i] = 0;