Commit 024756d5520726d5ccaab093b23605cec7398cba

Authored by David Mayerich
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,12 +345,12 @@ public:
345 } 345 }
346 346
347 ///multiplication operator: scale E0 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 return *this; 350 return *this;
351 } 351 }
352 352
353 - CUDA_CALLABLE T lambda() const{ 353 + /*CUDA_CALLABLE T lambda() const{
354 return stim::TAU / k.len(); 354 return stim::TAU / k.len();
355 } 355 }
356 356
@@ -413,9 +413,150 @@ public: @@ -413,9 +413,150 @@ public:
413 /// @param r is the reflected component of the plane wave 413 /// @param r is the reflected component of the plane wave
414 /// @param t is the transmitted component of the plane wave 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 vec3< std::complex<T> > k(3); 560 vec3< std::complex<T> > k(3);
420 k[0] = m_k[0]; 561 k[0] = m_k[0];
421 k[1] = m_k[1]; 562 k[1] = m_k[1];
@@ -525,8 +666,8 @@ public: @@ -525,8 +666,8 @@ public:
525 //t.m_E = Et * exp( complex<T>(0, phase_t) ); 666 //t.m_E = Et * exp( complex<T>(0, phase_t) );
526 667
527 r = planewave(kr[0], kr[1], kr[2], Er[0], Er[1], Er[2]); 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 std::string str() 672 std::string str()
532 { 673 {