From a5baabcb57c91384f6c34f01cb930341ca71b030 Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Fri, 14 Aug 2020 12:11:16 -0700 Subject: [PATCH 01/15] eigenmodes of diffracted planewaves in 3d --- python/simulation.py | 26 ++++++++++++++++++++++++++ src/meep.hpp | 17 ++++++++++++++++- src/mpb.cpp | 35 +++++++++++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/python/simulation.py b/python/simulation.py index c3b49fa08..69a64a640 100644 --- a/python/simulation.py +++ b/python/simulation.py @@ -99,6 +99,32 @@ def py_v3_to_vec(dims, iterable, is_cylindrical=False): else: raise ValueError("Invalid dimensions in Volume: {}".format(dims)) +class DiffractedPlanewave(object): + def __init__(self, + g=None, + axis=None, + s=None, + p=None): + self._g = g + self._axis = axis + self._s = s + self._p = p + + @property + def g(self): + return self._g + + @property + def axis(self): + return self._axis + + @property + def s(self): + return self._s + + @property + def p(self): + return self._p class PML(object): """ diff --git a/src/meep.hpp b/src/meep.hpp index f8fd74efa..05a74b5cc 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -1484,6 +1484,21 @@ class chunkloop_field_components { std::vector > values; // updated by update_values(idx) }; +class diffractedplanewave { + +public: + diffractedplanewave(int g[3], double axis[3], std::complex s, std::complex p); + int *get_g() { return g; }; + double *get_axis() { return axis; } + std::complex get_s() const { return s; }; + std::complex get_p() const { return p; }; +private: + int g[3]; // diffraction order + double axis[3]; // axis vector + std::complex s; // s polarization amplitude + std::complex p; // p polarization ampiltude +}; + class gaussianbeam { public: @@ -1710,7 +1725,7 @@ class fields { void *get_eigenmode(double frequency, direction d, const volume where, const volume eig_vol, int band_num, const vec &kpoint, bool match_frequency, int parity, double resolution, double eigensolver_tol, double *kdom = 0, - void **user_mdata = 0); + void **user_mdata = 0, diffractedplanewave *dp = 0); void add_eigenmode_source(component c, const src_time &src, direction d, const volume &where, const volume &eig_vol, int band_num, const vec &kpoint, diff --git a/src/mpb.cpp b/src/mpb.cpp index d4e1857a4..5f4de30ee 100644 --- a/src/mpb.cpp +++ b/src/mpb.cpp @@ -292,6 +292,15 @@ static int nextpow2357(int n) { } } +diffractedplanewave::diffractedplanewave(int g_[3], double axis_[3], std::complex s_, std::complex p_) { + for (int j = 0; j < 3; ++j) { + g[j] = g_[j]; + axis[j] = axis_[j]; + } + s = s_; + p = p_; +}; + /****************************************************************/ /* call MPB to get the band_numth eigenmode at freq frequency. */ /* */ @@ -313,7 +322,7 @@ static int nextpow2357(int n) { void *fields::get_eigenmode(double frequency, direction d, const volume where, const volume eig_vol, int band_num, const vec &_kpoint, bool match_frequency, int parity, double resolution, double eigensolver_tol, double *kdom, - void **user_mdata) { + void **user_mdata, diffractedplanewave *dp) { /*--------------------------------------------------------------*/ /*- part 1: preliminary setup for calling MPB -----------------*/ /*--------------------------------------------------------------*/ @@ -538,7 +547,7 @@ void *fields::get_eigenmode(double frequency, direction d, const volume where, c /*- part 2: newton iteration loop with call to MPB on each step */ /*- until eigenmode converged to requested tolerance */ /*--------------------------------------------------------------*/ - if (am_master()) do { + if (am_master() && !dp) do { eigensolver(H, eigvals, maxwell_operator, (void *)mdata, #if MPB_VERSION_MAJOR > 1 || (MPB_VERSION_MAJOR == 1 && MPB_VERSION_MINOR >= 6) NULL, NULL, /* eventually, we can support mu here */ @@ -591,6 +600,28 @@ void *fields::get_eigenmode(double frequency, direction d, const volume where, c } while (match_frequency && fabs(sqrt(eigvals[band_num - 1]) - frequency) > frequency * match_tol); + if (am_master() && dp) { + scalar_complex s = {real(dp->get_s()),imag(dp->get_s())}; + scalar_complex p = {real(dp->get_p()),imag(dp->get_p())}; + + master_printf("diffracted planewave: k = %g, %g, %g for omega = %g\n", k[0],k[1],k[2], frequency); + update_maxwell_data_k(mdata, k, G[0], G[1], G[2]); + maxwell_set_planewave(mdata, H, band_num, dp->get_g(), s, p, dp->get_axis()); + + eigvals[band_num - 1] = frequency; + + evectmatrix_resize(&W[0], 1, 0); + evectmatrix_resize(&W[1], 1, 0); + for (int i = 0; i < H.n; ++i) + W[0].data[i] = H.data[H.p - 1 + i * H.p]; + maxwell_ucross_op(W[0], W[1], mdata, kdir); // W[1] = (dTheta/dk) W[0] + mpb_real vscratch; + evectmatrix_XtY_diag_real(W[0], W[1], &vgrp, &vscratch); + vgrp /= sqrt(eigvals[band_num - 1]); + + master_printf("diffracted planewave: group velocity v=%g\n", vgrp); + } + double eigval = eigvals[band_num - 1]; // cleanup temporary storage From d323963e574b50ca6c1ea7d8bb17adc0a7862b9d Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Sat, 15 Aug 2020 19:25:05 -0700 Subject: [PATCH 02/15] overload get_eigenmode_coefficients_and_kpoints with diffractedplanewave object in place of bands array --- python/meep.i | 20 ++++++++++++ python/simulation.py | 74 +++++++++++++++++++++++++++++++------------- src/meep.hpp | 7 +++-- src/mpb.cpp | 8 ++--- 4 files changed, 81 insertions(+), 28 deletions(-) diff --git a/python/meep.i b/python/meep.i index e3396e820..a3aa5d50c 100644 --- a/python/meep.i +++ b/python/meep.i @@ -512,6 +512,25 @@ kpoint_list get_eigenmode_coefficients_and_kpoints(meep::fields *f, meep::dft_fl return res; } + +kpoint_list get_eigenmode_coefficients_and_kpoints(meep::fields *f, meep::dft_flux flux, const meep::volume &eig_vol, + meep::diffractedplanewave *dp, int parity, double eig_resolution, + double eigensolver_tol, std::complex *coeffs, + double *vgrp, meep::kpoint_func user_kpoint_func, + void *user_kpoint_data, double *cscale, meep::direction d) { + + size_t num_kpoints = flux.freq.size(); + meep::vec *kpoints = new meep::vec[num_kpoints]; + meep::vec *kdom = new meep::vec[num_kpoints]; + + f->get_eigenmode_coefficients(flux, eig_vol, NULL, 0, parity, eig_resolution, eigensolver_tol, + coeffs, vgrp, user_kpoint_func, user_kpoint_data, kpoints, kdom, cscale, d, dp); + + kpoint_list res = {kpoints, num_kpoints, kdom, num_kpoints}; + + return res; +} + PyObject *_get_array_slice_dimensions(meep::fields *f, const meep::volume &where, size_t dims[3], bool collapse_empty_dimensions, bool snap_empty_dimensions, meep::component cgrid = Centered, PyObject *min_max_loc = NULL) { @@ -1562,6 +1581,7 @@ PyObject *_get_array_slice_dimensions(meep::fields *f, const meep::volume &where DftEnergy, DftFields, Volume, + DiffractedPlanewave, after_sources, after_sources_and_time, after_time, diff --git a/python/simulation.py b/python/simulation.py index 69a64a640..2a8536c04 100644 --- a/python/simulation.py +++ b/python/simulation.py @@ -106,9 +106,9 @@ def __init__(self, s=None, p=None): self._g = g - self._axis = axis - self._s = s - self._p = p + self._axis = Vector3(*axis) + self._s = complex(s) + self._p = complex(p) @property def g(self): @@ -3283,25 +3283,55 @@ def get_eigenmode_coefficients(self, flux, bands, eig_parity=mp.NO_PARITY, eig_v if direction is None or direction == mp.AUTOMATIC: direction = flux.normal_direction - num_bands = len(bands) - coeffs = np.zeros(2 * num_bands * flux.freq.size(), dtype=np.complex128) - vgrp = np.zeros(num_bands * flux.freq.size()) - cscale = np.zeros(num_bands * flux.freq.size()) - - kpoints, kdom = mp.get_eigenmode_coefficients_and_kpoints( - self.fields, - flux.swigobj, - eig_vol, - np.array(bands, dtype=np.intc), - eig_parity, - eig_resolution, - eig_tolerance, - coeffs, - vgrp, - kpoint_func, - cscale, - direction - ) + if isinstance(bands,(list,range)): + num_bands = len(bands) + coeffs = np.zeros(2 * num_bands * flux.freq.size(), dtype=np.complex128) + vgrp = np.zeros(num_bands * flux.freq.size()) + cscale = np.zeros(num_bands * flux.freq.size()) + + kpoints, kdom = mp.get_eigenmode_coefficients_and_kpoints( + self.fields, + flux.swigobj, + eig_vol, + np.array(bands, dtype=np.intc), + eig_parity, + eig_resolution, + eig_tolerance, + coeffs, + vgrp, + kpoint_func, + cscale, + direction + ) + elif isinstance(bands,DiffractedPlanewave): + coeffs = np.zeros(2 * flux.freq.size(), dtype=np.complex128) + vgrp = np.zeros(flux.freq.size()) + cscale = np.zeros(flux.freq.size()) + + diffractedplanewave_args = [ + np.array(bands.g, dtype=np.intc), + py_v3_to_vec(self.dimensions, bands.axis, is_cylindrical=self.is_cylindrical), + bands.s, + bands.p + ] + diffractedplanewave = mp.diffractedplanewave(*diffractedplane_args) + + kpoints, kdom = mp.get_eigenmode_coefficients_and_kpoints( + self.fields, + flux.swigobj, + eig_vol, + diffractedplanewave, + eig_parity, + eig_resolution, + eig_tolerance, + coeffs, + vgrp, + kpoint_func, + cscale, + direction + ) + else: + raise TypeError("get_eigenmode_coefficients: bands must be either a list or DiffractedPlanewave object") return EigCoeffsResult(np.reshape(coeffs, (num_bands, flux.freq.size(), 2)), vgrp, kpoints, kdom, cscale) diff --git a/src/meep.hpp b/src/meep.hpp index 05a74b5cc..1ff855d14 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -1492,6 +1492,7 @@ class diffractedplanewave { double *get_axis() { return axis; } std::complex get_s() const { return s; }; std::complex get_p() const { return p; }; + private: int g[3]; // diffraction order double axis[3]; // axis vector @@ -1737,12 +1738,14 @@ class fields { int parity, double eig_resolution, double eigensolver_tol, std::complex *coeffs, double *vgrp, kpoint_func user_kpoint_func, void *user_kpoint_data, - vec *kpoints, vec *kdom, double *cscale, direction d); + vec *kpoints, vec *kdom, double *cscale, direction d, + diffractedplanewave *dp = 0); void get_eigenmode_coefficients(dft_flux flux, const volume &eig_vol, int *bands, int num_bands, int parity, double eig_resolution, double eigensolver_tol, std::complex *coeffs, double *vgrp, kpoint_func user_kpoint_func = 0, void *user_kpoint_data = 0, - vec *kpoints = 0, vec *kdom = 0, double *cscale = 0); + vec *kpoints = 0, vec *kdom = 0, double *cscale = 0, + diffractedplanewave *dp = 0); // initialize.cpp: void initialize_field(component, std::complex f(const vec &)); diff --git a/src/mpb.cpp b/src/mpb.cpp index 5f4de30ee..c379f37f7 100644 --- a/src/mpb.cpp +++ b/src/mpb.cpp @@ -859,7 +859,7 @@ void fields::get_eigenmode_coefficients(dft_flux flux, const volume &eig_vol, in double eigensolver_tol, std::complex *coeffs, double *vgrp, kpoint_func user_kpoint_func, void *user_kpoint_data, vec *kpoints, vec *kdom_list, - double *cscale, direction d) { + double *cscale, direction d, diffractedplanewave *dp) { int num_freqs = flux.freq.size(); bool match_frequency = true; @@ -884,7 +884,7 @@ void fields::get_eigenmode_coefficients(dft_flux flux, const volume &eig_vol, in am_now_working_on(MPBTime); void *mode_data = get_eigenmode(flux.freq[nf], d, flux.where, eig_vol, band_num, kpoint, match_frequency, - parity, eig_resolution, eigensolver_tol, kdom, (void **)&mdata); + parity, eig_resolution, eigensolver_tol, kdom, (void **)&mdata, dp); finished_working(); if (!mode_data) { // mode not found, assume evanescent coeffs[2 * nb * num_freqs + 2 * nf] = coeffs[2 * nb * num_freqs + 2 * nf + 1] = 0; @@ -1032,10 +1032,10 @@ void fields::get_eigenmode_coefficients(dft_flux flux, const volume &eig_vol, in double eigensolver_tol, std::complex *coeffs, double *vgrp, kpoint_func user_kpoint_func, void *user_kpoint_data, vec *kpoints, vec *kdom, - double *cscale) { + double *cscale, diffractedplanewave *dp) { get_eigenmode_coefficients(flux, eig_vol, bands, num_bands, parity, eig_resolution, eigensolver_tol, coeffs, vgrp, user_kpoint_func, user_kpoint_data, - kpoints, kdom, cscale, flux.normal_direction); + kpoints, kdom, cscale, flux.normal_direction, dp); } } // namespace meep From 332c75d8a88abfd07d0390e36bea155cb0372ef2 Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Sun, 16 Aug 2020 17:13:50 -0700 Subject: [PATCH 03/15] SWIG typemap for axis member of class diffractedplanewave --- python/meep.i | 24 +++++++++++++++++++----- python/simulation.py | 16 ++++++++-------- src/mpb.cpp | 3 +-- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/python/meep.i b/python/meep.i index a3aa5d50c..951e96e5c 100644 --- a/python/meep.i +++ b/python/meep.i @@ -512,9 +512,8 @@ kpoint_list get_eigenmode_coefficients_and_kpoints(meep::fields *f, meep::dft_fl return res; } - kpoint_list get_eigenmode_coefficients_and_kpoints(meep::fields *f, meep::dft_flux flux, const meep::volume &eig_vol, - meep::diffractedplanewave *dp, int parity, double eig_resolution, + meep::diffractedplanewave dp, int parity, double eig_resolution, double eigensolver_tol, std::complex *coeffs, double *vgrp, meep::kpoint_func user_kpoint_func, void *user_kpoint_data, double *cscale, meep::direction d) { @@ -522,9 +521,8 @@ kpoint_list get_eigenmode_coefficients_and_kpoints(meep::fields *f, meep::dft_fl size_t num_kpoints = flux.freq.size(); meep::vec *kpoints = new meep::vec[num_kpoints]; meep::vec *kdom = new meep::vec[num_kpoints]; - - f->get_eigenmode_coefficients(flux, eig_vol, NULL, 0, parity, eig_resolution, eigensolver_tol, - coeffs, vgrp, user_kpoint_func, user_kpoint_data, kpoints, kdom, cscale, d, dp); + f->get_eigenmode_coefficients(flux, eig_vol, NULL, 1, parity, eig_resolution, eigensolver_tol, + coeffs, vgrp, user_kpoint_func, user_kpoint_data, kpoints, kdom, cscale, d, &dp); kpoint_list res = {kpoints, num_kpoints, kdom, num_kpoints}; @@ -1053,6 +1051,16 @@ void _get_gradient(PyObject *grad, PyObject *fields_a, PyObject *fields_f, PyObj $1 = (std::complex *)array_data($input); } +// typemaps for diffractedplanewave + +%typecheck(SWIG_TYPECHECK_POINTER, fragment="NumPy_Fragments") double axis[3] { + $1 = is_array($input); +} + +%typemap(in) double axis[3] { + $1 = (double *)array_data($input); +} + // typemaps for gaussianbeam %typecheck(SWIG_TYPECHECK_POINTER, fragment="NumPy_Fragments") std::complex E0[3] { @@ -1495,6 +1503,12 @@ kpoint_list get_eigenmode_coefficients_and_kpoints(meep::fields *f, meep::dft_fl std::complex *coeffs, double *vgrp, meep::kpoint_func user_kpoint_func, void *user_kpoint_data, double *cscale, meep::direction d); +kpoint_list get_eigenmode_coefficients_and_kpoints(meep::fields *f, meep::dft_flux flux, + const meep::volume &eig_vol, meep::diffractedplanewave dp, + int parity, double eig_resolution, double eigensolver_tol, + std::complex *coeffs, double *vgrp, + meep::kpoint_func user_kpoint_func, void *user_kpoint_data, + double *cscale, meep::direction d); PyObject *_get_array_slice_dimensions(meep::fields *f, const meep::volume &where, size_t dims[3], bool collapse_empty_dimensions, bool snap_empty_dimensions, meep::component cgrid = Centered, PyObject *min_max_loc = NULL); diff --git a/python/simulation.py b/python/simulation.py index 2a8536c04..c4ccb95e5 100644 --- a/python/simulation.py +++ b/python/simulation.py @@ -3304,17 +3304,17 @@ def get_eigenmode_coefficients(self, flux, bands, eig_parity=mp.NO_PARITY, eig_v direction ) elif isinstance(bands,DiffractedPlanewave): - coeffs = np.zeros(2 * flux.freq.size(), dtype=np.complex128) - vgrp = np.zeros(flux.freq.size()) - cscale = np.zeros(flux.freq.size()) - + num_bands = 1 + coeffs = np.zeros(2 * num_bands * flux.freq.size(), dtype=np.complex128) + vgrp = np.zeros(num_bands * flux.freq.size()) + cscale = np.zeros(num_bands * flux.freq.size()) diffractedplanewave_args = [ np.array(bands.g, dtype=np.intc), - py_v3_to_vec(self.dimensions, bands.axis, is_cylindrical=self.is_cylindrical), - bands.s, - bands.p + np.array([bands.axis.x, bands.axis.y, bands.axis.z], dtype=np.float64), + bands.s * 1.0, + bands.p * 1.0 ] - diffractedplanewave = mp.diffractedplanewave(*diffractedplane_args) + diffractedplanewave = mp.diffractedplanewave(*diffractedplanewave_args) kpoints, kdom = mp.get_eigenmode_coefficients_and_kpoints( self.fields, diff --git a/src/mpb.cpp b/src/mpb.cpp index c379f37f7..c3ce09d8e 100644 --- a/src/mpb.cpp +++ b/src/mpb.cpp @@ -862,7 +862,6 @@ void fields::get_eigenmode_coefficients(dft_flux flux, const volume &eig_vol, in double *cscale, direction d, diffractedplanewave *dp) { int num_freqs = flux.freq.size(); bool match_frequency = true; - if (flux.use_symmetry && S.multiplicity() > 1 && parity == 0) abort("flux regions for eigenmode projection with symmetry should be created by " "add_mode_monitor()"); @@ -878,7 +877,7 @@ void fields::get_eigenmode_coefficients(dft_flux flux, const volume &eig_vol, in /*--------------------------------------------------------------*/ /*- call mpb to compute the eigenmode --------------------------*/ /*--------------------------------------------------------------*/ - int band_num = bands[nb]; + int band_num = bands ? bands[nb] : 1; double kdom[3]; if (user_kpoint_func) kpoint = user_kpoint_func(flux.freq[nf], band_num, user_kpoint_data); am_now_working_on(MPBTime); From ec238dcf8212dca03fe80029e59e336998d77b53 Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Fri, 21 Aug 2020 22:16:58 -0700 Subject: [PATCH 04/15] only set kperp when computing diffracted orders and fix get_eigenmode header for non-MPB builds --- src/mpb.cpp | 64 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/src/mpb.cpp b/src/mpb.cpp index c3ce09d8e..6ecacd7ba 100644 --- a/src/mpb.cpp +++ b/src/mpb.cpp @@ -600,26 +600,60 @@ void *fields::get_eigenmode(double frequency, direction d, const volume where, c } while (match_frequency && fabs(sqrt(eigvals[band_num - 1]) - frequency) > frequency * match_tol); - if (am_master() && dp) { + if (dp) { scalar_complex s = {real(dp->get_s()),imag(dp->get_s())}; scalar_complex p = {real(dp->get_p()),imag(dp->get_p())}; - master_printf("diffracted planewave: k = %g, %g, %g for omega = %g\n", k[0],k[1],k[2], frequency); - update_maxwell_data_k(mdata, k, G[0], G[1], G[2]); - maxwell_set_planewave(mdata, H, band_num, dp->get_g(), s, p, dp->get_axis()); + // compute sum of (kparallel+G)^2 in all the periodic directions + double k2sum = 0; + LOOP_OVER_DIRECTIONS(v.dim, dd) { + double ktmp = 0; + int m = 0; + if ((float(eig_vol.in_direction(dd)) == float(v.in_direction(dd))) && + (boundaries[High][dd] == Periodic && boundaries[Low][dd] == Periodic)) { + m = dp->get_g()[dd - X]; + ktmp = k[dd - X] + m/v.in_direction(dd); + k2sum += ktmp*ktmp; + } + } - eigvals[band_num - 1] = frequency; + // compute kperp (if it is non evanescent) OR + // frequency from kperp^2 and sum of (kparallel+G)^2 + LOOP_OVER_DIRECTIONS(v.dim, dd) { + if ((float(eig_vol.in_direction(dd)) != float(v.in_direction(dd))) && + (boundaries[High][dd] == Periodic && boundaries[Low][dd] == Periodic)) { + if (match_frequency) { + vec cen = eig_vol.center(); + double nn = sqrt(real(get_eps(cen, frequency)) * real(get_mu(cen, frequency))); + double k2 = frequency*frequency*nn*nn - k2sum; + if (k2 < 0) + return NULL; + else if (k2 > 0) + k[dd - X] = sqrt(k2); + } + else + frequency = sqrt(k[dd - X]*k[dd - X] + k2sum); + } + } - evectmatrix_resize(&W[0], 1, 0); - evectmatrix_resize(&W[1], 1, 0); - for (int i = 0; i < H.n; ++i) - W[0].data[i] = H.data[H.p - 1 + i * H.p]; - maxwell_ucross_op(W[0], W[1], mdata, kdir); // W[1] = (dTheta/dk) W[0] - mpb_real vscratch; - evectmatrix_XtY_diag_real(W[0], W[1], &vgrp, &vscratch); - vgrp /= sqrt(eigvals[band_num - 1]); + if (am_master()) { + master_printf("diffracted planewave: k = %g, %g, %g for omega = %g\n", k[0],k[1],k[2], frequency); + update_maxwell_data_k(mdata, k, G[0], G[1], G[2]); + maxwell_set_planewave(mdata, H, band_num, dp->get_g(), s, p, dp->get_axis()); - master_printf("diffracted planewave: group velocity v=%g\n", vgrp); + eigvals[band_num - 1] = frequency; + + evectmatrix_resize(&W[0], 1, 0); + evectmatrix_resize(&W[1], 1, 0); + for (int i = 0; i < H.n; ++i) + W[0].data[i] = H.data[H.p - 1 + i * H.p]; + maxwell_ucross_op(W[0], W[1], mdata, kdir); // W[1] = (dTheta/dk) W[0] + mpb_real vscratch; + evectmatrix_XtY_diag_real(W[0], W[1], &vgrp, &vscratch); + vgrp /= sqrt(eigvals[band_num - 1]); + + master_printf("diffracted planewave: group velocity v=%g\n", vgrp); + } } double eigval = eigvals[band_num - 1]; @@ -938,7 +972,7 @@ void fields::get_eigenmode_coefficients(dft_flux flux, const volume &eig_vol, in void *fields::get_eigenmode(double frequency, direction d, const volume where, const volume eig_vol, int band_num, const vec &kpoint, bool match_frequency, int parity, double resolution, double eigensolver_tol, double *kdom, - void **user_mdata) { + void **user_mdata, diffractedplanewave *dp) { (void)frequency; (void)d; From 3d641acc6956d2c23bf21d7c760ef975a1dcb76e Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Fri, 21 Aug 2020 23:21:24 -0700 Subject: [PATCH 05/15] add missing header for get_eigenmode_coefficients for non-MPB build --- src/mpb.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mpb.cpp b/src/mpb.cpp index 6ecacd7ba..6ebb33ca2 100644 --- a/src/mpb.cpp +++ b/src/mpb.cpp @@ -309,7 +309,7 @@ diffractedplanewave::diffractedplanewave(int g_[3], double axis_[3], std::comple /* routine to allow it to be followed either by */ /* (a) add_eigenmode_src() */ /* or */ -/* (b) get_eigenmode_coefficient() */ +/* (b) get_eigenmode_coefficients() */ /* */ /* the return value is an opaque pointer to an eigenmode_data */ /* structure (needs to be opaque to allow compilation without */ @@ -986,6 +986,7 @@ void *fields::get_eigenmode(double frequency, direction d, const volume where, c (void)eigensolver_tol; (void)kdom; (void)user_mdata; + (voi)dp; abort("Meep must be configured/compiled with MPB for get_eigenmode"); } @@ -1015,7 +1016,7 @@ void fields::get_eigenmode_coefficients(dft_flux flux, const volume &eig_vol, in double eigensolver_tol, std::complex *coeffs, double *vgrp, kpoint_func user_kpoint_func, void *user_kpoint_data, vec *kpoints, vec *kdom, - double *cscale, direction d) { + double *cscale, direction d, diffractedplanewave *dp) { (void)flux; (void)eig_vol; (void)bands; @@ -1031,7 +1032,8 @@ void fields::get_eigenmode_coefficients(dft_flux flux, const volume &eig_vol, in (void)kdom; (void)cscale; (void)d; - abort("Meep must be configured/compiled with MPB for get_eigenmode_coefficient"); + (void)dp; + abort("Meep must be configured/compiled with MPB for get_eigenmode_coefficients"); } void destroy_eigenmode_data(void *vedata, bool destroy_mdata) { From 93c087e09eb73b7e8a51bc44a8a17896054816ac Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Fri, 21 Aug 2020 23:22:23 -0700 Subject: [PATCH 06/15] typo --- src/mpb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpb.cpp b/src/mpb.cpp index 6ebb33ca2..222e14cff 100644 --- a/src/mpb.cpp +++ b/src/mpb.cpp @@ -986,7 +986,7 @@ void *fields::get_eigenmode(double frequency, direction d, const volume where, c (void)eigensolver_tol; (void)kdom; (void)user_mdata; - (voi)dp; + (void)dp; abort("Meep must be configured/compiled with MPB for get_eigenmode"); } From 0c1f74be037857d2274308a64c340d750cbfa385 Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Sat, 22 Aug 2020 09:44:27 -0700 Subject: [PATCH 07/15] SWIG typemap for diffraction order input parameter g --- python/meep.i | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/meep.i b/python/meep.i index 951e96e5c..f3c94098b 100644 --- a/python/meep.i +++ b/python/meep.i @@ -1053,6 +1053,14 @@ void _get_gradient(PyObject *grad, PyObject *fields_a, PyObject *fields_f, PyObj // typemaps for diffractedplanewave +%typecheck(SWIG_TYPECHECK_POINTER, fragment="NumPy_Fragments") int g[3] { + $1 = is_array($input); +} + +%typemap(in) int g[3] { + $1 = (int *)array_data($input); +} + %typecheck(SWIG_TYPECHECK_POINTER, fragment="NumPy_Fragments") double axis[3] { $1 = is_array($input); } From 32ea1f4fe8c6beae982b87d289228d1b8b9e454d Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Sat, 22 Aug 2020 10:48:37 -0700 Subject: [PATCH 08/15] rename parameter s to spol to resolve name conflict with Scheme intersect_ray_with_segment argument --- python/meep.i | 8 -------- src/meep.hpp | 2 +- src/mpb.cpp | 5 ++++- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/python/meep.i b/python/meep.i index f3c94098b..951e96e5c 100644 --- a/python/meep.i +++ b/python/meep.i @@ -1053,14 +1053,6 @@ void _get_gradient(PyObject *grad, PyObject *fields_a, PyObject *fields_f, PyObj // typemaps for diffractedplanewave -%typecheck(SWIG_TYPECHECK_POINTER, fragment="NumPy_Fragments") int g[3] { - $1 = is_array($input); -} - -%typemap(in) int g[3] { - $1 = (int *)array_data($input); -} - %typecheck(SWIG_TYPECHECK_POINTER, fragment="NumPy_Fragments") double axis[3] { $1 = is_array($input); } diff --git a/src/meep.hpp b/src/meep.hpp index 1ff855d14..878fb23a8 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -1487,7 +1487,7 @@ class chunkloop_field_components { class diffractedplanewave { public: - diffractedplanewave(int g[3], double axis[3], std::complex s, std::complex p); + diffractedplanewave(int g[3], double axis[3], std::complex spol, std::complex ppol); int *get_g() { return g; }; double *get_axis() { return axis; } std::complex get_s() const { return s; }; diff --git a/src/mpb.cpp b/src/mpb.cpp index 222e14cff..24215e8ad 100644 --- a/src/mpb.cpp +++ b/src/mpb.cpp @@ -626,8 +626,11 @@ void *fields::get_eigenmode(double frequency, direction d, const volume where, c vec cen = eig_vol.center(); double nn = sqrt(real(get_eps(cen, frequency)) * real(get_mu(cen, frequency))); double k2 = frequency*frequency*nn*nn - k2sum; - if (k2 < 0) + if (k2 < 0) { + master_printf("WARNING: diffraction order for g=(%d,%d,%d) is evanescent!\n", + dp->get_axis()[0],dp->get_axis()[1],dp->get_axis()[2]); return NULL; + } else if (k2 > 0) k[dd - X] = sqrt(k2); } From 91b93ed80574dde76b8a69f881588f14131be983 Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Sat, 22 Aug 2020 16:05:02 -0700 Subject: [PATCH 09/15] move constructor for diffractedplanewave from mpb.cpp to sources.cpp --- src/meep.hpp | 2 +- src/mpb.cpp | 9 --------- src/sources.cpp | 9 +++++++++ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/meep.hpp b/src/meep.hpp index 878fb23a8..1ff855d14 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -1487,7 +1487,7 @@ class chunkloop_field_components { class diffractedplanewave { public: - diffractedplanewave(int g[3], double axis[3], std::complex spol, std::complex ppol); + diffractedplanewave(int g[3], double axis[3], std::complex s, std::complex p); int *get_g() { return g; }; double *get_axis() { return axis; } std::complex get_s() const { return s; }; diff --git a/src/mpb.cpp b/src/mpb.cpp index 24215e8ad..afa24cf43 100644 --- a/src/mpb.cpp +++ b/src/mpb.cpp @@ -292,15 +292,6 @@ static int nextpow2357(int n) { } } -diffractedplanewave::diffractedplanewave(int g_[3], double axis_[3], std::complex s_, std::complex p_) { - for (int j = 0; j < 3; ++j) { - g[j] = g_[j]; - axis[j] = axis_[j]; - } - s = s_; - p = p_; -}; - /****************************************************************/ /* call MPB to get the band_numth eigenmode at freq frequency. */ /* */ diff --git a/src/sources.cpp b/src/sources.cpp index 583fd4d08..7d032f052 100644 --- a/src/sources.cpp +++ b/src/sources.cpp @@ -682,4 +682,13 @@ void gaussianbeam::get_fields(std::complex *EH, const vec &x) const { EH[5] = H[2] / (Eorig*ZR); } +diffractedplanewave::diffractedplanewave(int g_[3], double axis_[3], std::complex s_, std::complex p_) { + for (int j = 0; j < 3; ++j) { + g[j] = g_[j]; + axis[j] = axis_[j]; + } + s = s_; + p = p_; +}; + } // namespace meep From 83280f41fd6237e538e4c5502a444a4939f6a065 Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Sat, 22 Aug 2020 20:08:38 -0700 Subject: [PATCH 10/15] bug fix in k2sum and add Python test --- python/Makefile.am | 5 +- python/tests/diffracted_planewave.py | 118 +++++++++++++++++++++++++++ src/mpb.cpp | 4 +- 3 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 python/tests/diffracted_planewave.py diff --git a/python/Makefile.am b/python/Makefile.am index f213d3c73..54c3c9f1a 100644 --- a/python/Makefile.am +++ b/python/Makefile.am @@ -18,6 +18,7 @@ endif # WITH_MPI if WITH_MPB BINARY_GRATING_TEST = $(TEST_DIR)/binary_grating.py + DIFFRACTED_PLANEWAVE_TEST = $(TEST_DIR)/diffracted_planewave.py DISPERSIVE_EIGENMODE_TEST = $(TEST_DIR)/dispersive_eigenmode.py KDOM_TEST = $(TEST_DIR)/kdom.py MODE_COEFFS_TEST = $(TEST_DIR)/mode_coeffs.py @@ -25,6 +26,7 @@ if WITH_MPB WVG_SRC_TEST = $(TEST_DIR)/wvg_src.py else BINARY_GRATING_TEST = + DIFFRACTED_PLANEWAVE_TEST = DISPERSIVE_EIGENMODE_TEST = KDOM_TEST = MODE_COEFFS_TEST = @@ -43,9 +45,10 @@ TESTS = \ $(TEST_DIR)/cavity_farfield.py \ $(TEST_DIR)/chunks.py \ $(TEST_DIR)/cyl_ellipsoid.py \ - ${DISPERSIVE_EIGENMODE_TEST} \ $(TEST_DIR)/dft_energy.py \ $(TEST_DIR)/dft_fields.py \ + ${DIFFRACTED_PLANEWAVE_TEST} \ + ${DISPERSIVE_EIGENMODE_TEST} \ $(TEST_DIR)/divide_mpi_processes.py \ $(TEST_DIR)/eigfreq.py \ $(TEST_DIR)/faraday_rotation.py \ diff --git a/python/tests/diffracted_planewave.py b/python/tests/diffracted_planewave.py new file mode 100644 index 000000000..4bfe4ff2d --- /dev/null +++ b/python/tests/diffracted_planewave.py @@ -0,0 +1,118 @@ +from __future__ import division + +import unittest +import meep as mp +import math +import cmath +import numpy as np + +class TestDiffractedPlanewave(unittest.TestCase): + + def run_binary_grating_diffraction(self, gp, gh, gdc, theta, bands, orders): + + resolution = 25 # pixels/μm + + dpml = 1.0 # PML thickness + dsub = 3.0 # substrate thickness + dpad = 3.0 # length of padding between grating and PML + + sx = dpml+dsub+gh+dpad+dpml + sy = gp + + cell_size = mp.Vector3(sx,sy,0) + pml_layers = [mp.PML(thickness=dpml,direction=mp.X)] + + wvl = 0.5 # center wavelength + fcen = 1/wvl # center frequency + df = 0.05*fcen # frequency width + + ng = 1.5 + glass = mp.Medium(index=ng) + + # rotation angle of incident planewave; counter clockwise (CCW) about Z axis, 0 degrees along +X axis + theta_in = math.radians(theta) + + eig_parity = mp.ODD_Z + + # k (in source medium) with correct length (plane of incidence: XY) + k = mp.Vector3(fcen*ng).rotate(mp.Vector3(z=1), theta_in) + + if theta_in == 0: + k = mp.Vector3() + eig_parity += mp.EVEN_Y + + def pw_amp(k,x0): + def _pw_amp(x): + return cmath.exp(1j*2*math.pi*k.dot(x+x0)) + return _pw_amp + + src_pt = mp.Vector3(-0.5*sx+dpml+0.3*dsub,0,0) + sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df), + component=mp.Ez, + center=src_pt, + size=mp.Vector3(0,sy,0), + amp_func=pw_amp(k,src_pt))] + + sim = mp.Simulation(resolution=resolution, + cell_size=cell_size, + boundary_layers=pml_layers, + k_point=k, + default_material=glass, + sources=sources) + + tran_pt = mp.Vector3(0.5*sx-dpml-0.5*dpad,0,0) + tran_flux = sim.add_flux(fcen, 0, 1, + mp.FluxRegion(center=tran_pt, size=mp.Vector3(0,sy,0))) + + sim.run(until_after_sources=50) + + input_flux = mp.get_fluxes(tran_flux) + + sim.reset_meep() + + geometry = [mp.Block(material=glass, + size=mp.Vector3(dpml+dsub,mp.inf,mp.inf), + center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub),0,0)), + mp.Block(material=glass, + size=mp.Vector3(gh,gdc*gp,mp.inf), + center=mp.Vector3(-0.5*sx+dpml+dsub+0.5*gh,0,0))] + + sim = mp.Simulation(resolution=resolution, + cell_size=cell_size, + boundary_layers=pml_layers, + geometry=geometry, + k_point=k, + sources=sources) + + tran_flux = sim.add_mode_monitor(fcen, 0, 1, + mp.FluxRegion(center=tran_pt, size=mp.Vector3(0,sy,0))) + + sim.run(until_after_sources=100) + + for band_num,diff_order in zip(bands,orders): + res = sim.get_eigenmode_coefficients(tran_flux, + [band_num], + eig_parity=eig_parity) + tran_ref = (0.5 if ((theta_in == 0) and (band_num > 1)) else 1.0)*abs(res.alpha[0,0,0])**2/input_flux[0] + + res = sim.get_eigenmode_coefficients(tran_flux, + mp.DiffractedPlanewave((0,diff_order,0),mp.Vector3(1,1,0),1,0), + eig_parity=eig_parity) + if res is not None: + tran_dp = abs(res.alpha[0,0,0])**2/input_flux[0] + else: + tran_dp = 0 + + err = abs(tran_ref-tran_dp)/tran_ref + print("tran:, {} (band_num), {} (diff_order), {:.8f} (eigensolver), {:.8f} (planewave), {:.8f} (error)".format(band_num,diff_order,tran_ref,tran_dp,err)) + + self.assertAlmostEqual(tran_ref,tran_dp,places=5) + + def test_diffracted_planewave(self): + self.run_binary_grating_diffraction(2.6,0.4,0.6,0,range(1,6),range(0,5)) + self.run_binary_grating_diffraction(2.6,0.4,0.6,13.4,range(1,6),[-2,-1,-3,0,-4]) + self.run_binary_grating_diffraction(10.0,0.5,0.5,0,[2,4,6],[1,3,5]) + self.run_binary_grating_diffraction(10.0,0.5,0.5,10.7,[1,4,8],[-6,-4,-2]) + +if __name__ == '__main__': + unittest.main() diff --git a/src/mpb.cpp b/src/mpb.cpp index afa24cf43..30ed24c6e 100644 --- a/src/mpb.cpp +++ b/src/mpb.cpp @@ -603,7 +603,7 @@ void *fields::get_eigenmode(double frequency, direction d, const volume where, c if ((float(eig_vol.in_direction(dd)) == float(v.in_direction(dd))) && (boundaries[High][dd] == Periodic && boundaries[Low][dd] == Periodic)) { m = dp->get_g()[dd - X]; - ktmp = k[dd - X] + m/v.in_direction(dd); + ktmp = kpoint.in_direction(dd) + m/v.in_direction(dd); k2sum += ktmp*ktmp; } } @@ -619,7 +619,7 @@ void *fields::get_eigenmode(double frequency, direction d, const volume where, c double k2 = frequency*frequency*nn*nn - k2sum; if (k2 < 0) { master_printf("WARNING: diffraction order for g=(%d,%d,%d) is evanescent!\n", - dp->get_axis()[0],dp->get_axis()[1],dp->get_axis()[2]); + dp->get_g()[0],dp->get_g()[1],dp->get_g()[2]); return NULL; } else if (k2 > 0) From bfb3838a92064b8a2fb6a207937dc22a2e5c541b Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Sat, 22 Aug 2020 21:05:59 -0700 Subject: [PATCH 11/15] remove unicode character from Python test --- python/tests/diffracted_planewave.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/tests/diffracted_planewave.py b/python/tests/diffracted_planewave.py index 4bfe4ff2d..207676097 100644 --- a/python/tests/diffracted_planewave.py +++ b/python/tests/diffracted_planewave.py @@ -10,7 +10,7 @@ class TestDiffractedPlanewave(unittest.TestCase): def run_binary_grating_diffraction(self, gp, gh, gdc, theta, bands, orders): - resolution = 25 # pixels/μm + resolution = 25 # pixels/um dpml = 1.0 # PML thickness dsub = 3.0 # substrate thickness @@ -20,7 +20,7 @@ def run_binary_grating_diffraction(self, gp, gh, gdc, theta, bands, orders): sy = gp cell_size = mp.Vector3(sx,sy,0) - pml_layers = [mp.PML(thickness=dpml,direction=mp.X)] + absorber_layers = [mp.Absorber(thickness=dpml,direction=mp.X)] wvl = 0.5 # center wavelength fcen = 1/wvl # center frequency @@ -55,7 +55,7 @@ def _pw_amp(x): sim = mp.Simulation(resolution=resolution, cell_size=cell_size, - boundary_layers=pml_layers, + boundary_layers=absorber_layers, k_point=k, default_material=glass, sources=sources) @@ -79,7 +79,7 @@ def _pw_amp(x): sim = mp.Simulation(resolution=resolution, cell_size=cell_size, - boundary_layers=pml_layers, + boundary_layers=absorber_layers, geometry=geometry, k_point=k, sources=sources) From c4399d565726b3ebd1cb1124b577859edb48c578 Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Sat, 22 Aug 2020 21:45:53 -0700 Subject: [PATCH 12/15] bands parameter of get_eigenmode_coefficients can only be either a list or DiffractedPlanewave object --- python/simulation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/simulation.py b/python/simulation.py index c4ccb95e5..0fdb87ead 100644 --- a/python/simulation.py +++ b/python/simulation.py @@ -3283,7 +3283,7 @@ def get_eigenmode_coefficients(self, flux, bands, eig_parity=mp.NO_PARITY, eig_v if direction is None or direction == mp.AUTOMATIC: direction = flux.normal_direction - if isinstance(bands,(list,range)): + if isinstance(bands, list): num_bands = len(bands) coeffs = np.zeros(2 * num_bands * flux.freq.size(), dtype=np.complex128) vgrp = np.zeros(num_bands * flux.freq.size()) @@ -3303,7 +3303,7 @@ def get_eigenmode_coefficients(self, flux, bands, eig_parity=mp.NO_PARITY, eig_v cscale, direction ) - elif isinstance(bands,DiffractedPlanewave): + elif isinstance(bands, DiffractedPlanewave): num_bands = 1 coeffs = np.zeros(2 * num_bands * flux.freq.size(), dtype=np.complex128) vgrp = np.zeros(num_bands * flux.freq.size()) From de67d18968940224cc2b6e06ff386c59a329d611 Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Sat, 22 Aug 2020 22:31:08 -0700 Subject: [PATCH 13/15] use exception handling for isinstance since Python2 does not recognize range as separate type --- python/simulation.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/python/simulation.py b/python/simulation.py index 0fdb87ead..46fe3d396 100644 --- a/python/simulation.py +++ b/python/simulation.py @@ -3283,7 +3283,12 @@ def get_eigenmode_coefficients(self, flux, bands, eig_parity=mp.NO_PARITY, eig_v if direction is None or direction == mp.AUTOMATIC: direction = flux.normal_direction - if isinstance(bands, list): + try: + bands_list_range = isinstance(bands, (list,range)) + except TypeError: + bands_list_range = isinstance(bands, list) + + if bands_list_range: num_bands = len(bands) coeffs = np.zeros(2 * num_bands * flux.freq.size(), dtype=np.complex128) vgrp = np.zeros(num_bands * flux.freq.size()) From 86acbb4b3025136fb22e4cdfd28e5bb4e7cb3fe1 Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Sun, 23 Aug 2020 13:06:10 -0700 Subject: [PATCH 14/15] eigenvalue is square if eigenfrequency (bug fix for group velocity) --- python/tests/diffracted_planewave.py | 11 +++++------ src/mpb.cpp | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/python/tests/diffracted_planewave.py b/python/tests/diffracted_planewave.py index 207676097..0bfe48fac 100644 --- a/python/tests/diffracted_planewave.py +++ b/python/tests/diffracted_planewave.py @@ -89,22 +89,21 @@ def _pw_amp(x): sim.run(until_after_sources=100) - for band_num,diff_order in zip(bands,orders): + for band,order in zip(bands,orders): res = sim.get_eigenmode_coefficients(tran_flux, - [band_num], + [band], eig_parity=eig_parity) - tran_ref = (0.5 if ((theta_in == 0) and (band_num > 1)) else 1.0)*abs(res.alpha[0,0,0])**2/input_flux[0] + tran_ref = (0.5 if ((theta_in == 0) and (band > 1)) else 1.0)*abs(res.alpha[0,0,0])**2/input_flux[0] res = sim.get_eigenmode_coefficients(tran_flux, - mp.DiffractedPlanewave((0,diff_order,0),mp.Vector3(1,1,0),1,0), - eig_parity=eig_parity) + mp.DiffractedPlanewave((0,order,0),mp.Vector3(1,1,0),1,0)) if res is not None: tran_dp = abs(res.alpha[0,0,0])**2/input_flux[0] else: tran_dp = 0 err = abs(tran_ref-tran_dp)/tran_ref - print("tran:, {} (band_num), {} (diff_order), {:.8f} (eigensolver), {:.8f} (planewave), {:.8f} (error)".format(band_num,diff_order,tran_ref,tran_dp,err)) + print("tran:, {} (band), {} (order), {:.8f} (eigensolver), {:.8f} (planewave), {:.8f} (error)".format(band,order,tran_ref,tran_dp,err)) self.assertAlmostEqual(tran_ref,tran_dp,places=5) diff --git a/src/mpb.cpp b/src/mpb.cpp index 30ed24c6e..088544030 100644 --- a/src/mpb.cpp +++ b/src/mpb.cpp @@ -626,7 +626,7 @@ void *fields::get_eigenmode(double frequency, direction d, const volume where, c k[dd - X] = sqrt(k2); } else - frequency = sqrt(k[dd - X]*k[dd - X] + k2sum); + frequency = sqrt(kpoint.in_direction(dd)*kpoint.in_direction(dd) + k2sum); } } @@ -635,7 +635,7 @@ void *fields::get_eigenmode(double frequency, direction d, const volume where, c update_maxwell_data_k(mdata, k, G[0], G[1], G[2]); maxwell_set_planewave(mdata, H, band_num, dp->get_g(), s, p, dp->get_axis()); - eigvals[band_num - 1] = frequency; + eigvals[band_num - 1] = frequency*frequency; evectmatrix_resize(&W[0], 1, 0); evectmatrix_resize(&W[1], 1, 0); From 05b26dd00379c99bf839e8ef12b217bc50e83948 Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Mon, 24 Aug 2020 11:59:27 -0700 Subject: [PATCH 15/15] remove output for debugging --- python/tests/diffracted_planewave.py | 15 +++++++++++---- src/mpb.cpp | 5 ----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/python/tests/diffracted_planewave.py b/python/tests/diffracted_planewave.py index 0bfe48fac..2b79fc23d 100644 --- a/python/tests/diffracted_planewave.py +++ b/python/tests/diffracted_planewave.py @@ -46,7 +46,7 @@ def _pw_amp(x): return cmath.exp(1j*2*math.pi*k.dot(x+x0)) return _pw_amp - src_pt = mp.Vector3(-0.5*sx+dpml+0.3*dsub,0,0) + src_pt = mp.Vector3(-0.5*sx+dpml,0,0) sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df), component=mp.Ez, center=src_pt, @@ -60,7 +60,7 @@ def _pw_amp(x): default_material=glass, sources=sources) - tran_pt = mp.Vector3(0.5*sx-dpml-0.5*dpad,0,0) + tran_pt = mp.Vector3(0.5*sx-dpml,0,0) tran_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=tran_pt, size=mp.Vector3(0,sy,0))) @@ -93,18 +93,25 @@ def _pw_amp(x): res = sim.get_eigenmode_coefficients(tran_flux, [band], eig_parity=eig_parity) - tran_ref = (0.5 if ((theta_in == 0) and (band > 1)) else 1.0)*abs(res.alpha[0,0,0])**2/input_flux[0] + tran_ref = abs(res.alpha[0,0,0])**2/input_flux[0] + if (theta_in == 0): + tran_ref = 0.5*tran_ref + vg_ref = res.vgrp[0] res = sim.get_eigenmode_coefficients(tran_flux, - mp.DiffractedPlanewave((0,order,0),mp.Vector3(1,1,0),1,0)) + mp.DiffractedPlanewave((0,order,0),mp.Vector3(0,1,0),1,0)) if res is not None: tran_dp = abs(res.alpha[0,0,0])**2/input_flux[0] + if ((theta_in == 0) and (order == 0)): + tran_dp = 0.5*tran_dp else: tran_dp = 0 + vg_dp = res.vgrp[0] err = abs(tran_ref-tran_dp)/tran_ref print("tran:, {} (band), {} (order), {:.8f} (eigensolver), {:.8f} (planewave), {:.8f} (error)".format(band,order,tran_ref,tran_dp,err)) + self.assertAlmostEqual(vg_ref,vg_dp,places=5) self.assertAlmostEqual(tran_ref,tran_dp,places=5) def test_diffracted_planewave(self): diff --git a/src/mpb.cpp b/src/mpb.cpp index 088544030..7c27f3a7c 100644 --- a/src/mpb.cpp +++ b/src/mpb.cpp @@ -631,12 +631,9 @@ void *fields::get_eigenmode(double frequency, direction d, const volume where, c } if (am_master()) { - master_printf("diffracted planewave: k = %g, %g, %g for omega = %g\n", k[0],k[1],k[2], frequency); update_maxwell_data_k(mdata, k, G[0], G[1], G[2]); maxwell_set_planewave(mdata, H, band_num, dp->get_g(), s, p, dp->get_axis()); - eigvals[band_num - 1] = frequency*frequency; - evectmatrix_resize(&W[0], 1, 0); evectmatrix_resize(&W[1], 1, 0); for (int i = 0; i < H.n; ++i) @@ -645,8 +642,6 @@ void *fields::get_eigenmode(double frequency, direction d, const volume where, c mpb_real vscratch; evectmatrix_XtY_diag_real(W[0], W[1], &vgrp, &vscratch); vgrp /= sqrt(eigvals[band_num - 1]); - - master_printf("diffracted planewave: group velocity v=%g\n", vgrp); } }