Esempio n. 1
0
## 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
    def complex_vec(self, vec):   ## Note: the 'vec' coordinates are _relative_ to the source center
        # (oblique) plane wave source:
Esempio n. 2
0
## 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
    def complex_vec(self, vec):   ## Note: the 'vec' coordinates are _relative_ to the source center
        # (oblique) plane wave source:
Esempio n. 3
0
s = meep_utils.init_structure(model=model,
                              volume=vol,
                              sim_param=sim_param,
                              pml_axes="All")

## Create fields with Bloch-periodic boundaries (any transversal component of k-vector is allowed, but may not radiate)
f = meep.fields(s)

## Add a source of the plane wave (see meep_utils for definition of arbitrary source shape)
if not sim_param['frequency_domain']:  ## Select the source dependence on time
    src_time_type = meep.band_src_time(model.srcFreq / c / 2,
                                       model.srcWidth / c,
                                       model.simtime * c / 1.1)
    #src_time_type = meep.gaussian_src_time(model.srcFreq/c, model.srcWidth/c)
else:
    src_time_type = meep.continuous_src_time(sim_param['frequency'] / c)

# XXX srcvolume = meep.volume(
#meep.vec(-model.wgheight/2, -model.size_y/4-model.wgwidth/2, -model.size_z/2+model.pml_thickness),
#meep.vec(+model.wgheight/2, -model.size_y/4+model.wgwidth/2, -model.size_z/2+model.pml_thickness))
srcvolume = meep.volume(
    meep.vec(-model.size_x / 2, -model.size_y / 2 + model.pml_thickness),
    meep.vec(model.size_x / 2, -model.size_y / 2 + model.pml_thickness))


## 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):
Esempio n. 4
0
# Model selection
sim_param, model_param = meep_utils.process_param(sys.argv[1:])
model = PlasmonFilm_model(**model_param)
if sim_param['frequency_domain']: model.simulation_name += ("_frequency=%.4e" % sim_param['frequency'])

## 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, sim_param=sim_param, pml_axes="All")

## Create fields with Bloch-periodic boundaries 
f = meep.fields(s)

# Add the field source (see meep_utils for an example of how an arbitrary source waveform is defined)
src_time_type = meep.continuous_src_time(model.src_freq/c)
srcvolume = meep.volume( 
        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)


## Define visualisation output
slices =  [meep_utils.Slice(model=model, field=f, components=(meep.Dielectric), at_t=0, name='EPS')]
slices += [meep_utils.Slice(model=model, field=f, components=meep.Ez, at_y=0, min_timestep=.3e-15, outputgif=True, name='ParallelCut')]
slices += [meep_utils.Slice(model=model, field=f, components=meep.Ez, at_z=model.metalthick/2+model.resolution, min_timestep=.3e-15, outputgif=True, name='PerpendicularCut')]
slices += [meep_utils.Slice(model=model, field=f, components=meep.Ex, at_t=100e-15)]

if not sim_param['frequency_domain']:       ## time-domain computation
    f.step(); timer = meep_utils.Timer(simtime=model.simtime); meep.quiet(True) # use custom progress messages
    while (f.time()/c < model.simtime):     # timestepping cycle
Esempio n. 5
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
                              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
Esempio n. 7
0
# Model selection
model_param = meep_utils.process_param(sys.argv[1:])
model = PlasmonFilm_model(**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="All")

## Create fields with Bloch-periodic boundaries
f = meep.fields(s)

# Add the field source (see meep_utils for an example of how an arbitrary source waveform is defined)
src_time_type = meep.continuous_src_time(model.src_freq / c)
srcvolume = meep.volume(
    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)

## Define visualisation output
slices = [
    meep_utils.Slice(model=model,
                     field=f,
                     components=(meep.Dielectric),
                     at_t=0,
                     name='EPS')
]
Esempio n. 8
0
## Initialize volume and structure according to the model
#XXX vol = meep.vol2d(model.size_x, model.size_y, 1./model.resolution)
vol = meep.vol2d(model.size_x, model.size_y, 1./model.resolution)
vol.center_origin()
#s = meep_utils.init_structure(model=model, volume=vol, sim_param=sim_param, pml_axes=meep.Z)
s = meep_utils.init_structure(model=model, volume=vol, sim_param=sim_param, pml_axes="All")

## Create fields with Bloch-periodic boundaries (any transversal component of k-vector is allowed, but may not radiate)
f = meep.fields(s)

## Add a source of the plane wave (see meep_utils for definition of arbitrary source shape)
if not sim_param['frequency_domain']:           ## Select the source dependence on time
    src_time_type = meep.band_src_time(model.srcFreq/c / 2 , model.srcWidth/c, model.simtime*c/1.1)
    #src_time_type = meep.gaussian_src_time(model.srcFreq/c, model.srcWidth/c)
else:
    src_time_type = meep.continuous_src_time(sim_param['frequency']/c)

# XXX srcvolume = meep.volume( 
        #meep.vec(-model.wgheight/2, -model.size_y/4-model.wgwidth/2, -model.size_z/2+model.pml_thickness),
        #meep.vec(+model.wgheight/2, -model.size_y/4+model.wgwidth/2, -model.size_z/2+model.pml_thickness))
srcvolume = meep.volume( 
        meep.vec(-model.size_x/2, -model.size_y/2+model.pml_thickness),
        meep.vec( model.size_x/2, -model.size_y/2+model.pml_thickness))
## 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)
    def complex_vec(self, vec):   ## Note: the 'vec' coordinates are _relative_ to the source center
        return (np.random.random()-.5) + 1j*(np.random.random()-.5)
Esempio n. 9
0
    ## 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'])
    meep.set_COND_Callback(mc.__disown__())
    s.set_conductivity(meep.E_stuff,
                       meep.COND)  ## only "E_stuff" worked here for me
    srctype = meep.continuous_src_time(sim_param['frequency'] / c)

## Create fields with Bloch-periodic boundaries (any nonzero transversal component of k-vector is possible)
f = meep.fields(s)
f.use_bloch(meep.X, -model.Kx / (2 * np.pi))
f.use_bloch(meep.Y, -model.Ky / (2 * np.pi))

## Add a source of a plane wave (with possibly oblique incidence)
## Todo implement in MEEP: we should define an AmplitudeVolume() object and reuse it for monitors later
srcvolume = meep.volume(
    meep.vec(-model.size_x / 2, -model.size_y / 2, -model.size_z / 2 +
             model.pml_thickness),  ## TODO try from -inf to +inf
    meep.vec(model.size_x / 2, model.size_y / 2,
             -model.size_z / 2 + model.pml_thickness))

Esempio n. 10
0
    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'])
    meep.set_COND_Callback(mc.__disown__())
    s.set_conductivity(meep.E_stuff, meep.COND)  ## only "E_stuff" worked here for me
    srctype = meep.continuous_src_time(sim_param['frequency']/c)


## Create fields with Bloch-periodic boundaries (any nonzero transversal component of k-vector is possible)
f = meep.fields(s)
f.use_bloch(meep.X, -model.Kx/(2*np.pi))
f.use_bloch(meep.Y, -model.Ky/(2*np.pi))

## Add a source of a plane wave (with possibly oblique incidence)
## Todo implement in MEEP: we should define an AmplitudeVolume() object and reuse it for monitors later
srcvolume = meep.volume( 
        meep.vec(-model.size_x/2, -model.size_y/2, -model.size_z/2+model.pml_thickness),  ## TODO try from -inf to +inf
        meep.vec(model.size_x/2, model.size_y/2, -model.size_z/2+model.pml_thickness))
## TODO  move whole amplitude factor to meep_utils, exp(-1j*(a*x+b*y) - ((c*x)**2 + (d*y)**2))
class AmplitudeFactor(meep.Callback): 
    def __init__(self, Kx=0, Ky=0): 
## 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()
    dt = (field.time()/c)
    meep_utils.lorentzian_unstable_check_new(model, dt, quit_on_warning=False)
                              pml_axes="All")  ## XXX   meep.XY
f = meep.fields(s)
# Define the Bloch-periodic boundaries (any transversal component of k-vector is allowed)
#f.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 getattr(model, 'frequency',
               None):  ## 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(
        -getattr(model, 'frequency', None) / 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))
f.add_volume_source(
    meep.Ez, src_time_type, srcvolume
)  ## source of oblique polarization - excites both TE and TM modes
f.add_volume_source(meep.Ex, src_time_type, srcvolume)

slices = []
if not "noepssnapshot" in model.comment:
    slices += [
        meep_utils.Slice(model=model,
                         field=f,
                         components=(meep.Dielectric),
## 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="All") ## XXX   meep.XY
f = meep.fields(s)
# Define the Bloch-periodic boundaries (any transversal component of k-vector is allowed)
#f.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 getattr(model, 'frequency', None):           ## 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(-getattr(model, 'frequency', None)/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))
f.add_volume_source(meep.Ez, src_time_type, srcvolume) ## source of oblique polarization - excites both TE and TM modes
f.add_volume_source(meep.Ex, src_time_type, srcvolume)

slices = []
if not "noepssnapshot" in model.comment:
    slices += [meep_utils.Slice(model=model, field=f, components=(meep.Dielectric), at_t=0, name='EPS')]
if "narrowfreq-snapshots" in model.comment:
    slices += [meep_utils.Slice(model=model, field=f, components=meep.Ex, at_y=0, at_t=np.inf,
            name=('At%.3eHz'%getattr(model, 'frequency', None)) if getattr(model, 'frequency', None) else '',
            outputpng=True, outputvtk=False)]
if "fieldevolution" in model.comment: 
    slices += [meep_utils.Slice(model=model, field=f, components=(meep.Ex), at_x=0, name='FieldEvolution',