-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Snapping points with optional coordinate
Add LayerRefinementSpec for automatic mesh refinement Shift _filter_structures_plane to geometry/utils.py Automatically sets dl_min if not set yet
- Loading branch information
1 parent
672cb64
commit 9b3cd40
Showing
10 changed files
with
1,343 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
"""Tests 2d corner finder.""" | ||
|
||
import numpy as np | ||
import pydantic.v1 as pydantic | ||
import pytest | ||
import tidy3d as td | ||
from tidy3d.components.grid.corner_finder import CornerFinderSpec | ||
from tidy3d.components.grid.grid_spec import GridRefinement, LayerRefinementSpec | ||
|
||
CORNER_FINDER = CornerFinderSpec() | ||
GRID_REFINEMENT = GridRefinement() | ||
LAYER_REFINEMENT = LayerRefinementSpec(axis=2, size=(td.inf, td.inf, 2)) | ||
LAYER2D_REFINEMENT = LayerRefinementSpec(axis=2, size=(td.inf, td.inf, 0)) | ||
|
||
|
||
def test_filter_collinear_vertex(): | ||
"""In corner finder, test that collinear vertices are filtered""" | ||
# 2nd and 3rd vertices are on a collinear line | ||
vertices = ((0, 0), (0.1, 0), (0.5, 0), (1, 0), (1, 1)) | ||
polyslab = td.PolySlab(vertices=vertices, axis=2, slab_bounds=[-1, 1]) | ||
structures = [td.Structure(geometry=polyslab, medium=td.PEC)] | ||
corners = CORNER_FINDER.corners(normal_axis=2, coord=0, structure_list=structures) | ||
assert len(corners) == 3 | ||
|
||
# if angle threshold is 0, collinear vertex will not be filtered | ||
corner_finder = CORNER_FINDER.updated_copy(angle_threshold=0) | ||
corners = corner_finder.corners(normal_axis=2, coord=0, structure_list=structures) | ||
assert len(corners) == 5 | ||
|
||
|
||
def test_filter_nearby_vertex(): | ||
"""In corner finder, test that vertices that are very close are filtered""" | ||
# filter duplicate vertices | ||
vertices = ((0, 0), (0, 0), (1e-4, -1e-4), (1, 0), (1, 1)) | ||
polyslab = td.PolySlab(vertices=vertices, axis=2, slab_bounds=[-1, 1]) | ||
structures = [td.Structure(geometry=polyslab, medium=td.PEC)] | ||
corners = CORNER_FINDER.corners(normal_axis=2, coord=0, structure_list=structures) | ||
assert len(corners) == 4 | ||
|
||
# filter very close vertices | ||
corner_finder = CORNER_FINDER.updated_copy(distance_threshold=2e-4) | ||
corners = corner_finder.corners(normal_axis=2, coord=0, structure_list=structures) | ||
assert len(corners) == 3 | ||
|
||
|
||
def test_gridrefinement(): | ||
"""Test GradRefinement is working as expected.""" | ||
|
||
# no override grid step information | ||
with pytest.raises(pydantic.ValidationError): | ||
_ = GridRefinement(dl=None, refinement_factor=None) | ||
|
||
# generate override structures for z-axis | ||
center = [None, None, 0] | ||
grid_size_in_vaccum = 1 | ||
structure = GRID_REFINEMENT.override_structure(center, grid_size_in_vaccum) | ||
assert not structure.shadow | ||
for axis in range(2): | ||
assert structure.dl[axis] is None | ||
assert structure.geometry.size[axis] == td.inf | ||
dl = grid_size_in_vaccum / GRID_REFINEMENT.refinement_factor | ||
assert np.isclose(structure.dl[2], dl) | ||
assert np.isclose(structure.geometry.size[2], dl * GRID_REFINEMENT.num_cells) | ||
|
||
# explicitly define step size in refinement region that is smaller than that of refinement_factor | ||
dl = 0.01 | ||
grid_refinement = GRID_REFINEMENT.updated_copy(dl=dl) | ||
structure = grid_refinement.override_structure(center, grid_size_in_vaccum) | ||
for axis in range(2): | ||
assert structure.dl[axis] is None | ||
assert structure.geometry.size[axis] == td.inf | ||
assert np.isclose(structure.dl[2], dl) | ||
assert np.isclose(structure.geometry.size[2], dl * GRID_REFINEMENT.num_cells) | ||
|
||
|
||
def test_layerrefinement(): | ||
"""Test LayerRefinementSpec is working as expected.""" | ||
|
||
# size along axis must be inf | ||
with pytest.raises(pydantic.ValidationError): | ||
_ = LayerRefinementSpec(axis=0, size=(td.inf, 0, 0)) | ||
|
||
# classmethod | ||
for axis in range(3): | ||
layer = LayerRefinementSpec.from_unbounded_layer(axis=axis, bounds=(0, 1)) | ||
assert layer.center[axis] == 0.5 | ||
assert layer.size[axis] == 1 | ||
assert layer.size[(axis + 1) % 3] == td.inf | ||
assert layer.size[(axis + 2) % 3] == td.inf | ||
|
||
layer = LayerRefinementSpec.from_bounds(axis=axis, rmin=(0, 0, 0), rmax=(1, 2, 3)) | ||
|
||
with pytest.raises(pydantic.ValidationError): | ||
_ = LayerRefinementSpec.from_unbounded_layer(axis=axis, bounds=(0, td.inf)) | ||
with pytest.raises(pydantic.ValidationError): | ||
_ = LayerRefinementSpec.from_unbounded_layer(axis=axis, bounds=(td.inf, 0)) | ||
with pytest.raises(pydantic.ValidationError): | ||
_ = LayerRefinementSpec.from_unbounded_layer(axis=axis, bounds=(-td.inf, 0)) | ||
with pytest.raises(pydantic.ValidationError): | ||
_ = LayerRefinementSpec.from_unbounded_layer(axis=axis, bounds=(1, -1)) | ||
|
||
|
||
def test_layerrefinement_inplane_inside(): | ||
# inplane inside | ||
layer = LayerRefinementSpec.from_unbounded_layer(axis=2, bounds=(0, 1)) | ||
assert layer._inplane_inside([3e3, 4e4]) | ||
layer = LayerRefinementSpec(axis=1, size=(1, 0, 1)) | ||
assert layer._inplane_inside([0, 0]) | ||
assert not layer._inplane_inside([2, 0]) | ||
|
||
|
||
# def test_layerrefinement_snapping_points(): | ||
# """Test snapping points for LayerRefinementSpec is working as expected.""" | ||
|
||
# # snapping points for layer bounds | ||
# points = LAYER2D_REFINEMENT._snapping_points_along_axis | ||
# assert len(points) == 1 | ||
# assert points[0] == (None, None, 0) | ||
|
||
# points = LAYER_REFINEMENT._snapping_points_along_axis | ||
# assert len(points) == 2 | ||
# assert points[0] == (None, None, -1) | ||
# assert points[1] == (None, None, 1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.