fdtdx.SubpixelSmoothedProjection#
- class fdtdx.SubpixelSmoothedProjection(*, projection_midpoint=0.5)[source]#
Bases:
SameShapeTypeParameterTransformThis function is adapted from the Meep repository: NanoComp/meep
The details of this projection are described in the paper by Alec Hammond: https://arxiv.org/pdf/2503.20189
Project using subpixel smoothing, which allows for β→∞. This technique integrates out the discontinuity within the projection function, allowing the user to smoothly increase β from 0 to ∞ without losing the gradient. Effectively, a level set is created, and from this level set, first-order subpixel smoothing is applied to the interfaces (if any are present).
In order for this to work, the input array must already be smooth (e.g. by filtering).
While the original approach involves numerical quadrature, this approach performs a “trick” by assuming that the user is always infinitely projecting (β=∞). In this case, the expensive quadrature simplifies to an analytic fill-factor expression. When to use this fill factor requires some careful logic.
For one, we want to make sure that the user can indeed project at any level (not just infinity). So in these cases, we simply check if in interface is within the pixel. If not, we revert to the standard filter plus project technique.
If there is an interface, we want to make sure the derivative remains continuous both as the interface leaves the cell, and as it crosses the center. To ensure this, we need to account for the different possibilities.
Notes
The call method requires a beta parameter as a keyword argument passed to the parameter transformation
Quick Reference#
Attributes
Methods
Attributes#
-
SubpixelSmoothedProjection.projection_midpoint:
float# midpoint of the tanh projection. Defaults to 0.5
Methods#
- SubpixelSmoothedProjection.aset(attr_name, val, create_new_ok=False)#
Sets an attribute of this class. In contrast to the classical .at[].set(), this method updates the class attribute directly and does not only operate on jax pytree leaf nodes. Instead, replaces the full attribute with the new value.
The attribute can either be the attribute name of this class, or for nested classes it can also be the attribute name of a class, which itself is an attribute of this class. The syntax for this operation could look like this: “a->b->[0]->[‘name’]”. Here, the current class has an attribute a, which has an attribute b, which is a list, which we index at index 0, which is an element of type dictionary, which we index using the dictionary key ‘name’.
Note that dictionary keys cannot contain square brackets or single quotes (even if they are escaped).
- Parameters:
attr_name (str) – Name of attribute to set
val (Any) – Value to set the attribute to
create_new_ok (bool, optional) – If false (default), throw an error if the attribute does not exist. If true, creates a new attribute if the attribute name does not exist yet.
- Returns:
Updated instance with new attribute value
- Return type:
Self
- SubpixelSmoothedProjection.get_class_fields()#
- Return type:
list[TreeClassField]
- SubpixelSmoothedProjection.get_input_shape(output_shape)#
- Return type:
dict[str,tuple[int,...]]
- SubpixelSmoothedProjection.get_output_type(input_type)#
- Return type:
dict[str,ParameterType]
- SubpixelSmoothedProjection.get_public_fields()#
- Return type:
list[TreeClassField]
- SubpixelSmoothedProjection.init_module(config, materials, matrix_voxel_grid_shape, single_voxel_size, output_shape)#
- Return type:
Self
- SubpixelSmoothedProjection.init_type(input_type)#
- Return type:
Self
If you find any errors in the documentation, please report them in the Github Issues!