Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper update_fields interpolation scheme #1794

Closed
smartalecH opened this issue Oct 19, 2021 · 3 comments · Fixed by #1801
Closed

Proper update_fields interpolation scheme #1794

smartalecH opened this issue Oct 19, 2021 · 3 comments · Fixed by #1801
Labels

Comments

@smartalecH
Copy link
Collaborator

The subpixel smoothing paper describes the update equation using the following figure:

image

which is interpolation method 26(c) in the original Werner and Cary paper.

This method performs an interpolation, then the chi1inv multiplication, followed by another interpolation step. What's important is that this particular chi1inv component does not seem to be located on a typical grid point that it's originally stored (i.e. in the figure, the fields are interpolated to a "node" that doesn't store ε⁻¹ₓy).

The code, however, seems to just grab two ε points, one from a "leading corner" for each side that is being interpolated:

meep/src/step_generic.cpp

Lines 381 to 382 in b6166b1

#define OFFDIAG(u, g, sx) \
(0.25 * ((g[i] + g[i - sx]) * u[i] + (g[i + s] + g[(i + s) - sx]) * u[i + s]))

Note that u[i] aligns with g[i] and u[i + s] aligns with u[i + s], leaving g[i-sx] and g[i-isx+s] "unbalanced". (Note that multiplying each point by it's corresponding chi1inv component is a different interpolation scheme altogether and not always stable).

These two operations don't seem to be the same to me, but maybe I'm missing something with how chi1inv is stored (I thought an entire row of the tensor was stored at each corresponding yee point).

@smartalecH smartalecH changed the title Proper update fields interpolation scheme Proper update_fields interpolation scheme Oct 19, 2021
@smartalecH
Copy link
Collaborator Author

I think I see what's happening...

Even though we are indexing chi1inv at the same "location" as the fields, it actually doesn't correspond to the same location in space. Rather, if it's an off-diagonal element, it's been evaluated at a slightly off-center location (to line up with the proper node, I'm assuming):

IVEC_LOOP_ILOC(gv, here);
medium.eff_chi1inv_row(c, chi1invrow, gv.dV(here, smoothing_diameter), tol, maxeval);
medium.eff_chi1inv_row(c, chi1invrow_offdiag, gv.dV(here - shift1, smoothing_diameter), tol,
maxeval);
if (chi1inv[c][d0]) {
chi1inv[c][d0][i] = (d0 == dc) ? chi1invrow[0] : chi1invrow_offdiag[0];
trivial[0] = trivial[0] && (chi1inv[c][d0][i] == trivial_val[0]);
}
if (chi1inv[c][d1]) {
chi1inv[c][d1][i] = (d1 == dc) ? chi1invrow[1] : chi1invrow_offdiag[1];
trivial[1] = trivial[1] && (chi1inv[c][d1][i] == trivial_val[1]);
}
if (chi1inv[c][d2]) {
chi1inv[c][d2][i] = (d2 == dc) ? chi1invrow[2] : chi1invrow_offdiag[2];
trivial[2] = trivial[2] && (chi1inv[c][d2][i] == trivial_val[2]);
}

So hopefully shift1 corresponds to the distance from the Dy points and the point ε⁻¹ₓy is evaluated/indexed.

@stevengj
Copy link
Collaborator

The index in the array doesn't correspond exactly to the location in space — for different field components, the same index corresponds to different spatial points, because different field components are stored on different Yee grids.

For example, in the diagram above, all three of these spatial points correspond to the same array index i in their respective arrays:
image

@smartalecH
Copy link
Collaborator Author

Awesome, thanks!

For (my own) reference, this is the method we need to use to properly recombine the forward and adjoint fields.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants