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

computing the normal vector to an interface for a MaterialGrid #1537

Closed
oskooi opened this issue Mar 26, 2021 · 1 comment · Fixed by #1539
Closed

computing the normal vector to an interface for a MaterialGrid #1537

oskooi opened this issue Mar 26, 2021 · 1 comment · Fixed by #1539

Comments

@oskooi
Copy link
Collaborator

oskooi commented Mar 26, 2021

The following schematic shows the analytic expressions necessary to compute the gradient of the weights array u for a MaterialGrid in 2d from which the normal vector to an interface can be obtained at any Yee grid point using bilinear interpolation. In the figure, the MaterialGrid are the green points and the Yee grid points for Ex and Ey are the blue and red points, respectively.

Meep_Adjoint_Meeting_Notes

To set this up, we will need to modify the existing material_function::normal_vector routine which uses spherical quadrature such that for the case of a MaterialGrid it uses the analytic formulas shown above:

vec material_function::normal_vector(field_type ft, const volume &v) {
vec gradient(zero_vec(v.dim));
vec p(v.center());
double R = v.diameter();
int num_dirs = number_of_directions(v.dim);
int min_iters = 1 << num_dirs;
double chi1p1_prev = 0;
bool break_early = true;
for (int i = 0; i < num_sphere_quad[num_dirs - 1]; ++i) {
double weight;
vec pt = sphere_pt(p, R, i, weight);
double chi1p1_val = chi1p1(ft, pt);
if (i > 0 && i < min_iters) {
if (chi1p1_val != chi1p1_prev) { break_early = false; }
if (i == min_iters - 1 && break_early) {
// Don't average regions where epsilon is uniform
return zero_vec(v.dim);
}
}
chi1p1_prev = chi1p1_val;
gradient += (pt - p) * (weight * chi1p1_val);
}
return gradient;
}

We can then verify that the new approach to computing the normal vector is working correctly by comparing with the results obtained using spherical quadrature for e.g. a test case involving a cylinder (similar to #1522 (comment)).

@stevengj
Copy link
Collaborator

The first thing is to implement a function matgrid_grad that computes the gradient, similar to matgrid_val. Then you can call this when computing the normal vector if you detect that that pixel is completely within a material-grid object.

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

Successfully merging a pull request may close this issue.

2 participants