Commit 024756d5520726d5ccaab093b23605cec7398cba
1 parent
14634fca
integrate boundary scattering into the plane wave class
Showing
1 changed file
with
148 additions
and
7 deletions
Show diff stats
stim/optics/planewave.h
... | ... | @@ -345,12 +345,12 @@ public: |
345 | 345 | } |
346 | 346 | |
347 | 347 | ///multiplication operator: scale E0 |
348 | - /*CUDA_CALLABLE planewave<T>& operator* (const T& rhs) { | |
349 | - E0 = E0 * rhs; | |
348 | + CUDA_CALLABLE planewave<T>& operator* (const T& rhs) { | |
349 | + m_E = m_E * rhs; | |
350 | 350 | return *this; |
351 | 351 | } |
352 | 352 | |
353 | - CUDA_CALLABLE T lambda() const{ | |
353 | + /*CUDA_CALLABLE T lambda() const{ | |
354 | 354 | return stim::TAU / k.len(); |
355 | 355 | } |
356 | 356 | |
... | ... | @@ -413,9 +413,150 @@ public: |
413 | 413 | /// @param r is the reflected component of the plane wave |
414 | 414 | /// @param t is the transmitted component of the plane wave |
415 | 415 | |
416 | - /*void scatter(vec3<T> plane_normal, vec3<T> plane_position, std::complex<T> nr, planewave<T>& r, planewave<T>& t) { | |
416 | + void scatter(vec3<T> plane_normal, vec3<T> plane_position, std::complex<T> nr, planewave<T>& r, planewave<T>& t) { | |
417 | + | |
418 | + if (m_k[0].imag() != 0.0 || m_k[1].imag() != 0.0 || m_k[2].imag() != 0) { | |
419 | + std::cout << "ERROR: cannot scatter a plane wave with an imaginary k-vector." << std::endl; | |
420 | + } | |
421 | + | |
422 | + stim::vec3<T> ki(m_k[0].real(), m_k[1].real(), m_k[2].real()); //force the current k vector to be real | |
423 | + stim::vec3<T> kr; | |
424 | + stim::cvec3<T> kt, Ei, Er, Et; | |
417 | 425 | |
418 | - //TODO: Generate a real vector from the current K vector - this will not address complex k-vectors | |
426 | + plane_normal = plane_normal.direction(); | |
427 | + stim::vec3<T> k_dir = ki.direction(); // calculate the direction of the incident plane wave | |
428 | + | |
429 | + int facing = plane_face(k_dir, plane_normal); //determine which direction the plane wave is coming in | |
430 | + | |
431 | + if (facing == -1) { //if the wave hits the back of the plane, invert the plane and nr | |
432 | + std::cout << "ERROR: k-vector intersects the wrong side of the boundary." << std::endl; | |
433 | + return -1; //the plane wave is impacting the wrong side of the surface | |
434 | + } | |
435 | + | |
436 | + //use Snell's Law to calculate the transmitted angle | |
437 | + T cos_theta_i = k_dir.dot(-plane_normal); //compute the cosine of theta_i | |
438 | + T sin_theta_i = std::sqrt(1 - cos_theta_i * cos_theta_i); | |
439 | + T theta_i = acos(cos_theta_i); //compute theta_i | |
440 | + | |
441 | + //handle the degenerate case where theta_i is 0 (the plane wave hits head-on) | |
442 | + if (theta_i == 0) { | |
443 | + std::complex<T> rp = (1.0 - nr) / (1.0 + nr); //compute the Fresnel coefficients | |
444 | + std::complex<T> tp = 2.0 / (1.0 + nr); | |
445 | + | |
446 | + //ki = kv * ni; //calculate the incident k-vector (scaled by the incident refractive index) | |
447 | + kr = -ki; //the reflection vector is the inverse of the incident vector | |
448 | + kt[0] = ki[0] * nr; | |
449 | + kt[1] = ki[1] * nr; | |
450 | + kt[2] = ki[2] * nr; | |
451 | + //Ei = Ev; //compute the E vectors for all three plane waves based on the Fresnel coefficients | |
452 | + Er = m_E * rp; | |
453 | + Et = m_E * tp; | |
454 | + | |
455 | + //calculate the phase offset based on the plane positions | |
456 | + //T phase_i = plane_position.dot(kv - ki); //compute the phase offset for each plane wave | |
457 | + T phase_r = plane_position.dot(ki - kr); | |
458 | + std::complex<T> phase_t = | |
459 | + plane_position[0] * (ki[0] - kt[0]) + | |
460 | + plane_position[1] * (ki[1] - kt[1]) + | |
461 | + plane_position[2] * (ki[2] - kt[2]); | |
462 | + } | |
463 | + else { | |
464 | + T cos_theta_r = cos_theta_i; | |
465 | + T sin_theta_r = sin_theta_i; | |
466 | + T theta_r = theta_i; | |
467 | + | |
468 | + std::complex<T> sin_theta_t = nr * sin(theta_i); //compute the sine of theta_t using Snell's law | |
469 | + std::complex<T> cos_theta_t = std::sqrt(1.0 - sin_theta_t * sin_theta_t); | |
470 | + std::complex<T> theta_t = asin(sin_theta_t); //compute the cosine of theta_t | |
471 | + | |
472 | + //Define the basis vectors for the calculation (plane of incidence) | |
473 | + stim::vec3<T> z_hat = -plane_normal; | |
474 | + stim::vec3<T> y_hat = plane_parallel(k_dir, plane_normal); | |
475 | + stim::vec3<T> x_hat = y_hat.cross(z_hat); | |
476 | + | |
477 | + //calculate the k-vector magnitudes | |
478 | + //T kv_mag = kv.norm2(); | |
479 | + T ki_mag = ki.norm2(); | |
480 | + T kr_mag = ki_mag; | |
481 | + std::complex<T> kt_mag = ki_mag * nr; | |
482 | + | |
483 | + //calculate the k vector directions | |
484 | + stim::vec3<T> ki_dir = y_hat * sin_theta_i + z_hat * cos_theta_i; | |
485 | + stim::vec3<T> kr_dir = y_hat * sin_theta_r - z_hat * cos_theta_r; | |
486 | + stim::cvec3<T> kt_dir; | |
487 | + kt_dir[0] = y_hat[0] * sin_theta_t + z_hat[0] * cos_theta_t; | |
488 | + kt_dir[1] = y_hat[1] * sin_theta_t + z_hat[1] * cos_theta_t; | |
489 | + kt_dir[2] = y_hat[2] * sin_theta_t + z_hat[2] * cos_theta_t; | |
490 | + | |
491 | + //calculate the k vectors | |
492 | + ki = ki_dir * ki_mag; | |
493 | + kr = kr_dir * kr_mag; | |
494 | + kt = kt_dir * kt_mag; | |
495 | + | |
496 | + //calculate the Fresnel coefficients | |
497 | + std::complex<T> rs = std::sin(theta_t - theta_i) / std::sin(theta_t + theta_i); | |
498 | + std::complex<T> rp = std::tan(theta_t - theta_i) / std::tan(theta_t + theta_i); | |
499 | + std::complex<T> ts = (2.0 * (sin_theta_t * cos_theta_i)) / std::sin(theta_t + theta_i); | |
500 | + std::complex<T> tp = ((2.0 * sin_theta_t * cos_theta_i) / (std::sin(theta_t + theta_i) * std::cos(theta_t - theta_i))); | |
501 | + | |
502 | + //calculate the p component directions for each E vector | |
503 | + stim::vec3<T> Eip_dir = y_hat * cos_theta_i - z_hat * sin_theta_i; | |
504 | + stim::vec3<T> Erp_dir = y_hat * cos_theta_r + z_hat * sin_theta_r; | |
505 | + stim::cvec3<T> Etp_dir; | |
506 | + Etp_dir[0] = y_hat[0] * cos_theta_t - z_hat[0] * sin_theta_t; | |
507 | + Etp_dir[1] = y_hat[1] * cos_theta_t - z_hat[1] * sin_theta_t; | |
508 | + Etp_dir[2] = y_hat[2] * cos_theta_t - z_hat[2] * sin_theta_t; | |
509 | + | |
510 | + //calculate the s and t components of each E vector | |
511 | + //std::complex<T> E_mag = Ev.norm2(); | |
512 | + std::complex<T> Ei_s = m_E.dot(x_hat); | |
513 | + //std::complex<T> Ei_p = std::sqrt(E_mag * E_mag - Ei_s * Ei_s); | |
514 | + std::complex<T> Ei_p = m_E.dot(Eip_dir); | |
515 | + std::complex<T> Er_s = rs * Ei_s; | |
516 | + std::complex<T> Er_p = rp * Ei_p; | |
517 | + std::complex<T> Et_s = ts * Ei_s; | |
518 | + std::complex<T> Et_p = tp * Ei_p; | |
519 | + | |
520 | + | |
521 | + | |
522 | + //calculate the E vector for each plane wave | |
523 | + //Ei[0] = Eip_dir[0] * Ei_p + x_hat[0] * Ei_s; | |
524 | + //Ei[1] = Eip_dir[1] * Ei_p + x_hat[1] * Ei_s; | |
525 | + //Ei[2] = Eip_dir[2] * Ei_p + x_hat[2] * Ei_s; | |
526 | + | |
527 | + //std::cout << Ev << std::endl; | |
528 | + //std::cout << Ei << std::endl; | |
529 | + //std::cout << std::endl; | |
530 | + | |
531 | + Er[0] = Erp_dir[0] * Er_p + x_hat[0] * Er_s; | |
532 | + Er[1] = Erp_dir[1] * Er_p + x_hat[1] * Er_s; | |
533 | + Er[2] = Erp_dir[2] * Er_p + x_hat[2] * Er_s; | |
534 | + | |
535 | + Et[0] = Etp_dir[0] * Et_p + x_hat[0] * Et_s; | |
536 | + Et[1] = Etp_dir[1] * Et_p + x_hat[1] * Et_s; | |
537 | + Et[2] = Etp_dir[2] * Et_p + x_hat[2] * Et_s; | |
538 | + } | |
539 | + | |
540 | + | |
541 | + //calculate the phase offset based on the plane positions | |
542 | + //T phase_i = plane_position.dot(kv - ki); //compute the phase offset for each plane wave | |
543 | + T phase_r = plane_position.dot(ki - kr); | |
544 | + std::complex<T> phase_t = | |
545 | + plane_position[0] * (ki[0] - kt[0]) + | |
546 | + plane_position[1] * (ki[1] - kt[1]) + | |
547 | + plane_position[2] * (ki[2] - kt[2]); | |
548 | + | |
549 | + | |
550 | + //Ei = Ei * std::exp(std::complex<T>(0, 1)); | |
551 | + Er = Er * std::exp(std::complex<T>(0, 1) * phase_r); | |
552 | + Et = Et * std::exp(std::complex<T>(0, 1) * phase_t); | |
553 | + | |
554 | + //Pi = stim::optics::planewave<T>(ki[0], ki[1], ki[2], Ei[0], Ei[1], Ei[2]); | |
555 | + r = stim::optics::planewave<T>(kr[0], kr[1], kr[2], Er[0], Er[1], Er[2]); | |
556 | + t = stim::optics::planewave<T>(kt[0], kt[1], kt[2], Et[0], Et[1], Et[2]); | |
557 | + | |
558 | + return 0; | |
559 | + /*TODO: Generate a real vector from the current K vector - this will not address complex k-vectors | |
419 | 560 | vec3< std::complex<T> > k(3); |
420 | 561 | k[0] = m_k[0]; |
421 | 562 | k[1] = m_k[1]; |
... | ... | @@ -525,8 +666,8 @@ public: |
525 | 666 | //t.m_E = Et * exp( complex<T>(0, phase_t) ); |
526 | 667 | |
527 | 668 | r = planewave(kr[0], kr[1], kr[2], Er[0], Er[1], Er[2]); |
528 | - t = planewave(kt[0], kt[1], kt[2], Et[0], Et[1], Et[2]); | |
529 | - }*/ | |
669 | + t = planewave(kt[0], kt[1], kt[2], Et[0], Et[1], Et[2]);*/ | |
670 | + } | |
530 | 671 | |
531 | 672 | std::string str() |
532 | 673 | { | ... | ... |