Skip to content

Commit 08cb5e0

Browse files
authored
make greencyl_tol a parameter (#3064)
* make greencyl_tol a parameter * add greencyl_tol to wrappers * work around SWIG bug: make greencyl_tol a required argument
1 parent bd171ad commit 08cb5e0

File tree

5 files changed

+28
-21
lines changed

5 files changed

+28
-21
lines changed

python/adjoint/objective.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ def __init__(
443443
nperiods: Optional[int] = 1,
444444
decimation_factor: Optional[int] = 0,
445445
norm_near_fields: Optional[NearToFarData] = None,
446+
greencyl_tol: float = 1e-3,
446447
):
447448
"""Initialize an instance of differentiable Fourier fields instance.
448449
@@ -470,6 +471,7 @@ def __init__(
470471
self.decimation_factor = decimation_factor
471472
self.norm_near_fields = norm_near_fields
472473
self.nperiods = nperiods
474+
self.greencyl_tol = greencyl_tol
473475

474476
def register_monitors(self, frequencies):
475477
self._frequencies = np.asarray(frequencies)
@@ -501,7 +503,7 @@ def place_adjoint_source(self, dJ):
501503
)
502504

503505
all_nearsrcdata = self._monitor.swigobj.near_sourcedata(
504-
far_pt_vec, farpt_list, self._nfar_pts, dJ
506+
far_pt_vec, farpt_list, self._nfar_pts, dJ, self.greencyl_tol
505507
)
506508
for near_data in all_nearsrcdata:
507509
cur_comp = near_data.near_fd_comp

python/meep.i

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -329,12 +329,12 @@ PyObject *py_do_harminv(PyObject *vals, double dt, double f_min, double f_max, i
329329
}
330330

331331
// Wrapper around meep::dft_near2far::farfield
332-
PyObject *_get_farfield(meep::dft_near2far *f, const meep::vec & v) {
332+
PyObject *_get_farfield(meep::dft_near2far *f, const meep::vec & v, double greencyl_tol) {
333333
// Return value: New reference
334334
Py_ssize_t len = f->freq.size() * 6;
335335
PyObject *res = PyList_New(len);
336336

337-
std::complex<double> *ff_arr = f->farfield(v);
337+
std::complex<double> *ff_arr = f->farfield(v, greencyl_tol);
338338

339339
for (Py_ssize_t i = 0; i < len; i++) {
340340
PyList_SetItem(res, i, PyComplex_FromDoubles(ff_arr[i].real(), ff_arr[i].imag()));
@@ -347,13 +347,13 @@ PyObject *_get_farfield(meep::dft_near2far *f, const meep::vec & v) {
347347

348348
// Wrapper around meep::dft_near2far::get_farfields_array
349349
PyObject *_get_farfields_array(meep::dft_near2far *n2f, const meep::volume &where,
350-
double resolution) {
350+
double resolution, double greencyl_tol) {
351351
// Return value: New reference
352352
size_t dims[4] = {1, 1, 1, 1};
353353
int rank = 0;
354354
size_t N = 1;
355355

356-
double *EH = n2f->get_farfields_array(where, rank, dims, N, resolution);
356+
double *EH = n2f->get_farfields_array(where, rank, dims, N, resolution, greencyl_tol);
357357

358358
if (!EH) return PyArray_SimpleNew(0, 0, NPY_CDOUBLE);
359359

@@ -662,8 +662,8 @@ PyObject *py_do_harminv(PyObject *vals, double dt, double f_min, double f_max, i
662662
double spectral_density, double Q_thresh, double rel_err_thresh,
663663
double err_thresh, double rel_amp_thresh, double amp_thresh);
664664

665-
PyObject *_get_farfield(meep::dft_near2far *f, const meep::vec & v);
666-
PyObject *_get_farfields_array(meep::dft_near2far *n2f, const meep::volume &where, double resolution);
665+
PyObject *_get_farfield(meep::dft_near2far *f, const meep::vec & v, double greencyl_tol);
666+
PyObject *_get_farfields_array(meep::dft_near2far *n2f, const meep::volume &where, double resolution, double greencyl_tol);
667667
PyObject *_dft_ldos_ldos(meep::dft_ldos *f);
668668
PyObject *_dft_ldos_F(meep::dft_ldos *f);
669669
PyObject *_dft_ldos_J(meep::dft_ldos *f);

python/simulation.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3215,7 +3215,7 @@ def load_minus_energy(self, fname: str, energy: DftEnergy):
32153215
self.load_energy(fname, energy)
32163216
energy.scale_dfts(-1.0)
32173217

3218-
def get_farfield(self, near2far, x):
3218+
def get_farfield(self, near2far, x, greencyl_tol: float = 1e-3):
32193219
"""
32203220
Given a `Vector3` point `x` which can lie anywhere outside the near-field surface,
32213221
including outside the cell and a `near2far` object, returns the computed
@@ -3228,6 +3228,7 @@ def get_farfield(self, near2far, x):
32283228
return mp._get_farfield(
32293229
near2far.swigobj,
32303230
py_v3_to_vec(self.dimensions, x, is_cylindrical=self.is_cylindrical),
3231+
greencyl_tol,
32313232
)
32323233

32333234
def get_farfields(
@@ -3237,6 +3238,7 @@ def get_farfields(
32373238
where: Volume = None,
32383239
center: Vector3Type = None,
32393240
size: Vector3Type = None,
3241+
greencyl_tol: float = 1e-3,
32403242
):
32413243
"""
32423244
Like `output_farfields` but returns a dictionary of NumPy arrays instead of
@@ -3253,7 +3255,9 @@ def get_farfields(
32533255
self.init_sim()
32543256
vol = self._volume_from_kwargs(where, center, size)
32553257
self.fields.am_now_working_on(mp.GetFarfieldsTime)
3256-
result = mp._get_farfields_array(near2far.swigobj, vol, resolution)
3258+
result = mp._get_farfields_array(
3259+
near2far.swigobj, vol, resolution, greencyl_tol
3260+
)
32573261
self.fields.finished_working()
32583262
res_ex = complexarray(result[0], result[1])
32593263
res_ey = complexarray(result[2], result[3])

src/meep.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,17 +1360,17 @@ class dft_near2far {
13601360
dft_near2far(const dft_near2far &f);
13611361

13621362
/* return an array (Ex,Ey,Ez,Hx,Hy,Hz) x Nfreq of the far fields at x */
1363-
std::complex<double> *farfield(const vec &x);
1363+
std::complex<double> *farfield(const vec &x, double greencyl_tol = 1e-3);
13641364

13651365
/* like farfield, but requires F to be Nfreq*6 preallocated array, and
13661366
does *not* perform the reduction over processes...an MPI allreduce
13671367
summation by the caller is required to get the final result ... used
13681368
by other output routine to efficiently get far field on a grid of pts */
1369-
void farfield_lowlevel(std::complex<double> *F, const vec &x);
1369+
void farfield_lowlevel(std::complex<double> *F, const vec &x, double greencyl_tol = 1e-3);
13701370

13711371
/* Return a newly allocated array with all far fields */
13721372
double *get_farfields_array(const volume &where, int &rank, size_t *dims, size_t &N,
1373-
double resolution);
1373+
double resolution, double greencyl_tol = 1e-3);
13741374

13751375
/* output far fields on a grid to an HDF5 file */
13761376
void save_farfields(const char *fname, const char *prefix, const volume &where,
@@ -1400,7 +1400,7 @@ class dft_near2far {
14001400
double periodic_k[2], period[2];
14011401

14021402
std::vector<sourcedata> near_sourcedata(const vec &x_0, double *farpt_list, size_t nfar_pts,
1403-
const std::complex<double> *dJ);
1403+
const std::complex<double> *dJ, double greencyl_tol);
14041404
};
14051405

14061406
/* Class to compute local-density-of-states spectra: the power spectrum

src/near2far.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ void greencyl(std::complex<double> *EH, const vec &x, double freq, double eps, d
348348
}
349349
}
350350

351-
void dft_near2far::farfield_lowlevel(std::complex<double> *EH, const vec &x) {
351+
void dft_near2far::farfield_lowlevel(std::complex<double> *EH, const vec &x, double greencyl_tol) {
352352
if (x.dim != D3 && x.dim != D2 && x.dim != Dcyl)
353353
meep::abort("only 2d or 3d or cylindrical far-field computation is supported");
354354
greenfunc green = x.dim == D2 ? green2d : green3d;
@@ -384,7 +384,7 @@ void dft_near2far::farfield_lowlevel(std::complex<double> *EH, const vec &x) {
384384
std::complex<double> cphase = std::polar(1.0, phase);
385385
if (x.dim == Dcyl)
386386
greencyl(EH6, x, freq[i], eps, mu, xs, c0, f->dft[Nfreq * idx_dft + i], f->fc->m,
387-
1e-3);
387+
greencyl_tol);
388388
else
389389
green(EH6, x, freq[i], eps, mu, xs, c0, f->dft[Nfreq * idx_dft + i]);
390390
for (int j = 0; j < 6; ++j)
@@ -397,19 +397,19 @@ void dft_near2far::farfield_lowlevel(std::complex<double> *EH, const vec &x) {
397397
}
398398
}
399399

400-
std::complex<double> *dft_near2far::farfield(const vec &x) {
400+
std::complex<double> *dft_near2far::farfield(const vec &x, double greencyl_tol) {
401401
std::complex<double> *EH, *EH_local;
402402
const size_t Nfreq = freq.size();
403403
EH_local = new std::complex<double>[6 * Nfreq];
404-
farfield_lowlevel(EH_local, x);
404+
farfield_lowlevel(EH_local, x, greencyl_tol);
405405
EH = new std::complex<double>[6 * Nfreq];
406406
sum_to_all(EH_local, EH, 6 * Nfreq);
407407
delete[] EH_local;
408408
return EH;
409409
}
410410

411411
double *dft_near2far::get_farfields_array(const volume &where, int &rank, size_t *dims, size_t &N,
412-
double resolution) {
412+
double resolution, double greencyl_tol) {
413413
/* compute output grid size etc. */
414414
double dx[3] = {0, 0, 0};
415415
direction dirs[3] = {X, Y, Z};
@@ -457,7 +457,7 @@ double *dft_near2far::get_farfields_array(const volume &where, int &rank, size_t
457457
start = t;
458458
last_point = this_point;
459459
}
460-
farfield_lowlevel(EH1, x);
460+
farfield_lowlevel(EH1, x, greencyl_tol);
461461
if (verbosity > 1) all_wait(); // Allow consistent progress updates from master
462462
ptrdiff_t idx = (i0 * dims[1] + i1) * dims[2] + i2;
463463
for (size_t i = 0; i < Nfreq; ++i)
@@ -655,7 +655,8 @@ dft_near2far fields::add_dft_near2far(const volume_list *where, const double *fr
655655
// Modified from farfield_lowlevel
656656
std::vector<struct sourcedata> dft_near2far::near_sourcedata(const vec &x_0, double *farpt_list,
657657
size_t nfar_pts,
658-
const std::complex<double> *dJ) {
658+
const std::complex<double> *dJ,
659+
double greencyl_tol) {
659660
if (x_0.dim != D3 && x_0.dim != D2 && x_0.dim != Dcyl)
660661
meep::abort("only 2d or 3d or cylindrical far-field computation is supported");
661662
greenfunc green = x_0.dim == D2 ? green2d : green3d;
@@ -697,7 +698,7 @@ std::vector<struct sourcedata> dft_near2far::near_sourcedata(const vec &x_0, dou
697698
for (size_t ipt = 0; ipt < nfar_pts; ++ipt) {
698699
vec x = vec(farpt_list[3 * ipt], farpt_list[3 * ipt + 1], farpt_list[3 * ipt + 2]);
699700
if (x_0.dim == Dcyl)
700-
greencyl(EH6, x, freq[i], eps, mu, xs, c0, w, f->fc->m, 1e-3);
701+
greencyl(EH6, x, freq[i], eps, mu, xs, c0, w, f->fc->m, greencyl_tol);
701702
else
702703
green(EH6, x, freq[i], eps, mu, xs, c0, w);
703704
for (int j = 0; j < 6; ++j)

0 commit comments

Comments
 (0)