Beispiel #1
0
def main(args):

    n = 3.4     # index of waveguide
    w = 1       # width of waveguide
    r = 1       # inner radius of ring
    pad = 4     # padding between waveguide and edge of PML
    dpml = 32    # thickness of PML

    sr = r + w + pad + dpml  # radial size (cell is from 0 to sr)
    dimensions = mp.CYLINDRICAL
    cell = mp.Vector3(sr, 0, 0)

    # in cylindrical coordinates, the phi (angular) dependence of the fields
    # is given by exp(i m phi), where m is given by:
    m = args.m

    geometry = [mp.Block(center=mp.Vector3(r + (w / 2)),
                         size=mp.Vector3(w, mp.inf, mp.inf),
                         material=mp.Medium(index=n))]

    pml_layers = [mp.PML(dpml)]
    resolution = 20

    # If we don't want to excite a specific mode symmetry, we can just
    # put a single point source at some arbitrary place, pointing in some
    # arbitrary direction.  We will only look for Ez-polarized modes.

    fcen = args.fcen  # pulse center frequency
    df = args.df      # pulse frequency width
    sources = [mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                         component=mp.Ez,
                         center=mp.Vector3(r + 0.1))]

    # note that the r -> -r mirror symmetry is exploited automatically

    sim = mp.Simulation(cell_size=cell,
                        geometry=geometry,
                        boundary_layers=pml_layers,
                        resolution=resolution,
                        sources=sources,
                        dimensions=dimensions,
                        m=m)

    sim.run(mp.after_sources(mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)),
            until_after_sources=200)

    # Output fields for one period at the end.  (If we output
    # at a single time, we might accidentally catch the Ez field when it is
    # almost zero and get a distorted view.)  We'll append the fields
    # to a file to get an r-by-t picture.  We'll also output from -sr to -sr
    # instead of from 0 to sr.
    sim.run(mp.in_volume(mp.Volume(center=mp.Vector3(), size=mp.Vector3(2 * sr)),
                         mp.at_beginning(mp.output_epsilon),
                         mp.to_appended("ez", mp.at_every(1 / fcen / 20, mp.output_efield_z))),
            until=1 / fcen)
Beispiel #2
0
    def test_eigsrc_kz(self):
        resolution = 30  # pixels/um
        cell_size = mp.Vector3(14, 14)
        pml_layers = [mp.PML(thickness=2)]

        geometry = [
            mp.Block(center=mp.Vector3(),
                     size=mp.Vector3(mp.inf, 1, mp.inf),
                     material=mp.Medium(epsilon=12))
        ]

        fsrc = 0.3  # frequency of eigenmode or constant-amplitude source
        bnum = 1  # band number of eigenmode
        kz = 0.2  # fixed out-of-plane wavevector component

        sources = [
            mp.EigenModeSource(src=mp.GaussianSource(fsrc, fwidth=0.2 * fsrc),
                               center=mp.Vector3(),
                               size=mp.Vector3(y=14),
                               eig_band=bnum,
                               eig_parity=mp.EVEN_Y,
                               eig_match_freq=True)
        ]

        sim = mp.Simulation(cell_size=cell_size,
                            resolution=resolution,
                            boundary_layers=pml_layers,
                            sources=sources,
                            geometry=geometry,
                            symmetries=[mp.Mirror(mp.Y)],
                            k_point=mp.Vector3(z=kz),
                            special_kz=True)

        tran = sim.add_flux(
            fsrc, 0, 1,
            mp.FluxRegion(center=mp.Vector3(x=5), size=mp.Vector3(y=14)))
        sim.run(until_after_sources=50)
        res = sim.get_eigenmode_coefficients(tran, [1, 2],
                                             eig_parity=mp.EVEN_Y)

        total_flux = mp.get_fluxes(tran)[0]
        mode1_flux = abs(res.alpha[0, 0, 0])**2
        mode2_flux = abs(res.alpha[1, 0, 0])**2

        mode1_frac = 0.99
        self.assertGreater(mode1_flux / total_flux, mode1_frac)
        self.assertLess(mode2_flux / total_flux, 1 - mode1_frac)

        d = 3.5
        ez1 = sim.get_field_point(mp.Ez, mp.Vector3(2.3, -5.7, 4.8))
        ez2 = sim.get_field_point(mp.Ez, mp.Vector3(2.3, -5.7, 4.8 + d))
        ratio_ez = ez2 / ez1
        phase_diff = cmath.exp(1j * 2 * cmath.pi * kz * d)
        self.assertAlmostEqual(ratio_ez.real, phase_diff.real, places=10)
        self.assertAlmostEqual(ratio_ez.imag, phase_diff.imag, places=10)
Beispiel #3
0
def geo2D_ellipsoid_pc(n_matrix,
                       n_substrate,
                       film_xsize,
                       substrate_xsize,
                       film_ysize,
                       n_layers,
                       film_base_x,
                       ellipsex,
                       ellipsey,
                       ellipse_spacing,
                       layer_offset,
                       ellipse_x_offset=0):
    """
    Generate a layered structure with spheres. Within a layer the spheres are hexagonally packed
    """
    matrix_block = mp.Block(size=mp.Vector3(film_xsize, film_ysize, 1e20),
                            center=mp.Vector3(film_base_x - film_xsize / 2),
                            material=mp.Medium(epsilon=n_matrix**2))

    si_block = mp.Block(size=mp.Vector3(substrate_xsize, film_ysize, 1e20),
                        center=mp.Vector3(film_base_x + substrate_xsize / 2, 0,
                                          0),
                        material=mp.Medium(epsilon=n_substrate**2))

    print(n_substrate)

    spheres = [si_block, matrix_block]
    #spheres = []

    for n in range(n_layers):
        x = film_base_x - film_xsize * (n + 0.5) / n_layers + ellipse_x_offset
        offset = layer_offset[n]
        num_spheres = int(film_ysize / ellipse_spacing)
        sphere_layer = [
            mp.Ellipsoid(size=mp.Vector3(ellipsex, ellipsey, 1e20),
                         center=mp.Vector3(x, y + offset - film_ysize / 2, 0),
                         material=mp.Medium(epsilon=1))
            for y in np.linspace(0, film_ysize, num_spheres)
        ]
        spheres = spheres + sphere_layer

    return spheres
Beispiel #4
0
        def _check(med, expected, default=mp.Medium()):
            geometry = [mp.Block(center=mp.Vector3(), size=mp.Vector3(1, 1), material=med)]
            sim = mp.Simulation(cell_size=mp.Vector3(5, 5), resolution=10, geometry=geometry,
                                default_material=default)

            result = sim.has_mu()
            if expected:
                self.assertTrue(result)
            else:
                self.assertFalse(result)

            print("Estimated memory usage: {}".format(sim.get_estimated_memory_usage()))
Beispiel #5
0
def geo1D_thin_film_si(film_n,
                       si_n,
                       ps_thickness,
                       si_thickness,
                       pos=0,
                       bare_substrate=False):
    ps_block = mp.Block(size=mp.Vector3(1, 1, ps_thickness),
                        center=mp.Vector3(
                            0, 0, pos - (si_thickness + ps_thickness / 2)),
                        material=mp.Medium(epsilon=film_n**2))

    si_block = mp.Block(size=mp.Vector3(1, 1, si_thickness),
                        center=mp.Vector3(0, 0, pos - si_thickness / 2),
                        material=mp.Medium(epsilon=si_n**2))

    if bare_substrate:
        geometry = [si_block]
    else:
        geometry = [ps_block, si_block]

    return geometry
Beispiel #6
0
    def get_fragment_stats(self,
                           block_size,
                           cell_size,
                           dims,
                           box_center=mp.Vector3(),
                           dft_vecs=None,
                           def_mat=mp.air,
                           sym=[],
                           geom=None,
                           pml=[]):
        mat = mp.Medium(epsilon=12,
                        epsilon_offdiag=mp.Vector3(z=1),
                        mu_offdiag=mp.Vector3(x=20),
                        E_chi2_diag=mp.Vector3(1, 1),
                        H_chi3_diag=mp.Vector3(z=1),
                        E_susceptibilities=[
                            mp.LorentzianSusceptibility(),
                            mp.NoisyLorentzianSusceptibility()
                        ],
                        H_susceptibilities=[mp.DrudeSusceptibility()],
                        D_conductivity_diag=mp.Vector3(y=1),
                        B_conductivity_diag=mp.Vector3(x=1, z=1))

        if geom is None:
            geom = [mp.Block(size=block_size, center=box_center, material=mat)]
        sim = mp.Simulation(cell_size=cell_size,
                            resolution=10,
                            geometry=geom,
                            dimensions=dims,
                            default_material=def_mat,
                            symmetries=sym,
                            boundary_layers=pml)

        if dft_vecs:
            if dft_vecs['flux_regions']:
                sim.add_flux(1, 0.5, 5, *dft_vecs['flux_regions'])
            if dft_vecs['n2f_regions']:
                sim.add_near2far(1, 0.5, 7, *dft_vecs['n2f_regions'])
            if dft_vecs['force_regions']:
                sim.add_force(1, 0.5, 9, *dft_vecs['force_regions'])
            if dft_vecs['fields_components']:
                sim.add_dft_fields(dft_vecs['fields_components'],
                                   0,
                                   1,
                                   5,
                                   where=dft_vecs['fields_where'],
                                   center=dft_vecs['fields_center'],
                                   size=dft_vecs['fields_size'])

        gv = sim._create_grid_volume(False)
        stats = sim._compute_fragment_stats(gv)

        return stats
Beispiel #7
0
def createDiffractionSlit():
    cell = mp.Vector3(globalVariables.waveguideXSize, globalVariables.waveguideYSize, 0)

    geometry = [mp.Block(mp.Vector3(1e20, 1, 1e20),
                     center=mp.Vector3(0, 0),
                         material=mp.Medium(epsilon=globalVariables.epsilonOfMaterial)),
                mp.Block(mp.Vector3(globalVariables.blockXSize,globalVariables.blockYSize,0),
                         center=mp.Vector3(0,(globalVariables.blockYSize-globalVariables.waveguideYSize)/2.0,0),
                         material=mp.Medium(epsilon=globalVariables.epsilonOfBoundary)),
                mp.Block(mp.Vector3(globalVariables.blockXSize,globalVariables.blockYSize,0),
                         center=mp.Vector3(0,(globalVariables.waveguideYSize-globalVariables.blockYSize)/2.0,0),
                         material=mp.Medium(epsilon=globalVariables.epsilonOfBoundary))]


    sources = [mp.Source(mp.ContinuousSource(frequency=0.15),
                     component=mp.Ez,
                         center=mp.Vector3(-globalVariables.waveguideXSize/2+1,0,0))]

    pml_layers = [mp.PML(1.0)]

    return cell,geometry,sources,pml_layers
Beispiel #8
0
    def set_geometry(self, args: dict):
        if args['coordinates']['z'] == 0:
            args['coordinates']['z'] = mp.inf

        self.sim_data['geometry'] = [
            mp.Block(mp.Vector3(args['coordinates']['x'],
                                args['coordinates']['y'],
                                args['coordinates']['z']),
                     center=mp.Vector3(args['center']['x'],
                                       args['center']['y']),
                     material=mp.Medium(epsilon=args['material']))
        ]
Beispiel #9
0
def get_xs(wg_width=0.35, two_wg_gap=None, encapsulation=None):
    geometry = []
    # Cladding
    geometry.append(mp.Block(size=mp.Vector3(mp.inf, mp.inf, t_top),
                     center=mp.Vector3(z=t_top/2), material=Cladding))
    # BOX
    geometry.append(mp.Block(size=mp.Vector3(mp.inf, mp.inf, t_box),
                     center=mp.Vector3(z=-t_box/2), material=SiO2))
    if encapsulation is not None:
        t_ped_encap = t_ped + encapsulation
        t_rib_encap = t_si + encapsulation
        geometry.append(mp.Block(size=mp.Vector3(mp.inf, mp.inf, t_ped_encap),
                        center=mp.Vector3(z=t_ped_encap/2), material=SiO2))
        geometry.append(mp.Block(size=mp.Vector3(mp.inf, wg_width + 2*encapsulation, t_rib_encap),
                        center=mp.Vector3(z=t_rib_encap/2), material=SiO2))
    # partial
    geometry.append(mp.Block(size=mp.Vector3(mp.inf, w_ped, t_ped),
                     center=mp.Vector3(z=t_ped/2), material=ColdSi))
    # core
    if two_wg_gap is None:
        offsets = [0]
    else:
        offsets = np.array([-1, 1]) * (wg_width + two_wg_gap)/2
    for offset in offsets:
        geometry.append(mp.Block(size=mp.Vector3(mp.inf, wg_width, t_si),
                        center=mp.Vector3(y=offset, z=t_si/2), material=ColdSi))
    return geometry
def adjoint_solver_damping(design_params, frequencies=None, mat2=silicon):
    matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny),
                              mp.air,
                              mat2,
                              weights=np.ones((Nx, Ny)),
                              damping=3.14 * fcen)
    matgrid_region = mpa.DesignRegion(
        matgrid,
        volume=mp.Volume(center=mp.Vector3(),
                         size=mp.Vector3(design_region_size.x,
                                         design_region_size.y, 0)))

    matgrid_geometry = [
        mp.Block(center=matgrid_region.center,
                 size=matgrid_region.size,
                 material=matgrid)
    ]

    geometry = waveguide_geometry + matgrid_geometry

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell_size,
                        boundary_layers=pml_xy,
                        sources=wvg_source,
                        geometry=geometry)

    if not frequencies:
        frequencies = [fcen]

    obj_list = [
        mpa.EigenmodeCoefficient(sim,
                                 mp.Volume(
                                     center=mp.Vector3(0.5 * sxy - dpml - 0.1),
                                     size=mp.Vector3(0, sxy - 2 * dpml, 0)),
                                 1,
                                 eig_parity=eig_parity)
    ]

    def J(mode_mon):
        return npa.power(npa.abs(mode_mon), 2)

    opt = mpa.OptimizationProblem(simulation=sim,
                                  objective_functions=J,
                                  objective_arguments=obj_list,
                                  design_regions=[matgrid_region],
                                  frequencies=frequencies,
                                  minimum_run_time=150)

    f, dJ_du = opt([design_params])

    sim.reset_meep()
    return f, dJ_du
Beispiel #11
0
def adjoint_solver(design_params, mon_type):
    matgrid = mp.MaterialGrid(mp.Vector3(Nx,Ny),
                              mp.air,
                              silicon,
                              design_parameters=np.ones((Nx,Ny)))

    matgrid_region = mpa.DesignRegion(matgrid,
                                      volume=mp.Volume(center=mp.Vector3(),
                                                       size=mp.Vector3(design_shape.x,design_shape.y,0)))

    matgrid_geometry = [mp.Block(center=matgrid_region.center,
                                 size=matgrid_region.size,
                                 material=matgrid)]

    geometry = waveguide_geometry + matgrid_geometry

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell_size,
                        boundary_layers=boundary_layers,
                        sources=sources,
                        geometry=geometry)

    if mon_type.name == 'EIGENMODE':
        obj_list = [mpa.EigenmodeCoefficient(sim,
                                             mp.Volume(center=mp.Vector3(0.5*sxy-dpml),
                                                       size=mp.Vector3(0,sxy,0)),1)]

        def J(mode_mon):
            return npa.abs(mode_mon)**2

    elif mon_type.name == 'DFT':
        obj_list = [mpa.FourierFields(sim,
                                      mp.Volume(center=mp.Vector3(0.5*sxy-dpml),
                                                size=mp.Vector3(0,sxy,0)),
                                      mp.Ez)]

        def J(mode_mon):
            return npa.abs(mode_mon[0,63])**2

    opt = mpa.OptimizationProblem(
        simulation = sim,
        objective_functions = J,
        objective_arguments = obj_list,
        design_regions = [matgrid_region],
        frequencies=[fcen],
        decay_fields=[mp.Ez])

    f, dJ_du = opt([design_params])

    sim.reset_meep()

    return f, dJ_du
def main():
    n = 3.4  # index of waveguide
    r = 1
    a = r  # inner radius of ring
    w = 1  # width of waveguide
    b = a + w  # outer radius of ring
    pad = 4  # padding between waveguide and edge of PML

    dpml = 2  # thickness of PML
    pml_layers = [mp.PML(dpml)]

    resolution = 100

    sr = b + pad + dpml  # radial size (cell is from 0 to sr)
    dimensions = mp.CYLINDRICAL  # coordinate system is (r,phi,z) instead of (x,y,z)
    cell = mp.Vector3(sr, 0, 0)

    m = 4

    geometry = [
        mp.Block(center=mp.Vector3(a + (w / 2)),
                 size=mp.Vector3(w, 1e20, 1e20),
                 material=mp.Medium(index=n))
    ]

    # Finding a resonance mode with a high Q-value (calculated with Harminv)

    fcen = 0.15  # pulse center frequency
    df = 0.1  # pulse width (in frequency)

    sources = [
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  mp.Hz,
                  mp.Vector3(r + 0.1),
                  amplitude=1)
    ]

    sim = mp.Simulation(cell_size=cell,
                        geometry=geometry,
                        boundary_layers=pml_layers,
                        resolution=resolution,
                        sources=sources,
                        dimensions=dimensions,
                        m=m)

    h = mp.Harminv(mp.Hz, mp.Vector3(r + 0.1), fcen, df)
    sim.run(mp.after_sources(h), until_after_sources=200)

    print(f'Harminv found {len(h.modes)} resonant modes(s).')
    for mode in h.modes:
        print(f'The resonant mode with f={mode.freq} has Q={mode.Q}')
Beispiel #13
0
def get_freqs(hx, hy, a, w):

    wz = 0.22
    res = 20
    mode = "zEyO"
    resolution = res  # pixels/a, taken from simpetus example

    #     a = round(a,3)        # units of um
    #     h = round(wz, 3)         # units of um
    #     w = round(wy, 3)         # units of um
    #     hx = round(hx, 3)
    #     hy = round(hy, 3)
    h = wz
    h = h / a  # units of "a"
    w = w / a  # units of "a"
    hx = hx / a  # units of "a"
    hy = hy / a  # units of "a"

    nSi = 3.45
    Si = mp.Medium(index=nSi)

    geometry_lattice = mp.Lattice(size=mp.Vector3(
        1, 4, 4))  # dimensions of lattice taken from simpetus example

    geometry = [
        mp.Block(center=mp.Vector3(),
                 size=mp.Vector3(mp.inf, w, h),
                 material=Si),
        mp.Ellipsoid(material=mp.air,
                     center=mp.Vector3(),
                     size=mp.Vector3(hx, hy, mp.inf))
    ]

    k_points = [mp.Vector3(0.5, 0, 0)]
    num_bands = 2  # from simpetus example

    ms = mpb.ModeSolver(geometry_lattice=geometry_lattice,
                        geometry=geometry,
                        k_points=k_points,
                        resolution=resolution,
                        num_bands=num_bands)

    if mode == "te":

        ms.run_te()  # running for all modes and extracting parities

    if mode == "zEyO":

        ms.run_yodd_zeven()

    return ms.freqs
Beispiel #14
0
def forward_simulation(design_params,mon_type):
    matgrid = mp.MaterialGrid(mp.Vector3(Nx,Ny),
                              mp.air,
                              silicon,
                              design_parameters=design_params.reshape(Nx,Ny),
                              grid_type='U_SUM')
            
    matgrid_geometry = [mp.Block(center=mp.Vector3(),
                                 size=mp.Vector3(design_shape.x,design_shape.y,0),
                                 material=matgrid)]

    geometry = waveguide_geometry + matgrid_geometry

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell_size,
                        boundary_layers=boundary_layers,
                        sources=sources,
                        geometry=geometry)

    if mon_type.name == 'EIGENMODE':
        mode = sim.add_mode_monitor(fcen,
                                    0,
                                    1,
                                    mp.ModeRegion(center=mp.Vector3(0.5*sxy-dpml),size=mp.Vector3(0,sxy,0)),
                                    yee_grid=True)

    elif mon_type.name == 'DFT':
        mode = sim.add_dft_fields([mp.Ez],
                                  fcen,
                                  0,
                                  1,
                                  center=mp.Vector3(0.5*sxy-dpml),
                                  size=mp.Vector3(0,sxy),
                                  yee_grid=False)

    sim.run(until_after_sources=20)

    if mon_type.name == 'EIGENMODE':
        coeff = sim.get_eigenmode_coefficients(mode,[1],eig_parity).alpha[0,0,0]
        S12 = abs(coeff)**2

    elif mon_type.name == 'DFT':
        Ez_dft = sim.get_dft_array(mode, mp.Ez, 0)
        Ez2 = abs(Ez_dft[63])**2

    sim.reset_meep()

    if mon_type.name == 'EIGENMODE':
        return S12
    elif mon_type.name == 'DFT':
        return Ez2
Beispiel #15
0
    def create_sim(self, beta_vector, vacuum=False):

        args = self.args

        hwvg = mp.Block(center=origin,
                        material=mp.Medium(epsilon=args.eps),
                        size=mp.Vector3(self.cell_size.x, args.wh))
        vwvg = mp.Block(center=origin,
                        material=mp.Medium(epsilon=args.eps),
                        size=mp.Vector3(args.wv, self.cell_size.y))
        router = mp.Block(
            center=self.design_center,
            size=self.design_size,
            epsilon_func=self.basis.parameterized_function(beta_vector))
        geometry = [hwvg, vwvg, router]

        envelope = mp.GaussianSource(args.fcen, fwidth=args.df)
        amp = 1.0
        if callable(getattr(envelope, "fourier_transform", None)):
            amp /= envelope.fourier_transform(args.fcen)
        sources = [
            mp.EigenModeSource(src=envelope,
                               center=self.source_center,
                               size=self.source_size,
                               eig_band=args.source_mode,
                               amplitude=amp)
        ]

        sim = mp.Simulation(resolution=args.res,
                            cell_size=self.cell_size,
                            boundary_layers=[mp.PML(self.dpml)],
                            geometry=geometry,
                            sources=sources)

        if args.complex_fields:
            sim.force_complex_fields = True

        return sim
Beispiel #16
0
def add_waveguide_1d(geom=None,
                     wvg_width=.65,
                     wvg_height=.25,
                     center=mp.Vector3(0, 0, 0),
                     material=mp.Medium(index=3.45),
                     d_tuning=0,
                     material_tuning=mp.Medium(index=1.025)):
    """
    Creates a 1D waveguide.
    The LHe shell can be adopted such that N2 ice layers could be investigated
    as well.
    """

    if geom is None:
        geom = []
    if isinstance(center, mp.Vector3):
        _center = center
    elif len(center) == 3:
        _center = mp.Vector3(center[0], center[1], center[2])
    else:
        warnings.warn("Variable center not understood but passed")
        _center = center

    # LHe shell
    if d_tuning != 0:
        geom.append(
            mp.Block(material=index_to_material(material_tuning),
                     center=_center,
                     size=mp.Vector3(mp.inf, wvg_width + 2 * d_tuning,
                                     wvg_height + 2 * d_tuning)))

    # Si waveguide
    geom.append(
        mp.Block(material=index_to_material(material),
                 center=_center,
                 size=mp.Vector3(mp.inf, wvg_width, wvg_height)))

    return geom
Beispiel #17
0
    def test_custom_em_source(self):
        resolution = 20

        dpml = 2
        pml_layers = [mp.PML(thickness=dpml)]

        sx = 40
        sy = 12
        cell_size = mp.Vector3(sx + 2 * dpml, sy)

        v0 = 0.15  # pulse center frequency
        a = 0.2 * v0  # Gaussian envelope half-width
        b = -0.1  # linear chirp rate (positive: up-chirp, negative: down-chirp)
        t0 = 15  # peak time

        chirp = lambda t: np.exp(1j * 2 * np.pi * v0 *
                                 (t - t0)) * np.exp(-a * (t - t0)**2 + 1j * b *
                                                    (t - t0)**2)

        geometry = [
            mp.Block(center=mp.Vector3(0, 0, 0),
                     size=mp.Vector3(mp.inf, 1, mp.inf),
                     material=mp.Medium(epsilon=12))
        ]

        kx = 0.4  # initial guess for wavevector in x-direction of eigenmode
        kpoint = mp.Vector3(kx)
        bnum = 1

        sources = [
            mp.EigenModeSource(src=mp.CustomSource(src_func=chirp,
                                                   center_frequency=v0),
                               center=mp.Vector3(-0.5 * sx + dpml + 1),
                               size=mp.Vector3(y=sy),
                               eig_kpoint=kpoint,
                               eig_band=bnum,
                               eig_parity=mp.EVEN_Y + mp.ODD_Z,
                               eig_match_freq=True)
        ]

        sim = mp.Simulation(cell_size=cell_size,
                            boundary_layers=pml_layers,
                            resolution=resolution,
                            k_point=mp.Vector3(),
                            sources=sources,
                            geometry=geometry,
                            symmetries=[mp.Mirror(mp.Y)])

        t = np.linspace(0, 50, 1000)
        sim.run(until=t0 + 50)
def gen_particle_geo(loc, theta_x, theta_y, theta_z):
    R = np.empty((num_crystal, 3, 3))

    Rx_matrix = np.empty((num_crystal, 3, 3))
    Ry_matrix = np.empty((num_crystal, 3, 3))
    Rz_matrix = np.empty((num_crystal, 3, 3))

    for i in range(num_crystal):
        Rx_matrix[i, :, :] = np.array([[1, 0, 0],
                       [0, cos(theta_x[i]), -sin(theta_x[i])], 
                      [0, sin(theta_x[i]), cos(theta_x[i])]])

        Ry_matrix[i, :, :] = np.array([[cos(theta_y[i]), 0, sin(theta_y[i])], 
                      [0, 1, 0],
                      [-sin(theta_y[i]), 0, cos(theta_y[i])]])

        Rz_matrix[i, :, :] = np.array([[cos(theta_z[i]), -sin(theta_z[i]), 0],
                     [sin(theta_z[i]), cos(theta_z[i]), 0],
                     [0, 0, 1]])

        R[i, :, :] = np.matmul(np.matmul(Ry_matrix[i, :, :], Rx_matrix[i, :, :]), Rz_matrix[i, :, :])


    og_x = np.array([[1, 0, 0] for i in range(num_crystal)])
    og_y = np.array([[0, 1, 0] for i in range(num_crystal)])
    og_z = np.array([[0, 0, 1] for i in range(num_crystal)])

    Rx_vector = np.empty((num_crystal, 3))
    Ry_vector = np.empty((num_crystal, 3))
    Rz_vector = np.empty((num_crystal, 3))

    for i in range(num_crystal):
        Rx_vector[i, :] = np.matmul(R[i, :, :], og_x[i, :])
        Ry_vector[i, :] = np.matmul(R[i, :, :], og_y[i, :])
        Rz_vector[i, :] = np.matmul(R[i, :, :], og_z[i, :])

    geometry = [solid_region,]

    for i in range(num_crystal):
        if (np.abs(loc[i, 0]) < size_solid[0] - size_crystal_base[0]/2 and 
        np.abs(loc[i, 1]) < size_solid[1] - size_crystal_base[1]/2 and 
        np.abs(loc[i, 2]) < size_solid[2] - size_crystal_base[2]/2):
            geometry.append(mp.Block(
                size_crystal[i],
                center = mp.Vector3(loc[i, 0], loc[i, 1], loc[i, 2]),
                e1 = Rx_vector[i, :],
                e2 = Ry_vector[i, :],
                e3 = Rz_vector[i, :],
                material=mp.Medium(epsilon=10.5)))
    return geometry
Beispiel #19
0
    def setUpClass(cls):
        cls.resolution = 30  # pixels/μm

        cls.dpml = 1.0  # PML thickness
        cls.dsub = 1.0  # substrate thickness
        cls.dpad = 1.0  # padding thickness between grating and PML
        cls.gp = 6.0  # grating period
        cls.gh = 0.5  # grating height
        cls.gdc = 0.5  # grating duty cycle

        cls.sx = cls.dpml + cls.dsub + cls.gh + cls.dpad + cls.dpml
        cls.sy = cls.gp

        cls.cell_size = mp.Vector3(cls.sx, cls.sy, 0)

        # replace anisotropic PML with isotropic Absorber to
        # attenuate parallel-directed fields of oblique source
        cls.abs_layers = [mp.Absorber(thickness=cls.dpml, direction=mp.X)]

        wvl = 0.5  # center wavelength
        cls.fcen = 1 / wvl  # center frequency
        cls.df = 0.05 * cls.fcen  # frequency width

        cls.ng = 1.5
        cls.glass = mp.Medium(index=cls.ng)

        cls.geometry = [
            mp.Block(material=cls.glass,
                     size=mp.Vector3(cls.dpml + cls.dsub, mp.inf, mp.inf),
                     center=mp.Vector3(
                         -0.5 * cls.sx + 0.5 * (cls.dpml + cls.dsub), 0, 0)),
            mp.Block(material=cls.glass,
                     size=mp.Vector3(cls.gh, cls.gdc * cls.gp, mp.inf),
                     center=mp.Vector3(
                         -0.5 * cls.sx + cls.dpml + cls.dsub + 0.5 * cls.gh, 0,
                         0))
        ]
Beispiel #20
0
def main():
    # Some parameters to describe the geometry:
    eps = 13  # dielectric constant of waveguide
    w = 1.2  # width of waveguide
    r = 0.36  # radius of holes

    # The cell dimensions
    sy = 12  # size of cell in y direction (perpendicular to wvg.)
    dpml = 1  # PML thickness (y direction only!)

    cell = mp.Vector3(1, sy)

    b = mp.Block(size=mp.Vector3(mp.inf, w, mp.inf),
                 material=mp.Medium(epsilon=eps))
    c = mp.Cylinder(radius=r)

    fcen = 0.25  # pulse center frequency
    df = 1.5  # pulse freq. width: large df = short impulse

    s = mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Hz,
                  center=mp.Vector3(0.1234))

    sym = mp.Mirror(direction=mp.Y, phase=-1)

    sim = mp.Simulation(cell_size=cell,
                        geometry=[b, c],
                        sources=[s],
                        symmetries=[sym],
                        boundary_layers=[mp.PML(dpml, direction=mp.Y)],
                        resolution=20)

    kx = False  # if true, do run at specified kx and get fields
    k_interp = 19  # # k-points to interpolate, otherwise

    if kx:
        sim.k_point = mp.Vector3(kx)

        sim.run(mp.at_beginning(mp.output_epsilon),
                mp.after_sources(
                    mp.Harminv(mp.Hz, mp.Vector3(0.1234), fcen, df)),
                until_after_sources=300)

        sim.run(mp.at_every(1 / fcen / 20, mp.output_hfield_z), until=1 / fcen)

    else:
        sim.run_k_points(
            300, mp.interpolate(k_interp,
                                [mp.Vector3(), mp.Vector3(0.5)]))
Beispiel #21
0
def parallel_waveguide(s,yodd):
    geometry = [mp.Block(center=mp.Vector3(0,-0.5*(s+a),0),
                         size=mp.Vector3(mp.inf,a,a),
                         material=Si),
                mp.Block(center=mp.Vector3(0,0.5*(s+a),0),
                         size=mp.Vector3(mp.inf,a,a),
                         material=Si)]

    ms = mpb.ModeSolver(resolution=resolution,
                        k_points=k_points,
                        geometry_lattice=geometry_lattice,
                        geometry=geometry,
                        num_bands=1,
                        tolerance=1e-9)

    if yodd:
        ms.run_yodd_zodd()
    else:
        ms.run_yeven_zodd()

    f = ms.get_freqs()[0]
    vg = ms.compute_group_velocity_component(mp.Vector3(1,0,0))[0]

    return f,vg
def geom2(THICKNESS, sx, sy, g, d1, d2, material, spacer, dpml):
    Glass = mp.Medium(epsilon=g)
    diel1 = mp.Medium(epsilon=d1)
    diel2 = mp.Medium(epsilon=d2)
    mat = [Au, Al, Ag, Glass, diel1, diel2, Cr, Ti]
    geometry = []
    t = -sy * 0.5 + dpml
    for i in range(len(THICKNESS)):
        if THICKNESS[i] == 0:
            pass
        else:
            t += THICKNESS[i] * 0.5
            geometry.append(
                mp.Block(mp.Vector3(mp.inf, THICKNESS[i], mp.inf),
                         center=mp.Vector3(0, t, 0),
                         material=mat[material[i]]))
            t += THICKNESS[i] * 0.5
    geometry.append(
        mp.Block(mp.Vector3(spacer, THICKNESS[-3] + THICKNESS[-2], mp.inf),
                 center=mp.Vector3(
                     0, -(THICKNESS[-2] + THICKNESS[-3]) * 0.5 + t -
                     THICKNESS[-1], 0),
                 material=mat[material[-1]]))
    return (geometry)
Beispiel #23
0
def create_plasma(max_eps, lx, ly, resolution):  

    tamx = 1/resolution
    tamy = ly
    var = int((lx/2)*resolution)

    plasma = []

    for i in range(var):
        bloco = mp.Block(mp.Vector3(tamx,tamy,0),
                        center=mp.Vector3(tamx*i,0),
                        material=mp.Medium(epsilon=1+(i*max_eps/var)))
        plasma.append(bloco)
    
    return plasma
def generatePhotonicGrid(numpyArray):
    photonicArray = numpyArray
    geometry = [
        mp.Block(mp.Vector3(grid.xLength, grid.yLength, 1),
                 center=mp.Vector3(0, 0, 0),
                 material=mp.Medium(epsilon=1))
    ]
    areasWithSilicon = np.argwhere(photonicArray == 1)
    for i in areasWithSilicon:
        xindex = i[0]
        yindex = i[1]
        x, y = blockIndexToCenter(xindex, yindex)
        block = createBlockObject(x, y)
        geometry.append(block)
    return geometry
Beispiel #25
0
def createDiffractionGrating():
    cell = mp.Vector3(globalVariables.waveguideXSize, globalVariables.waveguideYSize, 0)

    geometry = [mp.Block(mp.Vector3(1e20, 1, 1e20),
                     center=mp.Vector3(0, 0),
                         material=mp.Medium(epsilon=globalVariables.epsilonOfMaterial))]
    for i in range(globalVariables.numberOfSlitsForDiffractionGrating+1):
        centerXValue , centerYValue = diffractionGratingBlockCenter(i)
        #centerXValue = np.round(centerXValue)
        #centerYValue = np.round(centerYValue)
        blockXSize , blockYSize = diffractionGratingBlockSize()
        #blockXSize = np.round(blockXSize)
        #blockYSize = np.round(blockYSize)
        geometry.append(mp.Block(mp.Vector3(blockXSize,blockYSize,0),
                                 center=mp.Vector3(centerXValue,centerYValue,0),
                                 material=mp.Medium(epsilon=globalVariables.epsilonOfBoundary)))
    print(len(geometry),"THIS IS LEN GEOMEETRY")
    sources = [mp.Source(mp.ContinuousSource(frequency=0.15),
                     component=mp.Ez,
                         center=mp.Vector3(-globalVariables.waveguideXSize/2+1,0,0))]

    pml_layers = [mp.PML(1.0)]

    return cell,geometry,sources,pml_layers
def adjoint_solver_complex_fields(design_params, frequencies=None):
    matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny),
                              mp.air,
                              silicon,
                              weights=np.ones((Nx, Ny)))

    matgrid_region = mpa.DesignRegion(
        matgrid,
        volume=mp.Volume(center=mp.Vector3(),
                         size=mp.Vector3(design_region_size.x,
                                         design_region_size.y, 0)))

    geometry = [
        mp.Block(center=matgrid_region.center,
                 size=matgrid_region.size,
                 material=matgrid)
    ]

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell_size,
                        k_point=k_point,
                        boundary_layers=pml_x,
                        sources=pt_source,
                        geometry=geometry)

    if not frequencies:
        frequencies = [fcen]

    obj_list = [
        mpa.FourierFields(
            sim, mp.Volume(center=mp.Vector3(0.9), size=mp.Vector3(0.2, 0.5)),
            mp.Ez)
    ]

    def J(dft_mon):
        return npa.power(npa.abs(dft_mon[:, 3, 9]), 2)

    opt = mpa.OptimizationProblem(simulation=sim,
                                  objective_functions=J,
                                  objective_arguments=obj_list,
                                  design_regions=[matgrid_region],
                                  frequencies=frequencies)

    f, dJ_du = opt([design_params])

    sim.reset_meep()

    return f, dJ_du
Beispiel #27
0
def add_substrate(geom=None, waveguide_height=0.22, substrate_height=5, material=mp.Medium(index=1.44)):
    """
    Creates a (by default SiO2) substrate.
    If the unlike case occurs that we need to change the center, we could again make everything relative to the center
    of the substrate.
    """
    if geom is None:
        geom = []

    _center = mp.Vector3(0, 0, -waveguide_height/2-substrate_height/2)

    geom.append(mp.Block(material=index_to_material(material),
                         center=_center,
                         size=mp.Vector3(mp.inf, mp.inf, substrate_height)))

    return geom
Beispiel #28
0
def adjoint_solver(design_params):

    design_variables = mp.MaterialGrid(mp.Vector3(Nr, 0, Nz), SiO2, Si)
    design_region = mpa.DesignRegion(
        design_variables,
        volume=mp.Volume(center=mp.Vector3(design_r / 2, 0, 0),
                         size=mp.Vector3(design_r, 0, design_z)))
    geometry = [
        mp.Block(center=design_region.center,
                 size=design_region.size,
                 material=design_variables)
    ]

    sim = mp.Simulation(cell_size=cell_size,
                        boundary_layers=boundary_layers,
                        geometry=geometry,
                        sources=source,
                        resolution=resolution,
                        dimensions=dimensions,
                        m=m)

    far_x = [mp.Vector3(5, 0, 20)]
    NearRegions = [
        mp.Near2FarRegion(center=mp.Vector3(
            design_r / 2, 0, (sz / 2 - dpml + design_z / 2) / 2),
                          size=mp.Vector3(design_r, 0, 0),
                          weight=+1)
    ]
    FarFields = mpa.Near2FarFields(sim, NearRegions, far_x)
    ob_list = [FarFields]

    def J(alpha):
        return npa.abs(alpha[0, 0, 0])**2

    opt = mpa.OptimizationProblem(simulation=sim,
                                  objective_functions=J,
                                  objective_arguments=ob_list,
                                  design_regions=[design_region],
                                  fcen=fcen,
                                  df=0,
                                  nf=1,
                                  maximum_run_time=1200)

    f, dJ_du = opt([design_params])
    sim.reset_meep()

    return f, dJ_du
Beispiel #29
0
    def test_dft_energy(self):
        resolution = 20
        cell = mp.Vector3(10, 5)
        geom = [
            mp.Block(size=mp.Vector3(mp.inf, 1, mp.inf),
                     material=mp.Medium(epsilon=12))
        ]
        pml = [mp.PML(1)]
        fsrc = 0.15
        sources = [
            mp.EigenModeSource(src=mp.GaussianSource(frequency=fsrc,
                                                     fwidth=0.2 * fsrc),
                               center=mp.Vector3(-3),
                               size=mp.Vector3(y=5),
                               eig_band=1,
                               eig_parity=mp.ODD_Z + mp.EVEN_Y,
                               eig_match_freq=True)
        ]

        sim = mp.Simulation(resolution=resolution,
                            cell_size=cell,
                            geometry=geom,
                            boundary_layers=pml,
                            sources=sources,
                            symmetries=[mp.Mirror(direction=mp.Y)])

        flux = sim.add_flux(
            fsrc, 0, 1,
            mp.FluxRegion(center=mp.Vector3(3), size=mp.Vector3(y=5)))
        energy = sim.add_energy(
            fsrc, 0, 1,
            mp.EnergyRegion(center=mp.Vector3(3), size=mp.Vector3(y=5)))
        sim.run(until_after_sources=100)

        res = sim.get_eigenmode_coefficients(flux, [1],
                                             eig_parity=mp.ODD_Z + mp.EVEN_Y)
        mode_vg = res.vgrp[0]
        poynting_flux = mp.get_fluxes(flux)[0]
        e_energy = mp.get_electric_energy(energy)[0]
        ratio_vg = (0.5 * poynting_flux) / e_energy
        m_energy = mp.get_magnetic_energy(energy)[0]
        t_energy = mp.get_total_energy(energy)[0]

        self.assertAlmostEqual(m_energy + e_energy, t_energy)
        self.assertAlmostEqual(ratio_vg, mode_vg, places=3)
Beispiel #30
0
def main(args):
    sx = 4.0  #spatial extent along x including pmls (μm)
    sy = 4
    sz = 0
    dpml = 1.0

    cell = mp.Vector3(sx, sy, sz)
    pml_layers = [mp.PML(dpml)]
    geometry = [
        mp.Block(mp.Vector3(mp.inf, 0.050, 0),
                 center=mp.Vector3(0, 0.025, 0),
                 material=Ag)
    ]
    resolution = args.res
    wvlmax = 1.0
    fmin = 1 / wvlmax
    wvlmin = 0.100
    fmax = 1 / wvlmin
    wvl = args.wvl
    fcen = 1 / wvl
    df = fmax - fmin
    nfreq = 1
    print("wavelength =", wvl, "μm")
    print("center frequency =", fcen, "1/μm")

    source = [
        mp.Source(mp.GaussianSource(fcen, 0, nfreq),
                  component=mp.Ex,
                  center=mp.Vector3(0, -0.050, 0))
    ]
    symmetries = [mp.Mirror(mp.X), mp.Mirror(mp.Z)]
    sim = mp.Simulation(cell_size=cell,
                        geometry=geometry,
                        sources=source,
                        resolution=resolution,
                        boundary_layers=pml_layers)
    pt = mp.Vector3(0, -0.050, 0)
    sim.run(mp.dft_ldos(fcen, 0, nfreq),
            until_after_sources=mp.stop_when_fields_decayed(
                20, mp.Ex, pt, 1e-3))
    eps_data = sim.get_array(center=mp.Vector3(),
                             size=cell,
                             component=mp.Dielectric)
    ey_data = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Ey)