Exemplo n.º 1
0
model_param = meep_utils.process_param(sys.argv[1:])
model = metamaterial_models.models[model_param.get('model', 'default')](**model_param)

## Initialize volume, structure and the fields according to the model
vol = meep.vol3d(model.size_x, model.size_y, model.size_z, 1./model.resolution)
vol.center_origin()
s = meep_utils.init_structure(model=model, volume=vol, pml_axes=meep.Z)
f = meep.fields(s)
# Define the Bloch-periodic boundaries (any transversal component of k-vector is allowed)
f.use_bloch(meep.X, getattr(model, 'Kx', 0) / (-2*np.pi)) 
f.use_bloch(meep.Y, getattr(model, 'Ky', 0) / (-2*np.pi))

# Add the field source (see meep_utils for an example of how an arbitrary source waveform is defined)
if not getattr(model, 'frequency', None):       ## (temporal source shape)
    #src_time_type = meep.band_src_time(model.src_freq/c, model.src_width/c, model.simtime*c/1.1)
    src_time_type = meep.gaussian_src_time(model.src_freq/c, model.src_width/c)
else:
    src_time_type = meep.continuous_src_time(getattr(model, 'frequency', None)/c)
srcvolume = meep.volume(                    ## (spatial source shape)
        meep.vec(-model.size_x/2, -model.size_y/2, -model.size_z/2+model.pml_thickness),
        meep.vec( model.size_x/2,  model.size_y/2, -model.size_z/2+model.pml_thickness))

#f.add_volume_source(meep.Ex, src_time_type, srcvolume)
## Replace the f.add_volume_source(meep.Ex, srctype, srcvolume) line with following:
## Option for a custom source (e.g. exciting some waveguide mode)
class SrcAmplitudeFactor(meep.Callback): 
    ## The source amplitude is complex -> phase factor modifies its direction
    ## todo: implement in MEEP: we should define an AmplitudeVolume() object and reuse it for monitors later
    def __init__(self, Kx=0, Ky=0): 
        meep.Callback.__init__(self)
        (self.Kx, self.Ky) = Kx, Ky
Exemplo n.º 2
0
model_param = meep_utils.process_param(sys.argv[1:])
model = metamaterial_models.models[model_param.get('model', 'default')](**model_param)

## Initialize volume, structure and the fields according to the model
vol = meep.vol3d(model.size_x, model.size_y, model.size_z, 1./model.resolution)
vol.center_origin()
s = meep_utils.init_structure(model=model, volume=vol, pml_axes=meep.Z)
f = meep.fields(s)
# Define the Bloch-periodic boundaries (any transversal component of k-vector is allowed)
f.use_bloch(meep.X, getattr(model, 'Kx', 0) / (-2*np.pi)) 
f.use_bloch(meep.Y, getattr(model, 'Ky', 0) / (-2*np.pi))

# Add the field source (see meep_utils for an example of how an arbitrary source waveform is defined)
if not getattr(model, 'frequency', None):       ## (temporal source shape)
    #src_time_type = meep.band_src_time(model.src_freq/c, model.src_width/c, model.simtime*c/1.1)
    src_time_type = meep.gaussian_src_time(model.src_freq/c, model.src_width/c)
else:
    src_time_type = meep.continuous_src_time(getattr(model, 'frequency', None)/c)
srcvolume = meep.volume(                    ## (spatial source shape)
        meep.vec(-model.size_x/2, -model.size_y/2, -model.size_z/2+model.pml_thickness),
        meep.vec( model.size_x/2,  model.size_y/2, -model.size_z/2+model.pml_thickness))

#f.add_volume_source(meep.Ex, src_time_type, srcvolume)
## Replace the f.add_volume_source(meep.Ex, srctype, srcvolume) line with following:
## Option for a custom source (e.g. exciting some waveguide mode)
class SrcAmplitudeFactor(meep.Callback): 
    ## The source amplitude is complex -> phase factor modifies its direction
    ## todo: implement in MEEP: we should define an AmplitudeVolume() object and reuse it for monitors later
    def __init__(self, Kx=0, Ky=0): 
        meep.Callback.__init__(self)
        (self.Kx, self.Ky) = Kx, Ky
vol.center_origin()
s = meep_utils.init_structure(model=model,
                              volume=vol,
                              sim_param=sim_param,
                              pml_axes="All")  ## XXX   meep.XY

## Create the fields object, and define the Bloch-periodic boundaries (any transversal component of k-vector is allowed)
field = meep.fields(s)
#field.use_bloch(meep.Z, 1)          ## periodic along the cylinder XXX
# (removing cylinder caps -> making an infinite waveguide with periodic boundary condition, change pml_axes=meep.XY)

# Add the field source (see meep_utils for an example of how an arbitrary source waveform is defined)
if not sim_param['frequency_domain']:  ## Select the source dependence on time
    #src_time_type = meep.band_src_time(-model.src_freq/c, model.src_width/c, model.simtime*c/1.1)
    src_time_type = meep.gaussian_src_time(
        -model.src_freq / c, model.src_width /
        c)  ## negative frequency supplied -> e^(+i omega t) convention
else:
    src_time_type = meep.continuous_src_time(
        -sim_param['frequency'] / c
    )  ## TODO check in freq domain that negative frequency is OK, and is it needed?
srcvolume = meep.volume(
    meep.vec(model.radius * .15, -model.radius * .25, -model.height * .15),
    meep.vec(model.radius * .15, -model.radius * .25, -model.height * .15))
field.add_volume_source(
    meep.Ez, src_time_type, srcvolume
)  ## source of oblique polarization - excites both TE and TM modes
field.add_volume_source(meep.Ex, src_time_type, srcvolume)

slice_makers = []
#slice_makers += [meep_utils.Slice(model=model, field=field, components=(meep.Ex, meep.Ey, meep.Ez), at_t=3, name="ElectricAtEnd")]
Exemplo n.º 4
0
    def run(self):

        ## TEMPORARY SETTINGS

        wg_bottom = 0.7
        wg_top = 0.7 + 0.22
        wg_center = (wg_bottom + wg_top) / 2.

        #top = 0.7 + 0.38

        ## preparing

        po = self.property_object
        self.engine.initialise_engine(self.landscape)
        fields = meep.fields(self.engine.structure)
        self.save_engine_dielectricum_to_file(po.eps_filename)

        ## Sources

        print 'Center wavelength:', po.wavelength
        print 'Bandwidth:', po.pulse_width
        center_freq = 1.0 / (float(po.wavelength))
        pulse_width_freq = (float(po.pulse_width)) / (
            float(po.wavelength)) * center_freq
        print 'Center frequency:', center_freq
        print 'Bandwidth:', pulse_width_freq

        if (po.pulsed_source):
            src = meep.gaussian_src_time(center_freq, pulse_width_freq)
        else:
            src = meep.continuous_src_time(center_freq)

        source_port_position = po.input_port.transform_copy(
            Translation(translation=(po.source_input_port_offset, 0))).position
        print 'wg_center_old:', wg_center
        wg_center = (po.input_port.wg_definition.process.wg_upper_z_coord +
                     po.input_port.wg_definition.process.wg_lower_z_coord) / 2.
        print 'wg_center_new:', wg_center
        c = Coord3(source_port_position[0], source_port_position[1], wg_center)
        print 'coord:', c
        source_position_vec = self.make_meep_vec(c)

        fields.add_point_source(meep.Ey, src, source_position_vec)

        ## 2D Cross section volumes

        for oc in po.output_cuts:
            fn = '%s_eps.h5' % oc.filename
            vol = oc.get_output_volume(self.engine.meepVol)
            f_eps = meep.prepareHDF5File(fn)
            fields.output_hdf5(meep.Dielectric, vol, f_eps)
            del f_eps
            system('h5topng %s' % fn)

        ### Fluxplanes

        self.fluxes = []
        for p in po.output_ports:
            pp = p.position
            port_width = p.wg_definition.wg_width
            wg_bottom = p.wg_definition.process.wg_lower_z_coord
            wg_top = p.wg_definition.process.wg_upper_z_coord

            ## Be aware: this is only for ports along y-axis!!
            vec_near = self.make_meep_vec(
                Coord3(pp[0], pp[1] - port_width / 2.0, wg_bottom))
            vec_far = self.make_meep_vec(
                Coord3(pp[0], pp[1] + port_width / 2.0, wg_top))

            fluxplane = meep.volume(vec_near, vec_far)
            fx = fields.add_dft_flux_plane(
                fluxplane, center_freq - (pulse_width_freq / 4.0),
                center_freq + (pulse_width_freq / 4.0), po.dft_terms)
            self.fluxes.append(fx)

        ## Reverse one of the fluxes if necessary

        if po.load_reversed_flux_from_file_ID > -1:
            self.fluxes[po.load_reversed_flux_from_file_ID].load_hdf5(
                fields, po.load_reversed_flux_from_file_filename)

        if (po.pulsed_source):
            stop = po.stop_time_multiplier * fields.last_source_time()
        else:
            stop = po.stop_time

        print 'Simulation will run for', stop, 'time units'

        output_files = []
        for oc in po.output_cuts:
            fn = '%s.h5' % oc.filename
            oc_file = meep.prepareHDF5File(fn)
            output_files.append(oc_file)

        i = 0
        n_o_output = 0
        while (fields.time() < stop):
            if (i > po.output_steps):
                j = 0
                for oc in po.output_cuts:
                    vol = oc.get_output_volume(self.engine.meepVol)
                    fields.output_hdf5(meep.Ey, vol, output_files[j], 1)
                    j += 1
                n_o_output += 1
                i = 0
            fields.step()
            i += 1

        print n_o_output, 'images outputted'
        print 'Outputting field images..'
        del output_files[:]
        for oc in po.output_cuts:
            fn = '%s.h5' % oc.filename
            fn_eps = '%s_eps.h5' % oc.filename
            st = 'h5topng -t 0:%d -R -Zc dkbluered -a yarg -A %s %s' % (
                n_o_output - 1, fn_eps, fn)
            print st
            system(st)
        print 'Outputting done!'

        #print 'obtaining fluxes:'
        self.flux_data = []
        for i in range(len(po.output_ports)):
            fd = meep.getFluxData(self.fluxes[i])
            self.flux_data.append(fd)
            #print fd

        ## Save flux data if necesarry

        if po.save_reversed_flux_to_file_ID > -1:
            fx = self.fluxes[po.save_reversed_flux_to_file_ID]
            fx.scale_dfts(-1)
            fx.save_hdf5(fields, po.save_reversed_flux_to_file_filename)

        return
Exemplo n.º 5
0
if not sim_param['frequency_domain']:
    meep.master_printf("== Time domain structure setup ==\n")
    ## Define each polarizability by redirecting the callback to the corresponding "where_material" function
    ## Define the frequency-independent epsilon for all materials (needed here, before defining s, or unstable)
    model.double_vec = model.eps
    meep.set_EPS_Callback(model.__disown__())
    s = meep.structure(vol, meep.EPS, perfectly_matched_layers,
                       meep.identity())

    ## Add all the materials
    model.build_polarizabilities(s)

    ## Add the source dependence
    #srctype = meep.band_src_time(model.srcFreq/c, model.srcWidth/c, model.simtime*c/1.1)
    srctype = meep.gaussian_src_time(model.srcFreq / c, model.srcWidth /
                                     c)  ## , 0, 1000e-12    ??

else:
    meep.master_printf(
        "== Frequency domain structure setup (for frequency of %g Hz) ==\n" %
        sim_param['frequency'])
    if (model.Kx != 0 or model.Ky != 0):
        print "Warning: frequency-domain solver may be broken for nonperpendicular incidence"
    ## Frequency-domain simulation does not support dispersive materials yet. We must define each material by
    ## using the nondispersive permittivity and the nondispersive conductivity
    ## (both calculated from polarizabilities at given frequency)

    ## Define the frequency-independent epsilon for all materials (has to be done _before_ defining s, or unstable)
    my_eps = meep_utils.MyHiFreqPermittivity(model, sim_param['frequency'])
    meep.set_EPS_Callback(my_eps.__disown__())
    s = meep.structure(vol, meep.EPS, perfectly_matched_layers,
Exemplo n.º 6
0
## Define the Perfectly Matched Layers
perfectly_matched_layers = meep.pml(model.pml_thickness)          ## PML on both faces at Z axis

if not sim_param['frequency_domain']:
    meep.master_printf("== Time domain structure setup ==\n")
    ## Define each polarizability by redirecting the callback to the corresponding "where_material" function
    ## Define the frequency-independent epsilon for all materials (needed here, before defining s, or unstable)
    model.double_vec = model.get_static_permittivity; meep.set_EPS_Callback(model.__disown__())
    s = meep.structure(vol, meep.EPS, perfectly_matched_layers, meep.identity())

    ## Add all the materials
    model.build_polarizabilities(s)

    ## Add the source dependence
    #srctype = meep.band_src_time(model.srcFreq/c, model.srcWidth/c, model.simtime*c/1.1)
    srctype = meep.gaussian_src_time(model.srcFreq/c, model.srcWidth/c) ## , 0, 1000e-12    ?? 

else:
    meep.master_printf("== Frequency domain structure setup (for frequency of %g Hz) ==\n" % sim_param['frequency'])
    if (model.Kx!=0 or model.Ky!=0): print "Warning: frequency-domain solver may be broken for nonperpendicular incidence"
    ## Frequency-domain simulation does not support dispersive materials yet. We must define each material by 
    ## using the nondispersive permittivity and the nondispersive conductivity 
    ## (both calculated from polarizabilities at given frequency)

    ## Define the frequency-independent epsilon for all materials (has to be done _before_ defining s, or unstable)
    my_eps = meep_utils.MyHiFreqPermittivity(model, sim_param['frequency'])
    meep.set_EPS_Callback(my_eps.__disown__())
    s = meep.structure(vol, meep.EPS, perfectly_matched_layers, meep.identity()) 

    ## Create callback to set nondispersive conductivity (depends on material polarizabilities and frequency)
    mc = meep_utils.MyConductivity(model, sim_param['frequency'])
if sim_param['frequency_domain']: model.simulation_name += ("_frequency=%.4e" % sim_param['frequency'])

## Initialize volume and structure according to the model
vol = meep.vol3d(model.size_x, model.size_y, model.size_z, 1./model.resolution)
vol.center_origin()
s = meep_utils.init_structure(model=model, volume=vol, sim_param=sim_param, pml_axes="All") ## XXX   meep.XY

## Create the fields object, and define the Bloch-periodic boundaries (any transversal component of k-vector is allowed)
field = meep.fields(s)
#field.use_bloch(meep.Z, 1)          ## periodic along the cylinder XXX
# (removing cylinder caps -> making an infinite waveguide with periodic boundary condition, change pml_axes=meep.XY)

# Add the field source (see meep_utils for an example of how an arbitrary source waveform is defined)
if not sim_param['frequency_domain']:           ## Select the source dependence on time
    #src_time_type = meep.band_src_time(-model.src_freq/c, model.src_width/c, model.simtime*c/1.1)
    src_time_type = meep.gaussian_src_time(-model.src_freq/c, model.src_width/c)  ## negative frequency supplied -> e^(+i omega t) convention
else:
    src_time_type = meep.continuous_src_time(-sim_param['frequency']/c) ## TODO check in freq domain that negative frequency is OK, and is it needed?
srcvolume = meep.volume( 
        meep.vec(model.radius*.15, -model.radius*.25, -model.height*.15),
        meep.vec(model.radius*.15, -model.radius*.25, -model.height*.15))
field.add_volume_source(meep.Ez, src_time_type, srcvolume) ## source of oblique polarization - excites both TE and TM modes
field.add_volume_source(meep.Ex, src_time_type, srcvolume)

slice_makers =  []
#slice_makers += [meep_utils.Slice(model=model, field=field, components=(meep.Ex, meep.Ey, meep.Ez), at_t=3, name="ElectricAtEnd")]
#slice_makers += [meep_utils.Slice(model=model, field=field, components=(meep.Hx, meep.Hy, meep.Hz), at_t=3, name="MagneticAtEnd")]
#slice_makers =  [meep_utils.Slice(model=model, field=field, components=(meep.Dielectric), at_t=0, name='EPS')]

if not sim_param['frequency_domain']:       ## time-domain computation
    field.step()