Exemplo n.º 1
0
    def radiating_base(self, sq_ratio, solve_cw=True):

        w = 0.30

        s = mp.structure(self.gv, one, mp.pml(self.ymax / 3.0))

        f = mp.fields(s)

        src = ContinuousSource(w)
        f.add_point_source(mp.Ez, src, self.pnt_src_vec)

        # let the source reach steady state
        if solve_cw:
            f.solve_cw(1e-6)
        else:
            while f.time() < 400:
                f.step()

        # amp1 and amp2 are of type complex
        amp1 = f.get_field(mp.Ez, self.p1)
        amp2 = f.get_field(mp.Ez, self.p2)

        ratio = abs(amp1) / abs(amp2)
        if self.gv.dim == mp.D2:
            ratio = ratio**2  # in 2d, decay is ~1/sqrt(r), so square to get 1/r

        print("Ratio is {} from ({} {}) and ({} {})".format(
            ratio, amp1.real, amp1, amp2.real, amp2))

        fail_fmt = "Failed: amp1 = ({}, {}), amp2 = ({}, {})\nabs(amp1/amp2){} = {}, too far from 2.0"
        fail_msg = fail_fmt.format(amp1.real, amp1, amp2.real, amp2,
                                   "^2" if sq_ratio else "", ratio)

        self.assertTrue(ratio <= 2.12 and ratio >= 1.88, fail_msg)
 def run(self, interactive_mode=False):
     self.engine.initialise_engine(self.landscape)  #mandatory !
     self.save_engine_dielectricum_to_file(
     )  #export to file the dielectricum as it was received by Meep
     #create a reference to the meep fields object
     fields = meep.fields(self.engine.structure)
     #If you want to use the mode profile at a certain port in your python-meep scripting,then you can retrieve it as follows (THIS IS NOT ACTUALLY USED FURTHER IN THE SCRIPT, IT'S JUST AN ILLUSTRATION OF WHAT YOU COULD DO...)
     mp = get_mode_profile_at_port(
         structure=mmi,
         resolution=simul_params["resolution"],
         port=mmi.west_ports[0],
         wavelength=simul_params["center_wavelength"])
     print mp
     #create a Gaussian source
     center_wavelength = simul_params["center_wavelength"]
     pulse_width = 30
     center_freq = 1.0 / (float(center_wavelength) / 1000.0)
     pulse_width_freq = ((float(pulse_width) / 1000.0) /
                         (float(center_wavelength) / 1000.0)) * center_freq
     src_gaussian = meep.gaussian_src_time(center_freq, pulse_width_freq)
     #add a point source (linked to the Gaussian source) at the position of the west port
     source_position_vec = self.make_meep_vec(
         mmi.west_ports[0].transform_copy(
             Translation(translation=(-9.0, 0))).position)
     fields.add_point_source(meep.Hz, src_gaussian, source_position_vec)
     #add a probing point to the upper output arm
     probing_point_vec = self.make_meep_vec(mmi.east_ports[1].position)
     #run the simulation
     h5_file = meep.prepareHDF5File("./mmi_low_level.h5")
     meep.runUntilFieldsDecayed(fields,
                                self.engine.meepVol,
                                meep.Hz,
                                probing_point_vec,
                                pHDF5OutputFile=h5_file,
                                pH5OutputIntervalSteps=100)
Exemplo n.º 3
0
def main(args):

    n = 3.4  # index of waveguide
    w = 1.0  # width of waveguide
    r = 1.0  # inner radius of ring

    pad = 4  # padding between waveguide and edge of PML
    dpml = 2  # thickness of PML

    sxy = 2.0 * (r + w + pad + dpml)  # cell size
    resolution = 10.0

    gv = mp.voltwo(sxy, sxy, resolution)
    gv.center_origin()

    sym = mp.mirror(mp.Y, gv)

    # exploit the mirror symmetry in structure+source:
    the_structure = mp.structure(gv, dummy_eps, mp.pml(dpml), sym)

    # Create a ring waveguide by two overlapping cylinders - later objects
    # take precedence over earlier objects, so we put the outer cylinder first.
    # and the inner (air) cylinder second.

    objects = []
    n2 = n * n
    dielectric = gm.Medium(epsilon_diag=gm.Vector3(n2, n2, n2))
    objects.append(gm.Cylinder(r + w, material=dielectric))
    objects.append(gm.Cylinder(r))

    mp.set_materials_from_geometry(the_structure, objects)
    f = mp.fields(the_structure)

    # 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 TM modes (E out of the plane).
    fcen = 0.15  # pulse center frequency
    df = 0.1
    src = GaussianSource(fcen, df)
    v = mp.volume(mp.vec(r + 0.1, 0.0), mp.vec(0.0, 0.0))
    f.add_volume_source(mp.Ez, src, v)

    T = 300.0
    stop_time = f.last_source_time() + T
    while f.round_time() < stop_time:
        f.step()

    # TODO: translate call to harminv
    # int bands = do_harminv (... Ez, vec3(r+0.1), fcen, df)

    # 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.)
    DeltaT = 1.0 / (20 * fcen)
    NextOutputTime = f.round_time() + DeltaT
    while f.round_time() < 1.0 / fcen:
        f.step()
        if f.round_time() >= NextOutputTime:
            f.output_hdf5(mp.Ez, f.total_volume())
            NextOutputTime += DeltaT
Exemplo n.º 4
0
 def make_fields(self):
     if self.gridSizeZ == None:
         self.meep_space = voltwo(self.gridSizeX,self.gridSizeY,self.res)
     else:
         self.meep_space = vol3d(self.gridSizeX,self.gridSizeY,self.gridSizeZ,self.res)
     material = epsilon(self.my_structure)
     set_EPS_Callback(material.__disown__())
     
     
     if self.symmetry_direction == None:
         sym = identity()
     else:
         sym = mirror(self.symmetry_direction,self.meep_space)*self.symmetry_val
         
     self.meep_structure = structure(self.meep_space, EPS, self.boundary_conditions,sym)
     
     
     the_fields = fields(self.meep_structure)
     
     for direc in self.periodic_directions:
         the_fields.set_boundary(Low,direc,Periodic)
         the_fields.set_boundary(High,direc,Periodic)
     
     
     the_fields.use_bloch(self.bloch)
     
     if self.my_source is not None:
         self.my_source.add_to_fields(the_fields)
  
     for f in self.fluxes:
         f.add_to_fields(the_fields)
     
     self.meep_fields = the_fields
     return the_fields
Exemplo n.º 5
0
    def setUp(self):
        def dummy_eps(v):
            return 1.0

        gv = mp.voltwo(16, 16, 10)
        gv.center_origin()
        sym = mp.mirror(mp.Y, gv)
        the_structure = mp.structure(gv, dummy_eps, mp.pml(2), sym)
        objects = []
        objects.append(Cylinder(1))
        mp.set_materials_from_geometry(the_structure, objects)
        self.f = mp.fields(the_structure)
        self.v = mp.volume(mp.vec(1.1, 0.0), mp.vec(0.0, 0.0))
Exemplo n.º 6
0
    def setUp(self):

        def dummy_eps(v):
            return 1.0

        gv = mp.voltwo(16, 16, 10)
        gv.center_origin()
        sym = mp.mirror(mp.Y, gv)
        the_structure = mp.structure(gv, dummy_eps, mp.pml(2), sym)
        objects = []
        objects.append(Cylinder(1))
        mp.set_materials_from_geometry(the_structure, objects)
        self.f = mp.fields(the_structure)
        self.v = mp.volume(mp.vec(1.1, 0.0), mp.vec(0.0, 0.0))
Exemplo n.º 7
0
    def init_fields(self):
        is_cylindrical = self.dimensions == mp.CYLINDRICAL

        if self.structure is None:
            self._init_structure(self.k_point)

        self.fields = mp.fields(
            self.structure,
            self.m if is_cylindrical else 0,
            self.k_point.z if self.special_kz and self.k_point else 0,
            not self.accurate_fields_near_cylorigin
        )

        if self.verbose:
            self.fields.verbose()

        def use_real(self):
            cond1 = is_cylindrical and self.m != 0
            cond2 = any([s.phase.imag for s in self.symmetries])
            cond3 = not self.k_point
            cond4 = self.special_kz and self.k_point.x == 0 and self.k_point.y == 0
            cond5 = not (cond3 or cond4 or self.k_point == Vector3())
            return not (self.force_complex_fields or cond1 or cond2 or cond5)

        if use_real(self):
            self.fields.use_real_fields()
        else:
            print("Meep: using complex fields.")

        if self.k_point:
            v = Vector3(self.k_point.x, self.k_point.y) if self.special_kz else self.k_point
            self.fields.use_bloch(py_v3_to_vec(self.dimensions, v, self.is_cylindrical))

        for s in self.sources:
            self.add_source(s)

        for hook in self.init_fields_hooks:
            hook()
Exemplo n.º 8
0
            pml = Meep.pml(landscape.pml_thickness, direction)
        else:
            pml = Meep.pml(landscape.pml_thickness)

        self.structure = Meep.structure(self.meepVol,
                                        Meep.EPS,
                                        pml,
                                        symmetry=symmetry_object)
        if self.is_nonlinear:
            LOG.debug("Meep node %i, setting chi3" % (self.node_nr))
            self.chi3 = MeepChi3_2D(landscape.simulation_volume, self.meepVol)
            Meep.set_CHI3_Callback(self.chi3.__disown__())
            self.structure.set_chi3(CHI3)

        LOG.debug("Meep node %i -Defining fields..." % (self.node_nr))
        self.meep_fields = Meep.fields(self.structure)
        for src in landscape.sources:
            self.__addMeepSource(src, self.meep_fields)
        for c in landscape.datacollectors:
            if isinstance(c, Fluxplane):
                self.__addMeepFluxplane(c, self.meep_fields)
            elif isinstance(c, Probingpoint):
                c.fieldValueCallback = lambda pComp: self.getFieldAmplitudeAtMonitorPoint(
                    c.point, pComp)
        LOG.debug("Meep node %i -Meep engine initialised!" % (self.node_nr))

    def __createMeepComputationalVolume(self, volume):
        '''Convert the simulation volume (runtime.basic.__SimulationVolume__) into a Meep computational volume'''
        if not isinstance(volume, __SimulationVolume__):
            raise InvalidArgumentException(
                "Invalid argument:: not of type runtime.basic.__SimulationVolume__"
Exemplo n.º 9
0
def bend_flux(no_bend):

    sx = 16.0  # size of cell in X direction
    sy = 32.0  # size of cell in Y direction
    pad = 4.0  # padding distance between waveguide and cell edge
    w = 1.0  # width of waveguide
    resolution = 10  # (set-param! resolution 10)

    gv = mp.voltwo(sx, sy, resolution)
    gv.center_origin()
    the_structure = mp.structure(gv, dummy_eps, mp.pml(1.0))

    wvg_ycen = -0.5 * (sy - w - 2.0 * pad)  # y center of horiz. wvg
    wvg_xcen = 0.5 * (sx - w - 2.0 * pad)  # x center of vert. wvg

    e1 = gm.Vector3(1.0, 0.0, 0.0)
    e2 = gm.Vector3(0.0, 1.0, 0.0)
    e3 = gm.Vector3(0.0, 0.0, 1.0)

    dielectric = gm.Medium(epsilon_diag=gm.Vector3(12, 12, 12))
    if no_bend:
        center = gm.Vector3(y=wvg_ycen)
        size = gm.Vector3(float('inf'), w, float('inf'))
        objects = [
            gm.Block(size, e1, e2, e3, material=dielectric, center=center)
        ]
        mp.set_materials_from_geometry(the_structure, objects)
    else:
        objects = []
        center = gm.Vector3(-0.5 * pad, wvg_ycen)
        size = gm.Vector3(sx - pad, w, float('inf'))
        objects.append(
            gm.Block(size, e1, e2, e3, material=dielectric, center=center))

        center = gm.Vector3(wvg_xcen, 0.5 * pad)
        size = gm.Vector3(w, sy - pad, float('inf'))
        objects.append(
            gm.Block(size, e1, e2, e3, material=dielectric, center=center))
        mp.set_materials_from_geometry(the_structure, objects)

    f = mp.fields(the_structure)

    fcen = 0.15  # pulse center frequency
    df = 0.1
    src = GaussianSource(fcen, df)
    v = mp.volume(mp.vec(1.0 - 0.5 * sx, wvg_ycen), mp.vec(0.0, w))
    f.add_volume_source(mp.Ez, src, v)

    f_start = fcen - 0.5 * df
    f_end = fcen + 0.5 * df
    nfreq = 100  # number of frequencies at which to compute flux

    if no_bend:
        trans_volume = mp.volume(mp.vec(0.5 * sx - 1.5, wvg_ycen),
                                 mp.vec(0.0, 2.0 * w))
    else:
        trans_volume = mp.volume(mp.vec(wvg_xcen, 0.5 * sy - 1.5),
                                 mp.vec(2.0 * w, 0.0))

    trans_vl = mp.volume_list(trans_volume, mp.Sz)
    trans = f.add_dft_flux(trans_vl, f_start, f_end, nfreq)

    refl_volume = mp.volume(mp.vec(-0.5 * sx + 1.5, wvg_ycen),
                            mp.vec(0.0, 2.0 * w))
    refl_vl = mp.volume_list(refl_volume, mp.Sz)
    refl = f.add_dft_flux(refl_vl, f_start, f_end, nfreq)

    dataname = "refl-flux"
    if not no_bend:
        refl.load_hdf5(f, dataname)
        refl.scale_dfts(-1.0)

    eval_point = mp.vec(0.5 * sx - 1.5, wvg_ycen) if no_bend else mp.vec(
        wvg_xcen, 0.5 * sy - 1.5)
    deltaT = 50.0
    next_check_time = f.round_time() + deltaT
    tol = 1.0e-3
    max_abs = 0.0
    cur_max = 0.0
    done = False

    while not done:
        f.step()

        # manually check fields-decayed condition
        absEz = abs(f.get_field(mp.Ez, eval_point))
        cur_max = max(cur_max, absEz)
        if f.round_time() >= next_check_time:
            next_check_time += deltaT
            max_abs = max(max_abs, cur_max)
            if max_abs > 0.0 and cur_max < tol * max_abs:
                done = True
            cur_max = 0.0

        # printf("%.2e %.2e %.2e %.2e\n",f.round_time(),absEz,max_abs,cur_max)

    if no_bend:
        refl.save_hdf5(f, dataname)

    print("{}\t\t | {}\t\t | {}".format("Time", "trans flux", "refl flux"))
    f0 = fcen - 0.5 * df
    fstep = df / (nfreq - 1)
    trans_flux = trans.flux()
    refl_flux = refl.flux()
    for nf in range(nfreq):
        print("{}\t\t | {}\t\t | {}".format(f0 + nf * fstep, trans_flux[nf],
                                            refl_flux[nf]))