Beispiel #1
0
 def ExH(e, h):
     ev = mp.Vector3(e[0], e[1], e[2])
     hv = mp.Vector3(h[0], h[1], h[2])
     return ev.conj().cross(hv)
Beispiel #2
0
def main(args):
    print("\nstart time:", datetime.now())

    # --------------------------------------------------------------------------
    # physical parameters characterizing light source and interface characteris-
    # tics (must be adjusted - eihter here or via command line interface (CLI))
    # --------------------------------------------------------------------------
    interface = args.interface
    s_pol = args.s_pol
    ref_medium = args.ref_medium

    n1 = args.n1
    n2 = args.n2

    kw_0 = args.kw_0
    kr_w = args.kr_w
    kr_c = args.kr_c

    # angle of incidence
    chi_deg = args.chi_deg
    #chi_deg = 1.0*op.critical(n1, n2)
    #chi_deg = 0.95*op.brewster(n1, n2)

    # --------------------------------------------------------------------------
    # specific Meep parameters (may need to be adjusted)
    # --------------------------------------------------------------------------
    sx = 5  # size of cell including PML in x-direction
    sy = 5  # size of cell including PML in y-direction
    pml_thickness = 0.25  # thickness of PML layer
    freq = 12  # vacuum frequency of source (5 to 12 is good)
    runtime = 10  # runs simulation for 10 times freq periods

    # number of pixels per wavelength in the denser medium (at least 10,
    # 20 to 30 is a good choice)
    pixel = 10

    # source position with respect to the center (point of impact) in Meep
    # units (-2.15 good); if equal -r_w, then source position coincides with
    # waist position
    source_shift = -2.15

    # --------------------------------------------------------------------------
    # derived (Meep) parameters (do not change)
    # --------------------------------------------------------------------------
    k_vac = 2 * math.pi * freq
    k1 = n1 * k_vac
    n_ref = (1 if ref_medium == 0 else
             n1 if ref_medium == 1 else n2 if ref_medium == 2 else math.nan)
    r_w = kr_w / (n_ref * k_vac)
    w_0 = kw_0 / (n_ref * k_vac)
    r_c = kr_c / (n_ref * k_vac)
    shift = source_shift + r_w
    chi_rad = math.radians(chi_deg)

    params = dict(W_y=w_0, k=k1)

    # --------------------------------------------------------------------------
    # placement of the dielectric interface within the computational cell
    # --------------------------------------------------------------------------
    # helper functions
    def alpha(chi_rad):
        """Angle of inclined plane with y-axis in radians."""
        return math.pi / 2 - chi_rad

    def Delta_x(alpha):
        """Inclined plane offset to the center of the cell."""
        sin_alpha = math.sin(alpha)
        cos_alpha = math.cos(alpha)
        return (sx / 2) * ((
            (math.sqrt(2) - cos_alpha) - sin_alpha) / sin_alpha)

    cell = mp.Vector3(sx, sy, 0)  # geometry-lattice

    if interface == "planar":
        default_material = mp.Medium(index=n1)
        # located at lower right edge for 45 degree
        geometry = [
            mp.Block(size=mp.Vector3(mp.inf, sx * math.sqrt(2), mp.inf),
                     center=mp.Vector3(+sx / 2 + Delta_x(alpha(chi_rad)),
                                       -sy / 2),
                     e1=mp.Vector3(1 / math.tan(alpha(chi_rad)), 1, 0),
                     e2=mp.Vector3(-1, 1 / math.tan(alpha(chi_rad)), 0),
                     e3=mp.Vector3(0, 0, 1),
                     material=mp.Medium(index=n2))
        ]
    elif interface == "concave":
        default_material = mp.Medium(index=n2)
        # move center to the right in order to ensure that the point of impact
        # is always centrally placed
        geometry = [
            mp.Cylinder(center=mp.Vector3(-r_c * math.cos(chi_rad),
                                          +r_c * math.sin(chi_rad)),
                        height=mp.inf,
                        radius=r_c,
                        material=mp.Medium(index=n1))
        ]
    elif interface == "convex":
        default_material = mp.Medium(index=n1)
        # move center to the right in order to ensure that the point of impact
        # is always centrally placed
        geometry = [
            mp.Cylinder(center=mp.Vector3(+r_c * math.cos(chi_rad),
                                          -r_c * math.sin(chi_rad)),
                        height=mp.inf,
                        radius=r_c,
                        material=mp.Medium(index=n2))
        ]

    # --------------------------------------------------------------------------
    # add absorbing boundary conditions and discretize structure
    # --------------------------------------------------------------------------
    pml_layers = [mp.PML(pml_thickness)]
    resolution = pixel * (n1 if n1 > n2 else n2) * freq
    # set Courant factor (mandatory if either n1 or n2 is smaller than 1)
    Courant = (n1 if n1 < n2 else n2) / 2

    # --------------------------------------------------------------------------
    # display values of physical variables
    # --------------------------------------------------------------------------
    print()
    print("Specified variables and derived values:")
    print("n1:", n1)
    print("n2:", n2)
    print("chi:  ", chi_deg, " [degree]")
    print("incl.:", 90 - chi_deg, " [degree]")
    print("kw_0: ", kw_0)
    if interface != "planar":
        print("kr_c: ", kr_c)
    print("kr_w: ", kr_w)
    print("k_vac:", k_vac)
    print("polarisation:", "s" if s_pol else "p")
    print("interface:", interface)
    print()

    # --------------------------------------------------------------------------
    # specify current source, output functions and run simulation
    # --------------------------------------------------------------------------
    force_complex_fields = False  # default: False
    eps_averaging = True  # default: True
    filename_prefix = None

    # specify optical beam
    beam = op.Gauss2d(x=shift, params=params)

    sources = [
        mp.Source(src=mp.ContinuousSource(frequency=freq, width=0.5),
                  component=mp.Ez if s_pol else mp.Ey,
                  size=mp.Vector3(0, 2, 0),
                  center=mp.Vector3(source_shift, 0, 0),
                  amp_func=beam.profile)
    ]

    sim = mp.Simulation(cell_size=cell,
                        boundary_layers=pml_layers,
                        default_material=default_material,
                        Courant=Courant,
                        geometry=geometry,
                        sources=sources,
                        resolution=resolution,
                        force_complex_fields=force_complex_fields,
                        eps_averaging=eps_averaging,
                        filename_prefix=filename_prefix)

    sim.use_output_directory(
        interface)  # put output files in a separate folder

    def eSquared(r, ex, ey, ez):
        """Calculate |E|^2.

        With |.| denoting the complex modulus if 'force_complex_fields?'
        is set to true, otherwise |.| gives the Euclidean norm.
        """
        return mp.Vector3(ex, ey, ez).norm()**2

    def output_efield2(sim):
        """Output E-field intensity."""
        name = "e2_s" if s_pol else "e2_p"
        func = eSquared
        cs = [mp.Ex, mp.Ey, mp.Ez]
        return sim.output_field_function(name, cs, func, real_only=True)

    sim.run(mp.at_beginning(mp.output_epsilon),
            mp.at_end(mp.output_efield_z if s_pol else mp.output_efield_y),
            mp.at_end(output_efield2),
            until=runtime)

    print("\nend time:", datetime.now())
Beispiel #3
0
def main(args):
    sx = 16  # size of cell in X direction
    sy = 32  # size of cell in Y direction
    cell = mp.Vector3(sx, sy, 0)

    pad = 4  # padding distance between waveguide and cell edge
    w = 1  # width of waveguide

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

    if args.no_bend:
        geometry = [mp.Block(mp.Vector3(mp.inf, w, mp.inf), center=mp.Vector3(0, wvg_ycen),
                             material=mp.Medium(epsilon=12))]
    else:
        geometry = [mp.Block(mp.Vector3(sx - pad, w, mp.inf), center=mp.Vector3(-0.5 * pad, wvg_ycen),
                             material=mp.Medium(epsilon=12)),
                    mp.Block(mp.Vector3(w, sy - pad, mp.inf), center=mp.Vector3(wvg_xcen, 0.5 * pad),
                             material=mp.Medium(epsilon=12))]

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

    sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez,
                         center=mp.Vector3(1 + (-0.5 * sx), wvg_ycen), size=mp.Vector3(0, w))]

    pml_layers = [mp.PML(1.0)]
    resolution = 10

    nfreq = 100  # number of frequencies at which to compute flux

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

    if args.no_bend:
        fr = mp.FluxRegion(center=mp.Vector3((sx / 2) - 1.5, wvg_ycen), size=mp.Vector3(0, w * 2))
    else:
        fr = mp.FluxRegion(center=mp.Vector3(wvg_xcen, (sy / 2) - 1.5), size=mp.Vector3(w * 2, 0))

    trans = sim.add_flux(fcen, df, nfreq, fr)

    refl_fr = mp.FluxRegion(center=mp.Vector3((-0.5 * sx) + 1.5, wvg_ycen),
                            size=mp.Vector3(0, w * 2))

    # reflected flux
    refl = sim.add_flux(fcen, df, nfreq, refl_fr)

    # for normal run, load negated fields to subtract incident from refl. fields
    if not args.no_bend:
        sim.load_minus_flux('refl-flux', refl)

    if args.no_bend:
        pt = mp.Vector3((sx / 2) - 1.5, wvg_ycen)
    else:
        pt = mp.Vector3(wvg_xcen, (sy / 2) - 1.5)

    sim.run(mp.at_beginning(mp.output_epsilon),
            until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, pt, 1e-3))

    # for normalization run, save flux fields for refl. plane
    if args.no_bend:
        sim.save_flux('refl-flux', refl)

    sim.display_fluxes(trans, refl)
Beispiel #4
0
 def get_arr2(sim):
     eps['arr2'] = sim.get_array(mp.Volume(mp.Vector3(), mp.Vector3(10, 10)),
                                 component=mp.Dielectric)
Beispiel #5
0
import meep as mp
import numpy as np
import matplotlib.pyplot as plt
from meep import materials
from sinus import create_vertices
sizex = 1
sizey = 2
resolution = 150
pml_th = 30 / resolution
fullx = sizex + 2 * pml_th
fully = sizey + 2 * pml_th
cell = mp.Vector3(fullx, fully, 0)
mat = materials.Au
#####################
# run modes
# geom - show geometry instead of actual simulation
# saveref - save the reference file, needed for field enhancement calculations
####################
aux_mat = mp.Medium(epsilon=1)
geom = False
saveref = True
####################

####################
# geometry, load AFM profile
####################

metal_vert = create_vertices(ampl=0.1,
                             periodicity=0.5,
                             thickness=0.04,
                             resolution=resolution,
Beispiel #6
0
    def init_output_lattice(self):

        cart_map = mp.Matrix(
            mp.Vector3(1, 0, 0),
            mp.Vector3(0, 1, 0),
            mp.Vector3(0, 0, 1)
        )

        Rin = mp.Matrix(
            mp.Vector3(*self.lattice[0]),
            mp.Vector3(*self.lattice[1]),
            mp.Vector3(*self.lattice[2])
        )

        if self.verbose:
            print("Read lattice vectors")
            if self.kpoint:
                fmt = "Read Bloch wavevector ({:.6g}, {:.6g}, {:.6g})"
                print(fmt.format(self.kpoint.x, self.kpoint.y, self.kpoint.z))
            fmt = "Input lattice = ({:.6g}, {:.6g}, {:.6g}), ({:.6g}, {:.6g}, {:.6g}), ({:.6g}, {:.6g}, {:.6g})"
            print(fmt.format(Rin.c1.x, Rin.c1.y, Rin.c1.z,
                             Rin.c2.x, Rin.c2.y, Rin.c2.z,
                             Rin.c3.x, Rin.c3.y, Rin.c3.z))

        Rout = mp.Matrix(Rin.c1, Rin.c2, Rin.c3)

        if self.rectify:
            # Orthogonalize the output lattice vectors.  If have_ve is true,
            # then the first new lattice vector should be in the direction
            # of the ve unit vector; otherwise, the first new lattice vector
            # is the first original lattice vector. Note that we do this in
            # such a way as to preserve the volume of the unit cell, and so
            # that our first vector (in the direction of ve) smoothly
            # interpolates between the original lattice vectors.

            if self.have_ve:
                ve = self.ve.unit()
            else:
                ve = Rout.c1.unit()

            # First, compute c1 in the direction of ve by smoothly
            # interpolating the old c1/c2/c3 (formula is slightly tricky)
            V = Rout.c1.cross(Rout.c2).dot(Rout.c3)
            Rout.c2 = Rout.c2 - Rout.c1
            Rout.c3 = Rout.c3 - Rout.c1
            Rout.c1 = ve.scale(V / Rout.c2.cross(Rout.c3).dot(ve))

            # Now, orthogonalize c2 and c3
            Rout.c2 = Rout.c2 - ve.scale(ve.dot(Rout.c2))
            Rout.c3 = Rout.c3 - ve.scale(ve.dot(Rout.c3))
            Rout.c3 = Rout.c3 - Rout.c2.scale(Rout.c2.dot(Rout.c3) /
                                              Rout.c2.dot(Rout.c2))

            cart_map.c1 = Rout.c1.unit()
            cart_map.c2 = Rout.c2.unit()
            cart_map.c3 = Rout.c3.unit()
            cart_map = cart_map.inverse()

        Rout.c1 = Rout.c1.scale(self.multiply_size[0])
        Rout.c2 = Rout.c2.scale(self.multiply_size[1])
        Rout.c3 = Rout.c3.scale(self.multiply_size[2])

        if self.verbose:
            fmt = "Output lattice = ({:.6g}, {:.6g}, {:.6g}), ({:.6g}, {:.6g}, {:.6g}), ({:.6g}, {:.6g}, {:.6g})"
            print(fmt.format(Rout.c1.x, Rout.c1.y, Rout.c1.z,
                             Rout.c2.x, Rout.c2.y, Rout.c2.z,
                             Rout.c3.x, Rout.c3.y, Rout.c3.z))

        self.coord_map = Rin.inverse() * Rout
        self.Rout = Rout
        self.cart_map = cart_map
Beispiel #7
0
job = pinboard.pinboard()
nm = 1e-9
um = 1e-6

### Parameters
W = 200*nm
sep = 330*nm

material = meep_ext.material.Au()
material = meep.Medium(index=3.5)

geometry = []
q = miepy.quaternion.from_spherical_coords(0, np.pi/4)
R = miepy.quaternion.as_rotation_matrix(q)

geometry.append(meep.Block(center=meep.Vector3(-sep/2, 0, 0),
                           size=meep.Vector3(W, W, W),
                           e1=meep.Vector3(*R[:,0]),
                           e2=meep.Vector3(*R[:,1]),
                           e3=meep.Vector3(*R[:,2]),
                           material=material))
geometry.append(meep.Block(center=meep.Vector3(sep/2, 0, 0),
                           size=meep.Vector3(W, W, W),
                           e1=meep.Vector3(*R[:,0]),
                           e2=meep.Vector3(*R[:,1]),
                           e3=meep.Vector3(*R[:,2]),
                           material=material))


box = [sep + 2**.5*W, 2**.5*W, 2**.5*W]
resolution = 1/(8*nm)
Beispiel #8
0
import meep as mp
import numpy as np
import math

cell_size = mp.Vector3(2, 2, 2)

geometry = [  #mp.Block(center=mp.Vector3(0,0,0), size=cell_size, material=mp.air),
    mp.Ellipsoid(material=mp.metal,
                 size=mp.Vector3(2, 0.5, 0.5),
                 e1=mp.Vector3(1, 1, 1),
                 e2=mp.Vector3(-1, 1, -1),
                 e3=mp.Vector3(-2, 1, 1))
]

sim = mp.Simulation(resolution=50, cell_size=cell_size, geometry=geometry)

sim.init_sim()

eps_data = sim.get_epsilon()
#eps_data = sim.get_array()

#sim.plot3D(eps_data)

#from mayavi import mlab
#s = mlab.contour3d()
#mlab.show()
#mlab.savefig(filename='test2.png')

from mayavi import mlab
s = mlab.contour3d(eps_data, colormap="hsv")
#mlab.show()
Beispiel #9
0
 def get_arr1(sim):
     eps['arr1'] = sim.get_array(
         mp.Dielectric, mp.Volume(mp.Vector3(), mp.Vector3(10, 10)))
Beispiel #10
0
import meep as mp
import math
import numpy as np
import numpy.matlib
import matplotlib.pyplot as plt

resolution = 50  # pixels/um

dpml = 1.0  # PML thickness
sz = 10 + 2 * dpml
cell_size = mp.Vector3(z=sz)
pml_layers = [mp.PML(dpml)]

wvl_min = 0.4  # min wavelength
wvl_max = 0.8  # max wavelength
fmin = 1 / wvl_max  # min frequency
fmax = 1 / wvl_min  # max frequency
fcen = 0.5 * (fmin + fmax)  # center frequency
df = fmax - fmin  # frequency width
nfreq = 50  # number of frequency bins


def planar_reflectance(theta):
    # rotation angle (in degrees) of source: CCW around Y axis, 0 degrees along +Z axis
    theta_r = math.radians(theta)

    # plane of incidence is XZ; rotate counter clockwise (CCW) about y-axis
    k = mp.Vector3(z=fmin).rotate(mp.Vector3(y=1), theta_r)

    # if normal incidence, force number of dimensions to be 1
    if theta_r == 0:
Beispiel #11
0
def planar_reflectance(theta):
    # rotation angle (in degrees) of source: CCW around Y axis, 0 degrees along +Z axis
    theta_r = math.radians(theta)

    # plane of incidence is XZ; rotate counter clockwise (CCW) about y-axis
    k = mp.Vector3(z=fmin).rotate(mp.Vector3(y=1), theta_r)

    # if normal incidence, force number of dimensions to be 1
    if theta_r == 0:
        dimensions = 1
    else:
        dimensions = 3

    sources = [
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Ex,
                  center=mp.Vector3(z=-0.5 * sz + dpml))
    ]

    sim = mp.Simulation(cell_size=cell_size,
                        boundary_layers=pml_layers,
                        sources=sources,
                        k_point=k,
                        dimensions=dimensions,
                        resolution=resolution)

    refl_fr = mp.FluxRegion(center=mp.Vector3(z=-0.25 * sz))
    refl = sim.add_flux(fcen, df, nfreq, refl_fr)

    sim.run(until_after_sources=mp.stop_when_fields_decayed(
        50, mp.Ex, mp.Vector3(z=-0.5 * sz + dpml), 1e-9))

    empty_flux = mp.get_fluxes(refl)
    empty_data = sim.get_flux_data(refl)

    sim.reset_meep()

    # add a block with n=3.5 for the air-dielectric interface
    geometry = [
        mp.Block(mp.Vector3(mp.inf, mp.inf, 0.5 * sz),
                 center=mp.Vector3(z=0.25 * sz),
                 material=mp.Medium(index=3.5))
    ]

    sim = mp.Simulation(cell_size=cell_size,
                        geometry=geometry,
                        boundary_layers=pml_layers,
                        sources=sources,
                        k_point=k,
                        dimensions=dimensions,
                        resolution=resolution)

    refl = sim.add_flux(fcen, df, nfreq, refl_fr)
    sim.load_minus_flux_data(refl, empty_data)

    sim.run(until_after_sources=mp.stop_when_fields_decayed(
        50, mp.Ex, mp.Vector3(z=-0.5 * sz + dpml), 1e-9))

    refl_flux = mp.get_fluxes(refl)
    freqs = mp.get_flux_freqs(refl)

    wvls = np.empty(nfreq)
    theta_out = np.empty(nfreq)
    R = np.empty(nfreq)
    for i in range(nfreq):
        wvls[i] = 1 / freqs[i]
        theta_out[i] = math.degrees(math.asin(k.x / freqs[i]))
        R[i] = -refl_flux[i] / empty_flux[i]
        print("refl:, {}, {}, {}, {}".format(k.x, wvls[i], theta_out[i], R[i]))

    return k.x * np.ones(nfreq), wvls, theta_out, R
Beispiel #12
0
	def __init__(self, resolution):
		self.block_index = 1.53
		self.block_permittivity = self.block_index**2
		self.permittivity_bounds = [1.0, self.block_permittivity]

		self.length_scale_meters = 1e-6
		self.length_scale_microns = self.length_scale_meters * 1e6

		self.num_wavelengths_per_range = 1
		self.num_ranges = 3
		self.num_total_wavelengths = self.num_ranges * self.num_wavelengths_per_range
		self.num_total_frequencies = self.num_total_wavelengths

		self.blue_lower_lambda_um = .4
		self.blue_upper_lambda_um = .5
		self.green_lower_lambda_um = self.blue_upper_lambda_um
		self.green_upper_lambda_um = .6
		self.red_lower_lambda_um = self.green_upper_lambda_um
		self.red_upper_lambda_um = .7

		self.source_lower_lambda_um = self.blue_lower_lambda_um
		self.source_upper_lambda_um = self.red_upper_lambda_um
		self.source_upper_freq_unitless = self.length_scale_microns / self.source_lower_lambda_um;
		self.source_lower_freq_unitless = self.length_scale_microns / self.source_upper_lambda_um;
		self.source_freq_spread_unitless = self.source_upper_freq_unitless - self.source_lower_freq_unitless;
		self.source_freq_center_unitless = 0.5 * (self.source_lower_freq_unitless + self.source_upper_freq_unitless);

		self.dft_freq_min = self.source_lower_freq_unitless
		self.dft_freq_max = self.source_upper_freq_unitless
		self.dft_freq_spread = self.dft_freq_max - self.dft_freq_min
		self.dft_freq_center = self.dft_freq_min + 0.5 * self.dft_freq_spread


		self.frequencies_in_ranges = [[], [], []]
		self.max_intensity = [0] * self.num_total_frequencies
		for freq_idx in range(0, self.num_total_frequencies):
			frequency = ((float(freq_idx) / float(self.num_total_frequencies - 1)) * self.dft_freq_spread) + self.dft_freq_min
			wavelength_um = self.length_scale_microns / frequency

			self.max_intensity[freq_idx] = 1.0 / (wavelength_um * wavelength_um)

			self.frequencies_in_ranges[self.check_frequency_range(frequency)].append(frequency)

		self.max_frequencies_in_a_range = max(list(map(lambda y: len(y), self.frequencies_in_ranges)))

		# Maybe... set this by a real length scaled by the length scale?
		# self.spacing = 0.025 / self.length_scale_microns
		# self.resolution = int(1 / self.spacing)
		self.resolution = resolution
		self.spacing = 1 / resolution

		self.focal_length = 1.5 / self.length_scale_microns
		self.side_gap = 0.5 / self.length_scale_microns
		self.top_bottom_gap = .2 / self.length_scale_microns


		self.block_dim_x = 2 / self.length_scale_microns;
		self.block_dim_y = 2 / self.length_scale_microns;
		self.block_dim_z = 2 / self.length_scale_microns;
		self.block_size = mp.Vector3(self.block_dim_x, self.block_dim_y, self.block_dim_z)

		self.source_loc_z_from_pml = 0.0 / self.length_scale_microns;

		self.t_pml_x = 1.0 / self.length_scale_microns
		self.t_pml_y = 1.0 / self.length_scale_microns
		self.t_pml_z = 1.0 / self.length_scale_microns

		self.cell_dim_x = 2 * self.t_pml_x + 2 * self.side_gap + self.block_dim_x;
		self.cell_dim_y = 2 * self.t_pml_y + 2 * self.side_gap + self.block_dim_y;
		self.cell_dim_z = 2 * self.t_pml_z + 2 * self.top_bottom_gap + self.block_dim_z + self.focal_length;

		self.cell = mp.Vector3(self.cell_dim_x, self.cell_dim_y, self.cell_dim_z)

		self.block_center = mp.Vector3(0, 0, 0.5 * self.cell_dim_z - self.t_pml_z - self.top_bottom_gap - 0.5 * self.block_dim_z)
		self.top_source_center = mp.Vector3(0, 0, 0.5 * self.cell_dim_z - self.t_pml_z)

		self.device = bayer_filter.BayerFilter(self.block_center, self.resolution, self.block_size, self.permittivity_bounds, self.length_scale_meters);

		self.pml_layers = [mp.PML(thickness = self.t_pml_x, direction = mp.X), mp.PML(thickness = self.t_pml_y, direction = mp.Y), mp.PML(thickness = self.t_pml_z, direction = mp.Z)]

		# Run all the way up to and through the PML boundary layers
		self.top_bottom_source_size_x = self.cell_dim_x
		self.top_bottom_source_size_y = self.cell_dim_y
		# Surface currenets
		self.top_bottom_source_size_z = 0;
		self.top_bottom_source_size = mp.Vector3(self.top_bottom_source_size_x, self.top_bottom_source_size_y, self.top_bottom_source_size_z)

		# This is the default value for it, but let's be explicit
		self.gaussian_cutoff = 5.0
		self.gaussian_width = 1.0 / self.source_freq_spread_unitless
		self.gaussian_peak_time = self.gaussian_cutoff * self.gaussian_width

		top_source_J = mp.Source(mp.GaussianSource(self.source_freq_center_unitless, fwidth=self.source_freq_spread_unitless, cutoff=self.gaussian_cutoff, start_time=0),
			component=mp.Ex, amplitude=1.0, center=self.top_source_center, size=self.top_bottom_source_size)
		self.forward_sources = [top_source_J]

		self.geometry = [mp.Block(size=self.block_size, center=self.block_center, epsilon_func=lambda loc: self.device.get_permittivity_value(loc))]

		self.z_measurement_point = self.block_center.z - 0.5 * self.block_dim_z - self.focal_length


		# Let's set up where we want to measure the figure of merit
		self.measure_blue_focal = mp.Vector3(self.block_dim_x / 4.0, self.block_dim_y / 4.0, self.z_measurement_point)
		self.measure_green_xpol_focal = mp.Vector3(-self.block_dim_x / 4.0, self.block_dim_y / 4.0, self.z_measurement_point)
		self.measure_red_focal = mp.Vector3(-self.block_dim_x / 4.0, -self.block_dim_y / 4.0, self.z_measurement_point)
		self.measure_green_ypol_focal = mp.Vector3(self.block_dim_x / 4.0, -self.block_dim_y / 4.0, self.z_measurement_point)

		self.dft_focal_plane_fields_center = mp.Vector3(0, 0, self.z_measurement_point)
		self.dft_focal_area_fields_size = mp.Vector3(self.block_dim_x, self.block_dim_y, 0);
		self.interpolate_focal_area_fields = interp.Interpolate(self.dft_focal_plane_fields_center, self.dft_focal_area_fields_size, self.resolution, 2)


		self.dft_block_fields_center = self.block_center
		self.dft_block_fields_size = self.block_size
		self.focal_plane_centers = [self.measure_blue_focal, self.measure_green_xpol_focal, self.measure_red_focal, self.measure_green_ypol_focal]


		self.xy_symmetry_transformation = [0] * 4
		self.xy_symmetry_transformation[BayerOptimization.QUADRANT_TOP_RIGHT] = BayerOptimization.QUADRANT_TOP_RIGHT
		self.xy_symmetry_transformation[BayerOptimization.QUADRANT_TOP_LEFT] = BayerOptimization.QUADRANT_BOTTOM_RIGHT
		self.xy_symmetry_transformation[BayerOptimization.QUADRANT_BOTTOM_LEFT] = BayerOptimization.QUADRANT_BOTTOM_LEFT
		self.xy_symmetry_transformation[BayerOptimization.QUADRANT_BOTTOM_RIGHT] = BayerOptimization.QUADRANT_TOP_LEFT

		self.range_to_quadrant = [0] * 4
		self.range_to_quadrant[BayerOptimization.RANGE_RED] = BayerOptimization.QUADRANT_RED
		self.range_to_quadrant[BayerOptimization.RANGE_GREEN] = [BayerOptimization.QUADRANT_GREEN_XPOL, BayerOptimization.QUADRANT_GREEN_YPOL]
		self.range_to_quadrant[BayerOptimization.RANGE_BLUE] = BayerOptimization.QUADRANT_BLUE

		self.quadrant_to_range = [0] * 4
		self.quadrant_to_range[BayerOptimization.QUADRANT_RED] = BayerOptimization.RANGE_RED
		self.quadrant_to_range[BayerOptimization.QUADRANT_GREEN_XPOL] = BayerOptimization.RANGE_GREEN
		self.quadrant_to_range[BayerOptimization.QUADRANT_GREEN_YPOL] = BayerOptimization.RANGE_GREEN
		self.quadrant_to_range[BayerOptimization.QUADRANT_BLUE] = BayerOptimization.RANGE_BLUE


		# Dipole sources have the following size in Meep
		dipole_source_size = mp.Vector3(0, 0, 0)

		# Adjoint source 0 corresponds to the blue quadrant
		adjoint_source_0 = mp.Source(mp.GaussianSource(self.source_freq_center_unitless, fwidth=self.source_freq_spread_unitless, cutoff=self.gaussian_cutoff, start_time=0), component=mp.Ex,
							 center=self.measure_blue_focal, amplitude=np.complex(0, 1), size=dipole_source_size);


		# Adjoint source 1 corresponds to the green x-polarized quadrant
		adjoint_source_1 = mp.Source(mp.GaussianSource(self.source_freq_center_unitless, fwidth=self.source_freq_spread_unitless, cutoff=self.gaussian_cutoff, start_time=0), component=mp.Ex,
							 center=self.measure_green_xpol_focal, amplitude=np.complex(0, 1), size=dipole_source_size);


		# Adjoint source 2 corresponds to the red quadrant
		adjoint_source_2 = mp.Source(mp.GaussianSource(self.source_freq_center_unitless, fwidth=self.source_freq_spread_unitless, cutoff=self.gaussian_cutoff, start_time=0), component=mp.Ex,
							 center=self.measure_red_focal, amplitude=np.complex(0, 1), size=dipole_source_size);


		# Adjoint source 3 corresponds to the green y-polarized quadrant
		adjoint_source_3 = mp.Source(mp.GaussianSource(self.source_freq_center_unitless, fwidth=self.source_freq_spread_unitless, cutoff=self.gaussian_cutoff, start_time=0), component=mp.Ex,
							 center=self.measure_green_ypol_focal, amplitude=np.complex(0, 1), size=dipole_source_size);

		self.adjoint_sources = [adjoint_source_0, adjoint_source_1, adjoint_source_2, adjoint_source_3]


		num_material_points = self.device.interpolation.num_points

		self.forward_fields_xpol = np.zeros((self.num_ranges, self.max_frequencies_in_a_range, 3, *num_material_points), dtype=np.complex)
		self.adjoint_fields_xpol = np.zeros((len(self.adjoint_sources), self.num_ranges, self.max_frequencies_in_a_range, 3, *num_material_points), dtype=np.complex)
Beispiel #13
0
    def find_k(self, p, omega, band_min, band_max, korig_and_kdir, tol,
               kmag_guess, kmag_min, kmag_max, *band_funcs):

        num_bands_save = self.num_bands
        kpoints_save = self.k_points
        nb = band_max - band_min + 1
        kdir = korig_and_kdir[1] if type(
            korig_and_kdir) is list else korig_and_kdir
        lat = self.geometry_lattice
        kdir1 = mp.cartesian_to_reciprocal(
            mp.reciprocal_to_cartesian(kdir, lat).unit(), lat)

        if type(korig_and_kdir) is list:
            korig = korig_and_kdir[0]
        else:
            korig = mp.Vector3()

        # k0s is a list caching the best k value found for each band:
        if type(kmag_guess) is list:
            k0s = kmag_guess
        else:
            k0s = [kmag_guess] * (band_max - band_min + 1)

        # dict to memoize all "band: k" results
        bktab = {}

        def rootfun(b):
            def _rootfun(k):
                # First, look in the cached table
                tab_val = bktab.get((b, k), None)
                if tab_val:
                    print("find-k {} at {}: {} (cached)".format(
                        b, k, tab_val[0]))
                    return tab_val
                # Otherwise, compute bands and cache results
                else:
                    self.num_bands = b
                    self.k_points = [korig + kdir1.scale(k)]
                    self.run_parity(p, False)
                    v = self.mode_solver.compute_group_velocity_component(
                        kdir1)

                    # Cache computed values
                    for _b, _f, _v in zip(range(band_min, b - band_min + 1,
                                                1), self.freqs[band_min - 1:],
                                          v[band_min - 1:]):
                        tabval = bktab.get((_b, k0s[_b - band_min]), None)

                        if not tabval or abs(_f - omega) < abs(tabval[0]):
                            k0s[_b - band_min + 1] = k

                        bktab[(_b, k)] = (_f - omega, _v)

                    fun = self.freqs[-1] - omega
                    print("find-k {} at {}: {}".format(b, k, fun))
                    return (fun, v[-1])

            return _rootfun

        # Don't let previous computations interfere
        if self.mode_solver:
            self.randomize_fields()

        ks = []
        for b in range(band_max, band_max - nb, -1):
            ks.append(
                mp.find_root_deriv(rootfun(b), tol, kmag_min, kmag_max,
                                   k0s[b - band_min]))

        if band_funcs:
            for b, k in zip(range(band_max, band_max - nb, -1), reversed(ks)):
                self.num_bands = b
                self.k_points = [korig + kdir1.scale(k)]

                def bfunc(ms, b_prime):
                    if b_prime == b:
                        for f in band_funcs:
                            apply_band_func_thunk(ms, f, b, True)

                self.run_parity(p, False, bfunc)

        self.num_bands = num_bands_save
        self.k_points = kpoints_save
        ks = list(reversed(ks))
        print("{}kvals:, {}, {}, {}".format(self.parity, omega, band_min,
                                            band_max),
              end='')
        for k in korig:
            print(", {}".format(k), end='')
        for k in kdir1:
            print(", {}".format(k), end='')
        for k in ks:
            print(", {}".format(k), end='')
        print()

        return ks
Beispiel #14
0
    def __init__(self,
                 resolution=10,
                 is_negative_epsilon_ok=False,
                 eigensolver_flops=0,
                 eigensolver_flags=68,
                 use_simple_preconditioner=False,
                 force_mu=False,
                 mu_input_file='',
                 epsilon_input_file='',
                 mesh_size=3,
                 target_freq=0.0,
                 tolerance=1.0e-7,
                 num_bands=1,
                 k_points=[],
                 ensure_periodicity=True,
                 geometry=[],
                 geometry_lattice=mp.Lattice(),
                 geometry_center=mp.Vector3(0, 0, 0),
                 default_material=mp.Medium(epsilon=1),
                 dimensions=3,
                 random_fields=False,
                 filename_prefix='',
                 deterministic=False,
                 verbose=False,
                 optimize_grid_size=True,
                 eigensolver_nwork=3,
                 eigensolver_block_size=-11):

        self.mode_solver = None
        self.resolution = resolution
        self.eigensolver_flags = eigensolver_flags
        self.k_points = k_points
        self.geometry = geometry
        self.geometry_lattice = geometry_lattice
        self.geometry_center = geometry_center
        self.default_material = default_material
        self.random_fields = random_fields
        self.filename_prefix = filename_prefix
        self.optimize_grid_size = optimize_grid_size
        self.parity = ''
        self.iterations = 0
        self.all_freqs = None
        self.freqs = []
        self.band_range_data = []
        self.total_run_time = 0
        self.current_k = mp.Vector3()
        self.k_split_num = 1
        self.k_split_index = 0
        self.eigensolver_iters = []

        grid_size = self._adjust_grid_size()

        if type(self.default_material) is not mp.Medium and callable(
                self.default_material):
            self.default_material.eps = False

        self.mode_solver = mode_solver(
            num_bands,
            self.resolution,
            self.geometry_lattice,
            tolerance,
            mesh_size,
            self.default_material,
            deterministic,
            target_freq,
            dimensions,
            verbose,
            ensure_periodicity,
            eigensolver_flops,
            is_negative_epsilon_ok,
            epsilon_input_file,
            mu_input_file,
            force_mu,
            use_simple_preconditioner,
            grid_size,
            eigensolver_nwork,
            eigensolver_block_size,
        )
Beispiel #15
0
    def __init__(self, dir_name, wavelength, thy_absorb, cyt_absorb):
        self.base_directory = base_directory + str(dir_name)

        self.wavelength = wavelength
        self.thy_absorb = thy_absorb
        self.cyt_absorb = cyt_absorb
        self.frequency = 1 / wavelength
        # Calculate wavelengths dependent on RI
        self.wavelength_in_media = wavelength / ri_media
        self.wavelength_in_cytoplasm = wavelength / ri_cytoplasm
        self.wavelength_in_thylakoid = wavelength / ri_thylakoid
        max_freq = self.frequency - 0.01
        min_freq = self.frequency + 0.01
        self.pulse_width = abs(max_freq - min_freq)

        cell = mp.Vector3(sxx, sxy, 0)
        pml_layers = [mp.PML(dpml)]

        thylakoid_material = mp.Medium(index=ri_thylakoid,
                                       D_conductivity=2 * math.pi * self.frequency * (thy_absorb / (ri_thylakoid ** 2)))
        cytoplasm_material = mp.Medium(index=ri_cytoplasm,
                                       D_conductivity=2 * math.pi * self.frequency * (cyt_absorb / (ri_cytoplasm ** 2)))

        thylakoid_region = mp.Sphere(radius=cell_radius,
                                     center=mp.Vector3(0, 0),
                                     material=thylakoid_material)
        cytoplasm_region = mp.Sphere(radius=cell_radius - thylakoid_thickness,
                                     center=mp.Vector3(0, 0),
                                     material=cytoplasm_material)
        geometry = [thylakoid_region, cytoplasm_region]

        # Sources
        kdir = mp.Vector3(1, 0, 0)  # direction of k (length is irrelevant)
        n = ri_media  # refractive index of material containing the source
        k = kdir.unit().scale(2 * math.pi * self.frequency * n)  # k with correct length

        def pw_amp(k, x0):
            def _pw_amp(x):
                return cmath.exp(1j * k.dot(x + x0))
            return _pw_amp
        source = [
            mp.Source(
                mp.ContinuousSource(frequency=self.frequency, fwidth=self.pulse_width),  # along x axis
                component=mp.Ez,
                center=mp.Vector3(-0.5 * simulation_size, 0),  # x, ,y ,z
                size=mp.Vector3(0, sxy, 0),
                amp_func=pw_amp(k, mp.Vector3(x=-0.5 * simulation_size))
            )
            ]

        sim = mp.Simulation(
            cell_size=cell,
            sources=source,
            boundary_layers=pml_layers,
            resolution=resolution,
            geometry=geometry,
            default_material=mp.Medium(index=ri_media),
            force_complex_fields=complex_f,
            eps_averaging=eps_av,
        )

        sim.use_output_directory(self.base_directory)
        sim.run(mp.at_every(0.6, mp.output_png(mp.Ez, "-Zc/data/home/bt16268/simInput/customColour.txt")), until=t)
Beispiel #16
0
    def _load_dump_structure(self, chunk_file=False, chunk_sim=False):
        from meep.materials import Al
        resolution = 50
        cell = mp.Vector3(5, 5)
        sources = mp.Source(src=mp.GaussianSource(1, fwidth=0.2),
                            center=mp.Vector3(),
                            component=mp.Ez)
        one_by_one = mp.Vector3(1, 1, mp.inf)
        geometry = [
            mp.Block(material=Al, center=mp.Vector3(), size=one_by_one),
            mp.Block(material=mp.Medium(epsilon=13),
                     center=mp.Vector3(1),
                     size=one_by_one)
        ]
        pml_layers = [mp.PML(0.5)]

        symmetries = [mp.Mirror(mp.Y)]

        sim1 = mp.Simulation(resolution=resolution,
                             cell_size=cell,
                             boundary_layers=pml_layers,
                             geometry=geometry,
                             symmetries=symmetries,
                             sources=[sources])

        sample_point = mp.Vector3(0.12, -0.29)
        ref_field_points = []

        def get_ref_field_point(sim):
            p = sim.get_field_point(mp.Ez, sample_point)
            ref_field_points.append(p.real)

        sim1.run(mp.at_every(5, get_ref_field_point), until=50)
        dump_fn = os.path.join(temp_dir, 'test_load_dump_structure.h5')
        dump_chunk_fname = None
        chunk_layout = None
        sim1.dump_structure(dump_fn)
        if chunk_file:
            dump_chunk_fname = os.path.join(
                temp_dir, 'test_load_dump_structure_chunks.h5')
            sim1.dump_chunk_layout(dump_chunk_fname)
            chunk_layout = dump_chunk_fname
        if chunk_sim:
            chunk_layout = sim1

        sim = mp.Simulation(resolution=resolution,
                            cell_size=cell,
                            boundary_layers=pml_layers,
                            sources=[sources],
                            symmetries=symmetries,
                            chunk_layout=chunk_layout,
                            load_structure=dump_fn)

        field_points = []

        def get_field_point(sim):
            p = sim.get_field_point(mp.Ez, sample_point)
            field_points.append(p.real)

        sim.run(mp.at_every(5, get_field_point), until=50)

        for ref_pt, pt in zip(ref_field_points, field_points):
            self.assertAlmostEqual(ref_pt, pt)
Beispiel #17
0
    def handle_cvector_dataset(self, in_arr):
        in_x_re = np.real(in_arr[:, :, 0]).ravel()
        in_x_im = np.imag(in_arr[:, :, 0]).ravel()
        in_y_re = np.real(in_arr[:, :, 1]).ravel()
        in_y_im = np.imag(in_arr[:, :, 1]).ravel()
        in_z_re = np.real(in_arr[:, :, 2]).ravel()
        in_z_im = np.imag(in_arr[:, :, 2]).ravel()

        d_in = [[in_x_re, in_x_im], [in_y_re, in_y_im], [in_z_re, in_z_im]]
        in_dims = [in_arr.shape[0], in_arr.shape[1], 1]
        rank = 2

        if self.verbose:
            print("Found complex vector dataset...")

        if self.verbose:
            fmt = "Input data is rank {}, size {}x{}x{}."
            print(fmt.format(rank, in_dims[0], in_dims[1], in_dims[2]))

        # rotate vector field according to cart_map
        if self.verbose:
            fmt1 = "Rotating vectors by matrix [ {:.10g}, {:.10g}, {:.10g}"
            fmt2 = "                             {:.10g}, {:.10g}, {:.10g}"
            fmt3 = "                             {:.10g}, {:.10g}, {:.10g} ]"
            print(fmt1.format(self.cart_map.c1.x, self.cart_map.c2.x, self.cart_map.c3.x))
            print(fmt2.format(self.cart_map.c1.y, self.cart_map.c2.y, self.cart_map.c3.y))
            print(fmt3.format(self.cart_map.c1.z, self.cart_map.c2.z, self.cart_map.c3.z))

        N = in_dims[0] * in_dims[1]
        for ri in range(2):
            for i in range(N):
                v = mp.Vector3(d_in[0][ri][i], d_in[1][ri][i], d_in[2][ri][i])
                v = self.cart_map * v
                d_in[0][ri][i] = v.x
                d_in[1][ri][i] = v.y
                d_in[2][ri][i] = v.z

        out_dims = [1, 1, 1]

        if self.resolution > 0:
            out_dims[0] = self.Rout.c1.norm() * self.resolution + 0.5
            out_dims[1] = self.Rout.c2.norm() * self.resolution + 0.5
            out_dims[2] = self.Rout.c3.norm() * self.resolution + 0.5
        else:
            for i in range(3):
                out_dims[i] = in_dims[i] * self.multiply_size[i]

        out_dims[2] = 1

        N = 1
        for i in range(3):
            out_dims[i] = int(max(out_dims[i], 1))
            N *= out_dims[i]

        if self.verbose:
            fmt = "Output data {}x{}x{}."
            print(fmt.format(out_dims[0], out_dims[1], out_dims[2]))

        if self.kpoint:
            kvector = [self.kpoint.x, self.kpoint.y, self.kpoint.z]
        else:
            kvector = []

        converted = []
        for dim in range(3):
            out_arr_re = np.zeros(int(N))
            out_arr_im = np.zeros(int(N))

            map_data(d_in[dim][0].ravel(), d_in[dim][1].ravel(), np.array(in_dims, dtype=np.intc),
                     out_arr_re, out_arr_im, np.array(out_dims, dtype=np.intc), self.coord_map,
                     kvector, self.pick_nearest, self.verbose)

            # multiply * scaleby
            complex_out = np.vectorize(complex)(out_arr_re, out_arr_im)
            complex_out *= self.scaleby
            converted.append(complex_out)

        result = np.zeros(np.prod(out_dims) * 3, np.complex128)
        result[0::3] = converted[0]
        result[1::3] = converted[1]
        result[2::3] = converted[2]

        return np.reshape(result, (out_dims[0], out_dims[1], 3))
Beispiel #18
0
 def print_field(sim):
     result.append(sim.get_field_point(mp.Ez, mp.Vector3(2, -1)))
Beispiel #19
0
def main(args):
    cell_zmax = 0.5 * cell_thickness if args.three_d else 0
    cell_zmin = -0.5 * cell_thickness if args.three_d else 0
    si_zmax = t_Si if args.three_d else 0

    # read cell size, volumes for source region and flux monitors,
    # and coupler geometry from GDSII file
    upper_branch = mp.get_GDSII_prisms(
        silicon, gdsII_file, UPPER_BRANCH_LAYER, si_zmin, si_zmax)
    lower_branch = mp.get_GDSII_prisms(
        silicon, gdsII_file, LOWER_BRANCH_LAYER, si_zmin, si_zmax)

    cell = mp.GDSII_vol(gdsII_file, CELL_LAYER, cell_zmin, cell_zmax)
    p1 = mp.GDSII_vol(gdsII_file, PORT1_LAYER, si_zmin, si_zmax)
    p2 = mp.GDSII_vol(gdsII_file, PORT2_LAYER, si_zmin, si_zmax)
    p3 = mp.GDSII_vol(gdsII_file, PORT3_LAYER, si_zmin, si_zmax)
    p4 = mp.GDSII_vol(gdsII_file, PORT4_LAYER, si_zmin, si_zmax)
    src_vol = mp.GDSII_vol(gdsII_file, SOURCE_LAYER, si_zmin, si_zmax)

    # displace upper and lower branches of coupler (as well as source and flux regions)
    if args.d != default_d:
        delta_y = 0.5 * (args.d - default_d)
        delta = mp.Vector3(y=delta_y)
        p1.center += delta
        p2.center -= delta
        p3.center += delta
        p4.center -= delta
        src_vol.center += delta
        cell.size += 2 * delta
        for np in range(len(lower_branch)):
            lower_branch[np].center -= delta
            for nv in range(len(lower_branch[np].vertices)):
                lower_branch[np].vertices[nv] -= delta
        for np in range(len(upper_branch)):
            upper_branch[np].center += delta
            for nv in range(len(upper_branch[np].vertices)):
                upper_branch[np].vertices[nv] += delta

    geometry = upper_branch + lower_branch

    if args.three_d:
        oxide_center = mp.Vector3(z=-0.5 * t_oxide)
        oxide_size = mp.Vector3(cell.size.x, cell.size.y, t_oxide)
        oxide_layer = [
            mp.Block(material=oxide, center=oxide_center, size=oxide_size)]
        geometry = geometry + oxide_layer

    sources = [mp.EigenModeSource(src=mp.GaussianSource(fcen, fwidth=df),
                                  size=src_vol.size,
                                  center=src_vol.center,
                                  eig_band=1,
                                  eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z,
                                  eig_match_freq=True)]

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

    mode1 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p1))
    mode2 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p2))
    mode3 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p3))
    mode4 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p4))

    sim.run(until_after_sources=100)

    # S parameters
    p1_coeff = sim.get_eigenmode_coefficients(
        mode1, [1], eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z).alpha[0, 0, 0]
    p2_coeff = sim.get_eigenmode_coefficients(
        mode2, [1], eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z).alpha[0, 0, 1]
    p3_coeff = sim.get_eigenmode_coefficients(
        mode3, [1], eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z).alpha[0, 0, 0]
    p4_coeff = sim.get_eigenmode_coefficients(
        mode4, [1], eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z).alpha[0, 0, 0]

    # transmittance
    p2_trans = abs(p2_coeff)**2 / abs(p1_coeff)**2
    p3_trans = abs(p3_coeff)**2 / abs(p1_coeff)**2
    p4_trans = abs(p4_coeff)**2 / abs(p1_coeff)**2

    print("trans:, {:.2f}, {:.6f}, {:.6f}, {:.6f}".format(
        args.d, p2_trans, p3_trans, p4_trans))
#dsub = 2.0                             # substrate thickness
width = 0.25  #环的宽度
r = width * len(ht)  #透镜的半径
focal_length = 20.0  #焦距
ff_res = 10.0
h = 5

NA = math.sin(math.atan(r / focal_length))
NA = round(NA, 3)

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

sr = r + dpad + dpml
sz = dpml + dpad + h + dpad + dpml
#sz=dpml+dsub+h+dpad+dpml
cell_size = mp.Vector3(sr, 0, sz)

#geometry = [mp.Block(material=mp.vacuum,
#		     size=mp.Vector3(sr,0,dpml+dpad),
#                    center=mp.Vector3(0.5*sr,0,-0.5*sz+0.5*(dpml+dpad)))]

geometry = [
    mp.Block(material=photoresist,
             size=mp.Vector3(width, 0, ht[0]),
             center=mp.Vector3(0.5 * width, 0,
                               -0.5 * sz + dpml + dpad + 0.5 * ht[0]))
]
for n in range(1, len(ht)):
    geometry.append(
        mp.Block(material=photoresist,
                 size=mp.Vector3(width, 0, ht[n]),
Beispiel #21
0
 def test_in_volume(self):
     sim = self.init_simple_simulation()
     sim.filename_prefix = 'test_in_volume'
     vol = mp.Volume(mp.Vector3(), size=mp.Vector3(x=2))
     sim.run(mp.at_end(mp.in_volume(vol, mp.output_efield_z)), until=200)
Beispiel #22
0
frq_cen = 0.5 * (frq_min + frq_max)
dfrq = frq_max - frq_min
nfrq = 100

# at least 8 pixels per smallest wavelength, i.e. np.floor(8/wvl_min)
resolution = 25

dpml = 0.5 * wvl_max
dair = 0.5 * wvl_max

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

symmetries = [mp.Mirror(mp.Y), mp.Mirror(mp.Z, phase=-1)]

s = 2 * (dpml + dair + r)
cell_size = mp.Vector3(s, s, s)

# is_integrated=True necessary for any planewave source extending into PML
sources = [
    mp.Source(mp.GaussianSource(frq_cen, fwidth=dfrq, is_integrated=True),
              center=mp.Vector3(-0.5 * s + dpml),
              size=mp.Vector3(0, s, s),
              component=mp.Ez)
]

sim = mp.Simulation(resolution=resolution,
                    cell_size=cell_size,
                    boundary_layers=pml_layers,
                    sources=sources,
                    k_point=mp.Vector3(),
                    symmetries=symmetries)
Beispiel #23
0
    def test_interpolate_vectors(self):

        expected = [
            mp.Vector3(),
            mp.Vector3(0.024999999999999842),
            mp.Vector3(0.04999999999999984),
            mp.Vector3(0.07499999999999984),
            mp.Vector3(0.09999999999999984),
            mp.Vector3(0.12499999999999983),
            mp.Vector3(0.14999999999999983),
            mp.Vector3(0.17499999999999982),
            mp.Vector3(0.19999999999999982),
            mp.Vector3(0.2249999999999998),
            mp.Vector3(0.2499999999999998),
            mp.Vector3(0.2749999999999998),
            mp.Vector3(0.2999999999999998),
            mp.Vector3(0.32499999999999984),
            mp.Vector3(0.34999999999999987),
            mp.Vector3(0.3749999999999999),
            mp.Vector3(0.3999999999999999),
            mp.Vector3(0.42499999999999993),
            mp.Vector3(0.44999999999999996),
            mp.Vector3(0.475),
            mp.Vector3(0.5)
        ]

        res = mp.interpolate(19, [mp.Vector3(), mp.Vector3(0.5)])

        np.testing.assert_allclose([v.x for v in expected], [v.x for v in res])
        np.testing.assert_allclose([v.y for v in expected], [v.y for v in res])
        np.testing.assert_allclose([v.z for v in expected], [v.z for v in res])
# -*- coding: utf-8 -*-

# From the Meep tutorial: plotting permittivity and fields of a straight waveguide
from __future__ import division

import meep as mp

cell = mp.Vector3(16, 8, 0)

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

sources = [
    mp.Source(mp.ContinuousSource(frequency=0.15),
              component=mp.Ez,
              center=mp.Vector3(-7, 0))
]

pml_layers = [mp.PML(1.0)]

resolution = 10

sim = mp.Simulation(cell_size=cell,
                    boundary_layers=pml_layers,
                    geometry=geometry,
                    sources=sources,
                    resolution=resolution)
Beispiel #25
0
 def record_ex_ey(sim):
     record_Ex.append(sim.get_field_point(mp.Ex, mp.Vector3(0, 0,
                                                            zout)))
     record_Ey.append(sim.get_field_point(mp.Ey, mp.Vector3(0, 0,
                                                            zout)))
     record_t.append(sim.meep_time())
Beispiel #26
0
    f1.write("\n\t" + case + "\n\n\n")
    f2.write(case + ", ")

    hu = min(hu, (H - h) / 2)
    hl = min(hl, (H - h) / 2)

    n_m = max(n_x, n_y, n_z)
    n_c = max(n_l, n_u)

    fcen = 1 / wavelength
    df = 0.05

    default_material = mp.Medium(epsilon=1)
    upper_material = mp.Medium(epsilon=n_u**2)
    core_material = mp.Medium(epsilon_diag=mp.Vector3(n_x**2, n_y**2, n_z**2))
    lower_material = mp.Medium(epsilon=n_l**2)

    geometry_lattice = mp.Lattice(size=mp.Vector3(0, monitorheight, 0))

    # bandNum = 4

    # geometry = [mp.Block(mp.Vector3(mp.inf, h, mp.inf), center=mp.Vector3(0,0,0), material=core_material),
    # 			mp.Block(mp.Vector3(mp.inf, h, mp.inf), center=mp.Vector3(0,0,0), material=core_material),
    # 			mp.Block(mp.Vector3(mp.inf, h, mp.inf), center=mp.Vector3(0,0,0), material=core_material),
    # 			mp.Block(mp.Vector3(mp.inf, h, mp.inf), center=mp.Vector3(0,0,0), material=core_material)]

    geometrympb = [
        mp.Block(mp.Vector3(mp.inf, monitorheight, mp.inf),
                 center=mp.Vector3(0, 0),
                 material=default_material),
Beispiel #27
0
import meep as mp
import numpy as np
from numpy import linalg as LA
import matplotlib.pyplot as plt

n = 3.4
w = 1
r = 1
pad = 4
dpml = 2

sxy = 2 * (r + w + pad + dpml)
vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sxy - 2 * dpml, sxy - 2 * dpml))

c1 = mp.Cylinder(radius=r + w, material=mp.Medium(index=n))
c2 = mp.Cylinder(radius=r)

fcen = 0.118
df = 0.08
src = [
    mp.Source(mp.ContinuousSource(fcen, fwidth=df),
              component=mp.Ez,
              center=mp.Vector3(r + 0.1))
]

sim = mp.Simulation(cell_size=mp.Vector3(sxy, sxy),
                    geometry=[c1, c2],
                    sources=[src],
                    resolution=10,
                    force_complex_fields=True,
                    symmetries=[mp.Mirror(mp.Y)],
Beispiel #28
0
    def notch(w):

        print("#----------------------------------------")
        print("NOTCH WIDTH: %s nanometers" % (w * 1000))
        print("#----------------------------------------")

        # w is the width of the notch in the waveguide

        angrad = ang * pi / 180
        bottomoffset = e * h / tan(angrad)

        vertices = [
            mp.Vector3(w / 2 + bottomoffset, (.5 + e) * h),
            mp.Vector3(-w / 2 - bottomoffset, (.5 + e) * h),
            mp.Vector3(-w / 2 + bottomoffset, (.5 - e) * h),
            mp.Vector3(w / 2 - bottomoffset, (.5 - e) * h)
        ]

        if bottomoffset > w / 2:
            ratio = (w / 2) / bottomoffset
            vertices = [
                mp.Vector3(w / 2, h / 2),
                mp.Vector3(-w / 2, h / 2),
                mp.Vector3(0, (.5 - e * ratio) * h)
            ]

        print(vertices)

        #Waveguide Geometry
        cell = mp.Vector3(a, H)

        geometry = [
            mp.Block(cell, center=mp.Vector3(0, 0), material=default_material),
            mp.Block(mp.Vector3(a, hu + h / 2),
                     center=mp.Vector3(0, (hu + h / 2) / 2),
                     material=upper_material),
            mp.Block(mp.Vector3(a, hl + h / 2),
                     center=mp.Vector3(0, -(hl + h / 2) / 2),
                     material=lower_material),
            mp.Block(mp.Vector3(a, h),
                     center=mp.Vector3(0, 0),
                     material=core_material)
        ]

        if w > 0:
            geometry.append(
                mp.Prism(vertices, height=1, material=upper_material))

        pml_layers = [mp.Absorber(thickness=dpml)]

        r00 = None
        r01 = None
        r10 = None
        r11 = None

        t00 = None
        t01 = None
        t10 = None
        t11 = None

        su0 = None
        sd0 = None
        su1 = None
        sd1 = None

        modes = [0, 1]

        if only_fund:
            modes = [0]

        # eig_parity_fund = 	mp.EVEN_Z+mp.EVEN_Y;
        # eig_parity_first = 	mp.EVEN_Z+mp.ODD_Y;

        eig_parity_fund = mp.EVEN_Y
        eig_parity_first = mp.ODD_Y

        # for mode in [0, 1]:
        for mode in modes:

            if mode == 0:
                eig_parity = eig_parity_fund  # Fundamental
                print("-----------")
                print("MODE TYPE: FUNDAMENTAL")

            else:
                eig_parity = eig_parity_first  # First Order
                print("-----------")
                print("MODE TYPE: FIRST ORDER")

            # sources = [	mp.EigenModeSource(
            # 				mp.GaussianSource(	frequency = fcen,
            # 									fwidth = df),
            # 									size = mp.Vector3(0,H),
            # 									center = mp.Vector3(Ls, 0),
            # 									eig_parity = eig_parity) ]

            sources = [
                mp.EigenModeSource(mp.ContinuousSource(frequency=fcen),
                                   size=mp.Vector3(0, monitorheight),
                                   center=mp.Vector3(Ls, 0),
                                   eig_parity=eig_parity)
            ]

            sim = mp.Simulation(cell_size=cell,
                                boundary_layers=pml_layers,
                                geometry=geometry,
                                sources=sources,
                                resolution=resolution,
                                force_complex_fields=True)
            '''
			#--------------------------------------------------
			#FOR DISPLAYING THE GEOMETRY

			sim.run(until = 200)

			eps_data = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Dielectric)
			plt.figure(dpi=100)
			plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary')
			#plt.axis('off')
			plt.show()

			quit()
			#----------------------------------------------------
			'''
            '''
			#------------------------------------------------------
			#FOR GENERATING THE ELECTRIC FIELD GIF
			#Note: After running this program, write the following commands in Terminal:
			    # $ source deactivate mp
			    # $ cd notchtest-out/
			    # $ python ../NotchIP.py

			sim.use_output_directory()
			sim.run(mp.at_beginning(mp.output_epsilon),
			        mp.to_appended("ez", mp.at_every(0.6, mp.output_efield_z)),
			        until = 200)
			#sim.run(mp.at_every(0.6 , mp.output_png(mp.Ez, "-Zc dkbluered")), until=200)

			#---------------------------------------------------------
			'''

            #---------------------------------------------------------
            # FOR GENERATING THE TRANSMITTANCE SPECTRUM

            # nfreq = 1  # number of frequencies at which to compute flux
            #
            # refl_fr1 = 	mp.FluxRegion(center=mp.Vector3(Lr1,0), 	size=mp.Vector3(0,monitorheight))	# Reflected flux 1
            # refl_fr2 = 	mp.FluxRegion(center=mp.Vector3(Lr2,0), 	size=mp.Vector3(0,monitorheight))	# Reflected flux 2
            # tran_fr = 	mp.FluxRegion(center=mp.Vector3(Lt,0), 		size=mp.Vector3(0,monitorheight))	# Transmitted flux
            # su_fr = 	mp.FluxRegion(center=mp.Vector3(0, monitorheight/2),	size=mp.Vector3(a,0))	# Flux loss above the waveguide
            # sd_fr = 	mp.FluxRegion(center=mp.Vector3(0,-monitorheight/2), 	size=mp.Vector3(a,0))	# Flux loss below the waveguide
            #
            # refl1 = sim.add_flux(fcen, df, nfreq, refl_fr1)
            # refl2 = sim.add_flux(fcen, df, nfreq, refl_fr2)
            # tran = 	sim.add_flux(fcen, df, nfreq, tran_fr)
            # su = 	sim.add_flux(fcen, df, nfreq, su_fr)
            # sd = 	sim.add_flux(fcen, df, nfreq, sd_fr)

            # ------------------------ CODE FOR SEPARATING FUND AND FIRST ORDER MODE STARTS HERE ------------------------

            refl_vals = []
            tran_vals = []

            def get_refl_slice(sim):
                # print(sim.get_array(center=mp.Vector3(Lr1,0), size=mp.Vector3(0,H), component=mp.Ez, cmplx=True))
                # refl_val = sim.get_array(center=mp.Vector3(Lr1,0), size=mp.Vector3(0,H), component=mp.Ez, cmplx=True)
                refl_vals.append(
                    sim.get_array(center=mp.Vector3(Lr1, 0),
                                  size=mp.Vector3(
                                      0, monitorheight - 2 / resolution),
                                  component=mp.Ez,
                                  cmplx=True))

            def get_tran_slice(sim):
                # print(sim.get_array(center=mp.Vector3(Lt, 0), size=mp.Vector3(0,H), component=mp.Ez, cmplx=True))
                # tran_val = sim.get_array(center=mp.Vector3(Lt, 0), size=mp.Vector3(0,H), component=mp.Ez, cmplx=True)
                tran_vals.append(
                    sim.get_array(center=mp.Vector3(Lt, 0),
                                  size=mp.Vector3(
                                      0, monitorheight - 2 / resolution),
                                  component=mp.Ez,
                                  cmplx=True))

            gif = True

            # T = 50*(a-4)/12;
            T = 60

            if resolution == 50:
                epsform = "eps-000000.00"
            else:
                epsform = "eps-000000000"

            if gif:  # and w == 0.1:
                sim.use_output_directory()
                sim.run(mp.at_beginning(mp.output_epsilon),
                        mp.at_every(
                            1,
                            mp.output_png(
                                mp.Ez,
                                "-RZc bluered -A notchtest-out/notchtest-" +
                                epsform + ".h5 -a gray:.2")),
                        mp.at_end(get_refl_slice),
                        mp.at_end(get_tran_slice),
                        until=T)

                os.system("convert notchtest-out/notchtest-ez-*.png    " +
                          casedash + "-" + str(int(w * 1000)) + "-" +
                          str(mode) + "-full.gif")
                os.system("rm notchtest-out/notchtest-ez-*.png")

                nfreq = 1  # number of frequencies at which to compute flux

                refl_fr1 = mp.FluxRegion(
                    center=mp.Vector3(Lr1, 0),
                    size=mp.Vector3(0, monitorheight))  # Reflected flux 1
                refl_fr2 = mp.FluxRegion(
                    center=mp.Vector3(Lr2, 0),
                    size=mp.Vector3(0, monitorheight))  # Reflected flux 2
                tran_fr = mp.FluxRegion(
                    center=mp.Vector3(Lt, 0),
                    size=mp.Vector3(0, monitorheight))  # Transmitted flux
                su_fr = mp.FluxRegion(
                    center=mp.Vector3(0, monitorheight / 2),
                    size=mp.Vector3(a, 0))  # Flux loss above the waveguide
                sd_fr = mp.FluxRegion(
                    center=mp.Vector3(0, -monitorheight / 2),
                    size=mp.Vector3(a, 0))  # Flux loss below the waveguide

                refl1 = sim.add_flux(fcen, df, nfreq, refl_fr1)
                refl2 = sim.add_flux(fcen, df, nfreq, refl_fr2)
                tran = sim.add_flux(fcen, df, nfreq, tran_fr)
                su = sim.add_flux(fcen, df, nfreq, su_fr)
                sd = sim.add_flux(fcen, df, nfreq, sd_fr)

                # sim.run(mp.at_every(wavelength / 20, mp.output_efield_z), until=wavelength)
                # sim.run(mp.at_every(wavelength/20 , mp.output_png(mp.Ez, "-RZc bluered -A notchtest-out/notchtest-eps-000000000.h5 -a gray:.2")), until=19*wavelength/20)
                sim.run(mp.at_every(
                    wavelength / 20,
                    mp.output_png(
                        mp.Ez, "-RZc bluered -A notchtest-out/notchtest-" +
                        epsform + ".h5 -a gray:.2")),
                        until=19 * wavelength / 20)
                sim.run(until=20)
                # sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-5))
            else:
                sim.run(mp.at_beginning(mp.output_epsilon),
                        mp.at_time(T, get_refl_slice),
                        mp.at_time(T, get_tran_slice))  #,
                # until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-5))

            os.system("h5topng notchtest-out/notchtest-" + epsform +
                      ".h5; mv notchtest-out/notchtest-" + epsform + ".png " +
                      casedash + "-" + str(int(w * 1000)) + "-" + str(mode) +
                      "-eps.png")
            # os.system("cp notchtest-out/notchtest-ez-000100.00.png " 	+ case + "-" + str(int(w*1000)) + "-" + str(mode) + ".png")
            os.system("convert notchtest-out/notchtest-ez-*.png    " +
                      casedash + "-" + str(int(w * 1000)) + "-" + str(mode) +
                      ".gif")
            os.system("rm notchtest-out/notchtest-ez-*.png")

            # get_eigenmode(fcen, mp., refl_fr1, 1, kpoint)
            # v = mp.volume(mp.vec(Lr1, -monitorheight/2), mp.vec(Lr1, monitorheight/2))
            # mode = get_eigenmode(fcen, mp.X, v, v, 1, mp.vec(0, 0, 0), True, 0, 0, 1e-7, True)
            # print(mode.amplitude)

            # coef_refl_fund = 	mp.get_eigenmode_coefficients_and_kpoints(refl_fr1, 1, eig_parity=eig_parity_fund, 	eig_resolution=resolution, eig_tolerance=1e-7)
            # coef_refl_first = 	mp.get_eigenmode_coefficients_and_kpoints(refl_fr1, 1, eig_parity=eig_parity_first, eig_resolution=resolution, eig_tolerance=1e-7)
            #
            # coef_tran_fund = 	mp.get_eigenmode_coefficients_and_kpoints(tran_fr, 	1, eig_parity=eig_parity_fund, 	eig_resolution=resolution, eig_tolerance=1e-7)
            # coef_tran_first = 	mp.get_eigenmode_coefficients_and_kpoints(tran_fr, 	1, eig_parity=eig_parity_first, eig_resolution=resolution, eig_tolerance=1e-7)

            ep = mp.ODD_Z

            coef_refl_fund, vgrp, kpoints_fund = sim.get_eigenmode_coefficients(
                refl1, [1],
                eig_parity=ep,
                eig_resolution=resolution,
                eig_tolerance=1e-7)
            coef_refl_first, vgrp, kpoints_first = sim.get_eigenmode_coefficients(
                refl1, [2],
                eig_parity=ep,
                eig_resolution=resolution,
                eig_tolerance=1e-7)

            coef_tran_fund, vgrp, kpoints_fund = sim.get_eigenmode_coefficients(
                tran, [1],
                eig_parity=ep,
                eig_resolution=resolution,
                eig_tolerance=1e-7)
            coef_tran_first, vgrp, kpoints_first = sim.get_eigenmode_coefficients(
                tran, [2],
                eig_parity=ep,
                eig_resolution=resolution,
                eig_tolerance=1e-7)

            # print(kpoints_fund)
            # print(kpoints_first)
            # print(kpoints_fund[0])
            # print(type(kpoints_fund[0]))
            # print(dir(kpoints_fund[0]))

            n_eff_fund = wavelength * kpoints_fund[0].x
            n_eff_first = wavelength * kpoints_first[0].x

            print(n_eff_fund)
            print(n_eff_first)

            # print(coef_refl_fund)
            # print(type(coef_refl_fund))
            # print(dir(coef_refl_fund))

            # print(coef_refl_fund[0])
            # print(coef_refl_fund[0][0,0,:])
            #
            # fund_refl_amp = 		coef_refl_fund[0][0,0,1];
            # first_order_refl_amp =	coef_refl_first[0][0,0,1];
            # fund_tran_amp =			coef_tran_fund[0][0,0,0];
            # first_order_tran_amp =	coef_tran_first[0][0,0,0];

            print("get_eigenmode_coefficients:\n")

            print(coef_refl_fund)
            print(coef_refl_first)
            print(coef_tran_fund)
            print(coef_tran_first)

            print("\n")
            # print(coef_refl_fund[0,0,:])

            fund_refl_amp = coef_refl_fund[0, 0, 1]
            first_order_refl_amp = coef_refl_first[0, 0, 1]
            fund_tran_amp = coef_tran_fund[0, 0, 0]
            first_order_tran_amp = coef_tran_first[0, 0, 0]

            refl_val = refl_vals[0]
            tran_val = tran_vals[0]

            # n_eff must satisfy n_e <= n_eff <= n_c for the mode to be bound.

            def fund_func(n_eff):
                if n_eff >= n_c and n_eff <= n_e:
                    return sqrt(
                        n_eff**2 - n_c**2) - sqrt(n_e**2 - n_eff**2) * tan(
                            pi * h / wavelength * sqrt(n_e**2 - n_eff**2))

            def first_order_func(n_eff):
                if n_eff >= n_c and n_eff <= n_e:
                    return sqrt(n_eff**2 -
                                n_c**2) - sqrt(n_e**2 - n_eff**2) * tan(
                                    pi * h / wavelength *
                                    sqrt(n_e**2 - n_eff**2) - pi / 2)

            initial_guess = (n_c + n_e) / 2

            # n_eff_fund = 	fsolve(fund_func, initial_guess)
            # n_eff_first = 	fsolve(first_order_func, n_c)

            print(n_eff_fund, n_eff_first)

            assert (n_eff_fund > n_eff_first)

            if len(n_eff_funds) == 0:
                n_eff_funds.append(n_eff_fund)

            if len(n_eff_firsts) == 0:
                n_eff_firsts.append(n_eff_first)

            ky0_fund = np.abs(2 * pi / wavelength *
                              sqrt(n_e**2 - n_eff_fund**2))
            ky0_first = np.abs(2 * pi / wavelength *
                               sqrt(n_e**2 - n_eff_first**2))

            ky1_fund = ky0_fund  # np.abs(2 * pi / wavelength * sqrt(n_eff_fund **2 - n_c**2))
            ky1_first = ky0_first  # np.abs(2 * pi / wavelength * sqrt(n_eff_first**2 - n_c**2))

            E_fund = lambda y: cos(ky0_fund * y) if np.abs(y) < h / 2 else cos(
                ky0_fund * h / 2) * np.exp(-ky1_fund * (np.abs(y) - h / 2))
            E_first_order = lambda y: sin(ky0_first * y) if np.abs(
                y) < h / 2 else sin(ky0_first * h / 2) * np.exp(-ky1_first * (
                    np.abs(y) - h / 2)) * np.sign(y)
            # y_list = np.arange(-H/2+.5/resolution, H/2-.5/resolution, 1/resolution)

            #print("Y LIST: ", y_list)
            #print("SIZE OF Y LIST: ", y_list.size)

            E_fund_vec = np.zeros(y_list.size)
            E_first_order_vec = np.zeros(y_list.size)

            for index in range(y_list.size):
                y = y_list[index]
                E_fund_vec[index] = E_fund(y)
                E_first_order_vec[index] = E_first_order(y)

            # print(dir(sim))
            # print(type(sim.get_eigenmode_coefficients))
            # print(dir(sim.get_eigenmode_coefficients))
            # print(type(sim.get_eigenmode))
            # print(dir(sim.get_eigenmode))
            # print(sim.get_eigenmode.__code__.co_varnames)
            # print(sim.get_eigenmode.__defaults__)

            # E1 = sim.get_eigenmode(fcen, mp.X, refl1.where, 1, None)
            # E2 = sim.get_eigenmode(fcen, mp.X, refl1.where, 2, None)
            # E3 = sim.get_eigenmode(fcen, mp.X, refl1.where, 3, None)
            # E4 = sim.get_eigenmode(fcen, mp.X, refl1.where, 4, None)

            # E1 = sim.get_eigenmode(fcen, mp.X, refl1.where, 1, mp.Vector3(0, 0, 0))
            # E2 = sim.get_eigenmode(fcen, mp.X, refl1.where, 2, mp.Vector3(0, 0, 0))
            # E3 = sim.get_eigenmode(fcen, mp.X, refl1.where, 3, mp.Vector3(0, 0, 0))
            # E4 = sim.get_eigenmode(fcen, mp.X, refl1.where, 4, mp.Vector3(0, 0, 0))

            # print(refl1.where)
            # numEA = 0
            # E1 = sim.fields.get_eigenmode(fcen, mp.X, refl1.where, refl1.where, 1, mp.vec(0,0,0), True, 0, numEA, 1e-7, True)

            # print(type(E1))
            # print(dir(E1))
            #
            # print(refl1.where)
            # # print(E1, E2, E3, E4)
            # print(E1.amplitude, E1.band_num, E1.group_velocity, E1.k)
            # print(type(E1.amplitude))
            # print(dir(E1.amplitude))
            # print(doc(E1.amplitude))
            # print(self(E1.amplitude))
            # print(E1.amplitude(y_list))
            # print(type(E1.amplitude(y_list)))
            # print(dir(E1.amplitude(y_list)))
            # print(E1.amplitude, E2.amplitude, E3.amplitude, E4.amplitude)

            # E1 = sim.get_eigenmode(fcen, mp.X, refl1.where, refl1.where, 1, mp.vec(0, 0, 0))
            # E2 = sim.get_eigenmode(fcen, mp.X, refl1.where, refl1.where, 2, mp.vec(0, 0, 0))
            # E3 = sim.get_eigenmode(fcen, mp.X, refl1.where, refl1.where, 3, mp.vec(0, 0, 0))
            # E4 = sim.get_eigenmode(fcen, mp.X, refl1.where, refl1.where, 4, mp.vec(0, 0, 0))

            # print(y_list)
            #
            # E1a = np.zeros(y_list.size, dtype='Complex128');
            # E2a = np.zeros(y_list.size, dtype='Complex128');
            # E3a = np.zeros(y_list.size, dtype='Complex128');
            # E4a = np.zeros(y_list.size, dtype='Complex128');
            #
            # # print(mp.eigenmode_amplitude.__code__.co_varnames)
            # # print(mp.eigenmode_amplitude.__defaults__)
            #
            # for i in range(y_list.size):
            # 	# print(E1)
            # 	# print(E1.swigobj)
            # 	# print(E1.amplitude)
            # 	# print(mp.vec(Lr1, y_list[i], 0))
            # 	# print(mp.Vector3(Lr1, y_list[i], 0))
            # 	# print(mp.Ez)
            # 	# E1a[i] = mp.eigenmode_amplitude(E1.swigobj, mp.vec(Lr1, y_list[i], 0), mp.Ez);
            # 	eval_point = mp.vec(Lr1, y_list[i], 0)
            # 	# print(eval_point)
            # 	E1a[i] = mp.eigenmode_amplitude(E1.swigobj, eval_point, mp.Ex)
            # 	E2a[i] = mp.eigenmode_amplitude(E2.swigobj, eval_point, mp.Ex)
            # 	E3a[i] = mp.eigenmode_amplitude(E3.swigobj, eval_point, mp.Ex)
            # 	E4a[i] = mp.eigenmode_amplitude(E4.swigobj, eval_point, mp.Ex)
            # 	# E1a[i] = mp.eigenmode_amplitude(E1.amplitude, mp.Vector3(Lr1, y_list[i], 0), mp.Ez);
            #
            # plt.plot(y_list, np.abs(E1a)**2, 'bo-', label='E1')
            # plt.plot(y_list, np.abs(E2a)**2, 'ro-', label='E2')
            # plt.plot(y_list, np.abs(E3a)**2, 'go-', label='E3')
            # plt.plot(y_list, np.abs(E4a)**2, 'co-', label='E4')
            # # plt.axis([40.0, 300.0, 0.0, 100.0])
            # plt.xlabel("y (um)")
            # plt.ylabel("Field (a.u.)")
            # plt.legend(loc="center right")
            # plt.show()

            # print("r VECTOR: ", 	refl_val)
            # print("t VECTOR: ", 	tran_val)
            # print("E0 VECTOR: ", 	E_fund_vec)
            # print("E1 VECTOR: ", 	E_first_order_vec)

            # fund_refl_amp_2 = 			np.conj(np.dot(refl_val, E_fund_vec) 		/ np.dot(E_fund_vec, E_fund_vec))					# Conjugate becasue MEEP uses physics exp(kz-wt) rather than engineering exp(wt-kz)
            # first_order_refl_amp_2 = 	np.conj(np.dot(refl_val, E_first_order_vec) / np.dot(E_first_order_vec, E_first_order_vec))
            # fund_tran_amp_2 = 			np.conj(np.dot(tran_val, E_fund_vec) 		/ np.dot(E_fund_vec, E_fund_vec))
            # first_order_tran_amp_2 = 	np.conj(np.dot(tran_val, E_first_order_vec) / np.dot(E_first_order_vec, E_first_order_vec))

            fund_refl_amp0 = fund_refl_amp
            fund_tran_amp0 = fund_tran_amp

            fund_refl_amp = np.conj(
                np.dot(refl_val, E0) / np.dot(E0, E0)
            )  # Conjugate becasue MEEP uses physics exp(kz-wt) rather than engineering exp(wt-kz)
            first_order_refl_amp = 0  # np.conj(np.dot(refl_val, E1[:,2]) / np.dot(E1[:,2], E1[:,2]))
            fund_tran_amp = np.conj(np.dot(tran_val, E0) / np.dot(E0, E0))
            first_order_tran_amp = 0  # np.conj(np.dot(tran_val, E1[:,2]) / np.dot(E1[:,2], E1[:,2]))

            fund_refl = np.conj(fund_refl_amp) * E0
            not_fund_refl = refl_val - fund_refl
            fund_tran = np.conj(fund_tran_amp) * E0
            not_fund_tran = tran_val - fund_tran

            fund_refl_power = np.dot(np.conj(fund_refl), fund_refl)
            not_fund_refl_power = np.dot(np.conj(not_fund_refl), not_fund_refl)
            fund_tran_power = np.dot(np.conj(fund_tran), fund_tran)
            not_fund_tran_power = np.dot(np.conj(not_fund_tran), not_fund_tran)

            f2.write(
                "%s, " %
                [fund_refl_amp0, fund_tran_amp0, fund_refl_amp, fund_tran_amp])

            # assert(fund_refl_power + not_fund_refl_power == 1)
            # assert(fund_tran_power + not_fund_tran_power == 1)
            # f2.write("\n");

            fund_refl_ratio = np.abs(fund_refl_power /
                                     (fund_refl_power + not_fund_refl_power))
            first_order_refl_ratio = 0
            fund_tran_ratio = np.abs(fund_tran_power /
                                     (fund_tran_power + not_fund_tran_power))
            first_order_tran_ratio = 0

            f2.write("%s, " % [
                fund_refl_ratio, fund_refl_power, not_fund_refl_power,
                fund_refl_power + not_fund_refl_power, fund_tran_ratio,
                fund_tran_power, not_fund_tran_power,
                fund_tran_power + not_fund_tran_power
            ])

            plt.plot(y_list, np.abs(refl_val), 'bo-', label='reflectance')
            plt.plot(y_list, np.abs(tran_val), 'ro-', label='transmittance')
            plt.plot(y_list, E0, 'go-', label='E0')
            plt.plot(y_list, fund_refl, 'co-', label='over')
            plt.plot(y_list, not_fund_refl, 'ko-', label='over')
            # plt.axis([40.0, 300.0, 0.0, 100.0])
            plt.xlabel("y (um)")
            plt.ylabel("Field")
            plt.legend(loc="center right")
            plt.savefig(case + "fields.png")
            plt.close()

            #
            # print("\n")
            #
            # print(tran_val.size, refl_val.size)
            #
            # print("\n")
            #
            # print(tran_val, refl_val, E0)
            #
            # print("\n")
            # # print(np.conj(tran_val), tran_val, E1[:,2])
            # #
            # # print(np.conj(refl_val), refl_val, E1[:,2])
            #
            # refl_tot_power = np.abs(np.dot(np.conj(refl_val), refl_val))
            # tran_tot_power = np.abs(np.dot(np.conj(tran_val), tran_val))
            #
            # print(fund_refl_amp, refl_tot_power, fund_tran_amp, tran_tot_power)

            # print(fund_refl_amp 		, fund_refl_amp_2 		)
            # print(first_order_refl_amp 	, first_order_refl_amp_2)
            # print(fund_tran_amp 		, fund_tran_amp_2 		)
            # print(first_order_tran_amp 	, first_order_tran_amp_2)
            #
            # print(np.angle(fund_refl_amp), 			np.angle(fund_refl_amp_2))
            # print(np.angle(first_order_refl_amp), 	np.angle(first_order_refl_amp_2))
            # print(np.angle(fund_tran_amp), 			np.angle(fund_tran_amp_2))
            # print(np.angle(first_order_tran_amp), 	np.angle(first_order_tran_amp_2))

            # fund_refl_power = 			np.abs(fund_tran_amp)			** 2
            # fund_refl_power = 			np.abs(fund_refl_amp)			** 2
            # first_order_refl_power = 	np.abs(first_order_refl_amp) 	** 2
            # fund_tran_power = 			np.abs(fund_tran_amp) 			** 2
            # first_order_tran_power = 	np.abs(first_order_tran_amp) 	** 2

            # print(fund_refl_power, first_order_refl_power, fund_tran_power, first_order_tran_power)

            # fund_refl_ratio = 			fund_refl_power 		/ (fund_refl_power + first_order_refl_power)
            # first_order_refl_ratio = 	first_order_refl_power 	/ (fund_refl_power + first_order_refl_power)
            # fund_tran_ratio = 			fund_tran_power 		/ (fund_tran_power + first_order_tran_power)
            # first_order_tran_ratio = 	first_order_tran_power 	/ (fund_tran_power + first_order_tran_power)

            # fund_refl_power = 			np.abs(fund_refl_amp)			** 2
            # first_order_refl_power = 	np.abs(first_order_refl_amp)	** 2
            # fund_tran_power = 			np.abs(fund_tran_amp)			** 2
            # first_order_tran_power = 	np.abs(first_order_tran_amp)	** 2
            #
            # fund_refl_ratio = 			fund_refl_power 		/ refl_tot_power
            # first_order_refl_ratio = 	first_order_refl_power 	/ refl_tot_power
            # fund_tran_ratio = 			fund_tran_power 		/ tran_tot_power
            # first_order_tran_ratio = 	first_order_tran_power 	/ tran_tot_power
            #
            # fund_refl_ratio = 			1
            # first_order_refl_ratio = 	0
            # fund_tran_ratio = 			1
            # first_order_tran_ratio = 	0

            print("Percentage of reflected light in fundamental mode: ",
                  fund_refl_ratio * 100)
            print("Percentage of reflected light in first order mode: ",
                  first_order_refl_ratio * 100)
            print("Percentage of transmitted light in fundamental mode: ",
                  fund_tran_ratio * 100)
            print("Percentage of transmitted light in first order mode: ",
                  first_order_tran_ratio * 100)

            # ------------------------ CODE FOR SEPARATING FUND AND FIRST ORDER MODE ENDS HERE ------------------------

            wl = []  #list of wavelengths

            refl1_flux = mp.get_fluxes(refl1)
            refl2_flux = mp.get_fluxes(refl2)
            tran_flux = mp.get_fluxes(tran)
            su_flux = mp.get_fluxes(su)
            sd_flux = mp.get_fluxes(sd)

            flux_freqs = mp.get_flux_freqs(refl1)

            for i in range(nfreq):
                wl = np.append(wl, 1 / flux_freqs[i])
                print(1 / flux_freqs[i])

            # for ind, elt in enumerate(wl):
            #     #print(round(elt, 4))
            #     if round(elt, 3) == 0.637:
            #         #print("ALERT: MATCH FOUND")
            #         index = ind

            index = 0

            rp = refl1_flux[index]
            tp = tran_flux[index]

            # print("rp/tp:\n")
            # print(rp)
            # print(tp)
            # print("\n")

            R = -refl1_flux[index] / (refl2_flux[index] - refl1_flux[index])
            T = tran_flux[index] / (refl2_flux[index] - refl1_flux[index])
            S = (refl2_flux[index] - tran_flux[index]) / (refl2_flux[index] -
                                                          refl1_flux[index])
            Su = su_flux[index] / (refl2_flux[index] - refl1_flux[index])
            Sd = -sd_flux[index] / (refl2_flux[index] - refl1_flux[index])

            S_correction = (1 - R - T) / (Su + Sd)

            # print(R, T, S, Su, Sd)

            r = sqrt(R)
            t = sqrt(T)

            r_fund = (r * fund_refl_ratio) * np.exp(
                1j * np.angle(fund_refl_amp) + 2j * pi *
                (-Lr1 - w / 2) * n_eff_fund / wavelength
            )  # Lr1 is negative because it is the (negative) position of the monitor, not the distace from the monitor to the center.
            r_first = (r * first_order_refl_ratio) * np.exp(
                1j * np.angle(first_order_refl_amp) + 2j * pi *
                (-Lr1 - w / 2) * n_eff_first / wavelength)
            t_fund = (t * fund_tran_ratio
                      ) * np.exp(1j * np.angle(fund_tran_amp) + 2j * pi *
                                 (Lt - w / 2) * n_eff_fund / wavelength)
            t_first = (t * first_order_tran_ratio) * np.exp(
                1j * np.angle(first_order_tran_amp) + 2j * pi *
                (Lt - w / 2) * n_eff_first / wavelength)

            if mode == 0:
                r00 = r_fund
                r01 = r_first

                t00 = t_fund
                t01 = t_first

                su0 = sqrt(np.abs(Su * S_correction))
                sd0 = sqrt(np.abs(Sd * S_correction))
                # su0 = sqrt(Su)
                # sd0 = sqrt(Sd)

                r00s.append(r00)
                r01s.append(r01)
                t00s.append(t00)
                t01s.append(t01)
                su0s.append(su0)
                sd0s.append(sd0)

                if only_fund:
                    r10s.append(0)
                    r11s.append(0)
                    t10s.append(0)
                    t11s.append(1)
                    su1s.append(0)
                    sd1s.append(0)
            else:
                r10 = r_fund
                r11 = r_first

                t10 = t_fund
                t11 = t_first

                su1 = sqrt(np.abs(Su * S_correction))
                sd1 = sqrt(np.abs(Sd * S_correction))
                # su1 = sqrt(Su)
                # sd1 = sqrt(Sd)

                r10s.append(r10)
                r11s.append(r11)
                t10s.append(t10)
                t11s.append(t11)
                su1s.append(su1)
                sd1s.append(sd1)

            norm_Su = S * Su / (Su + Sd)

            NET = round((R + T + S) * 100, 0)
            if NET > 100.0:
                NET = 100.0

            NET_LOSS = round((Su + Sd) / S * 100, 0)
            if NET_LOSS > 100.0:
                NET_LOSS = 100.0
            '''
			np.append(ws, [w * 1000])
			np.append(Rs, [R * 100])
			np.append(Ts, [T * 100])
			np.append(Ss, [S * 100])
			np.append(NET_LIST, [NET])
			np.append(Sus, [Su * 100])
			np.append(Sds, [Sd * 100])
			np.append(NET_LOSS_LIST, [NET_LOSS])
			np.append(norm_Sus, [norm_Su * 100])
			'''

            if mode == 0:
                ws.append(w * 1000)
                Rs.append(R * 100)
                Ts.append(T * 100)
                Ss.append(S * 100)
                NET_LIST.append(NET)
                Sus.append(Su * 100)
                Sds.append(Sd * 100)
                NET_LOSS_LIST.append(NET_LOSS)
                norm_Sus.append(norm_Su * 100)

            if mode == 0:

                f1.write(
                    "--------------------------------------------------- \n")

                f1.write("Notch Width: %s nanometers \n" % (w * 1000))
                f1.write("Reflection Percentage: %s\n" % (R * 100))
                f1.write("Transmission Percentage: %s\n" % (T * 100))
                f1.write("Total Loss Percentage: %s\n" % (S * 100))
                f1.write("Percentage of Light Accounted For: %s\n" % (NET))
                f1.write("Upper Loss Percentage: %s\n" % (Su * 100))
                f1.write("Lower Loss Percentage: %s\n" % (Sd * 100))
                f1.write("Percentage of Total Loss Accounted For: %s\n" %
                         (NET_LOSS))
                f1.write("Normalized Upper Loss Percentage: %s\n" %
                         (norm_Su * 100))
                f1.write("\n \n")

                f1.write("FUNDAMENTAL MODE \n")
                f1.write("n_eff:   %s\n" % (n_eff_fund))
                f1.write("Re(r00): %s\n" % (np.real(r00)))
                f1.write("Im(r00): %s\n" % (np.imag(r00)))
                f1.write("Re(r01): %s\n" % (np.real(r01)))
                f1.write("Im(r01): %s\n" % (np.imag(r01)))
                f1.write("Re(t00): %s\n" % (np.real(t00)))
                f1.write("Im(t00): %s\n" % (np.imag(t00)))
                f1.write("Re(t01): %s\n" % (np.real(t01)))
                f1.write("Im(t01): %s\n" % (np.imag(t01)))
                f1.write("Re(su0): %s\n" % (np.real(su0)))
                f1.write("Im(su0): %s\n" % (np.imag(su0)))
                f1.write("Re(sd0): %s\n" % (np.real(sd0)))
                f1.write("Im(sd0): %s\n" % (np.imag(sd0)))
                f1.write("\n")

            else:

                f1.write("FIRST ORDER MODE \n")
                f1.write("n_eff:   %s\n" % (n_eff_first))
                f1.write("Re(r10): %s\n" % (np.real(r10)))
                f1.write("Im(r10): %s\n" % (np.imag(r10)))
                f1.write("Re(r11): %s\n" % (np.real(r11)))
                f1.write("Im(r11): %s\n" % (np.imag(r11)))
                f1.write("Re(t10): %s\n" % (np.real(t10)))
                f1.write("Im(t10): %s\n" % (np.imag(t10)))
                f1.write("Re(t11): %s\n" % (np.real(t11)))
                f1.write("Im(t11): %s\n" % (np.imag(t11)))
                f1.write("Re(su1): %s\n" % (np.real(su1)))
                f1.write("Im(su1): %s\n" % (np.imag(su1)))
                f1.write("Re(sd1): %s\n" % (np.real(sd1)))
                f1.write("Im(sd1): %s\n" % (np.imag(sd1)))

                f1.write(
                    "--------------------------------------------------- \n")

            sim.reset_meep()
sigma_dr = (a / c) * (1 / 100) / (eps_r * eps_0)

#normalization
wavelength = c / fIn
f = a / wavelength
nPointsPerWavelength = resolution / a * wavelength
df = fWidth * a / c
tScale = 2 * resolution

#initialize the computational cell
cellX = bwidth + 2 * buffer
cellY = bheight + 2 * buffer
cellZ = 0
#bthick + 2;
cell = mp.Vector3(cellX, cellY, cellZ)

maxPathLength = 2
t = maxPathLength / c
tau = t * c / a
nTimeSteps = tScale * tau

#output normalized values
print("Wavelength: ", wavelength)
print("Normalized Frequency: ", f)
print("Normalized Frequency Width: ", df)
print("Number of Points Per Wavelength: ", nPointsPerWavelength)
print("Stop Time (seconds): ", t)
print("Number of Time Steps: ", nTimeSteps)
print("Normalized Stop Time: ", tau)
Beispiel #30
0
 def _try(k, v):
     return try_plus(try_plus(k, v), mp.Vector3() - v)