diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md index 5cf57b394..219cc96ee 100644 --- a/doc/docs/Python_User_Interface.md +++ b/doc/docs/Python_User_Interface.md @@ -1051,9 +1051,9 @@ Given a frequency `omega` and a `Vector3` `pt`, returns the average eigenvalue o — Initialize the component `c` fields using the function `func` which has a single argument, a `Vector3` giving a position and returns a complex number for the value of the field at that point. -**`add_dft_fields(cs, freq_min, freq_max, nfreq, where=None, center=None, size=None)`** +**`add_dft_fields(cs, freq_min, freq_max, nfreq, where=None, center=None, size=None, yee_grid=False)`** — -Given a list of field components `cs`, compute the Fourier transform of these fields for `nfreq` equally spaced frequencies covering the frequency range `freq_min` to `freq_max` over the `Volume` specified by `where` (default to the entire cell). The volume can also be specified via the `center` and `size` arguments. +Given a list of field components `cs`, compute the Fourier transform of these fields for `nfreq` equally spaced frequencies covering the frequency range `freq_min` to `freq_max` over the `Volume` specified by `where` (default to the entire cell). The volume can also be specified via the `center` and `size` arguments. The default routine interpolates the Fourier transformed fields at the center of each voxel within the specified volume. Alternatively, the exact Fourier transformed fields evaluated at each corresponding Yee grid point is available by setting `yee_grid` to `True`. **`flux_in_box(dir, box=None, center=None, size=None)`** — diff --git a/python/meep.i b/python/meep.i index 0320c456f..e65b3cd08 100644 --- a/python/meep.i +++ b/python/meep.i @@ -957,6 +957,16 @@ meep::volume_list *make_volume_list(const meep::volume &v, int c, //-------------------------------------------------- // typemaps needed for add_dft_fields //-------------------------------------------------- + +%typecheck(SWIG_TYPECHECK_POINTER) const volume where { + int py_material = PyObject_IsInstance($input, py_volume_object()); + $1 = py_material; +} + +%typecheck(SWIG_TYPECHECK_POINTER) meep::component *components { + $1 = PyList_Check($input); +} + %typemap(in) (meep::component *components, int num_components) { if (!PyList_Check($input)) { meep::abort("Expected a list"); diff --git a/python/simulation.py b/python/simulation.py index 89621117b..28226ef0a 100644 --- a/python/simulation.py +++ b/python/simulation.py @@ -1539,22 +1539,22 @@ def _evaluate_dft_objects(self): if dft.swigobj is None: dft.swigobj = dft.func(*dft.args) - def add_dft_fields(self, components, freq_min, freq_max, nfreq, where=None, center=None, size=None): + def add_dft_fields(self, components, freq_min, freq_max, nfreq, where=None, center=None, size=None, yee_grid=False): center_v3 = Vector3(*center) if center is not None else None size_v3 = Vector3(*size) if size is not None else None - dftf = DftFields(self._add_dft_fields, [components, where, center_v3, size_v3, freq_min, freq_max, nfreq]) + use_centered_grid = not yee_grid + dftf = DftFields(self._add_dft_fields, [components, where, center_v3, size_v3, freq_min, freq_max, nfreq, use_centered_grid]) self.dft_objects.append(dftf) return dftf - def _add_dft_fields(self, components, where, center, size, freq_min, freq_max, nfreq): + def _add_dft_fields(self, components, where, center, size, freq_min, freq_max, nfreq, use_centered_grid): if self.fields is None: self.init_sim() try: where = self._volume_from_kwargs(where, center, size) except ValueError: where = self.fields.total_volume() - - return self.fields.add_dft_fields(components, where, freq_min, freq_max, nfreq) + return self.fields.add_dft_fields(components, where, freq_min, freq_max, nfreq, use_centered_grid) def output_dft(self, dft_fields, fname): if self.fields is None: diff --git a/python/tests/dft_fields.py b/python/tests/dft_fields.py index feb4e33ed..a4fde8422 100644 --- a/python/tests/dft_fields.py +++ b/python/tests/dft_fields.py @@ -34,7 +34,12 @@ def init(self): sources=sources, boundary_layers=pml_layers, ) - + def test_use_centered_grid(self): + sim = self.init() + sim.init_sim() + dft_fields = sim.add_dft_fields([mp.Ez], self.fcen, self.fcen, 1, yee_grid=True) + sim.run(until=100) + def test_get_dft_array(self): sim = self.init() sim.init_sim() diff --git a/python/typemap_utils.cpp b/python/typemap_utils.cpp index 447c06476..821a43716 100644 --- a/python/typemap_utils.cpp +++ b/python/typemap_utils.cpp @@ -82,6 +82,15 @@ static PyObject *py_vector3_object() { return vector3_object; } +static PyObject *py_volume_object() { + static PyObject *volume_object = NULL; + if (volume_object == NULL) { + PyObject *geom_mod = get_geom_mod(); + volume_object = PyObject_GetAttrString(PyImport_ImportModule("meep"), "Volume"); + } + return volume_object; +} + static PyObject *vec2py(const meep::vec &v, bool newobj = false) { double x = 0, y = 0, z = 0; diff --git a/src/dft.cpp b/src/dft.cpp index db407c091..b53acaef5 100644 --- a/src/dft.cpp +++ b/src/dft.cpp @@ -672,13 +672,16 @@ void dft_fields::remove() { } dft_fields fields::add_dft_fields(component *components, int num_components, const volume where, - double freq_min, double freq_max, int Nfreq) { + double freq_min, double freq_max, int Nfreq, bool use_centered_grid) { bool include_dV_and_interp_weights = false; + bool sqrt_dV_and_interp_weights = false; // default option from meep.hpp (expose to user?) + std::complex extra_weight = 1.0; // default option from meep.hpp (expose to user?) cdouble stored_weight = 1.0; dft_chunk *chunks = 0; for (int nc = 0; nc < num_components; nc++) chunks = add_dft(components[nc], where, freq_min, freq_max, Nfreq, - include_dV_and_interp_weights, stored_weight, chunks); + include_dV_and_interp_weights, stored_weight, chunks, + sqrt_dV_and_interp_weights,extra_weight,use_centered_grid); return dft_fields(chunks, freq_min, freq_max, Nfreq, where); } diff --git a/src/meep.hpp b/src/meep.hpp index 40a228f85..94ef2e8c3 100644 --- a/src/meep.hpp +++ b/src/meep.hpp @@ -1743,7 +1743,7 @@ class fields { int Nfreq); dft_fields add_dft_fields(component *components, int num_components, const volume where, - double freq_min, double freq_max, int Nfreq); + double freq_min, double freq_max, int Nfreq, bool use_centered_grid=true); /********************************************************/ /* process_dft_component is an intermediate-level */