From 051e579779e1f725e705e59e90001a2def41ee0d Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 8 May 2019 22:08:26 +0800 Subject: [PATCH 01/61] Implement gyrotropic susceptibility class. --- src/meep.hpp | 23 +++++- src/susceptibility.cpp | 171 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 188 insertions(+), 6 deletions(-) diff --git a/src/meep.hpp b/src/meep.hpp index 7689334e2..2fc6079be 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -223,7 +223,8 @@ class susceptibility { class lorentzian_susceptibility : public susceptibility { public: lorentzian_susceptibility(double omega_0, double gamma, bool no_omega_0_denominator = false) - : omega_0(omega_0), gamma(gamma), no_omega_0_denominator(no_omega_0_denominator) {} + : omega_0(omega_0), gamma(gamma), no_omega_0_denominator(no_omega_0_denominator), + have_gyrotropy(false) {} virtual susceptibility *clone() const { return new lorentzian_susceptibility(*this); } virtual ~lorentzian_susceptibility() {} @@ -249,6 +250,7 @@ class lorentzian_susceptibility : public susceptibility { protected: double omega_0, gamma; bool no_omega_0_denominator; + bool have_gyrotropy; // whether to assign an extra slot for gyrotropy calculations }; /* like a Lorentzian susceptibility, but the polarization equation @@ -272,6 +274,25 @@ class noisy_lorentzian_susceptibility : public lorentzian_susceptibility { double noise_amp; }; +/* like a Lorentzian susceptibility, but with precession around a bias vector */ +class gyrotropic_susceptibility : public lorentzian_susceptibility { +public: + gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma, + bool no_omega_0_denominator = true); + virtual susceptibility *clone() const { return new gyrotropic_susceptibility(*this); } + + virtual void update_P(realnum *W[NUM_FIELD_COMPONENTS][2], + realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, + const grid_volume &gv, void *P_internal_data) const; + + virtual void dump_params(h5file *h5f, size_t *start); + virtual int get_num_params() { return 7; } + +protected: + vec bias; + double gyro_tensor[3][3]; +}; + class multilevel_susceptibility : public susceptibility { public: multilevel_susceptibility() : L(0), T(0), Gamma(0), N0(0), alpha(0), omega(0), gamma(0) {} diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index d45034352..774357612 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -92,6 +92,7 @@ typedef struct { size_t ntot; realnum *P[NUM_FIELD_COMPONENTS][2]; realnum *P_prev[NUM_FIELD_COMPONENTS][2]; + realnum *P_tmp[NUM_FIELD_COMPONENTS][2]; // extra slot used for gyrotropic medium updating realnum data[1]; } lorentzian_data; @@ -100,8 +101,9 @@ typedef struct { void *lorentzian_susceptibility::new_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv) const { int num = 0; + int nslots = have_gyrotropy ? 3 : 2; FOR_COMPONENTS(c) DOCMP2 { - if (needs_P(c, cmp, W)) num += 2 * gv.ntot(); + if (needs_P(c, cmp, W)) num += nslots * gv.ntot(); } size_t sz = sizeof(lorentzian_data) + sizeof(realnum) * (num - 1); lorentzian_data *d = (lorentzian_data *)malloc(sz); @@ -119,12 +121,18 @@ void lorentzian_susceptibility::init_internal_data(realnum *W[NUM_FIELD_COMPONEN size_t ntot = d->ntot = gv.ntot(); realnum *P = d->data; realnum *P_prev = d->data + ntot; + realnum *P_tmp = have_gyrotropy ? P_prev + ntot : NULL; + int nslots = have_gyrotropy ? 3 : 2; + FOR_COMPONENTS(c) DOCMP2 { if (needs_P(c, cmp, W)) { d->P[c][cmp] = P; d->P_prev[c][cmp] = P_prev; - P += 2 * ntot; - P_prev += 2 * ntot; + d->P_tmp[c][cmp] = P_tmp; + + P += nslots * ntot; + P_prev += nslots * ntot; + if (have_gyrotropy) P_tmp += nslots * ntot; } } } @@ -137,12 +145,17 @@ void *lorentzian_susceptibility::copy_internal_data(void *data) const { size_t ntot = d->ntot; realnum *P = dnew->data; realnum *P_prev = dnew->data + ntot; + realnum *P_tmp = have_gyrotropy ? P_prev + ntot : NULL; + int nslots = have_gyrotropy ? 3 : 2; + FOR_COMPONENTS(c) DOCMP2 { if (d->P[c][cmp]) { dnew->P[c][cmp] = P; dnew->P_prev[c][cmp] = P_prev; - P += 2 * ntot; - P_prev += 2 * ntot; + dnew->P_tmp[c][cmp] = P_tmp; + P += nslots * ntot; + P_prev += nslots * ntot; + if (have_gyrotropy) P_tmp += nslots * ntot; } } return (void *)dnew; @@ -321,4 +334,152 @@ void noisy_lorentzian_susceptibility::dump_params(h5file *h5f, size_t *start) { h5f->write_chunk(1, start, params_dims, params_data); *start += num_params; } + + +gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma, + bool no_omega_0_denominator) + : lorentzian_susceptibility(omega_0, gamma, no_omega_0_denominator), bias(bias) { + have_gyrotropy = true; + + // Precalculate g_{ij} = sum_k epsilon_{ijk} b_k, used in update_P. + memset(gyro_tensor, 0, 9 * sizeof(double)); + gyro_tensor[X][Y] = bias.z(); gyro_tensor[Y][X] = -bias.z(); + gyro_tensor[Y][Z] = bias.x(); gyro_tensor[Z][Y] = -bias.x(); + gyro_tensor[Z][X] = bias.y(); gyro_tensor[X][Z] = -bias.y(); +} + +void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], + realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, + const grid_volume &gv, void *P_internal_data) const { + lorentzian_data *d = (lorentzian_data *)P_internal_data; + const double omega2pi = 2 * pi * omega_0, g2pi = gamma * 2 * pi; + const double omega0dtsqr = omega2pi * omega2pi * dt * dt; + const double gamma1 = (1 - g2pi * dt / 2); + const double omega0dtsqr_denom = no_omega_0_denominator ? 0 : omega0dtsqr; + (void)W_prev; // unused; + + FOR_COMPONENTS(c) DOCMP2 { + if (d->P[c][cmp]) { + const direction d0 = component_direction(c); + const realnum *w = W[c][cmp], *s = sigma[c][d0]; + if (w && s) { + if (d0 != X && d0 != Y && d0 != Z) + abort("Cylindrical coordinates are not supported for gyrotropic media"); + + const realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; + realnum *rhs = d->P_tmp[c][cmp]; + + const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); + + direction d1 = cycle_direction(gv.dim, d0, 1); + component c1 = direction_component(c, d1); + ptrdiff_t is1 = gv.stride(d1) * (is_magnetic(c) ? -1 : +1); + const realnum *w1 = W[c1][cmp]; + const realnum *s1 = w1 ? sigma[c][d1] : NULL; + + direction d2 = cycle_direction(gv.dim, d0, 2); + component c2 = direction_component(c, d2); + ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); + const realnum *w2 = W[c2][cmp]; + const realnum *s2 = w2 ? sigma[c][d2] : NULL; + + // Off-diagonal polarization components + const realnum *pp1 = d->P_prev[c1][cmp]; + const realnum *pp2 = d->P_prev[c2][cmp]; + const realnum g1 = pi * dt * gyro_tensor[d0][d1]; + const realnum g2 = pi * dt * gyro_tensor[d0][d2]; + + if (s2 && !s1) { // make s1 the non-NULL one if possible + SWAP(direction, d1, d2); + SWAP(component, c1, c2); + SWAP(ptrdiff_t, is1, is2); + SWAP(const realnum *, w1, w2); + SWAP(const realnum *, s1, s2); + } + if (s1 && s2) { // 3x3 anisotropic + LOOP_OVER_VOL_OWNED(gv, c, i) { + if (s[i] != 0) { + rhs[i] = (2 - omega0dtsqr_denom) * p[i] + + omega0dtsqr * (s[i] * w[i] + + OFFDIAG(s1, w1, is1, is) + + OFFDIAG(s2, w2, is2, is)) + - gamma1 * pp[i]; + if (pp1) rhs[i] -= g1 * pp1[i]; + if (pp2) rhs[i] -= g2 * pp2[i]; + } + } + } else if (s1) { // 2x2 anisotropic + LOOP_OVER_VOL_OWNED(gv, c, i) { + if (s[i] != 0) { + rhs[i] = (2 - omega0dtsqr_denom) * p[i] + + omega0dtsqr * (s[i] * w[i] + OFFDIAG(s1, w1, is1, is)) + - gamma1 * pp[i]; + if (pp1) rhs[i] -= g1 * pp1[i]; + if (pp2) rhs[i] -= g2 * pp2[i]; + } + } + } else { // isotropic + LOOP_OVER_VOL_OWNED(gv, c, i) { + rhs[i] = (2 - omega0dtsqr_denom) * p[i] + + omega0dtsqr * (s[i] * w[i]) - gamma1 * pp[i]; + if (pp1) rhs[i] -= g1 * pp1[i]; + if (pp2) rhs[i] -= g2 * pp2[i]; + } + } + } + } + } + + // Perform 3x3 matrix inversion, exploiting skew symmetry + const double g2 = (1 + g2pi * dt / 2); + const double gx = pi * dt * gyro_tensor[Y][Z]; + const double gy = pi * dt * gyro_tensor[Z][X]; + const double gz = pi * dt * gyro_tensor[X][Y]; + const double invdet = 1.0 / g2 / (g2*g2 + gx*gx + gy*gy + gz*gz); + double inv[3][3]; + + inv[X][X] = invdet * (g2*g2 + gx*gx); + inv[Y][Y] = invdet * (g2*g2 + gy*gy); + inv[Z][Z] = invdet * (g2*g2 + gz*gz); + + inv[X][Y] = invdet * (gx*gy + g2*gz); + inv[Y][X] = invdet * (gy*gx - g2*gz); + inv[Z][X] = invdet * (gz*gx + g2*gy); + inv[X][Z] = invdet * (gx*gz - g2*gy); + inv[Y][Z] = invdet * (gy*gz + g2*gx); + inv[Z][Y] = invdet * (gz*gy - g2*gx); + + FOR_COMPONENTS(c) DOCMP2 { + if (d->P[c][cmp]) { + const direction d0 = component_direction(c); + if (W[c][cmp] && sigma[c][d0]) { + realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp], *rhs = d->P_tmp[c][cmp]; + const direction d1 = cycle_direction(gv.dim, d0, 1); + const direction d2 = cycle_direction(gv.dim, d0, 2); + const component c1 = direction_component(c, d1); + const component c2 = direction_component(c, d2); + const realnum *rhs1 = W[c1][cmp] ? d->P_tmp[c1][cmp] : NULL; + const realnum *rhs2 = W[c2][cmp] ? d->P_tmp[c2][cmp] : NULL; + + LOOP_OVER_VOL_OWNED(gv, c, i) { + pp[i] = p[i]; + p[i] = inv[d0][d0] * rhs[i]; + if (rhs1) p[i] += inv[d0][d1] * rhs1[i]; + if (rhs2) p[i] += inv[d0][d2] * rhs2[i]; + } + } + } + } +} + +void gyrotropic_susceptibility::dump_params(h5file *h5f, size_t *start) { + size_t num_params = 8; + size_t params_dims[1] = {num_params}; + double params_data[] = { + 7, (double)get_id(), bias.x(), bias.y(), bias.z(), + omega_0, gamma, (double)no_omega_0_denominator}; + h5f->write_chunk(1, start, params_dims, params_data); + *start += num_params; +} + } // namespace meep From c068942ea4c389d8d9b281f481dae1a956ed2622 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 8 May 2019 22:08:52 +0800 Subject: [PATCH 02/61] Add Python and Scheme support for gyrotropic media. --- python/geom.py | 12 ++++++++++++ python/meep.i | 2 ++ python/typemap_utils.cpp | 14 ++++++++++++++ scheme/meep.scm.in | 4 ++++ scheme/structure.cpp | 10 ++++++++++ src/material_data.hpp | 1 + src/meepgeom.cpp | 8 +++++++- 7 files changed, 50 insertions(+), 1 deletion(-) diff --git a/python/geom.py b/python/geom.py index a3dc12715..e4d8fec14 100644 --- a/python/geom.py +++ b/python/geom.py @@ -280,6 +280,18 @@ def __init__(self, noise_amp=0.0, **kwargs): super(NoisyDrudeSusceptibility, self).__init__(**kwargs) self.noise_amp = noise_amp +class GyrotropicLorentzianSusceptibility(LorentzianSusceptibility): + + def __init__(self, bias=Vector3(0, 0, 1), **kwargs): + super(GyrotropicLorentzianSusceptibility, self).__init__(**kwargs) + self.bias = bias + +class GyrotropicDrudeSusceptibility(DrudeSusceptibility): + + def __init__(self, bias=Vector3(), **kwargs): + super(GyrotropicDrudeSusceptibility, self).__init__(**kwargs) + self.bias = bias + class MultilevelAtom(Susceptibility): diff --git a/python/meep.i b/python/meep.i index 12a020f52..998f13133 100644 --- a/python/meep.i +++ b/python/meep.i @@ -1371,6 +1371,8 @@ PyObject *_get_array_slice_dimensions(meep::fields *f, const meep::volume &where Ellipsoid, FreqRange, GeometricObject, + GyrotropicDrudeSusceptibility, + GyrotropicLorentzianSusceptibility, Lattice, LorentzianSusceptibility, Matrix, diff --git a/python/typemap_utils.cpp b/python/typemap_utils.cpp index dc0b2e253..a639370c1 100644 --- a/python/typemap_utils.cpp +++ b/python/typemap_utils.cpp @@ -469,6 +469,20 @@ static PyObject *susceptibility_to_py_obj(susceptibility_struct *s) { res = PyObject_Call(py_lorentz_class, args, NULL); Py_DECREF(py_lorentz_class); } + } else if (s->bias.x || s->bias.y || s->bias.z) { + if (s->drude) { + PyObject *py_gyrotropic_drude_class = PyObject_GetAttrString(geom_mod, "GyrotropicDrudeSusceptibility"); + res = PyObject_Call(py_gyrotropic_drude_class, args, NULL); + Py_DECREF(py_gyrotropic_drude_class); + } else { + PyObject *py_gyrotropic_lorentz_class = + PyObject_GetAttrString(geom_mod, "GyrotropicLorentzianSusceptibility"); + res = PyObject_Call(py_gyrotropic_lorentz_class, args, NULL); + Py_DECREF(py_gyrotropic_lorentz_class); + } + PyObject *py_bias = vec2py(vector3_to_vec(s->bias)); + PyObject_SetAttrString(res, "bias", py_bias); + Py_DECREF(py_bias); } else { if (s->drude) { PyObject *py_noisy_drude_class = PyObject_GetAttrString(geom_mod, "NoisyDrudeSusceptibility"); diff --git a/scheme/meep.scm.in b/scheme/meep.scm.in index a4ea946bd..cfec58b06 100644 --- a/scheme/meep.scm.in +++ b/scheme/meep.scm.in @@ -57,6 +57,10 @@ (define-property noise-amp no-default 'number)) (define-class noisy-drude-susceptibility drude-susceptibility (define-property noise-amp no-default 'number)) +(define-class gyrotropic-lorentzian-susceptibility lorentzian-susceptibility + (define-property bias no-default 'vector3)) +(define-class gyrotropic-drude-susceptibility drude-susceptibility + (define-property bias no-default 'vector3)) (define polarizability lorentzian-susceptibility) ; backwards compat (define omega frequency) ; backwards compat diff --git a/scheme/structure.cpp b/scheme/structure.cpp index 43c8f49a2..068915971 100644 --- a/scheme/structure.cpp +++ b/scheme/structure.cpp @@ -1295,6 +1295,11 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) master_printf("noisy lorentzian susceptibility: frequency=%g, gamma=%g, amp = %g\n", d->frequency, d->gamma, nd->noise_amp); sus = new meep::noisy_lorentzian_susceptibility(nd->noise_amp, d->frequency, d->gamma); + } else if (d->which_subclass == lorentzian_susceptibility::GYROTROPIC_LORENTZIAN_SUSCEPTIBILITY) { + gyrotropic_lorentzian_susceptibility *gd = d->subclass.gyrotropic_lorentzian_susceptibility_data; + master_printf("gyrotropic lorentzian susceptibility: bias=(%g,%g,%g), frequency=%g, gamma=%g\n", + gd->bias.x, gd->bias.y, gd->bias.z, d->frequency, d->gamma); + sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma); } else { // just a Lorentzian master_printf("lorentzian susceptibility: frequency=%g, gamma=%g\n", d->frequency, d->gamma); @@ -1310,6 +1315,11 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) d->frequency, d->gamma, nd->noise_amp); sus = new meep::noisy_lorentzian_susceptibility(nd->noise_amp, d->frequency, d->gamma, true); + } else if (d->which_subclass == drude_susceptibility::GYROTROPIC_DRUDE_SUSCEPTIBILITY) { + gyrotropic_drude_susceptibility *gd = d->subclass.gyrotropic_drude_susceptibility_data; + master_printf("gyrotropic drude susceptibility: bias=(%g,%g,%g), frequency=%g, gamma=%g\n", + gd->bias.x, gd->bias.y, gd->bias.z, d->frequency, d->gamma); + sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma, true); } else { // just a Drude master_printf("drude susceptibility: frequency=%g, gamma=%g\n", d->frequency, d->gamma); sus = new meep::lorentzian_susceptibility(d->frequency, d->gamma, true); diff --git a/src/material_data.hpp b/src/material_data.hpp index 0610d7fdb..352b6155e 100644 --- a/src/material_data.hpp +++ b/src/material_data.hpp @@ -59,6 +59,7 @@ struct transition { typedef struct susceptibility_struct { vector3 sigma_offdiag; vector3 sigma_diag; + vector3 bias; double frequency; double gamma; double noise_amp; diff --git a/src/meepgeom.cpp b/src/meepgeom.cpp index 3c2ad82dd..e1cb860b6 100644 --- a/src/meepgeom.cpp +++ b/src/meepgeom.cpp @@ -1363,6 +1363,7 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) susceptibility *ss = &(p->user_s); if (ss->is_file) meep::abort("unknown susceptibility"); bool noisy = (ss->noise_amp != 0.0); + bool gyrotropic = (ss->bias.x != 0.0 || ss->bias.y != 0.0 || ss->bias.z != 0.0); meep::susceptibility *sus; if (ss->transitions.size() != 0 || ss->initial_populations.size() != 0) { @@ -1373,12 +1374,17 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) if (noisy) { sus = new meep::noisy_lorentzian_susceptibility(ss->noise_amp, ss->frequency, ss->gamma, ss->drude); + } else if (gyrotropic) { + sus = new meep::gyrotropic_susceptibility(vector3_to_vec(ss->bias), ss->frequency, + ss->gamma, ss->drude); } else { sus = new meep::lorentzian_susceptibility(ss->frequency, ss->gamma, ss->drude); } - master_printf("%s%s susceptibility: frequency=%g, gamma=%g", noisy ? "noisy " : "", + master_printf("%s%s susceptibility: frequency=%g, gamma=%g", + noisy ? "noisy " : gyrotropic ? "gyrotropic" : "", ss->drude ? "drude" : "lorentzian", ss->frequency, ss->gamma); if (noisy) master_printf(" amp=%g ", ss->noise_amp); + if (gyrotropic) master_printf(" bias=(%g,%g,%g) ", ss->bias.x, ss->bias.y, ss->bias.z); master_printf("\n"); } From 374335841b66c1ce87c967e827ae6f8c1c3857ff Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 9 May 2019 17:13:34 +0800 Subject: [PATCH 03/61] Initialize bias vector in python susceptibility struct. --- python/typemap_utils.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python/typemap_utils.cpp b/python/typemap_utils.cpp index a639370c1..dea028d1d 100644 --- a/python/typemap_utils.cpp +++ b/python/typemap_utils.cpp @@ -330,6 +330,7 @@ static int py_susceptibility_to_susceptibility(PyObject *po, susceptibility_stru s->frequency = 0; s->gamma = 0; s->noise_amp = 0; + s->bias.x = s->bias.y = s->bias.z = 0; s->transitions.resize(0); s->initial_populations.resize(0); @@ -345,6 +346,10 @@ static int py_susceptibility_to_susceptibility(PyObject *po, susceptibility_stru if (!get_attr_dbl(po, &s->noise_amp, "noise_amp")) { return 0; } } + if (PyObject_HasAttrString(po, "bias")) { + if (!get_attr_v3(po, &s->bias, "bias")) return 0; + } + if (PyObject_HasAttrString(po, "transitions")) { // MultilevelAtom PyObject *py_trans = PyObject_GetAttrString(po, "transitions"); From 88ea6ca4ba400648c8991dce7b5cd1c2b6e1ce25 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 10 May 2019 10:36:47 +0800 Subject: [PATCH 04/61] Remove "bias" from gyrotropic_susceptibility; the information is already in gyro_tensor. --- src/meep.hpp | 1 - src/susceptibility.cpp | 28 ++++++++++++++-------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/meep.hpp b/src/meep.hpp index 2fc6079be..c03283e09 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -289,7 +289,6 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { virtual int get_num_params() { return 7; } protected: - vec bias; double gyro_tensor[3][3]; }; diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 774357612..3b7289c32 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -338,7 +338,7 @@ void noisy_lorentzian_susceptibility::dump_params(h5file *h5f, size_t *start) { gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma, bool no_omega_0_denominator) - : lorentzian_susceptibility(omega_0, gamma, no_omega_0_denominator), bias(bias) { + : lorentzian_susceptibility(omega_0, gamma, no_omega_0_denominator) { have_gyrotropy = true; // Precalculate g_{ij} = sum_k epsilon_{ijk} b_k, used in update_P. @@ -431,23 +431,22 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], } // Perform 3x3 matrix inversion, exploiting skew symmetry - const double g2 = (1 + g2pi * dt / 2); + const double gd = (1 + g2pi * dt / 2); const double gx = pi * dt * gyro_tensor[Y][Z]; const double gy = pi * dt * gyro_tensor[Z][X]; const double gz = pi * dt * gyro_tensor[X][Y]; - const double invdet = 1.0 / g2 / (g2*g2 + gx*gx + gy*gy + gz*gz); + const double invdet = 1.0 / gd / (gd*gd + gx*gx + gy*gy + gz*gz); double inv[3][3]; - inv[X][X] = invdet * (g2*g2 + gx*gx); - inv[Y][Y] = invdet * (g2*g2 + gy*gy); - inv[Z][Z] = invdet * (g2*g2 + gz*gz); - - inv[X][Y] = invdet * (gx*gy + g2*gz); - inv[Y][X] = invdet * (gy*gx - g2*gz); - inv[Z][X] = invdet * (gz*gx + g2*gy); - inv[X][Z] = invdet * (gx*gz - g2*gy); - inv[Y][Z] = invdet * (gy*gz + g2*gx); - inv[Z][Y] = invdet * (gz*gy - g2*gx); + inv[X][X] = invdet * (gd*gd + gx*gx); + inv[Y][Y] = invdet * (gd*gd + gy*gy); + inv[Z][Z] = invdet * (gd*gd + gz*gz); + inv[X][Y] = invdet * (gx*gy + gd*gz); + inv[Y][X] = invdet * (gy*gx - gd*gz); + inv[Z][X] = invdet * (gz*gx + gd*gy); + inv[X][Z] = invdet * (gx*gz - gd*gy); + inv[Y][Z] = invdet * (gy*gz + gd*gx); + inv[Z][Y] = invdet * (gz*gy - gd*gx); FOR_COMPONENTS(c) DOCMP2 { if (d->P[c][cmp]) { @@ -475,8 +474,9 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], void gyrotropic_susceptibility::dump_params(h5file *h5f, size_t *start) { size_t num_params = 8; size_t params_dims[1] = {num_params}; + double bias[] = { gyro_tensor[Y][Z], gyro_tensor[Z][X], gyro_tensor[X][Y] }; double params_data[] = { - 7, (double)get_id(), bias.x(), bias.y(), bias.z(), + 7, (double)get_id(), bias[X], bias[Y], bias[Z], omega_0, gamma, (double)no_omega_0_denominator}; h5f->write_chunk(1, start, params_dims, params_data); *start += num_params; From 3115557e5cd2e1453e9d93e0cb2dbdc06ec603e9 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 22 May 2019 13:26:11 +0800 Subject: [PATCH 05/61] Add gyrotropic media to docs --- doc/docs/Materials.md | 25 +++++++++++++++++++++++++ doc/docs/Python_User_Interface.md | 8 ++++++++ 2 files changed, 33 insertions(+) diff --git a/doc/docs/Materials.md b/doc/docs/Materials.md index c71885402..882e1a76a 100644 --- a/doc/docs/Materials.md +++ b/doc/docs/Materials.md @@ -167,6 +167,31 @@ $$ \mathbf{E} \; (\textrm{SALT}) = \frac{2 |\theta|}{\hbar \sqrt{\gamma_\perp \g For a two level gain medium, $\gamma_\parallel = \gamma_{12} + \gamma_{21}$. For more details on applying SALT to atomic media with an arbitrary number of levels, see [Optics Express, Vol. 23, pp. 6455-77, 2015](https://www.osapublishing.org/oe/abstract.cfm?uri=oe-23-5-6455). +Gyrotropic Media +---------------- + +(**Experimental feature**) Meep supports gyrotropic media, which break optical reciprocity and give rise to magneto-optical phenomena such as the [Faraday effect](https://en.wikipedia.org/wiki/Faraday_effect). Such materials are used in devices like [Faraday rotators](https://en.wikipedia.org/wiki/Faraday_rotator). The following discussion concerns a medium with gyrotropic ε (i.e., a gyroelectric medium). Gyromagnetic media can be treated by the usual substitution of ε with μ, **E** with **H**, etc. + +In a gyroelectric medium, the equation of motion of the polarization vector $\mathbf{P}_n$ is very similar to the [Drude-Lorentz](Materials.md#material-dispersion) case, but contains an additional precession term: + +$$\frac{d^2\mathbf{P}_n}{dt^2} + \gamma_n \frac{d\mathbf{P}_n}{dt} + \mathbf{b}_n \times \frac{d\mathbf{P}_n}{dt} + \omega_n^2 \mathbf{P}_n = \sigma_n(\mathbf{x}) \omega_n^2 \mathbf{E}$$ + +(Optionally, the polarization may be of Drude form, in which case the final $\omega_n^2 \mathbf{P}_n$ term on the left-hand side is omitted; we will describe the Lorentz case.) The third term on the left-hand side breaks time-reversal symmetry and describes the gyrotropy of the medium, parameterized by the bias vector $\mathbf{b}_n$ (usually describing the effect of an applied static magnetic field). In the absence of damping ($\gamma = 0$) and coupling to the electric field ($\sigma_n = 0$), the equation of motion reduces to a precession around $\mathbf{b}_n$, with angular frequency equal to $|\mathbf{b}_n|$: + +$$\frac{d\mathbf{P}_n}{dt} = \mathbf{P}_n \times \mathbf{b}_n$$ + +In the frequency domain, gyrotropy corresponds to the presence of imaginary off-diagonal components in the ε tensor (or the μ tensor for a gyromagnetic medium). Take the case $\mathbf{b} = b \hat{z}$. When all fields have harmonic time-dependence $\exp(-i\omega t)$, the polarization equation of motion reduces to + +$$\mathbf{P}_n = \chi_n \mathbf{E}, \quad \chi_n = \frac{\omega_n^2}{\omega_n^2 - \omega^2 + i\omega\gamma_n} \begin{bmatrix}\xi & -i\eta & 0 \\ i\eta & \xi & 0 \\ 0 & 0 & 1 \end{bmatrix} \, \sigma_n(\mathbf{x})$$ + +where + +$$\xi = \frac{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 + \omega^2 b^2}\,, \quad \eta = \frac{\omega b (\omega_n^2 - \omega^2 - i\omega \gamma_n)}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 + \omega^2 b^2}$$ + +It is common to operate in a limit where the gyrotropy is weak relative to the frequency detuning, but strong relative to the loss. Let $\omega_n = \omega + \Delta\omega_n$, where $\gamma_n \ll b \ll \Delta \omega_n \ll \omega$. Then the above susceptibility tensor simplifies to + +$$\chi_n \approx \frac{\omega}{2 \Delta\omega_n} \begin{bmatrix}1 & -i\eta & 0 \\ i\eta & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}\, \sigma_n(\mathbf{x}), \quad \eta = \frac{b}{2\Delta\omega_n}$$ + Materials Library ----------------- diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index 88b0050e6..0b0ef0cf1 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -392,6 +392,14 @@ The noise has root-mean square amplitude σ $\times$ `noise_amp`. This is a somewhat unusual polarizable medium, a Lorentzian susceptibility with a random noise term added into the damped-oscillator equation at each point. This can be used to directly model thermal radiation in both the [far field](http://journals.aps.org/prl/abstract/10.1103/PhysRevLett.93.213905) and the [near field](http://math.mit.edu/~stevenj/papers/RodriguezIl11.pdf). Note, however that it is more efficient to [compute far-field thermal radiation using Kirchhoff's law](http://www.simpetus.com/projects.html#meep_thermal_radiation) of radiation, which states that emissivity equals absorptivity. Near-field thermal radiation can usually be computed more efficiently using frequency-domain methods, e.g. via [SCUFF-EM](https://github.com/HomerReid/scuff-em), as described e.g. [here](http://doi.org/10.1103/PhysRevB.92.134202) or [here](http://doi.org/10.1103/PhysRevB.88.054305). +### GyrotropicLorentzianSusceptibility or GyrotropicDrudeSusceptibility + +(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility of Lorentzian (damped harmonic oscillator) or Drude form. See [Material Dispersion](Materials.md#gyrotropic-media), with the same `sigma`, `frequency`, and `gamma` parameters, but with an additional 3-vector `bias`: + +**`bias` [`Vector3`]** +— +The gyrotropy vector. The direction of this vector determines the orientation of the gyrotropic response, and the magnitude equals the precession frequency $|\mathbf{b}_n|/2\pi$. + ### Vector3 Properties: From c0b5939bc20d69d97f809b3fafbe09ea00f8a561 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 22 May 2019 13:29:25 +0800 Subject: [PATCH 06/61] Minor copyedit --- doc/docs/Python_User_Interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index 0b0ef0cf1..11f3b3f28 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -394,7 +394,7 @@ This is a somewhat unusual polarizable medium, a Lorentzian susceptibility with ### GyrotropicLorentzianSusceptibility or GyrotropicDrudeSusceptibility -(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility of Lorentzian (damped harmonic oscillator) or Drude form. See [Material Dispersion](Materials.md#gyrotropic-media), with the same `sigma`, `frequency`, and `gamma` parameters, but with an additional 3-vector `bias`: +(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility of Lorentzian (damped harmonic oscillator) or Drude form. See [Material Dispersion](Materials.md#gyrotropic-media). The parameters `sigma`, `frequency`, and `gamma` have the usual meanings, and there is an additional 3-vector `bias`: **`bias` [`Vector3`]** — From 9e595d0f53d49fe273a56409123821e84220aa58 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 22 May 2019 20:36:26 +0800 Subject: [PATCH 07/61] Fix logic in py_susceptibility_to_susceptibility --- python/typemap_utils.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/python/typemap_utils.cpp b/python/typemap_utils.cpp index dea028d1d..e5d569bae 100644 --- a/python/typemap_utils.cpp +++ b/python/typemap_utils.cpp @@ -464,17 +464,7 @@ static PyObject *susceptibility_to_py_obj(susceptibility_struct *s) { PyObject *res; PyObject *args = PyTuple_New(0); - if (s->noise_amp == 0) { - if (s->drude) { - PyObject *py_drude_class = PyObject_GetAttrString(geom_mod, "DrudeSusceptibility"); - res = PyObject_Call(py_drude_class, args, NULL); - Py_DECREF(py_drude_class); - } else { - PyObject *py_lorentz_class = PyObject_GetAttrString(geom_mod, "LorentzianSusceptibility"); - res = PyObject_Call(py_lorentz_class, args, NULL); - Py_DECREF(py_lorentz_class); - } - } else if (s->bias.x || s->bias.y || s->bias.z) { + if (s->bias.x || s->bias.y || s->bias.z) { if (s->drude) { PyObject *py_gyrotropic_drude_class = PyObject_GetAttrString(geom_mod, "GyrotropicDrudeSusceptibility"); res = PyObject_Call(py_gyrotropic_drude_class, args, NULL); @@ -488,6 +478,16 @@ static PyObject *susceptibility_to_py_obj(susceptibility_struct *s) { PyObject *py_bias = vec2py(vector3_to_vec(s->bias)); PyObject_SetAttrString(res, "bias", py_bias); Py_DECREF(py_bias); + } else if (s->noise_amp == 0) { + if (s->drude) { + PyObject *py_drude_class = PyObject_GetAttrString(geom_mod, "DrudeSusceptibility"); + res = PyObject_Call(py_drude_class, args, NULL); + Py_DECREF(py_drude_class); + } else { + PyObject *py_lorentz_class = PyObject_GetAttrString(geom_mod, "LorentzianSusceptibility"); + res = PyObject_Call(py_lorentz_class, args, NULL); + Py_DECREF(py_lorentz_class); + } } else { if (s->drude) { PyObject *py_noisy_drude_class = PyObject_GetAttrString(geom_mod, "NoisyDrudeSusceptibility"); From 074ecf097bc2c35491d71e3312a5e9421fc05f04 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 23 May 2019 00:07:42 +0800 Subject: [PATCH 08/61] In add_susceptibilities, always pass a 3-vector as gyrotropic bias --- src/meepgeom.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/meepgeom.cpp b/src/meepgeom.cpp index e1cb860b6..d42c2aec6 100644 --- a/src/meepgeom.cpp +++ b/src/meepgeom.cpp @@ -1375,16 +1375,16 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) sus = new meep::noisy_lorentzian_susceptibility(ss->noise_amp, ss->frequency, ss->gamma, ss->drude); } else if (gyrotropic) { - sus = new meep::gyrotropic_susceptibility(vector3_to_vec(ss->bias), ss->frequency, + sus = new meep::gyrotropic_susceptibility(meep::vec(ss->bias.x, ss->bias.y, ss->bias.z), ss->frequency, ss->gamma, ss->drude); } else { sus = new meep::lorentzian_susceptibility(ss->frequency, ss->gamma, ss->drude); } master_printf("%s%s susceptibility: frequency=%g, gamma=%g", - noisy ? "noisy " : gyrotropic ? "gyrotropic" : "", + noisy ? "noisy " : gyrotropic ? "gyrotropic " : "", ss->drude ? "drude" : "lorentzian", ss->frequency, ss->gamma); - if (noisy) master_printf(" amp=%g ", ss->noise_amp); - if (gyrotropic) master_printf(" bias=(%g,%g,%g) ", ss->bias.x, ss->bias.y, ss->bias.z); + if (noisy) master_printf(", amp=%g ", ss->noise_amp); + if (gyrotropic) master_printf(", bias=(%g,%g,%g) ", ss->bias.x, ss->bias.y, ss->bias.z); master_printf("\n"); } From 579b76d331fe8739cbd72e6f24453bfe4e8b6e24 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 23 May 2019 09:17:32 +0800 Subject: [PATCH 09/61] First try at gyrotropic media tutorial --- doc/docs/Materials.md | 4 +- doc/docs/Python_Tutorials/Gyrotropic_Media.md | 121 ++++++++++++++++++ 2 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 doc/docs/Python_Tutorials/Gyrotropic_Media.md diff --git a/doc/docs/Materials.md b/doc/docs/Materials.md index 882e1a76a..12c03b61b 100644 --- a/doc/docs/Materials.md +++ b/doc/docs/Materials.md @@ -182,11 +182,11 @@ $$\frac{d\mathbf{P}_n}{dt} = \mathbf{P}_n \times \mathbf{b}_n$$ In the frequency domain, gyrotropy corresponds to the presence of imaginary off-diagonal components in the ε tensor (or the μ tensor for a gyromagnetic medium). Take the case $\mathbf{b} = b \hat{z}$. When all fields have harmonic time-dependence $\exp(-i\omega t)$, the polarization equation of motion reduces to -$$\mathbf{P}_n = \chi_n \mathbf{E}, \quad \chi_n = \frac{\omega_n^2}{\omega_n^2 - \omega^2 + i\omega\gamma_n} \begin{bmatrix}\xi & -i\eta & 0 \\ i\eta & \xi & 0 \\ 0 & 0 & 1 \end{bmatrix} \, \sigma_n(\mathbf{x})$$ +$$\mathbf{P}_n = \chi_n \mathbf{E}, \quad \chi_n = \frac{\omega_n^2}{\omega_n^2 - \omega^2 - i\omega\gamma_n} \begin{bmatrix}\xi & -i\eta & 0 \\ i\eta & \xi & 0 \\ 0 & 0 & 1 \end{bmatrix} \, \sigma_n(\mathbf{x})$$ where -$$\xi = \frac{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 + \omega^2 b^2}\,, \quad \eta = \frac{\omega b (\omega_n^2 - \omega^2 - i\omega \gamma_n)}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 + \omega^2 b^2}$$ +$$\xi = \frac{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 - \omega^2 b^2}\,, \quad \eta = \frac{\omega b (\omega_n^2 - \omega^2 - i\omega \gamma_n)}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 - \omega^2 b^2}$$ It is common to operate in a limit where the gyrotropy is weak relative to the frequency detuning, but strong relative to the loss. Let $\omega_n = \omega + \Delta\omega_n$, where $\gamma_n \ll b \ll \Delta \omega_n \ll \omega$. Then the above susceptibility tensor simplifies to diff --git a/doc/docs/Python_Tutorials/Gyrotropic_Media.md b/doc/docs/Python_Tutorials/Gyrotropic_Media.md new file mode 100644 index 000000000..b67fb0afc --- /dev/null +++ b/doc/docs/Python_Tutorials/Gyrotropic_Media.md @@ -0,0 +1,121 @@ +--- +# Gyrotropic media +--- + +In this example, we will perform simulations with a gyrotropic medium. See [Materials](../Materials.md#gyrotropic-media) for more information on how gyrotropy is supported. + +[TOC] + +### Dispersion Relation for a Gyrotropic Medium + +Here, we model a uniform gyrotroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. For TE modes, the electric field lies in the *x*-*y* plane and magnetic field pointing along *z*, with the wavevector $\mathbf{k}$ in the *x*-*y* plane. The dispersion relation can be shown to be + +$$\omega = v(\omega) |\mathbf{k}|, \quad v^2 = \mu^{-1} \left[\epsilon^{-1}\right]_{xx}$$ + +The ε tensor is given by + +$$\epsilon = \epsilon_\infty + \frac{\omega_n^2}{\omega_n^2 - \omega^2 - i\omega\gamma_n} \begin{bmatrix}\xi & -i\eta & 0 \\ i\eta & \xi & 0 \\ 0 & 0 & 1 \end{bmatrix} \, \sigma_n(\mathbf{x}),$$ + +with + +$$\xi = \frac{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 + \omega^2 b^2}\,, \quad \eta = \frac{\omega b (\omega_n^2 - \omega^2 - i\omega \gamma_n)}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 + \omega^2 b^2}$$ + +We choose the material parameters $\epsilon_\infty = 1$, $f_n = 1.2$, $\gamma_n = 10^{-5}$, and $\sigma_n = 0.1$, with $|\mathbf{b}_n|$ ranging from zero to $10^{-2}$. + + + + +From the dispersion relation ω(k), we will compute the numerical ε(ω) via the formula: + +$$\varepsilon(\omega) = \left( \frac{ck}{\omega} \right) ^2$$ + +We will then compare this with the analytical ε(ω) that we specified. The simulation script is in [material-dispersion.py](https://github.com/NanoComp/meep/blob/master/python/examples/material-dispersion.py). + +Since this is a uniform medium, our computational cell can actually be of *zero* size (i.e. one pixel), where we will use Bloch-periodic boundary conditions to specify the wavevector *k*. + +```py +cell = mp.Vector3() +resolution = 20 +``` + +We will then fill all space with an artificial dispersive material: + +```py +susceptibilities = [mp.LorentzianSusceptibility(frequency=1.1, gamma=1e-5, sigma=0.5), + mp.LorentzianSusceptibility(frequency=0.5, gamma=0.1, sigma=2e-5)] + +default_material = mp.Medium(epsilon=2.25, E_susceptibilities=susceptibilities) +``` + +corresponding to the dielectric function: + +$$\varepsilon(\omega) = \varepsilon(2\pi f) = 2.25 + \frac{1.1^2 \cdot 0.5}{1.1^2 - f^2 -if \cdot 10^{-5}/2\pi} + \frac{0.5^2 \cdot 2\cdot 10^{-5}}{0.5^2 - f^2 -if \cdot 0.1 / 2\pi}$$ + +The real and imaginary parts of this dielectric function ε(ω) are plotted below: + +
+![](../images/Material-dispersion-eps.png) +
+ +We can see that the f=1.1 resonance causes a large change in both the real and imaginary parts of ε around that frequency. In fact, there is a range of frequencies from 1.1 to 1.2161 where ε is *negative*. In this range, no propagating modes exist — it is actually a kind of electromagnetic band gap associated with polariton resonances in a material. For more information on the physics of such materials, see e.g. Chapter 14 of [Introduction to Solid State Physics](http://www.wiley.com/WileyCDA/WileyTitle/productCd-EHEP000803.html) by C. Kittel. + +On the other hand, the f=0.5 resonance, because the `sigma` numerator is so small, causes very little change in the real part of ε. Nevertheless, it generates a clear peak in the *imaginary* part of ε, corresponding to a resonant absorption peak. + +Now, we'll set up the rest of the simulation. We'll specify a broadband $E_z$-polarized Gaussian source, create a list of *k* wavevectors that we want to compute ω(k) over, and compute the associated frequencies by using the `k_points` function: + +```py +fcen = 1.0 +df = 2.0 + +sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3())] + +kmin = 0.3 +kmax = 2.2 +k_interp = 99 + +kpts = mp.interpolate(k_interp, [mp.Vector3(kmin), mp.Vector3(kmax)]) + +sim = mp.Simulation(cell_size=cell, geometry=[], sources=sources, default_material=default_material, resolution=resolution) + +all_freqs = sim.run_k_points(200, kpts) # a list of lists of frequencies +``` + +The `run_k_points` function returns a *list of lists* of frequencies — one list of complex frequencies for each *k* point — which we store in the `all_freqs` variable. Finally, we want to loop over this list and print out the corresponding ε via the ratio (ck/ω)$^2$ as described above. To do this, we will use Python's `zip` function which combines multiple lists into one: + +```py +for fs, kx in zip(all_freqs, [v.x for v in kpts]): + for f in fs: + print("eps:, {.6f}, {.6f}, {.6f}".format(f.real, f.imag, (kx / f)**2)) +``` + +Alternatively we could just read all of the frequencies into Python or Octave/Matlab and compute the ratios there. After running the program with + +```sh +unix% python -u material-dispersion.py | tee material-dispersion.out +``` + +we can then `grep` for the frequencies and the computed dielectric function, and plot it. First, let's plot the dispersion relation ω(k) for the real part of ω: + +
+![](../images/Material-dispersion-bands.png) +
+ +The red circles are the computed points from Meep, whereas the blue line is the analytical band diagram from the specified ε(ω). As you can see, we get *two* bands at each *k*, separated by a polaritonic gap (shaded yellow). This dispersion relation can be thought of as the interaction (anti-crossing) between the light line of the ambient ε=2.25 material (dashed black line) and the horizontal line corresponding to the phonon resonance. + +Similarly, the computed and analytical real parts of the dielectric function are given by: + +
+![](../images/Material-dispersion-epsre.png) +
+ +which shows excellent agreement between the analytical (blue line) and numerical (red circles) calculations. The imaginary part, however, is more subtle: + +
+![](../images/Material-dispersion-epsim.png) +
+ +The blue line is the analytical calculation from above and the red circles are the numerical value from Meep — why is the agreement so poor? There is nothing wrong with Meep, and this is *not* a numerical error. The problem is simply that we are comparing apples and oranges. + +The blue line is the analytical calculation of ε(ω) for a *real* frequency ω which corresponds to solutions with a *complex* wavevector *k*, whereas Meep is computing ε at a *complex* ω for a *real* wavevector *k*. So, the correct comparison is to plug Meep's *complex* ω into the analytical formula for ε(ω), which results in the green lines on the graph that fall almost on top of the red circles. + +Why did our comparison of the *real* part of ε look so good, then? The reason is that ε(ω) at real and complex values of ω are closely related by the analytic properties of ε. In particular, because ε is an analytic function on the real-ω axis, adding a *small* imaginary part to ω as we are doing here does not change ε by much. The losses are small for all of the computed *k* points. The change was only significant for the imaginary ε because the imaginary ε was small to begin with. From afd8583485670b0c0dccba2b72e2c77066827527 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 23 May 2019 13:37:39 +0800 Subject: [PATCH 10/61] Fix errors in gyrotropy formulas in notes --- doc/docs/Materials.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/docs/Materials.md b/doc/docs/Materials.md index 12c03b61b..d6316aa3b 100644 --- a/doc/docs/Materials.md +++ b/doc/docs/Materials.md @@ -176,21 +176,21 @@ In a gyroelectric medium, the equation of motion of the polarization vector $\ma $$\frac{d^2\mathbf{P}_n}{dt^2} + \gamma_n \frac{d\mathbf{P}_n}{dt} + \mathbf{b}_n \times \frac{d\mathbf{P}_n}{dt} + \omega_n^2 \mathbf{P}_n = \sigma_n(\mathbf{x}) \omega_n^2 \mathbf{E}$$ -(Optionally, the polarization may be of Drude form, in which case the final $\omega_n^2 \mathbf{P}_n$ term on the left-hand side is omitted; we will describe the Lorentz case.) The third term on the left-hand side breaks time-reversal symmetry and describes the gyrotropy of the medium, parameterized by the bias vector $\mathbf{b}_n$ (usually describing the effect of an applied static magnetic field). In the absence of damping ($\gamma = 0$) and coupling to the electric field ($\sigma_n = 0$), the equation of motion reduces to a precession around $\mathbf{b}_n$, with angular frequency equal to $|\mathbf{b}_n|$: +(Optionally, the polarization may be of Drude form, in which case the $\omega_n^2 \mathbf{P}_n$ term on the left-hand side is omitted.) The third term on the left-hand side breaks time-reversal symmetry and describes the gyrotropy of the medium; it is parameterized by the bias vector $\mathbf{b}_n$, usually describing the effect of an applied static magnetic field. In the $\gamma_n = \omega_n = 0$ limit, the equation of motion reduces to a precession around $\mathbf{b}_n$, with angular frequency equal to $|\mathbf{b}_n|$: $$\frac{d\mathbf{P}_n}{dt} = \mathbf{P}_n \times \mathbf{b}_n$$ -In the frequency domain, gyrotropy corresponds to the presence of imaginary off-diagonal components in the ε tensor (or the μ tensor for a gyromagnetic medium). Take the case $\mathbf{b} = b \hat{z}$. When all fields have harmonic time-dependence $\exp(-i\omega t)$, the polarization equation of motion reduces to +In the frequency domain, a gyroelectric medium has imaginary off-diagonal components in the ε tensor. Take the case $\mathbf{b} = b \hat{z}$. When all fields have harmonic time-dependence $\exp(-i\omega t)$, the polarization equation of motion reduces to -$$\mathbf{P}_n = \chi_n \mathbf{E}, \quad \chi_n = \frac{\omega_n^2}{\omega_n^2 - \omega^2 - i\omega\gamma_n} \begin{bmatrix}\xi & -i\eta & 0 \\ i\eta & \xi & 0 \\ 0 & 0 & 1 \end{bmatrix} \, \sigma_n(\mathbf{x})$$ +$$\mathbf{P}_n = \chi_n \mathbf{E}, \quad \chi_n = \omega_n^2 \begin{bmatrix}\xi_\perp & -i\eta & 0 \\ i\eta & \xi_\perp & 0 \\ 0 & 0 & \xi_\parallel \end{bmatrix} \, \sigma_n(\mathbf{x})$$ where -$$\xi = \frac{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 - \omega^2 b^2}\,, \quad \eta = \frac{\omega b (\omega_n^2 - \omega^2 - i\omega \gamma_n)}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 - \omega^2 b^2}$$ +$$\xi_\perp = \frac{\Delta_n}{\Delta_n^2 - \omega^2 b^2}\,,\;\;\; \xi_\parallel = \frac{1}{\Delta_n}, \;\;\; \eta = \frac{\omega b}{\Delta_n^2 - \omega^2 b^2}, \;\;\;\Delta_n \equiv \omega_n^2 - \omega^2 - i\omega\gamma_n$$ -It is common to operate in a limit where the gyrotropy is weak relative to the frequency detuning, but strong relative to the loss. Let $\omega_n = \omega + \Delta\omega_n$, where $\gamma_n \ll b \ll \Delta \omega_n \ll \omega$. Then the above susceptibility tensor simplifies to +In many applications, the gyrotropy is weak relative to the frequency detuning but strong relative to the loss. For this case, we can define $\omega_n = \omega + \Delta\omega_n$, and take $\gamma_n \ll b \ll \Delta \omega_n \ll \omega$. In this limit, the susceptibility tensor reduces to -$$\chi_n \approx \frac{\omega}{2 \Delta\omega_n} \begin{bmatrix}1 & -i\eta & 0 \\ i\eta & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}\, \sigma_n(\mathbf{x}), \quad \eta = \frac{b}{2\Delta\omega_n}$$ +$$\chi_n \approx \frac{\omega}{2\Delta\omega_n} \begin{bmatrix}1 & -ib/2\Delta\omega_n & 0 \\ ib/2\Delta\omega_n & 1 & 0 \\ 0 & 0 & 1\end{bmatrix} \sigma_n(\mathbf{x})$$ Materials Library ----------------- From 69a302b8691bbf1d88936e30ebe58822b05e70dc Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 23 May 2019 23:08:54 +0800 Subject: [PATCH 11/61] Re-implemention of gyrotropy using LLG equation --- doc/docs/Materials.md | 20 +++-- python/geom.py | 14 +--- python/meep.i | 15 ++-- python/typemap_utils.cpp | 24 +++--- scheme/meep.scm.in | 7 +- scheme/structure.cpp | 18 ++--- src/material_data.hpp | 1 + src/meep.hpp | 12 ++- src/meepgeom.cpp | 11 ++- src/susceptibility.cpp | 165 +++++++++++++++------------------------ 10 files changed, 118 insertions(+), 169 deletions(-) diff --git a/doc/docs/Materials.md b/doc/docs/Materials.md index d6316aa3b..0205127b2 100644 --- a/doc/docs/Materials.md +++ b/doc/docs/Materials.md @@ -172,25 +172,23 @@ Gyrotropic Media (**Experimental feature**) Meep supports gyrotropic media, which break optical reciprocity and give rise to magneto-optical phenomena such as the [Faraday effect](https://en.wikipedia.org/wiki/Faraday_effect). Such materials are used in devices like [Faraday rotators](https://en.wikipedia.org/wiki/Faraday_rotator). The following discussion concerns a medium with gyrotropic ε (i.e., a gyroelectric medium). Gyromagnetic media can be treated by the usual substitution of ε with μ, **E** with **H**, etc. -In a gyroelectric medium, the equation of motion of the polarization vector $\mathbf{P}_n$ is very similar to the [Drude-Lorentz](Materials.md#material-dispersion) case, but contains an additional precession term: +In a gyroelectric medium, the equation of motion of the polarization vector $\mathbf{P}_n$ is a variant of the [Landau-Lifshitz-Gilbert equation](https://en.wikipedia.org/wiki/Landau%E2%80%93Lifshitz%E2%80%93Gilbert_equation): -$$\frac{d^2\mathbf{P}_n}{dt^2} + \gamma_n \frac{d\mathbf{P}_n}{dt} + \mathbf{b}_n \times \frac{d\mathbf{P}_n}{dt} + \omega_n^2 \mathbf{P}_n = \sigma_n(\mathbf{x}) \omega_n^2 \mathbf{E}$$ +$$\frac{d\mathbf{P}_n}{dt} = \mathbf{b}_n \times \left( - \sigma_n \mathbf{E} + \omega_n \mathbf{P}_n + \alpha_n \frac{d\mathbf{P}_n}{dt} \right) - \gamma_n \mathbf{P}_n$$ -(Optionally, the polarization may be of Drude form, in which case the $\omega_n^2 \mathbf{P}_n$ term on the left-hand side is omitted.) The third term on the left-hand side breaks time-reversal symmetry and describes the gyrotropy of the medium; it is parameterized by the bias vector $\mathbf{b}_n$, usually describing the effect of an applied static magnetic field. In the $\gamma_n = \omega_n = 0$ limit, the equation of motion reduces to a precession around $\mathbf{b}_n$, with angular frequency equal to $|\mathbf{b}_n|$: +Although this is completely different from the damped harmonic oscillator equation used for [Drude-Lorentz susceptibility](Materials.md#material-dispersion), the constants σ$_n$, ω$_n$, and γ$_n$ play rather analogous roles: σ$_n$ couples the polarization to the electric field, ω$_n$ is the angular frequency of precession, and γ$_n$ is a damping factor. There is also a second damping factor α$_n$, and a "bias vector" **b**$_n$ which typically describes the direction of an applied static magnetic field. The bias vector is assumed to have unit length. -$$\frac{d\mathbf{P}_n}{dt} = \mathbf{P}_n \times \mathbf{b}_n$$ +In the frequency domain, the ε tensor acquires off-diagonal components representing a gyrotropic response. Take the case $\mathbf{b}_n = \hat{\mathbf{z}}$, and assume that all fields have harmonic time-dependence $\exp(-i\omega t)$. The polarization equation then reduces to -In the frequency domain, a gyroelectric medium has imaginary off-diagonal components in the ε tensor. Take the case $\mathbf{b} = b \hat{z}$. When all fields have harmonic time-dependence $\exp(-i\omega t)$, the polarization equation of motion reduces to +$$\mathbf{P}_n = \chi_n \mathbf{E}, \quad \chi_n = \frac{\sigma_n}{(\omega_n - i \omega \alpha_n)^2 - (\omega + i \gamma_n)^2} \begin{bmatrix} \omega_n - i \omega \alpha_n & -i(\omega + i \gamma) & 0 \\ i(\omega + i \gamma) & \omega_n - i \omega \alpha_n & 0 \\ 0 & 0 & 0\end{bmatrix}$$ -$$\mathbf{P}_n = \chi_n \mathbf{E}, \quad \chi_n = \omega_n^2 \begin{bmatrix}\xi_\perp & -i\eta & 0 \\ i\eta & \xi_\perp & 0 \\ 0 & 0 & \xi_\parallel \end{bmatrix} \, \sigma_n(\mathbf{x})$$ +Hence, the dielectric function is -where - -$$\xi_\perp = \frac{\Delta_n}{\Delta_n^2 - \omega^2 b^2}\,,\;\;\; \xi_\parallel = \frac{1}{\Delta_n}, \;\;\; \eta = \frac{\omega b}{\Delta_n^2 - \omega^2 b^2}, \;\;\;\Delta_n \equiv \omega_n^2 - \omega^2 - i\omega\gamma_n$$ +$$\epsilon = \begin{bmatrix} \epsilon_\perp & -i \eta & 0 \\ i\eta & \epsilon_\perp & 0 \\ 0 & 0 & \epsilon_\infty\end{bmatrix}$$ -In many applications, the gyrotropy is weak relative to the frequency detuning but strong relative to the loss. For this case, we can define $\omega_n = \omega + \Delta\omega_n$, and take $\gamma_n \ll b \ll \Delta \omega_n \ll \omega$. In this limit, the susceptibility tensor reduces to +where -$$\chi_n \approx \frac{\omega}{2\Delta\omega_n} \begin{bmatrix}1 & -ib/2\Delta\omega_n & 0 \\ ib/2\Delta\omega_n & 1 & 0 \\ 0 & 0 & 1\end{bmatrix} \sigma_n(\mathbf{x})$$ +$$\epsilon_\perp = \epsilon_\infty + \frac{\sigma_n (\omega_n - i\omega\alpha_n)}{(\omega_n - i \omega \alpha_n)^2 - (\omega + i \gamma_n)^2}, \;\;\; \eta = \frac{\sigma_n (\omega + i\gamma_n)}{(\omega_n - i \omega \alpha_n)^2 - (\omega + i \gamma_n)^2}$$ Materials Library ----------------- diff --git a/python/geom.py b/python/geom.py index e4d8fec14..4101c53e4 100644 --- a/python/geom.py +++ b/python/geom.py @@ -280,18 +280,12 @@ def __init__(self, noise_amp=0.0, **kwargs): super(NoisyDrudeSusceptibility, self).__init__(**kwargs) self.noise_amp = noise_amp -class GyrotropicLorentzianSusceptibility(LorentzianSusceptibility): +class GyrotropicSusceptibility(LorentzianSusceptibility): - def __init__(self, bias=Vector3(0, 0, 1), **kwargs): - super(GyrotropicLorentzianSusceptibility, self).__init__(**kwargs) + def __init__(self, bias=Vector3(0, 0, 1), alpha=0.0, **kwargs): + super(GyrotropicSusceptibility, self).__init__(**kwargs) self.bias = bias - -class GyrotropicDrudeSusceptibility(DrudeSusceptibility): - - def __init__(self, bias=Vector3(), **kwargs): - super(GyrotropicDrudeSusceptibility, self).__init__(**kwargs) - self.bias = bias - + self.alpha = alpha class MultilevelAtom(Susceptibility): diff --git a/python/meep.i b/python/meep.i index 998f13133..d984185d2 100644 --- a/python/meep.i +++ b/python/meep.i @@ -749,21 +749,21 @@ meep::volume_list *make_volume_list(const meep::volume &v, int c, } %typemap(in) const meep::src_time & { - PyObject *swig_obj = NULL; + PyObject *obj = NULL; void *tmp_ptr = 0; int tmp_res = 0; if(PyObject_IsInstance($input, py_source_time_object())) { - swig_obj = PyObject_GetAttrString($input, "swigobj"); + obj = PyObject_GetAttrString($input, "swigobj"); } else if(PyObject_IsInstance($input, py_meep_src_time_object())) { - swig_obj = $input; - Py_XINCREF(swig_obj); + obj = $input; + Py_XINCREF(obj); } else { meep::abort("Expected a meep.source.SourceTime or a meep.src_time\n"); } - tmp_res = SWIG_ConvertPtr(swig_obj, &tmp_ptr, $1_descriptor, 0); - Py_XDECREF(swig_obj); + tmp_res = SWIG_ConvertPtr(obj, &tmp_ptr, $1_descriptor, 0); + Py_XDECREF(obj); if(!SWIG_IsOK(tmp_res)) { SWIG_exception_fail(SWIG_ArgError(tmp_res), "Couldn't convert Python object to meep::src_time"); @@ -1371,8 +1371,7 @@ PyObject *_get_array_slice_dimensions(meep::fields *f, const meep::volume &where Ellipsoid, FreqRange, GeometricObject, - GyrotropicDrudeSusceptibility, - GyrotropicLorentzianSusceptibility, + GyrotropicSusceptibility, Lattice, LorentzianSusceptibility, Matrix, diff --git a/python/typemap_utils.cpp b/python/typemap_utils.cpp index e5d569bae..60d9a776a 100644 --- a/python/typemap_utils.cpp +++ b/python/typemap_utils.cpp @@ -331,6 +331,7 @@ static int py_susceptibility_to_susceptibility(PyObject *po, susceptibility_stru s->gamma = 0; s->noise_amp = 0; s->bias.x = s->bias.y = s->bias.z = 0; + s->alpha = 0; s->transitions.resize(0); s->initial_populations.resize(0); @@ -350,6 +351,10 @@ static int py_susceptibility_to_susceptibility(PyObject *po, susceptibility_stru if (!get_attr_v3(po, &s->bias, "bias")) return 0; } + if (PyObject_HasAttrString(po, "alpha")) { + if (!get_attr_dbl(po, &s->alpha, "alpha")) { return 0; } + } + if (PyObject_HasAttrString(po, "transitions")) { // MultilevelAtom PyObject *py_trans = PyObject_GetAttrString(po, "transitions"); @@ -465,19 +470,18 @@ static PyObject *susceptibility_to_py_obj(susceptibility_struct *s) { PyObject *args = PyTuple_New(0); if (s->bias.x || s->bias.y || s->bias.z) { - if (s->drude) { - PyObject *py_gyrotropic_drude_class = PyObject_GetAttrString(geom_mod, "GyrotropicDrudeSusceptibility"); - res = PyObject_Call(py_gyrotropic_drude_class, args, NULL); - Py_DECREF(py_gyrotropic_drude_class); - } else { - PyObject *py_gyrotropic_lorentz_class = - PyObject_GetAttrString(geom_mod, "GyrotropicLorentzianSusceptibility"); - res = PyObject_Call(py_gyrotropic_lorentz_class, args, NULL); - Py_DECREF(py_gyrotropic_lorentz_class); - } + PyObject *py_gyrotropic_class = PyObject_GetAttrString(geom_mod, "GyrotropicSusceptibility"); + res = PyObject_Call(py_gyrotropic_class, args, NULL); + Py_DECREF(py_gyrotropic_class); + PyObject *py_bias = vec2py(vector3_to_vec(s->bias)); PyObject_SetAttrString(res, "bias", py_bias); Py_DECREF(py_bias); + + PyObject *py_alpha = PyFloat_FromDouble(s->alpha); + PyObject_SetAttrString(res, "alpha", py_alpha); + Py_DECREF(py_alpha); + } else if (s->noise_amp == 0) { if (s->drude) { PyObject *py_drude_class = PyObject_GetAttrString(geom_mod, "DrudeSusceptibility"); diff --git a/scheme/meep.scm.in b/scheme/meep.scm.in index cfec58b06..06f5df939 100644 --- a/scheme/meep.scm.in +++ b/scheme/meep.scm.in @@ -57,10 +57,9 @@ (define-property noise-amp no-default 'number)) (define-class noisy-drude-susceptibility drude-susceptibility (define-property noise-amp no-default 'number)) -(define-class gyrotropic-lorentzian-susceptibility lorentzian-susceptibility - (define-property bias no-default 'vector3)) -(define-class gyrotropic-drude-susceptibility drude-susceptibility - (define-property bias no-default 'vector3)) +(define-class gyrotropic-susceptibility lorentzian-susceptibility + (define-property bias no-default 'vector3) + (define-property alpha no-default 'number)) (define polarizability lorentzian-susceptibility) ; backwards compat (define omega frequency) ; backwards compat diff --git a/scheme/structure.cpp b/scheme/structure.cpp index 068915971..be5b99789 100644 --- a/scheme/structure.cpp +++ b/scheme/structure.cpp @@ -1295,11 +1295,12 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) master_printf("noisy lorentzian susceptibility: frequency=%g, gamma=%g, amp = %g\n", d->frequency, d->gamma, nd->noise_amp); sus = new meep::noisy_lorentzian_susceptibility(nd->noise_amp, d->frequency, d->gamma); - } else if (d->which_subclass == lorentzian_susceptibility::GYROTROPIC_LORENTZIAN_SUSCEPTIBILITY) { - gyrotropic_lorentzian_susceptibility *gd = d->subclass.gyrotropic_lorentzian_susceptibility_data; - master_printf("gyrotropic lorentzian susceptibility: bias=(%g,%g,%g), frequency=%g, gamma=%g\n", - gd->bias.x, gd->bias.y, gd->bias.z, d->frequency, d->gamma); - sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma); + } else if (d->which_subclass == lorentzian_susceptibility::GYROTROPIC_SUSCEPTIBILITY) { + gyrotropic_susceptibility *gd = d->subclass.gyrotropic_susceptibility_data; + master_printf("gyrotropic lorentzian susceptibility: bias=(%g,%g,%g), alpha=%g, frequency=%g, gamma=%g\n", + gd->bias.x, gd->bias.y, gd->bias.z, gd->alpha, d->frequency, d->gamma); + sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), gd->alpha, + d->frequency, d->gamma); } else { // just a Lorentzian master_printf("lorentzian susceptibility: frequency=%g, gamma=%g\n", d->frequency, d->gamma); @@ -1315,12 +1316,7 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) d->frequency, d->gamma, nd->noise_amp); sus = new meep::noisy_lorentzian_susceptibility(nd->noise_amp, d->frequency, d->gamma, true); - } else if (d->which_subclass == drude_susceptibility::GYROTROPIC_DRUDE_SUSCEPTIBILITY) { - gyrotropic_drude_susceptibility *gd = d->subclass.gyrotropic_drude_susceptibility_data; - master_printf("gyrotropic drude susceptibility: bias=(%g,%g,%g), frequency=%g, gamma=%g\n", - gd->bias.x, gd->bias.y, gd->bias.z, d->frequency, d->gamma); - sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma, true); - } else { // just a Drude + } else { // just a Drude master_printf("drude susceptibility: frequency=%g, gamma=%g\n", d->frequency, d->gamma); sus = new meep::lorentzian_susceptibility(d->frequency, d->gamma, true); } diff --git a/src/material_data.hpp b/src/material_data.hpp index 352b6155e..ec5c998c4 100644 --- a/src/material_data.hpp +++ b/src/material_data.hpp @@ -60,6 +60,7 @@ typedef struct susceptibility_struct { vector3 sigma_offdiag; vector3 sigma_diag; vector3 bias; + double alpha; double frequency; double gamma; double noise_amp; diff --git a/src/meep.hpp b/src/meep.hpp index c03283e09..0e0a401dd 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -223,8 +223,7 @@ class susceptibility { class lorentzian_susceptibility : public susceptibility { public: lorentzian_susceptibility(double omega_0, double gamma, bool no_omega_0_denominator = false) - : omega_0(omega_0), gamma(gamma), no_omega_0_denominator(no_omega_0_denominator), - have_gyrotropy(false) {} + : omega_0(omega_0), gamma(gamma), no_omega_0_denominator(no_omega_0_denominator) {} virtual susceptibility *clone() const { return new lorentzian_susceptibility(*this); } virtual ~lorentzian_susceptibility() {} @@ -250,7 +249,6 @@ class lorentzian_susceptibility : public susceptibility { protected: double omega_0, gamma; bool no_omega_0_denominator; - bool have_gyrotropy; // whether to assign an extra slot for gyrotropy calculations }; /* like a Lorentzian susceptibility, but the polarization equation @@ -274,11 +272,10 @@ class noisy_lorentzian_susceptibility : public lorentzian_susceptibility { double noise_amp; }; -/* like a Lorentzian susceptibility, but with precession around a bias vector */ +/* gyrotropic susceptibility */ class gyrotropic_susceptibility : public lorentzian_susceptibility { public: - gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma, - bool no_omega_0_denominator = true); + gyrotropic_susceptibility(const vec &bias, double alpha, double omega_0, double gamma); virtual susceptibility *clone() const { return new gyrotropic_susceptibility(*this); } virtual void update_P(realnum *W[NUM_FIELD_COMPONENTS][2], @@ -286,9 +283,10 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { const grid_volume &gv, void *P_internal_data) const; virtual void dump_params(h5file *h5f, size_t *start); - virtual int get_num_params() { return 7; } + virtual int get_num_params() { return 8; } protected: + double alpha; double gyro_tensor[3][3]; }; diff --git a/src/meepgeom.cpp b/src/meepgeom.cpp index d42c2aec6..a135396c7 100644 --- a/src/meepgeom.cpp +++ b/src/meepgeom.cpp @@ -1375,16 +1375,19 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) sus = new meep::noisy_lorentzian_susceptibility(ss->noise_amp, ss->frequency, ss->gamma, ss->drude); } else if (gyrotropic) { - sus = new meep::gyrotropic_susceptibility(meep::vec(ss->bias.x, ss->bias.y, ss->bias.z), ss->frequency, - ss->gamma, ss->drude); + sus = new meep::gyrotropic_susceptibility(meep::vec(ss->bias.x, ss->bias.y, ss->bias.z), + ss->alpha, ss->frequency, ss->gamma); } else { sus = new meep::lorentzian_susceptibility(ss->frequency, ss->gamma, ss->drude); } master_printf("%s%s susceptibility: frequency=%g, gamma=%g", noisy ? "noisy " : gyrotropic ? "gyrotropic " : "", - ss->drude ? "drude" : "lorentzian", ss->frequency, ss->gamma); + gyrotropic ? "" : ss->drude ? "drude" : "lorentzian", + ss->frequency, ss->gamma); if (noisy) master_printf(", amp=%g ", ss->noise_amp); - if (gyrotropic) master_printf(", bias=(%g,%g,%g) ", ss->bias.x, ss->bias.y, ss->bias.z); + if (gyrotropic) master_printf(", bias=(%g,%g,%g), alpha=%g ", + ss->bias.x, ss->bias.y, ss->bias.z, + ss->alpha); master_printf("\n"); } diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 3b7289c32..76296aea8 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -92,7 +92,6 @@ typedef struct { size_t ntot; realnum *P[NUM_FIELD_COMPONENTS][2]; realnum *P_prev[NUM_FIELD_COMPONENTS][2]; - realnum *P_tmp[NUM_FIELD_COMPONENTS][2]; // extra slot used for gyrotropic medium updating realnum data[1]; } lorentzian_data; @@ -101,9 +100,8 @@ typedef struct { void *lorentzian_susceptibility::new_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv) const { int num = 0; - int nslots = have_gyrotropy ? 3 : 2; FOR_COMPONENTS(c) DOCMP2 { - if (needs_P(c, cmp, W)) num += nslots * gv.ntot(); + if (needs_P(c, cmp, W)) num += 2 * gv.ntot(); } size_t sz = sizeof(lorentzian_data) + sizeof(realnum) * (num - 1); lorentzian_data *d = (lorentzian_data *)malloc(sz); @@ -121,18 +119,12 @@ void lorentzian_susceptibility::init_internal_data(realnum *W[NUM_FIELD_COMPONEN size_t ntot = d->ntot = gv.ntot(); realnum *P = d->data; realnum *P_prev = d->data + ntot; - realnum *P_tmp = have_gyrotropy ? P_prev + ntot : NULL; - int nslots = have_gyrotropy ? 3 : 2; - FOR_COMPONENTS(c) DOCMP2 { if (needs_P(c, cmp, W)) { d->P[c][cmp] = P; d->P_prev[c][cmp] = P_prev; - d->P_tmp[c][cmp] = P_tmp; - - P += nslots * ntot; - P_prev += nslots * ntot; - if (have_gyrotropy) P_tmp += nslots * ntot; + P += 2 * ntot; + P_prev += 2 * ntot; } } } @@ -145,17 +137,12 @@ void *lorentzian_susceptibility::copy_internal_data(void *data) const { size_t ntot = d->ntot; realnum *P = dnew->data; realnum *P_prev = dnew->data + ntot; - realnum *P_tmp = have_gyrotropy ? P_prev + ntot : NULL; - int nslots = have_gyrotropy ? 3 : 2; - FOR_COMPONENTS(c) DOCMP2 { if (d->P[c][cmp]) { dnew->P[c][cmp] = P; dnew->P_prev[c][cmp] = P_prev; - dnew->P_tmp[c][cmp] = P_tmp; - P += nslots * ntot; - P_prev += nslots * ntot; - if (have_gyrotropy) P_tmp += nslots * ntot; + P += 2 * ntot; + P_prev += 2 * ntot; } } return (void *)dnew; @@ -336,16 +323,14 @@ void noisy_lorentzian_susceptibility::dump_params(h5file *h5f, size_t *start) { } -gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma, - bool no_omega_0_denominator) - : lorentzian_susceptibility(omega_0, gamma, no_omega_0_denominator) { - have_gyrotropy = true; +gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double alpha, double omega_0, double gamma) + : lorentzian_susceptibility(omega_0, gamma, false), alpha(alpha) { - // Precalculate g_{ij} = sum_k epsilon_{ijk} b_k, used in update_P. + const vec bn = bias / fmax(abs(bias), 1e-10); // avoid division by zero memset(gyro_tensor, 0, 9 * sizeof(double)); - gyro_tensor[X][Y] = bias.z(); gyro_tensor[Y][X] = -bias.z(); - gyro_tensor[Y][Z] = bias.x(); gyro_tensor[Z][Y] = -bias.x(); - gyro_tensor[Z][X] = bias.y(); gyro_tensor[X][Z] = -bias.y(); + gyro_tensor[X][Y] = bn.z(); gyro_tensor[Y][X] = -bn.z(); + gyro_tensor[Y][Z] = bn.x(); gyro_tensor[Z][Y] = -bn.x(); + gyro_tensor[Z][X] = bn.y(); gyro_tensor[X][Z] = -bn.y(); } void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], @@ -353,9 +338,12 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv, void *P_internal_data) const { lorentzian_data *d = (lorentzian_data *)P_internal_data; const double omega2pi = 2 * pi * omega_0, g2pi = gamma * 2 * pi; - const double omega0dtsqr = omega2pi * omega2pi * dt * dt; - const double gamma1 = (1 - g2pi * dt / 2); - const double omega0dtsqr_denom = no_omega_0_denominator ? 0 : omega0dtsqr; + const double alpha2pi = 2 * pi * alpha; + const double ua = 1 - 0.5 * g2pi * dt; + const double va = alpha2pi - 0.5 * omega2pi * dt; + const double ub = 1 + 0.5 * g2pi * dt; + const double vb = alpha2pi + 0.5 * omega2pi * dt; + (void)W_prev; // unused; FOR_COMPONENTS(c) DOCMP2 { @@ -366,105 +354,74 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], if (d0 != X && d0 != Y && d0 != Z) abort("Cylindrical coordinates are not supported for gyrotropic media"); - const realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; - realnum *rhs = d->P_tmp[c][cmp]; - + const realnum *p = d->P[c][cmp]; + realnum *pp = d->P_prev[c][cmp]; const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); direction d1 = cycle_direction(gv.dim, d0, 1); - component c1 = direction_component(c, d1); - ptrdiff_t is1 = gv.stride(d1) * (is_magnetic(c) ? -1 : +1); - const realnum *w1 = W[c1][cmp]; - const realnum *s1 = w1 ? sigma[c][d1] : NULL; - direction d2 = cycle_direction(gv.dim, d0, 2); + + component c1 = direction_component(c, d1); component c2 = direction_component(c, d2); - ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); + + const realnum *w1 = W[c1][cmp]; const realnum *w2 = W[c2][cmp]; - const realnum *s2 = w2 ? sigma[c][d2] : NULL; // Off-diagonal polarization components - const realnum *pp1 = d->P_prev[c1][cmp]; - const realnum *pp2 = d->P_prev[c2][cmp]; - const realnum g1 = pi * dt * gyro_tensor[d0][d1]; - const realnum g2 = pi * dt * gyro_tensor[d0][d2]; + const realnum *p1 = d->P[c1][cmp]; + const realnum *p2 = d->P[c2][cmp]; - if (s2 && !s1) { // make s1 the non-NULL one if possible - SWAP(direction, d1, d2); - SWAP(component, c1, c2); - SWAP(ptrdiff_t, is1, is2); - SWAP(const realnum *, w1, w2); - SWAP(const realnum *, s1, s2); - } - if (s1 && s2) { // 3x3 anisotropic - LOOP_OVER_VOL_OWNED(gv, c, i) { - if (s[i] != 0) { - rhs[i] = (2 - omega0dtsqr_denom) * p[i] - + omega0dtsqr * (s[i] * w[i] - + OFFDIAG(s1, w1, is1, is) - + OFFDIAG(s2, w2, is2, is)) - - gamma1 * pp[i]; - if (pp1) rhs[i] -= g1 * pp1[i]; - if (pp2) rhs[i] -= g2 * pp2[i]; - } - } - } else if (s1) { // 2x2 anisotropic - LOOP_OVER_VOL_OWNED(gv, c, i) { - if (s[i] != 0) { - rhs[i] = (2 - omega0dtsqr_denom) * p[i] - + omega0dtsqr * (s[i] * w[i] + OFFDIAG(s1, w1, is1, is)) - - gamma1 * pp[i]; - if (pp1) rhs[i] -= g1 * pp1[i]; - if (pp2) rhs[i] -= g2 * pp2[i]; - } - } - } else { // isotropic - LOOP_OVER_VOL_OWNED(gv, c, i) { - rhs[i] = (2 - omega0dtsqr_denom) * p[i] - + omega0dtsqr * (s[i] * w[i]) - gamma1 * pp[i]; - if (pp1) rhs[i] -= g1 * pp1[i]; - if (pp2) rhs[i] -= g2 * pp2[i]; - } - } + const realnum vab1 = va * gyro_tensor[d0][d1]; + const realnum vab2 = va * gyro_tensor[d0][d2]; + + const realnum ndt1 = dt * gyro_tensor[d0][d1]; + const realnum ndt2 = dt * gyro_tensor[d0][d2]; + + LOOP_OVER_VOL_OWNED(gv, c, i) { + pp[i] = ua * p[i]; + if (p1) pp[i] += vab1 * p1[i]; + if (p2) pp[i] += vab2 * p2[i]; + if (w1) pp[i] += ndt1 * s[i] * w1[i]; + if (w2) pp[i] += ndt2 * s[i] * w2[i]; + } } } } // Perform 3x3 matrix inversion, exploiting skew symmetry - const double gd = (1 + g2pi * dt / 2); - const double gx = pi * dt * gyro_tensor[Y][Z]; - const double gy = pi * dt * gyro_tensor[Z][X]; - const double gz = pi * dt * gyro_tensor[X][Y]; - const double invdet = 1.0 / gd / (gd*gd + gx*gx + gy*gy + gz*gz); + const double gx = vb * gyro_tensor[Y][Z]; + const double gy = vb * gyro_tensor[Z][X]; + const double gz = vb * gyro_tensor[X][Y]; + const double invdet = 1.0 / ub / (ub*ub + gx*gx + gy*gy + gz*gz); double inv[3][3]; - inv[X][X] = invdet * (gd*gd + gx*gx); - inv[Y][Y] = invdet * (gd*gd + gy*gy); - inv[Z][Z] = invdet * (gd*gd + gz*gz); - inv[X][Y] = invdet * (gx*gy + gd*gz); - inv[Y][X] = invdet * (gy*gx - gd*gz); - inv[Z][X] = invdet * (gz*gx + gd*gy); - inv[X][Z] = invdet * (gx*gz - gd*gy); - inv[Y][Z] = invdet * (gy*gz + gd*gx); - inv[Z][Y] = invdet * (gz*gy - gd*gx); + inv[X][X] = invdet * (ub*ub + gx*gx); + inv[Y][Y] = invdet * (ub*ub + gy*gy); + inv[Z][Z] = invdet * (ub*ub + gz*gz); + inv[X][Y] = invdet * (gx*gy - ub*gz); + inv[Y][X] = invdet * (gy*gx + ub*gz); + inv[Z][X] = invdet * (gz*gx - ub*gy); + inv[X][Z] = invdet * (gx*gz + ub*gy); + inv[Y][Z] = invdet * (gy*gz - ub*gx); + inv[Z][Y] = invdet * (gz*gy + ub*gx); FOR_COMPONENTS(c) DOCMP2 { if (d->P[c][cmp]) { const direction d0 = component_direction(c); if (W[c][cmp] && sigma[c][d0]) { - realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp], *rhs = d->P_tmp[c][cmp]; + realnum *p = d->P[c][cmp]; + const realnum *pp = d->P_prev[c][cmp]; const direction d1 = cycle_direction(gv.dim, d0, 1); const direction d2 = cycle_direction(gv.dim, d0, 2); const component c1 = direction_component(c, d1); const component c2 = direction_component(c, d2); - const realnum *rhs1 = W[c1][cmp] ? d->P_tmp[c1][cmp] : NULL; - const realnum *rhs2 = W[c2][cmp] ? d->P_tmp[c2][cmp] : NULL; + const realnum *pp1 = W[c1][cmp] ? d->P_prev[c1][cmp] : NULL; + const realnum *pp2 = W[c2][cmp] ? d->P_prev[c2][cmp] : NULL; LOOP_OVER_VOL_OWNED(gv, c, i) { - pp[i] = p[i]; - p[i] = inv[d0][d0] * rhs[i]; - if (rhs1) p[i] += inv[d0][d1] * rhs1[i]; - if (rhs2) p[i] += inv[d0][d2] * rhs2[i]; + p[i] = inv[d0][d0] * pp[i]; + if (pp1) p[i] += inv[d0][d1] * pp1[i]; + if (pp2) p[i] += inv[d0][d2] * pp2[i]; } } } @@ -472,12 +429,12 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], } void gyrotropic_susceptibility::dump_params(h5file *h5f, size_t *start) { - size_t num_params = 8; + size_t num_params = 9; size_t params_dims[1] = {num_params}; double bias[] = { gyro_tensor[Y][Z], gyro_tensor[Z][X], gyro_tensor[X][Y] }; double params_data[] = { - 7, (double)get_id(), bias[X], bias[Y], bias[Z], - omega_0, gamma, (double)no_omega_0_denominator}; + 8, (double)get_id(), bias[X], bias[Y], bias[Z], + alpha, omega_0, gamma, (double)no_omega_0_denominator}; h5f->write_chunk(1, start, params_dims, params_data); *start += num_params; } From 2481e16b7265e30d0dee00989a00e0d9ff193484 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 23 May 2019 23:49:29 +0800 Subject: [PATCH 12/61] Tweak handling of sigma tensor in gyrotropic case --- src/susceptibility.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 76296aea8..895793d5b 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -356,7 +356,6 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const realnum *p = d->P[c][cmp]; realnum *pp = d->P_prev[c][cmp]; - const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); direction d1 = cycle_direction(gv.dim, d0, 1); direction d2 = cycle_direction(gv.dim, d0, 2); @@ -367,7 +366,9 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const realnum *w1 = W[c1][cmp]; const realnum *w2 = W[c2][cmp]; - // Off-diagonal polarization components + const realnum *s1 = w1 ? sigma[c1][d1] : NULL; + const realnum *s2 = w2 ? sigma[c2][d2] : NULL; + const realnum *p1 = d->P[c1][cmp]; const realnum *p2 = d->P[c2][cmp]; @@ -381,8 +382,8 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], pp[i] = ua * p[i]; if (p1) pp[i] += vab1 * p1[i]; if (p2) pp[i] += vab2 * p2[i]; - if (w1) pp[i] += ndt1 * s[i] * w1[i]; - if (w2) pp[i] += ndt2 * s[i] * w2[i]; + if (w1) pp[i] += ndt1 * s1[i] * w1[i]; + if (w2) pp[i] += ndt2 * s2[i] * w2[i]; } } } From d6cc4854dea95e10eaa51ab0d83cdb1e09763133 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 24 May 2019 09:18:42 +0800 Subject: [PATCH 13/61] Update Python doc. --- doc/docs/Python_User_Interface.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index 11f3b3f28..75bb1ae69 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -394,11 +394,27 @@ This is a somewhat unusual polarizable medium, a Lorentzian susceptibility with ### GyrotropicLorentzianSusceptibility or GyrotropicDrudeSusceptibility -(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility of Lorentzian (damped harmonic oscillator) or Drude form. See [Material Dispersion](Materials.md#gyrotropic-media). The parameters `sigma`, `frequency`, and `gamma` have the usual meanings, and there is an additional 3-vector `bias`: +(**Experimental feature**) Specifies a single dispersive [gyrotropic susceptibility](Materials.md#gyrotropic-media) governed by the Landau-Lifshitz-Gilbert equation. Note that the parameters `sigma`, `frequency`, and `gamma` play different roles compared to the Lorentzian or Drude case. + +**`sigma` [`number`]** +— +The scale factor σ specifying the coupling to the driving field. In magnetic ferrites, this is equal to the Larmor precession frequency at magnetic saturation. + +**`frequency` [`number`]** +— +The frequency of gyrotropic precession (Larmor frequency), $f_n = \omega_n / 2\pi$. + +**`gamma` [`number`]** +— +The loss rate $\gamma_n / 2\pi$ in the off-diagonal response. + +**`alpha` [`number`]** +— +The loss rate $\alpha_n / 2\pi$ in the diagonal response. **`bias` [`Vector3`]** — -The gyrotropy vector. The direction of this vector determines the orientation of the gyrotropic response, and the magnitude equals the precession frequency $|\mathbf{b}_n|/2\pi$. +Gyrotropy vector describing the direction of the static biasing magnetic field. The magnitude is ignored. ### Vector3 From 9267c353ba3efa9ffbcc3a59b625d4e48d228bed Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 24 May 2019 09:28:31 +0800 Subject: [PATCH 14/61] Drop 2pi factor from gyrotropic sigma --- doc/docs/Python_User_Interface.md | 4 ++-- src/susceptibility.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index 75bb1ae69..0dc977f35 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -398,11 +398,11 @@ This is a somewhat unusual polarizable medium, a Lorentzian susceptibility with **`sigma` [`number`]** — -The scale factor σ specifying the coupling to the driving field. In magnetic ferrites, this is equal to the Larmor precession frequency at magnetic saturation. +The coupling factor $\sigma_n / 2\pi$ between the polarization and the driving field. In magnetic ferrites, this is the Larmor precession frequency at the saturation field. **`frequency` [`number`]** — -The frequency of gyrotropic precession (Larmor frequency), $f_n = \omega_n / 2\pi$. +The frequency of gyrotropic precession, $f_n = \omega_n / 2\pi$. In magnetic ferrites, this is the Larmor precession frequency. **`gamma` [`number`]** — diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 895793d5b..d8614c1dd 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -349,7 +349,7 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], FOR_COMPONENTS(c) DOCMP2 { if (d->P[c][cmp]) { const direction d0 = component_direction(c); - const realnum *w = W[c][cmp], *s = sigma[c][d0]; + const realnum *w = W[c][cmp], *s = 2*pi*sigma[c][d0]; if (w && s) { if (d0 != X && d0 != Y && d0 != Z) abort("Cylindrical coordinates are not supported for gyrotropic media"); @@ -366,8 +366,8 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const realnum *w1 = W[c1][cmp]; const realnum *w2 = W[c2][cmp]; - const realnum *s1 = w1 ? sigma[c1][d1] : NULL; - const realnum *s2 = w2 ? sigma[c2][d2] : NULL; + const realnum *s1 = w1 ? 2*pi*sigma[c1][d1] : NULL; + const realnum *s2 = w2 ? 2*pi*sigma[c2][d2] : NULL; const realnum *p1 = d->P[c1][cmp]; const realnum *p2 = d->P[c2][cmp]; From 77812cd426a49c0bca39612ba09125a602a6cda5 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 24 May 2019 11:45:16 +0800 Subject: [PATCH 15/61] Doc updates --- doc/docs/Materials.md | 2 +- doc/docs/Python_Tutorials/Gyrotropic_Media.md | 33 ++++++++++++------- doc/docs/Scheme_User_Interface.md | 24 ++++++++++++++ 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/doc/docs/Materials.md b/doc/docs/Materials.md index 0205127b2..c4f60bee8 100644 --- a/doc/docs/Materials.md +++ b/doc/docs/Materials.md @@ -176,7 +176,7 @@ In a gyroelectric medium, the equation of motion of the polarization vector $\ma $$\frac{d\mathbf{P}_n}{dt} = \mathbf{b}_n \times \left( - \sigma_n \mathbf{E} + \omega_n \mathbf{P}_n + \alpha_n \frac{d\mathbf{P}_n}{dt} \right) - \gamma_n \mathbf{P}_n$$ -Although this is completely different from the damped harmonic oscillator equation used for [Drude-Lorentz susceptibility](Materials.md#material-dispersion), the constants σ$_n$, ω$_n$, and γ$_n$ play rather analogous roles: σ$_n$ couples the polarization to the electric field, ω$_n$ is the angular frequency of precession, and γ$_n$ is a damping factor. There is also a second damping factor α$_n$, and a "bias vector" **b**$_n$ which typically describes the direction of an applied static magnetic field. The bias vector is assumed to have unit length. +Although this is completely different from the damped harmonic oscillator equation used for [Drude-Lorentz susceptibility](Materials.md#material-dispersion), the constants σ$_n$, ω$_n$, and γ$_n$ play analogous roles: σ$_n$ couples the polarization to the electric field, ω$_n$ is the angular frequency of precession, and γ$_n$ is a damping factor. There is also a second damping factor α$_n$, and a "bias vector" **b**$_n$ which typically describes the direction of an applied static magnetic field. The bias vector is assumed to have unit length. In the frequency domain, the ε tensor acquires off-diagonal components representing a gyrotropic response. Take the case $\mathbf{b}_n = \hat{\mathbf{z}}$, and assume that all fields have harmonic time-dependence $\exp(-i\omega t)$. The polarization equation then reduces to diff --git a/doc/docs/Python_Tutorials/Gyrotropic_Media.md b/doc/docs/Python_Tutorials/Gyrotropic_Media.md index b67fb0afc..532f506d5 100644 --- a/doc/docs/Python_Tutorials/Gyrotropic_Media.md +++ b/doc/docs/Python_Tutorials/Gyrotropic_Media.md @@ -6,25 +6,39 @@ In this example, we will perform simulations with a gyrotropic medium. See [Mate [TOC] -### Dispersion Relation for a Gyrotropic Medium +## Electromagnetic wave propagation in a ferrite -Here, we model a uniform gyrotroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. For TE modes, the electric field lies in the *x*-*y* plane and magnetic field pointing along *z*, with the wavevector $\mathbf{k}$ in the *x*-*y* plane. The dispersion relation can be shown to be +### Material properties -$$\omega = v(\omega) |\mathbf{k}|, \quad v^2 = \mu^{-1} \left[\epsilon^{-1}\right]_{xx}$$ +Ferrites are ceramic materials exhibiting strong gyromagnetic resonances, commonly used in microwave engineering to construct isolators (one-way valves) and circulators. In the presence of a biasing magnetic field $\mathbf{H} = H_0 \hat{\mathbf{z}}$, the permeability tensor of a ferrite material has the form -The ε tensor is given by +$$\mu = \begin{bmatrix} \mu_\perp & -i \kappa & 0 \\ i\kappa & \mu_\perp & 0 \\ 0 & 0 & 1\end{bmatrix}$$ -$$\epsilon = \epsilon_\infty + \frac{\omega_n^2}{\omega_n^2 - \omega^2 - i\omega\gamma_n} \begin{bmatrix}\xi & -i\eta & 0 \\ i\eta & \xi & 0 \\ 0 & 0 & 1 \end{bmatrix} \, \sigma_n(\mathbf{x}),$$ +where -with +$$\mu_\perp = 1 + \frac{\omega_m (\omega_0 - i\omega\alpha)}{(\omega_0 - i \omega \alpha)^2 - (\omega + i \gamma)^2}, \;\;\; \kappa = \frac{\omega_m (\omega + i\gamma)}{(\omega_0 - i \omega \alpha)^2 - (\omega + i \gamma)^2}$$ -$$\xi = \frac{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 + \omega^2 b^2}\,, \quad \eta = \frac{\omega b (\omega_n^2 - \omega^2 - i\omega \gamma_n)}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 + \omega^2 b^2}$$ +This permeability can be derived from the [Landau-Lifshitz-Gilbert equation](https://en.wikipedia.org/wiki/Landau%E2%80%93Lifshitz%E2%80%93Gilbert_equation) describing a magnetic dipole in a magnetic field. The Larmor precession frequency is $\omega_0 = \gamma H_0$ where $\gamma$ is the gyromagnetic ratio of the electron. The Larmor precession frequency at saturation field is $\omega_m = \gamma M_s$ where $M_s$ is the saturation magnetization. This precisely matches the permeability tensor derived from [Meep's gyrotropy model](../Materials.md#gyrotropic-media), with the identification $\omega_0 \leftrightarrow \omega_n$ and $\omega_m \leftrightarrow \sigma_n$. -We choose the material parameters $\epsilon_\infty = 1$, $f_n = 1.2$, $\gamma_n = 10^{-5}$, and $\sigma_n = 0.1$, with $|\mathbf{b}_n|$ ranging from zero to $10^{-2}$. +In Meep units, we will take $\omega_0/2\pi = 1$ and $\omega_m/2\pi = 1.2$, with $\alpha/2\pi = \gamma/2\pi = 10^{-3}$ and $\epsilon = 15$. The diagonal and off-diagonal components of the permeability tensor are plotted below: +
+![](../images/Ferrite-mu.png) +
+ +### Dispersion relation + +Consider a uniform ferrite medium with bias field in the *z* direction. The gyrotropy acts upon the *x* and *y* components of the magnetic field, so we focus on TM plane waves that have wavevector $\mathbf{k}$ and magnetic fields in the *x*-*y* plane, and electric fields parallel to *z*. From Maxwell's equations, we derive the dispersion relation + +$$\omega^2 = \epsilon^{-1} \left[\mu^{-1}\right]_{\perp} |\mathbf{k}|^2$$ +where $[\mu^{-1}\right]_{\perp} = [\mu^{-1}\right]_{xx} = [\mu^{-1}\right]_{yy}$. + + +### FIXME + From the dispersion relation ω(k), we will compute the numerical ε(ω) via the formula: $$\varepsilon(\omega) = \left( \frac{ck}{\omega} \right) ^2$$ @@ -53,9 +67,6 @@ $$\varepsilon(\omega) = \varepsilon(2\pi f) = 2.25 + \frac{1.1^2 \cdot 0.5}{1.1^ The real and imaginary parts of this dielectric function ε(ω) are plotted below: -
-![](../images/Material-dispersion-eps.png) -
We can see that the f=1.1 resonance causes a large change in both the real and imaginary parts of ε around that frequency. In fact, there is a range of frequencies from 1.1 to 1.2161 where ε is *negative*. In this range, no propagating modes exist — it is actually a kind of electromagnetic band gap associated with polariton resonances in a material. For more information on the physics of such materials, see e.g. Chapter 14 of [Introduction to Solid State Physics](http://www.wiley.com/WileyCDA/WileyTitle/productCd-EHEP000803.html) by C. Kittel. diff --git a/doc/docs/Scheme_User_Interface.md b/doc/docs/Scheme_User_Interface.md index c422c2945..85f47b7cc 100644 --- a/doc/docs/Scheme_User_Interface.md +++ b/doc/docs/Scheme_User_Interface.md @@ -339,6 +339,30 @@ Specifies a single dispersive susceptibility of Lorentzian (damped harmonic osci — The noise has root-mean square amplitude σ $\times$ `noise-amp`. +### gyrotropic-susceptibility + +(**Experimental feature**) Specifies a single dispersive [gyrotropic susceptibility](Materials.md#gyrotropic-media) governed by the Landau-Lifshitz-Gilbert equation. Note that the parameters `sigma`, `frequency`, and `gamma` play different roles compared to the Lorentzian or Drude case. + +**`sigma` [`number`]** +— +The coupling factor $\sigma_n / 2\pi$ between the polarization and the driving field. In magnetic ferrites, this is the Larmor precession frequency at the saturation field. + +**`frequency` [`number`]** +— +The frequency of gyrotropic precession, $f_n = \omega_n / 2\pi$. In magnetic ferrites, this is the Larmor precession frequency. + +**`gamma` [`number`]** +— +The loss rate $\gamma_n / 2\pi$ in the off-diagonal response. + +**`alpha` [`number`]** +— +The loss rate $\alpha_n / 2\pi$ in the diagonal response. + +**`bias` [`vector3`]** +— +Gyrotropy vector describing the direction of the static biasing magnetic field. The magnitude is ignored. + ### geometric-object This class, and its descendants, are used to specify the solid geometric objects that form the dielectric structure being simulated. The base class is: From 14454cf9fdf2c4d6a7016e094526b7cc668e2098 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 24 May 2019 11:51:24 +0800 Subject: [PATCH 16/61] Fix last change to update_P --- src/susceptibility.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index d8614c1dd..b73e6fb7a 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -349,8 +349,8 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], FOR_COMPONENTS(c) DOCMP2 { if (d->P[c][cmp]) { const direction d0 = component_direction(c); - const realnum *w = W[c][cmp], *s = 2*pi*sigma[c][d0]; - if (w && s) { + const realnum *w = W[c][cmp]; + if (w) { if (d0 != X && d0 != Y && d0 != Z) abort("Cylindrical coordinates are not supported for gyrotropic media"); @@ -366,8 +366,8 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const realnum *w1 = W[c1][cmp]; const realnum *w2 = W[c2][cmp]; - const realnum *s1 = w1 ? 2*pi*sigma[c1][d1] : NULL; - const realnum *s2 = w2 ? 2*pi*sigma[c2][d2] : NULL; + const realnum *s1 = w1 ? sigma[c1][d1] : NULL; + const realnum *s2 = w2 ? sigma[c2][d2] : NULL; const realnum *p1 = d->P[c1][cmp]; const realnum *p2 = d->P[c2][cmp]; @@ -375,8 +375,8 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const realnum vab1 = va * gyro_tensor[d0][d1]; const realnum vab2 = va * gyro_tensor[d0][d2]; - const realnum ndt1 = dt * gyro_tensor[d0][d1]; - const realnum ndt2 = dt * gyro_tensor[d0][d2]; + const realnum ndt1 = 2*pi*dt * gyro_tensor[d0][d1]; + const realnum ndt2 = 2*pi*dt * gyro_tensor[d0][d2]; LOOP_OVER_VOL_OWNED(gv, c, i) { pp[i] = ua * p[i]; From 5e0f3719de95161e45205b6cdcc868676a116a43 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 24 May 2019 14:41:54 +0800 Subject: [PATCH 17/61] Fix printf typo --- src/meepgeom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meepgeom.cpp b/src/meepgeom.cpp index a135396c7..bc825a3e2 100644 --- a/src/meepgeom.cpp +++ b/src/meepgeom.cpp @@ -1381,7 +1381,7 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) sus = new meep::lorentzian_susceptibility(ss->frequency, ss->gamma, ss->drude); } master_printf("%s%s susceptibility: frequency=%g, gamma=%g", - noisy ? "noisy " : gyrotropic ? "gyrotropic " : "", + noisy ? "noisy " : gyrotropic ? "gyrotropic" : "", gyrotropic ? "" : ss->drude ? "drude" : "lorentzian", ss->frequency, ss->gamma); if (noisy) master_printf(", amp=%g ", ss->noise_amp); From 722c9c6b78dbf8e20ae99f12975d3a8129cacd8d Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 24 May 2019 14:50:20 +0800 Subject: [PATCH 18/61] Remove spurious 2pi factor in alpha (which is not a rate) --- doc/docs/Python_Tutorials/Gyrotropic_Media.md | 2 +- doc/docs/Python_User_Interface.md | 2 +- doc/docs/Scheme_User_Interface.md | 2 +- src/susceptibility.cpp | 5 ++--- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/docs/Python_Tutorials/Gyrotropic_Media.md b/doc/docs/Python_Tutorials/Gyrotropic_Media.md index 532f506d5..4902f4d55 100644 --- a/doc/docs/Python_Tutorials/Gyrotropic_Media.md +++ b/doc/docs/Python_Tutorials/Gyrotropic_Media.md @@ -20,7 +20,7 @@ $$\mu_\perp = 1 + \frac{\omega_m (\omega_0 - i\omega\alpha)}{(\omega_0 - i \omeg This permeability can be derived from the [Landau-Lifshitz-Gilbert equation](https://en.wikipedia.org/wiki/Landau%E2%80%93Lifshitz%E2%80%93Gilbert_equation) describing a magnetic dipole in a magnetic field. The Larmor precession frequency is $\omega_0 = \gamma H_0$ where $\gamma$ is the gyromagnetic ratio of the electron. The Larmor precession frequency at saturation field is $\omega_m = \gamma M_s$ where $M_s$ is the saturation magnetization. This precisely matches the permeability tensor derived from [Meep's gyrotropy model](../Materials.md#gyrotropic-media), with the identification $\omega_0 \leftrightarrow \omega_n$ and $\omega_m \leftrightarrow \sigma_n$. -In Meep units, we will take $\omega_0/2\pi = 1$ and $\omega_m/2\pi = 1.2$, with $\alpha/2\pi = \gamma/2\pi = 10^{-3}$ and $\epsilon = 15$. The diagonal and off-diagonal components of the permeability tensor are plotted below: +We will take $\omega_0/2\pi = 1$, $\omega_m/2\pi = 1.2$, $\alpha = \gamma/2\pi = 10^{-3}$, and $\epsilon = 15$. The diagonal and off-diagonal components of the permeability tensor are plotted below:
![](../images/Ferrite-mu.png) diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index 0dc977f35..8cc35d1aa 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -410,7 +410,7 @@ The loss rate $\gamma_n / 2\pi$ in the off-diagonal response. **`alpha` [`number`]** — -The loss rate $\alpha_n / 2\pi$ in the diagonal response. +The loss factor $\alpha_n$ in the diagonal response (note that there is no 2π factor). **`bias` [`Vector3`]** — diff --git a/doc/docs/Scheme_User_Interface.md b/doc/docs/Scheme_User_Interface.md index 85f47b7cc..1117430af 100644 --- a/doc/docs/Scheme_User_Interface.md +++ b/doc/docs/Scheme_User_Interface.md @@ -357,7 +357,7 @@ The loss rate $\gamma_n / 2\pi$ in the off-diagonal response. **`alpha` [`number`]** — -The loss rate $\alpha_n / 2\pi$ in the diagonal response. +The loss factor $\alpha_n$ in the diagonal response (note that there is no 2π factor). **`bias` [`vector3`]** — diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index b73e6fb7a..582e52787 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -338,11 +338,10 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv, void *P_internal_data) const { lorentzian_data *d = (lorentzian_data *)P_internal_data; const double omega2pi = 2 * pi * omega_0, g2pi = gamma * 2 * pi; - const double alpha2pi = 2 * pi * alpha; const double ua = 1 - 0.5 * g2pi * dt; - const double va = alpha2pi - 0.5 * omega2pi * dt; + const double va = alpha - 0.5 * omega2pi * dt; const double ub = 1 + 0.5 * g2pi * dt; - const double vb = alpha2pi + 0.5 * omega2pi * dt; + const double vb = alpha + 0.5 * omega2pi * dt; (void)W_prev; // unused; From e091b5e54de9c8ebcf050477cfd2b28530dee31f Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 24 May 2019 17:42:08 +0800 Subject: [PATCH 19/61] Minor code tweak --- src/susceptibility.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 582e52787..4a9b50e2e 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -337,12 +337,10 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, const grid_volume &gv, void *P_internal_data) const { lorentzian_data *d = (lorentzian_data *)P_internal_data; - const double omega2pi = 2 * pi * omega_0, g2pi = gamma * 2 * pi; - const double ua = 1 - 0.5 * g2pi * dt; - const double va = alpha - 0.5 * omega2pi * dt; - const double ub = 1 + 0.5 * g2pi * dt; - const double vb = alpha + 0.5 * omega2pi * dt; - + const double ua = 1 - pi * gamma * dt; + const double ub = 1 + pi * gamma * dt; + const double va = alpha - pi * omega_0 * dt; + const double vb = alpha + pi * omega_0 * dt; (void)W_prev; // unused; FOR_COMPONENTS(c) DOCMP2 { From 104fff9322589b4a09b733d8e2846f5e9465b570 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sat, 25 May 2019 17:25:41 +0800 Subject: [PATCH 20/61] Use a central-difference scheme for the LLG dynamics, which seems slighly more stable... --- src/meep.hpp | 4 +- src/susceptibility.cpp | 126 +++++++++++++++++++++++------------------ 2 files changed, 73 insertions(+), 57 deletions(-) diff --git a/src/meep.hpp b/src/meep.hpp index 0e0a401dd..4669a974d 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -223,7 +223,8 @@ class susceptibility { class lorentzian_susceptibility : public susceptibility { public: lorentzian_susceptibility(double omega_0, double gamma, bool no_omega_0_denominator = false) - : omega_0(omega_0), gamma(gamma), no_omega_0_denominator(no_omega_0_denominator) {} + : omega_0(omega_0), gamma(gamma), no_omega_0_denominator(no_omega_0_denominator), + have_gyrotropy(false) {} virtual susceptibility *clone() const { return new lorentzian_susceptibility(*this); } virtual ~lorentzian_susceptibility() {} @@ -249,6 +250,7 @@ class lorentzian_susceptibility : public susceptibility { protected: double omega_0, gamma; bool no_omega_0_denominator; + bool have_gyrotropy; // whether to assign an extra slot for gyrotropy calculations }; /* like a Lorentzian susceptibility, but the polarization equation diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 4a9b50e2e..038afa62f 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -92,6 +92,7 @@ typedef struct { size_t ntot; realnum *P[NUM_FIELD_COMPONENTS][2]; realnum *P_prev[NUM_FIELD_COMPONENTS][2]; + realnum *P_tmp[NUM_FIELD_COMPONENTS][2]; // extra slot used for gyrotropic medium updating realnum data[1]; } lorentzian_data; @@ -100,8 +101,9 @@ typedef struct { void *lorentzian_susceptibility::new_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv) const { int num = 0; + int nslots = have_gyrotropy ? 3 : 2; FOR_COMPONENTS(c) DOCMP2 { - if (needs_P(c, cmp, W)) num += 2 * gv.ntot(); + if (needs_P(c, cmp, W)) num += nslots * gv.ntot(); } size_t sz = sizeof(lorentzian_data) + sizeof(realnum) * (num - 1); lorentzian_data *d = (lorentzian_data *)malloc(sz); @@ -119,12 +121,18 @@ void lorentzian_susceptibility::init_internal_data(realnum *W[NUM_FIELD_COMPONEN size_t ntot = d->ntot = gv.ntot(); realnum *P = d->data; realnum *P_prev = d->data + ntot; + realnum *P_tmp = have_gyrotropy ? P_prev + ntot : NULL; + int nslots = have_gyrotropy ? 3 : 2; + FOR_COMPONENTS(c) DOCMP2 { if (needs_P(c, cmp, W)) { d->P[c][cmp] = P; d->P_prev[c][cmp] = P_prev; - P += 2 * ntot; - P_prev += 2 * ntot; + d->P_tmp[c][cmp] = P_tmp; + + P += nslots * ntot; + P_prev += nslots * ntot; + if (have_gyrotropy) P_tmp += nslots * ntot; } } } @@ -137,12 +145,17 @@ void *lorentzian_susceptibility::copy_internal_data(void *data) const { size_t ntot = d->ntot; realnum *P = dnew->data; realnum *P_prev = dnew->data + ntot; + realnum *P_tmp = have_gyrotropy ? P_prev + ntot : NULL; + int nslots = have_gyrotropy ? 3 : 2; + FOR_COMPONENTS(c) DOCMP2 { if (d->P[c][cmp]) { dnew->P[c][cmp] = P; dnew->P_prev[c][cmp] = P_prev; - P += 2 * ntot; - P_prev += 2 * ntot; + dnew->P_tmp[c][cmp] = P_tmp; + P += nslots * ntot; + P_prev += nslots * ntot; + if (have_gyrotropy) P_tmp += nslots * ntot; } } return (void *)dnew; @@ -325,6 +338,7 @@ void noisy_lorentzian_susceptibility::dump_params(h5file *h5f, size_t *start) { gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double alpha, double omega_0, double gamma) : lorentzian_susceptibility(omega_0, gamma, false), alpha(alpha) { + have_gyrotropy = true; const vec bn = bias / fmax(abs(bias), 1e-10); // avoid division by zero memset(gyro_tensor, 0, 9 * sizeof(double)); @@ -334,13 +348,11 @@ gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double alp } void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], - realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, - const grid_volume &gv, void *P_internal_data) const { + realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, + const grid_volume &gv, void *P_internal_data) const { lorentzian_data *d = (lorentzian_data *)P_internal_data; - const double ua = 1 - pi * gamma * dt; - const double ub = 1 + pi * gamma * dt; - const double va = alpha - pi * omega_0 * dt; - const double vb = alpha + pi * omega_0 * dt; + const realnum w4pit = 4*pi*dt*omega_0; + const realnum g4pit = 4*pi*dt*gamma; (void)W_prev; // unused; FOR_COMPONENTS(c) DOCMP2 { @@ -348,79 +360,81 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const direction d0 = component_direction(c); const realnum *w = W[c][cmp]; if (w) { - if (d0 != X && d0 != Y && d0 != Z) - abort("Cylindrical coordinates are not supported for gyrotropic media"); + if (d0 != X && d0 != Y && d0 != Z) + abort("Cylindrical coordinates are not supported for gyrotropic media"); const realnum *p = d->P[c][cmp]; - realnum *pp = d->P_prev[c][cmp]; + const realnum *pp = d->P_prev[c][cmp]; + realnum *ptmp = d->P_tmp[c][cmp]; direction d1 = cycle_direction(gv.dim, d0, 1); direction d2 = cycle_direction(gv.dim, d0, 2); - component c1 = direction_component(c, d1); component c2 = direction_component(c, d2); const realnum *w1 = W[c1][cmp]; const realnum *w2 = W[c2][cmp]; - const realnum *s1 = w1 ? sigma[c1][d1] : NULL; const realnum *s2 = w2 ? sigma[c2][d2] : NULL; - - const realnum *p1 = d->P[c1][cmp]; - const realnum *p2 = d->P[c2][cmp]; - - const realnum vab1 = va * gyro_tensor[d0][d1]; - const realnum vab2 = va * gyro_tensor[d0][d2]; - - const realnum ndt1 = 2*pi*dt * gyro_tensor[d0][d1]; - const realnum ndt2 = 2*pi*dt * gyro_tensor[d0][d2]; - - LOOP_OVER_VOL_OWNED(gv, c, i) { - pp[i] = ua * p[i]; - if (p1) pp[i] += vab1 * p1[i]; - if (p2) pp[i] += vab2 * p2[i]; - if (w1) pp[i] += ndt1 * s1[i] * w1[i]; - if (w2) pp[i] += ndt2 * s2[i] * w2[i]; - } + const realnum *p1 = d->P[c1][cmp], *pp1 = d->P_prev[c1][cmp]; + const realnum *p2 = d->P[c2][cmp], *pp2 = d->P_prev[c2][cmp]; + + const realnum ab1 = alpha * gyro_tensor[d0][d1]; + const realnum ab2 = alpha * gyro_tensor[d0][d2]; + const realnum wb1 = w4pit * gyro_tensor[d0][d1]; + const realnum wb2 = w4pit * gyro_tensor[d0][d2]; + const realnum bt1 = 4*pi*dt * gyro_tensor[d0][d1]; + const realnum bt2 = 4*pi*dt * gyro_tensor[d0][d2]; + + LOOP_OVER_VOL_OWNED(gv, c, i) { + ptmp[i] = pp[i] - g4pit * p[i]; + if (pp1) ptmp[i] += ab1 * pp1[i]; + if (pp2) ptmp[i] += ab2 * pp2[i]; + if (p1) ptmp[i] -= wb1 * p1[i]; + if (p2) ptmp[i] -= wb2 * p2[i]; + if (s1) ptmp[i] += bt1 * s1[i] * w1[i]; + if (s2) ptmp[i] += bt2 * s2[i] * w2[i]; + } } } } // Perform 3x3 matrix inversion, exploiting skew symmetry - const double gx = vb * gyro_tensor[Y][Z]; - const double gy = vb * gyro_tensor[Z][X]; - const double gz = vb * gyro_tensor[X][Y]; - const double invdet = 1.0 / ub / (ub*ub + gx*gx + gy*gy + gz*gz); + const double ax = alpha * gyro_tensor[Y][Z]; + const double ay = alpha * gyro_tensor[Z][X]; + const double az = alpha * gyro_tensor[X][Y]; + const double invdet = 1.0 / (1 + ax*ax + ay*ay + az*az); double inv[3][3]; - inv[X][X] = invdet * (ub*ub + gx*gx); - inv[Y][Y] = invdet * (ub*ub + gy*gy); - inv[Z][Z] = invdet * (ub*ub + gz*gz); - inv[X][Y] = invdet * (gx*gy - ub*gz); - inv[Y][X] = invdet * (gy*gx + ub*gz); - inv[Z][X] = invdet * (gz*gx - ub*gy); - inv[X][Z] = invdet * (gx*gz + ub*gy); - inv[Y][Z] = invdet * (gy*gz - ub*gx); - inv[Z][Y] = invdet * (gz*gy + ub*gx); + inv[X][X] = invdet * (1 + ax*ax); + inv[Y][Y] = invdet * (1 + ay*ay); + inv[Z][Z] = invdet * (1 + az*az); + inv[X][Y] = invdet * (ax*ay - az); + inv[Y][X] = invdet * (ay*ax + az); + inv[Z][X] = invdet * (az*ax - ay); + inv[X][Z] = invdet * (ax*az + ay); + inv[Y][Z] = invdet * (ay*az - ax); + inv[Z][Y] = invdet * (az*ay + ax); FOR_COMPONENTS(c) DOCMP2 { if (d->P[c][cmp]) { const direction d0 = component_direction(c); if (W[c][cmp] && sigma[c][d0]) { - realnum *p = d->P[c][cmp]; - const realnum *pp = d->P_prev[c][cmp]; + realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; + const realnum *ptmp = d->P_tmp[c][cmp]; const direction d1 = cycle_direction(gv.dim, d0, 1); const direction d2 = cycle_direction(gv.dim, d0, 2); const component c1 = direction_component(c, d1); const component c2 = direction_component(c, d2); - const realnum *pp1 = W[c1][cmp] ? d->P_prev[c1][cmp] : NULL; - const realnum *pp2 = W[c2][cmp] ? d->P_prev[c2][cmp] : NULL; - - LOOP_OVER_VOL_OWNED(gv, c, i) { - p[i] = inv[d0][d0] * pp[i]; - if (pp1) p[i] += inv[d0][d1] * pp1[i]; - if (pp2) p[i] += inv[d0][d2] * pp2[i]; - } + const realnum *ptmp1 = W[c1][cmp] ? d->P_tmp[c1][cmp] : NULL; + const realnum *ptmp2 = W[c2][cmp] ? d->P_tmp[c2][cmp] : NULL; + + LOOP_OVER_VOL_OWNED(gv, c, i) { + pp[i] = p[i]; + p[i] = inv[d0][d0] * ptmp[i]; + if (ptmp1) p[i] += inv[d0][d1] * ptmp1[i]; + if (ptmp2) p[i] += inv[d0][d2] * ptmp2[i]; + } } } } From 054c5f5d3253d3be561b750b32c6e2c328b467c7 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sun, 26 May 2019 16:51:32 +0800 Subject: [PATCH 21/61] Try implementing the full nonlinear LLG equation --- src/meep.hpp | 3 +- src/susceptibility.cpp | 95 ++++++++++++++++++++---------------------- 2 files changed, 47 insertions(+), 51 deletions(-) diff --git a/src/meep.hpp b/src/meep.hpp index 4669a974d..ae82ad616 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -289,7 +289,8 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { protected: double alpha; - double gyro_tensor[3][3]; + double bvec[3]; + int sgn[3][3]; }; class multilevel_susceptibility : public susceptibility { diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 038afa62f..609a35bd6 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -92,7 +92,7 @@ typedef struct { size_t ntot; realnum *P[NUM_FIELD_COMPONENTS][2]; realnum *P_prev[NUM_FIELD_COMPONENTS][2]; - realnum *P_tmp[NUM_FIELD_COMPONENTS][2]; // extra slot used for gyrotropic medium updating + realnum *P_tmp[NUM_FIELD_COMPONENTS][2]; // extra slot for gyrotropic medium updating realnum data[1]; } lorentzian_data; @@ -340,11 +340,12 @@ gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double alp : lorentzian_susceptibility(omega_0, gamma, false), alpha(alpha) { have_gyrotropy = true; - const vec bn = bias / fmax(abs(bias), 1e-10); // avoid division by zero - memset(gyro_tensor, 0, 9 * sizeof(double)); - gyro_tensor[X][Y] = bn.z(); gyro_tensor[Y][X] = -bn.z(); - gyro_tensor[Y][Z] = bn.x(); gyro_tensor[Z][Y] = -bn.x(); - gyro_tensor[Z][X] = bn.y(); gyro_tensor[X][Z] = -bn.y(); + const vec b = bias / fmax(abs(bias), 1e-10); // avoid division by zero + bvec[0] = b.x(); bvec[1] = b.y(); bvec[2] = b.z(); + + memset(sgn, 0, 9 * sizeof(int)); + sgn[X][Y] = sgn[Y][Z] = sgn[Z][X] = 1; + sgn[X][Z] = sgn[Z][Y] = sgn[Y][X] = -1; } void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], @@ -352,7 +353,9 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv, void *P_internal_data) const { lorentzian_data *d = (lorentzian_data *)P_internal_data; const realnum w4pit = 4*pi*dt*omega_0; - const realnum g4pit = 4*pi*dt*gamma; + const realnum g2pi = 2*pi*gamma; + const realnum g2pisq = g2pi*g2pi; + const realnum pi4dt = 4*pi*dt; (void)W_prev; // unused; FOR_COMPONENTS(c) DOCMP2 { @@ -361,79 +364,72 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const realnum *w = W[c][cmp]; if (w) { if (d0 != X && d0 != Y && d0 != Z) - abort("Cylindrical coordinates are not supported for gyrotropic media"); + abort("Cylindrical coordinates not supported for gyrotropic media\n"); - const realnum *p = d->P[c][cmp]; const realnum *pp = d->P_prev[c][cmp]; realnum *ptmp = d->P_tmp[c][cmp]; - direction d1 = cycle_direction(gv.dim, d0, 1); direction d2 = cycle_direction(gv.dim, d0, 2); component c1 = direction_component(c, d1); component c2 = direction_component(c, d2); - const realnum *w1 = W[c1][cmp]; const realnum *w2 = W[c2][cmp]; const realnum *s1 = w1 ? sigma[c1][d1] : NULL; const realnum *s2 = w2 ? sigma[c2][d2] : NULL; const realnum *p1 = d->P[c1][cmp], *pp1 = d->P_prev[c1][cmp]; const realnum *p2 = d->P[c2][cmp], *pp2 = d->P_prev[c2][cmp]; + const realnum wb1 = w4pit * sgn[d0][d1] * bvec[c2]; + const realnum wb2 = w4pit * sgn[d0][d2] * bvec[c1]; + const int sgn1 = sgn[d0][d1]; + const int sgn2 = sgn[d0][d2]; - const realnum ab1 = alpha * gyro_tensor[d0][d1]; - const realnum ab2 = alpha * gyro_tensor[d0][d2]; - const realnum wb1 = w4pit * gyro_tensor[d0][d1]; - const realnum wb2 = w4pit * gyro_tensor[d0][d2]; - const realnum bt1 = 4*pi*dt * gyro_tensor[d0][d1]; - const realnum bt2 = 4*pi*dt * gyro_tensor[d0][d2]; + if (!pp1 || !pp2 || !p1 || !p2 || !s1 || !s2) + abort("Gyrotropic media require 3D fields\n"); LOOP_OVER_VOL_OWNED(gv, c, i) { - ptmp[i] = pp[i] - g4pit * p[i]; - if (pp1) ptmp[i] += ab1 * pp1[i]; - if (pp2) ptmp[i] += ab2 * pp2[i]; - if (p1) ptmp[i] -= wb1 * p1[i]; - if (p2) ptmp[i] -= wb2 * p2[i]; - if (s1) ptmp[i] += bt1 * s1[i] * w1[i]; - if (s2) ptmp[i] += bt2 * s2[i] * w2[i]; + ptmp[i] = pp[i] - wb1 * p1[i] - wb2 * p2[i] + - sgn1 * p1[i] * (pi4dt*s2[i]*w2[i] + g2pi * pp2[i]) + - sgn2 * p2[i] * (pi4dt*s1[i]*w1[i] + g2pi * pp1[i]); } } } } - // Perform 3x3 matrix inversion, exploiting skew symmetry - const double ax = alpha * gyro_tensor[Y][Z]; - const double ay = alpha * gyro_tensor[Z][X]; - const double az = alpha * gyro_tensor[X][Y]; - const double invdet = 1.0 / (1 + ax*ax + ay*ay + az*az); - double inv[3][3]; - - inv[X][X] = invdet * (1 + ax*ax); - inv[Y][Y] = invdet * (1 + ay*ay); - inv[Z][Z] = invdet * (1 + az*az); - inv[X][Y] = invdet * (ax*ay - az); - inv[Y][X] = invdet * (ay*ax + az); - inv[Z][X] = invdet * (az*ax - ay); - inv[X][Z] = invdet * (ax*az + ay); - inv[Y][Z] = invdet * (ay*az - ax); - inv[Z][Y] = invdet * (az*ay + ax); + FOR_COMPONENTS(c) DOCMP2 { // Overwrite P_prev + if (d->P[c][cmp]) { + if (W[c][cmp] && sigma[c][component_direction(c)]) { + const realnum *p = d->P[c][cmp]; + realnum *pp = d->P_prev[c][cmp]; + LOOP_OVER_VOL_OWNED(gv, c, i) { + pp[i] = p[i]; + } + } + } + } - FOR_COMPONENTS(c) DOCMP2 { + FOR_COMPONENTS(c) DOCMP2 { // Perform matrix inversion if (d->P[c][cmp]) { const direction d0 = component_direction(c); if (W[c][cmp] && sigma[c][d0]) { - realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; + realnum *p = d->P[c][cmp]; + const realnum *pp = d->P_prev[c][cmp]; const realnum *ptmp = d->P_tmp[c][cmp]; const direction d1 = cycle_direction(gv.dim, d0, 1); const direction d2 = cycle_direction(gv.dim, d0, 2); const component c1 = direction_component(c, d1); const component c2 = direction_component(c, d2); - const realnum *ptmp1 = W[c1][cmp] ? d->P_tmp[c1][cmp] : NULL; - const realnum *ptmp2 = W[c2][cmp] ? d->P_tmp[c2][cmp] : NULL; + const realnum *pp1 = d->P_prev[c1][cmp]; + const realnum *pp2 = d->P_prev[c2][cmp]; + const realnum *ptmp1 = d->P_tmp[c1][cmp]; + const realnum *ptmp2 = d->P_tmp[c2][cmp]; + const int sgn1 = sgn[d0][d1]; + const int sgn2 = sgn[d0][d2]; LOOP_OVER_VOL_OWNED(gv, c, i) { - pp[i] = p[i]; - p[i] = inv[d0][d0] * ptmp[i]; - if (ptmp1) p[i] += inv[d0][d1] * ptmp1[i]; - if (ptmp2) p[i] += inv[d0][d2] * ptmp2[i]; + p[i] = 1/(1 + g2pisq*(pp[i]*pp[i] + pp1[i]*pp1[i] + pp2[i]*pp2[i])) + * ((1 + g2pisq * pp[i]*pp[i]) * ptmp[i] + + (g2pisq*pp[i]*pp1[i] - g2pi*sgn1*pp2[i]) * ptmp1[i] + + (g2pisq*pp[i]*pp2[i] - g2pi*sgn2*pp1[i]) * ptmp2[i]); } } } @@ -443,9 +439,8 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], void gyrotropic_susceptibility::dump_params(h5file *h5f, size_t *start) { size_t num_params = 9; size_t params_dims[1] = {num_params}; - double bias[] = { gyro_tensor[Y][Z], gyro_tensor[Z][X], gyro_tensor[X][Y] }; double params_data[] = { - 8, (double)get_id(), bias[X], bias[Y], bias[Z], + 8, (double)get_id(), bvec[0], bvec[1], bvec[2], alpha, omega_0, gamma, (double)no_omega_0_denominator}; h5f->write_chunk(1, start, params_dims, params_data); *start += num_params; From 15636743b8d6d104d63e9fe0c9835818efcf836f Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Mon, 27 May 2019 13:52:22 +0800 Subject: [PATCH 22/61] Add implicit static polarization to gyrotropy implementation --- python/geom.py | 3 +- python/typemap_utils.cpp | 10 ----- scheme/meep.scm.in | 3 +- scheme/structure.cpp | 7 ++-- src/material_data.hpp | 1 - src/meep.hpp | 10 ++--- src/meepgeom.cpp | 7 ++-- src/susceptibility.cpp | 81 +++++++++++++++++++++------------------- 8 files changed, 55 insertions(+), 67 deletions(-) diff --git a/python/geom.py b/python/geom.py index 4101c53e4..4ef0be335 100644 --- a/python/geom.py +++ b/python/geom.py @@ -282,10 +282,9 @@ def __init__(self, noise_amp=0.0, **kwargs): class GyrotropicSusceptibility(LorentzianSusceptibility): - def __init__(self, bias=Vector3(0, 0, 1), alpha=0.0, **kwargs): + def __init__(self, bias=Vector3(0, 0, 1), **kwargs): super(GyrotropicSusceptibility, self).__init__(**kwargs) self.bias = bias - self.alpha = alpha class MultilevelAtom(Susceptibility): diff --git a/python/typemap_utils.cpp b/python/typemap_utils.cpp index 60d9a776a..302d78c35 100644 --- a/python/typemap_utils.cpp +++ b/python/typemap_utils.cpp @@ -331,7 +331,6 @@ static int py_susceptibility_to_susceptibility(PyObject *po, susceptibility_stru s->gamma = 0; s->noise_amp = 0; s->bias.x = s->bias.y = s->bias.z = 0; - s->alpha = 0; s->transitions.resize(0); s->initial_populations.resize(0); @@ -351,10 +350,6 @@ static int py_susceptibility_to_susceptibility(PyObject *po, susceptibility_stru if (!get_attr_v3(po, &s->bias, "bias")) return 0; } - if (PyObject_HasAttrString(po, "alpha")) { - if (!get_attr_dbl(po, &s->alpha, "alpha")) { return 0; } - } - if (PyObject_HasAttrString(po, "transitions")) { // MultilevelAtom PyObject *py_trans = PyObject_GetAttrString(po, "transitions"); @@ -477,11 +472,6 @@ static PyObject *susceptibility_to_py_obj(susceptibility_struct *s) { PyObject *py_bias = vec2py(vector3_to_vec(s->bias)); PyObject_SetAttrString(res, "bias", py_bias); Py_DECREF(py_bias); - - PyObject *py_alpha = PyFloat_FromDouble(s->alpha); - PyObject_SetAttrString(res, "alpha", py_alpha); - Py_DECREF(py_alpha); - } else if (s->noise_amp == 0) { if (s->drude) { PyObject *py_drude_class = PyObject_GetAttrString(geom_mod, "DrudeSusceptibility"); diff --git a/scheme/meep.scm.in b/scheme/meep.scm.in index 06f5df939..857559f97 100644 --- a/scheme/meep.scm.in +++ b/scheme/meep.scm.in @@ -58,8 +58,7 @@ (define-class noisy-drude-susceptibility drude-susceptibility (define-property noise-amp no-default 'number)) (define-class gyrotropic-susceptibility lorentzian-susceptibility - (define-property bias no-default 'vector3) - (define-property alpha no-default 'number)) + (define-property bias no-default 'vector3)) (define polarizability lorentzian-susceptibility) ; backwards compat (define omega frequency) ; backwards compat diff --git a/scheme/structure.cpp b/scheme/structure.cpp index be5b99789..8f6bdf16f 100644 --- a/scheme/structure.cpp +++ b/scheme/structure.cpp @@ -1297,10 +1297,9 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) sus = new meep::noisy_lorentzian_susceptibility(nd->noise_amp, d->frequency, d->gamma); } else if (d->which_subclass == lorentzian_susceptibility::GYROTROPIC_SUSCEPTIBILITY) { gyrotropic_susceptibility *gd = d->subclass.gyrotropic_susceptibility_data; - master_printf("gyrotropic lorentzian susceptibility: bias=(%g,%g,%g), alpha=%g, frequency=%g, gamma=%g\n", - gd->bias.x, gd->bias.y, gd->bias.z, gd->alpha, d->frequency, d->gamma); - sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), gd->alpha, - d->frequency, d->gamma); + master_printf("gyrotropic lorentzian susceptibility: bias=(%g,%g,%g), frequency=%g, gamma=%g\n", + gd->bias.x, gd->bias.y, gd->bias.z, d->frequency, d->gamma); + sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma); } else { // just a Lorentzian master_printf("lorentzian susceptibility: frequency=%g, gamma=%g\n", d->frequency, d->gamma); diff --git a/src/material_data.hpp b/src/material_data.hpp index ec5c998c4..352b6155e 100644 --- a/src/material_data.hpp +++ b/src/material_data.hpp @@ -60,7 +60,6 @@ typedef struct susceptibility_struct { vector3 sigma_offdiag; vector3 sigma_diag; vector3 bias; - double alpha; double frequency; double gamma; double noise_amp; diff --git a/src/meep.hpp b/src/meep.hpp index ae82ad616..1fc6ca2e0 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -277,7 +277,7 @@ class noisy_lorentzian_susceptibility : public lorentzian_susceptibility { /* gyrotropic susceptibility */ class gyrotropic_susceptibility : public lorentzian_susceptibility { public: - gyrotropic_susceptibility(const vec &bias, double alpha, double omega_0, double gamma); + gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma); virtual susceptibility *clone() const { return new gyrotropic_susceptibility(*this); } virtual void update_P(realnum *W[NUM_FIELD_COMPONENTS][2], @@ -285,12 +285,12 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { const grid_volume &gv, void *P_internal_data) const; virtual void dump_params(h5file *h5f, size_t *start); - virtual int get_num_params() { return 8; } + virtual int get_num_params() { return 7; } protected: - double alpha; - double bvec[3]; - int sgn[3][3]; + double psat; // conserved magnitude of the polarization vector + double bvec[3]; // unit vector pointing along direction of gyrotropic bias + int sgn[3][3]; // antisymmetric tensor: sgn[X][Y] = 1, sgn[Z][Y] = -1, etc. }; class multilevel_susceptibility : public susceptibility { diff --git a/src/meepgeom.cpp b/src/meepgeom.cpp index bc825a3e2..d30a32adf 100644 --- a/src/meepgeom.cpp +++ b/src/meepgeom.cpp @@ -1376,7 +1376,7 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) ss->drude); } else if (gyrotropic) { sus = new meep::gyrotropic_susceptibility(meep::vec(ss->bias.x, ss->bias.y, ss->bias.z), - ss->alpha, ss->frequency, ss->gamma); + ss->frequency, ss->gamma); } else { sus = new meep::lorentzian_susceptibility(ss->frequency, ss->gamma, ss->drude); } @@ -1385,9 +1385,8 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) gyrotropic ? "" : ss->drude ? "drude" : "lorentzian", ss->frequency, ss->gamma); if (noisy) master_printf(", amp=%g ", ss->noise_amp); - if (gyrotropic) master_printf(", bias=(%g,%g,%g), alpha=%g ", - ss->bias.x, ss->bias.y, ss->bias.z, - ss->alpha); + if (gyrotropic) master_printf(", bias=(%g,%g,%g) ", + ss->bias.x, ss->bias.y, ss->bias.z); master_printf("\n"); } diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 609a35bd6..06c80cbf8 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -336,11 +336,13 @@ void noisy_lorentzian_susceptibility::dump_params(h5file *h5f, size_t *start) { } -gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double alpha, double omega_0, double gamma) - : lorentzian_susceptibility(omega_0, gamma, false), alpha(alpha) { +gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma) + : lorentzian_susceptibility(omega_0, gamma, false) { have_gyrotropy = true; - const vec b = bias / fmax(abs(bias), 1e-10); // avoid division by zero + psat = abs(bias); + + const vec b = (psat != 0.0 ? bias/psat : vec(0,0,1)); bvec[0] = b.x(); bvec[1] = b.y(); bvec[2] = b.z(); memset(sgn, 0, 9 * sizeof(int)); @@ -354,8 +356,7 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], lorentzian_data *d = (lorentzian_data *)P_internal_data; const realnum w4pit = 4*pi*dt*omega_0; const realnum g2pi = 2*pi*gamma; - const realnum g2pisq = g2pi*g2pi; - const realnum pi4dt = 4*pi*dt; + const realnum dt4pi = 4*pi*dt; (void)W_prev; // unused; FOR_COMPONENTS(c) DOCMP2 { @@ -366,31 +367,30 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], if (d0 != X && d0 != Y && d0 != Z) abort("Cylindrical coordinates not supported for gyrotropic media\n"); + const direction d1 = cycle_direction(gv.dim, d0, 1); + const direction d2 = cycle_direction(gv.dim, d0, 2); + const component c1 = direction_component(c, d1); + const component c2 = direction_component(c, d2); + const realnum *pp = d->P_prev[c][cmp]; - realnum *ptmp = d->P_tmp[c][cmp]; - direction d1 = cycle_direction(gv.dim, d0, 1); - direction d2 = cycle_direction(gv.dim, d0, 2); - component c1 = direction_component(c, d1); - component c2 = direction_component(c, d2); - const realnum *w1 = W[c1][cmp]; - const realnum *w2 = W[c2][cmp]; - const realnum *s1 = w1 ? sigma[c1][d1] : NULL; - const realnum *s2 = w2 ? sigma[c2][d2] : NULL; const realnum *p1 = d->P[c1][cmp], *pp1 = d->P_prev[c1][cmp]; const realnum *p2 = d->P[c2][cmp], *pp2 = d->P_prev[c2][cmp]; - const realnum wb1 = w4pit * sgn[d0][d1] * bvec[c2]; - const realnum wb2 = w4pit * sgn[d0][d2] * bvec[c1]; - const int sgn1 = sgn[d0][d1]; - const int sgn2 = sgn[d0][d2]; + realnum *ptmp = d->P_tmp[c][cmp]; + + const realnum *w1 = W[c1][cmp], *s1 = w1 ? sigma[c1][d1] : NULL; + const realnum *w2 = W[c2][cmp], *s2 = w2 ? sigma[c2][d2] : NULL; + const realnum pb1 = psat * bvec[d1], pb2 = psat * bvec[d2]; + const realnum wb1 = w4pit * bvec[d1], wb2 = w4pit * bvec[d2]; + const int sgn1 = sgn[d0][d1], sgn2 = sgn[d0][d2]; if (!pp1 || !pp2 || !p1 || !p2 || !s1 || !s2) abort("Gyrotropic media require 3D fields\n"); LOOP_OVER_VOL_OWNED(gv, c, i) { - ptmp[i] = pp[i] - wb1 * p1[i] - wb2 * p2[i] - - sgn1 * p1[i] * (pi4dt*s2[i]*w2[i] + g2pi * pp2[i]) - - sgn2 * p2[i] * (pi4dt*s1[i]*w1[i] + g2pi * pp1[i]); - } + ptmp[i] = pp[i] + + sgn1 * ((g2pi * pp1[i] + dt4pi*s1[i]*w1[i]) * (pb2+p2[i]) + wb1*p2[i]) + + sgn2 * ((g2pi * pp2[i] + dt4pi*s2[i]*w2[i]) * (pb1+p1[i]) + wb2*p1[i]); + } } } } @@ -411,25 +411,28 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], if (d->P[c][cmp]) { const direction d0 = component_direction(c); if (W[c][cmp] && sigma[c][d0]) { - realnum *p = d->P[c][cmp]; - const realnum *pp = d->P_prev[c][cmp]; - const realnum *ptmp = d->P_tmp[c][cmp]; const direction d1 = cycle_direction(gv.dim, d0, 1); const direction d2 = cycle_direction(gv.dim, d0, 2); const component c1 = direction_component(c, d1); const component c2 = direction_component(c, d2); - const realnum *pp1 = d->P_prev[c1][cmp]; - const realnum *pp2 = d->P_prev[c2][cmp]; - const realnum *ptmp1 = d->P_tmp[c1][cmp]; - const realnum *ptmp2 = d->P_tmp[c2][cmp]; - const int sgn1 = sgn[d0][d1]; - const int sgn2 = sgn[d0][d2]; - LOOP_OVER_VOL_OWNED(gv, c, i) { - p[i] = 1/(1 + g2pisq*(pp[i]*pp[i] + pp1[i]*pp1[i] + pp2[i]*pp2[i])) - * ((1 + g2pisq * pp[i]*pp[i]) * ptmp[i] - + (g2pisq*pp[i]*pp1[i] - g2pi*sgn1*pp2[i]) * ptmp1[i] - + (g2pisq*pp[i]*pp2[i] - g2pi*sgn2*pp1[i]) * ptmp2[i]); + realnum *p = d->P[c][cmp]; + const realnum *pp = d->P_prev[c][cmp], *ptmp = d->P_tmp[c][cmp]; + const realnum *pp1 = d->P_prev[c1][cmp], *ptmp1 = d->P_tmp[c1][cmp]; + const realnum *pp2 = d->P_prev[c2][cmp], *ptmp2 = d->P_tmp[c2][cmp]; + const realnum pb0 = psat * bvec[d0]; + const realnum pb1 = psat * bvec[d1], pb2 = psat * bvec[d2]; + const int sgn1 = sgn[d0][d1], sgn2 = sgn[d0][d2]; + realnum gp0, gp1, gp2; + + LOOP_OVER_VOL_OWNED(gv, c, i) { + gp0 = g2pi * (pb0 + pp[i]); + gp1 = g2pi * (pb1 + pp1[i]); + gp2 = g2pi * (pb2 + pp2[i]); + p[i] = 1/(1 + gp0*gp0 + gp1*gp1 + gp2*gp2) + * ((1 + gp0*gp0) * ptmp[i] + + (gp0*gp1 - sgn1*gp2) * ptmp1[i] + + (gp0*gp2 - sgn2*gp1) * ptmp2[i]); } } } @@ -437,11 +440,11 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], } void gyrotropic_susceptibility::dump_params(h5file *h5f, size_t *start) { - size_t num_params = 9; + size_t num_params = 8; size_t params_dims[1] = {num_params}; double params_data[] = { - 8, (double)get_id(), bvec[0], bvec[1], bvec[2], - alpha, omega_0, gamma, (double)no_omega_0_denominator}; + 7, (double)get_id(), bvec[0], bvec[1], bvec[2], + omega_0, gamma, (double)no_omega_0_denominator}; h5f->write_chunk(1, start, params_dims, params_data); *start += num_params; } From a7b1e2795ee528be9ef87f36af747eb26b83d89e Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Mon, 27 May 2019 16:18:41 +0800 Subject: [PATCH 23/61] Put static P back in in subtract_P --- src/meep.hpp | 3 +++ src/susceptibility.cpp | 24 ++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/meep.hpp b/src/meep.hpp index 1fc6ca2e0..57a84b11e 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -284,6 +284,9 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, const grid_volume &gv, void *P_internal_data) const; + virtual void subtract_P(field_type ft, realnum *f_minus_p[NUM_FIELD_COMPONENTS][2], + void *P_internal_data) const; + virtual void dump_params(h5file *h5f, size_t *start); virtual int get_num_params() { return 7; } diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 06c80cbf8..1c28e87cf 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -399,10 +399,10 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], if (d->P[c][cmp]) { if (W[c][cmp] && sigma[c][component_direction(c)]) { const realnum *p = d->P[c][cmp]; - realnum *pp = d->P_prev[c][cmp]; + realnum *pp = d->P_prev[c][cmp]; LOOP_OVER_VOL_OWNED(gv, c, i) { pp[i] = p[i]; - } + } } } } @@ -439,6 +439,26 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], } } +void gyrotropic_susceptibility::subtract_P(field_type ft, + realnum *f_minus_p[NUM_FIELD_COMPONENTS][2], + void *P_internal_data) const { + lorentzian_data *d = (lorentzian_data *)P_internal_data; + field_type ft2 = ft == E_stuff ? D_stuff : B_stuff; // for sources etc. + size_t ntot = d->ntot; + FOR_FT_COMPONENTS(ft, ec) DOCMP2 { + if (d->P[ec][cmp]) { + component dc = field_type_component(ft2, ec); + if (f_minus_p[dc][cmp]) { + const realnum pb = psat * bvec[component_direction(ec)]; + realnum *p = d->P[ec][cmp]; + realnum *fmp = f_minus_p[dc][cmp]; + for (size_t i = 0; i < ntot; ++i) + fmp[i] -= pb + p[i]; + } + } + } +} + void gyrotropic_susceptibility::dump_params(h5file *h5f, size_t *start) { size_t num_params = 8; size_t params_dims[1] = {num_params}; From 1dc5912cf2081d70ea6554c0300f0d392e2bddbf Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Mon, 27 May 2019 17:36:59 +0800 Subject: [PATCH 24/61] Add gyrotropy example --- python/examples/gyrotropic-dispersion.py | 61 ++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 python/examples/gyrotropic-dispersion.py diff --git a/python/examples/gyrotropic-dispersion.py b/python/examples/gyrotropic-dispersion.py new file mode 100644 index 000000000..09f0fde06 --- /dev/null +++ b/python/examples/gyrotropic-dispersion.py @@ -0,0 +1,61 @@ +import numpy as np +from numpy.linalg import inv +import matplotlib.pyplot as plt + +## Material parameters +sn = 0.0002 +fn = 0.5 +gn = 1e-5 +epsn = 15 +psat = 100 + +def meep_sim(gn, sn, epsn, tmax): + + ## For mu ~ 1 and epsn ~ 15, wavelength will be ~0.26. Set dx and dt to ~0.01 + resolution = 100 + + cellsize = [0.01, 0.01, 7.0] # Don't set to zero size: need 3D fields + fsrc = 0.8 + src_z = -1.75 + pml_depth = 1.5 + + import meep as mp + + cell = mp.Vector3(*cellsize) + + ## Define gyromagnetic material biased along z direction + susc = [mp.GyrotropicSusceptibility(frequency=fn, gamma=gn, sigma=sn, + bias=mp.Vector3(0, 0, psat))] + mat = mp.Medium(epsilon=epsn, mu=1, H_susceptibilities=susc) + + pml_layers = [mp.PML(thickness=pml_depth, direction=mp.Z)] + + sources = [mp.Source(mp.ContinuousSource(frequency=fsrc), + component=mp.Ex, center=mp.Vector3(0, 0, src_z))] + + sim = mp.Simulation(cell_size=cell, geometry=[], sources=sources, + k_point=mp.Vector3(), # Periodic BCs in x and y + boundary_layers=pml_layers, + default_material=mat, resolution=resolution) + + sim.run(until=tmax) + + ex_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, cellsize[2]), component=mp.Ex) + ey_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, cellsize[2]), component=mp.Ey) + + L = cellsize[2]/2 + z = np.linspace(-L, L, len(ex_data)) + plt.title('t = {}'.format(tmax)) + plt.plot(z, ex_data, label='Ex') + plt.plot(z, ey_data, label='Ey') + plt.xlim(-L, L) + plt.xlabel('z') + plt.legend() + +plt.figure(2, figsize=(8,8)) +plt.subplot(2,1,1) +meep_sim(gn, sn, epsn, 200) +plt.subplot(2,1,2) +meep_sim(gn, sn, epsn, 500) +plt.tight_layout() +plt.show() From 8dd19881195fea5a807288d8634734aad23f8d20 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Tue, 28 May 2019 11:42:18 +0800 Subject: [PATCH 25/61] Fix; use LOOP_OVER_VOL instead of LOOP_OVER_VOL_OWNED to ensure updating of off-diagonal components --- python/meep.i | 12 ++-- src/susceptibility.cpp | 142 ++++++++++++++++++++--------------------- 2 files changed, 75 insertions(+), 79 deletions(-) diff --git a/python/meep.i b/python/meep.i index 998f13133..3f576efd9 100644 --- a/python/meep.i +++ b/python/meep.i @@ -749,21 +749,21 @@ meep::volume_list *make_volume_list(const meep::volume &v, int c, } %typemap(in) const meep::src_time & { - PyObject *swig_obj = NULL; + PyObject *swig_obj_1 = NULL; void *tmp_ptr = 0; int tmp_res = 0; if(PyObject_IsInstance($input, py_source_time_object())) { - swig_obj = PyObject_GetAttrString($input, "swigobj"); + swig_obj_1 = PyObject_GetAttrString($input, "swigobj"); } else if(PyObject_IsInstance($input, py_meep_src_time_object())) { - swig_obj = $input; - Py_XINCREF(swig_obj); + swig_obj_1 = $input; + Py_XINCREF(swig_obj_1); } else { meep::abort("Expected a meep.source.SourceTime or a meep.src_time\n"); } - tmp_res = SWIG_ConvertPtr(swig_obj, &tmp_ptr, $1_descriptor, 0); - Py_XDECREF(swig_obj); + tmp_res = SWIG_ConvertPtr(swig_obj_1, &tmp_ptr, $1_descriptor, 0); + Py_XDECREF(swig_obj_1); if(!SWIG_IsOK(tmp_res)) { SWIG_exception_fail(SWIG_ArgError(tmp_res), "Couldn't convert Python object to meep::src_time"); diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 3b7289c32..4c65f1844 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -362,70 +362,66 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], if (d->P[c][cmp]) { const direction d0 = component_direction(c); const realnum *w = W[c][cmp], *s = sigma[c][d0]; - if (w && s) { - if (d0 != X && d0 != Y && d0 != Z) - abort("Cylindrical coordinates are not supported for gyrotropic media"); - const realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; - realnum *rhs = d->P_tmp[c][cmp]; + if (!w || !s || (d0 != X && d0 != Y && d0 != Z)) + abort("Non-3D fields not supported for gyrotropic media\n"); - const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); + const realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; + realnum *rhs = d->P_tmp[c][cmp]; + const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); - direction d1 = cycle_direction(gv.dim, d0, 1); - component c1 = direction_component(c, d1); - ptrdiff_t is1 = gv.stride(d1) * (is_magnetic(c) ? -1 : +1); - const realnum *w1 = W[c1][cmp]; - const realnum *s1 = w1 ? sigma[c][d1] : NULL; + direction d1 = cycle_direction(gv.dim, d0, 1); + direction d2 = cycle_direction(gv.dim, d0, 2); + component c1 = direction_component(c, d1); + component c2 = direction_component(c, d2); + ptrdiff_t is1 = gv.stride(d1) * (is_magnetic(c) ? -1 : +1); + ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); - direction d2 = cycle_direction(gv.dim, d0, 2); - component c2 = direction_component(c, d2); - ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); - const realnum *w2 = W[c2][cmp]; - const realnum *s2 = w2 ? sigma[c][d2] : NULL; + const realnum *w1 = W[c1][cmp], *s1 = w1 ? sigma[c][d1] : NULL; + const realnum *w2 = W[c2][cmp], *s2 = w2 ? sigma[c][d2] : NULL; + const realnum *pp1 = d->P_prev[c1][cmp], g1 = pi * dt * gyro_tensor[d0][d1]; + const realnum *pp2 = d->P_prev[c2][cmp], g2 = pi * dt * gyro_tensor[d0][d2]; - // Off-diagonal polarization components - const realnum *pp1 = d->P_prev[c1][cmp]; - const realnum *pp2 = d->P_prev[c2][cmp]; - const realnum g1 = pi * dt * gyro_tensor[d0][d1]; - const realnum g2 = pi * dt * gyro_tensor[d0][d2]; + const realnum *p1 = d->P[c1][cmp]; + const realnum *p2 = d->P[c2][cmp]; - if (s2 && !s1) { // make s1 the non-NULL one if possible - SWAP(direction, d1, d2); - SWAP(component, c1, c2); - SWAP(ptrdiff_t, is1, is2); - SWAP(const realnum *, w1, w2); - SWAP(const realnum *, s1, s2); - } - if (s1 && s2) { // 3x3 anisotropic - LOOP_OVER_VOL_OWNED(gv, c, i) { - if (s[i] != 0) { - rhs[i] = (2 - omega0dtsqr_denom) * p[i] - + omega0dtsqr * (s[i] * w[i] - + OFFDIAG(s1, w1, is1, is) - + OFFDIAG(s2, w2, is2, is)) - - gamma1 * pp[i]; - if (pp1) rhs[i] -= g1 * pp1[i]; - if (pp2) rhs[i] -= g2 * pp2[i]; - } - } - } else if (s1) { // 2x2 anisotropic - LOOP_OVER_VOL_OWNED(gv, c, i) { - if (s[i] != 0) { - rhs[i] = (2 - omega0dtsqr_denom) * p[i] - + omega0dtsqr * (s[i] * w[i] + OFFDIAG(s1, w1, is1, is)) - - gamma1 * pp[i]; - if (pp1) rhs[i] -= g1 * pp1[i]; - if (pp2) rhs[i] -= g2 * pp2[i]; - } - } - } else { // isotropic - LOOP_OVER_VOL_OWNED(gv, c, i) { - rhs[i] = (2 - omega0dtsqr_denom) * p[i] - + omega0dtsqr * (s[i] * w[i]) - gamma1 * pp[i]; - if (pp1) rhs[i] -= g1 * pp1[i]; - if (pp2) rhs[i] -= g2 * pp2[i]; - } - } + realnum *rhs1 = d->P_tmp[c1][cmp]; + realnum *rhs2 = d->P_tmp[c2][cmp]; + + if (!pp1 || !pp2) + abort("Non-3D fields not supported for gyrotropic media\n"); + + if (s2 && !s1) { // make s1 the non-NULL one if possible + SWAP(direction, d1, d2); + SWAP(component, c1, c2); + SWAP(ptrdiff_t, is1, is2); + SWAP(const realnum *, w1, w2); + SWAP(const realnum *, s1, s2); + } + if (s1 && s2) { // 3x3 anisotropic + LOOP_OVER_VOL(gv, c, i) { + if (s[i] != 0) { + rhs[i] = (2 - omega0dtsqr_denom) * p[i] + + omega0dtsqr * (s[i] * w[i] + + OFFDIAG(s1, w1, is1, is) + + OFFDIAG(s2, w2, is2, is)) + - gamma1 * pp[i] - g1 * pp1[i] - g2 * pp2[i]; + } + } + } else if (s1) { // 2x2 anisotropic + LOOP_OVER_VOL(gv, c, i) { + if (s[i] != 0) { + rhs[i] = (2 - omega0dtsqr_denom) * p[i] + + omega0dtsqr * (s[i] * w[i] + OFFDIAG(s1, w1, is1, is)) + - gamma1 * pp[i] - g1 * pp1[i] - g2 * pp2[i]; + } + } + } else { // isotropic + LOOP_OVER_VOL(gv, c, i) { + rhs[i] = (2 - omega0dtsqr_denom) * p[i] + + omega0dtsqr * (s[i] * w[i]) - gamma1 * pp[i] + - g1 * pp1[i] - g2 * pp2[i]; + } } } } @@ -451,21 +447,21 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], FOR_COMPONENTS(c) DOCMP2 { if (d->P[c][cmp]) { const direction d0 = component_direction(c); - if (W[c][cmp] && sigma[c][d0]) { - realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp], *rhs = d->P_tmp[c][cmp]; - const direction d1 = cycle_direction(gv.dim, d0, 1); - const direction d2 = cycle_direction(gv.dim, d0, 2); - const component c1 = direction_component(c, d1); - const component c2 = direction_component(c, d2); - const realnum *rhs1 = W[c1][cmp] ? d->P_tmp[c1][cmp] : NULL; - const realnum *rhs2 = W[c2][cmp] ? d->P_tmp[c2][cmp] : NULL; - - LOOP_OVER_VOL_OWNED(gv, c, i) { - pp[i] = p[i]; - p[i] = inv[d0][d0] * rhs[i]; - if (rhs1) p[i] += inv[d0][d1] * rhs1[i]; - if (rhs2) p[i] += inv[d0][d2] * rhs2[i]; - } + realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; + const realnum *rhs = d->P_tmp[c][cmp]; + const direction d1 = cycle_direction(gv.dim, d0, 1); + const direction d2 = cycle_direction(gv.dim, d0, 2); + const component c1 = direction_component(c, d1); + const component c2 = direction_component(c, d2); + const realnum *rhs1 = d->P_tmp[c1][cmp]; + const realnum *rhs2 = d->P_tmp[c2][cmp]; + + if (!rhs || !rhs1 || !rhs2) + abort("Internal error in gyrotropy code\n"); + + LOOP_OVER_VOL(gv, c, i) { + pp[i] = p[i]; + p[i] = inv[d0][d0] * rhs[i] + inv[d0][d1] * rhs1[i] + inv[d0][d2] * rhs2[i]; } } } From 0842ad65e2d696729caa3bc1852fda2f78bb19ef Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Tue, 28 May 2019 13:11:51 +0800 Subject: [PATCH 26/61] Clamp the magnitude of the LLG polarization vector. --- python/examples/gyrotropic-dispersion.py | 7 +- src/susceptibility.cpp | 83 +++++++++++++++++------- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/python/examples/gyrotropic-dispersion.py b/python/examples/gyrotropic-dispersion.py index 09f0fde06..f4939976f 100644 --- a/python/examples/gyrotropic-dispersion.py +++ b/python/examples/gyrotropic-dispersion.py @@ -14,10 +14,10 @@ def meep_sim(gn, sn, epsn, tmax): ## For mu ~ 1 and epsn ~ 15, wavelength will be ~0.26. Set dx and dt to ~0.01 resolution = 100 - cellsize = [0.01, 0.01, 7.0] # Don't set to zero size: need 3D fields + cellsize = [0.01, 0.01, 5.0] # Don't set to zero size: need 3D fields fsrc = 0.8 - src_z = -1.75 - pml_depth = 1.5 + src_z = -1.8 + pml_depth = 0.25 import meep as mp @@ -58,4 +58,3 @@ def meep_sim(gn, sn, epsn, tmax): plt.subplot(2,1,2) meep_sim(gn, sn, epsn, 500) plt.tight_layout() -plt.show() diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 1c28e87cf..656137533 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -363,34 +363,33 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], if (d->P[c][cmp]) { const direction d0 = component_direction(c); const realnum *w = W[c][cmp]; - if (w) { - if (d0 != X && d0 != Y && d0 != Z) - abort("Cylindrical coordinates not supported for gyrotropic media\n"); - const direction d1 = cycle_direction(gv.dim, d0, 1); - const direction d2 = cycle_direction(gv.dim, d0, 2); - const component c1 = direction_component(c, d1); - const component c2 = direction_component(c, d2); + if (!w || (d0 != X && d0 != Y && d0 != Z)) + abort("Cylindrical coordinates not supported for gyrotropic media\n"); - const realnum *pp = d->P_prev[c][cmp]; - const realnum *p1 = d->P[c1][cmp], *pp1 = d->P_prev[c1][cmp]; - const realnum *p2 = d->P[c2][cmp], *pp2 = d->P_prev[c2][cmp]; - realnum *ptmp = d->P_tmp[c][cmp]; + const direction d1 = cycle_direction(gv.dim, d0, 1); + const direction d2 = cycle_direction(gv.dim, d0, 2); + const component c1 = direction_component(c, d1); + const component c2 = direction_component(c, d2); - const realnum *w1 = W[c1][cmp], *s1 = w1 ? sigma[c1][d1] : NULL; - const realnum *w2 = W[c2][cmp], *s2 = w2 ? sigma[c2][d2] : NULL; - const realnum pb1 = psat * bvec[d1], pb2 = psat * bvec[d2]; - const realnum wb1 = w4pit * bvec[d1], wb2 = w4pit * bvec[d2]; - const int sgn1 = sgn[d0][d1], sgn2 = sgn[d0][d2]; + const realnum *pp = d->P_prev[c][cmp]; + const realnum *p1 = d->P[c1][cmp], *pp1 = d->P_prev[c1][cmp]; + const realnum *p2 = d->P[c2][cmp], *pp2 = d->P_prev[c2][cmp]; + realnum *ptmp = d->P_tmp[c][cmp]; + + const realnum *w1 = W[c1][cmp], *s1 = w1 ? sigma[c1][d1] : NULL; + const realnum *w2 = W[c2][cmp], *s2 = w2 ? sigma[c2][d2] : NULL; + const realnum pb1 = psat * bvec[d1], pb2 = psat * bvec[d2]; + const realnum wb1 = w4pit * bvec[d1], wb2 = w4pit * bvec[d2]; + const int sgn1 = sgn[d0][d1], sgn2 = sgn[d0][d2]; - if (!pp1 || !pp2 || !p1 || !p2 || !s1 || !s2) - abort("Gyrotropic media require 3D fields\n"); + if (!pp1 || !pp2 || !p1 || !p2 || !s1 || !s2) + abort("Gyrotropic media require 3D fields\n"); - LOOP_OVER_VOL_OWNED(gv, c, i) { - ptmp[i] = pp[i] - + sgn1 * ((g2pi * pp1[i] + dt4pi*s1[i]*w1[i]) * (pb2+p2[i]) + wb1*p2[i]) - + sgn2 * ((g2pi * pp2[i] + dt4pi*s2[i]*w2[i]) * (pb1+p1[i]) + wb2*p1[i]); - } + LOOP_OVER_VOL(gv, c, i) { + ptmp[i] = pp[i] + + sgn1 * ((g2pi * pp1[i] + dt4pi*s1[i]*w1[i]) * (pb2+p2[i]) + wb1*p2[i]) + + sgn2 * ((g2pi * pp2[i] + dt4pi*s2[i]*w2[i]) * (pb1+p1[i]) + wb2*p1[i]); } } } @@ -400,7 +399,7 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], if (W[c][cmp] && sigma[c][component_direction(c)]) { const realnum *p = d->P[c][cmp]; realnum *pp = d->P_prev[c][cmp]; - LOOP_OVER_VOL_OWNED(gv, c, i) { + LOOP_OVER_VOL(gv, c, i) { pp[i] = p[i]; } } @@ -425,7 +424,7 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const int sgn1 = sgn[d0][d1], sgn2 = sgn[d0][d2]; realnum gp0, gp1, gp2; - LOOP_OVER_VOL_OWNED(gv, c, i) { + LOOP_OVER_VOL(gv, c, i) { gp0 = g2pi * (pb0 + pp[i]); gp1 = g2pi * (pb1 + pp1[i]); gp2 = g2pi * (pb2 + pp2[i]); @@ -437,6 +436,40 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], } } } + + // FIXME: hack to clamp the magnitude of the total polarization vector at psat. + FOR_COMPONENTS(c) DOCMP2 { + if (d->P[c][cmp]) { + const direction d0 = component_direction(c); + const direction d1 = cycle_direction(gv.dim, d0, 1); + const direction d2 = cycle_direction(gv.dim, d0, 2); + const component c1 = direction_component(c, d1); + const component c2 = direction_component(c, d2); + + const realnum *p = d->P[c][cmp]; + const realnum *p1 = d->P_prev[c1][cmp], *p2 = d->P_prev[c2][cmp]; + const realnum pb0 = psat * bvec[d0]; + const realnum pb1 = psat * bvec[d1], pb2 = psat * bvec[d2]; + realnum *ptmp = d->P_tmp[c][cmp]; + realnum ptot0, ptot1, ptot2; + + LOOP_OVER_VOL(gv, c, i) { + ptot0 = pb0 + p[i]; + ptot1 = pb1 + p1[i]; + ptot2 = pb2 + p2[i]; + ptmp[i] = ptot0*psat/sqrt(ptot0*ptot0+ptot1*ptot1+ptot2*ptot2) - pb0; + } + } + } + FOR_COMPONENTS(c) DOCMP2 { + if (d->P[c][cmp]) { + realnum *p = d->P[c][cmp]; + const realnum *ptmp = d->P_tmp[c][cmp]; + LOOP_OVER_VOL(gv, c, i) { + p[i] = ptmp[i]; + } + } + } } void gyrotropic_susceptibility::subtract_P(field_type ft, From 9364b6f3ffc18a41a2cd67e8a693686ac39592bc Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Tue, 28 May 2019 13:34:12 +0800 Subject: [PATCH 27/61] Revert inadvertent unrelated change to meep.i --- python/meep.i | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/python/meep.i b/python/meep.i index 3f576efd9..998f13133 100644 --- a/python/meep.i +++ b/python/meep.i @@ -749,21 +749,21 @@ meep::volume_list *make_volume_list(const meep::volume &v, int c, } %typemap(in) const meep::src_time & { - PyObject *swig_obj_1 = NULL; + PyObject *swig_obj = NULL; void *tmp_ptr = 0; int tmp_res = 0; if(PyObject_IsInstance($input, py_source_time_object())) { - swig_obj_1 = PyObject_GetAttrString($input, "swigobj"); + swig_obj = PyObject_GetAttrString($input, "swigobj"); } else if(PyObject_IsInstance($input, py_meep_src_time_object())) { - swig_obj_1 = $input; - Py_XINCREF(swig_obj_1); + swig_obj = $input; + Py_XINCREF(swig_obj); } else { meep::abort("Expected a meep.source.SourceTime or a meep.src_time\n"); } - tmp_res = SWIG_ConvertPtr(swig_obj_1, &tmp_ptr, $1_descriptor, 0); - Py_XDECREF(swig_obj_1); + tmp_res = SWIG_ConvertPtr(swig_obj, &tmp_ptr, $1_descriptor, 0); + Py_XDECREF(swig_obj); if(!SWIG_IsOK(tmp_res)) { SWIG_exception_fail(SWIG_ArgError(tmp_res), "Couldn't convert Python object to meep::src_time"); From 18831d288f5e1b457713cb3b051d4fcf2162f569 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Tue, 28 May 2019 15:15:29 +0800 Subject: [PATCH 28/61] Minor code cleanup --- python/geom.py | 2 +- src/susceptibility.cpp | 29 ++++++++++------------------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/python/geom.py b/python/geom.py index e4d8fec14..9b8744f6c 100644 --- a/python/geom.py +++ b/python/geom.py @@ -282,7 +282,7 @@ def __init__(self, noise_amp=0.0, **kwargs): class GyrotropicLorentzianSusceptibility(LorentzianSusceptibility): - def __init__(self, bias=Vector3(0, 0, 1), **kwargs): + def __init__(self, bias=Vector3(), **kwargs): super(GyrotropicLorentzianSusceptibility, self).__init__(**kwargs) self.bias = bias diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 4c65f1844..3d67c709b 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -364,7 +364,7 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const realnum *w = W[c][cmp], *s = sigma[c][d0]; if (!w || !s || (d0 != X && d0 != Y && d0 != Z)) - abort("Non-3D fields not supported for gyrotropic media\n"); + abort("Gyrotropic media require 3D Cartesian fields\n"); const realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; realnum *rhs = d->P_tmp[c][cmp]; @@ -379,17 +379,13 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const realnum *w1 = W[c1][cmp], *s1 = w1 ? sigma[c][d1] : NULL; const realnum *w2 = W[c2][cmp], *s2 = w2 ? sigma[c][d2] : NULL; - const realnum *pp1 = d->P_prev[c1][cmp], g1 = pi * dt * gyro_tensor[d0][d1]; - const realnum *pp2 = d->P_prev[c2][cmp], g2 = pi * dt * gyro_tensor[d0][d2]; - - const realnum *p1 = d->P[c1][cmp]; - const realnum *p2 = d->P[c2][cmp]; - - realnum *rhs1 = d->P_tmp[c1][cmp]; - realnum *rhs2 = d->P_tmp[c2][cmp]; + const realnum *pp1 = d->P_prev[c1][cmp], g1 = pi*dt*gyro_tensor[d0][d1]; + const realnum *pp2 = d->P_prev[c2][cmp], g2 = pi*dt*gyro_tensor[d0][d2]; + const realnum *p1 = d->P[c1][cmp], *p2 = d->P[c2][cmp]; + realnum *rhs1 = d->P_tmp[c1][cmp], *rhs2 = d->P_tmp[c2][cmp]; if (!pp1 || !pp2) - abort("Non-3D fields not supported for gyrotropic media\n"); + abort("Gyrotropic media require 3D Cartesian fields\n"); if (s2 && !s1) { // make s1 the non-NULL one if possible SWAP(direction, d1, d2); @@ -448,20 +444,15 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], if (d->P[c][cmp]) { const direction d0 = component_direction(c); realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; - const realnum *rhs = d->P_tmp[c][cmp]; + const realnum *rhs0 = d->P_tmp[c][cmp]; const direction d1 = cycle_direction(gv.dim, d0, 1); const direction d2 = cycle_direction(gv.dim, d0, 2); - const component c1 = direction_component(c, d1); - const component c2 = direction_component(c, d2); - const realnum *rhs1 = d->P_tmp[c1][cmp]; - const realnum *rhs2 = d->P_tmp[c2][cmp]; - - if (!rhs || !rhs1 || !rhs2) - abort("Internal error in gyrotropy code\n"); + const realnum *rhs1 = d->P_tmp[direction_component(c, d1)][cmp]; + const realnum *rhs2 = d->P_tmp[direction_component(c, d2)][cmp]; LOOP_OVER_VOL(gv, c, i) { pp[i] = p[i]; - p[i] = inv[d0][d0] * rhs[i] + inv[d0][d1] * rhs1[i] + inv[d0][d2] * rhs2[i]; + p[i] = inv[d0][d0] * rhs0[i] + inv[d0][d1] * rhs1[i] + inv[d0][d2] * rhs2[i]; } } } From 006365d251639bb0868b6bac0a3ba0c2ec9dcbf8 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 29 May 2019 10:57:36 +0800 Subject: [PATCH 29/61] Flag "needs_W_notowned" for gyrotropic media --- src/meep.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/meep.hpp b/src/meep.hpp index c03283e09..4fffd168f 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -287,6 +287,11 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { virtual void dump_params(h5file *h5f, size_t *start); virtual int get_num_params() { return 7; } + virtual bool needs_W_notowned(component c, realnum *W[NUM_FIELD_COMPONENTS][2]) const { + (void)c; + (void)W; + return true; + } protected: double gyro_tensor[3][3]; From 021cf485c2d17b37a89793fa623d7eabbc3dc4bf Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 30 May 2019 12:55:08 +0800 Subject: [PATCH 30/61] Update gyrotropic P components explicitly; don't use LOOP_OVER_VOL_OWNED --- src/susceptibility.cpp | 112 +++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 71 deletions(-) diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 3d67c709b..323284b3e 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -355,7 +355,7 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const double omega2pi = 2 * pi * omega_0, g2pi = gamma * 2 * pi; const double omega0dtsqr = omega2pi * omega2pi * dt * dt; const double gamma1 = (1 - g2pi * dt / 2); - const double omega0dtsqr_denom = no_omega_0_denominator ? 0 : omega0dtsqr; + const double diagfac = 2 - (no_omega_0_denominator ? 0 : omega0dtsqr); (void)W_prev; // unused; FOR_COMPONENTS(c) DOCMP2 { @@ -364,60 +364,29 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const realnum *w = W[c][cmp], *s = sigma[c][d0]; if (!w || !s || (d0 != X && d0 != Y && d0 != Z)) - abort("Gyrotropic media require 3D Cartesian fields\n"); - - const realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; - realnum *rhs = d->P_tmp[c][cmp]; - const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); - - direction d1 = cycle_direction(gv.dim, d0, 1); - direction d2 = cycle_direction(gv.dim, d0, 2); - component c1 = direction_component(c, d1); - component c2 = direction_component(c, d2); - ptrdiff_t is1 = gv.stride(d1) * (is_magnetic(c) ? -1 : +1); - ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); + abort("gyrotropic media require 3D Cartesian fields\n"); + const direction d1 = cycle_direction(gv.dim, d0, 1); + const direction d2 = cycle_direction(gv.dim, d0, 2); + const component c1 = direction_component(c, d1); + const component c2 = direction_component(c, d2); const realnum *w1 = W[c1][cmp], *s1 = w1 ? sigma[c][d1] : NULL; const realnum *w2 = W[c2][cmp], *s2 = w2 ? sigma[c][d2] : NULL; - const realnum *pp1 = d->P_prev[c1][cmp], g1 = pi*dt*gyro_tensor[d0][d1]; - const realnum *pp2 = d->P_prev[c2][cmp], g2 = pi*dt*gyro_tensor[d0][d2]; - const realnum *p1 = d->P[c1][cmp], *p2 = d->P[c2][cmp]; - realnum *rhs1 = d->P_tmp[c1][cmp], *rhs2 = d->P_tmp[c2][cmp]; - - if (!pp1 || !pp2) - abort("Gyrotropic media require 3D Cartesian fields\n"); - - if (s2 && !s1) { // make s1 the non-NULL one if possible - SWAP(direction, d1, d2); - SWAP(component, c1, c2); - SWAP(ptrdiff_t, is1, is2); - SWAP(const realnum *, w1, w2); - SWAP(const realnum *, s1, s2); - } - if (s1 && s2) { // 3x3 anisotropic - LOOP_OVER_VOL(gv, c, i) { - if (s[i] != 0) { - rhs[i] = (2 - omega0dtsqr_denom) * p[i] - + omega0dtsqr * (s[i] * w[i] - + OFFDIAG(s1, w1, is1, is) - + OFFDIAG(s2, w2, is2, is)) - - gamma1 * pp[i] - g1 * pp1[i] - g2 * pp2[i]; - } - } - } else if (s1) { // 2x2 anisotropic - LOOP_OVER_VOL(gv, c, i) { - if (s[i] != 0) { - rhs[i] = (2 - omega0dtsqr_denom) * p[i] - + omega0dtsqr * (s[i] * w[i] + OFFDIAG(s1, w1, is1, is)) - - gamma1 * pp[i] - g1 * pp1[i] - g2 * pp2[i]; - } - } - } else { // isotropic - LOOP_OVER_VOL(gv, c, i) { - rhs[i] = (2 - omega0dtsqr_denom) * p[i] - + omega0dtsqr * (s[i] * w[i]) - gamma1 * pp[i] - - g1 * pp1[i] - g2 * pp2[i]; - } + const realnum *p0 = d->P[c][cmp], *pp0 = d->P_prev[c][cmp]; + const realnum *p1 = d->P[c1][cmp], *pp1 = d->P_prev[c1][cmp]; + const realnum *p2 = d->P[c2][cmp], *pp2 = d->P_prev[c2][cmp]; + realnum *rhs0 = d->P_tmp[c][cmp], *rhs1 = d->P_tmp[c1][cmp], *rhs2 = d->P_tmp[c2][cmp]; + const realnum g01 = pi*dt*gyro_tensor[d0][d1], g10 = pi*dt*gyro_tensor[d1][d0]; + const realnum g12 = pi*dt*gyro_tensor[d1][d2], g21 = pi*dt*gyro_tensor[d2][d1]; + const realnum g20 = pi*dt*gyro_tensor[d2][d0], g02 = pi*dt*gyro_tensor[d0][d2]; + + if (!pp1 || !pp2) abort("gyrotropic media require 3D Cartesian fields\n"); + if (s1 || s2) abort("gyrotropic media do not support tensor sigma\n"); + + LOOP_OVER_VOL_OWNED(gv, c, i) { + rhs0[i] = diagfac*p0[i] - g01*pp1[i] - g02*pp2[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w[i]; + rhs1[i] = diagfac*p1[i] - g12*pp2[i] - g10*pp0[i] - gamma1*pp1[i]; + rhs2[i] = diagfac*p2[i] - g21*pp1[i] - g20*pp0[i] - gamma1*pp2[i]; } } } @@ -428,31 +397,32 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const double gy = pi * dt * gyro_tensor[Z][X]; const double gz = pi * dt * gyro_tensor[X][Y]; const double invdet = 1.0 / gd / (gd*gd + gx*gx + gy*gy + gz*gz); - double inv[3][3]; - - inv[X][X] = invdet * (gd*gd + gx*gx); - inv[Y][Y] = invdet * (gd*gd + gy*gy); - inv[Z][Z] = invdet * (gd*gd + gz*gz); - inv[X][Y] = invdet * (gx*gy + gd*gz); - inv[Y][X] = invdet * (gy*gx - gd*gz); - inv[Z][X] = invdet * (gz*gx + gd*gy); - inv[X][Z] = invdet * (gx*gz - gd*gy); - inv[Y][Z] = invdet * (gy*gz + gd*gx); - inv[Z][Y] = invdet * (gz*gy - gd*gx); + const double inv[3][3] + = {{ invdet*(gd*gd+gx*gx), invdet*(gx*gy+gd*gz), invdet*(gx*gz-gd*gy) }, + { invdet*(gy*gx-gd*gz), invdet*(gd*gd+gy*gy), invdet*(gy*gz+gd*gx) }, + { invdet*(gz*gx+gd*gy), invdet*(gz*gy-gd*gx), invdet*(gd*gd+gz*gz) }}; FOR_COMPONENTS(c) DOCMP2 { if (d->P[c][cmp]) { const direction d0 = component_direction(c); - realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; - const realnum *rhs0 = d->P_tmp[c][cmp]; const direction d1 = cycle_direction(gv.dim, d0, 1); const direction d2 = cycle_direction(gv.dim, d0, 2); - const realnum *rhs1 = d->P_tmp[direction_component(c, d1)][cmp]; - const realnum *rhs2 = d->P_tmp[direction_component(c, d2)][cmp]; - - LOOP_OVER_VOL(gv, c, i) { - pp[i] = p[i]; - p[i] = inv[d0][d0] * rhs0[i] + inv[d0][d1] * rhs1[i] + inv[d0][d2] * rhs2[i]; + const component c1 = direction_component(c, d1); + const component c2 = direction_component(c, d2); + realnum *p0 = d->P[c][cmp], *pp0 = d->P_prev[c][cmp]; + realnum *p1 = d->P[c1][cmp], *pp1 = d->P_prev[c1][cmp]; + realnum *p2 = d->P[c2][cmp], *pp2 = d->P_prev[c2][cmp]; + const realnum *rhs0 = d->P_tmp[c][cmp]; + const realnum *rhs1 = d->P_tmp[c1][cmp]; + const realnum *rhs2 = d->P_tmp[c2][cmp]; + + LOOP_OVER_VOL_OWNED(gv, c, i) { + pp0[i] = p0[i]; + pp1[i] = p1[i]; + pp2[i] = p2[i]; + p0[i] = inv[d0][d0] * rhs0[i] + inv[d0][d1] * rhs1[i] + inv[d0][d2] * rhs2[i]; + p1[i] = inv[d1][d1] * rhs1[i] + inv[d1][d2] * rhs2[i] + inv[d1][d0] * rhs0[i]; + p2[i] = inv[d2][d2] * rhs2[i] + inv[d2][d0] * rhs0[i] + inv[d2][d1] * rhs1[i]; } } } From 164b5a822983d122a623e91dd73bb7c415c69e94 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 30 May 2019 21:54:32 +0800 Subject: [PATCH 31/61] Enable needs_P on all components for gyrotropic media --- src/meep.hpp | 1 + src/susceptibility.cpp | 45 ++++++++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/meep.hpp b/src/meep.hpp index 4fffd168f..68a69d3f9 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -281,6 +281,7 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { bool no_omega_0_denominator = true); virtual susceptibility *clone() const { return new gyrotropic_susceptibility(*this); } + bool needs_P(component c, int cmp, realnum *W[NUM_FIELD_COMPONENTS][2]) const; virtual void update_P(realnum *W[NUM_FIELD_COMPONENTS][2], realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, const grid_volume &gv, void *P_internal_data) const; diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 323284b3e..1d6815d10 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -348,6 +348,17 @@ gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double ome gyro_tensor[Z][X] = bias.y(); gyro_tensor[X][Z] = -bias.y(); } +bool gyrotropic_susceptibility::needs_P(component c, int cmp, realnum *W[NUM_FIELD_COMPONENTS][2]) const { + if (!is_electric(c) && !is_magnetic(c)) return false; + direction d0 = component_direction(c); + if ((d0 == X || d0 == Y || d0 == Z) && sigma[c][d0]) { + FOR_DIRECTIONS(d) { + if (W[direction_component(c, d)][cmp]) return true; + } + } + return false; +} + void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, const grid_volume &gv, void *P_internal_data) const { @@ -370,23 +381,21 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const direction d2 = cycle_direction(gv.dim, d0, 2); const component c1 = direction_component(c, d1); const component c2 = direction_component(c, d2); - const realnum *w1 = W[c1][cmp], *s1 = w1 ? sigma[c][d1] : NULL; - const realnum *w2 = W[c2][cmp], *s2 = w2 ? sigma[c][d2] : NULL; - const realnum *p0 = d->P[c][cmp], *pp0 = d->P_prev[c][cmp]; - const realnum *p1 = d->P[c1][cmp], *pp1 = d->P_prev[c1][cmp]; - const realnum *p2 = d->P[c2][cmp], *pp2 = d->P_prev[c2][cmp]; - realnum *rhs0 = d->P_tmp[c][cmp], *rhs1 = d->P_tmp[c1][cmp], *rhs2 = d->P_tmp[c2][cmp]; - const realnum g01 = pi*dt*gyro_tensor[d0][d1], g10 = pi*dt*gyro_tensor[d1][d0]; - const realnum g12 = pi*dt*gyro_tensor[d1][d2], g21 = pi*dt*gyro_tensor[d2][d1]; - const realnum g20 = pi*dt*gyro_tensor[d2][d0], g02 = pi*dt*gyro_tensor[d0][d2]; + const realnum *s1 = W[c1][cmp] ? sigma[c][d1] : NULL; + const realnum *s2 = W[c2][cmp] ? sigma[c][d2] : NULL; + const realnum *p = d->P[c][cmp]; + const realnum *pp0 = d->P_prev[c][cmp]; + const realnum *pp1 = d->P_prev[c1][cmp]; + const realnum *pp2 = d->P_prev[c2][cmp]; + realnum *rhs = d->P_tmp[c][cmp]; + const realnum g1 = pi*dt*gyro_tensor[d0][d1], g2 = pi*dt*gyro_tensor[d0][d2]; if (!pp1 || !pp2) abort("gyrotropic media require 3D Cartesian fields\n"); if (s1 || s2) abort("gyrotropic media do not support tensor sigma\n"); LOOP_OVER_VOL_OWNED(gv, c, i) { - rhs0[i] = diagfac*p0[i] - g01*pp1[i] - g02*pp2[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w[i]; - rhs1[i] = diagfac*p1[i] - g12*pp2[i] - g10*pp0[i] - gamma1*pp1[i]; - rhs2[i] = diagfac*p2[i] - g21*pp1[i] - g20*pp0[i] - gamma1*pp2[i]; + rhs[i] = diagfac*p[i] - g1*pp1[i] - g2*pp2[i] - gamma1*pp0[i] + + omega0dtsqr*s[i]*w[i]; } } } @@ -409,20 +418,14 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const direction d2 = cycle_direction(gv.dim, d0, 2); const component c1 = direction_component(c, d1); const component c2 = direction_component(c, d2); - realnum *p0 = d->P[c][cmp], *pp0 = d->P_prev[c][cmp]; - realnum *p1 = d->P[c1][cmp], *pp1 = d->P_prev[c1][cmp]; - realnum *p2 = d->P[c2][cmp], *pp2 = d->P_prev[c2][cmp]; + realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; const realnum *rhs0 = d->P_tmp[c][cmp]; const realnum *rhs1 = d->P_tmp[c1][cmp]; const realnum *rhs2 = d->P_tmp[c2][cmp]; LOOP_OVER_VOL_OWNED(gv, c, i) { - pp0[i] = p0[i]; - pp1[i] = p1[i]; - pp2[i] = p2[i]; - p0[i] = inv[d0][d0] * rhs0[i] + inv[d0][d1] * rhs1[i] + inv[d0][d2] * rhs2[i]; - p1[i] = inv[d1][d1] * rhs1[i] + inv[d1][d2] * rhs2[i] + inv[d1][d0] * rhs0[i]; - p2[i] = inv[d2][d2] * rhs2[i] + inv[d2][d0] * rhs0[i] + inv[d2][d1] * rhs1[i]; + pp[i] = p[i]; + p[i] = inv[d0][d0] * rhs0[i] + inv[d0][d1] * rhs1[i] + inv[d0][d2] * rhs2[i]; } } } From 6515785d14d3cde4cf1ec2bf3d5e04ba225304e2 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 30 May 2019 22:59:37 +0800 Subject: [PATCH 32/61] Fix gyrotropy scheme to track 9 polarization components per unit cell. --- python/meep.i | 12 +-- src/meep.hpp | 11 ++- src/susceptibility.cpp | 184 +++++++++++++++++++++++++++++------------ 3 files changed, 147 insertions(+), 60 deletions(-) diff --git a/python/meep.i b/python/meep.i index 998f13133..3f576efd9 100644 --- a/python/meep.i +++ b/python/meep.i @@ -749,21 +749,21 @@ meep::volume_list *make_volume_list(const meep::volume &v, int c, } %typemap(in) const meep::src_time & { - PyObject *swig_obj = NULL; + PyObject *swig_obj_1 = NULL; void *tmp_ptr = 0; int tmp_res = 0; if(PyObject_IsInstance($input, py_source_time_object())) { - swig_obj = PyObject_GetAttrString($input, "swigobj"); + swig_obj_1 = PyObject_GetAttrString($input, "swigobj"); } else if(PyObject_IsInstance($input, py_meep_src_time_object())) { - swig_obj = $input; - Py_XINCREF(swig_obj); + swig_obj_1 = $input; + Py_XINCREF(swig_obj_1); } else { meep::abort("Expected a meep.source.SourceTime or a meep.src_time\n"); } - tmp_res = SWIG_ConvertPtr(swig_obj, &tmp_ptr, $1_descriptor, 0); - Py_XDECREF(swig_obj); + tmp_res = SWIG_ConvertPtr(swig_obj_1, &tmp_ptr, $1_descriptor, 0); + Py_XDECREF(swig_obj_1); if(!SWIG_IsOK(tmp_res)) { SWIG_exception_fail(SWIG_ArgError(tmp_res), "Couldn't convert Python object to meep::src_time"); diff --git a/src/meep.hpp b/src/meep.hpp index 68a69d3f9..79caf4480 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -223,8 +223,7 @@ class susceptibility { class lorentzian_susceptibility : public susceptibility { public: lorentzian_susceptibility(double omega_0, double gamma, bool no_omega_0_denominator = false) - : omega_0(omega_0), gamma(gamma), no_omega_0_denominator(no_omega_0_denominator), - have_gyrotropy(false) {} + : omega_0(omega_0), gamma(gamma), no_omega_0_denominator(no_omega_0_denominator) {} virtual susceptibility *clone() const { return new lorentzian_susceptibility(*this); } virtual ~lorentzian_susceptibility() {} @@ -250,7 +249,6 @@ class lorentzian_susceptibility : public susceptibility { protected: double omega_0, gamma; bool no_omega_0_denominator; - bool have_gyrotropy; // whether to assign an extra slot for gyrotropy calculations }; /* like a Lorentzian susceptibility, but the polarization equation @@ -281,10 +279,17 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { bool no_omega_0_denominator = true); virtual susceptibility *clone() const { return new gyrotropic_susceptibility(*this); } + void *new_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv) const; + void init_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], double dt, + const grid_volume &gv, void *data) const; + void *copy_internal_data(void *data) const; + bool needs_P(component c, int cmp, realnum *W[NUM_FIELD_COMPONENTS][2]) const; virtual void update_P(realnum *W[NUM_FIELD_COMPONENTS][2], realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, const grid_volume &gv, void *P_internal_data) const; + void subtract_P(field_type ft, realnum *f_minus_p[NUM_FIELD_COMPONENTS][2], + void *P_internal_data) const; virtual void dump_params(h5file *h5f, size_t *start); virtual int get_num_params() { return 7; } diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 1d6815d10..4cb5a07dc 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -92,7 +92,6 @@ typedef struct { size_t ntot; realnum *P[NUM_FIELD_COMPONENTS][2]; realnum *P_prev[NUM_FIELD_COMPONENTS][2]; - realnum *P_tmp[NUM_FIELD_COMPONENTS][2]; // extra slot used for gyrotropic medium updating realnum data[1]; } lorentzian_data; @@ -101,9 +100,8 @@ typedef struct { void *lorentzian_susceptibility::new_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv) const { int num = 0; - int nslots = have_gyrotropy ? 3 : 2; FOR_COMPONENTS(c) DOCMP2 { - if (needs_P(c, cmp, W)) num += nslots * gv.ntot(); + if (needs_P(c, cmp, W)) num += 2 * gv.ntot(); } size_t sz = sizeof(lorentzian_data) + sizeof(realnum) * (num - 1); lorentzian_data *d = (lorentzian_data *)malloc(sz); @@ -121,18 +119,12 @@ void lorentzian_susceptibility::init_internal_data(realnum *W[NUM_FIELD_COMPONEN size_t ntot = d->ntot = gv.ntot(); realnum *P = d->data; realnum *P_prev = d->data + ntot; - realnum *P_tmp = have_gyrotropy ? P_prev + ntot : NULL; - int nslots = have_gyrotropy ? 3 : 2; - FOR_COMPONENTS(c) DOCMP2 { if (needs_P(c, cmp, W)) { d->P[c][cmp] = P; d->P_prev[c][cmp] = P_prev; - d->P_tmp[c][cmp] = P_tmp; - - P += nslots * ntot; - P_prev += nslots * ntot; - if (have_gyrotropy) P_tmp += nslots * ntot; + P += 2 * ntot; + P_prev += 2 * ntot; } } } @@ -145,17 +137,12 @@ void *lorentzian_susceptibility::copy_internal_data(void *data) const { size_t ntot = d->ntot; realnum *P = dnew->data; realnum *P_prev = dnew->data + ntot; - realnum *P_tmp = have_gyrotropy ? P_prev + ntot : NULL; - int nslots = have_gyrotropy ? 3 : 2; - FOR_COMPONENTS(c) DOCMP2 { if (d->P[c][cmp]) { dnew->P[c][cmp] = P; dnew->P_prev[c][cmp] = P_prev; - dnew->P_tmp[c][cmp] = P_tmp; - P += nslots * ntot; - P_prev += nslots * ntot; - if (have_gyrotropy) P_tmp += nslots * ntot; + P += 2 * ntot; + P_prev += 2 * ntot; } } return (void *)dnew; @@ -339,8 +326,6 @@ void noisy_lorentzian_susceptibility::dump_params(h5file *h5f, size_t *start) { gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma, bool no_omega_0_denominator) : lorentzian_susceptibility(omega_0, gamma, no_omega_0_denominator) { - have_gyrotropy = true; - // Precalculate g_{ij} = sum_k epsilon_{ijk} b_k, used in update_P. memset(gyro_tensor, 0, 9 * sizeof(double)); gyro_tensor[X][Y] = bias.z(); gyro_tensor[Y][X] = -bias.z(); @@ -348,6 +333,73 @@ gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double ome gyro_tensor[Z][X] = bias.y(); gyro_tensor[X][Z] = -bias.y(); } +/* To implement gyrotropic susceptibilities, we track three + polarization components (e.g. Px, Py, Pz) on EACH of the Yee cell's + three driving field positions (e.g., Ex, Ey, and Ez), i.e. 9 + numbers per cell. This takes 3x the memory and runtime compared to + Lorentzian susceptibility. The advantage is that during update_P, + we can directly access the value of P at each update point without + averaging. */ + +typedef struct { + size_t sz_data; + size_t ntot; + realnum *P[NUM_FIELD_COMPONENTS][2][3]; + realnum *P_prev[NUM_FIELD_COMPONENTS][2][3]; + realnum *P_tmp[NUM_FIELD_COMPONENTS][2][3]; + realnum data[1]; +} gyrotropy_data; + +void *gyrotropic_susceptibility::new_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], + const grid_volume &gv) const { + int num = 0; + FOR_COMPONENTS(c) DOCMP2 { + if (needs_P(c, cmp, W)) num += 9 * gv.ntot(); + } + size_t sz = sizeof(gyrotropy_data) + sizeof(realnum) * (num - 1); + gyrotropy_data *d = (gyrotropy_data *)malloc(sz); + d->sz_data = sz; + return (void *)d; +} + +void gyrotropic_susceptibility::init_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], double dt, + const grid_volume &gv, void *data) const { + (void)dt; // unused + gyrotropy_data *d = (gyrotropy_data *)data; + size_t sz_data = d->sz_data; + memset(d, 0, sz_data); + d->sz_data = sz_data; + d->ntot = gv.ntot(); + realnum *p = d->data; + FOR_COMPONENTS(c) DOCMP2 { + if (needs_P(c, cmp, W)) { + for (int dd = X; dd < R; dd++) { + d->P[c][cmp][dd] = p; p += d->ntot; + d->P_prev[c][cmp][dd] = p; p += d->ntot; + d->P_tmp[c][cmp][dd] = p; p += d->ntot; + } + } + } +} + +void *gyrotropic_susceptibility::copy_internal_data(void *data) const { + gyrotropy_data *d = (gyrotropy_data *)data; + if (!d) return 0; + gyrotropy_data *dnew = (gyrotropy_data *)malloc(d->sz_data); + memcpy(dnew, d, d->sz_data); + realnum *p = dnew->data; + FOR_COMPONENTS(c) DOCMP2 { + if (d->P[c][cmp][0]) { + for (int dd = X; dd < R; dd++) { + dnew->P[c][cmp][dd] = p; p += d->ntot; + dnew->P_prev[c][cmp][dd] = p; p += d->ntot; + dnew->P_tmp[c][cmp][dd] = p; p += d->ntot; + } + } + } + return (void *)dnew; +} + bool gyrotropic_susceptibility::needs_P(component c, int cmp, realnum *W[NUM_FIELD_COMPONENTS][2]) const { if (!is_electric(c) && !is_magnetic(c)) return false; direction d0 = component_direction(c); @@ -362,49 +414,58 @@ bool gyrotropic_susceptibility::needs_P(component c, int cmp, realnum *W[NUM_FIE void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, const grid_volume &gv, void *P_internal_data) const { - lorentzian_data *d = (lorentzian_data *)P_internal_data; + gyrotropy_data *d = (gyrotropy_data *)P_internal_data; const double omega2pi = 2 * pi * omega_0, g2pi = gamma * 2 * pi; const double omega0dtsqr = omega2pi * omega2pi * dt * dt; const double gamma1 = (1 - g2pi * dt / 2); const double diagfac = 2 - (no_omega_0_denominator ? 0 : omega0dtsqr); + const double pt = pi*dt; (void)W_prev; // unused; FOR_COMPONENTS(c) DOCMP2 { - if (d->P[c][cmp]) { + if (d->P[c][cmp][0]) { const direction d0 = component_direction(c); - const realnum *w = W[c][cmp], *s = sigma[c][d0]; + const realnum *w0 = W[c][cmp], *s = sigma[c][d0]; - if (!w || !s || (d0 != X && d0 != Y && d0 != Z)) + if (!w0 || !s || (d0 != X && d0 != Y && d0 != Z)) abort("gyrotropic media require 3D Cartesian fields\n"); const direction d1 = cycle_direction(gv.dim, d0, 1); const direction d2 = cycle_direction(gv.dim, d0, 2); - const component c1 = direction_component(c, d1); - const component c2 = direction_component(c, d2); - const realnum *s1 = W[c1][cmp] ? sigma[c][d1] : NULL; - const realnum *s2 = W[c2][cmp] ? sigma[c][d2] : NULL; - const realnum *p = d->P[c][cmp]; - const realnum *pp0 = d->P_prev[c][cmp]; - const realnum *pp1 = d->P_prev[c1][cmp]; - const realnum *pp2 = d->P_prev[c2][cmp]; - realnum *rhs = d->P_tmp[c][cmp]; - const realnum g1 = pi*dt*gyro_tensor[d0][d1], g2 = pi*dt*gyro_tensor[d0][d2]; - - if (!pp1 || !pp2) abort("gyrotropic media require 3D Cartesian fields\n"); - if (s1 || s2) abort("gyrotropic media do not support tensor sigma\n"); + const realnum *w1 = W[direction_component(c, d1)][cmp]; + const realnum *w2 = W[direction_component(c, d2)][cmp]; + const realnum *p0 = d->P[c][cmp][d0], *pp0 = d->P_prev[c][cmp][d0]; + const realnum *p1 = d->P[c][cmp][d1], *pp1 = d->P_prev[c][cmp][d1]; + const realnum *p2 = d->P[c][cmp][d2], *pp2 = d->P_prev[c][cmp][d2]; + realnum *rhs0 = d->P_tmp[c][cmp][d0]; + realnum *rhs1 = d->P_tmp[c][cmp][d1]; + realnum *rhs2 = d->P_tmp[c][cmp][d2]; + const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); + const ptrdiff_t is1 = gv.stride(d1) * (is_magnetic(c) ? -1 : +1); + const ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); + + if (!pp1 || !pp2 || !w1 || !w2) + abort("gyrotropic media require 3D Cartesian fields\n"); + + if (sigma[c][d1] || sigma[c][d2]) + abort("gyrotropic media do not support tensor sigma\n"); LOOP_OVER_VOL_OWNED(gv, c, i) { - rhs[i] = diagfac*p[i] - g1*pp1[i] - g2*pp2[i] - gamma1*pp0[i] - + omega0dtsqr*s[i]*w[i]; + rhs0[i] = diagfac*p0[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w0[i] + - pt*gyro_tensor[d0][d1]*pp1[i] - pt*gyro_tensor[d0][d2]*pp2[i]; + rhs1[i] = diagfac*p1[i] - gamma1*pp1[i] + omega0dtsqr*s[i]*OFFDIAG(s,w1,is1,is) + - pt*gyro_tensor[d1][d0]*pp0[i] - pt*gyro_tensor[d1][d2]*pp2[i]; + rhs2[i] = diagfac*p2[i] - gamma1*pp2[i] + omega0dtsqr*s[i]*OFFDIAG(s,w2,is2,is) + - pt*gyro_tensor[d2][d1]*pp1[i] - pt*gyro_tensor[d2][d0]*pp0[i]; } } } // Perform 3x3 matrix inversion, exploiting skew symmetry const double gd = (1 + g2pi * dt / 2); - const double gx = pi * dt * gyro_tensor[Y][Z]; - const double gy = pi * dt * gyro_tensor[Z][X]; - const double gz = pi * dt * gyro_tensor[X][Y]; + const double gx = pt * gyro_tensor[Y][Z]; + const double gy = pt * gyro_tensor[Z][X]; + const double gz = pt * gyro_tensor[X][Y]; const double invdet = 1.0 / gd / (gd*gd + gx*gx + gy*gy + gz*gz); const double inv[3][3] = {{ invdet*(gd*gd+gx*gx), invdet*(gx*gy+gd*gz), invdet*(gx*gz-gd*gy) }, @@ -412,20 +473,41 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], { invdet*(gz*gx+gd*gy), invdet*(gz*gy-gd*gx), invdet*(gd*gd+gz*gz) }}; FOR_COMPONENTS(c) DOCMP2 { - if (d->P[c][cmp]) { + if (d->P[c][cmp][0]) { const direction d0 = component_direction(c); const direction d1 = cycle_direction(gv.dim, d0, 1); const direction d2 = cycle_direction(gv.dim, d0, 2); - const component c1 = direction_component(c, d1); - const component c2 = direction_component(c, d2); - realnum *p = d->P[c][cmp], *pp = d->P_prev[c][cmp]; - const realnum *rhs0 = d->P_tmp[c][cmp]; - const realnum *rhs1 = d->P_tmp[c1][cmp]; - const realnum *rhs2 = d->P_tmp[c2][cmp]; + realnum *p0 = d->P[c][cmp][d0], *pp0 = d->P_prev[c][cmp][d0]; + realnum *p1 = d->P[c][cmp][d1], *pp1 = d->P_prev[c][cmp][d1]; + realnum *p2 = d->P[c][cmp][d2], *pp2 = d->P_prev[c][cmp][d2]; + const realnum *rhs0 = d->P_tmp[c][cmp][d0]; + const realnum *rhs1 = d->P_tmp[c][cmp][d1]; + const realnum *rhs2 = d->P_tmp[c][cmp][d2]; LOOP_OVER_VOL_OWNED(gv, c, i) { - pp[i] = p[i]; - p[i] = inv[d0][d0] * rhs0[i] + inv[d0][d1] * rhs1[i] + inv[d0][d2] * rhs2[i]; + pp0[i] = p0[i]; pp1[i] = p1[i]; pp2[i] = p2[i]; + p0[i] = inv[d0][d0] * rhs0[i] + inv[d0][d1] * rhs1[i] + inv[d0][d2] * rhs2[i]; + p1[i] = inv[d1][d0] * rhs0[i] + inv[d1][d1] * rhs1[i] + inv[d1][d2] * rhs2[i]; + p2[i] = inv[d2][d0] * rhs0[i] + inv[d2][d1] * rhs1[i] + inv[d2][d2] * rhs2[i]; + } + } + } +} + +void gyrotropic_susceptibility::subtract_P(field_type ft, + realnum *f_minus_p[NUM_FIELD_COMPONENTS][2], + void *P_internal_data) const { + gyrotropy_data *d = (gyrotropy_data *)P_internal_data; + field_type ft2 = ft == E_stuff ? D_stuff : B_stuff; // for sources etc. + size_t ntot = d->ntot; + FOR_FT_COMPONENTS(ft, ec) DOCMP2 { + if (d->P[ec][cmp][0]) { + component dc = field_type_component(ft2, ec); + if (f_minus_p[dc][cmp]) { + realnum *p = d->P[ec][cmp][component_direction(ec)]; + realnum *fmp = f_minus_p[dc][cmp]; + for (size_t i = 0; i < ntot; ++i) + fmp[i] -= p[i]; } } } From be5ae68e0c7e9c13b0ff67aef2f3a582e07a7e0a Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 30 May 2019 23:00:23 +0800 Subject: [PATCH 33/61] Revert unrelated last change to meep.i --- python/meep.i | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/python/meep.i b/python/meep.i index 3f576efd9..998f13133 100644 --- a/python/meep.i +++ b/python/meep.i @@ -749,21 +749,21 @@ meep::volume_list *make_volume_list(const meep::volume &v, int c, } %typemap(in) const meep::src_time & { - PyObject *swig_obj_1 = NULL; + PyObject *swig_obj = NULL; void *tmp_ptr = 0; int tmp_res = 0; if(PyObject_IsInstance($input, py_source_time_object())) { - swig_obj_1 = PyObject_GetAttrString($input, "swigobj"); + swig_obj = PyObject_GetAttrString($input, "swigobj"); } else if(PyObject_IsInstance($input, py_meep_src_time_object())) { - swig_obj_1 = $input; - Py_XINCREF(swig_obj_1); + swig_obj = $input; + Py_XINCREF(swig_obj); } else { meep::abort("Expected a meep.source.SourceTime or a meep.src_time\n"); } - tmp_res = SWIG_ConvertPtr(swig_obj_1, &tmp_ptr, $1_descriptor, 0); - Py_XDECREF(swig_obj_1); + tmp_res = SWIG_ConvertPtr(swig_obj, &tmp_ptr, $1_descriptor, 0); + Py_XDECREF(swig_obj); if(!SWIG_IsOK(tmp_res)) { SWIG_exception_fail(SWIG_ArgError(tmp_res), "Couldn't convert Python object to meep::src_time"); From 795fef522dd4c729c466e3fe9e2bbb62564c31da Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 31 May 2019 11:57:21 +0800 Subject: [PATCH 34/61] Avoiding need for allocation of P_tmp in gyrotropy_data. --- src/susceptibility.cpp | 65 ++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 43 deletions(-) diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 4cb5a07dc..2040cf260 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -346,7 +346,6 @@ typedef struct { size_t ntot; realnum *P[NUM_FIELD_COMPONENTS][2][3]; realnum *P_prev[NUM_FIELD_COMPONENTS][2][3]; - realnum *P_tmp[NUM_FIELD_COMPONENTS][2][3]; realnum data[1]; } gyrotropy_data; @@ -354,7 +353,7 @@ void *gyrotropic_susceptibility::new_internal_data(realnum *W[NUM_FIELD_COMPONEN const grid_volume &gv) const { int num = 0; FOR_COMPONENTS(c) DOCMP2 { - if (needs_P(c, cmp, W)) num += 9 * gv.ntot(); + if (needs_P(c, cmp, W)) num += 6 * gv.ntot(); } size_t sz = sizeof(gyrotropy_data) + sizeof(realnum) * (num - 1); gyrotropy_data *d = (gyrotropy_data *)malloc(sz); @@ -376,7 +375,6 @@ void gyrotropic_susceptibility::init_internal_data(realnum *W[NUM_FIELD_COMPONEN for (int dd = X; dd < R; dd++) { d->P[c][cmp][dd] = p; p += d->ntot; d->P_prev[c][cmp][dd] = p; p += d->ntot; - d->P_tmp[c][cmp][dd] = p; p += d->ntot; } } } @@ -393,7 +391,6 @@ void *gyrotropic_susceptibility::copy_internal_data(void *data) const { for (int dd = X; dd < R; dd++) { dnew->P[c][cmp][dd] = p; p += d->ntot; dnew->P_prev[c][cmp][dd] = p; p += d->ntot; - dnew->P_tmp[c][cmp][dd] = p; p += d->ntot; } } } @@ -422,6 +419,17 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const double pt = pi*dt; (void)W_prev; // unused; + // Precalculate 3x3 matrix inverse, exploiting skew symmetry + const double gd = (1 + g2pi * dt / 2); + const double gx = pt * gyro_tensor[Y][Z]; + const double gy = pt * gyro_tensor[Z][X]; + const double gz = pt * gyro_tensor[X][Y]; + const double invdet = 1.0 / gd / (gd*gd + gx*gx + gy*gy + gz*gz); + const double inv[3][3] + = {{ invdet*(gd*gd+gx*gx), invdet*(gx*gy+gd*gz), invdet*(gx*gz-gd*gy) }, + { invdet*(gy*gx-gd*gz), invdet*(gd*gd+gy*gy), invdet*(gy*gz+gd*gx) }, + { invdet*(gz*gx+gd*gy), invdet*(gz*gy-gd*gx), invdet*(gd*gd+gz*gz) }}; + FOR_COMPONENTS(c) DOCMP2 { if (d->P[c][cmp][0]) { const direction d0 = component_direction(c); @@ -434,15 +442,13 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const direction d2 = cycle_direction(gv.dim, d0, 2); const realnum *w1 = W[direction_component(c, d1)][cmp]; const realnum *w2 = W[direction_component(c, d2)][cmp]; - const realnum *p0 = d->P[c][cmp][d0], *pp0 = d->P_prev[c][cmp][d0]; - const realnum *p1 = d->P[c][cmp][d1], *pp1 = d->P_prev[c][cmp][d1]; - const realnum *p2 = d->P[c][cmp][d2], *pp2 = d->P_prev[c][cmp][d2]; - realnum *rhs0 = d->P_tmp[c][cmp][d0]; - realnum *rhs1 = d->P_tmp[c][cmp][d1]; - realnum *rhs2 = d->P_tmp[c][cmp][d2]; + realnum *p0 = d->P[c][cmp][d0], *pp0 = d->P_prev[c][cmp][d0]; + realnum *p1 = d->P[c][cmp][d1], *pp1 = d->P_prev[c][cmp][d1]; + realnum *p2 = d->P[c][cmp][d2], *pp2 = d->P_prev[c][cmp][d2]; const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); const ptrdiff_t is1 = gv.stride(d1) * (is_magnetic(c) ? -1 : +1); const ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); + realnum rhs0, rhs1, rhs2; if (!pp1 || !pp2 || !w1 || !w2) abort("gyrotropic media require 3D Cartesian fields\n"); @@ -451,44 +457,17 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], abort("gyrotropic media do not support tensor sigma\n"); LOOP_OVER_VOL_OWNED(gv, c, i) { - rhs0[i] = diagfac*p0[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w0[i] + rhs0 = diagfac*p0[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w0[i] - pt*gyro_tensor[d0][d1]*pp1[i] - pt*gyro_tensor[d0][d2]*pp2[i]; - rhs1[i] = diagfac*p1[i] - gamma1*pp1[i] + omega0dtsqr*s[i]*OFFDIAG(s,w1,is1,is) + rhs1 = diagfac*p1[i] - gamma1*pp1[i] + omega0dtsqr*s[i]*OFFDIAG(s,w1,is1,is) - pt*gyro_tensor[d1][d0]*pp0[i] - pt*gyro_tensor[d1][d2]*pp2[i]; - rhs2[i] = diagfac*p2[i] - gamma1*pp2[i] + omega0dtsqr*s[i]*OFFDIAG(s,w2,is2,is) + rhs2 = diagfac*p2[i] - gamma1*pp2[i] + omega0dtsqr*s[i]*OFFDIAG(s,w2,is2,is) - pt*gyro_tensor[d2][d1]*pp1[i] - pt*gyro_tensor[d2][d0]*pp0[i]; - } - } - } - - // Perform 3x3 matrix inversion, exploiting skew symmetry - const double gd = (1 + g2pi * dt / 2); - const double gx = pt * gyro_tensor[Y][Z]; - const double gy = pt * gyro_tensor[Z][X]; - const double gz = pt * gyro_tensor[X][Y]; - const double invdet = 1.0 / gd / (gd*gd + gx*gx + gy*gy + gz*gz); - const double inv[3][3] - = {{ invdet*(gd*gd+gx*gx), invdet*(gx*gy+gd*gz), invdet*(gx*gz-gd*gy) }, - { invdet*(gy*gx-gd*gz), invdet*(gd*gd+gy*gy), invdet*(gy*gz+gd*gx) }, - { invdet*(gz*gx+gd*gy), invdet*(gz*gy-gd*gx), invdet*(gd*gd+gz*gz) }}; - FOR_COMPONENTS(c) DOCMP2 { - if (d->P[c][cmp][0]) { - const direction d0 = component_direction(c); - const direction d1 = cycle_direction(gv.dim, d0, 1); - const direction d2 = cycle_direction(gv.dim, d0, 2); - realnum *p0 = d->P[c][cmp][d0], *pp0 = d->P_prev[c][cmp][d0]; - realnum *p1 = d->P[c][cmp][d1], *pp1 = d->P_prev[c][cmp][d1]; - realnum *p2 = d->P[c][cmp][d2], *pp2 = d->P_prev[c][cmp][d2]; - const realnum *rhs0 = d->P_tmp[c][cmp][d0]; - const realnum *rhs1 = d->P_tmp[c][cmp][d1]; - const realnum *rhs2 = d->P_tmp[c][cmp][d2]; - - LOOP_OVER_VOL_OWNED(gv, c, i) { pp0[i] = p0[i]; pp1[i] = p1[i]; pp2[i] = p2[i]; - p0[i] = inv[d0][d0] * rhs0[i] + inv[d0][d1] * rhs1[i] + inv[d0][d2] * rhs2[i]; - p1[i] = inv[d1][d0] * rhs0[i] + inv[d1][d1] * rhs1[i] + inv[d1][d2] * rhs2[i]; - p2[i] = inv[d2][d0] * rhs0[i] + inv[d2][d1] * rhs1[i] + inv[d2][d2] * rhs2[i]; + p0[i] = inv[d0][d0] * rhs0 + inv[d0][d1] * rhs1 + inv[d0][d2] * rhs2; + p1[i] = inv[d1][d0] * rhs0 + inv[d1][d1] * rhs1 + inv[d1][d2] * rhs2; + p2[i] = inv[d2][d0] * rhs0 + inv[d2][d1] * rhs1 + inv[d2][d2] * rhs2; } } } From 83f42e1c0216d415d7bbb294aa917b3e7a405ec3 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 31 May 2019 12:32:19 +0800 Subject: [PATCH 35/61] Implement num_cinternal_notowned stuff for gyrotropic media --- src/meep.hpp | 4 ++++ src/susceptibility.cpp | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/meep.hpp b/src/meep.hpp index 79caf4480..507558d0e 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -291,6 +291,10 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { void subtract_P(field_type ft, realnum *f_minus_p[NUM_FIELD_COMPONENTS][2], void *P_internal_data) const; + int num_cinternal_notowned_needed(component c, void *P_internal_data) const; + realnum *cinternal_notowned_ptr(int inotowned, component c, int cmp, + int n, void *P_internal_data) const; + virtual void dump_params(h5file *h5f, size_t *start); virtual int get_num_params() { return 7; } virtual bool needs_W_notowned(component c, realnum *W[NUM_FIELD_COMPONENTS][2]) const { diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 2040cf260..257f200ee 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -492,6 +492,19 @@ void gyrotropic_susceptibility::subtract_P(field_type ft, } } +int gyrotropic_susceptibility::num_cinternal_notowned_needed(component c, + void *P_internal_data) const { + gyrotropy_data *d = (gyrotropy_data *)P_internal_data; + return d->P[c][0][0] ? 3 : 0; +} + +realnum *gyrotropic_susceptibility::cinternal_notowned_ptr(int inotowned, component c, int cmp, + int n, void *P_internal_data) const { + gyrotropy_data *d = (gyrotropy_data *)P_internal_data; + if (!d || !d->P[c][cmp][inotowned]) return NULL; + return d->P[c][cmp][inotowned] + n; +} + void gyrotropic_susceptibility::dump_params(h5file *h5f, size_t *start) { size_t num_params = 8; size_t params_dims[1] = {num_params}; From 7fa88a22622bb33b252a95c366c9bbcf3152db2e Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 31 May 2019 16:28:57 +0800 Subject: [PATCH 36/61] Update documentation for gyrotropic media, and relax some minor restrictions. --- doc/docs/Materials.md | 10 +- doc/docs/Python_Tutorials/Gyrotropic_Media.md | 162 +++++++++--------- .../images/Faraday-rotation-comparison.png | Bin 0 -> 97734 bytes doc/docs/images/Faraday-rotation.png | Bin 0 -> 71606 bytes python/examples/faraday-rotation.py | 68 ++++++++ src/susceptibility.cpp | 15 +- 6 files changed, 155 insertions(+), 100 deletions(-) create mode 100644 doc/docs/images/Faraday-rotation-comparison.png create mode 100644 doc/docs/images/Faraday-rotation.png create mode 100644 python/examples/faraday-rotation.py diff --git a/doc/docs/Materials.md b/doc/docs/Materials.md index d6316aa3b..1d9a553e5 100644 --- a/doc/docs/Materials.md +++ b/doc/docs/Materials.md @@ -180,17 +180,13 @@ $$\frac{d^2\mathbf{P}_n}{dt^2} + \gamma_n \frac{d\mathbf{P}_n}{dt} + \mathbf{b}_ $$\frac{d\mathbf{P}_n}{dt} = \mathbf{P}_n \times \mathbf{b}_n$$ -In the frequency domain, a gyroelectric medium has imaginary off-diagonal components in the ε tensor. Take the case $\mathbf{b} = b \hat{z}$. When all fields have harmonic time-dependence $\exp(-i\omega t)$, the polarization equation of motion reduces to +In the frequency domain, a gyroelectric medium has skew-symmetric off-diagonal components in the ε tensor. Take the case $\mathbf{b} = b \hat{z}$. When all fields have harmonic time-dependence $\exp(-i\omega t)$, the polarization equation of motion reduces to -$$\mathbf{P}_n = \chi_n \mathbf{E}, \quad \chi_n = \omega_n^2 \begin{bmatrix}\xi_\perp & -i\eta & 0 \\ i\eta & \xi_\perp & 0 \\ 0 & 0 & \xi_\parallel \end{bmatrix} \, \sigma_n(\mathbf{x})$$ +$$\mathbf{P}_n = \begin{bmatrix}\chi_\perp & -i\eta & 0 \\ i\eta & \chi_\perp & 0 \\ 0 & 0 & \chi_\parallel \end{bmatrix} \mathbf{E}$$ where -$$\xi_\perp = \frac{\Delta_n}{\Delta_n^2 - \omega^2 b^2}\,,\;\;\; \xi_\parallel = \frac{1}{\Delta_n}, \;\;\; \eta = \frac{\omega b}{\Delta_n^2 - \omega^2 b^2}, \;\;\;\Delta_n \equiv \omega_n^2 - \omega^2 - i\omega\gamma_n$$ - -In many applications, the gyrotropy is weak relative to the frequency detuning but strong relative to the loss. For this case, we can define $\omega_n = \omega + \Delta\omega_n$, and take $\gamma_n \ll b \ll \Delta \omega_n \ll \omega$. In this limit, the susceptibility tensor reduces to - -$$\chi_n \approx \frac{\omega}{2\Delta\omega_n} \begin{bmatrix}1 & -ib/2\Delta\omega_n & 0 \\ ib/2\Delta\omega_n & 1 & 0 \\ 0 & 0 & 1\end{bmatrix} \sigma_n(\mathbf{x})$$ +$$\chi_\perp = \frac{\omega_n^2 \Delta_n}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}),\;\;\; \chi_\parallel = \frac{\omega_n^2}{\Delta_n}\,\sigma_n(\mathbf{x}), \;\;\; \eta = \frac{\omega_n^2 \omega b}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}), \;\;\;\Delta_n \equiv \omega_n^2 - \omega^2 - i\omega\gamma_n$$ Materials Library ----------------- diff --git a/doc/docs/Python_Tutorials/Gyrotropic_Media.md b/doc/docs/Python_Tutorials/Gyrotropic_Media.md index b67fb0afc..baf6a25dd 100644 --- a/doc/docs/Python_Tutorials/Gyrotropic_Media.md +++ b/doc/docs/Python_Tutorials/Gyrotropic_Media.md @@ -2,120 +2,116 @@ # Gyrotropic media --- -In this example, we will perform simulations with a gyrotropic medium. See [Materials](../Materials.md#gyrotropic-media) for more information on how gyrotropy is supported. +In this example, we will perform simulations with gyrotropic media. See [Materials](../Materials.md#gyrotropic-media) for more information on how gyrotropy is supported. -[TOC] +### Faraday Rotation -### Dispersion Relation for a Gyrotropic Medium +Consider a uniform gyrotroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. According to the [gyrotropic Lorentzian model implemented in Meep](../Materials.md#gyrotropic-media), the *x* and *y* components of the dielectric function are -Here, we model a uniform gyrotroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. For TE modes, the electric field lies in the *x*-*y* plane and magnetic field pointing along *z*, with the wavevector $\mathbf{k}$ in the *x*-*y* plane. The dispersion relation can be shown to be +$$\epsilon = \begin{bmatrix}\epsilon_\perp & -i\eta \\ i\eta & \epsilon_\perp \end{bmatrix}$$ -$$\omega = v(\omega) |\mathbf{k}|, \quad v^2 = \mu^{-1} \left[\epsilon^{-1}\right]_{xx}$$ +where -The ε tensor is given by +$$\epsilon_\perp = \epsilon_\infty + \frac{\omega_n^2 \Delta_n}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}),\;\;\; \eta = \frac{\omega_n^2 \omega b}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}), \;\;\;\Delta_n \equiv \omega_n^2 - \omega^2 - i\omega\gamma_n$$ -$$\epsilon = \epsilon_\infty + \frac{\omega_n^2}{\omega_n^2 - \omega^2 - i\omega\gamma_n} \begin{bmatrix}\xi & -i\eta & 0 \\ i\eta & \xi & 0 \\ 0 & 0 & 1 \end{bmatrix} \, \sigma_n(\mathbf{x}),$$ +The skew-symmetric off-diagonal components in ε give rise to [Faraday rotation](https://en.wikipedia.org/wiki/Faraday_effect): when a plane wave linearly polarized along *x* is launched along the gyrotropy axis *z*, the polarization vector will precess around the gyrotropy axis as the wave propagates. This is the principle behind [Faraday rotators](https://en.wikipedia.org/wiki/Faraday_rotator), devices that act as one-way valves for light. -with +A plane wave undergoing Faraday rotation can be described by the complex ansatz -$$\xi = \frac{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 + \omega^2 b^2}\,, \quad \eta = \frac{\omega b (\omega_n^2 - \omega^2 - i\omega \gamma_n)}{(\omega_n^2 - \omega^2 - i\omega \gamma_n)^2 + \omega^2 b^2}$$ +$$\begin{bmatrix}E_x \\ E_y\end{bmatrix} = E_0 \begin{bmatrix}\cos(\kappa_c z) \\ \sin(\kappa_c z)\end{bmatrix} e^{i(kz-\omega t)}$$ -We choose the material parameters $\epsilon_\infty = 1$, $f_n = 1.2$, $\gamma_n = 10^{-5}$, and $\sigma_n = 0.1$, with $|\mathbf{b}_n|$ ranging from zero to $10^{-2}$. +where $\kappa_c$ is the Faraday rotation, in radians, per unit of propagation distance. Substituting this into Maxwell's equations, with the above gyroelectric dielectric function, yields +$$|\kappa_c| = \frac{1}{2} \omega^2 \mu \sqrt{\epsilon_\perp - \sqrt{\epsilon_\perp^2 - \eta^2}}$$ +We model this phenomenon in the simulation script [faraday-rotation.py](https://github.com/NanoComp/meep/blob/master/python/examples/faraday-rotation.py). First, we define a gyroelectric material: +```import meep as mp -From the dispersion relation ω(k), we will compute the numerical ε(ω) via the formula: +## Define a gyroelectric medium +f0 = 1.0 +gamma = 1e-4 +epsn = 2.0 +b0 = 1.05 +sigma = 0.2 -$$\varepsilon(\omega) = \left( \frac{ck}{\omega} \right) ^2$$ - -We will then compare this with the analytical ε(ω) that we specified. The simulation script is in [material-dispersion.py](https://github.com/NanoComp/meep/blob/master/python/examples/material-dispersion.py). - -Since this is a uniform medium, our computational cell can actually be of *zero* size (i.e. one pixel), where we will use Bloch-periodic boundary conditions to specify the wavevector *k*. - -```py -cell = mp.Vector3() -resolution = 20 -``` - -We will then fill all space with an artificial dispersive material: - -```py -susceptibilities = [mp.LorentzianSusceptibility(frequency=1.1, gamma=1e-5, sigma=0.5), - mp.LorentzianSusceptibility(frequency=0.5, gamma=0.1, sigma=2e-5)] - -default_material = mp.Medium(epsilon=2.25, E_susceptibilities=susceptibilities) +susc = [mp.GyrotropicLorentzianSusceptibility(frequency=f0, gamma=gamma, sigma=sigma, + bias=mp.Vector3(0, 0, b0))] +mat = mp.Medium(epsilon=epsn, mu=1, E_susceptibilities=susc) ``` -corresponding to the dielectric function: - -$$\varepsilon(\omega) = \varepsilon(2\pi f) = 2.25 + \frac{1.1^2 \cdot 0.5}{1.1^2 - f^2 -if \cdot 10^{-5}/2\pi} + \frac{0.5^2 \cdot 2\cdot 10^{-5}}{0.5^2 - f^2 -if \cdot 0.1 / 2\pi}$$ - -The real and imaginary parts of this dielectric function ε(ω) are plotted below: - -
-![](../images/Material-dispersion-eps.png) -
- -We can see that the f=1.1 resonance causes a large change in both the real and imaginary parts of ε around that frequency. In fact, there is a range of frequencies from 1.1 to 1.2161 where ε is *negative*. In this range, no propagating modes exist — it is actually a kind of electromagnetic band gap associated with polariton resonances in a material. For more information on the physics of such materials, see e.g. Chapter 14 of [Introduction to Solid State Physics](http://www.wiley.com/WileyCDA/WileyTitle/productCd-EHEP000803.html) by C. Kittel. - -On the other hand, the f=0.5 resonance, because the `sigma` numerator is so small, causes very little change in the real part of ε. Nevertheless, it generates a clear peak in the *imaginary* part of ε, corresponding to a resonant absorption peak. +The `GyrotropicLorentzianSusceptibility` object has a `bias` argument that takes a `Vector3` specifying the gyrotropy vector. In this case, the vector points along *z*, and its magnitude (which specifies the precession frequency) is determined by the variable `b0`. The other arguments play the same role as in an ordinary (non-gyrotropic) [Lorentzian susceptibility](Material_Dispersion.md). -Now, we'll set up the rest of the simulation. We'll specify a broadband $E_z$-polarized Gaussian source, create a list of *k* wavevectors that we want to compute ω(k) over, and compute the associated frequencies by using the `k_points` function: +Next, we set up and run the Meep simulation. -```py -fcen = 1.0 -df = 2.0 +```tmax = 100 +L = 20.0 +cell = mp.Vector3(0, 0, L) +fsrc, src_z = 0.8, -8.5 +pml_layers = [mp.PML(thickness=1.0, direction=mp.Z)] -sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3())] +sources = [mp.Source(mp.ContinuousSource(frequency=fsrc), + component=mp.Ex, center=mp.Vector3(0, 0, src_z))] -kmin = 0.3 -kmax = 2.2 -k_interp = 99 - -kpts = mp.interpolate(k_interp, [mp.Vector3(kmin), mp.Vector3(kmax)]) - -sim = mp.Simulation(cell_size=cell, geometry=[], sources=sources, default_material=default_material, resolution=resolution) - -all_freqs = sim.run_k_points(200, kpts) # a list of lists of frequencies +sim = mp.Simulation(cell_size=cell, geometry=[], sources=sources, + k_point=mp.Vector3(), # Periodic boundary conditions + boundary_layers=pml_layers, + default_material=mat, resolution=50) +sim.run(until=tmax) ``` -The `run_k_points` function returns a *list of lists* of frequencies — one list of complex frequencies for each *k* point — which we store in the `all_freqs` variable. Finally, we want to loop over this list and print out the corresponding ε via the ratio (ck/ω)$^2$ as described above. To do this, we will use Python's `zip` function which combines multiple lists into one: +The simulation cell is one pixel wide in the *x* and *y* directions, with periodic boundary conditions. PMLs are placed in the *z* direction. A `ContinuousSource` emits a wave whose electric field is initially polarized along *x*. We then plot the *x* and *y* components of the electric field versus *z*: -```py -for fs, kx in zip(all_freqs, [v.x for v in kpts]): - for f in fs: - print("eps:, {.6f}, {.6f}, {.6f}".format(f.real, f.imag, (kx / f)**2)) -``` +```import numpy as np +import matplotlib.pyplot as plt -Alternatively we could just read all of the frequencies into Python or Octave/Matlab and compute the ratios there. After running the program with +ex_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, L), component=mp.Ex) +ey_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, L), component=mp.Ey) -```sh -unix% python -u material-dispersion.py | tee material-dispersion.out +z = np.linspace(-L/2, L/2, len(ex_data)) +plt.figure(1) +plt.plot(z, ex_data, label='Ex') +plt.plot(z, ey_data, label='Ey') +plt.xlim(-L/2, L/2) +plt.xlabel('z') +plt.legend() +plt.show() ``` -we can then `grep` for the frequencies and the computed dielectric function, and plot it. First, let's plot the dispersion relation ω(k) for the real part of ω: -
-![](../images/Material-dispersion-bands.png) +![](../images/Faraday-rotation.png)
-The red circles are the computed points from Meep, whereas the blue line is the analytical band diagram from the specified ε(ω). As you can see, we get *two* bands at each *k*, separated by a polaritonic gap (shaded yellow). This dispersion relation can be thought of as the interaction (anti-crossing) between the light line of the ambient ε=2.25 material (dashed black line) and the horizontal line corresponding to the phonon resonance. - -Similarly, the computed and analytical real parts of the dielectric function are given by: - -
-![](../images/Material-dispersion-epsre.png) -
+We see that the wave indeed rotates in the *x*-*y* plane as it travels. This can be compared quantitatively to the above ansatz for a wave undergoing Faraday rotation, using the material parameters to calculate the rotation rate $\kappa_c$: + +```dfsq = (f0*2 - 1j*f0*gamma - fsrc**2) +eperp = epsn + sigma * f0**2 * dfsq / (dfsq**2 + (fsrc*b0)**2) +eta = sigma * f0**2 * fsrc * b0 / (dfsq**2 + (fsrc*b0)**2) + +k_gyro = 2*np.pi*fsrc * np.sqrt(0.5*(eperp - np.sqrt(eperp**2 - eta**2))) +Ex_theory = 0.37 * np.cos(k_gyro * (z - src_z)) # amplitude estimated by eye +Ey_theory = 0.37 * np.sin(k_gyro * (z - src_z)) + +plt.figure(2) +plt.subplot(2,1,1) +plt.plot(z, ex_data, label='Ex (MEEP)') +plt.plot(z, Ex_theory, 'k--') +plt.plot(z, -Ex_theory, 'k--', label='Ex (theory)') +plt.xlim(-L/2, L/2); plt.xlabel('z') +plt.legend() + +plt.subplot(2,1,2) +plt.plot(z, ey_data, label='Ey (MEEP)') +plt.plot(z, Ey_theory, 'k--') +plt.plot(z, -Ey_theory, 'k--', label='Ey (theory)') +plt.xlim(-L/2, L/2); plt.xlabel('z') +plt.legend() +plt.tight_layout() +plt.show() +``` -which shows excellent agreement between the analytical (blue line) and numerical (red circles) calculations. The imaginary part, however, is more subtle: +The results are in excellent agreement:
-![](../images/Material-dispersion-epsim.png) +![](../images/Faraday-rotation-comparison.png)
- -The blue line is the analytical calculation from above and the red circles are the numerical value from Meep — why is the agreement so poor? There is nothing wrong with Meep, and this is *not* a numerical error. The problem is simply that we are comparing apples and oranges. - -The blue line is the analytical calculation of ε(ω) for a *real* frequency ω which corresponds to solutions with a *complex* wavevector *k*, whereas Meep is computing ε at a *complex* ω for a *real* wavevector *k*. So, the correct comparison is to plug Meep's *complex* ω into the analytical formula for ε(ω), which results in the green lines on the graph that fall almost on top of the red circles. - -Why did our comparison of the *real* part of ε look so good, then? The reason is that ε(ω) at real and complex values of ω are closely related by the analytic properties of ε. In particular, because ε is an analytic function on the real-ω axis, adding a *small* imaginary part to ω as we are doing here does not change ε by much. The losses are small for all of the computed *k* points. The change was only significant for the imaginary ε because the imaginary ε was small to begin with. diff --git a/doc/docs/images/Faraday-rotation-comparison.png b/doc/docs/images/Faraday-rotation-comparison.png new file mode 100644 index 0000000000000000000000000000000000000000..eb8e33972b828d7a9061de356630b01d78de93f9 GIT binary patch literal 97734 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 literal 0 HcmV?d00001 diff --git a/doc/docs/images/Faraday-rotation.png b/doc/docs/images/Faraday-rotation.png new file mode 100644 index 0000000000000000000000000000000000000000..2f12bc384abb5b14e4ebdb265eb74a94503cf0eb GIT binary patch literal 71606 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 AO#lD@ literal 0 HcmV?d00001 diff --git a/python/examples/faraday-rotation.py b/python/examples/faraday-rotation.py new file mode 100644 index 000000000..9b415fabd --- /dev/null +++ b/python/examples/faraday-rotation.py @@ -0,0 +1,68 @@ +import meep as mp + +## Define a gyroelectric medium +f0 = 1.0 +gamma = 1e-4 +epsn = 2.0 +b0 = 1.05 +sn = 0.2 + +susc = [mp.GyrotropicLorentzianSusceptibility(frequency=f0, gamma=gamma, sigma=sn, + bias=mp.Vector3(0, 0, b0))] +mat = mp.Medium(epsilon=epsn, mu=1, E_susceptibilities=susc) + +## Set up and run the Meep simulation: +tmax = 100 +L = 20.0 +cell = mp.Vector3(0, 0, L) +fsrc, src_z = 0.8, -8.5 +pml_layers = [mp.PML(thickness=1.0, direction=mp.Z)] + +sources = [mp.Source(mp.ContinuousSource(frequency=fsrc), + component=mp.Ex, center=mp.Vector3(0, 0, src_z))] + +sim = mp.Simulation(cell_size=cell, geometry=[], sources=sources, + k_point=mp.Vector3(), # Periodic boundary conditions + boundary_layers=pml_layers, + default_material=mat, resolution=50) +sim.run(until=tmax) + +## Plot results: +import numpy as np +import matplotlib.pyplot as plt + +ex_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, L), component=mp.Ex) +ey_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, L), component=mp.Ey) + +z = np.linspace(-L/2, L/2, len(ex_data)) +plt.figure(1) +plt.plot(z, ex_data, label='Ex') +plt.plot(z, ey_data, label='Ey') +plt.xlim(-L/2, L/2); plt.xlabel('z') +plt.legend() + +## Comparison with analytic result: +dfsq = (f0*2 - 1j*f0*gamma - fsrc**2) +eperp = epsn + sn * f0**2 * dfsq / (dfsq**2 + (fsrc*b0)**2) +eta = sn * f0**2 * fsrc * b0 / (dfsq**2 + (fsrc*b0)**2) + +k_gyro = 2*np.pi*fsrc * np.sqrt(0.5*(eperp - np.sqrt(eperp**2 - eta**2))) +Ex_theory = 0.37 * np.cos(k_gyro * (z - src_z)) +Ey_theory = 0.37 * np.sin(k_gyro * (z - src_z)) + +plt.figure(2) +plt.subplot(2,1,1) +plt.plot(z, ex_data, label='Ex (MEEP)') +plt.plot(z, Ex_theory, 'k--') +plt.plot(z, -Ex_theory, 'k--', label='Ex (theory)') +plt.xlim(-L/2, L/2); plt.xlabel('z') +plt.legend() + +plt.subplot(2,1,2) +plt.plot(z, ey_data, label='Ey (MEEP)') +plt.plot(z, Ey_theory, 'k--') +plt.plot(z, -Ey_theory, 'k--', label='Ey (theory)') +plt.xlim(-L/2, L/2); plt.xlabel('z') +plt.legend() +plt.tight_layout() +plt.show() diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 257f200ee..e0ef45d9a 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -400,12 +400,7 @@ void *gyrotropic_susceptibility::copy_internal_data(void *data) const { bool gyrotropic_susceptibility::needs_P(component c, int cmp, realnum *W[NUM_FIELD_COMPONENTS][2]) const { if (!is_electric(c) && !is_magnetic(c)) return false; direction d0 = component_direction(c); - if ((d0 == X || d0 == Y || d0 == Z) && sigma[c][d0]) { - FOR_DIRECTIONS(d) { - if (W[direction_component(c, d)][cmp]) return true; - } - } - return false; + return (d0 == X || d0 == Y || d0 == Z) && sigma[c][d0] && W[c][cmp]; } void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], @@ -450,18 +445,18 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); realnum rhs0, rhs1, rhs2; - if (!pp1 || !pp2 || !w1 || !w2) + if (!pp1 || !pp2) abort("gyrotropic media require 3D Cartesian fields\n"); if (sigma[c][d1] || sigma[c][d2]) - abort("gyrotropic media do not support tensor sigma\n"); + abort("gyrotropic media do not support anisotropic sigma\n"); LOOP_OVER_VOL_OWNED(gv, c, i) { rhs0 = diagfac*p0[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w0[i] - pt*gyro_tensor[d0][d1]*pp1[i] - pt*gyro_tensor[d0][d2]*pp2[i]; - rhs1 = diagfac*p1[i] - gamma1*pp1[i] + omega0dtsqr*s[i]*OFFDIAG(s,w1,is1,is) + rhs1 = diagfac*p1[i] - gamma1*pp1[i] + (w1 ? omega0dtsqr*s[i]*OFFDIAG(s,w1,is1,is) : 0) - pt*gyro_tensor[d1][d0]*pp0[i] - pt*gyro_tensor[d1][d2]*pp2[i]; - rhs2 = diagfac*p2[i] - gamma1*pp2[i] + omega0dtsqr*s[i]*OFFDIAG(s,w2,is2,is) + rhs2 = diagfac*p2[i] - gamma1*pp2[i] + (w2 ? omega0dtsqr*s[i]*OFFDIAG(s,w2,is2,is) : 0) - pt*gyro_tensor[d2][d1]*pp1[i] - pt*gyro_tensor[d2][d0]*pp0[i]; pp0[i] = p0[i]; pp1[i] = p1[i]; pp2[i] = p2[i]; From 3028e304aaee4ab6b5965e8bf2009496c1d99e2d Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 31 May 2019 17:51:30 +0800 Subject: [PATCH 37/61] Add virtual keywords to gyrotropic_susceptibility methods --- src/meep.hpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/meep.hpp b/src/meep.hpp index 507558d0e..10c9420fd 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -279,21 +279,21 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { bool no_omega_0_denominator = true); virtual susceptibility *clone() const { return new gyrotropic_susceptibility(*this); } - void *new_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv) const; - void init_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], double dt, - const grid_volume &gv, void *data) const; - void *copy_internal_data(void *data) const; + virtual void *new_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv) const; + virtual void init_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], double dt, + const grid_volume &gv, void *data) const; + virtual void *copy_internal_data(void *data) const; - bool needs_P(component c, int cmp, realnum *W[NUM_FIELD_COMPONENTS][2]) const; + virtual bool needs_P(component c, int cmp, realnum *W[NUM_FIELD_COMPONENTS][2]) const; virtual void update_P(realnum *W[NUM_FIELD_COMPONENTS][2], realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, const grid_volume &gv, void *P_internal_data) const; - void subtract_P(field_type ft, realnum *f_minus_p[NUM_FIELD_COMPONENTS][2], - void *P_internal_data) const; + virtual void subtract_P(field_type ft, realnum *f_minus_p[NUM_FIELD_COMPONENTS][2], + void *P_internal_data) const; - int num_cinternal_notowned_needed(component c, void *P_internal_data) const; - realnum *cinternal_notowned_ptr(int inotowned, component c, int cmp, - int n, void *P_internal_data) const; + virtual int num_cinternal_notowned_needed(component c, void *P_internal_data) const; + virtual realnum *cinternal_notowned_ptr(int inotowned, component c, int cmp, + int n, void *P_internal_data) const; virtual void dump_params(h5file *h5f, size_t *start); virtual int get_num_params() { return 7; } From 1cc846e20283bcb186a68397c6be7b0698c17299 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sun, 2 Jun 2019 10:52:17 +0800 Subject: [PATCH 38/61] Merge latest changes from master --- doc/docs/Python_User_Interface.md | 16 ++++++++++------ python/geom.py | 8 +++++++- python/meep.i | 3 ++- python/typemap_utils.cpp | 13 ++++++++++--- scheme/meep.scm.in | 4 +++- scheme/structure.cpp | 13 +++++++++---- src/meep.hpp | 10 +++------- src/meepgeom.cpp | 12 +++++------- 8 files changed, 49 insertions(+), 30 deletions(-) diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index 8cc35d1aa..458ea9733 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -394,7 +394,15 @@ This is a somewhat unusual polarizable medium, a Lorentzian susceptibility with ### GyrotropicLorentzianSusceptibility or GyrotropicDrudeSusceptibility -(**Experimental feature**) Specifies a single dispersive [gyrotropic susceptibility](Materials.md#gyrotropic-media) governed by the Landau-Lifshitz-Gilbert equation. Note that the parameters `sigma`, `frequency`, and `gamma` play different roles compared to the Lorentzian or Drude case. +(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility. See [Material Dispersion](Materials.md#gyrotropic-media). + +For gyrotropic media of Lorentzian (damped harmonic oscillator) or Drude form, the parameters `sigma`, `frequency`, and `gamma` have the same meanings as in `LorentzianSusceptibility` and `DrudeSusceptibility`, but with an additional 3-vector `bias`: + +**`bias` [`Vector3`]** +— +The gyrotropy vector. The direction of this vector determines the orientation of the gyrotropic response, and the magnitude equals the precession frequency $|\mathbf{b}_n|/2\pi$. + +For gyrotropic media of Landau-Lifshitz-Gilbert form, the parameters `sigma`, `frequency`, and `gamma` play different roles, and there is an additiona `alpha` parameter: **`sigma` [`number`]** — @@ -402,7 +410,7 @@ The coupling factor $\sigma_n / 2\pi$ between the polarization and the driving f **`frequency` [`number`]** — -The frequency of gyrotropic precession, $f_n = \omega_n / 2\pi$. In magnetic ferrites, this is the Larmor precession frequency. +The Larmor precession frequency, $f_n = \omega_n / 2\pi$. **`gamma` [`number`]** — @@ -412,10 +420,6 @@ The loss rate $\gamma_n / 2\pi$ in the off-diagonal response. — The loss factor $\alpha_n$ in the diagonal response (note that there is no 2π factor). -**`bias` [`Vector3`]** -— -Gyrotropy vector describing the direction of the static biasing magnetic field. The magnitude is ignored. - ### Vector3 Properties: diff --git a/python/geom.py b/python/geom.py index 203289a1b..e52aea387 100644 --- a/python/geom.py +++ b/python/geom.py @@ -280,12 +280,18 @@ def __init__(self, noise_amp=0.0, **kwargs): super(NoisyDrudeSusceptibility, self).__init__(**kwargs) self.noise_amp = noise_amp -class GyrotropicSusceptibility(LorentzianSusceptibility): +class GyrotropicLorentzianSusceptibility(LorentzianSusceptibility): def __init__(self, bias=Vector3(), **kwargs): super(GyrotropicLorentzianSusceptibility, self).__init__(**kwargs) self.bias = bias +class GyrotropicDrudeSusceptibility(DrudeSusceptibility): + + def __init__(self, bias=Vector3(), **kwargs): + super(GyrotropicDrudeSusceptibility, self).__init__(**kwargs) + self.bias = bias + class MultilevelAtom(Susceptibility): def __init__(self, initial_populations=[], transitions=[], **kwargs): diff --git a/python/meep.i b/python/meep.i index d984185d2..98223c364 100644 --- a/python/meep.i +++ b/python/meep.i @@ -1371,7 +1371,8 @@ PyObject *_get_array_slice_dimensions(meep::fields *f, const meep::volume &where Ellipsoid, FreqRange, GeometricObject, - GyrotropicSusceptibility, + GyrotropicDrudeSusceptibility, + GyrotropicLorentzianSusceptibility, Lattice, LorentzianSusceptibility, Matrix, diff --git a/python/typemap_utils.cpp b/python/typemap_utils.cpp index 302d78c35..f8fe8327b 100644 --- a/python/typemap_utils.cpp +++ b/python/typemap_utils.cpp @@ -465,9 +465,16 @@ static PyObject *susceptibility_to_py_obj(susceptibility_struct *s) { PyObject *args = PyTuple_New(0); if (s->bias.x || s->bias.y || s->bias.z) { - PyObject *py_gyrotropic_class = PyObject_GetAttrString(geom_mod, "GyrotropicSusceptibility"); - res = PyObject_Call(py_gyrotropic_class, args, NULL); - Py_DECREF(py_gyrotropic_class); + if (s->drude) { + PyObject *py_gyrotropic_drude_class = PyObject_GetAttrString(geom_mod, "GyrotropicDrudeSusceptibility"); + res = PyObject_Call(py_gyrotropic_drude_class, args, NULL); + Py_DECREF(py_gyrotropic_drude_class); + } else { + PyObject *py_gyrotropic_lorentz_class = + PyObject_GetAttrString(geom_mod, "GyrotropicLorentzianSusceptibility"); + res = PyObject_Call(py_gyrotropic_lorentz_class, args, NULL); + Py_DECREF(py_gyrotropic_lorentz_class); + } PyObject *py_bias = vec2py(vector3_to_vec(s->bias)); PyObject_SetAttrString(res, "bias", py_bias); diff --git a/scheme/meep.scm.in b/scheme/meep.scm.in index 857559f97..cfec58b06 100644 --- a/scheme/meep.scm.in +++ b/scheme/meep.scm.in @@ -57,7 +57,9 @@ (define-property noise-amp no-default 'number)) (define-class noisy-drude-susceptibility drude-susceptibility (define-property noise-amp no-default 'number)) -(define-class gyrotropic-susceptibility lorentzian-susceptibility +(define-class gyrotropic-lorentzian-susceptibility lorentzian-susceptibility + (define-property bias no-default 'vector3)) +(define-class gyrotropic-drude-susceptibility drude-susceptibility (define-property bias no-default 'vector3)) (define polarizability lorentzian-susceptibility) ; backwards compat diff --git a/scheme/structure.cpp b/scheme/structure.cpp index 8f6bdf16f..85a601965 100644 --- a/scheme/structure.cpp +++ b/scheme/structure.cpp @@ -1295,10 +1295,10 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) master_printf("noisy lorentzian susceptibility: frequency=%g, gamma=%g, amp = %g\n", d->frequency, d->gamma, nd->noise_amp); sus = new meep::noisy_lorentzian_susceptibility(nd->noise_amp, d->frequency, d->gamma); - } else if (d->which_subclass == lorentzian_susceptibility::GYROTROPIC_SUSCEPTIBILITY) { - gyrotropic_susceptibility *gd = d->subclass.gyrotropic_susceptibility_data; + } else if (d->which_subclass == lorentzian_susceptibility::GYROTROPIC_LORENTZIAN_SUSCEPTIBILITY) { + gyrotropic_lorentzian_susceptibility *gd = d->subclass.gyrotropic_lorentzian_susceptibility_data; master_printf("gyrotropic lorentzian susceptibility: bias=(%g,%g,%g), frequency=%g, gamma=%g\n", - gd->bias.x, gd->bias.y, gd->bias.z, d->frequency, d->gamma); + gd->bias.x, gd->bias.y, gd->bias.z, d->frequency, d->gamma); sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma); } else { // just a Lorentzian master_printf("lorentzian susceptibility: frequency=%g, gamma=%g\n", d->frequency, @@ -1315,7 +1315,12 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) d->frequency, d->gamma, nd->noise_amp); sus = new meep::noisy_lorentzian_susceptibility(nd->noise_amp, d->frequency, d->gamma, true); - } else { // just a Drude + } else if (d->which_subclass == drude_susceptibility::GYROTROPIC_DRUDE_SUSCEPTIBILITY) { + gyrotropic_drude_susceptibility *gd = d->subclass.gyrotropic_drude_susceptibility_data; + master_printf("gyrotropic drude susceptibility: bias=(%g,%g,%g), frequency=%g, gamma=%g\n", + gd->bias.x, gd->bias.y, gd->bias.z, d->frequency, d->gamma); + sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma, true); + } else { // just a Drude master_printf("drude susceptibility: frequency=%g, gamma=%g\n", d->frequency, d->gamma); sus = new meep::lorentzian_susceptibility(d->frequency, d->gamma, true); } diff --git a/src/meep.hpp b/src/meep.hpp index 9ca175a65..e1a1767a9 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -275,7 +275,8 @@ class noisy_lorentzian_susceptibility : public lorentzian_susceptibility { /* gyrotropic susceptibility */ class gyrotropic_susceptibility : public lorentzian_susceptibility { public: - gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma); + gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma, + bool no_omega_0_denominator = true); virtual susceptibility *clone() const { return new gyrotropic_susceptibility(*this); } virtual void *new_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv) const; @@ -294,9 +295,6 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { virtual realnum *cinternal_notowned_ptr(int inotowned, component c, int cmp, int n, void *P_internal_data) const; - virtual void subtract_P(field_type ft, realnum *f_minus_p[NUM_FIELD_COMPONENTS][2], - void *P_internal_data) const; - virtual void dump_params(h5file *h5f, size_t *start); virtual int get_num_params() { return 7; } virtual bool needs_W_notowned(component c, realnum *W[NUM_FIELD_COMPONENTS][2]) const { @@ -306,9 +304,7 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { } protected: - double psat; // conserved magnitude of the polarization vector - double bvec[3]; // unit vector pointing along direction of gyrotropic bias - int sgn[3][3]; // antisymmetric tensor: sgn[X][Y] = 1, sgn[Z][Y] = -1, etc. + double gyro_tensor[3][3]; }; class multilevel_susceptibility : public susceptibility { diff --git a/src/meepgeom.cpp b/src/meepgeom.cpp index d30a32adf..a259669b5 100644 --- a/src/meepgeom.cpp +++ b/src/meepgeom.cpp @@ -1375,18 +1375,16 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) sus = new meep::noisy_lorentzian_susceptibility(ss->noise_amp, ss->frequency, ss->gamma, ss->drude); } else if (gyrotropic) { - sus = new meep::gyrotropic_susceptibility(meep::vec(ss->bias.x, ss->bias.y, ss->bias.z), - ss->frequency, ss->gamma); + sus = new meep::gyrotropic_susceptibility(meep::vec(ss->bias.x, ss->bias.y, ss->bias.z), ss->frequency, + ss->gamma, ss->drude); } else { sus = new meep::lorentzian_susceptibility(ss->frequency, ss->gamma, ss->drude); } master_printf("%s%s susceptibility: frequency=%g, gamma=%g", - noisy ? "noisy " : gyrotropic ? "gyrotropic" : "", - gyrotropic ? "" : ss->drude ? "drude" : "lorentzian", - ss->frequency, ss->gamma); + noisy ? "noisy " : gyrotropic ? "gyrotropic " : "", + ss->drude ? "drude" : "lorentzian", ss->frequency, ss->gamma); if (noisy) master_printf(", amp=%g ", ss->noise_amp); - if (gyrotropic) master_printf(", bias=(%g,%g,%g) ", - ss->bias.x, ss->bias.y, ss->bias.z); + if (gyrotropic) master_printf(", bias=(%g,%g,%g) ", ss->bias.x, ss->bias.y, ss->bias.z); master_printf("\n"); } From 2951befe1e1919931d8bd36074933d7add28c0ec Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sun, 2 Jun 2019 10:53:14 +0800 Subject: [PATCH 39/61] Remove gyrotropic-dispersion.py (incomplete attempt) --- python/examples/gyrotropic-dispersion.py | 60 ------------------------ 1 file changed, 60 deletions(-) delete mode 100644 python/examples/gyrotropic-dispersion.py diff --git a/python/examples/gyrotropic-dispersion.py b/python/examples/gyrotropic-dispersion.py deleted file mode 100644 index f4939976f..000000000 --- a/python/examples/gyrotropic-dispersion.py +++ /dev/null @@ -1,60 +0,0 @@ -import numpy as np -from numpy.linalg import inv -import matplotlib.pyplot as plt - -## Material parameters -sn = 0.0002 -fn = 0.5 -gn = 1e-5 -epsn = 15 -psat = 100 - -def meep_sim(gn, sn, epsn, tmax): - - ## For mu ~ 1 and epsn ~ 15, wavelength will be ~0.26. Set dx and dt to ~0.01 - resolution = 100 - - cellsize = [0.01, 0.01, 5.0] # Don't set to zero size: need 3D fields - fsrc = 0.8 - src_z = -1.8 - pml_depth = 0.25 - - import meep as mp - - cell = mp.Vector3(*cellsize) - - ## Define gyromagnetic material biased along z direction - susc = [mp.GyrotropicSusceptibility(frequency=fn, gamma=gn, sigma=sn, - bias=mp.Vector3(0, 0, psat))] - mat = mp.Medium(epsilon=epsn, mu=1, H_susceptibilities=susc) - - pml_layers = [mp.PML(thickness=pml_depth, direction=mp.Z)] - - sources = [mp.Source(mp.ContinuousSource(frequency=fsrc), - component=mp.Ex, center=mp.Vector3(0, 0, src_z))] - - sim = mp.Simulation(cell_size=cell, geometry=[], sources=sources, - k_point=mp.Vector3(), # Periodic BCs in x and y - boundary_layers=pml_layers, - default_material=mat, resolution=resolution) - - sim.run(until=tmax) - - ex_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, cellsize[2]), component=mp.Ex) - ey_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, cellsize[2]), component=mp.Ey) - - L = cellsize[2]/2 - z = np.linspace(-L, L, len(ex_data)) - plt.title('t = {}'.format(tmax)) - plt.plot(z, ex_data, label='Ex') - plt.plot(z, ey_data, label='Ey') - plt.xlim(-L, L) - plt.xlabel('z') - plt.legend() - -plt.figure(2, figsize=(8,8)) -plt.subplot(2,1,1) -meep_sim(gn, sn, epsn, 200) -plt.subplot(2,1,2) -meep_sim(gn, sn, epsn, 500) -plt.tight_layout() From d29cbe83bba2892e7c4fbfefa395184965dd16b5 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sun, 2 Jun 2019 10:57:05 +0800 Subject: [PATCH 40/61] Complete merge --- python/geom.py | 3 ++- python/meep.i | 16 ++++++++-------- python/typemap_utils.cpp | 1 - src/susceptibility.cpp | 3 ++- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/python/geom.py b/python/geom.py index e52aea387..002ecc5ff 100644 --- a/python/geom.py +++ b/python/geom.py @@ -292,7 +292,8 @@ def __init__(self, bias=Vector3(), **kwargs): super(GyrotropicDrudeSusceptibility, self).__init__(**kwargs) self.bias = bias -class MultilevelAtom(Susceptibility): + + class MultilevelAtom(Susceptibility): def __init__(self, initial_populations=[], transitions=[], **kwargs): super(MultilevelAtom, self).__init__(**kwargs) diff --git a/python/meep.i b/python/meep.i index 98223c364..998f13133 100644 --- a/python/meep.i +++ b/python/meep.i @@ -749,21 +749,21 @@ meep::volume_list *make_volume_list(const meep::volume &v, int c, } %typemap(in) const meep::src_time & { - PyObject *obj = NULL; + PyObject *swig_obj = NULL; void *tmp_ptr = 0; int tmp_res = 0; if(PyObject_IsInstance($input, py_source_time_object())) { - obj = PyObject_GetAttrString($input, "swigobj"); + swig_obj = PyObject_GetAttrString($input, "swigobj"); } else if(PyObject_IsInstance($input, py_meep_src_time_object())) { - obj = $input; - Py_XINCREF(obj); + swig_obj = $input; + Py_XINCREF(swig_obj); } else { meep::abort("Expected a meep.source.SourceTime or a meep.src_time\n"); } - tmp_res = SWIG_ConvertPtr(obj, &tmp_ptr, $1_descriptor, 0); - Py_XDECREF(obj); + tmp_res = SWIG_ConvertPtr(swig_obj, &tmp_ptr, $1_descriptor, 0); + Py_XDECREF(swig_obj); if(!SWIG_IsOK(tmp_res)) { SWIG_exception_fail(SWIG_ArgError(tmp_res), "Couldn't convert Python object to meep::src_time"); @@ -1371,8 +1371,8 @@ PyObject *_get_array_slice_dimensions(meep::fields *f, const meep::volume &where Ellipsoid, FreqRange, GeometricObject, - GyrotropicDrudeSusceptibility, - GyrotropicLorentzianSusceptibility, + GyrotropicDrudeSusceptibility, + GyrotropicLorentzianSusceptibility, Lattice, LorentzianSusceptibility, Matrix, diff --git a/python/typemap_utils.cpp b/python/typemap_utils.cpp index f8fe8327b..5c74107c6 100644 --- a/python/typemap_utils.cpp +++ b/python/typemap_utils.cpp @@ -475,7 +475,6 @@ static PyObject *susceptibility_to_py_obj(susceptibility_struct *s) { res = PyObject_Call(py_gyrotropic_lorentz_class, args, NULL); Py_DECREF(py_gyrotropic_lorentz_class); } - PyObject *py_bias = vec2py(vector3_to_vec(s->bias)); PyObject_SetAttrString(res, "bias", py_bias); Py_DECREF(py_bias); diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 50aebbda5..e0ef45d9a 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -503,8 +503,9 @@ realnum *gyrotropic_susceptibility::cinternal_notowned_ptr(int inotowned, compon void gyrotropic_susceptibility::dump_params(h5file *h5f, size_t *start) { size_t num_params = 8; size_t params_dims[1] = {num_params}; + double bias[] = { gyro_tensor[Y][Z], gyro_tensor[Z][X], gyro_tensor[X][Y] }; double params_data[] = { - 7, (double)get_id(), bvec[0], bvec[1], bvec[2], + 7, (double)get_id(), bias[X], bias[Y], bias[Z], omega_0, gamma, (double)no_omega_0_denominator}; h5f->write_chunk(1, start, params_dims, params_data); *start += num_params; From 2c6df3347fe8b3e50b098571e67834543908bc50 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sun, 2 Jun 2019 11:19:04 +0800 Subject: [PATCH 41/61] Update Materials.md to discuss both Lorentzian and LLG gyrotropic models --- doc/docs/Materials.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/doc/docs/Materials.md b/doc/docs/Materials.md index 67d8e4482..fda5ebbcc 100644 --- a/doc/docs/Materials.md +++ b/doc/docs/Materials.md @@ -170,23 +170,29 @@ For a two level gain medium, $\gamma_\parallel = \gamma_{12} + \gamma_{21}$. For Gyrotropic Media ---------------- -(**Experimental feature**) Meep supports gyrotropic media, which break optical reciprocity and give rise to magneto-optical phenomena such as the [Faraday effect](https://en.wikipedia.org/wiki/Faraday_effect). Such materials are used in devices like [Faraday rotators](https://en.wikipedia.org/wiki/Faraday_rotator). The following discussion concerns a medium with gyrotropic ε (i.e., a gyroelectric medium). Gyromagnetic media can be treated by the usual substitution of ε with μ, **E** with **H**, etc. +(**Experimental feature**) Meep supports gyrotropic media, which break optical reciprocity and give rise to magneto-optical phenomena such as the [Faraday effect](https://en.wikipedia.org/wiki/Faraday_effect). Such materials are used in devices like [Faraday rotators](https://en.wikipedia.org/wiki/Faraday_rotator). The following discussion concerns media with gyrotropic ε (i.e., gyroelectric media). Gyromagnetic media, which have gyrotropic μ, can be treated by the usual substitution of ε with μ, **E** with **H**, etc. -In a gyroelectric medium, the equation of motion of the polarization vector $\mathbf{P}_n$ is a variant of the [Landau-Lifshitz-Gilbert equation](https://en.wikipedia.org/wiki/Landau%E2%80%93Lifshitz%E2%80%93Gilbert_equation): +In a gyrotropic medium, the polarization vector $\mathbf{P}_n$ undergoes precession around a preferred direction. There are two available equations of motion for $\mathbf{P}_n$. The first is a [Drude-Lorentz](Materials.md#material-dispersion) model with an additional precession term: + +$$\frac{d^2\mathbf{P}_n}{dt^2} + \gamma_n \frac{d\mathbf{P}_n}{dt} + \mathbf{b}_n \times \frac{d\mathbf{P}_n}{dt} + \omega_n^2 \mathbf{P}_n = \sigma_n(\mathbf{x}) \omega_n^2 \mathbf{E}$$ + +(The above equation shows the Lorentz case; for the Drude case, the $\omega_n^2 \mathbf{P}_n$ term on the left-hand side is omitted.) The third term on the left-hand side breaks time-reversal symmetry and is responsible for the gyrotropy; it is parameterized by the bias vector $\mathbf{b}_n$, usually describing the effect of a static magnetic field applied to the material. In the $\gamma_n = \omega_n = 0$ limit, the equation of motion reduces to a precession around $\mathbf{b}_n$, with angular frequency equal to $|\mathbf{b}_n|$: + +$$\frac{d\mathbf{P}_n}{dt} = \mathbf{P}_n \times \mathbf{b}_n$$ + +The second type of gyrotropic equation of motion is a linearized [Landau-Lifshitz-Gilbert equation](https://en.wikipedia.org/wiki/Landau%E2%80%93Lifshitz%E2%80%93Gilbert_equation): $$\frac{d\mathbf{P}_n}{dt} = \mathbf{b}_n \times \left( - \sigma_n \mathbf{E} + \omega_n \mathbf{P}_n + \alpha_n \frac{d\mathbf{P}_n}{dt} \right) - \gamma_n \mathbf{P}_n$$ -Although this is completely different from the damped harmonic oscillator equation used for [Drude-Lorentz susceptibility](Materials.md#material-dispersion), the constants σ$_n$, ω$_n$, and γ$_n$ play analogous roles: σ$_n$ couples the polarization to the electric field, ω$_n$ is the angular frequency of precession, and γ$_n$ is a damping factor. There is also a second damping factor α$_n$, and a "bias vector" **b**$_n$ which typically describes the direction of an applied static magnetic field. The bias vector is assumed to have unit length. +The Landau-Lifshitz-Gilbert equation describes the precessional motion of a point magnetic dipole in a magnetic field; when it is used to model magnetic susceptibility, it accurately describes the behavior of gyromagnetic materials such as ferrites. Although this equation of motion is completely different from the [Drude-Lorentz equation](Materials.md#material-dispersion), the constants σ$_n$, ω$_n$, and γ$_n$ play analogous roles: σ$_n$ couples the polarization to the electric field, ω$_n$ is the angular frequency of precession, and γ$_n$ is a damping factor. There is also a second damping factor α$_n$, and a bias vector **b**$_n$. -In the frequency domain, a gyroelectric medium has skew-symmetric off-diagonal components in the ε tensor. Take the case $\mathbf{b} = b \hat{z}$. When all fields have harmonic time-dependence $\exp(-i\omega t)$, the polarization equation of motion reduces to +In the frequency domain, a gyroelectric medium exhibits skew-symmetric off-diagonal components in its ε tensor. Take the case $\mathbf{b} = b \hat{z}$. When all fields have harmonic time-dependence $\exp(-i\omega t)$, the polarization equation of motion reduces to $$\mathbf{P}_n = \begin{bmatrix}\chi_\perp & -i\eta & 0 \\ i\eta & \chi_\perp & 0 \\ 0 & 0 & \chi_\parallel \end{bmatrix} \mathbf{E}$$ For the gyrotropic Lorentzian model, -In the frequency domain, the ε tensor acquires off-diagonal components representing a gyrotropic response. Take the case $\mathbf{b}_n = \hat{\mathbf{z}}$, and assume that all fields have harmonic time-dependence $\exp(-i\omega t)$. The polarization equation then reduces to - -$$\chi_\perp = \frac{\omega_n^2 \Delta_n}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}),\;\;\; \chi_\parallel = \frac{\omega_n^2}{\Delta_n}\,\sigma_n(\mathbf{x}), \;\;\; \eta = \frac{\omega_n^2 \omega b}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}), \;\;\;\Delta_n \equiv \omega_n^2 - \omega^2 - i\omega\gamma_n$$ +$$\chi_\perp = \frac{\omega_n^2 \Delta_n \sigma_n}{\Delta_n^2 - \omega^2 b^2},\;\;\; \chi_\parallel = \frac{\omega_n^2 \sigma_n}{\Delta_n}, \;\;\; \eta = \frac{\omega_n^2 \omega b \sigma_n}{\Delta_n^2 - \omega^2 b^2}, \;\;\;\Delta_n \equiv \omega_n^2 - \omega^2 - i\omega\gamma_n$$ And for the Landau-Lifshitz-Gilbert model, From 67e60dee9b2d181627b4258eef4d83ea8a6b432d Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sun, 2 Jun 2019 16:47:54 +0800 Subject: [PATCH 42/61] Introduce a new gyrotropy_model enum type, to allow for the LLG model. --- scheme/structure.cpp | 12 ++++++------ src/meep.hpp | 8 ++++++-- src/meepgeom.cpp | 6 ++++-- src/susceptibility.cpp | 8 ++++---- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/scheme/structure.cpp b/scheme/structure.cpp index 85a601965..59f042348 100644 --- a/scheme/structure.cpp +++ b/scheme/structure.cpp @@ -1299,10 +1299,10 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) gyrotropic_lorentzian_susceptibility *gd = d->subclass.gyrotropic_lorentzian_susceptibility_data; master_printf("gyrotropic lorentzian susceptibility: bias=(%g,%g,%g), frequency=%g, gamma=%g\n", gd->bias.x, gd->bias.y, gd->bias.z, d->frequency, d->gamma); - sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma); + sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma, + meep::GYROTROPIC_LORENTZIAN); } else { // just a Lorentzian - master_printf("lorentzian susceptibility: frequency=%g, gamma=%g\n", d->frequency, - d->gamma); + master_printf("lorentzian susceptibility: frequency=%g, gamma=%g\n", d->frequency, d->gamma); sus = new meep::lorentzian_susceptibility(d->frequency, d->gamma); } break; @@ -1313,13 +1313,13 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) noisy_drude_susceptibility *nd = d->subclass.noisy_drude_susceptibility_data; master_printf("noisy drude susceptibility: frequency=%g, gamma=%g, amp = %g\n", d->frequency, d->gamma, nd->noise_amp); - sus = new meep::noisy_lorentzian_susceptibility(nd->noise_amp, d->frequency, d->gamma, - true); + sus = new meep::noisy_lorentzian_susceptibility(nd->noise_amp, d->frequency, d->gamma, true); } else if (d->which_subclass == drude_susceptibility::GYROTROPIC_DRUDE_SUSCEPTIBILITY) { gyrotropic_drude_susceptibility *gd = d->subclass.gyrotropic_drude_susceptibility_data; master_printf("gyrotropic drude susceptibility: bias=(%g,%g,%g), frequency=%g, gamma=%g\n", gd->bias.x, gd->bias.y, gd->bias.z, d->frequency, d->gamma); - sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma, true); + sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma, + meep::GYROTROPIC_DRUDE); } else { // just a Drude master_printf("drude susceptibility: frequency=%g, gamma=%g\n", d->frequency, d->gamma); sus = new meep::lorentzian_susceptibility(d->frequency, d->gamma, true); diff --git a/src/meep.hpp b/src/meep.hpp index e1a1767a9..bc566dfc7 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -272,11 +272,13 @@ class noisy_lorentzian_susceptibility : public lorentzian_susceptibility { double noise_amp; }; +typedef enum { GYROTROPIC_LORENTZIAN, GYROTROPIC_DRUDE, LANDAU_LIFSHITZ_GILBERT } gyrotropy_model; + /* gyrotropic susceptibility */ -class gyrotropic_susceptibility : public lorentzian_susceptibility { +class gyrotropic_susceptibility : public susceptibility { public: gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma, - bool no_omega_0_denominator = true); + gyrotropy_model model=GYROTROPIC_LORENTZIAN); virtual susceptibility *clone() const { return new gyrotropic_susceptibility(*this); } virtual void *new_internal_data(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv) const; @@ -305,6 +307,8 @@ class gyrotropic_susceptibility : public lorentzian_susceptibility { protected: double gyro_tensor[3][3]; + double omega_0, gamma; + gyrotropy_model model; }; class multilevel_susceptibility : public susceptibility { diff --git a/src/meepgeom.cpp b/src/meepgeom.cpp index a259669b5..ddbc52632 100644 --- a/src/meepgeom.cpp +++ b/src/meepgeom.cpp @@ -1375,8 +1375,10 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) sus = new meep::noisy_lorentzian_susceptibility(ss->noise_amp, ss->frequency, ss->gamma, ss->drude); } else if (gyrotropic) { - sus = new meep::gyrotropic_susceptibility(meep::vec(ss->bias.x, ss->bias.y, ss->bias.z), ss->frequency, - ss->gamma, ss->drude); + meep::gyrotropy_model model + = ss->drude ? meep::GYROTROPIC_DRUDE : meep::GYROTROPIC_LORENTZIAN; + sus = new meep::gyrotropic_susceptibility(meep::vec(ss->bias.x, ss->bias.y, ss->bias.z), + ss->frequency, ss->gamma, model); } else { sus = new meep::lorentzian_susceptibility(ss->frequency, ss->gamma, ss->drude); } diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index e0ef45d9a..d6a565316 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -324,8 +324,8 @@ void noisy_lorentzian_susceptibility::dump_params(h5file *h5f, size_t *start) { gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma, - bool no_omega_0_denominator) - : lorentzian_susceptibility(omega_0, gamma, no_omega_0_denominator) { + gyrotropy_model model) + : omega_0(omega_0), gamma(gamma), model(model) { // Precalculate g_{ij} = sum_k epsilon_{ijk} b_k, used in update_P. memset(gyro_tensor, 0, 9 * sizeof(double)); gyro_tensor[X][Y] = bias.z(); gyro_tensor[Y][X] = -bias.z(); @@ -410,7 +410,7 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const double omega2pi = 2 * pi * omega_0, g2pi = gamma * 2 * pi; const double omega0dtsqr = omega2pi * omega2pi * dt * dt; const double gamma1 = (1 - g2pi * dt / 2); - const double diagfac = 2 - (no_omega_0_denominator ? 0 : omega0dtsqr); + const double diagfac = 2 - (model == GYROTROPIC_DRUDE ? 0 : omega0dtsqr); const double pt = pi*dt; (void)W_prev; // unused; @@ -506,7 +506,7 @@ void gyrotropic_susceptibility::dump_params(h5file *h5f, size_t *start) { double bias[] = { gyro_tensor[Y][Z], gyro_tensor[Z][X], gyro_tensor[X][Y] }; double params_data[] = { 7, (double)get_id(), bias[X], bias[Y], bias[Z], - omega_0, gamma, (double)no_omega_0_denominator}; + omega_0, gamma, (double)model}; h5f->write_chunk(1, start, params_dims, params_data); *start += num_params; } From 566e32c142057e3cb901abcba651af80371ed769 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Mon, 3 Jun 2019 15:51:36 +0800 Subject: [PATCH 43/61] More plumbing to provide support for Landau-Lifshitz-Gilbert type gyrotropy model --- python/geom.py | 10 +++- python/meep.i | 1 + python/typemap_utils.cpp | 15 ++++- scheme/meep.scm.in | 6 ++ scheme/structure.cpp | 12 +++- src/material_data.hpp | 2 + src/meep.hpp | 6 +- src/meepgeom.cpp | 15 +++-- src/susceptibility.cpp | 123 ++++++++++++++++++++++----------------- 9 files changed, 122 insertions(+), 68 deletions(-) diff --git a/python/geom.py b/python/geom.py index 002ecc5ff..e3dc6ea61 100644 --- a/python/geom.py +++ b/python/geom.py @@ -292,8 +292,16 @@ def __init__(self, bias=Vector3(), **kwargs): super(GyrotropicDrudeSusceptibility, self).__init__(**kwargs) self.bias = bias +class GyrotropicSaturatedSusceptibility(Susceptibility): - class MultilevelAtom(Susceptibility): + def __init__(self, bias=Vector3(), frequency=0.0, gamma=0.0, alpha=0.0, **kwargs): + super(GyrotropicSaturatedSusceptibility, self).__init__(**kwargs) + self.frequency = frequency + self.gamma = gamma + self.bias = bias + self.alpha = alpha + +class MultilevelAtom(Susceptibility): def __init__(self, initial_populations=[], transitions=[], **kwargs): super(MultilevelAtom, self).__init__(**kwargs) diff --git a/python/meep.i b/python/meep.i index 998f13133..af274db9d 100644 --- a/python/meep.i +++ b/python/meep.i @@ -1373,6 +1373,7 @@ PyObject *_get_array_slice_dimensions(meep::fields *f, const meep::volume &where GeometricObject, GyrotropicDrudeSusceptibility, GyrotropicLorentzianSusceptibility, + GyrotropicSaturatedSusceptibility, Lattice, LorentzianSusceptibility, Matrix, diff --git a/python/typemap_utils.cpp b/python/typemap_utils.cpp index 5c74107c6..04f472347 100644 --- a/python/typemap_utils.cpp +++ b/python/typemap_utils.cpp @@ -329,8 +329,10 @@ static int py_susceptibility_to_susceptibility(PyObject *po, susceptibility_stru s->frequency = 0; s->gamma = 0; + s->alpha = 0; s->noise_amp = 0; s->bias.x = s->bias.y = s->bias.z = 0; + s->saturated_gyrotropy = false; s->transitions.resize(0); s->initial_populations.resize(0); @@ -350,6 +352,11 @@ static int py_susceptibility_to_susceptibility(PyObject *po, susceptibility_stru if (!get_attr_v3(po, &s->bias, "bias")) return 0; } + if (PyObject_HasAttrString(po, "alpha")) { + s->saturated_gyrotropy = true; + if (!get_attr_dbl(po, &s->alpha, "alpha")) { return 0; } + } + if (PyObject_HasAttrString(po, "transitions")) { // MultilevelAtom PyObject *py_trans = PyObject_GetAttrString(po, "transitions"); @@ -464,8 +471,12 @@ static PyObject *susceptibility_to_py_obj(susceptibility_struct *s) { PyObject *res; PyObject *args = PyTuple_New(0); - if (s->bias.x || s->bias.y || s->bias.z) { - if (s->drude) { + if (s->saturated_gyrotropy || s->bias.x || s->bias.y || s->bias.z) { + if (s->saturated_gyrotropy) { + PyObject *py_gyrotropic_class = PyObject_GetAttrString(geom_mod, "GyrotropicSaturatedSusceptibility"); + res = PyObject_Call(py_gyrotropic_class, args, NULL); + Py_DECREF(py_gyrotropic_class); + } else if (s->drude) { PyObject *py_gyrotropic_drude_class = PyObject_GetAttrString(geom_mod, "GyrotropicDrudeSusceptibility"); res = PyObject_Call(py_gyrotropic_drude_class, args, NULL); Py_DECREF(py_gyrotropic_drude_class); diff --git a/scheme/meep.scm.in b/scheme/meep.scm.in index cfec58b06..7c312c83a 100644 --- a/scheme/meep.scm.in +++ b/scheme/meep.scm.in @@ -62,6 +62,12 @@ (define-class gyrotropic-drude-susceptibility drude-susceptibility (define-property bias no-default 'vector3)) +(define-class gyrotropic-saturated-susceptibility susceptibility + (define-property frequency no-default 'number) + (define-property gamma no-default 'number) + (define-property bias no-default 'vector3) + (define-property alpha no-default 'number)) + (define polarizability lorentzian-susceptibility) ; backwards compat (define omega frequency) ; backwards compat (define (sigma x) (sigma-diag x x x)) diff --git a/scheme/structure.cpp b/scheme/structure.cpp index 59f042348..d71626bcf 100644 --- a/scheme/structure.cpp +++ b/scheme/structure.cpp @@ -1300,7 +1300,7 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) master_printf("gyrotropic lorentzian susceptibility: bias=(%g,%g,%g), frequency=%g, gamma=%g\n", gd->bias.x, gd->bias.y, gd->bias.z, d->frequency, d->gamma); sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma, - meep::GYROTROPIC_LORENTZIAN); + 0.0, meep::GYROTROPIC_LORENTZIAN); } else { // just a Lorentzian master_printf("lorentzian susceptibility: frequency=%g, gamma=%g\n", d->frequency, d->gamma); sus = new meep::lorentzian_susceptibility(d->frequency, d->gamma); @@ -1319,13 +1319,21 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) master_printf("gyrotropic drude susceptibility: bias=(%g,%g,%g), frequency=%g, gamma=%g\n", gd->bias.x, gd->bias.y, gd->bias.z, d->frequency, d->gamma); sus = new meep::gyrotropic_susceptibility(vector3_to_vec(gd->bias), d->frequency, d->gamma, - meep::GYROTROPIC_DRUDE); + 0.0, meep::GYROTROPIC_DRUDE); } else { // just a Drude master_printf("drude susceptibility: frequency=%g, gamma=%g\n", d->frequency, d->gamma); sus = new meep::lorentzian_susceptibility(d->frequency, d->gamma, true); } break; } + case susceptibility::GYROTROPIC_SATURATED_SUSCEPTIBILITY: { + gyrotropic_saturated_susceptibility *d = p->user_s.subclass.gyrotropic_saturated_susceptibility_data; + master_printf("gyrotropic Landau-Lifshitz-Gilbert-type susceptibility: bias=(%g,%g,%g), frequency=%g, gamma=%g, alpha=%g\n", + d->bias.x, d->bias.y, d->bias.z, d->frequency, d->gamma, d->alpha); + sus = new meep::gyrotropic_susceptibility(vector3_to_vec(d->bias), d->frequency, d->gamma, + d->alpha, meep::GYROTROPIC_SATURATED); + break; + } case susceptibility::MULTILEVEL_ATOM: { multilevel_atom *d = p->user_s.subclass.multilevel_atom_data; sus = make_multilevel_sus(d); diff --git a/src/material_data.hpp b/src/material_data.hpp index 352b6155e..20c6f9823 100644 --- a/src/material_data.hpp +++ b/src/material_data.hpp @@ -62,8 +62,10 @@ typedef struct susceptibility_struct { vector3 bias; double frequency; double gamma; + double alpha; double noise_amp; bool drude; + bool saturated_gyrotropy; bool is_file; std::vector transitions; std::vector initial_populations; diff --git a/src/meep.hpp b/src/meep.hpp index bc566dfc7..c1fd244d5 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -272,12 +272,12 @@ class noisy_lorentzian_susceptibility : public lorentzian_susceptibility { double noise_amp; }; -typedef enum { GYROTROPIC_LORENTZIAN, GYROTROPIC_DRUDE, LANDAU_LIFSHITZ_GILBERT } gyrotropy_model; +typedef enum { GYROTROPIC_LORENTZIAN, GYROTROPIC_DRUDE, GYROTROPIC_SATURATED } gyrotropy_model; /* gyrotropic susceptibility */ class gyrotropic_susceptibility : public susceptibility { public: - gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma, + gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma, double alpha=0.0, gyrotropy_model model=GYROTROPIC_LORENTZIAN); virtual susceptibility *clone() const { return new gyrotropic_susceptibility(*this); } @@ -307,7 +307,7 @@ class gyrotropic_susceptibility : public susceptibility { protected: double gyro_tensor[3][3]; - double omega_0, gamma; + double omega_0, gamma, alpha; gyrotropy_model model; }; diff --git a/src/meepgeom.cpp b/src/meepgeom.cpp index ddbc52632..efab7a6d3 100644 --- a/src/meepgeom.cpp +++ b/src/meepgeom.cpp @@ -1375,18 +1375,23 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) sus = new meep::noisy_lorentzian_susceptibility(ss->noise_amp, ss->frequency, ss->gamma, ss->drude); } else if (gyrotropic) { - meep::gyrotropy_model model - = ss->drude ? meep::GYROTROPIC_DRUDE : meep::GYROTROPIC_LORENTZIAN; + meep::gyrotropy_model model + = ss->saturated_gyrotropy ? meep::GYROTROPIC_SATURATED + : ss->drude ? meep::GYROTROPIC_DRUDE : meep::GYROTROPIC_LORENTZIAN; sus = new meep::gyrotropic_susceptibility(meep::vec(ss->bias.x, ss->bias.y, ss->bias.z), - ss->frequency, ss->gamma, model); + ss->frequency, ss->gamma, ss->alpha, model); } else { sus = new meep::lorentzian_susceptibility(ss->frequency, ss->gamma, ss->drude); } master_printf("%s%s susceptibility: frequency=%g, gamma=%g", noisy ? "noisy " : gyrotropic ? "gyrotropic " : "", - ss->drude ? "drude" : "lorentzian", ss->frequency, ss->gamma); + ss->saturated_gyrotropy ? "Landau-Lifshitz-Gilbert-type" + : ss->drude ? "drude" : "lorentzian", ss->frequency, ss->gamma); if (noisy) master_printf(", amp=%g ", ss->noise_amp); - if (gyrotropic) master_printf(", bias=(%g,%g,%g) ", ss->bias.x, ss->bias.y, ss->bias.z); + if (gyrotropic) { + if (ss->saturated_gyrotropy) master_printf(", alpha=%g", ss->alpha); + master_printf(", bias=(%g,%g,%g)", ss->bias.x, ss->bias.y, ss->bias.z); + } master_printf("\n"); } diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index d6a565316..a36cb94e4 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -324,8 +324,8 @@ void noisy_lorentzian_susceptibility::dump_params(h5file *h5f, size_t *start) { gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double omega_0, double gamma, - gyrotropy_model model) - : omega_0(omega_0), gamma(gamma), model(model) { + double alpha, gyrotropy_model model) + : omega_0(omega_0), gamma(gamma), alpha(alpha), model(model) { // Precalculate g_{ij} = sum_k epsilon_{ijk} b_k, used in update_P. memset(gyro_tensor, 0, 9 * sizeof(double)); gyro_tensor[X][Y] = bias.z(); gyro_tensor[Y][X] = -bias.z(); @@ -408,63 +408,76 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const grid_volume &gv, void *P_internal_data) const { gyrotropy_data *d = (gyrotropy_data *)P_internal_data; const double omega2pi = 2 * pi * omega_0, g2pi = gamma * 2 * pi; - const double omega0dtsqr = omega2pi * omega2pi * dt * dt; - const double gamma1 = (1 - g2pi * dt / 2); - const double diagfac = 2 - (model == GYROTROPIC_DRUDE ? 0 : omega0dtsqr); - const double pt = pi*dt; (void)W_prev; // unused; - // Precalculate 3x3 matrix inverse, exploiting skew symmetry - const double gd = (1 + g2pi * dt / 2); - const double gx = pt * gyro_tensor[Y][Z]; - const double gy = pt * gyro_tensor[Z][X]; - const double gz = pt * gyro_tensor[X][Y]; - const double invdet = 1.0 / gd / (gd*gd + gx*gx + gy*gy + gz*gz); - const double inv[3][3] - = {{ invdet*(gd*gd+gx*gx), invdet*(gx*gy+gd*gz), invdet*(gx*gz-gd*gy) }, - { invdet*(gy*gx-gd*gz), invdet*(gd*gd+gy*gy), invdet*(gy*gz+gd*gx) }, - { invdet*(gz*gx+gd*gy), invdet*(gz*gy-gd*gx), invdet*(gd*gd+gz*gz) }}; - - FOR_COMPONENTS(c) DOCMP2 { - if (d->P[c][cmp][0]) { - const direction d0 = component_direction(c); - const realnum *w0 = W[c][cmp], *s = sigma[c][d0]; - - if (!w0 || !s || (d0 != X && d0 != Y && d0 != Z)) - abort("gyrotropic media require 3D Cartesian fields\n"); - - const direction d1 = cycle_direction(gv.dim, d0, 1); - const direction d2 = cycle_direction(gv.dim, d0, 2); - const realnum *w1 = W[direction_component(c, d1)][cmp]; - const realnum *w2 = W[direction_component(c, d2)][cmp]; - realnum *p0 = d->P[c][cmp][d0], *pp0 = d->P_prev[c][cmp][d0]; - realnum *p1 = d->P[c][cmp][d1], *pp1 = d->P_prev[c][cmp][d1]; - realnum *p2 = d->P[c][cmp][d2], *pp2 = d->P_prev[c][cmp][d2]; - const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); - const ptrdiff_t is1 = gv.stride(d1) * (is_magnetic(c) ? -1 : +1); - const ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); - realnum rhs0, rhs1, rhs2; - - if (!pp1 || !pp2) - abort("gyrotropic media require 3D Cartesian fields\n"); - - if (sigma[c][d1] || sigma[c][d2]) - abort("gyrotropic media do not support anisotropic sigma\n"); - - LOOP_OVER_VOL_OWNED(gv, c, i) { - rhs0 = diagfac*p0[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w0[i] - - pt*gyro_tensor[d0][d1]*pp1[i] - pt*gyro_tensor[d0][d2]*pp2[i]; - rhs1 = diagfac*p1[i] - gamma1*pp1[i] + (w1 ? omega0dtsqr*s[i]*OFFDIAG(s,w1,is1,is) : 0) - - pt*gyro_tensor[d1][d0]*pp0[i] - pt*gyro_tensor[d1][d2]*pp2[i]; - rhs2 = diagfac*p2[i] - gamma1*pp2[i] + (w2 ? omega0dtsqr*s[i]*OFFDIAG(s,w2,is2,is) : 0) - - pt*gyro_tensor[d2][d1]*pp1[i] - pt*gyro_tensor[d2][d0]*pp0[i]; - - pp0[i] = p0[i]; pp1[i] = p1[i]; pp2[i] = p2[i]; - p0[i] = inv[d0][d0] * rhs0 + inv[d0][d1] * rhs1 + inv[d0][d2] * rhs2; - p1[i] = inv[d1][d0] * rhs0 + inv[d1][d1] * rhs1 + inv[d1][d2] * rhs2; - p2[i] = inv[d2][d0] * rhs0 + inv[d2][d1] * rhs1 + inv[d2][d2] * rhs2; + switch (model) { + case GYROTROPIC_LORENTZIAN: + case GYROTROPIC_DRUDE: + { + const double omega0dtsqr = omega2pi * omega2pi * dt * dt; + const double gamma1 = (1 - g2pi * dt / 2); + const double diagfac = 2 - (model == GYROTROPIC_DRUDE ? 0 : omega0dtsqr); + const double pt = pi*dt; + + // Precalculate 3x3 matrix inverse, exploiting skew symmetry + const double gd = (1 + g2pi * dt / 2); + const double gx = pt * gyro_tensor[Y][Z]; + const double gy = pt * gyro_tensor[Z][X]; + const double gz = pt * gyro_tensor[X][Y]; + const double invdet = 1.0 / gd / (gd*gd + gx*gx + gy*gy + gz*gz); + const double inv[3][3] + = {{ invdet*(gd*gd+gx*gx), invdet*(gx*gy+gd*gz), invdet*(gx*gz-gd*gy) }, + { invdet*(gy*gx-gd*gz), invdet*(gd*gd+gy*gy), invdet*(gy*gz+gd*gx) }, + { invdet*(gz*gx+gd*gy), invdet*(gz*gy-gd*gx), invdet*(gd*gd+gz*gz) }}; + + FOR_COMPONENTS(c) DOCMP2 { + if (d->P[c][cmp][0]) { + const direction d0 = component_direction(c); + const realnum *w0 = W[c][cmp], *s = sigma[c][d0]; + + if (!w0 || !s || (d0 != X && d0 != Y && d0 != Z)) + abort("gyrotropic media require 3D Cartesian fields\n"); + + const direction d1 = cycle_direction(gv.dim, d0, 1); + const direction d2 = cycle_direction(gv.dim, d0, 2); + const realnum *w1 = W[direction_component(c, d1)][cmp]; + const realnum *w2 = W[direction_component(c, d2)][cmp]; + realnum *p0 = d->P[c][cmp][d0], *pp0 = d->P_prev[c][cmp][d0]; + realnum *p1 = d->P[c][cmp][d1], *pp1 = d->P_prev[c][cmp][d1]; + realnum *p2 = d->P[c][cmp][d2], *pp2 = d->P_prev[c][cmp][d2]; + const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); + const ptrdiff_t is1 = gv.stride(d1) * (is_magnetic(c) ? -1 : +1); + const ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); + realnum rhs0, rhs1, rhs2; + + if (!pp1 || !pp2) + abort("gyrotropic media require 3D Cartesian fields\n"); + if (sigma[c][d1] || sigma[c][d2]) + abort("gyrotropic media do not support anisotropic sigma\n"); + + LOOP_OVER_VOL_OWNED(gv, c, i) { + rhs0 = diagfac*p0[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w0[i] + - pt*gyro_tensor[d0][d1]*pp1[i] - pt*gyro_tensor[d0][d2]*pp2[i]; + rhs1 = diagfac*p1[i] - gamma1*pp1[i] + (w1 ? omega0dtsqr*s[i]*OFFDIAG(s,w1,is1,is) : 0) + - pt*gyro_tensor[d1][d0]*pp0[i] - pt*gyro_tensor[d1][d2]*pp2[i]; + rhs2 = diagfac*p2[i] - gamma1*pp2[i] + (w2 ? omega0dtsqr*s[i]*OFFDIAG(s,w2,is2,is) : 0) + - pt*gyro_tensor[d2][d1]*pp1[i] - pt*gyro_tensor[d2][d0]*pp0[i]; + + pp0[i] = p0[i]; pp1[i] = p1[i]; pp2[i] = p2[i]; + p0[i] = inv[d0][d0] * rhs0 + inv[d0][d1] * rhs1 + inv[d0][d2] * rhs2; + p1[i] = inv[d1][d0] * rhs0 + inv[d1][d1] * rhs1 + inv[d1][d2] * rhs2; + p2[i] = inv[d2][d0] * rhs0 + inv[d2][d1] * rhs1 + inv[d2][d2] * rhs2; + } + } } } + break; + + case GYROTROPIC_SATURATED: + { + abort("Landau-Liftshitz-Gilbert type gyrotropy is not yet implemented\n"); + } + break; } } From 6b76cccff10d4c60411b5f58dac803b0ffacd0e1 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Tue, 4 Jun 2019 11:03:45 +0800 Subject: [PATCH 44/61] Fix typo in susceptibility update equation --- python/examples/faraday-rotation.py | 16 ++++++++-------- src/susceptibility.cpp | 7 +++++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/python/examples/faraday-rotation.py b/python/examples/faraday-rotation.py index 9b415fabd..28a74f75c 100644 --- a/python/examples/faraday-rotation.py +++ b/python/examples/faraday-rotation.py @@ -2,10 +2,10 @@ ## Define a gyroelectric medium f0 = 1.0 -gamma = 1e-4 -epsn = 2.0 -b0 = 1.05 -sn = 0.2 +gamma = 1e-6 +epsn = 1.5 +b0 = 0.15 +sn = 0.1 susc = [mp.GyrotropicLorentzianSusceptibility(frequency=f0, gamma=gamma, sigma=sn, bias=mp.Vector3(0, 0, b0))] @@ -24,7 +24,7 @@ sim = mp.Simulation(cell_size=cell, geometry=[], sources=sources, k_point=mp.Vector3(), # Periodic boundary conditions boundary_layers=pml_layers, - default_material=mat, resolution=50) + default_material=mat, resolution=100) sim.run(until=tmax) ## Plot results: @@ -42,13 +42,13 @@ plt.legend() ## Comparison with analytic result: -dfsq = (f0*2 - 1j*f0*gamma - fsrc**2) +dfsq = (f0**2 - 1j*fsrc*gamma - fsrc**2) eperp = epsn + sn * f0**2 * dfsq / (dfsq**2 + (fsrc*b0)**2) eta = sn * f0**2 * fsrc * b0 / (dfsq**2 + (fsrc*b0)**2) k_gyro = 2*np.pi*fsrc * np.sqrt(0.5*(eperp - np.sqrt(eperp**2 - eta**2))) -Ex_theory = 0.37 * np.cos(k_gyro * (z - src_z)) -Ey_theory = 0.37 * np.sin(k_gyro * (z - src_z)) +Ex_theory = 0.37 * np.cos(k_gyro * (z - src_z)).real +Ey_theory = 0.37 * np.sin(k_gyro * (z - src_z)).real plt.figure(2) plt.subplot(2,1,1) diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index e0ef45d9a..2165652e2 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -403,6 +403,9 @@ bool gyrotropic_susceptibility::needs_P(component c, int cmp, realnum *W[NUM_FIE return (d0 == X || d0 == Y || d0 == Z) && sigma[c][d0] && W[c][cmp]; } +// Similar to the OFFDIAG macro, but without averaging sigma. +#define OFFDIAGW(g, sx, s) (0.25 * (g[i] + g[i - sx] + g[i + s] + g[i + s - sx])) + void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, const grid_volume &gv, void *P_internal_data) const { @@ -454,9 +457,9 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], LOOP_OVER_VOL_OWNED(gv, c, i) { rhs0 = diagfac*p0[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w0[i] - pt*gyro_tensor[d0][d1]*pp1[i] - pt*gyro_tensor[d0][d2]*pp2[i]; - rhs1 = diagfac*p1[i] - gamma1*pp1[i] + (w1 ? omega0dtsqr*s[i]*OFFDIAG(s,w1,is1,is) : 0) + rhs1 = diagfac*p1[i] - gamma1*pp1[i] + (w1 ? omega0dtsqr*s[i]*OFFDIAGW(w1,is1,is) : 0) - pt*gyro_tensor[d1][d0]*pp0[i] - pt*gyro_tensor[d1][d2]*pp2[i]; - rhs2 = diagfac*p2[i] - gamma1*pp2[i] + (w2 ? omega0dtsqr*s[i]*OFFDIAG(s,w2,is2,is) : 0) + rhs2 = diagfac*p2[i] - gamma1*pp2[i] + (w2 ? omega0dtsqr*s[i]*OFFDIAGW(w2,is2,is) : 0) - pt*gyro_tensor[d2][d1]*pp1[i] - pt*gyro_tensor[d2][d0]*pp0[i]; pp0[i] = p0[i]; pp1[i] = p1[i]; pp2[i] = p2[i]; From aa32c6ded27f3fe0c144478693fb5d5a6648a219 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Tue, 4 Jun 2019 11:12:00 +0800 Subject: [PATCH 45/61] Fix typos in Faraday rotation formula in docs --- doc/docs/Python_Tutorials/Gyrotropic_Media.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/docs/Python_Tutorials/Gyrotropic_Media.md b/doc/docs/Python_Tutorials/Gyrotropic_Media.md index baf6a25dd..dcccb64b0 100644 --- a/doc/docs/Python_Tutorials/Gyrotropic_Media.md +++ b/doc/docs/Python_Tutorials/Gyrotropic_Media.md @@ -22,7 +22,7 @@ $$\begin{bmatrix}E_x \\ E_y\end{bmatrix} = E_0 \begin{bmatrix}\cos(\kappa_c z) \ where $\kappa_c$ is the Faraday rotation, in radians, per unit of propagation distance. Substituting this into Maxwell's equations, with the above gyroelectric dielectric function, yields -$$|\kappa_c| = \frac{1}{2} \omega^2 \mu \sqrt{\epsilon_\perp - \sqrt{\epsilon_\perp^2 - \eta^2}}$$ +$$|\kappa_c| = \omega \sqrt{\frac{\mu}{2} \, \left(\epsilon_\perp - \sqrt{\epsilon_\perp^2 - \eta^2}\right)}$$ We model this phenomenon in the simulation script [faraday-rotation.py](https://github.com/NanoComp/meep/blob/master/python/examples/faraday-rotation.py). First, we define a gyroelectric material: From 3934533a6b079d6d330eaa1a17dab129ae64bc9a Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Tue, 4 Jun 2019 11:21:42 +0800 Subject: [PATCH 46/61] Merge from master --- src/susceptibility.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index b9b808153..f054e8067 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -461,9 +461,9 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], LOOP_OVER_VOL_OWNED(gv, c, i) { rhs0 = diagfac*p0[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w0[i] - pt*gyro_tensor[d0][d1]*pp1[i] - pt*gyro_tensor[d0][d2]*pp2[i]; - rhs1 = diagfac*p1[i] - gamma1*pp1[i] + (w1 ? omega0dtsqr*s[i]*OFFDIAG(s,w1,is1,is) : 0) + rhs1 = diagfac*p1[i] - gamma1*pp1[i] + (w1 ? omega0dtsqr*s[i]*OFFDIAGW(w1,is1,is) : 0) - pt*gyro_tensor[d1][d0]*pp0[i] - pt*gyro_tensor[d1][d2]*pp2[i]; - rhs2 = diagfac*p2[i] - gamma1*pp2[i] + (w2 ? omega0dtsqr*s[i]*OFFDIAG(s,w2,is2,is) : 0) + rhs2 = diagfac*p2[i] - gamma1*pp2[i] + (w2 ? omega0dtsqr*s[i]*OFFDIAGW(w2,is2,is) : 0) - pt*gyro_tensor[d2][d1]*pp1[i] - pt*gyro_tensor[d2][d0]*pp0[i]; pp0[i] = p0[i]; pp1[i] = p1[i]; pp2[i] = p2[i]; From c499a468190d5d9a2b70499def021fc6eee8ab6c Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Tue, 4 Jun 2019 11:44:02 +0800 Subject: [PATCH 47/61] Reimplement linearized-LLG updating equations --- src/susceptibility.cpp | 81 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 10 deletions(-) diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index f054e8067..8c5108ed0 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -410,20 +410,21 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], realnum *W_prev[NUM_FIELD_COMPONENTS][2], double dt, const grid_volume &gv, void *P_internal_data) const { gyrotropy_data *d = (gyrotropy_data *)P_internal_data; - const double omega2pi = 2 * pi * omega_0, g2pi = gamma * 2 * pi; + const double omega2pidt = 2 * pi * omega_0 * dt; + const double g2pidt = 2 * pi * gamma * dt; (void)W_prev; // unused; switch (model) { case GYROTROPIC_LORENTZIAN: case GYROTROPIC_DRUDE: { - const double omega0dtsqr = omega2pi * omega2pi * dt * dt; - const double gamma1 = (1 - g2pi * dt / 2); - const double diagfac = 2 - (model == GYROTROPIC_DRUDE ? 0 : omega0dtsqr); + const double omega0dtsqr = omega2pidt * omega2pidt; + const double gamma1 = (1 - g2pidt / 2); + const double diag = 2 - (model == GYROTROPIC_DRUDE ? 0 : omega0dtsqr); const double pt = pi*dt; // Precalculate 3x3 matrix inverse, exploiting skew symmetry - const double gd = (1 + g2pi * dt / 2); + const double gd = (1 + g2pidt / 2); const double gx = pt * gyro_tensor[Y][Z]; const double gy = pt * gyro_tensor[Z][X]; const double gz = pt * gyro_tensor[X][Y]; @@ -459,14 +460,14 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], abort("gyrotropic media do not support anisotropic sigma\n"); LOOP_OVER_VOL_OWNED(gv, c, i) { - rhs0 = diagfac*p0[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w0[i] + rhs0 = diag*p0[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w0[i] - pt*gyro_tensor[d0][d1]*pp1[i] - pt*gyro_tensor[d0][d2]*pp2[i]; - rhs1 = diagfac*p1[i] - gamma1*pp1[i] + (w1 ? omega0dtsqr*s[i]*OFFDIAGW(w1,is1,is) : 0) + rhs1 = diag*p1[i] - gamma1*pp1[i] + (w1 ? omega0dtsqr*s[i]*OFFDIAGW(w1,is1,is) : 0) - pt*gyro_tensor[d1][d0]*pp0[i] - pt*gyro_tensor[d1][d2]*pp2[i]; - rhs2 = diagfac*p2[i] - gamma1*pp2[i] + (w2 ? omega0dtsqr*s[i]*OFFDIAGW(w2,is2,is) : 0) + rhs2 = diag*p2[i] - gamma1*pp2[i] + (w2 ? omega0dtsqr*s[i]*OFFDIAGW(w2,is2,is) : 0) - pt*gyro_tensor[d2][d1]*pp1[i] - pt*gyro_tensor[d2][d0]*pp0[i]; - pp0[i] = p0[i]; pp1[i] = p1[i]; pp2[i] = p2[i]; + pp0[i] = p0[i]; pp1[i] = p1[i]; pp2[i] = p2[i]; p0[i] = inv[d0][d0] * rhs0 + inv[d0][d1] * rhs1 + inv[d0][d2] * rhs2; p1[i] = inv[d1][d0] * rhs0 + inv[d1][d1] * rhs1 + inv[d1][d2] * rhs2; p2[i] = inv[d2][d0] * rhs0 + inv[d2][d1] * rhs1 + inv[d2][d2] * rhs2; @@ -478,7 +479,67 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], case GYROTROPIC_SATURATED: { - abort("Landau-Liftshitz-Gilbert type gyrotropy is not yet implemented\n"); + const double dwfac = -2*pi*omega2pidt, alppi = pi*alpha; + const double dt2pi = 2*pi*dt; + + // Precalculate 3x3 matrix inverse, exploiting skew symmetry + const double gd = 0.5; + const double gx = -0.5 * alpha * gyro_tensor[Y][Z]; + const double gy = -0.5 * alpha * gyro_tensor[Z][X]; + const double gz = -0.5 * alpha * gyro_tensor[X][Y]; + const double invdet = 1.0 / gd / (gd*gd + gx*gx + gy*gy + gz*gz); + const double inv[3][3] + = {{ invdet*(gd*gd+gx*gx), invdet*(gx*gy+gd*gz), invdet*(gx*gz-gd*gy) }, + { invdet*(gy*gx-gd*gz), invdet*(gd*gd+gy*gy), invdet*(gy*gz+gd*gx) }, + { invdet*(gz*gx+gd*gy), invdet*(gz*gy-gd*gx), invdet*(gd*gd+gz*gz) }}; + + FOR_COMPONENTS(c) DOCMP2 { + if (d->P[c][cmp][0]) { + const direction d0 = component_direction(c); + const realnum *w0 = W[c][cmp], *s = sigma[c][d0]; + + if (!w0 || !s || (d0 != X && d0 != Y && d0 != Z)) + abort("gyrotropic media require 3D Cartesian fields\n"); + + const direction d1 = cycle_direction(gv.dim, d0, 1); + const direction d2 = cycle_direction(gv.dim, d0, 2); + const realnum *w1 = W[direction_component(c, d1)][cmp]; + const realnum *w2 = W[direction_component(c, d2)][cmp]; + realnum *p0 = d->P[c][cmp][d0], *pp0 = d->P_prev[c][cmp][d0]; + realnum *p1 = d->P[c][cmp][d1], *pp1 = d->P_prev[c][cmp][d1]; + realnum *p2 = d->P[c][cmp][d2], *pp2 = d->P_prev[c][cmp][d2]; + const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); + const ptrdiff_t is1 = gv.stride(d1) * (is_magnetic(c) ? -1 : +1); + const ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); + realnum rhs0, rhs1, rhs2; + + if (!pp1 || !pp2) + abort("gyrotropic media require 3D Cartesian fields\n"); + if (sigma[c][d1] || sigma[c][d2]) + abort("gyrotropic media do not support anisotropic sigma\n"); + + LOOP_OVER_VOL_OWNED(gv, c, i) { + rhs0 = 0.5*pp0[i] - g2pidt*p0[i] + + gyro_tensor[d0][d1]*(dwfac*p1[i] + alppi*pp1[i] + + (w1 ? dt2pi*s[i]*OFFDIAGW(w1,is1,is) : 0)) + + gyro_tensor[d0][d2]*(dwfac*p2[i] + alppi*pp2[i] + + (w2 ? dt2pi*s[i]*OFFDIAGW(w2,is2,is) : 0)); + rhs1 = 0.5*pp1[i] - g2pidt*p1[i] + + gyro_tensor[d1][d2]*(dwfac*p2[i] + alppi*pp2[i] + + (w2 ? dt2pi*s[i]*OFFDIAGW(w2,is2,is) : 0)) + + gyro_tensor[d1][d0]*(dwfac*p0[i] + alppi*pp0[i] + dt2pi*s[i]*w0[i]); + rhs2 = 0.5*pp2[i] - g2pidt*p2[i] + + gyro_tensor[d2][d0]*(dwfac*p0[i] + alppi*pp0[i] + dt2pi*s[i]*w0[i]) + + gyro_tensor[d2][d1]*(dwfac*p1[i] + alppi*pp1[i] + + (w1 ? dt2pi*s[i]*OFFDIAGW(w1,is1,is) : 0)); + + pp0[i] = p0[i]; pp1[i] = p1[i]; pp2[i] = p2[i]; + p0[i] = inv[d0][d0] * rhs0 + inv[d0][d1] * rhs1 + inv[d0][d2] * rhs2; + p1[i] = inv[d1][d0] * rhs0 + inv[d1][d1] * rhs1 + inv[d1][d2] * rhs2; + p2[i] = inv[d2][d0] * rhs0 + inv[d2][d1] * rhs1 + inv[d2][d2] * rhs2; + } + } + } } break; } From 545da4a0e30aba636de7d4b9450b5e16eb89d49c Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Tue, 4 Jun 2019 15:48:58 +0800 Subject: [PATCH 48/61] Fix typo --- src/susceptibility.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 8c5108ed0..a3a42335d 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -484,9 +484,9 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], // Precalculate 3x3 matrix inverse, exploiting skew symmetry const double gd = 0.5; - const double gx = -0.5 * alpha * gyro_tensor[Y][Z]; - const double gy = -0.5 * alpha * gyro_tensor[Z][X]; - const double gz = -0.5 * alpha * gyro_tensor[X][Y]; + const double gx = -pi * alpha * gyro_tensor[Y][Z]; + const double gy = -pi * alpha * gyro_tensor[Z][X]; + const double gz = -pi * alpha * gyro_tensor[X][Y]; const double invdet = 1.0 / gd / (gd*gd + gx*gx + gy*gy + gz*gz); const double inv[3][3] = {{ invdet*(gd*gd+gx*gx), invdet*(gx*gy+gd*gz), invdet*(gx*gz-gd*gy) }, From c6576ecb4a79825070f8af0325e6e576d47e7e46 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Tue, 4 Jun 2019 17:33:54 +0800 Subject: [PATCH 49/61] Minor code clarification --- src/susceptibility.cpp | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index a3a42335d..1528c57ee 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -452,7 +452,7 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); const ptrdiff_t is1 = gv.stride(d1) * (is_magnetic(c) ? -1 : +1); const ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); - realnum rhs0, rhs1, rhs2; + realnum r0, r1, r2; if (!pp1 || !pp2) abort("gyrotropic media require 3D Cartesian fields\n"); @@ -460,17 +460,17 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], abort("gyrotropic media do not support anisotropic sigma\n"); LOOP_OVER_VOL_OWNED(gv, c, i) { - rhs0 = diag*p0[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w0[i] + r0 = diag*p0[i] - gamma1*pp0[i] + omega0dtsqr*s[i]*w0[i] - pt*gyro_tensor[d0][d1]*pp1[i] - pt*gyro_tensor[d0][d2]*pp2[i]; - rhs1 = diag*p1[i] - gamma1*pp1[i] + (w1 ? omega0dtsqr*s[i]*OFFDIAGW(w1,is1,is) : 0) + r1 = diag*p1[i] - gamma1*pp1[i] + (w1 ? omega0dtsqr*s[i]*OFFDIAGW(w1,is1,is) : 0) - pt*gyro_tensor[d1][d0]*pp0[i] - pt*gyro_tensor[d1][d2]*pp2[i]; - rhs2 = diag*p2[i] - gamma1*pp2[i] + (w2 ? omega0dtsqr*s[i]*OFFDIAGW(w2,is2,is) : 0) + r2 = diag*p2[i] - gamma1*pp2[i] + (w2 ? omega0dtsqr*s[i]*OFFDIAGW(w2,is2,is) : 0) - pt*gyro_tensor[d2][d1]*pp1[i] - pt*gyro_tensor[d2][d0]*pp0[i]; pp0[i] = p0[i]; pp1[i] = p1[i]; pp2[i] = p2[i]; - p0[i] = inv[d0][d0] * rhs0 + inv[d0][d1] * rhs1 + inv[d0][d2] * rhs2; - p1[i] = inv[d1][d0] * rhs0 + inv[d1][d1] * rhs1 + inv[d1][d2] * rhs2; - p2[i] = inv[d2][d0] * rhs0 + inv[d2][d1] * rhs1 + inv[d2][d2] * rhs2; + p0[i] = inv[d0][d0] * r0 + inv[d0][d1] * r1 + inv[d0][d2] * r2; + p1[i] = inv[d1][d0] * r0 + inv[d1][d1] * r1 + inv[d1][d2] * r2; + p2[i] = inv[d2][d0] * r0 + inv[d2][d1] * r1 + inv[d2][d2] * r2; } } } @@ -511,7 +511,7 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], const ptrdiff_t is = gv.stride(d0) * (is_magnetic(c) ? -1 : +1); const ptrdiff_t is1 = gv.stride(d1) * (is_magnetic(c) ? -1 : +1); const ptrdiff_t is2 = gv.stride(d2) * (is_magnetic(c) ? -1 : +1); - realnum rhs0, rhs1, rhs2; + realnum r0, r1, r2, q0, q1, q2; if (!pp1 || !pp2) abort("gyrotropic media require 3D Cartesian fields\n"); @@ -519,24 +519,18 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], abort("gyrotropic media do not support anisotropic sigma\n"); LOOP_OVER_VOL_OWNED(gv, c, i) { - rhs0 = 0.5*pp0[i] - g2pidt*p0[i] - + gyro_tensor[d0][d1]*(dwfac*p1[i] + alppi*pp1[i] - + (w1 ? dt2pi*s[i]*OFFDIAGW(w1,is1,is) : 0)) - + gyro_tensor[d0][d2]*(dwfac*p2[i] + alppi*pp2[i] - + (w2 ? dt2pi*s[i]*OFFDIAGW(w2,is2,is) : 0)); - rhs1 = 0.5*pp1[i] - g2pidt*p1[i] - + gyro_tensor[d1][d2]*(dwfac*p2[i] + alppi*pp2[i] - + (w2 ? dt2pi*s[i]*OFFDIAGW(w2,is2,is) : 0)) - + gyro_tensor[d1][d0]*(dwfac*p0[i] + alppi*pp0[i] + dt2pi*s[i]*w0[i]); - rhs2 = 0.5*pp2[i] - g2pidt*p2[i] - + gyro_tensor[d2][d0]*(dwfac*p0[i] + alppi*pp0[i] + dt2pi*s[i]*w0[i]) - + gyro_tensor[d2][d1]*(dwfac*p1[i] + alppi*pp1[i] - + (w1 ? dt2pi*s[i]*OFFDIAGW(w1,is1,is) : 0)); + q0 = dwfac*p0[i] + alppi*pp0[i] + dt2pi*s[i]*w0[i]; + q1 = dwfac*p1[i] + alppi*pp1[i] + (w1 ? dt2pi*s[i]*OFFDIAGW(w1,is1,is) : 0); + q2 = dwfac*p2[i] + alppi*pp2[i] + (w2 ? dt2pi*s[i]*OFFDIAGW(w2,is2,is) : 0); + + r0 = 0.5*pp0[i] - g2pidt*p0[i] + gyro_tensor[d0][d1]*q1 + gyro_tensor[d0][d2]*q2; + r1 = 0.5*pp1[i] - g2pidt*p1[i] + gyro_tensor[d1][d2]*q2 + gyro_tensor[d1][d0]*q0; + r2 = 0.5*pp2[i] - g2pidt*p2[i] + gyro_tensor[d2][d0]*q0 + gyro_tensor[d2][d1]*q1; pp0[i] = p0[i]; pp1[i] = p1[i]; pp2[i] = p2[i]; - p0[i] = inv[d0][d0] * rhs0 + inv[d0][d1] * rhs1 + inv[d0][d2] * rhs2; - p1[i] = inv[d1][d0] * rhs0 + inv[d1][d1] * rhs1 + inv[d1][d2] * rhs2; - p2[i] = inv[d2][d0] * rhs0 + inv[d2][d1] * rhs1 + inv[d2][d2] * rhs2; + p0[i] = inv[d0][d0] * r0 + inv[d0][d1] * r1 + inv[d0][d2] * r2; + p1[i] = inv[d1][d0] * r0 + inv[d1][d1] * r1 + inv[d1][d2] * r2; + p2[i] = inv[d2][d0] * r0 + inv[d2][d1] * r1 + inv[d2][d2] * r2; } } } From aedb897184580d0734e6c59ba42b7899d68d8172 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 5 Jun 2019 11:05:34 +0800 Subject: [PATCH 50/61] Fix Faraday rotation example --- doc/docs/Materials.md | 6 ++-- doc/docs/Python_Tutorials/Gyrotropic_Media.md | 32 +++++++++--------- doc/docs/Python_User_Interface.md | 2 +- .../images/Faraday-rotation-comparison.png | Bin 97734 -> 100658 bytes doc/docs/images/Faraday-rotation.png | Bin 71606 -> 76081 bytes python/examples/faraday-rotation.py | 14 ++++---- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/doc/docs/Materials.md b/doc/docs/Materials.md index 1d9a553e5..aeb33576d 100644 --- a/doc/docs/Materials.md +++ b/doc/docs/Materials.md @@ -174,12 +174,14 @@ Gyrotropic Media In a gyroelectric medium, the equation of motion of the polarization vector $\mathbf{P}_n$ is very similar to the [Drude-Lorentz](Materials.md#material-dispersion) case, but contains an additional precession term: -$$\frac{d^2\mathbf{P}_n}{dt^2} + \gamma_n \frac{d\mathbf{P}_n}{dt} + \mathbf{b}_n \times \frac{d\mathbf{P}_n}{dt} + \omega_n^2 \mathbf{P}_n = \sigma_n(\mathbf{x}) \omega_n^2 \mathbf{E}$$ +$$\frac{d^2\mathbf{P}_n}{dt^2} + \gamma_n \frac{d\mathbf{P}_n}{dt} - \frac{d\mathbf{P}_n}{dt} \times \mathbf{b}_n + \omega_n^2 \mathbf{P}_n = \sigma_n(\mathbf{x}) \omega_n^2 \mathbf{E}$$ -(Optionally, the polarization may be of Drude form, in which case the $\omega_n^2 \mathbf{P}_n$ term on the left-hand side is omitted.) The third term on the left-hand side breaks time-reversal symmetry and describes the gyrotropy of the medium; it is parameterized by the bias vector $\mathbf{b}_n$, usually describing the effect of an applied static magnetic field. In the $\gamma_n = \omega_n = 0$ limit, the equation of motion reduces to a precession around $\mathbf{b}_n$, with angular frequency equal to $|\mathbf{b}_n|$: +(Optionally, the polarization may be of Drude form, in which case the $\omega_n^2 \mathbf{P}_n$ term on the left is omitted.) The third term on the left side is responsible for the gyrotropy of the medium. This term breaks time-reversal symmetry and typically describes the effect of a static external magnetic field on the motion of electrons within the material. The bias vector $\mathbf{b}_n$ characterizes the direction and magnitude of the external magnetic field. In the $\gamma_n = \omega_n = 0$ limit, the equation of motion reduces to a precession around $\mathbf{b}_n$: $$\frac{d\mathbf{P}_n}{dt} = \mathbf{P}_n \times \mathbf{b}_n$$ +Hence, the magnitude of the bias vector is the angular frequency of the gyrotropic precession. + In the frequency domain, a gyroelectric medium has skew-symmetric off-diagonal components in the ε tensor. Take the case $\mathbf{b} = b \hat{z}$. When all fields have harmonic time-dependence $\exp(-i\omega t)$, the polarization equation of motion reduces to $$\mathbf{P}_n = \begin{bmatrix}\chi_\perp & -i\eta & 0 \\ i\eta & \chi_\perp & 0 \\ 0 & 0 & \chi_\parallel \end{bmatrix} \mathbf{E}$$ diff --git a/doc/docs/Python_Tutorials/Gyrotropic_Media.md b/doc/docs/Python_Tutorials/Gyrotropic_Media.md index dcccb64b0..568eb163b 100644 --- a/doc/docs/Python_Tutorials/Gyrotropic_Media.md +++ b/doc/docs/Python_Tutorials/Gyrotropic_Media.md @@ -6,11 +6,11 @@ In this example, we will perform simulations with gyrotropic media. See [Materia ### Faraday Rotation -Consider a uniform gyrotroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. According to the [gyrotropic Lorentzian model implemented in Meep](../Materials.md#gyrotropic-media), the *x* and *y* components of the dielectric function are +Consider a uniform gyroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. In the frequency domain, the *x* and *y* components of the dielectric function are $$\epsilon = \begin{bmatrix}\epsilon_\perp & -i\eta \\ i\eta & \epsilon_\perp \end{bmatrix}$$ -where +In the [gyrotropic Lorentzian model](../Materials.md#gyrotropic-media), the tensor components are $$\epsilon_\perp = \epsilon_\infty + \frac{\omega_n^2 \Delta_n}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}),\;\;\; \eta = \frac{\omega_n^2 \omega b}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}), \;\;\;\Delta_n \equiv \omega_n^2 - \omega^2 - i\omega\gamma_n$$ @@ -20,7 +20,7 @@ A plane wave undergoing Faraday rotation can be described by the complex ansatz $$\begin{bmatrix}E_x \\ E_y\end{bmatrix} = E_0 \begin{bmatrix}\cos(\kappa_c z) \\ \sin(\kappa_c z)\end{bmatrix} e^{i(kz-\omega t)}$$ -where $\kappa_c$ is the Faraday rotation, in radians, per unit of propagation distance. Substituting this into Maxwell's equations, with the above gyroelectric dielectric function, yields +where $\kappa_c$ is the Faraday rotation (in radians) per unit of propagation distance. Substituting this into the frequency domain Maxwell's equations, with the above dielectric tensor, yields $$|\kappa_c| = \omega \sqrt{\frac{\mu}{2} \, \left(\epsilon_\perp - \sqrt{\epsilon_\perp^2 - \eta^2}\right)}$$ @@ -30,10 +30,10 @@ We model this phenomenon in the simulation script [faraday-rotation.py](https:// ## Define a gyroelectric medium f0 = 1.0 -gamma = 1e-4 -epsn = 2.0 -b0 = 1.05 -sigma = 0.2 +gamma = 1e-6 +epsn = 1.5 +b0 = 0.15 +sn = 0.1 susc = [mp.GyrotropicLorentzianSusceptibility(frequency=f0, gamma=gamma, sigma=sigma, bias=mp.Vector3(0, 0, b0))] @@ -84,28 +84,28 @@ plt.show() We see that the wave indeed rotates in the *x*-*y* plane as it travels. This can be compared quantitatively to the above ansatz for a wave undergoing Faraday rotation, using the material parameters to calculate the rotation rate $\kappa_c$: -```dfsq = (f0*2 - 1j*f0*gamma - fsrc**2) -eperp = epsn + sigma * f0**2 * dfsq / (dfsq**2 + (fsrc*b0)**2) -eta = sigma * f0**2 * fsrc * b0 / (dfsq**2 + (fsrc*b0)**2) +```dfsq = (f0**2 - 1j*fsrc*gamma - fsrc**2) +eperp = epsn + sn * f0**2 * dfsq / (dfsq**2 - (fsrc*b0)**2) +eta = sn * f0**2 * fsrc * b0 / (dfsq**2 - (fsrc*b0)**2) k_gyro = 2*np.pi*fsrc * np.sqrt(0.5*(eperp - np.sqrt(eperp**2 - eta**2))) -Ex_theory = 0.37 * np.cos(k_gyro * (z - src_z)) # amplitude estimated by eye -Ey_theory = 0.37 * np.sin(k_gyro * (z - src_z)) +Ex_theory = 0.37 * np.cos(k_gyro * (z - src_z)).real +Ey_theory = 0.37 * np.sin(k_gyro * (z - src_z)).real plt.figure(2) plt.subplot(2,1,1) plt.plot(z, ex_data, label='Ex (MEEP)') plt.plot(z, Ex_theory, 'k--') -plt.plot(z, -Ex_theory, 'k--', label='Ex (theory)') +plt.plot(z, -Ex_theory, 'k--', label='Ex envelope (theory)') plt.xlim(-L/2, L/2); plt.xlabel('z') -plt.legend() +plt.legend(loc='lower right') plt.subplot(2,1,2) plt.plot(z, ey_data, label='Ey (MEEP)') plt.plot(z, Ey_theory, 'k--') -plt.plot(z, -Ey_theory, 'k--', label='Ey (theory)') +plt.plot(z, -Ey_theory, 'k--', label='Ey envelope (theory)') plt.xlim(-L/2, L/2); plt.xlabel('z') -plt.legend() +plt.legend(loc='lower right') plt.tight_layout() plt.show() ``` diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index 11f3b3f28..f36b4dafe 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -394,7 +394,7 @@ This is a somewhat unusual polarizable medium, a Lorentzian susceptibility with ### GyrotropicLorentzianSusceptibility or GyrotropicDrudeSusceptibility -(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility of Lorentzian (damped harmonic oscillator) or Drude form. See [Material Dispersion](Materials.md#gyrotropic-media). The parameters `sigma`, `frequency`, and `gamma` have the usual meanings, and there is an additional 3-vector `bias`: +(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility of Lorentzian (damped harmonic oscillator) or Drude form. See [Material Dispersion](Materials.md#gyrotropic-media). Its parameters are `sigma`, `frequency`, and `gamma`, which have the usual meanings, and an additional 3-vector `bias`: **`bias` [`Vector3`]** — diff --git a/doc/docs/images/Faraday-rotation-comparison.png b/doc/docs/images/Faraday-rotation-comparison.png index eb8e33972b828d7a9061de356630b01d78de93f9..9cf49a63fab4128aa310d3bb0452fd5968a4519f 100644 GIT binary patch literal 100658 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 DLy)?6 literal 97734 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 diff --git a/doc/docs/images/Faraday-rotation.png b/doc/docs/images/Faraday-rotation.png index 2f12bc384abb5b14e4ebdb265eb74a94503cf0eb..cfc9b210ccf42dad0679e7a24a593b9f3f79eaf3 100644 GIT binary patch literal 76081 zcmeGD^;erw*9Hg&FHZ4d#i6(rcZyrF;_k&Af>WTl7PsOKCAb7B5~P#@#UXehxCARU z>GQnr_syF5Vg7&_7OdR4leIW!-}`L2u4~7>*HFa8qQC+G0JzFZ@3a8`WH11LLshJ`vUP3^ui_v@gCD%$4>-~>@9ELt>b3r?Puv} z3vjXYc6WC3c6PL)^|kf%a&&X$=i=q!;h=T!_I4NL=KlYG&gJH5&)s_bnG67+1t`Ch z(e=+i0tbAd)(__FIs7R%wWeKbtDGrLNy+m986Af%%&IYk9NLbIxeh{E#P?@L-M*3R zp9;4Zqx%CMdUpq+m!gt9!oW0(kX8ax(SvzQ+S|zh_ghz2R|S8- zbpQF*xA~@)mdJYJ_FSq+3ro{fs6^oP2KVy?H!m-5csy6vi*CQu5!)=&KleRF&kuY4 zD=X0GcN~gCGP(?Yh**Xb4G!IkXAZaffuh2T~@YU!Sfgn|AvyxvsZ5kaaCWfBeAF)f?X5uR6Y-p4L*+&=8f}8zwU!vX{CyJX&eTuh#w6UTxM`YSx(d%+1Mp zC#k5XCy+NOy<#4(#GI~FuDv5c{~yZ|u+O8xb{$wgbTx>jaq8)vhvNqU+E+cXe~O*< z^sn?Cx2?EOaJHj{1Xb&PKi`HlX;3jYuo7dDQ&P$?r;Dt0%l>CCmWfuT{{J?D6@}b; zRqwV5J`HXRxMz{NQx?Bow7!LDhJFlu`2HOk9Rnj(jd^lKK>bt0Az~@F)5#%`>woLl z56B_Pu(d9q+R{b^J-wdWt$4(LS^Q=>*rhA#W2#s>-4BNgAokq3SEwqp{GUkk4iErb zYvTF>Rb&2CAm+FAbbs2O3cWw=d#!I4U<=v4|NHlBCtY*db*0%JpT>U!>0wstk;wOG zaZ^}BFi&1E54S~g(vGOB!Fn(ncXaQP-T$o<_FWJS%$q_nnMS^JTAC|MY_0p(>2LeLl@7L5%j^Lq-ySX8dw zTdS2zA=lLy6Rri1K;1gUsCMeIlmAA_7|O$Fc<=M$Ddgyg!xen>K}}6+;4Z(<-&C5o#KD!=X1%#a_0fZ$@vR|A z)Q2I;MNsU2LE3+FgS_t_2r@Y+Q`30xNW_(l3`u&YUkU}y7Uf*WG$w`SYT>45b5Kd#6= z9AByO=c=feC-J5)WW{ln^7}`$H{eJThP+9u*$VZxzJUQ5@!O40qc(ht?QTVPiz{w@ z)C>#^+1c5`iGgagJwJ*MrGxLhPtn59K#>(Ne~~Ni9eV)MTJ@maWV6rCY_Mm>?={G&&@9Xv zb&|&0hu})vBYW3J7h=AFKCJcUr<>{7S?lg&{-Qe^$(zop&8g>ysq^jE&*ZP~MitNC zvzpsAwGAL!2BH_Wc&bGGt8^Ck##>7v!8tF@0RFdb;eJ6hF%0AH7s3an&=k1Q;}|a5 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� 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 AO#lD@ diff --git a/python/examples/faraday-rotation.py b/python/examples/faraday-rotation.py index 28a74f75c..16e17b697 100644 --- a/python/examples/faraday-rotation.py +++ b/python/examples/faraday-rotation.py @@ -24,7 +24,7 @@ sim = mp.Simulation(cell_size=cell, geometry=[], sources=sources, k_point=mp.Vector3(), # Periodic boundary conditions boundary_layers=pml_layers, - default_material=mat, resolution=100) + default_material=mat, resolution=50) sim.run(until=tmax) ## Plot results: @@ -43,8 +43,8 @@ ## Comparison with analytic result: dfsq = (f0**2 - 1j*fsrc*gamma - fsrc**2) -eperp = epsn + sn * f0**2 * dfsq / (dfsq**2 + (fsrc*b0)**2) -eta = sn * f0**2 * fsrc * b0 / (dfsq**2 + (fsrc*b0)**2) +eperp = epsn + sn * f0**2 * dfsq / (dfsq**2 - (fsrc*b0)**2) +eta = sn * f0**2 * fsrc * b0 / (dfsq**2 - (fsrc*b0)**2) k_gyro = 2*np.pi*fsrc * np.sqrt(0.5*(eperp - np.sqrt(eperp**2 - eta**2))) Ex_theory = 0.37 * np.cos(k_gyro * (z - src_z)).real @@ -54,15 +54,15 @@ plt.subplot(2,1,1) plt.plot(z, ex_data, label='Ex (MEEP)') plt.plot(z, Ex_theory, 'k--') -plt.plot(z, -Ex_theory, 'k--', label='Ex (theory)') +plt.plot(z, -Ex_theory, 'k--', label='Ex envelope (theory)') plt.xlim(-L/2, L/2); plt.xlabel('z') -plt.legend() +plt.legend(loc='lower right') plt.subplot(2,1,2) plt.plot(z, ey_data, label='Ey (MEEP)') plt.plot(z, Ey_theory, 'k--') -plt.plot(z, -Ey_theory, 'k--', label='Ey (theory)') +plt.plot(z, -Ey_theory, 'k--', label='Ey envelope (theory)') plt.xlim(-L/2, L/2); plt.xlabel('z') -plt.legend() +plt.legend(loc='lower right') plt.tight_layout() plt.show() From a39cea1bde1b152cef30d55807715a47c5e907af Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 5 Jun 2019 16:14:18 +0800 Subject: [PATCH 51/61] For Landau-Lifshitz-Gilbert model, ignore the magnitude of the bias vector. --- src/susceptibility.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 1528c57ee..7d3256be9 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -327,10 +327,13 @@ gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double ome double alpha, gyrotropy_model model) : omega_0(omega_0), gamma(gamma), alpha(alpha), model(model) { // Precalculate g_{ij} = sum_k epsilon_{ijk} b_k, used in update_P. + + // Ignore |b| for Landau-Lifshitz-Gilbert gyrotropy model: + const vec b = (model == GYROTROPIC_SATURATED) ? bias/abs(bias) : bias; memset(gyro_tensor, 0, 9 * sizeof(double)); - gyro_tensor[X][Y] = bias.z(); gyro_tensor[Y][X] = -bias.z(); - gyro_tensor[Y][Z] = bias.x(); gyro_tensor[Z][Y] = -bias.x(); - gyro_tensor[Z][X] = bias.y(); gyro_tensor[X][Z] = -bias.y(); + gyro_tensor[X][Y] = b.z(); gyro_tensor[Y][X] = -b.z(); + gyro_tensor[Y][Z] = b.x(); gyro_tensor[Z][Y] = -b.x(); + gyro_tensor[Z][X] = b.y(); gyro_tensor[X][Z] = -b.y(); } /* To implement gyrotropic susceptibilities, we track three @@ -479,14 +482,11 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], case GYROTROPIC_SATURATED: { - const double dwfac = -2*pi*omega2pidt, alppi = pi*alpha; - const double dt2pi = 2*pi*dt; - // Precalculate 3x3 matrix inverse, exploiting skew symmetry const double gd = 0.5; - const double gx = -pi * alpha * gyro_tensor[Y][Z]; - const double gy = -pi * alpha * gyro_tensor[Z][X]; - const double gz = -pi * alpha * gyro_tensor[X][Y]; + const double gx = -0.5 * alpha * gyro_tensor[Y][Z]; + const double gy = -0.5 * alpha * gyro_tensor[Z][X]; + const double gz = -0.5 * alpha * gyro_tensor[X][Y]; const double invdet = 1.0 / gd / (gd*gd + gx*gx + gy*gy + gz*gz); const double inv[3][3] = {{ invdet*(gd*gd+gx*gx), invdet*(gx*gy+gd*gz), invdet*(gx*gz-gd*gy) }, @@ -519,9 +519,9 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], abort("gyrotropic media do not support anisotropic sigma\n"); LOOP_OVER_VOL_OWNED(gv, c, i) { - q0 = dwfac*p0[i] + alppi*pp0[i] + dt2pi*s[i]*w0[i]; - q1 = dwfac*p1[i] + alppi*pp1[i] + (w1 ? dt2pi*s[i]*OFFDIAGW(w1,is1,is) : 0); - q2 = dwfac*p2[i] + alppi*pp2[i] + (w2 ? dt2pi*s[i]*OFFDIAGW(w2,is2,is) : 0); + q0 = -omega2pidt*p0[i] + 0.5*alpha*pp0[i] + dt*s[i]*w0[i]; + q1 = -omega2pidt*p1[i] + 0.5*alpha*pp1[i] + dt*s[i]*(w1 ? OFFDIAGW(w1,is1,is) : 0); + q2 = -omega2pidt*p2[i] + 0.5*alpha*pp2[i] + dt*s[i]*(w2 ? OFFDIAGW(w2,is2,is) : 0); r0 = 0.5*pp0[i] - g2pidt*p0[i] + gyro_tensor[d0][d1]*q1 + gyro_tensor[d0][d2]*q2; r1 = 0.5*pp1[i] - g2pidt*p1[i] + gyro_tensor[d1][d2]*q2 + gyro_tensor[d1][d0]*q0; From 01d9f98969e0e33d6e8de1d5573c7c664587dadd Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 5 Jun 2019 17:25:18 +0800 Subject: [PATCH 52/61] Fix minor hiccup in docs. --- doc/docs/Python_User_Interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index 8bb257980..a15e95e97 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -406,7 +406,7 @@ The gyrotropy vector. The direction of this vector determines the orientation o **`sigma` [`number`]** — -The coupling factor $\sigma_n / 2\pi$ between the polarization and the driving field. In magnetic ferrites, this is the Larmor precession frequency at the saturation field if `bias` is a unit vector. +The coupling factor $\sigma_n / 2\pi$ between the polarization and the driving field. In magnetic ferrites, this is the Larmor precession frequency at the saturation field. **`frequency` [`number`]** — From d2ab1740fb6ab5306bddbf42115ecf2b8043562e Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 6 Jun 2019 10:45:14 +0800 Subject: [PATCH 53/61] Support dumping and undumping of gyrotropic susceptibilities --- python/typemap_utils.cpp | 3 +++ src/meep.hpp | 2 +- src/meepgeom.cpp | 13 +++++++++---- src/structure_dump.cpp | 26 ++++++++++++++++++++++++++ src/susceptibility.cpp | 6 +++--- 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/python/typemap_utils.cpp b/python/typemap_utils.cpp index 04f472347..6e3d7029b 100644 --- a/python/typemap_utils.cpp +++ b/python/typemap_utils.cpp @@ -476,6 +476,9 @@ static PyObject *susceptibility_to_py_obj(susceptibility_struct *s) { PyObject *py_gyrotropic_class = PyObject_GetAttrString(geom_mod, "GyrotropicSaturatedSusceptibility"); res = PyObject_Call(py_gyrotropic_class, args, NULL); Py_DECREF(py_gyrotropic_class); + PyObject *py_alpha = PyFloat_FromDouble(s->alpha); + PyObject_SetAttrString(res, "alpha", py_alpha); + Py_DECREF(py_alpha); } else if (s->drude) { PyObject *py_gyrotropic_drude_class = PyObject_GetAttrString(geom_mod, "GyrotropicDrudeSusceptibility"); res = PyObject_Call(py_gyrotropic_drude_class, args, NULL); diff --git a/src/meep.hpp b/src/meep.hpp index c1fd244d5..e387006cb 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -298,7 +298,7 @@ class gyrotropic_susceptibility : public susceptibility { int n, void *P_internal_data) const; virtual void dump_params(h5file *h5f, size_t *start); - virtual int get_num_params() { return 7; } + virtual int get_num_params() { return 8; } virtual bool needs_W_notowned(component c, realnum *W[NUM_FIELD_COMPONENTS][2]) const { (void)c; (void)W; diff --git a/src/meepgeom.cpp b/src/meepgeom.cpp index efab7a6d3..a85a1250d 100644 --- a/src/meepgeom.cpp +++ b/src/meepgeom.cpp @@ -38,9 +38,11 @@ void check_offdiag(medium_struct *m) { bool susceptibility_equal(const susceptibility &s1, const susceptibility &s2) { return (vector3_equal(s1.sigma_diag, s2.sigma_diag) && - vector3_equal(s1.sigma_offdiag, s2.sigma_offdiag) && s1.frequency == s2.frequency && - s1.gamma == s2.gamma && s1.noise_amp == s2.noise_amp && s1.drude == s2.drude && - s1.is_file == s2.is_file); + vector3_equal(s1.sigma_offdiag, s2.sigma_offdiag) && + vector3_equal(s1.bias, s2.bias) && s1.frequency == s2.frequency && + s1.gamma == s2.gamma && s1.alpha == s2.alpha && + s1.noise_amp == s2.noise_amp && s1.drude == s2.drude && + s1.saturated_gyrotropy == s2.saturated_gyrotropy && s1.is_file == s2.is_file); } bool susceptibility_list_equal(const susceptibility_list &s1, const susceptibility_list &s2) { @@ -1178,10 +1180,12 @@ double geom_epsilon::conductivity(meep::component c, const meep::vec &r) { (must be updated manually, re-copying from ctl-io.cpp), if we add new susceptibility subclasses) */ static bool susceptibility_equiv(const susceptibility *o0, const susceptibility *o) { + if (!vector3_equal(o0->bias, o->bias)) return 0; if (o0->frequency != o->frequency) return 0; if (o0->gamma != o->gamma) return 0; if (o0->noise_amp != o->noise_amp) return 0; if (o0->drude != o->drude) return 0; + if (o0->saturated_gyrotropy != o->saturated_gyrotropy) return 0; if (o0->is_file != o->is_file) return 0; if (o0->transitions != o->transitions) return 0; @@ -1363,7 +1367,8 @@ void geom_epsilon::add_susceptibilities(meep::field_type ft, meep::structure *s) susceptibility *ss = &(p->user_s); if (ss->is_file) meep::abort("unknown susceptibility"); bool noisy = (ss->noise_amp != 0.0); - bool gyrotropic = (ss->bias.x != 0.0 || ss->bias.y != 0.0 || ss->bias.z != 0.0); + bool gyrotropic = (ss->saturated_gyrotropy || ss->bias.x != 0.0 + || ss->bias.y != 0.0 || ss->bias.z != 0.0); meep::susceptibility *sus; if (ss->transitions.size() != 0 || ss->initial_populations.size() != 0) { diff --git a/src/structure_dump.cpp b/src/structure_dump.cpp index b7cd91eff..7b9ca14e0 100644 --- a/src/structure_dump.cpp +++ b/src/structure_dump.cpp @@ -362,6 +362,32 @@ susceptibility *make_sus_list_from_params(h5file *file, int rank, size_t dims[3] res = sus; } if (sus->next) sus = sus->next; + } else if (num_params == 8) { + // This is a gyrotropic_susceptibility and the next 8 values in the dataset + // are id, bias.x, bias.y, bias.z, omega_0, gamma, alpha, and model. + size_t gyro_susc_dims[3] = {8, 0, 0}; + realnum gyro_susc_params[8]; + file->read_chunk(rank, &start, gyro_susc_dims, gyro_susc_params); + start += gyro_susc_dims[0]; + + int id = (int)gyro_susc_params[0]; + const vec bias(gyro_susc_params[1], gyro_susc_params[2], gyro_susc_params[3]); + const double omega_0 = gyro_susc_params[4]; + const double gamma = gyro_susc_params[5]; + const double alpha = gyro_susc_params[6]; + const gyrotropy_model model = (gyrotropy_model)gyro_susc_params[7]; + if (sus) { + sus->next = + new gyrotropic_susceptibility(bias, omega_0, gamma, alpha, model); + sus->next->ntot = ntot; + sus->next->set_id(id); + } else { + sus = new gyrotropic_susceptibility(bias, omega_0, gamma, alpha, model); + sus->ntot = ntot; + sus->set_id(id); + res = sus; + } + if (sus->next) sus = sus->next; } else { abort("Invalid number of susceptibility parameters in structure::load"); } diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 7d3256be9..9b7c2b2cb 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -572,12 +572,12 @@ realnum *gyrotropic_susceptibility::cinternal_notowned_ptr(int inotowned, compon } void gyrotropic_susceptibility::dump_params(h5file *h5f, size_t *start) { - size_t num_params = 8; + size_t num_params = 9; size_t params_dims[1] = {num_params}; double bias[] = { gyro_tensor[Y][Z], gyro_tensor[Z][X], gyro_tensor[X][Y] }; double params_data[] = { - 7, (double)get_id(), bias[X], bias[Y], bias[Z], - omega_0, gamma, (double)model}; + 8, (double)get_id(), bias[X], bias[Y], bias[Z], + omega_0, gamma, alpha, (double)model}; h5f->write_chunk(1, start, params_dims, params_data); *start += num_params; } From 329ab8952daf042fc882fc8d0b1b699700f50e14 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 6 Jun 2019 11:22:42 +0800 Subject: [PATCH 54/61] Doc updates and minor tweaks accompanying last merge --- doc/docs/Python_User_Interface.md | 2 +- doc/docs/Scheme_User_Interface.md | 18 +++++++++++++----- src/susceptibility.cpp | 3 +-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index a15e95e97..4611437ff 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -422,7 +422,7 @@ The loss factor $\alpha_n$ in the diagonal response. Note that this parameter is **`bias` [`Vector3`]** — -Vector specifying the orientation of the gyrotropic response. The magnitude is ignored (unlike the `GyrotropicLorentzianSusceptibility` or `GyrotropicDrudeSusceptibility` case); the relevant precession frequencies are determined by `sigma` and `frequency`, described above. +Vector specifying the orientation of the gyrotropic response. Unlike the similarly-named `bias` parameter `GyrotropicLorentzianSusceptibility` or `GyrotropicDrudeSusceptibility`, the magnitude is ignored; the relevant precession frequencies are instead determined by `sigma` and `frequency`, described above. ### Vector3 diff --git a/doc/docs/Scheme_User_Interface.md b/doc/docs/Scheme_User_Interface.md index 1117430af..c03a86483 100644 --- a/doc/docs/Scheme_User_Interface.md +++ b/doc/docs/Scheme_User_Interface.md @@ -339,9 +339,17 @@ Specifies a single dispersive susceptibility of Lorentzian (damped harmonic osci — The noise has root-mean square amplitude σ $\times$ `noise-amp`. -### gyrotropic-susceptibility +### gyrotropic-lorentzian-susceptibility or gyrotropic-drude-susceptibility -(**Experimental feature**) Specifies a single dispersive [gyrotropic susceptibility](Materials.md#gyrotropic-media) governed by the Landau-Lifshitz-Gilbert equation. Note that the parameters `sigma`, `frequency`, and `gamma` play different roles compared to the Lorentzian or Drude case. +(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility of Lorentzian (damped harmonic oscillator) or Drude form. See [Material Dispersion](Materials.md#gyrotropic-media). Its parameters are `sigma`, `frequency`, and `gamma`, which have the usual meanings, and an additional 3-vector `bias`: + +**`bias` [`vector3`]** +— +The gyrotropy vector. The direction of this vector determines the orientation of the gyrotropic response, and the magnitude equals the precession frequency $|\mathbf{b}_n|/2\pi$. + +### gyrotropic-saturated-susceptibility + +(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility governed by a linearized Landau-Lifshitz-Gilbert equation. See [Material Dispersion](Materials.md#gyrotropic-media). This class takes parameters `sigma`, `frequency`, and `gamma`, whose meanings are different from the Lorentzian and Drude case. It also takes a 3-vector `bias` parameter and an `alpha` parameter: **`sigma` [`number`]** — @@ -349,7 +357,7 @@ The coupling factor $\sigma_n / 2\pi$ between the polarization and the driving f **`frequency` [`number`]** — -The frequency of gyrotropic precession, $f_n = \omega_n / 2\pi$. In magnetic ferrites, this is the Larmor precession frequency. +The Larmor precession frequency, $f_n = \omega_n / 2\pi$. **`gamma` [`number`]** — @@ -357,11 +365,11 @@ The loss rate $\gamma_n / 2\pi$ in the off-diagonal response. **`alpha` [`number`]** — -The loss factor $\alpha_n$ in the diagonal response (note that there is no 2π factor). +The loss factor $\alpha_n$ in the diagonal response. Note that this parameter is dimensionless and contains no 2π factor. **`bias` [`vector3`]** — -Gyrotropy vector describing the direction of the static biasing magnetic field. The magnitude is ignored. +Vector specifying the orientation of the gyrotropic response. Unlike the similarly-named `bias` parameter in `gyrotropic-lorentzian-susceptibility` or `gyrotropic-drude-susceptibility`, the magnitude is ignored; the relevant precession frequencies are instead determined by `sigma` and `frequency`, described above. ### geometric-object diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 9b7c2b2cb..60663ccff 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -327,8 +327,7 @@ gyrotropic_susceptibility::gyrotropic_susceptibility(const vec &bias, double ome double alpha, gyrotropy_model model) : omega_0(omega_0), gamma(gamma), alpha(alpha), model(model) { // Precalculate g_{ij} = sum_k epsilon_{ijk} b_k, used in update_P. - - // Ignore |b| for Landau-Lifshitz-Gilbert gyrotropy model: + // Ignore |b| for Landau-Lifshitz-Gilbert gyrotropy model. const vec b = (model == GYROTROPIC_SATURATED) ? bias/abs(bias) : bias; memset(gyro_tensor, 0, 9 * sizeof(double)); gyro_tensor[X][Y] = b.z(); gyro_tensor[Y][X] = -b.z(); From 256aa892d2e9a2078aa54612c9f87faa732ceb0e Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 12 Jun 2019 10:03:18 +0800 Subject: [PATCH 55/61] Translate Faraday rotation tutorial from Python to Scheme --- doc/docs/Python_Tutorials/Gyrotropic_Media.md | 46 ++++------ doc/docs/Scheme_Tutorials/Gyrotropic_Media.md | 88 +++++++++++++++++++ python/examples/faraday-rotation.py | 14 +-- scheme/examples/faraday-rotation.ctl | 40 +++++++++ 4 files changed, 151 insertions(+), 37 deletions(-) create mode 100644 doc/docs/Scheme_Tutorials/Gyrotropic_Media.md create mode 100644 scheme/examples/faraday-rotation.ctl diff --git a/doc/docs/Python_Tutorials/Gyrotropic_Media.md b/doc/docs/Python_Tutorials/Gyrotropic_Media.md index a9835f6df..c63313a65 100644 --- a/doc/docs/Python_Tutorials/Gyrotropic_Media.md +++ b/doc/docs/Python_Tutorials/Gyrotropic_Media.md @@ -8,14 +8,10 @@ In this example, we will perform simulations with gyrotropic media. See [Materia ### Faraday Rotation -Consider a uniform gyroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. In the frequency domain, the *x* and *y* components of the dielectric function are +Consider a uniform gyroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. In the frequency domain, the *x* and *y* components of the dielectric function have the form $$\epsilon = \begin{bmatrix}\epsilon_\perp & -i\eta \\ i\eta & \epsilon_\perp \end{bmatrix}$$ -In the [gyrotropic Lorentzian model](../Materials.md#gyrotropic-media), the tensor components are - -$$\epsilon_\perp = \epsilon_\infty + \frac{\omega_n^2 \Delta_n}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}),\;\;\; \eta = \frac{\omega_n^2 \omega b}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}), \;\;\;\Delta_n \equiv \omega_n^2 - \omega^2 - i\omega\gamma_n$$ - The skew-symmetric off-diagonal components in ε give rise to [Faraday rotation](https://en.wikipedia.org/wiki/Faraday_effect): when a plane wave linearly polarized along *x* is launched along the gyrotropy axis *z*, the polarization vector will precess around the gyrotropy axis as the wave propagates. This is the principle behind [Faraday rotators](https://en.wikipedia.org/wiki/Faraday_rotator), devices that act as one-way valves for light. A plane wave undergoing Faraday rotation can be described by the complex ansatz @@ -30,12 +26,12 @@ We model this phenomenon in the simulation script [faraday-rotation.py](https:// ```import meep as mp -## Define a gyroelectric medium -f0 = 1.0 -gamma = 1e-6 -epsn = 1.5 -b0 = 0.15 -sn = 0.1 +## Parameters for a gyrotropic Lorentzian medium +epsn = 1.5 # background permittivity +f0 = 1.0 # natural frequency +gamm = 1e-6 # damping rate +sn = 0.1 # sigma parameter +b0 = 0.15 # magnitude of bias vector susc = [mp.GyrotropicLorentzianSusceptibility(frequency=f0, gamma=gamma, sigma=sigma, bias=mp.Vector3(0, 0, b0))] @@ -84,7 +80,13 @@ plt.show() ![](../images/Faraday-rotation.png)

-We see that the wave indeed rotates in the *x*-*y* plane as it travels. This can be compared quantitatively to the above ansatz for a wave undergoing Faraday rotation, using the material parameters to calculate the rotation rate $\kappa_c$: +We see that the wave indeed rotates in the *x*-*y* plane as it travels. + +Moreover, we can compare the Faraday rotation rate in these simulation results to theoretical predictions. In the [gyrotropic Lorentzian model](../Materials.md#gyrotropic-media), the ε tensor components are given by + +$$\epsilon_\perp = \epsilon_\infty + \frac{\omega_n^2 \Delta_n}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}),\;\;\; \eta = \frac{\omega_n^2 \omega b}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}), \;\;\;\Delta_n \equiv \omega_n^2 - \omega^2 - i\omega\gamma_n$$ + +From these expressions, we can calculate the rotation rate $\kappa_c$ at the operating frequency, and hence find the $\mathbf{E}_x$ and $\mathbf{E}_y$ field envelopes for the complex ansatz given at the top of this section. ```dfsq = (f0**2 - 1j*fsrc*gamma - fsrc**2) eperp = epsn + sn * f0**2 * dfsq / (dfsq**2 - (fsrc*b0)**2) @@ -112,26 +114,8 @@ plt.tight_layout() plt.show() ``` -The results are in excellent agreement: +As shown in the figure below, the results are in excellent agreement:
![](../images/Faraday-rotation-comparison.png)
- -## Microwave ferrites - -Ferrites are ceramic materials exhibiting strong gyromagnetic resonances, commonly used in microwave engineering to construct isolators (one-way valves) and circulators. In the presence of a biasing magnetic field $\mathbf{H} = H_0 \hat{\mathbf{z}}$, the permeability tensor of a ferrite material has the form - -$$\mu = \begin{bmatrix} \mu_\perp & -i \kappa & 0 \\ i\kappa & \mu_\perp & 0 \\ 0 & 0 & 1\end{bmatrix}$$ - -where - -$$\mu_\perp = 1 + \frac{\omega_m (\omega_0 - i\omega\alpha)}{(\omega_0 - i \omega \alpha)^2 - (\omega + i \gamma)^2}, \;\;\; \kappa = \frac{\omega_m (\omega + i\gamma)}{(\omega_0 - i \omega \alpha)^2 - (\omega + i \gamma)^2}$$ - -This permeability can be derived from the [Landau-Lifshitz-Gilbert equation](https://en.wikipedia.org/wiki/Landau%E2%80%93Lifshitz%E2%80%93Gilbert_equation) describing a magnetic dipole in a magnetic field. The Larmor precession frequency is $\omega_0 = \gamma H_0$ where $\gamma$ is the gyromagnetic ratio of the electron. The Larmor precession frequency at saturation field is $\omega_m = \gamma M_s$ where $M_s$ is the saturation magnetization. This precisely matches the permeability tensor derived from [Meep's gyrotropy model](../Materials.md#gyrotropic-media), with the identification $\omega_0 \leftrightarrow \omega_n$ and $\omega_m \leftrightarrow \sigma_n$. - -We will take $\omega_0/2\pi = 1$, $\omega_m/2\pi = 1.2$, $\alpha = \gamma/2\pi = 10^{-3}$, and $\epsilon = 15$. The diagonal and off-diagonal components of the permeability tensor are plotted below: - -
-![](../images/Ferrite-mu.png) -
diff --git a/doc/docs/Scheme_Tutorials/Gyrotropic_Media.md b/doc/docs/Scheme_Tutorials/Gyrotropic_Media.md new file mode 100644 index 000000000..235db22d7 --- /dev/null +++ b/doc/docs/Scheme_Tutorials/Gyrotropic_Media.md @@ -0,0 +1,88 @@ +--- +# Gyrotropic media +--- + +In this example, we will perform simulations with gyrotropic media. See [Materials](../Materials.md#gyrotropic-media) for more information on how gyrotropy is supported. + +[TOC] + +### Faraday Rotation + +Consider a uniform gyroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. In the frequency domain, the *x* and *y* components of the dielectric function have the form + +$$\epsilon = \begin{bmatrix}\epsilon_\perp & -i\eta \\ i\eta & \epsilon_\perp \end{bmatrix}$$ + +The skew-symmetric off-diagonal components in ε give rise to [Faraday rotation](https://en.wikipedia.org/wiki/Faraday_effect): when a plane wave linearly polarized along *x* is launched along the gyrotropy axis *z*, the polarization vector will precess around the gyrotropy axis as the wave propagates. This is the principle behind [Faraday rotators](https://en.wikipedia.org/wiki/Faraday_rotator), devices that act as one-way valves for light. + +A plane wave undergoing Faraday rotation can be described by the complex ansatz + +$$\begin{bmatrix}E_x \\ E_y\end{bmatrix} = E_0 \begin{bmatrix}\cos(\kappa_c z) \\ \sin(\kappa_c z)\end{bmatrix} e^{i(kz-\omega t)}$$ + +where $\kappa_c$ is the Faraday rotation (in radians) per unit of propagation distance. Substituting this into the frequency domain Maxwell's equations, with the above dielectric tensor, yields + +$$|\kappa_c| = \omega \sqrt{\frac{\mu}{2} \, \left(\epsilon_\perp - \sqrt{\epsilon_\perp^2 - \eta^2}\right)}$$ + +We model this phenomenon in the simulation script [faraday-rotation.ctl](https://github.com/NanoComp/meep/blob/master/scheme/examples/faraday-rotation.ctl). First, we define a gyroelectric material: + +```(define-param epsn 1.5) ; background permittivity +(define-param f0 1.0) ; natural frequency +(define-param g0 1e-6) ; damping rate +(define-param sn 0.1) ; sigma parameter +(define-param b0 0.15) ; magnitude of bias vector + +(set! default-material + (make dielectric + (epsilon epsn) + (E-susceptibilities + (make gyrotropic-lorentzian-susceptibility + (frequency f0) + (sigma sn) + (gamma g0) + (bias (vector3 0 0 b0)))))) +``` + +The `gyrotropic-lorentzian-susceptibility` object has a `bias` argument that takes a `vector3` specifying the gyrotropy vector. In this case, the vector points along *z*, and its magnitude (which specifies the precession frequency) is determined by the variable `b0`. The other arguments play the same role as in an ordinary (non-gyrotropic) [Lorentzian susceptibility](Material_Dispersion.md). + +Next, we set up and run the Meep simulation. + +```(define-param tmax 100) +(define-param L 20.0) +(define-param fsrc 0.8) +(define-param src-z -8.5) +(set-param! resolution 50) + +(set! geometry-lattice (make lattice (size 0 0 L))) + +(set! pml-layers (list (make pml (thickness 1.0) (direction Z)))) + +(set! sources (list + (make source + (src (make continuous-src (frequency fsrc))) + (component Ex) + (center (vector3 0 0 src-z))))) + +(run-until tmax + (to-appended "efields" + (at-end output-efield-x) + (at-end output-efield-y))) +``` + +The simulation cell is one pixel wide in the *x* and *y* directions, with periodic boundary conditions. PMLs are placed in the *z* direction. A `ContinuousSource` emits a wave whose electric field is initially polarized along *x*. + +After running the simulation, the `ex` and `ey` datasets in `faraday-rotation-efields.h5` contain the values of $\mathbf{E}_x$ and $\mathbf{E}_y$. These are plotted against *z* in the figure below: + +
+![](../images/Faraday-rotation.png) +
+ +We see that the wave indeed rotates in the *x*-*y* plane as it travels. + +Moreover, we can compare the Faraday rotation rate in these simulation results to theoretical predictions. In the [gyrotropic Lorentzian model](../Materials.md#gyrotropic-media), the ε tensor components are given by + +$$\epsilon_\perp = \epsilon_\infty + \frac{\omega_n^2 \Delta_n}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}),\;\;\; \eta = \frac{\omega_n^2 \omega b}{\Delta_n^2 - \omega^2 b^2}\,\sigma_n(\mathbf{x}), \;\;\;\Delta_n \equiv \omega_n^2 - \omega^2 - i\omega\gamma_n$$ + +From these expressions, we can calculate the rotation rate $\kappa_c$ at the operating frequency, and hence find the $\mathbf{E}_x$ and $\mathbf{E}_y$ field envelopes for the complex ansatz given at the top of this section. As shown in the figure below, the results are in excellent agreement: + +
+![](../images/Faraday-rotation-comparison.png) +
diff --git a/python/examples/faraday-rotation.py b/python/examples/faraday-rotation.py index 16e17b697..9bba6a35e 100644 --- a/python/examples/faraday-rotation.py +++ b/python/examples/faraday-rotation.py @@ -1,11 +1,13 @@ +# From the Meep tutorial: plotting Faraday rotation of a linearly polarized plane wave + import meep as mp -## Define a gyroelectric medium -f0 = 1.0 -gamma = 1e-6 -epsn = 1.5 -b0 = 0.15 -sn = 0.1 +## Parameters for a gyrotropic Lorentzian medium +epsn = 1.5 # background permittivity +f0 = 1.0 # natural frequency +gamm = 1e-6 # damping rate +sn = 0.1 # sigma parameter +b0 = 0.15 # magnitude of bias vector susc = [mp.GyrotropicLorentzianSusceptibility(frequency=f0, gamma=gamma, sigma=sn, bias=mp.Vector3(0, 0, b0))] diff --git a/scheme/examples/faraday-rotation.ctl b/scheme/examples/faraday-rotation.ctl new file mode 100644 index 000000000..bd287eda3 --- /dev/null +++ b/scheme/examples/faraday-rotation.ctl @@ -0,0 +1,40 @@ +;; From the Meep tutorial: plotting Faraday rotation of a linearly polarized plane wave + +;; Parameters for a gyrotropic Lorentzian medium +(define-param epsn 1.5) ; background permittivity +(define-param f0 1.0) ; natural frequency +(define-param g0 1e-6) ; damping rate +(define-param sn 0.1) ; sigma parameter +(define-param b0 0.15) ; magnitude of bias vector + +(set! default-material + (make dielectric + (epsilon epsn) + (E-susceptibilities + (make gyrotropic-lorentzian-susceptibility + (frequency f0) + (sigma sn) + (gamma g0) + (bias (vector3 0 0 b0)))))) + +;; Set up and run the Meep simulation: +(define-param tmax 100) +(define-param L 20.0) +(define-param fsrc 0.8) +(define-param src-z -8.5) +(set-param! resolution 50) + +(set! geometry-lattice (make lattice (size 0 0 L))) + +(set! pml-layers (list (make pml (thickness 1.0) (direction Z)))) + +(set! sources (list + (make source + (src (make continuous-src (frequency fsrc))) + (component Ex) + (center (vector3 0 0 src-z))))) + +(run-until tmax + (to-appended "efields" + (at-end output-efield-x) + (at-end output-efield-y))) From 9b7c6b7385d160fd6a5cdba45f3dd206c0321d69 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 12 Jun 2019 10:08:42 +0800 Subject: [PATCH 56/61] Fix typo in last change --- python/examples/faraday-rotation.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/examples/faraday-rotation.py b/python/examples/faraday-rotation.py index 9bba6a35e..b09d1fcec 100644 --- a/python/examples/faraday-rotation.py +++ b/python/examples/faraday-rotation.py @@ -3,11 +3,11 @@ import meep as mp ## Parameters for a gyrotropic Lorentzian medium -epsn = 1.5 # background permittivity -f0 = 1.0 # natural frequency -gamm = 1e-6 # damping rate -sn = 0.1 # sigma parameter -b0 = 0.15 # magnitude of bias vector +epsn = 1.5 # background permittivity +f0 = 1.0 # natural frequency +gamma = 1e-6 # damping rate +sn = 0.1 # sigma parameter +b0 = 0.15 # magnitude of bias vector susc = [mp.GyrotropicLorentzianSusceptibility(frequency=f0, gamma=gamma, sigma=sn, bias=mp.Vector3(0, 0, b0))] From 0bc91b22e18fd2f038d4754c0b6debedccbb4843 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 12 Jun 2019 10:16:42 +0800 Subject: [PATCH 57/61] Fix missing 2pi factor in gyrotropic LLG susceptibility's sigma parameter --- src/susceptibility.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/susceptibility.cpp b/src/susceptibility.cpp index 60663ccff..f63332095 100644 --- a/src/susceptibility.cpp +++ b/src/susceptibility.cpp @@ -481,6 +481,8 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], case GYROTROPIC_SATURATED: { + const double dt2pi = 2*pi*dt; + // Precalculate 3x3 matrix inverse, exploiting skew symmetry const double gd = 0.5; const double gx = -0.5 * alpha * gyro_tensor[Y][Z]; @@ -518,9 +520,9 @@ void gyrotropic_susceptibility::update_P(realnum *W[NUM_FIELD_COMPONENTS][2], abort("gyrotropic media do not support anisotropic sigma\n"); LOOP_OVER_VOL_OWNED(gv, c, i) { - q0 = -omega2pidt*p0[i] + 0.5*alpha*pp0[i] + dt*s[i]*w0[i]; - q1 = -omega2pidt*p1[i] + 0.5*alpha*pp1[i] + dt*s[i]*(w1 ? OFFDIAGW(w1,is1,is) : 0); - q2 = -omega2pidt*p2[i] + 0.5*alpha*pp2[i] + dt*s[i]*(w2 ? OFFDIAGW(w2,is2,is) : 0); + q0 = -omega2pidt*p0[i] + 0.5*alpha*pp0[i] + dt2pi*s[i]*w0[i]; + q1 = -omega2pidt*p1[i] + 0.5*alpha*pp1[i] + dt2pi*s[i]*(w1 ? OFFDIAGW(w1,is1,is) : 0); + q2 = -omega2pidt*p2[i] + 0.5*alpha*pp2[i] + dt2pi*s[i]*(w2 ? OFFDIAGW(w2,is2,is) : 0); r0 = 0.5*pp0[i] - g2pidt*p0[i] + gyro_tensor[d0][d1]*q1 + gyro_tensor[d0][d2]*q2; r1 = 0.5*pp1[i] - g2pidt*p1[i] + gyro_tensor[d1][d2]*q2 + gyro_tensor[d1][d0]*q0; From 2ee30762dd47d835cfd94a42f5d7961f14f75be4 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 12 Jun 2019 13:57:24 +0800 Subject: [PATCH 58/61] Minor fixes for gyrotropy documentation --- doc/docs/Materials.md | 14 +++---- doc/docs/Python_Tutorials/Gyrotropic_Media.md | 20 +++++---- doc/docs/Python_User_Interface.md | 8 ++-- doc/docs/Scheme_Tutorials/Gyrotropic_Media.md | 42 ++++++++++--------- doc/docs/Scheme_User_Interface.md | 8 ++-- mkdocs.yml | 2 + 6 files changed, 51 insertions(+), 43 deletions(-) diff --git a/doc/docs/Materials.md b/doc/docs/Materials.md index 1a28f7a5d..5ea4a16d2 100644 --- a/doc/docs/Materials.md +++ b/doc/docs/Materials.md @@ -174,7 +174,7 @@ Gyrotropic Media In a gyrotropic medium, the polarization vector undergoes precession around a preferred direction. In the frequency domain, this corresponds to the presence of skew-symmetric off-diagonal components in the ε tensor (for a gyroelectric medium) or the μ tensor (for a gyromagnetic medium). Two different gyrotropy models are supported: -### Gyrotropic Drude-Lorentz model +### Gyrotropic Drude-Lorentz Model The first gyrotropy model is a [Drude-Lorentz](Materials.md#material-dispersion) model with an additional precession, which is intended to describe gyroelectric materials. The polarization equation is @@ -186,7 +186,7 @@ $$\frac{d\mathbf{P}_n}{dt} = \mathbf{P}_n \times \mathbf{b}_n$$ Hence, the magnitude of the bias vector is the angular frequency of the gyrotropic precession induced by the external field. -### Gyrotropic saturated dipole (linearized Landau-Lifshitz-Gilbert) model +### Gyrotropic Saturated Dipole (Linearized Landau-Lifshitz-Gilbert) Model The second gyrotropy model is a linearized [Landau-Lifshitz-Gilbert equation](https://en.wikipedia.org/wiki/Landau%E2%80%93Lifshitz%E2%80%93Gilbert_equation), suitable for modeling gyromagnetic materials such as ferrites. Its polarization equation of motion is @@ -194,21 +194,21 @@ $$\frac{d\mathbf{P}_n}{dt} = \mathbf{b}_n \times \left( - \sigma_n \mathbf{E} + Note: although the above equation is written in terms of electric susceptibilities, this model is typically used for magnetic susceptibilities. Meep places no restriction on the field type that either gyrotropy model can be applied to. As usual, electric and magnetic susceptibilities can be swapped by substituting ε with μ, **E** with **H**, etc. -The Landau-Lifshitz-Gilbert equation describes the precessional motion of a saturated point magnetic dipole in a magnetic field. In the above equation, the variable $P_n$ represents the linearized deviation of the polarization from its static equilibrium value (assumed to be much larger and aligned parallel to $\mathbf{b}_n$). Note that this equation of motion is completely different from the [Drude-Lorentz equation](Materials.md#material-dispersion), though the constants σ$_n$, ω$_n$, and γ$_n$ play analogous roles (σ$_n$ couples the polarization to the driving field, ω$_n$ is the angular frequency of precession, and γ$_n$ is a damping factor). +The Landau-Lifshitz-Gilbert equation describes the precessional motion of a saturated point magnetic dipole in a magnetic field. In the above equation, the variable $\mathbf{P}_n$ represents the linearized deviation of the polarization from its static equilibrium value (assumed to be much larger and aligned parallel to $\mathbf{b}_n$). Note that this equation of motion is completely different from the [Drude-Lorentz equation](Materials.md#material-dispersion), though the constants σ$_n$, ω$_n$, and γ$_n$ play analogous roles (σ$_n$ couples the polarization to the driving field, ω$_n$ is the angular frequency of precession, and γ$_n$ is a damping factor). In this model, $\mathbf{b}_n$ is taken to be a unit vector (i.e., its magnitude is ignored). -### Frequency domain susceptibility tensors +### Frequency Domain Susceptibility Tensors -Suppose $\mathbf{b} = b \hat{z}$, and let all fields have harmonic time-dependence $\exp(-i\omega t)$. Then +Suppose $\mathbf{b} = b \hat{z}$, and let all fields have harmonic time-dependence $\exp(-i\omega t)$. Then $\mathbf{P}_n$ is related to the applied field $\mathbf{E}$ by $$\mathbf{P}_n = \begin{bmatrix}\chi_\perp & -i\eta & 0 \\ i\eta & \chi_\perp & 0 \\ 0 & 0 & \chi_\parallel \end{bmatrix} \mathbf{E}$$ -For the gyrotropic Lorentzian model, +For the [gyrotropic Lorentzian model](Materials.md#gyrotropic-drude-lorentz-model), the components of the susceptibility tensor are $$\chi_\perp = \frac{\omega_n^2 \Delta_n \sigma_n}{\Delta_n^2 - \omega^2 b^2},\;\;\; \chi_\parallel = \frac{\omega_n^2 \sigma_n}{\Delta_n}, \;\;\; \eta = \frac{\omega_n^2 \omega b \sigma_n}{\Delta_n^2 - \omega^2 b^2}, \;\;\;\Delta_n \equiv \omega_n^2 - \omega^2 - i\omega\gamma_n$$ -And for the gyrotropic saturated dipole (linearized Landau-Lifshitz-Gilbert) model, +And for the [gyrotropic saturated dipole (linearized Landau-Lifshitz-Gilbert) model](Materials.md#gyrotropic-saturated-dipole-linearized-landau-lifshitz-gilbert-model), $$\chi_\perp = \frac{\sigma_n (\omega_n - i \omega \alpha_n)}{(\omega_n - i \omega \alpha_n)^2 - (\omega + i \gamma_n)^2}, \;\;\; \chi_\parallel = 0, \;\;\; \eta = \frac{\sigma_n (\omega + i \gamma)}{(\omega_n - i \omega \alpha_n)^2 - (\omega + i \gamma_n)^2}$$ diff --git a/doc/docs/Python_Tutorials/Gyrotropic_Media.md b/doc/docs/Python_Tutorials/Gyrotropic_Media.md index c63313a65..cb16d053d 100644 --- a/doc/docs/Python_Tutorials/Gyrotropic_Media.md +++ b/doc/docs/Python_Tutorials/Gyrotropic_Media.md @@ -1,5 +1,5 @@ --- -# Gyrotropic media +# Gyrotropic Media --- In this example, we will perform simulations with gyrotropic media. See [Materials](../Materials.md#gyrotropic-media) for more information on how gyrotropy is supported. @@ -8,11 +8,11 @@ In this example, we will perform simulations with gyrotropic media. See [Materia ### Faraday Rotation -Consider a uniform gyroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. In the frequency domain, the *x* and *y* components of the dielectric function have the form +Consider a uniform gyroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. In the frequency domain, the *x* and *y* components of the dielectric tensor have the form $$\epsilon = \begin{bmatrix}\epsilon_\perp & -i\eta \\ i\eta & \epsilon_\perp \end{bmatrix}$$ -The skew-symmetric off-diagonal components in ε give rise to [Faraday rotation](https://en.wikipedia.org/wiki/Faraday_effect): when a plane wave linearly polarized along *x* is launched along the gyrotropy axis *z*, the polarization vector will precess around the gyrotropy axis as the wave propagates. This is the principle behind [Faraday rotators](https://en.wikipedia.org/wiki/Faraday_rotator), devices that act as one-way valves for light. +The skew-symmetric off-diagonal components give rise to [Faraday rotation](https://en.wikipedia.org/wiki/Faraday_effect): when a plane wave linearly polarized along *x* is launched along the gyrotropy axis *z*, the polarization vector will precess around the gyrotropy axis as the wave propagates. This is the principle behind [Faraday rotators](https://en.wikipedia.org/wiki/Faraday_rotator), devices that act as one-way valves for light. A plane wave undergoing Faraday rotation can be described by the complex ansatz @@ -24,7 +24,8 @@ $$|\kappa_c| = \omega \sqrt{\frac{\mu}{2} \, \left(\epsilon_\perp - \sqrt{\epsil We model this phenomenon in the simulation script [faraday-rotation.py](https://github.com/NanoComp/meep/blob/master/python/examples/faraday-rotation.py). First, we define a gyroelectric material: -```import meep as mp +```python +import meep as mp ## Parameters for a gyrotropic Lorentzian medium epsn = 1.5 # background permittivity @@ -42,7 +43,8 @@ The `GyrotropicLorentzianSusceptibility` object has a `bias` argument that takes Next, we set up and run the Meep simulation. -```tmax = 100 +```python +tmax = 100 L = 20.0 cell = mp.Vector3(0, 0, L) fsrc, src_z = 0.8, -8.5 @@ -58,9 +60,10 @@ sim = mp.Simulation(cell_size=cell, geometry=[], sources=sources, sim.run(until=tmax) ``` -The simulation cell is one pixel wide in the *x* and *y* directions, with periodic boundary conditions. PMLs are placed in the *z* direction. A `ContinuousSource` emits a wave whose electric field is initially polarized along *x*. We then plot the *x* and *y* components of the electric field versus *z*: +The simulation cell is one pixel wide in the *x* and *y* directions, with periodic boundary conditions. [PMLs](../Perfectly_Matched_Layer.md) are placed in the *z* direction. A `ContinuousSource` emits a wave whose electric field is initially polarized along *x*. We then plot the *x* and *y* components of the electric field versus *z*: -```import numpy as np +```python +import numpy as np import matplotlib.pyplot as plt ex_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, L), component=mp.Ex) @@ -88,7 +91,8 @@ $$\epsilon_\perp = \epsilon_\infty + \frac{\omega_n^2 \Delta_n}{\Delta_n^2 - \om From these expressions, we can calculate the rotation rate $\kappa_c$ at the operating frequency, and hence find the $\mathbf{E}_x$ and $\mathbf{E}_y$ field envelopes for the complex ansatz given at the top of this section. -```dfsq = (f0**2 - 1j*fsrc*gamma - fsrc**2) +```python +dfsq = (f0**2 - 1j*fsrc*gamma - fsrc**2) eperp = epsn + sn * f0**2 * dfsq / (dfsq**2 - (fsrc*b0)**2) eta = sn * f0**2 * fsrc * b0 / (dfsq**2 - (fsrc*b0)**2) diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index 4611437ff..d8a7c86fe 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -394,15 +394,15 @@ This is a somewhat unusual polarizable medium, a Lorentzian susceptibility with ### GyrotropicLorentzianSusceptibility or GyrotropicDrudeSusceptibility -(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility of Lorentzian (damped harmonic oscillator) or Drude form. See [Material Dispersion](Materials.md#gyrotropic-media). Its parameters are `sigma`, `frequency`, and `gamma`, which have the usual meanings, and an additional 3-vector `bias`: +(**Experimental feature**) Specifies a single dispersive [gyrotropic susceptibility](Materials.md#gyrotropic-media) of [Lorentzian (damped harmonic oscillator) or Drude form](Materials.md#gyrotropic-drude-lorentz-model). Its parameters are `sigma`, `frequency`, and `gamma`, which have the [usual meanings](#susceptibility), and an additional 3-vector `bias`: **`bias` [`Vector3`]** — -The gyrotropy vector. The direction of this vector determines the orientation of the gyrotropic response, and the magnitude equals the precession frequency $|\mathbf{b}_n|/2\pi$. +The gyrotropy vector. Its direction determines the orientation of the gyrotropic response, and the magnitude is the precession frequency $|\mathbf{b}_n|/2\pi$. ### GyrotropicSaturatedSusceptibility -(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility governed by a linearized Landau-Lifshitz-Gilbert equation. See [Material Dispersion](Materials.md#gyrotropic-media). This class takes parameters `sigma`, `frequency`, and `gamma`, whose meanings are different from the Lorentzian and Drude case. It also takes a 3-vector `bias` parameter and an `alpha` parameter: +(**Experimental feature**) Specifies a single dispersive [gyrotropic susceptibility](Materials.md#gyrotropic-media) governed by a [linearized Landau-Lifshitz-Gilbert equation](Materials.md#gyrotropic-saturated-dipole-linearized-landau-lifshitz-gilbert-model). This class takes parameters `sigma`, `frequency`, and `gamma`, whose meanings are different from the Lorentzian and Drude case. It also takes a 3-vector `bias` parameter and an `alpha` parameter: **`sigma` [`number`]** — @@ -422,7 +422,7 @@ The loss factor $\alpha_n$ in the diagonal response. Note that this parameter is **`bias` [`Vector3`]** — -Vector specifying the orientation of the gyrotropic response. Unlike the similarly-named `bias` parameter `GyrotropicLorentzianSusceptibility` or `GyrotropicDrudeSusceptibility`, the magnitude is ignored; the relevant precession frequencies are instead determined by `sigma` and `frequency`, described above. +Vector specifying the orientation of the gyrotropic response. Unlike the similarly-named `bias` parameter for the [gyrotropic Lorentzian/Drude susceptibilities](#gyrotropiclorentziansusceptibility-or-gyrotropicdrudesusceptibility), the magnitude is ignored; instead, the relevant precession frequencies are determined by the `sigma` and `frequency` parameters. ### Vector3 diff --git a/doc/docs/Scheme_Tutorials/Gyrotropic_Media.md b/doc/docs/Scheme_Tutorials/Gyrotropic_Media.md index 235db22d7..0164be888 100644 --- a/doc/docs/Scheme_Tutorials/Gyrotropic_Media.md +++ b/doc/docs/Scheme_Tutorials/Gyrotropic_Media.md @@ -1,5 +1,5 @@ --- -# Gyrotropic media +# Gyrotropic Media --- In this example, we will perform simulations with gyrotropic media. See [Materials](../Materials.md#gyrotropic-media) for more information on how gyrotropy is supported. @@ -8,11 +8,11 @@ In this example, we will perform simulations with gyrotropic media. See [Materia ### Faraday Rotation -Consider a uniform gyroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. In the frequency domain, the *x* and *y* components of the dielectric function have the form +Consider a uniform gyroelectric medium with bias vector $\mathbf{b} = b \hat{z}$. In the frequency domain, the *x* and *y* components of the dielectric tensor have the form $$\epsilon = \begin{bmatrix}\epsilon_\perp & -i\eta \\ i\eta & \epsilon_\perp \end{bmatrix}$$ -The skew-symmetric off-diagonal components in ε give rise to [Faraday rotation](https://en.wikipedia.org/wiki/Faraday_effect): when a plane wave linearly polarized along *x* is launched along the gyrotropy axis *z*, the polarization vector will precess around the gyrotropy axis as the wave propagates. This is the principle behind [Faraday rotators](https://en.wikipedia.org/wiki/Faraday_rotator), devices that act as one-way valves for light. +The skew-symmetric off-diagonal components give rise to [Faraday rotation](https://en.wikipedia.org/wiki/Faraday_effect): when a plane wave linearly polarized along *x* is launched along the gyrotropy axis *z*, the polarization vector will precess around the gyrotropy axis as the wave propagates. This is the principle behind [Faraday rotators](https://en.wikipedia.org/wiki/Faraday_rotator), devices that act as one-way valves for light. A plane wave undergoing Faraday rotation can be described by the complex ansatz @@ -24,7 +24,8 @@ $$|\kappa_c| = \omega \sqrt{\frac{\mu}{2} \, \left(\epsilon_\perp - \sqrt{\epsil We model this phenomenon in the simulation script [faraday-rotation.ctl](https://github.com/NanoComp/meep/blob/master/scheme/examples/faraday-rotation.ctl). First, we define a gyroelectric material: -```(define-param epsn 1.5) ; background permittivity +```scm +(define-param epsn 1.5) ; background permittivity (define-param f0 1.0) ; natural frequency (define-param g0 1e-6) ; damping rate (define-param sn 0.1) ; sigma parameter @@ -32,20 +33,21 @@ We model this phenomenon in the simulation script [faraday-rotation.ctl](https:/ (set! default-material (make dielectric - (epsilon epsn) - (E-susceptibilities - (make gyrotropic-lorentzian-susceptibility - (frequency f0) - (sigma sn) - (gamma g0) - (bias (vector3 0 0 b0)))))) + (epsilon epsn) + (E-susceptibilities + (make gyrotropic-lorentzian-susceptibility + (frequency f0) + (sigma sn) + (gamma g0) + (bias (vector3 0 0 b0)))))) ``` The `gyrotropic-lorentzian-susceptibility` object has a `bias` argument that takes a `vector3` specifying the gyrotropy vector. In this case, the vector points along *z*, and its magnitude (which specifies the precession frequency) is determined by the variable `b0`. The other arguments play the same role as in an ordinary (non-gyrotropic) [Lorentzian susceptibility](Material_Dispersion.md). Next, we set up and run the Meep simulation. -```(define-param tmax 100) +```scm +(define-param tmax 100) (define-param L 20.0) (define-param fsrc 0.8) (define-param src-z -8.5) @@ -56,18 +58,18 @@ Next, we set up and run the Meep simulation. (set! pml-layers (list (make pml (thickness 1.0) (direction Z)))) (set! sources (list - (make source - (src (make continuous-src (frequency fsrc))) - (component Ex) - (center (vector3 0 0 src-z))))) + (make source + (src (make continuous-src (frequency fsrc))) + (component Ex) + (center (vector3 0 0 src-z))))) (run-until tmax - (to-appended "efields" - (at-end output-efield-x) - (at-end output-efield-y))) + (to-appended "efields" + (at-end output-efield-x) + (at-end output-efield-y))) ``` -The simulation cell is one pixel wide in the *x* and *y* directions, with periodic boundary conditions. PMLs are placed in the *z* direction. A `ContinuousSource` emits a wave whose electric field is initially polarized along *x*. +The simulation cell is one pixel wide in the *x* and *y* directions, with periodic boundary conditions. [PMLs](../Perfectly_Matched_Layer.md) are placed in the *z* direction. A `ContinuousSource` emits a wave whose electric field is initially polarized along *x*. After running the simulation, the `ex` and `ey` datasets in `faraday-rotation-efields.h5` contain the values of $\mathbf{E}_x$ and $\mathbf{E}_y$. These are plotted against *z* in the figure below: diff --git a/doc/docs/Scheme_User_Interface.md b/doc/docs/Scheme_User_Interface.md index c03a86483..871327c48 100644 --- a/doc/docs/Scheme_User_Interface.md +++ b/doc/docs/Scheme_User_Interface.md @@ -341,15 +341,15 @@ The noise has root-mean square amplitude σ $\times$ `noise-amp`. ### gyrotropic-lorentzian-susceptibility or gyrotropic-drude-susceptibility -(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility of Lorentzian (damped harmonic oscillator) or Drude form. See [Material Dispersion](Materials.md#gyrotropic-media). Its parameters are `sigma`, `frequency`, and `gamma`, which have the usual meanings, and an additional 3-vector `bias`: +(**Experimental feature**) Specifies a single dispersive [gyrotropic susceptibility](Materials.md#gyrotropic-media) of [Lorentzian (damped harmonic oscillator) or Drude form](Materials.md#gyrotropic-drude-lorentz-model). Its parameters are `sigma`, `frequency`, and `gamma`, which have the [usual meanings](#susceptibility), and an additional 3-vector `bias`: **`bias` [`vector3`]** — -The gyrotropy vector. The direction of this vector determines the orientation of the gyrotropic response, and the magnitude equals the precession frequency $|\mathbf{b}_n|/2\pi$. +The gyrotropy vector. Its direction determines the orientation of the gyrotropic response, and the magnitude is the precession frequency $|\mathbf{b}_n|/2\pi$. ### gyrotropic-saturated-susceptibility -(**Experimental feature**) Specifies a single dispersive gyrotropic susceptibility governed by a linearized Landau-Lifshitz-Gilbert equation. See [Material Dispersion](Materials.md#gyrotropic-media). This class takes parameters `sigma`, `frequency`, and `gamma`, whose meanings are different from the Lorentzian and Drude case. It also takes a 3-vector `bias` parameter and an `alpha` parameter: +(**Experimental feature**) Specifies a single dispersive [gyrotropic susceptibility](Materials.md#gyrotropic-media) governed by a [linearized Landau-Lifshitz-Gilbert equation](Materials.md#gyrotropic-saturated-dipole-linearized-landau-lifshitz-gilbert-model). This class takes parameters `sigma`, `frequency`, and `gamma`, whose meanings are different from the Lorentzian and Drude case. It also takes a 3-vector `bias` parameter and an `alpha` parameter: **`sigma` [`number`]** — @@ -369,7 +369,7 @@ The loss factor $\alpha_n$ in the diagonal response. Note that this parameter is **`bias` [`vector3`]** — -Vector specifying the orientation of the gyrotropic response. Unlike the similarly-named `bias` parameter in `gyrotropic-lorentzian-susceptibility` or `gyrotropic-drude-susceptibility`, the magnitude is ignored; the relevant precession frequencies are instead determined by `sigma` and `frequency`, described above. +Vector specifying the orientation of the gyrotropic response. Unlike the similarly-named `bias` parameter for the [gyrotropic Lorentzian/Drude susceptibilities](#gyrotropiclorentziansusceptibility-or-gyrotropicdrudesusceptibility), the magnitude is ignored; instead, the relevant precession frequencies are determined by the `sigma` and `frequency` parameters. ### geometric-object diff --git a/mkdocs.yml b/mkdocs.yml index b3bbe07dc..fc67d59c7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -56,6 +56,7 @@ pages: - 'Tutorial/Near-to-Far Field Spectra': 'Python_Tutorials/Near_to_Far_Field_Spectra.md' - 'Tutorial/Local Density of States': 'Python_Tutorials/Local_Density_of_States.md' - 'Tutorial/Optical Forces': 'Python_Tutorials/Optical_Forces.md' + - 'Tutorial/Gyrotropic Media': 'Python_Tutorials/Gyrotropic_Media.md' - 'Tutorial/Multilevel Atomic Susceptibility': 'Python_Tutorials/Multilevel_Atomic_Susceptibility.md' - 'Tutorial/Frequency-Domain Solver': 'Python_Tutorials/Frequency_Domain_Solver.md' - 'Tutorial/Eigenmode Source': 'Python_Tutorials/Eigenmode_Source.md' @@ -72,6 +73,7 @@ pages: - 'Tutorial/Near-to-Far Field Spectra': 'Scheme_Tutorials/Near_to_Far_Field_Spectra.md' - 'Tutorial/Local Density of States': 'Scheme_Tutorials/Local_Density_of_States.md' - 'Tutorial/Optical Forces': 'Scheme_Tutorials/Optical_Forces.md' + - 'Tutorial/Gyrotropic Media': 'Scheme_Tutorials/Gyrotropic_Media.md' - 'Tutorial/Multilevel Atomic Susceptibility': 'Scheme_Tutorials/Multilevel_Atomic_Susceptibility.md' - 'Tutorial/Frequency-Domain Solver': 'Scheme_Tutorials/Frequency_Domain_Solver.md' - 'Tutorial/Eigenmode Source': 'Scheme_Tutorials/Eigenmode_Source.md' From 356a5070bbc09bf5bfbe2f4819b51baf056e665d Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 13 Jun 2019 15:52:53 +0800 Subject: [PATCH 59/61] Add Faraday rotation unit test --- doc/docs/Python_Tutorials/Gyrotropic_Media.md | 5 +- python/examples/faraday-rotation.py | 5 +- python/tests/faraday_rotation.py | 94 +++++++++++++++++++ 3 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 python/tests/faraday_rotation.py diff --git a/doc/docs/Python_Tutorials/Gyrotropic_Media.md b/doc/docs/Python_Tutorials/Gyrotropic_Media.md index cb16d053d..a10250f05 100644 --- a/doc/docs/Python_Tutorials/Gyrotropic_Media.md +++ b/doc/docs/Python_Tutorials/Gyrotropic_Media.md @@ -54,7 +54,6 @@ sources = [mp.Source(mp.ContinuousSource(frequency=fsrc), component=mp.Ex, center=mp.Vector3(0, 0, src_z))] sim = mp.Simulation(cell_size=cell, geometry=[], sources=sources, - k_point=mp.Vector3(), # Periodic boundary conditions boundary_layers=pml_layers, default_material=mat, resolution=50) sim.run(until=tmax) @@ -66,8 +65,8 @@ The simulation cell is one pixel wide in the *x* and *y* directions, with period import numpy as np import matplotlib.pyplot as plt -ex_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, L), component=mp.Ex) -ey_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, L), component=mp.Ey) +ex_data = sim.get_efield_x().real +ey_data = sim.get_efield_y().real z = np.linspace(-L/2, L/2, len(ex_data)) plt.figure(1) diff --git a/python/examples/faraday-rotation.py b/python/examples/faraday-rotation.py index b09d1fcec..449c18b10 100644 --- a/python/examples/faraday-rotation.py +++ b/python/examples/faraday-rotation.py @@ -24,7 +24,6 @@ component=mp.Ex, center=mp.Vector3(0, 0, src_z))] sim = mp.Simulation(cell_size=cell, geometry=[], sources=sources, - k_point=mp.Vector3(), # Periodic boundary conditions boundary_layers=pml_layers, default_material=mat, resolution=50) sim.run(until=tmax) @@ -33,8 +32,8 @@ import numpy as np import matplotlib.pyplot as plt -ex_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, L), component=mp.Ex) -ey_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, 0, L), component=mp.Ey) +ex_data = sim.get_efield_x().real +ey_data = sim.get_efield_y().real z = np.linspace(-L/2, L/2, len(ex_data)) plt.figure(1) diff --git a/python/tests/faraday_rotation.py b/python/tests/faraday_rotation.py new file mode 100644 index 000000000..61ec9712e --- /dev/null +++ b/python/tests/faraday_rotation.py @@ -0,0 +1,94 @@ +from __future__ import division + +import unittest +import numpy as np +import meep as mp + +## Farady rotation rate for gyrotropic Lorentzian medium +def kgyro_lorentzian(freq, epsn, f0, gamma, sigma, b0): + dfsq = (f0**2 - 1j*freq*gamma - freq**2) + eperp = epsn + sigma * f0**2 * dfsq / (dfsq**2 - (freq*b0)**2) + eta = sigma * f0**2 * freq * b0 / (dfsq**2 - (freq*b0)**2) + return 2*np.pi*freq * np.sqrt(0.5*(eperp - np.sqrt(eperp**2 - eta**2))) + +## Farady rotation rate for gyrotropic Drude medium +def kgyro_drude(freq, epsn, f0, gamma, sigma, b0): + dfsq = - 1j*freq*gamma - freq**2 + eperp = epsn + sigma * f0**2 * dfsq / (dfsq**2 - (freq*b0)**2) + eta = sigma * f0**2 * freq * b0 / (dfsq**2 - (freq*b0)**2) + return 2*np.pi*freq * np.sqrt(0.5*(eperp - np.sqrt(eperp**2 - eta**2))) + +## Farady rotation rate for Landau-Lifshitz-Gilbert medium +def kgyro_llg(freq, epsn, f0, gamma, sigma, alpha): + df1 = f0 - 1j*freq*alpha + df2 = freq + 1j*gamma + eperp = epsn + sigma * df1/(df1**2 - df2**2) + eta = sigma * df2 / (df1**2 - df2**2) + return 2*np.pi*freq * np.sqrt(0.5*(eperp - np.sqrt(eperp**2 - eta**2))) + +class TestFaradayRotation(unittest.TestCase): + ## Simulate a linearly polarized plane wave traveling along the gyrotropy axis. + ## Extract Faraday rotation angle by comparing the Ex and Ey amplitudes, and + ## compare to the theoretical result predicted by rotation rate KPRED + ## up to relative tolerance RTOL. + def check_rotation(self, mat, L, fsrc, zsrc, resolution, tmax, zout, kpred, rtol): + cell = mp.Vector3(0, 0, L) + pml_layers = [mp.PML(thickness=1.0, direction=mp.Z)] + sources = [mp.Source(mp.ContinuousSource(frequency=fsrc), + component=mp.Ex, center=mp.Vector3(0, 0, zsrc))] + + self.sim = mp.Simulation(cell_size=cell, geometry=[], sources=sources, + boundary_layers=pml_layers, + default_material=mat, resolution=resolution) + + record_vol = mp.Volume(center=mp.Vector3(0, 0, zout)) + record_Ex, record_Ey, record_t = [], [], [] + + def record_ex_ey(sim): + record_Ex.append(sim.get_array(vol=record_vol, component=mp.Ex)) + record_Ey.append(sim.get_array(vol=record_vol, component=mp.Ey)) + record_t.append(sim.meep_time()) + + self.sim.run(mp.after_time(0.5*tmax, mp.at_every(1e-6, record_ex_ey)), until=tmax) + + ex_rel = np.amax(abs(np.fft.fft(record_Ex))) + ey_rel = np.amax(abs(np.fft.fft(record_Ey))) + result = np.arctan2(ey_rel, ex_rel) + + Ex_theory = np.abs(np.cos(kpred * (zout - zsrc)).real) + Ey_theory = np.abs(np.sin(kpred * (zout - zsrc)).real) + expected = np.arctan2(Ey_theory, Ex_theory) + + np.testing.assert_allclose(expected, result, rtol=rtol) + + def test_faraday_rotation(self): + L, zsrc, zout = 12.0, -4.5, 4.0 + freq, tmax = 0.8, 300.0 + resolution = 24 + + ## Test gyrotropic lorentzian (2% tolerance) + epsn, f0, gamma, sn, b0 = 1.5, 1.0, 1e-3, 0.1, 0.15 + susc = [mp.GyrotropicLorentzianSusceptibility(frequency=f0, gamma=gamma, sigma=sn, + bias=mp.Vector3(0, 0, b0))] + mat = mp.Medium(epsilon=epsn, mu=1, E_susceptibilities=susc) + k = kgyro_lorentzian(freq, epsn, f0, gamma, sn, b0) + self.check_rotation(mat, L, freq, zsrc, resolution, tmax, zout, k, 0.02) + + ## Test gyrotropic Drude medium (2% tolerance) + susc = [mp.GyrotropicDrudeSusceptibility(frequency=f0, gamma=gamma, sigma=sn, + bias=mp.Vector3(0, 0, b0))] + mat = mp.Medium(epsilon=epsn, mu=1, E_susceptibilities=susc) + k = kgyro_drude(freq, epsn, f0, gamma, sn, b0) + self.check_rotation(mat, L, freq, zsrc, resolution, tmax, zout, k, 0.02) + + ## Test Landau-Lifshitz-Gilbert medium (5% tolerance) + alpha = 1e-5 + susc = [mp.GyrotropicSaturatedSusceptibility(frequency=f0, gamma=gamma, sigma=sn, + alpha=alpha, + bias=mp.Vector3(0, 0, 1.0))] + mat = mp.Medium(epsilon=epsn, mu=1, E_susceptibilities=susc) + k = kgyro_llg(freq, epsn, f0, gamma, sn, alpha) + self.check_rotation(mat, L, freq, zsrc, resolution, tmax, zout, k, 0.05) + +if __name__ == '__main__': + unittest.main() From 5742b8937c15c8805bb0c1dfd4472d16f4cd562d Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 13 Jun 2019 21:02:52 +0800 Subject: [PATCH 60/61] Use absolute tolerance (in degrees) for Faraday rotation unit test --- python/tests/faraday_rotation.py | 33 +++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/python/tests/faraday_rotation.py b/python/tests/faraday_rotation.py index 61ec9712e..140868b5b 100644 --- a/python/tests/faraday_rotation.py +++ b/python/tests/faraday_rotation.py @@ -29,9 +29,9 @@ def kgyro_llg(freq, epsn, f0, gamma, sigma, alpha): class TestFaradayRotation(unittest.TestCase): ## Simulate a linearly polarized plane wave traveling along the gyrotropy axis. ## Extract Faraday rotation angle by comparing the Ex and Ey amplitudes, and - ## compare to the theoretical result predicted by rotation rate KPRED - ## up to relative tolerance RTOL. - def check_rotation(self, mat, L, fsrc, zsrc, resolution, tmax, zout, kpred, rtol): + ## compare to a theoretical result corresponding to rotation rate KPRED. + ## The default acceptable tolerance TOL is 1.5 degrees. + def check_rotation(self, mat, L, fsrc, zsrc, resolution, tmax, zout, kpred, tol=1.5): cell = mp.Vector3(0, 0, L) pml_layers = [mp.PML(thickness=1.0, direction=mp.Z)] sources = [mp.Source(mp.ContinuousSource(frequency=fsrc), @@ -53,42 +53,49 @@ def record_ex_ey(sim): ex_rel = np.amax(abs(np.fft.fft(record_Ex))) ey_rel = np.amax(abs(np.fft.fft(record_Ey))) - result = np.arctan2(ey_rel, ex_rel) + result = np.arctan2(ey_rel, ex_rel) * 180/np.pi Ex_theory = np.abs(np.cos(kpred * (zout - zsrc)).real) Ey_theory = np.abs(np.sin(kpred * (zout - zsrc)).real) - expected = np.arctan2(Ey_theory, Ex_theory) + expected = np.arctan2(Ey_theory, Ex_theory) * 180/np.pi - np.testing.assert_allclose(expected, result, rtol=rtol) + print("Rotation angle (in degrees): {}, expected {}\n".format(result, expected)) + np.testing.assert_allclose(expected, result, atol=tol) def test_faraday_rotation(self): L, zsrc, zout = 12.0, -4.5, 4.0 - freq, tmax = 0.8, 300.0 + freq, tmax = 0.8, 100.0 resolution = 24 - ## Test gyrotropic lorentzian (2% tolerance) + ## Test gyrotropic Lorentzian medium epsn, f0, gamma, sn, b0 = 1.5, 1.0, 1e-3, 0.1, 0.15 susc = [mp.GyrotropicLorentzianSusceptibility(frequency=f0, gamma=gamma, sigma=sn, bias=mp.Vector3(0, 0, b0))] mat = mp.Medium(epsilon=epsn, mu=1, E_susceptibilities=susc) k = kgyro_lorentzian(freq, epsn, f0, gamma, sn, b0) - self.check_rotation(mat, L, freq, zsrc, resolution, tmax, zout, k, 0.02) + print('=' * 24) + print("Testing Faraday rotation for gyrotropic Lorentzian model...") + self.check_rotation(mat, L, freq, zsrc, resolution, tmax, zout, k) - ## Test gyrotropic Drude medium (2% tolerance) + ## Test gyrotropic Drude medium susc = [mp.GyrotropicDrudeSusceptibility(frequency=f0, gamma=gamma, sigma=sn, bias=mp.Vector3(0, 0, b0))] mat = mp.Medium(epsilon=epsn, mu=1, E_susceptibilities=susc) k = kgyro_drude(freq, epsn, f0, gamma, sn, b0) - self.check_rotation(mat, L, freq, zsrc, resolution, tmax, zout, k, 0.02) + print('=' * 24) + print("Testing Faraday rotation for gyrotropic Drude model...") + self.check_rotation(mat, L, freq, zsrc, resolution, tmax, zout, k) - ## Test Landau-Lifshitz-Gilbert medium (5% tolerance) + ## Test Landau-Lifshitz-Gilbert medium alpha = 1e-5 susc = [mp.GyrotropicSaturatedSusceptibility(frequency=f0, gamma=gamma, sigma=sn, alpha=alpha, bias=mp.Vector3(0, 0, 1.0))] mat = mp.Medium(epsilon=epsn, mu=1, E_susceptibilities=susc) k = kgyro_llg(freq, epsn, f0, gamma, sn, alpha) - self.check_rotation(mat, L, freq, zsrc, resolution, tmax, zout, k, 0.05) + print('=' * 24) + print("Testing Faraday rotation for Landau-Lifshitz-Gilbert model...") + self.check_rotation(mat, L, freq, zsrc, resolution, tmax, zout, k) if __name__ == '__main__': unittest.main() From f649858fa579ad7bfe0b5e7f5d6ec2407b7215ba Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Thu, 13 Jun 2019 23:31:32 +0800 Subject: [PATCH 61/61] Add faraday rotation test to python/Makefile.am --- python/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/python/Makefile.am b/python/Makefile.am index fd1197209..9e9ad2999 100644 --- a/python/Makefile.am +++ b/python/Makefile.am @@ -43,6 +43,7 @@ TESTS = \ $(TEST_DIR)/cyl_ellipsoid.py \ $(TEST_DIR)/dft_energy.py \ $(TEST_DIR)/dft_fields.py \ + $(TEST_DIR)/faraday_rotation.py \ $(TEST_DIR)/field_functions.py \ $(TEST_DIR)/force.py \ $(TEST_DIR)/fragment_stats.py \