POWER SPLITTER DESIGN CHANGE Issues: **ResolutionError**: Cannot neatly resolve quantity (unyt_quantity(7040, 'nm')) at given resolution (unyt_quantity(100, 'nm'))
Hello All,
I'm trying to scale the power splitter problem to "mmWave frequencies". From what I understand, the current design region is 1.6 um x 1.6 um, but I need to modify this to better suit my target frequencies.
However, when I try changing the design, I keep running into errors like:
- FrozenIssues.
-
ValueError: The
design_vararray with shape (500, 500) does not fit into thedestinationarray with shape (344, 280) - ResolutionError: Cannot neatly resolve quantity (unyt_quantity(7040, 'nm')) at given resolution (unyt_quantity(100, 'nm')) ---> this error has been repeating irrespective of changes I made.
I'm not sure what's causing these issues. I'd appreciate any insights on how to properly scale the design without running into these errors.
Thanks in advance.
Hi @VikramReddy-Anapana , can you paste the code that is causing you issues?
- I tried to modify the existing Power_splitter ---> attempted to increase the design region by a little ---> ValueError
- I tried to scale it to mmWave frequencies ---> ResolutionError
Modified_DefaultPOWER_SPLITTER_Invrs_gym.txt
import jax import jax.numpy as jnp import matplotlib.pyplot as plt from skimage import measure import unyt as u from invrs_gym import challenges from invrs_gym.challenges.ceviche import defaults from totypes import types
Define the desired design extent and grid spacing
Setting design extent in nm
desired_design_extent = u.unyt_array([5000, 5000], u.nm)
Set grid spacing to 10 nm
grid_spacing = u.unyt_quantity(10, u.nm)
Adjust the design extent to be divisible by grid spacing
adjusted_design_extent = u.unyt_array( [ round(desired_design_extent[0].value / grid_spacing.value) * grid_spacing.value, round(desired_design_extent[1].value / grid_spacing.value) * grid_spacing.value, ], u.nm, )
print("Adjusted Design Extent:", adjusted_design_extent)
Define the new grid shape based on the adjusted design extent
grid_shape = (int(adjusted_design_extent[0].value // grid_spacing.value), int(adjusted_design_extent[1].value // grid_spacing.value))
print("New grid shape:", grid_shape)
Create the custom wdm_spec using the adjusted design extent
custom_wdm_spec = defaults.wdm_spec( design_extent_ij=adjusted_design_extent, design_wg_offset=u.unyt_quantity(120, u.nm), intended_sim_resolution=grid_spacing, )
Custom density initializer to modify waveguide and middle box layout
def custom_density_initializer(key, density_array): new_shape = (int(adjusted_design_extent[0].value // grid_spacing.value), int(adjusted_design_extent[1].value // grid_spacing.value))
# Create a new design array with the desired pattern
density_array = jnp.ones(new_shape)
middle_box_start_x, middle_box_end_x = 120, 180
middle_box_start_y, middle_box_end_y = 100, 150
if middle_box_end_x <= new_shape[0] and middle_box_end_y <= new_shape[1]:
density_array = density_array.at[middle_box_start_x:middle_box_end_x, middle_box_start_y:middle_box_end_y].set(1)
# Return the density array for the custom design
return types.Density2DArray(
array=density_array,
lower_bound=0.0,
upper_bound=1.0,
fixed_solid=None,
fixed_void=None,
)
Create the challenge with the custom density initializer
challenge = challenges.ceviche_power_splitter( density_initializer=custom_density_initializer )
Applying the updated design region spec to the challenge
Applying custom design region
challenge.component.ceviche_model.spec = custom_wdm_spec
Initialize parameters --> for the updated challenge
default_params = challenge.component.init(jax.random.PRNGKey(0))
def plot_params(ax, params, contour_levels=(0.5,)): density = challenge.component.ceviche_model.density(params.array) im = ax.imshow(1 - density, cmap="gray") im.set_clim(-2, 1) for level in contour_levels: for c in measure.find_contours(density, level=level): plt.plot(c[:, 1], c[:, 0], 'k') _ = ax.axis(False)
plt.figure(figsize=(8, 6)) plot_params(ax=plt.subplot(111), params=default_params, contour_levels=(0.6, 0.6)) plt.show()
Adjusted Design Extent: [5000 5000] nm New grid shape: (500, 500)
ValueError Traceback (most recent call last) Cell In[39], line 85 82 _ = ax.axis(False) 84 plt.figure(figsize=(8, 6)) ---> 85 plot_params(ax=plt.subplot(111), params=default_params, contour_levels=(0.6, 0.6)) 86 plt.show()
Cell In[39], line 76, in plot_params(ax, params, contour_levels) 75 def plot_params(ax, params, contour_levels=(0.5,)): ---> 76 density = challenge.component.ceviche_model.density(params.array) 77 im = ax.imshow(1 - density, cmap="gray") 78 im.set_clim(-2, 1)
File ~\anaconda3\Lib\site-packages\ceviche_challenges\model_base.py:227, in Model.density(self, design_variable) 218 if design_variable.shape != self.design_variable_shape: 219 raise ValueError( 220 'Invalid design variable shape. Got ({}, {},) but expected ({}, {},)' 221 .format( (...) 225 self.design_variable_shape[1], 226 )) --> 227 return primitives.insert_design_variable( 228 self.transform_design_variable(design_variable), 229 self.density_bg, 230 self.design_region_coords, 231 )
File ~\anaconda3\Lib\site-packages\autograd\tracer.py:48, in primitive.
File ~\anaconda3\Lib\site-packages\ceviche_challenges\primitives.py:44, in insert_design_variable(design_var, destination, coords)
41 (x_min, y_min, x_max, y_max) = coords
42 if (design_var.shape[0] > destination.shape[0] or
43 design_var.shape[1] > destination.shape[1]):
---> 44 raise ValueError(
45 'The design_var array with shape {} does not fit into the '
46 'destination array with shape {}'.format(design_var.shape,
47 destination.shape))
48 if not np.all([coord > 0 for coord in coords]):
49 raise ValueError('All values in coord must be positive')
ValueError: The design_var array with shape (500, 500) does not fit into the destination array with shape (344, 280)
------------------------------ for mmWave specifications code ----------------------------------------------------------------- File ~\anaconda3\Lib\site-packages\ceviche_challenges\units.py:77, in resolve(v, resolution) 75 resolved = _resolve_or_none(v, resolution) 76 if resolved is None: ---> 77 raise ResolutionError( 78 "Cannot neatly resolve quantity (%r) at given resolution (%r)." % 79 (v, resolution)) 80 else: 81 return resolved
ResolutionError: Cannot neatly resolve quantity (unyt_quantity(403040, 'nm')) at given resolution (unyt_quantity(10000, 'nm')).
Please take a look at the attached code.
Sorry, can you pare down your code to the bare minimum which exhibits the problem, and then paste it in a code block? See here for help: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks
mmwave_wavelengths_nm = [10710000.0, 5000000.0]
mmwave_grid_spacing_nm = 10000
design_extent = u.unyt_array([400000, 400000], u.nm)
if (design_extent[0] % mmwave_grid_spacing_nm != 0) or (design_extent[1] % mmwave_grid_spacing_nm != 0):
raise ValueError("Design extent must be a multiple of grid spacing!")
custom_wdm_spec = defaults.wdm_spec(
design_extent_ij=design_extent,
design_wg_offset=u.unyt_quantity(1200, u.nm),
intended_sim_resolution=u.unyt_quantity(mmwave_grid_spacing_nm, u.nm),
)
challenge = challenges.ceviche_power_splitter(
grid_spacing_nm=mmwave_grid_spacing_nm,
wavelengths_nm=mmwave_wavelengths_nm,
)
challenge.component.ceviche_model.spec = custom_wdm_spec
Can you please provide the full code that reproduces the problem? So that I can just copy and paste it in an empty notebook and reproduce the issue.
Please see the following full code
import unyt as u
from invrs_gym import challenges
from invrs_gym.challenges.ceviche import defaults
import jax.random as jax_random
import jax.numpy as jnp
from totypes import types
import matplotlib.pyplot as plt
from skimage import measure
# mmWave parameters
mmwave_wavelengths_nm = [10710000.0, 5000000.0]
# Grid spacing in nanometers (10 um)
mmwave_grid_spacing_nm = 10000
# custom wdm_spec
custom_wdm_spec = defaults.wdm_spec(
design_extent_ij=u.unyt_array([400000, 400000], u.nm),
design_wg_offset=u.unyt_quantity(1200, u.nm),
intended_sim_resolution=mmwave_grid_spacing_nm * u.nm
)
# custom density initializer --> fix shape mismatch issues
def custom_density_initializer(key, density_array):
new_shape = (40, 40)
fixed_solid = jnp.ones(new_shape, dtype=bool) if density_array.fixed_solid is not None else None
fixed_void = jnp.zeros(new_shape, dtype=bool) if density_array.fixed_void is not None else None
return types.Density2DArray(
array=jnp.ones(new_shape),
lower_bound=density_array.lower_bound,
upper_bound=density_array.upper_bound,
fixed_solid=fixed_solid,
fixed_void=fixed_void,
)
challenge_mmwave = challenges.ceviche_power_splitter(
grid_spacing_nm=mmwave_grid_spacing_nm,
wavelengths_nm=mmwave_wavelengths_nm,
density_initializer=custom_density_initializer,
)
# Override the default spec
challenge_mmwave.component.ceviche_model.spec = custom_wdm_spec
default_params_mmwave = challenge_mmwave.component.init(jax_random.PRNGKey(0))
def plot_params(ax, params, contour_levels=(0.5,)):
density = challenge_mmwave.component.ceviche_model.density(params.array)
im = ax.imshow(1 - density, cmap="gray")
im.set_clim(-2, 1)
for level in contour_levels:
for c in measure.find_contours(density, level=level):
ax.plot(c[:, 1], c[:, 0], 'k')
_ = ax.axis(False)
plt.figure(figsize=(8, 6))
plot_params(ax=plt.subplot(111), params=default_params_mmwave, contour_levels=(0.4, 0.6))
plt.show()
OK, the issue is that there are several parameters which define the geometry, and you are adjusting only some of them. I suggest taking a look at the ceviche.defaults module to see how the spec is constructed, and then make your own constructor where all the parameters are adjusted.
Apologies, I didn’t notice your response earlier. I went through defaults.py, but it’s still unclear how to use it to scale the structure for mmWave frequencies. Could you please guide me on the correct approach? I have explored various options but haven’t found a solution.
I think you need to implement your own version of this function:
https://github.com/invrs-io/gym/blob/4758d3ae29bcc088b086bc8fb0f97dea2e4d1ab4/src/invrs_gym/challenges/ceviche/defaults.py#L184-L264
Please create a new issue if you have new questions.