From 31aa7c9d9baece5e5bd4e432ec9d6bb3c88db8d9 Mon Sep 17 00:00:00 2001 From: Alex Cerjan Date: Fri, 22 Mar 2019 12:40:24 -0400 Subject: [PATCH 1/5] Fixed run-k-points bug by adding change-k-point. Slight update to documentation to remind users to set the k-point prior to adding flux / energy regions. --- doc/docs/Python_User_Interface.md | 4 ++-- doc/docs/Scheme_User_Interface.md | 4 ++-- python/simulation.py | 1 + scheme/meep.scm.in | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index 66a8f443d..253f1adc7 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -1072,7 +1072,7 @@ As described in the tutorial, you normally use `add_flux` via statements like: **`transmission = sim.add_flux(...)`** — -to store the flux object in a variable. `add_flux` initializes the fields if necessary, just like calling `run`, so you should only call it *after* initializing your `Simulation` object which includes specifying `geometry`, `sources`, `boundary_layers`, etcetera. You can create as many flux objects as you want, e.g. to look at powers flowing in different regions or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the flux region multiplied by the number of electric and magnetic field components required to get the Poynting vector multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. +to store the flux object in a variable. `add_flux` initializes the fields if necessary, just like calling `run`, so you should only call it *after* initializing your `Simulation` object which includes specifying `geometry`, `sources`, `boundary_layers`, `k_point`, etcetera. You can create as many flux objects as you want, e.g. to look at powers flowing in different regions or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the flux region multiplied by the number of electric and magnetic field components required to get the Poynting vector multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. Once you have called `add_flux`, the Fourier transforms of the fields are accumulated automatically during time-stepping by the [run functions](#run-functions). At any time, you can ask for Meep to print out the current flux spectrum via: @@ -1205,7 +1205,7 @@ As for energy regions, you normally use `add_energy` via statements like: En = sim.add_energy(...) ``` -to store the energy object in a variable. `add_energy` initializes the fields if necessary, just like calling `run`, so you should only call it *after* setting up your `geometry`, `sources`, `boundary_layers`, etcetera. You can create as many energy objects as you want, e.g. to look at the energy densities in different objects or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the energy region multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. +to store the energy object in a variable. `add_energy` initializes the fields if necessary, just like calling `run`, so you should only call it *after* setting up your `geometry`, `sources`, `boundary_layers`, `k_point`, etcetera. You can create as many energy objects as you want, e.g. to look at the energy densities in different objects or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the energy region multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. Once you have called `add_energy`, the Fourier transforms of the fields are accumulated automatically during time-stepping by the `run` functions. At any time, you can ask for Meep to print out the current energy density spectrum via: diff --git a/doc/docs/Scheme_User_Interface.md b/doc/docs/Scheme_User_Interface.md index 8aca81d1b..03df55aca 100644 --- a/doc/docs/Scheme_User_Interface.md +++ b/doc/docs/Scheme_User_Interface.md @@ -904,7 +904,7 @@ As described in the tutorial, you normally use `add-flux` via statements like: **`(define transmission (add-flux ...))`** — -to store the flux object in a variable. `add-flux` initializes the fields if necessary, just like calling `run`, so you should only call it *after* setting up your `geometry`, `sources`, `pml-layers`, etcetera. You can create as many flux objects as you want, e.g. to look at powers flowing in different regions or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the flux region multiplied by the number of electric and magnetic field components required to get the Poynting vector multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. +to store the flux object in a variable. `add-flux` initializes the fields if necessary, just like calling `run`, so you should only call it *after* setting up your `geometry`, `sources`, `pml-layers`, `k-point`, etcetera. You can create as many flux objects as you want, e.g. to look at powers flowing in different regions or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the flux region multiplied by the number of electric and magnetic field components required to get the Poynting vector multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. Once you have called `add-flux`, the Fourier transforms of the fields are accumulated automatically during time-stepping by the [run functions](#run-functions). At any time, you can ask for Meep to print out the current flux spectrum via: @@ -1005,7 +1005,7 @@ As for energy regions, you normally use `add-energy` via statements like: (define En (add-energy ...)) ``` -to store the energy object in a variable. `add-energy` initializes the fields if necessary, just like calling `run`, so you should only call it *after* setting up your `geometry`, `sources`, `pml-layers`, etcetera. You can create as many energy objects as you want, e.g. to look at the energy densities in different objects or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the energy region multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. +to store the energy object in a variable. `add-energy` initializes the fields if necessary, just like calling `run`, so you should only call it *after* setting up your `geometry`, `sources`, `pml-layers`, `k-point`, etcetera. You can create as many energy objects as you want, e.g. to look at the energy densities in different objects or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the energy region multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. Once you have called `add-energy`, the Fourier transforms of the fields are accumulated automatically during time-stepping by the `run` functions. At any time, you can ask for Meep to print out the current energy density spectrum via: diff --git a/python/simulation.py b/python/simulation.py index 83eb13053..d98e42a86 100644 --- a/python/simulation.py +++ b/python/simulation.py @@ -1257,6 +1257,7 @@ def run_k_points(self, t, k_points): k_index += 1 if k_index == 1: + self.change_k_point(k) self.init_sim() output_epsilon(self) diff --git a/scheme/meep.scm.in b/scheme/meep.scm.in index fee50d199..e483bcc2b 100644 --- a/scheme/meep.scm.in +++ b/scheme/meep.scm.in @@ -1353,7 +1353,7 @@ (define all-freqs '()) (map (lambda (k) (set! k-index (+ k-index 1)) - (if (= k-index 1) (begin (init-fields) (output-epsilon))) + (if (= k-index 1) (begin (change-k-point! k) (init-fields) (output-epsilon))) (let ((freqs (run-k-point T k))) (print "freqs:, " k-index ", " (vector3-x k) ", " (vector3-y k) ", " (vector3-z k)) From 24362bdc6312e56ff037ae5c451be9eaa83d7e38 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Mon, 25 Mar 2019 16:03:24 -0400 Subject: [PATCH 2/5] delete unnecessary init-fields call --- scheme/meep.scm.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scheme/meep.scm.in b/scheme/meep.scm.in index e483bcc2b..af9499c86 100644 --- a/scheme/meep.scm.in +++ b/scheme/meep.scm.in @@ -1353,7 +1353,7 @@ (define all-freqs '()) (map (lambda (k) (set! k-index (+ k-index 1)) - (if (= k-index 1) (begin (change-k-point! k) (init-fields) (output-epsilon))) + (if (= k-index 1) (begin (change-k-point! k) (output-epsilon))) (let ((freqs (run-k-point T k))) (print "freqs:, " k-index ", " (vector3-x k) ", " (vector3-y k) ", " (vector3-z k)) From 3300041b6fb3a343253e003e875e63c43cf145e0 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Mon, 25 Mar 2019 16:05:17 -0400 Subject: [PATCH 3/5] in Python we don't output_epsilon by default --- python/simulation.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/python/simulation.py b/python/simulation.py index d98e42a86..fa14f3d10 100644 --- a/python/simulation.py +++ b/python/simulation.py @@ -1255,12 +1255,6 @@ def run_k_points(self, t, k_points): for k in k_points: k_index += 1 - - if k_index == 1: - self.change_k_point(k) - self.init_sim() - output_epsilon(self) - harminv = self.run_k_point(t, k) freqs = [complex(m.freq, m.decay) for m in harminv.modes] From bbe913fcba7b107cdbef37daf222452e1edfe13c Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Mon, 25 Mar 2019 16:08:02 -0400 Subject: [PATCH 4/5] add_flux/energy/force are lazy in Python --- doc/docs/Python_User_Interface.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index 253f1adc7..8d6003da1 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -1072,7 +1072,7 @@ As described in the tutorial, you normally use `add_flux` via statements like: **`transmission = sim.add_flux(...)`** — -to store the flux object in a variable. `add_flux` initializes the fields if necessary, just like calling `run`, so you should only call it *after* initializing your `Simulation` object which includes specifying `geometry`, `sources`, `boundary_layers`, `k_point`, etcetera. You can create as many flux objects as you want, e.g. to look at powers flowing in different regions or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the flux region multiplied by the number of electric and magnetic field components required to get the Poynting vector multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. +to store the flux object in a variable. You can create as many flux objects as you want, e.g. to look at powers flowing in different regions or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the flux region multiplied by the number of electric and magnetic field components required to get the Poynting vector multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. Once you have called `add_flux`, the Fourier transforms of the fields are accumulated automatically during time-stepping by the [run functions](#run-functions). At any time, you can ask for Meep to print out the current flux spectrum via: @@ -1205,7 +1205,7 @@ As for energy regions, you normally use `add_energy` via statements like: En = sim.add_energy(...) ``` -to store the energy object in a variable. `add_energy` initializes the fields if necessary, just like calling `run`, so you should only call it *after* setting up your `geometry`, `sources`, `boundary_layers`, `k_point`, etcetera. You can create as many energy objects as you want, e.g. to look at the energy densities in different objects or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the energy region multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. +to store the energy object in a variable. You can create as many energy objects as you want, e.g. to look at the energy densities in different objects or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the energy region multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. Once you have called `add_energy`, the Fourier transforms of the fields are accumulated automatically during time-stepping by the `run` functions. At any time, you can ask for Meep to print out the current energy density spectrum via: @@ -1287,7 +1287,7 @@ As for force regions, you normally use `add_force` via statements like: Fx = sim.add_force(...) ``` -to store the force object in a variable. `add_force` initializes the fields if necessary, just like calling `run`, so you should only call it *after* initializing your `Simulation` object which includes specifying `geometry`, `sources`, `boundary_layers`, etcetera. You can create as many force objects as you want, e.g. to look at forces on different objects, in different directions, or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the force region, multiplied by the number of electric and magnetic field components required to get the stress vector, multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. +to store the force object in a variable. You can create as many force objects as you want, e.g. to look at forces on different objects, in different directions, or in different frequency ranges. Note, however, that Meep has to store (and update at every time step) a number of Fourier components equal to the number of grid points intersecting the force region, multiplied by the number of electric and magnetic field components required to get the stress vector, multiplied by `nfreq`, so this can get quite expensive (in both memory and time) if you want a lot of frequency points over large regions of space. Once you have called `add_force`, the Fourier transforms of the fields are accumulated automatically during time-stepping by the `run` functions. At any time, you can ask for Meep to print out the current force spectrum via: From 6162767c86ada06a35f7488c9b8ce07fc6e47fa1 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Mon, 25 Mar 2019 17:16:07 -0400 Subject: [PATCH 5/5] init-fields if they aren't created yet --- scheme/meep.scm.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scheme/meep.scm.in b/scheme/meep.scm.in index af9499c86..4fbb632cc 100644 --- a/scheme/meep.scm.in +++ b/scheme/meep.scm.in @@ -1353,7 +1353,7 @@ (define all-freqs '()) (map (lambda (k) (set! k-index (+ k-index 1)) - (if (= k-index 1) (begin (change-k-point! k) (output-epsilon))) + (if (= k-index 1) (begin (change-k-point! k) (if (null? fields) (init-fields)) (output-epsilon))) (let ((freqs (run-k-point T k))) (print "freqs:, " k-index ", " (vector3-x k) ", " (vector3-y k) ", " (vector3-z k))