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

Support uniform dimensions in TopologyDesignRegion #1987

Merged
merged 1 commit into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
- `TopologyDesignRegion` is now invariant in `z` by default and supports assigning dimensions along which a design should be uniform via `TopologyDesignRegion(uniform=(bool, bool, bool))`.

### Fixed
- Some validation fixes for design region.

Expand Down
12 changes: 12 additions & 0 deletions tests/test_plugins/test_invdes.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ def test_region_params():
_ = design_region.params_zeros


def test_region_uniform():
"""Test parameter shape for uniform dimensions"""
region = make_design_region()
shape = region.params_shape

test_region = region.updated_copy(uniform=(1, 1, 1))
assert test_region.params_shape == (1, 1, 1)

test_region = region.updated_copy(uniform=(1, 0, 1))
assert test_region.params_shape == (1, *shape[1:])


def test_region_penalties():
"""Test evaluation of penalties of a ``TopologyDesignRegion``."""

Expand Down
11 changes: 8 additions & 3 deletions tidy3d/plugins/invdes/region.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ class TopologyDesignRegion(DesignRegion):
"a value on the same order as the grid size.",
)

uniform: tuple[bool, bool, bool] = pd.Field(
(False, False, True),
title="Uniform",
description="Axes along which the design should be uniform. By default, the structure "
"is assumed to be uniform, i.e. invariant, in the z direction.",
)

transformations: typing.Tuple[TransformationType, ...] = pd.Field(
(),
title="Transformations",
Expand Down Expand Up @@ -166,12 +173,10 @@ def _check_params(params: anp.ndarray = None):
@property
def params_shape(self) -> typing.Tuple[int, int, int]:
"""Shape of the parameters array in (x, y, z), given the ``pixel_size`` and bounds."""
# rmin, rmax = np.array(self.geometry.bounds)
# lengths = rmax - rmin
side_lengths = np.array(self.size)
num_pixels = np.ceil(side_lengths / self.pixel_size)
# TODO: if the structure is infinite but the simulation is finite, need reduced bounds
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this TODO be removed?

More generally, in principle since we have the explicit uniform argument now, it probably doesn't make that much sense to set to single pixel if the design region is infinite. We should just span the entire simulation instead. Thoughts @yaugenst-flex @tylerflex ?

Copy link
Contributor Author

@yaugenst-flex yaugenst-flex Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think the problem with that was that the invdes region has no information about the simulation, i.e. it can't determine the array shape from inf bounds because it can't intersect with the simulation domain.
would require more changes to make that work somehow

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then maybe this should be a method of InverseDesign not a property of TopologyDesignRegion, or it should be a method that takes in a Simulation?

Not necessary to fix here but something to think about. It's just that the inf behavior would be kind of unexpected to me especially compared to other Tidy3D components which we often send to inf when we just want to span the whole domain.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More generally though it may be hard to come up with a simulation setup in which you want your topology region to span the whole domain.. Certainly seems fishy with PML, maybe in some cases with periodic boundaries?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah agree I don't think this would ever be correct with PMLs. periodic could make sense yeah

num_pixels[np.isinf(num_pixels)] = 1
num_pixels[np.logical_or(np.isinf(num_pixels), self.uniform)] = 1
return tuple(int(n) for n in num_pixels)

def _warn_deprecate_params(self):
Expand Down
Loading