MCPcopy Create free account
hub / github.com/NanoComp/meep / src_vol_chunkloop

Function src_vol_chunkloop

src/sources.cpp:243–312  ·  view source on GitHub ↗

Adding source volumes can be treated as a kind of "integration" problem, since we need to loop over all the chunks that intersect the source grid_volume, with appropriate interpolation weights at the boundaries so that the integral of the current is fixed regardless of resolution. Unlike most uses of fields::loop_in_chunks, however, we set use_symmetry=false: we only find the inter

Source from the content-addressed store, hash-verified

241 with the untransformed chunks (since the transformed versions are
242 implicit). */
243static void src_vol_chunkloop(fields_chunk *fc, int ichunk, component c, ivec is, ivec ie, vec s0,
244 vec s1, vec e0, vec e1, double dV0, double dV1, ivec shift,
245 complex<double> shift_phase, const symmetry &S, int sn, void *data_) {
246 src_vol_chunkloop_data *data = (src_vol_chunkloop_data *)data_;
247
248 (void)S;
249 (void)sn; // these should be the identity
250 (void)dV0;
251 (void)dV1; // grid_volume weighting is included in data->amp
252 (void)ichunk;
253
254 size_t npts = 1;
255 LOOP_OVER_DIRECTIONS(is.dim, d) { npts *= (ie.in_direction(d) - is.in_direction(d)) / 2 + 1; }
256 std::vector<ptrdiff_t> index_array(npts);
257 std::vector<complex<double> > amps_array(npts);
258
259 complex<double> amp = data->amp * conj(shift_phase);
260
261 direction cd = component_direction(c);
262
263 double inva = fc->gv.inva;
264 size_t idx_vol = 0;
265 LOOP_OVER_IVECS(fc->gv, is, ie, idx) {
266 IVEC_LOOP_ILOC(fc->gv, iloc);
267 if (!fc->gv.owns(iloc)) continue;
268
269 IVEC_LOOP_LOC(fc->gv, loc);
270 loc += shift * (0.5 * inva);
271
272 vec rel_loc = loc - data->center;
273 amps_array[idx_vol] = IVEC_LOOP_WEIGHT(s0, s1, e0, e1, 1) * amp * data->A(rel_loc);
274
275 // check for invalid sources at r=0 in cylindrical coordinates
276 if (fc->gv.dim == Dcyl && loc.r() == 0 && amps_array[idx_vol] != 0.0) {
277 if (fc->m == 0) {
278 if (component_direction(c) == R || component_direction(c) == P)
279 meep::abort("Not possible to place a %s source at r=0 in "
280 "cylindrical coordinates for m = 0.",
281 component_name(c));
282 }
283 else if (fabs(fc->m) == 1.0) {
284 if (component_direction(c) == Z)
285 meep::abort("Not possible to place a %s source at r=0 in "
286 "cylindrical coordinates for |m| = 1.0.",
287 component_name(c));
288 }
289 else {
290 meep::abort("Not possible to place a source at r=0 in "
291 "cylindrical coordinates for m = %g.",
292 fc->m);
293 }
294 }
295
296 /* for "D" sources, multiply by epsilon. FIXME: this is not quite
297 right because it doesn't handle non-diagonal chi1inv!
298 similarly, for "B" sources, multiply by mu. */
299 if (is_D(c) && fc->s->chi1inv[c - Dx + Ex][cd])
300 amps_array[idx_vol] /= fc->s->chi1inv[c - Dx + Ex][cd][idx];

Callers

nothing calls this directly

Calls 13

component_directionFunction · 0.85
abortFunction · 0.85
component_nameFunction · 0.85
is_DFunction · 0.85
is_BFunction · 0.85
is_H_or_BFunction · 0.85
ownsMethod · 0.80
LOOP_OVER_DIRECTIONSFunction · 0.70
LOOP_OVER_IVECSFunction · 0.70
src_volClass · 0.70
in_directionMethod · 0.45
rMethod · 0.45

Tested by

no test coverage detected