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)
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
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
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))
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()
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__"
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]))