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] = std::complex<G>(
abs(reflc.z[i] + gdict.z), 0) + j*zc;
475 r = sqrt(R[0]*R[0] + R[1]*R[1] + R[2]*R[2]);
477 expo = exp(-j*k*r - k*k*gdict.w0*gdict.w0/2.0);
482 kr_sum_1 = (-j*kr_inv - kr_inv*kr_inv + j*kr_inv*kr_inv*kr_inv);
483 kr_sum_2 = (j*kr_inv + 3.0*kr_inv*kr_inv - 3.0*j*kr_inv*kr_inv*kr_inv);
484 kr_sum_3 = (j*kr_inv + kr_inv*kr_inv);
487 if (reflc.z[i] + gdict.z >= 0.0) {
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);
496 efield[0] = std::conj(prefactor*expo*(kr_sum_1 + kr_sum_2*(R[0]*R[0] / (r*r)) - kr_sum_3*(R[2] / r)));
497 efield[1] = std::conj(prefactor*expo*kr_sum_2*R[0]*R[1]/(r*r));
498 efield[2] = std::conj(prefactor*expo*(kr_sum_2*R[0]*R[2]/(r*r) - kr_sum_3*R[0]/r));
500 hfield[0] = std::conj(prefactor*expo*kr_sum_2*R[0]*R[1]/(r*r));
501 hfield[1] = std::conj(prefactor*expo*(kr_sum_1 + kr_sum_2*(R[1]*R[1] / (r*r)) - kr_sum_3*(R[2] / r)));
502 hfield[2] = std::conj(prefactor*expo*(kr_sum_2*R[1]*R[2]/(r*r) - kr_sum_3*R[1]/r));
506 n_source[0] = reflc.nx[i];
507 n_source[1] = reflc.ny[i];
508 n_source[2] = reflc.nz[i];
510 ut.
ext(n_source, efield, M);
511 ut.
ext(n_source, hfield, J);
515 res_field->r1x[i] = efield[0].real();
516 res_field->i1x[i] = efield[0].imag();
518 res_field->r1y[i] = efield[1].real();
519 res_field->i1y[i] = efield[1].imag();
521 res_field->r1z[i] = efield[2].real();
522 res_field->i1z[i] = efield[2].imag();
525 res_field->r2x[i] = hfield[0].real();
526 res_field->i2x[i] = hfield[0].imag();
528 res_field->r2y[i] = hfield[1].real();
529 res_field->i2y[i] = hfield[1].imag();
531 res_field->r2z[i] = hfield[2].real();
532 res_field->i2z[i] = hfield[2].imag();
535 if ((gdict.mode == 1) or (gdict.mode == 2))
542 if ((gdict.mode == 0) or (gdict.mode == 2))
544 res_current->r1x[i] = Factor*J[0].real();
545 res_current->i1x[i] = Factor*J[0].imag();
547 res_current->r1y[i] = Factor*J[1].real();
548 res_current->i1y[i] = Factor*J[1].imag();
550 res_current->r1z[i] = Factor*J[2].real();
551 res_current->i1z[i] = Factor*J[2].imag();
553 res_current->r1x[i] = 0.0;
554 res_current->i1x[i] = 0.0;
556 res_current->r1y[i] = 0.0;
557 res_current->i1y[i] = 0.0;
559 res_current->r1z[i] = 0.0;
560 res_current->i1z[i] = 0.0;
564 if ((gdict.mode == 0) or (gdict.mode == 1))
566 res_current->r2x[i] = -Factor*M[0].real();
567 res_current->i2x[i] = -Factor*M[0].imag();
569 res_current->r2y[i] = -Factor*M[1].real();
570 res_current->i2y[i] = -Factor*M[1].imag();
572 res_current->r2z[i] = -Factor*M[2].real();
573 res_current->i2z[i] = -Factor*M[2].imag();
575 res_current->r2x[i] = 0.0;
576 res_current->i2x[i] = 0.0;
578 res_current->r2y[i] = 0.0;
579 res_current->i2y[i] = 0.0;
581 res_current->r2z[i] = 0.0;
582 res_current->i2z[i] = 0.0;
598 template<
typename T,
typename U,
typename V,
typename W,
typename G>
601 int nTot = refldict.n_cells[0] * refldict.n_cells[1];
605 reflc.x =
new G[nTot];
606 reflc.y =
new G[nTot];
607 reflc.z =
new G[nTot];
609 reflc.nx =
new G[nTot];
610 reflc.ny =
new G[nTot];
611 reflc.nz =
new G[nTot];
613 reflc.area =
new G[nTot];
616 bool transform =
true;
619 G zRx = M_PI * sgdict.w0x*sgdict.w0x * sgdict.n / sgdict.lam;
620 G zRy = M_PI * sgdict.w0y*sgdict.w0y * sgdict.n / sgdict.lam;
621 G k = 2 * M_PI / sgdict.lam;
629 std::complex<G> j(0, 1);
631 std::complex<G> efield;
633 for (
int i=0; i<nTot; i++)
635 wzx = sgdict.w0x * sqrt(1 + (reflc.z[i] / zRx)*(reflc.z[i] / zRx));
636 wzy = sgdict.w0y * sqrt(1 + ((reflc.z[i] - sgdict.dxyz) / zRy)*((reflc.z[i] - sgdict.dxyz) / zRy));
637 Rzx_inv = reflc.z[i] / (reflc.z[i]*reflc.z[i] + zRx*zRx);
638 Rzy_inv = (reflc.z[i] - sgdict.dxyz) / ((reflc.z[i] - sgdict.dxyz)*(reflc.z[i] - sgdict.dxyz) + zRy*zRy);
639 phizx = atan(reflc.z[i] / zRx);
640 phizy = atan((reflc.z[i] - sgdict.dxyz) / zRy);
642 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) -
643 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);
645 res_field->x[i] = efield.real();
646 res_field->y[i] = efield.imag();
660 template<
typename T,
typename U,
typename V,
typename W>
661 void calcJM(T *res_field, T *res_current, V refldict,
int mode)
664 int nTot = refldict.n_cells[0] * refldict.n_cells[1];
668 reflc.x =
new U[nTot];
669 reflc.y =
new U[nTot];
670 reflc.z =
new U[nTot];
672 reflc.nx =
new U[nTot];
673 reflc.ny =
new U[nTot];
674 reflc.nz =
new U[nTot];
676 reflc.area =
new U[nTot];
678 bool transform =
true;
683 std::array<std::complex<U>, 3> field;
684 std::array<U, 3> n_source;
686 std::array<std::complex<U>, 3> js;
687 std::array<std::complex<U>, 3> ms;
692 for (
int i=0; i<nTot; i++)
694 field[0] = {res_field->r1x[i], res_field->i1x[i]};
695 field[1] = {res_field->r1y[i], res_field->i1y[i]};
696 field[2] = {res_field->r1z[i], res_field->i1z[i]};
698 n_source[0] = reflc.nx[i];
699 n_source[1] = reflc.ny[i];
700 n_source[2] = reflc.nz[i];
702 ut.
ext(n_source, field, ms);
704 res_current->r2x[i] = -ms[0].real();
705 res_current->i2x[i] = -ms[0].imag();
707 res_current->r2y[i] = -ms[1].real();
708 res_current->i2y[i] = -ms[1].imag();
710 res_current->r2z[i] = -ms[2].real();
711 res_current->i2z[i] = -ms[2].imag();
713 field[0] = {res_field->r2x[i], res_field->i2x[i]};
714 field[1] = {res_field->r2y[i], res_field->i2y[i]};
715 field[2] = {res_field->r2z[i], res_field->i2z[i]};
717 ut.
ext(n_source, field, js);
719 res_current->r1x[i] = js[0].real();
720 res_current->i1x[i] = js[0].imag();
722 res_current->r1y[i] = js[1].real();
723 res_current->i1y[i] = js[1].imag();
725 res_current->r1z[i] = js[2].real();
726 res_current->i1z[i] = js[2].imag();
733 for (
int i=0; i<nTot; i++)
735 field[0] = {res_field->r1x[i], res_field->i1x[i]};
736 field[1] = {res_field->r1y[i], res_field->i1y[i]};
737 field[2] = {res_field->r1z[i], res_field->i1z[i]};
739 n_source[0] = reflc.nx[i];
740 n_source[1] = reflc.ny[i];
741 n_source[2] = reflc.nz[i];
743 ut.
ext(n_source, field, ms);
745 res_current->r2x[i] = -2*ms[0].real();
746 res_current->i2x[i] = -2*ms[0].imag();
748 res_current->r2y[i] = -2*ms[1].real();
749 res_current->i2y[i] = -2*ms[1].imag();
751 res_current->r2z[i] = -2*ms[2].real();
752 res_current->i2z[i] = -2*ms[2].imag();
754 res_current->r1x[i] = 0;
755 res_current->i1x[i] = 0;
757 res_current->r1y[i] = 0;
758 res_current->i1y[i] = 0;
760 res_current->r1z[i] = 0;
761 res_current->i1z[i] = 0;
768 for (
int i=0; i<nTot; i++)
770 field[0] = {res_field->r2x[i], res_field->i2x[i]};
771 field[1] = {res_field->r2y[i], res_field->i2y[i]};
772 field[2] = {res_field->r2z[i], res_field->i2z[i]};
774 n_source[0] = reflc.nx[i];
775 n_source[1] = reflc.ny[i];
776 n_source[2] = reflc.nz[i];
778 ut.
ext(n_source, field, js);
780 res_current->r1x[i] = 2*js[0].real();
781 res_current->i1x[i] = 2*js[0].imag();
783 res_current->r1y[i] = 2*js[1].real();
784 res_current->i1y[i] = 2*js[1].imag();
786 res_current->r1z[i] = 2*js[2].real();
787 res_current->i1z[i] = 2*js[2].imag();
789 res_current->r2x[i] = 0;
790 res_current->i2x[i] = 0;
792 res_current->r2y[i] = 0;
793 res_current->i2y[i] = 0;
795 res_current->r2z[i] = 0;
796 res_current->i2z[i] = 0;
803 for (
int i=0; i<nTot; i++)
805 field[0] = {res_field->r1x[i], res_field->i1x[i]};
806 field[1] = {res_field->r1y[i], res_field->i1y[i]};
807 field[2] = {res_field->r1z[i], res_field->i1z[i]};
809 n_source[0] = reflc.nx[i];
810 n_source[1] = reflc.ny[i];
811 n_source[2] = reflc.nz[i];
813 ut.
ext(n_source, field, js);
815 res_current->r1x[i] = 2*js[0].real();
816 res_current->i1x[i] = 2*js[0].imag();
818 res_current->r1y[i] = 2*js[1].real();
819 res_current->i1y[i] = 2*js[1].imag();
821 res_current->r1z[i] = 2*js[2].real();
822 res_current->i1z[i] = 2*js[2].imag();
824 res_current->r2x[i] = 0;
825 res_current->i2x[i] = 0;
827 res_current->r2y[i] = 0;
828 res_current->i2y[i] = 0;
830 res_current->r2z[i] = 0;
831 res_current->i2z[i] = 0;