-
Notifications
You must be signed in to change notification settings - Fork 49
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
Automatical mesh refinement in layered structures #2113
base: pre/2.8
Are you sure you want to change the base?
Conversation
263c36d
to
2cabc71
Compare
7fd5daa
to
e2369f9
Compare
e2369f9
to
9b3cd40
Compare
There are still a few items to be done, but they are likely to be minor. You are welcome to start reviewing now, e.g. the general flow, naming, etc. |
9b3cd40
to
e32a9fd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Just some minor comments so far
0c4c009
to
701c33c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like impressive work, note I mostly reviewed the usage rather than the low level since there seem to be many eyes on it.
title="Minimal Number Of Steps Along Axis", | ||
description="If not ``None`` and the thickness of the layer is nonzero, set minimal " | ||
"number of steps discretizing the layer thickness.", | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is not always enforced as it could lead to very small step size for thin layers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will not be enforced if dl_min
is set. However, if dl_min=0/None
, we'll internally set a dl_min
based on material response and those refinement factors, meaning that it will be enforced for thin layers. In a way, that is expected because in many classes of simulation you'll want to resolve the thin layer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I can see how that's probably what's needed in RF. However one thing I'm a little wary about is if people put some arbitrary small thickness for layers that they want to say are "very thin". Like ideally they should put 0 thickness and use a 2D medium but they may try instead to put like a 10nm plate with a layer refinement because they don't know better, and then get a giant number of grid cells and time steps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not easy to differentiate between the 2 scenarios (intended vs. non-intended refinement). Maybe we could issue a warning if the simulation is in optical frequencies, but I'm not super convinced it would be useful, since we already have validations in place for the number of time steps (and cost)…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like ideally they should put 0 thickness and use a 2D medium but they may try instead to put like a 10nm plate with a layer refinement because they don't know better
Probably low chance, as now by default, thickness will not be refined, and we only snap one bound to the grid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good. From what I can tell, we can use the interface easily enough to build automatic meshes for RF. It would be good to have a more clear understanding of the bounds_refinement
and corner_refinement
fields, i.e., how exactly do they work (maybe with an illustration?)
Am I understanding it correctly that the bounds_refinement
will create GridRefinement.num_cells
at both bounds? Are the cells inside the layer or outside the layer?
And for corner_refinement
, where are the cells created? Inside or outside the polygon?
When a metal layer is very thin and we do not want to mesh both sides of the metal, so as to enable a larger delta t, would it be possible to automatically choose the best interface (top or bottom) for placing a grid boundary. Consider the case attached. Is it correct that placing a grid boundary along the black line would be more economical/accurate than at the red line, since it would reduce the number of times a control volume contains >2 materials? (Near the metal corners is where I am thinking) |
No, that's perfect! |
When the thickness of metal layer is much thinner than the Yee cell size, it looks chances are equal with black/red line? Could you share a figure on the control volume on this (let's take this discussion off-line)? Separately, it is interesting to study the behavior of conformal meshing in a simple microstrip when the grid line is placed at black/red. I think they will lead to slightly different averaged permittivity/permeability, as the red line go through 2 materials, while black 3 materials. |
This PR is pretty great! I am still playing around with all of the options to understand what they are doing. I found perhaps one non-ideal scenario. When I used a default Could it be because the two |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I said, this is great! Still trying it on examples, but I think I found one bug.
0e7a77e
to
b84c400
Compare
Could you share the code here so that I can reproduce? |
…cture Snapping points with optional coordinate Shift _filter_structures_plane to geometry/utils.py Automatically sets dl_min if not set yet Revise and improve plot_grid visualization Change linestyle for override structures in plot_grid
c8c7cd6
to
edde033
Compare
(associated with https://github.com/flexcompute/tidy3d-core/issues/509)
Background
In many applications, structures are built layer by layer. Materials can be considered uniform along the normal axis.
In 2D, we can simply use shapely to find out corners. With corners, we can have boundaries (or edges). With the two, we can automatically generate snapping points and refinement mesh override structures.
Features
GridRefinement
class here for local mesh refinement. It is to make it easier to generate mesh override structures based on the number of grid cells and refined grid size. The refined grid size can be defined by either the refinement factor w.r.t. vacuum grid size, or grid size directly.LayerRefinementSpec
that defines the layer (it can be bounded on the inplane dimensions so that corners outside the bound are discarded) and various mesh generation specs.layer_refinement_specs
field toGridSpec
. The final snapping points and override structures will be internal ones + user supplied ones. The internal ones are generated byLayerRefinementSpec
.dl_min
is not set by the user, we'll automatically generate a value based on the structures, simulation domain size, and layer_specs.Examples
If we are fine with default meshing specs,
layer_refinement_spec
can be easily defined. First, let's defined a layer that is unbounded perpendicular to the normal axis:and grid_spec,
grid_spec = td.GridSpec.auto(wavelength=wavelength, layer_refinement_specs=[layer])
Consider a patch antenna but we drill a big hole on the left, with the above grid_spec, we get
As you can see, metal corners are all identified, and snapping points are applied at those corners. Small mesh refinement structures are placed at corners, too, so that the mesh is denser near those singularities.
Sometimes, you only want refine a portion of the layer, as the other portion is not affecting the simulation as much. E.g., we only want to refine the feeding region,
Tasks
Major
dl_min
if not set yet:Minor
None
as coordinate, so that it's not snapped along that axis. Now snapping point is of type CoordinateOptional. In visualization, snapping points will besnapping line
if one of the inplane coordinate isNone
._filter_structures_plane
to geometry/utils.py, as it'll be used in 2d corner finder.Miscellaneous
None