Skip to content

Commit

Permalink
Damping (#1804)
Browse files Browse the repository at this point in the history
* fake conductivity term

* has cond

* fix

* rerun check

* revision & documentation

* rerun check

* rerun check

* Update python/geom.py

Co-authored-by: Steven G. Johnson <stevenj@mit.edu>

Co-authored-by: Mo Chen <mochen@Mos-MacBook-Pro.local>
Co-authored-by: Steven G. Johnson <stevenj@mit.edu>
  • Loading branch information
3 people authored Oct 28, 2021
1 parent 39ca7a2 commit cab86aa
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 12 deletions.
9 changes: 7 additions & 2 deletions python/geom.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ class MaterialGrid(object):
the `default_material` argument of the [`Simulation`](#Simulation) constructor (similar to a
[material function](#medium)).
"""
def __init__(self,grid_size,medium1,medium2,weights=None,grid_type="U_DEFAULT",do_averaging=False,beta=0,eta=0.5):
def __init__(self,grid_size,medium1,medium2,weights=None,grid_type="U_DEFAULT",do_averaging=False,beta=0,eta=0.5,damping=0):
"""
Creates a `MaterialGrid` object.
Expand Down Expand Up @@ -563,11 +563,15 @@ def __init__(self,grid_size,medium1,medium2,weights=None,grid_type="U_DEFAULT",d
grid values. Subpixel smoothing is fast and accurate because it exploits an analytic formulation
for level-set functions.
A nonzero damping term creates an artificial conductivity σ = u(1-u)*damping, which acts as
dissipation loss that penalize intermediate pixel values of non-binarized structures. The value of
damping should be proportional to 2π times the typical frequency of the problem.
It is possible to overlap any number of different `MaterialGrid`s. This can be useful for defining
grids which are symmetric (e.g., mirror, rotation). One way to set this up is by overlapping a
given `MaterialGrid` object with a symmetrized copy of itself. In the case of spatially overlapping
`MaterialGrid` objects (with no intervening objects), any overlapping points are computed using the
method `grid_type` which is one of `"U_MIN"` (minimum of the overlapping grid values), `"U_PROD"`
method `grid_type` which is one of `"U_MIN"` (minimum of the overlapping grid values), `"U_PROD"`
(product), `"U_MEAN"` (mean), `"U_DEFAULT"` (topmost material grid). In general, these `"U_*"` options
allow you to combine any material grids that overlap in space with no intervening objects.
"""
Expand All @@ -586,6 +590,7 @@ def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
self.do_averaging = do_averaging
self.beta = beta
self.eta = eta
self.damping = damping
if weights is None:
self.weights = np.zeros((self.num_params,))
elif weights.size != self.num_params:
Expand Down
6 changes: 5 additions & 1 deletion python/typemap_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -581,11 +581,15 @@ static int pymaterial_to_material(PyObject *po, material_type *mt) {
PyObject *py_eta = PyObject_GetAttrString(po, "eta");
double eta = 0;
if (py_eta) { eta = PyFloat_AsDouble(py_eta); }
md = make_material_grid(do_averaging,beta,eta);
PyObject *py_damping = PyObject_GetAttrString(po, "damping");
double damping = 0;
if (py_damping) { damping = PyFloat_AsDouble(py_damping); }
md = make_material_grid(do_averaging,beta,eta,damping);
if (!pymaterial_grid_to_material_grid(po, md)) { return 0; }
Py_XDECREF(py_do_averaging);
Py_XDECREF(py_beta);
Py_XDECREF(py_eta);
Py_XDECREF(py_damping);
}
else if (PyFunction_Check(po)) {
PyObject *eps = PyObject_GetAttrString(po, "eps");
Expand Down
1 change: 1 addition & 0 deletions src/material_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ void material_data::copy_from(const material_data &from) {
medium_2 = from.medium_2;
beta = from.beta;
eta = from.eta;
damping = from.damping;
}

material_type_list::material_type_list() : items(NULL), num_items(0) {}
Expand Down
3 changes: 2 additions & 1 deletion src/material_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ struct material_data {
medium_struct medium_2;
double beta;
double eta;
double damping;
/*
There are several possible scenarios when material grids overlap -- these
different scenarios enable different applications.
Expand Down Expand Up @@ -180,7 +181,7 @@ extern material_type vacuum;
material_type make_dielectric(double epsilon);
material_type make_user_material(user_material_func user_func, void *user_data);
material_type make_file_material(char *epsilon_input_file);
material_type make_material_grid(bool do_averaging, double beta, double eta);
material_type make_material_grid(bool do_averaging, double beta, double eta, double damping);
void read_epsilon_file(const char *eps_input_file);
void update_weights(material_type matgrid, double *weights);

Expand Down
25 changes: 18 additions & 7 deletions src/meepgeom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,10 @@ void epsilon_material_grid(material_data *md, double u) {
// mm->D_conductivity_diag.x = mm->D_conductivity_diag.y = mm->D_conductivity_diag.z = u*(1-u) *
// omega_mean;
}
double fake_damping = u*(1-u)*(md->damping);
mm->D_conductivity_diag.x += fake_damping;
mm->D_conductivity_diag.y += fake_damping;
mm->D_conductivity_diag.z += fake_damping;
}

// return material of the point p from the file (assumed already read)
Expand Down Expand Up @@ -1507,20 +1511,26 @@ static double get_cnd(meep::component c, const medium_struct *m) {
}
}

static bool has_conductivity(const material_type &md, meep::component c) {
medium_struct *mm;
if (is_medium(md, &mm) && get_cnd(c, mm)) return true;
if (md->which_subclass == material_data::MATERIAL_GRID &&
(get_cnd(c, &md->medium_1) || get_cnd(c, &md->medium_2) ||
md->damping != 0)) return true;
return false;
}

bool geom_epsilon::has_conductivity(meep::component c) {
medium_struct *mm;

FOR_DIRECTIONS(d) FOR_SIDES(b) {
if (cond[d][b].prof) return true;
}

for (int i = 0; i < geometry.num_items; ++i)
if (is_medium(geometry.items[i].material, &mm) && get_cnd(c, mm)) return true;

if (meep_geom::has_conductivity((material_type) geometry.items[i].material, c)) return true;
for (int i = 0; i < extra_materials.num_items; ++i)
if (is_medium(extra_materials.items[i], &mm) && get_cnd(c, mm)) return true;

return (is_medium(default_material, &mm) && get_cnd(c, mm) != 0);
if (meep_geom::has_conductivity((material_type) extra_materials.items[i], c)) return true;
return meep_geom::has_conductivity((material_type) default_material, c);
}

static meep::vec geometry_edge; // geometry_lattice.size / 2
Expand Down Expand Up @@ -2024,12 +2034,13 @@ material_type make_file_material(const char *eps_input_file) {
/******************************************************************************/
/* Material grid functions */
/******************************************************************************/
material_type make_material_grid(bool do_averaging, double beta, double eta) {
material_type make_material_grid(bool do_averaging, double beta, double eta, double damping) {
material_data *md = new material_data();
md->which_subclass = material_data::MATERIAL_GRID;
md->do_averaging = do_averaging;
md->beta = beta;
md->eta = eta;
md->damping = damping;
return md;
}

Expand Down
2 changes: 1 addition & 1 deletion src/meepgeom.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ void set_materials_from_geom_epsilon(meep::structure *s, geom_epsilon *geps,
material_type make_dielectric(double epsilon);
material_type make_user_material(user_material_func user_func, void *user_data, bool do_averaging);
material_type make_file_material(const char *eps_input_file);
material_type make_material_grid(bool do_averaging, double beta, double eta);
material_type make_material_grid(bool do_averaging, double beta, double eta, double damping);

vector3 vec_to_vector3(const meep::vec &pt);
meep::vec vector3_to_vec(const vector3 v3);
Expand Down

0 comments on commit cab86aa

Please sign in to comment.