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

Simulation runs but not if I add_flux, get 'NoneType' object has no attribute '__swig_destroy__' #2967

Open
poutine-dejeuner opened this issue Jan 17, 2025 · 3 comments

Comments

@poutine-dejeuner
Copy link

poutine-dejeuner commented Jan 17, 2025

I am attempting to adapt the meepcon tutorial with mode decomposition. The simulation as it is created can be run without problem but as soon as I add add_flux, or add_mode_monitor to the simulation, I get this error

tutorial3.py 132 <module>
sim.run(until_after_sources=mp.stop_when_fields_decayed(

simulation.py 4443 run
self._evaluate_dft_objects()

simulation.py 2889 _evaluate_dft_objects
dft.swigobj = dft.func(*dft.args)

simulation.py 3416 _add_flux
return self._add_fluxish_stuff(

simulation.py 3718 _add_fluxish_stuff
vol_list.__swig_destroy__(vol_list)

AttributeError:
'NoneType' object has no attribute '__swig_destroy__'

With add_mode_monitor, the error is different but is happening at the same place

tutorial3.py 158 <module>
sim.run(until_after_sources=mp.stop_when_fields_decayed(

simulation.py 4443 run
self._evaluate_dft_objects()

simulation.py 2889 _evaluate_dft_objects
dft.swigobj = dft.func(*dft.args)

simulation.py 3442 _add_mode_monitor
raise ValueError(

ValueError:
add_mode_monitor expected just one ModeRegion. Got 0

The code is below, everything above line 117 is unchanged from the original tutorial

import autograd.numpy as npa
import numpy as np
import meep.adjoint as mpa
import meep as mp

seed = 240
np.random.seed(seed)
mp.verbosity(0)
Si = mp.Medium(index=3.4)
SiO2 = mp.Medium(index=1.44)

waveguide_width = 0.5  # (μm)
design_region_width = 2.5  # (μm)
design_region_height = 2.5  # (μm)
arm_separation = 1.0  # (μm) distance between arms center to center
waveguide_length = 0.5  # (μm)
pml_size = 1.0  # (μm)
resolution = 20  # (pixels/μm)

minimum_length = 0.09  # (μm)
eta_e = 0.75
filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length, eta_e)  # (μm)
eta_i = 0.5
eta_d = 1-eta_e
design_region_resolution = int(4*resolution)  # (pixels/μm)
frequencies = 1/np.linspace(1.5, 1.6, 5)  # (1/μm)

Nx = int(design_region_resolution*design_region_width)
Ny = int(design_region_resolution*design_region_height)

volume = mp.Volume(center=mp.Vector3(),
                   size=mp.Vector3(design_region_width,
                   design_region_height))
design_variables = mp.MaterialGrid(mp.Vector3(Nx, Ny), SiO2, Si)
design_region = mpa.DesignRegion(design_variables,
                                 volume=volume)

Sx = 2*pml_size + 2*waveguide_length + design_region_width  # cell size in X
Sy = 2*pml_size + design_region_height + 0.5  # cell size in Y
cell_size = mp.Vector3(Sx, Sy)

pml_layers = [mp.PML(pml_size)]

fcen = 1/1.55
width = 0.2
fwidth = width * fcen
source_center = [-Sx/2 + pml_size + waveguide_length/3, 0, 0]
source_size = mp.Vector3(0, 2, 0)
kpoint = mp.Vector3(1, 0, 0)
src = mp.GaussianSource(frequency=fcen, fwidth=fwidth)
source = [mp.EigenModeSource(src,
                             eig_band=1,
                             direction=mp.NO_DIRECTION,
                             eig_kpoint=kpoint,
                             size=source_size,
                             center=source_center,
                             eig_parity=mp.ODD_Z+mp.EVEN_Y)]

geometry = [
    # left waveguide
    mp.Block(center=mp.Vector3(x=-Sx/4), material=Si,
             size=mp.Vector3(Sx/2+1, waveguide_width, 0)),
    # top right waveguide
    mp.Block(center=mp.Vector3(x=Sx/4, y=arm_separation/2), material=Si,
             size=mp.Vector3(Sx/2+1, waveguide_width, 0)),
    # bottom right waveguide
    mp.Block(center=mp.Vector3(x=Sx/4, y=-arm_separation/2), material=Si,
             size=mp.Vector3(Sx/2+1, waveguide_width, 0)),
    mp.Block(center=design_region.center,
             size=design_region.size, material=design_variables)
]

def mapping(x, eta, beta):
    # up-down symmetry
    x = (npa.fliplr(x.reshape(Nx, Ny)) + x.reshape(Nx, Ny))/2

    # filter
    filtered_field = mpa.conic_filter(x, filter_radius, design_region_width,
                                      design_region_height,
                                      design_region_resolution)

    # projection
    projected_field = mpa.tanh_projection(filtered_field, beta, eta)

    # interpolate to actual materials
    return projected_field.flatten()

# Modifications start here
#--------------------------------------------------
# Flux test
map = mapping(np.random.rand(Nx, Ny), 0.5, 256)
sim = mp.Simulation(cell_size=cell_size,
                    boundary_layers=pml_layers,
                    geometry=geometry,
                    sources=source,
                    symmetries=[mp.Mirror(direction=mp.Y)],
                    default_material=SiO2,
                    resolution=resolution)
design_region.update_design_parameters(map)
mon_pt = source_center
mon_pt = mp.Vector3(*mon_pt)
size = mp.Vector3(y=1.5)
fluxregion = mp.FluxRegion(center=mon_pt, size=size)
flux = sim.add_flux(fcen, 0, 1, FluxRegions=fluxregion)
sim.run(until_after_sources=mp.stop_when_fields_decayed(
        50, mp.Ez, mp.Vector3(*source_center), 1e-9))
res = sim.get_eigenmode_coefficients(flux, [1],
                                     eig_parity=mp.ODD_Z+mp.EVEN_Y)
source_coeffs = res.alpha

#Mode_mon test
source = [mp.EigenModeSource(src,
                             eig_band=1,
                             direction=mp.NO_DIRECTION,
                             eig_kpoint=kpoint,
                             size=source_size,
                             center=source_center)]
sim = mp.Simulation(cell_size=cell_size,
                    boundary_layers=pml_layers,
                    geometry=geometry,
                    sources=source,
                    symmetries=[mp.Mirror(direction=mp.Y)],
                    default_material=SiO2,
                    resolution=resolution)
design_region.update_design_parameters(map)
mon_pt = [-Sx/2 + pml_size + 2*waveguide_length/3 , 0, 0]
mon_pt = mp.Vector3(*mon_pt)
size = mp.Vector3(y=1.5)
fluxregion = mp.FluxRegion(center=mon_pt, size=size)
mon = sim.add_mode_monitor(fcen, 0, 1, FluxRegions=fluxregion)
sim.run(until_after_sources=mp.stop_when_fields_decayed(
        50, mp.Ez, mp.Vector3(*source_center), 1e-9))
res = sim.get_eigenmode_coefficients(mon, [1])
source_coeffs = res.alpha
@poutine-dejeuner
Copy link
Author

poutine-dejeuner commented Jan 17, 2025

The problem is actually with simulation.add_flux. If an argument is passed as a keyword argument, the function does not execute properly. For example in the code above, add_flux was called like
sim.add_flux(fcen, 0, 1, Fluxregion=fluxregion) which caused the
'NoneType' object has no attribute '__swig_destroy__' error.

@oskooi
Copy link
Collaborator

oskooi commented Jan 18, 2025

The problem is actually with simulation.add_flux. If an argument is passed as a keyword argument, the function does not execute

This is the intended behavior. In the function signature for add_flux, FluxRegion is a positional argument not a keyword argument.

@poutine-dejeuner
Copy link
Author

Yeah, I get it. I was just not expecting that behavior. In most libraries I use I dont have any problem accessing arguments as positional or keyword.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants