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,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 | { |