class BlockZCG(Grating): #2D block ZCG si_n = interp.interp1d(*zip(*[[((speed_of_light*10**6)/float(f)),n] for f,n in opencsv('materials/silicon_n.csv',1)])) si_k = interp.interp1d(*zip(*[[((speed_of_light*10**6)/float(f)),n] for f,n in opencsv('materials/silicon_k.csv',1)])) def __init__(self, params, wavelengths, target = None, resample = False, fbases = 30): super().__init__(params, wavelengths, target) d, ff, tblocks, tslab = params self.labels = ['d','ff','tblocks', 'tslab'] #create simulation self.sim = S4.New(((d, 0), (0, d)), fbases) self.sim.AddMaterial("Vacuum", 1) self.sim.AddMaterial("Silicon", 0) #edited later in setmaterials self.sim.AddLayer('top', 0, "Vacuum") self.sim.AddLayer('blocks', tblocks, "Vacuum") self.sim.AddLayer('slab', tslab, "Silicon") self.sim.AddLayer('bottom', 0, "Vacuum") self.sim.SetRegionRectangle('blocks','Silicon',(0,0),0,(d*ff/2, d*ff/2)) self.sim.SetExcitationPlanewave((0, 0), 0, 1) def setmaterials(self, wl): self.sim.SetMaterial('Silicon', complex(self.__class__.si_n(wl), self.__class__.si_k(wl))**2)
class ZCG(Grating): si_n = interp.interp1d(*zip(*[[nu2lambda(float(f))*10**6, n] for (f, n) in opencsv('materials/silicon_n.csv',1)])) si_k = interp.interp1d(*zip(*[[nu2lambda(float(f))*10**6,n] for (f, n) in opencsv('materials/silicon_k.csv',1)])) def __init__(self, params, wavelengths, target = None, resample = False): super().__init__(params, wavelengths, target, resample) self.labels = ['d','ff','tline','tslab','tstep'] d, ff, tline, tslab, tstep = params assert tline > tstep, "tstep cannot be larger than tline" #create simulation self.sim = S4.New(d, 20) self.sim.AddMaterial("Vacuum", 1) self.sim.AddMaterial("Silicon", 0) #edited later in setmaterials self.sim.AddLayer('top', 0, "Vacuum") self.sim.AddLayer('step', tstep, "Vacuum") self.sim.AddLayer('lines', tline - tstep, "Vacuum") self.sim.AddLayer('slab', tslab, "Silicon") self.sim.AddLayer('bottom', 0, "Vacuum") self.sim.SetRegionRectangle('step', 'Silicon', (-d*ff/4, 0), 0, (d*ff/4, 0)) self.sim.SetRegionRectangle('lines', 'Silicon', (0,0), 0, (d*ff/2, 0)) self.sim.SetExcitationPlanewave((0, 0), 0, 1) def setmaterials(self, wl): self.sim.SetMaterial('Silicon', complex(self.__class__.si_n(wl), self.__class__.si_k(wl))**2)
def main(): SPEED_OF_LIGHT = 299792458 * 10**6 #in um/s #dimensions d = 4.7075 tline = 2.8249 tair = 1.6692 ff = 0.6215 tstep = 0.0847 si_n = interp.interp1d(*zip( *[[(SPEED_OF_LIGHT / float(f)), n] for f, n in h.opencsv('../matdat/silicon_n.csv', 1)])) si_k = interp.interp1d(*zip( *[[(SPEED_OF_LIGHT / float(f)), n] for f, n in h.opencsv('../matdat/silicon_k.csv', 1)])) #saph_n = interp.interp1d(*zip(*[[float(f)*(10**6),n] for f,n in h.opencsv('../matdat/al2o3_n.csv',1)])) #saph_k = interp.interp1d(*zip(*[[float(f)*(10**6),n] for f,n in h.opencsv('../matdat/al2o3_k.csv',1)])) for var in 'a': #np.linspace(3.6,4,5): n = var vartext = 'd' #create simulation S = S4.New(d, 30) #materials S.AddMaterial("Vacuum", 1) S.AddMaterial("Silicon", 16) #complex(12.1,2*10**-4)) S.AddMaterial('saph', 1) #layers S.AddLayer('top', 0, "Vacuum") S.AddLayer('step', tstep, "Vacuum") S.AddLayer('lines', tline - tstep, "Vacuum") S.AddLayer('slab', tair, "Vacuum") #S.AddLayer('bottom',0,'saph') S.AddLayerCopy('bottom', 0, 'top') #patterning S.SetRegionRectangle('step', 'Silicon', (-d * ff / 4, 0), 0, (d * ff / 4, 0)) S.SetRegionRectangle('lines', 'Silicon', (0, 0), 0, (d * ff / 2, 0)) #light S.SetExcitationPlanewave((0, 0), 0, 1) trans = [] wavelengths = np.linspace(8, 12, 2000) for wl in wavelengths: S.SetFrequency(1 / wl) #S.SetMaterial('saph',complex(saph_n(wl),saph_k(wl))**2) S.SetMaterial('Silicon', complex(si_n(wl), si_k(wl))**2) trans.append(float(np.real(S.GetPowerFlux('bottom')[0]))) #print("wl:",wl,"\ttrans:",trans[-1]) plt.plot(wavelengths, trans, label=vartext + ' = ' + str(var)) plt.legend() plt.show()
def main(): #parameters #numG = 3 #horizontal dimensions d = 4.3 d_stddev = 0/100 ff = 0.74 ff_stddev = 0/100 fhi = 1/2 #vertical dimensions tline = 2.7 tair = 4 tstep = 0.3 #material properties SPEED_OF_LIGHT = 299792458*10**6 #in um/s si_n = interp.interp1d(*zip(*[[(SPEED_OF_LIGHT/float(f)),n] for f,n in h.opencsv('matdat/silicon_n.csv',1)])) si_k = interp.interp1d(*zip(*[[(SPEED_OF_LIGHT/float(f)),n] for f,n in h.opencsv('matdat/silicon_k.csv',1)])) for numG in (1,3,5): #generate the grating lines; period is baked in pds = list(accumulate([0]+[d*gauss(1, d_stddev) for i in range(numG-1)])) pds = [i - (pds[0]+pds[-1])/2 for i in pds] fills = [round(d*ff*gauss(1, ff_stddev),3) for i in range(numG)] lines = list(zip(pds, fills)) #S4 #create simulation, basic layers print("size (ish):",2*pds[-1] + d) S = S4.New(2*pds[-1] + d*gauss(1, d_stddev),30) S.AddMaterial("Vacuum",1) S.AddMaterial("Silicon",complex(12.1,2*10**-4)) S.AddLayer('top',0,"Vacuum") S.AddLayer('step',tstep,"Vacuum") S.AddLayer('lines',tline-tstep,"Vacuum") S.AddLayer('airgap',tair,"Vacuum") S.AddLayer('bottom',0,'Silicon') #patterning (remember, period is already baked into cent and fill) print(lines) for (cent, fill) in lines: S.SetRegionRectangle('lines','Silicon',(cent,0),0,(fill/2,0)) S.SetRegionRectangle('step','Silicon',(cent+fill*(1-fhi)/2,0),0,(fill*fhi/2,0)) #excitation and measurement S.SetExcitationPlanewave((0,0),0,1) trans = [] wavelengths = np.linspace(7,13,1001) for wl in wavelengths: S.SetFrequency(1/wl) S.SetMaterial('Silicon',complex(si_n(wl),si_k(wl))**2) trans.append(float(np.real(S.GetPowerFlux('bottom')[0]))) plt.plot(wavelengths,trans, label = "numG: "+str(numG)) plt.legend() plt.show()
class NIRZCG(Grating): SPEED_OF_LIGHT = 299792458 * 10**9 #in nm/s si_n = interp.interp1d(*zip( *[[((299792458 * 10**9) / float(f)), n] for f, n in h.opencsv('../matdat/silicon_n.csv', 1)])) si_k = interp.interp1d(*zip( *[[((299792458 * 10**9) / float(f)), n] for f, n in h.opencsv('../matdat/silicon_k.csv', 1)])) sio2_n = interp.interp1d(*zip( *[[float(f) * (10**3), n] for f, n in h.opencsv('../matdat/sio2_n.csv', 1)])) sio2_k = interp.interp1d(*zip( *[[float(f) * (10**3), n] for f, n in h.opencsv('../matdat/sio2_k.csv', 1)])) def __init__(self, params, wavelengths, target=None): Grating.__init__(self, params, wavelengths, target) self.d, self.ff, self.tline, self.tslab, self.tstep = params self.labels = ['d', 'ff', 'tline', 'tslab', 'tstep'] self.edge_supp = 5 def evaluate(self): if self.fom is None: S = S4.New(self.d, 20) #materials S.AddMaterial("Vacuum", 1) S.AddMaterial("Silicon", 1) #edited later per wavelength S.AddMaterial("Oxide", 1) #layers S.AddLayer('top', 0, "Vacuum") S.AddLayer('step', self.tstep, "Vacuum") S.AddLayer('lines', self.tline - self.tstep, "Vacuum") S.AddLayer('slab', self.tslab, "Silicon") S.AddLayer('bottom', 0, "Oxide") #patterning S.SetRegionRectangle('step', 'Silicon', (-self.d * self.ff / 4, 0), 0, (self.d * self.ff / 4, 0)) S.SetRegionRectangle('lines', 'Silicon', (0, 0), 0, (self.d * self.ff / 2, 0)) #light S.SetExcitationPlanewave((0, 0), 0, 1) self.trans = [] for wl in np.linspace(*self.wls): S.SetFrequency(1 / wl) S.SetMaterial('Silicon', complex(NIRZCG.si_n(wl), NIRZCG.si_k(wl))**2) S.SetMaterial('Oxide', complex(NIRZCG.sio2_n(wl), NIRZCG.sio2_k(wl))**2) self.trans.append( (wl, float(np.real(S.GetPowerFlux('bottom')[0])))) self._calcfom() return self.fom
class ZCG(Grating): SPEED_OF_LIGHT = 299792458 * 10**6 #in um/s si_n = interp.interp1d(*zip( *[[((299792458 * 10**6) / float(f)), n] for f, n in h.opencsv('../matdat/silicon_n.csv', 1)])) si_k = interp.interp1d(*zip( *[[((299792458 * 10**6) / float(f)), n] for f, n in h.opencsv('../matdat/silicon_k.csv', 1)])) #saph_n = interp.interp1d(*zip(*[[float(f)*(10**6),n] for f,n in h.opencsv('../matdat/al2o3_n.csv',1)])) #saph_k = interp.interp1d(*zip(*[[float(f)*(10**6),n] for f,n in h.opencsv('../matdat/al2o3_k.csv',1)])) def __init__(self, params, wavelengths): Grating.__init__(self, params, wavelengths) self.d, self.ff, self.tline, self.tslab, self.tstep = params self.labels = ['d', 'ff', 'tline', 'tslab', 'tstep'] def evaluate(self): if self.fom is None: #self.tstep = max(0.1, self.tstep) #self.params[4] = self.tstep S = S4.New(self.d, 20) #materials S.AddMaterial("Vacuum", 1) S.AddMaterial("Silicon", 1) #edited later per wavelength #S.AddMaterial("Sapphire",1) #as above #layers S.AddLayer('top', 0, "Vacuum") S.AddLayer('step', self.tstep, "Vacuum") S.AddLayer('lines', self.tline - self.tstep, "Vacuum") S.AddLayer('slab', self.tslab, "Silicon") S.AddLayer('bottom', 0, "Vacuum") #patterning S.SetRegionRectangle('step', 'Silicon', (-self.d * self.ff / 4, 0), 0, (self.d * self.ff / 4, 0)) S.SetRegionRectangle('lines', 'Silicon', (0, 0), 0, (self.d * self.ff / 2, 0)) #light S.SetExcitationPlanewave((0, 0), 0, 1) self.trans = [] for wl in np.linspace(*self.wls): S.SetFrequency(1 / wl) S.SetMaterial('Silicon', complex(ZCG.si_n(wl), ZCG.si_k(wl))**2) #S.SetMaterial('Sapphire',complex(ZCG.saph_n(wl),ZCG.saph_k(wl))**2) self.trans.append( (wl, float(np.real(S.GetPowerFlux('bottom')[0])))) self._calcfom() return self.fom
def main(): saph_n = interp.interp1d(*zip( *[[float(f) * (10**6), n] for f, n in h.opencsv('../matdat/al2o3_n.csv', 1)])) saph_k = interp.interp1d(*zip( *[[float(f) * (10**6), n] for f, n in h.opencsv('../matdat/al2o3_k.csv', 1)])) kdat = [(wl, saph_n(wl)) for wl in np.linspace(2, 14, 251)] plt.plot(*zip(*kdat)) plt.show()
class ZCG2D(Grating2D): si_n = interp.interp1d(*zip( *[[((consts.speed_of_light * 10**6) / float(f)), n] for f, n in h.opencsv('matdat/silicon_n.csv', 1)])) si_k = interp.interp1d(*zip( *[[((consts.speed_of_light * 10**6) / float(f)), n] for f, n in h.opencsv('matdat/silicon_k.csv', 1)])) def evaluate(self, fbasis=30): if self.fom is None: S = S4.New(Lattice=((self.d, 0), (0, self.d)), NumBasis=fbasis) #materials S.AddMaterial("Vacuum", 1) S.AddMaterial("Silicon", 1) #edited later by wavelength #layers S.AddLayer('top', 0, "Vacuum") S.AddLayer('blocks', self.tblocks, "Vacuum") S.AddLayer('slab', self.tslab, "Silicon") S.AddLayer('bottom', 0, "Vacuum") #patterning for shape in self.allpolys: coords = shape.exterior.coords[: -1] if shape.exterior.is_ccw else shape.exterior.coords[: 0: -1] S.SetRegionPolygon('blocks', 'Silicon', (0, 0), 0, tuple(coords)) for inner in shape.interiors: coords = inner.coords[: -1] if inner.is_ccw else inner.coords[: 0: -1] S.SetRegionPolygon('blocks', 'Vacuum', (0, 0), 0, tuple(coords)) #light S.SetExcitationPlanewave((0, 0), 0, 1) self.trans = [] for wl in np.linspace(*self.wls): print("Solving for wavelength", wl, end='\r') S.SetFrequency(1 / wl) S.SetMaterial('Silicon', complex(ZCG2D.si_n(wl), ZCG2D.si_k(wl))**2) self.trans.append( (wl, float(np.real(S.GetPowerFlux('bottom')[0])))) self._calcfom() return self.fom
class HCG(Grating): si_n = interp.interp1d(*zip( *[[nu2lambda(float(f)) * 10**6, n] for (f, n) in h.opencsv('../matdat/silicon_n.csv', 1)])) si_k = interp.interp1d(*zip( *[[nu2lambda(float(f)) * 10**6, n] for (f, n) in h.opencsv('../matdat/silicon_k.csv', 1)])) def __init__(self, params, wavelengths, target): Grating.__init__(self, params, wavelengths, target) self.d, self.ff, self.tline, self.tslab, self.tstep = params self.labels = ['d', 'ff', 'tline', 'tair', 'tstep'] if self.tstep > self.tline: raise ValueError("tstep cannot be larger than tline") def evaluate(self): if self.fom is None: S = S4.New(self.d, 20) #materials S.AddMaterial("Vacuum", 1) S.AddMaterial("Silicon", 1) #edited later per wavelength #layers S.AddLayer('top', 0, "Vacuum") S.AddLayer('step', self.tstep, "Vacuum") S.AddLayer('lines', self.tline - self.tstep, "Vacuum") S.AddLayer('airgap', self.tslab, "Vacuum") S.AddLayer('bottom', 0, "Silicon") #patterning S.SetRegionRectangle('step', 'Silicon', (-self.d * self.ff / 4, 0), 0, (self.d * self.ff / 4, 0)) S.SetRegionRectangle('lines', 'Silicon', (0, 0), 0, (self.d * self.ff / 2, 0)) #light S.SetExcitationPlanewave((0, 0), 0, 1) self.trans = [] for wl in np.linspace(*self.wls): S.SetFrequency(1 / wl) S.SetMaterial( 'Silicon', complex(self.__class__.si_n(wl), self.__class__.si_k(wl))**2) self.trans.append( (wl, float(np.real(S.GetPowerFlux('bottom')[0])))) self._calcfom() self.findpeak() return self.fom
def main(): SPEED_OF_LIGHT = 299792458 * 10**6 #in um/s #dimensions d = 4.8 tline = 2.7 tslab = 1.6 ff = 2 / 3 tstep = 0.25 si_n = interp.interp1d(*zip( *[[(SPEED_OF_LIGHT / float(f)), n] for f, n in h.opencsv('matdat/silicon_n.csv', 1)])) si_k = interp.interp1d(*zip( *[[(SPEED_OF_LIGHT / float(f)), n] for f, n in h.opencsv('matdat/silicon_k.csv', 1)])) for tslab in np.linspace(1.45, 1.55, 5): #create simulation S = S4.New(d, 30) #materials S.AddMaterial("Vacuum", 1) S.AddMaterial("Silicon", complex(12.1, 2 * 10**-4)) #layers S.AddLayer('top', 0, "Vacuum") S.AddLayer('step', tstep, "Vacuum") S.AddLayer('lines', tline - tstep, "Vacuum") S.AddLayer('slab', tslab, "Silicon") S.AddLayerCopy('bottom', 0, 'top') #patterning S.SetRegionRectangle('step', 'Silicon', (-d * ff / 4, 0), 0, (d * ff / 4, 0)) S.SetRegionRectangle('lines', 'Silicon', (0, 0), 0, (d * ff / 2, 0)) #light S.SetExcitationPlanewave((0, 0), 0, 1) trans = [] wavelengths = np.linspace(7, 13, 1000) for wl in wavelengths: S.SetFrequency(1 / wl) S.SetMaterial('Silicon', complex(si_n(wl), si_k(wl))**2) trans.append(float(np.real(S.GetPowerFlux('bottom')[0]))) plt.plot(wavelengths, trans, label='tslab=' + str(tslab)) plt.legend() plt.show()
class BlockHCG(Grating): #2D block HCG SPEED_OF_LIGHT = 299792458 * 10**6 #in um/s si_n = interp.interp1d(*zip( *[[((299792458 * 10**6) / float(f)), n] for f, n in h.opencsv('../matdat/silicon_n.csv', 1)])) si_k = interp.interp1d(*zip( *[[((299792458 * 10**6) / float(f)), n] for f, n in h.opencsv('../matdat/silicon_k.csv', 1)])) def __init__(self, params, wavelengths): Grating.__init__(self, params, wavelengths) self.d, self.ff, self.tblocks, self.tair = params self.labels = ['d', 'ff', 'tblocks', 'tair'] def evaluate(self): if self.fom is None: S = S4.New(Lattice=((self.d, 0), (0, self.d)), NumBasis=20) #materials S.AddMaterial("Vacuum", 1) S.AddMaterial("Silicon", 1) #edited later by wavelength #layers S.AddLayer('top', 0, "Vacuum") S.AddLayer('blocks', self.tblocks, "Vacuum") S.AddLayer('airgap', self.tair, "Vacuum") S.AddLayer('bottom', 0, "Silicon") #patterning S.SetRegionRectangle('blocks', 'Silicon', (0, 0), 0, (self.d * self.ff / 2, self.d * self.ff / 2)) #light S.SetExcitationPlanewave((0, 0), 0, 1) self.trans = [] for wl in np.linspace(*self.wls): S.SetFrequency(1 / wl) S.SetMaterial('Silicon', complex(BlockHCG.si_n(wl), BlockHCG.si_k(wl))**2) self.trans.append( (wl, float(np.real(S.GetPowerFlux('bottom')[0])))) self._calcfom() return self.fom
class BlockZCG(Grating): #2D block ZCG si_n = interp.interp1d(*zip( *[[((speed_of_light * 10**6) / float(f)), n] for f, n in h.opencsv('materials/silicon_n.csv', 1)])) si_k = interp.interp1d(*zip( *[[((speed_of_light * 10**6) / float(f)), n] for f, n in h.opencsv('materials/silicon_k.csv', 1)])) def __init__(self, params, wavelengths, target): Grating.__init__(self, params, wavelengths, target) self.d, self.ff, self.tblocks, self.tslab = params self.labels = ['d', 'ff', 'tblocks', 'tslab'] def evaluate(self, fbasis=30): if self.fom is None: S = S4.New(Lattice=((self.d, 0), (0, self.d)), NumBasis=fbasis) #materials S.AddMaterial("Vacuum", 1) S.AddMaterial("Silicon", 1) #edited later by wavelength #layers S.AddLayer('top', 0, "Vacuum") S.AddLayer('blocks', self.tblocks, "Vacuum") S.AddLayer('slab', self.tslab, "Silicon") S.AddLayer('bottom', 0, "Vacuum") #patterning S.SetRegionRectangle('blocks', 'Silicon', (0, 0), 0, (self.d * self.ff / 2, self.d * self.ff / 2)) #light S.SetExcitationPlanewave((0, 0), 0, 1) self.trans = [] for wl in np.linspace(*self.wls): S.SetFrequency(1 / wl) S.SetMaterial( 'Silicon', complex(self.__class__.si_n(wl), self.__class__.si_k(wl))**2) self.trans.append( (wl, float(np.real(S.GetPowerFlux('bottom')[0])))) self._calcfom() self.findpeak()
def main(): SPEED_OF_LIGHT = 299792458*10**6 #in um/s #dimensions d = 4.8 tline = 2.7 tslab = 1.6 ff=2/3 si_n = interp.interp1d(*zip(*[[(SPEED_OF_LIGHT/float(f)),n] for f,n in h.opencsv('matdat/silicon_n.csv',1)])) si_k = interp.interp1d(*zip(*[[(SPEED_OF_LIGHT/float(f)),n] for f,n in h.opencsv('matdat/silicon_k.csv',1)])) for a in 'a':#np.linspace(0, 0.3, 6): #create simulation S = S4.New(d,30) #materials S.AddMaterial("Vacuum",1) S.AddMaterial("Silicon",complex(12.1,2*10**-4)) #layers S.AddLayer('top',0,"Vacuum") S.AddLayer('lines',tline,"Vacuum") S.AddLayer('slab',tslab,"Silicon") S.AddLayerCopy('bottom',0,'top') #patterning S.SetRegionRectangle('lines','Silicon',(0,0),0,(d*ff/2,0)) #light S.SetExcitationPlanewave((0,0),0,1) trans = [] wavelengths = np.linspace(7,13,500) for wl in wavelengths: S.SetFrequency(1/wl) S.SetMaterial('Silicon',complex(si_n(wl),si_k(wl))**2) trans.append(float(np.real(S.GetPowerFlux('bottom')[0]))) h.writecsv('d48_tline27_tslab16_ff667.csv', zip(wavelengths, trans), ['Wavelength (um)','Transmittance']) plt.plot(wavelengths,trans, label='tline='+str(tline)) plt.legend() plt.show()
import lib.helpers as h import scipy.interpolate as interp SPEED_OF_LIGHT = 299792458 * 10**6 #in um/s si_n = interp.interp1d(*zip( *[[(SPEED_OF_LIGHT / float(f)), n] for f, n in h.opencsv('matdat/silicon_n.csv', 1)])) si_k = interp.interp1d(*zip( *[[(SPEED_OF_LIGHT / float(f)), n] for f, n in h.opencsv('matdat/silicon_k.csv', 1)]))
class BiZCG(Grating): si_n = interp.interp1d(*zip( *[[nu2lambda(float(f)) * 10**6, n] for (f, n) in h.opencsv('../matdat/silicon_n.csv', 1)])) si_k = interp.interp1d(*zip( *[[nu2lambda(float(f)) * 10**6, n] for (f, n) in h.opencsv('../matdat/silicon_k.csv', 1)])) def __init__(self, params, wavelengths, target, angle=5): Grating.__init__(self, params, wavelengths, target) self.labels = ['d', 'ff', 'tline1', 'tline2', 'tslab', 'angle'] self.d, self.ff, self.tline1, self.tline2, self.tslab, self.angle = params if self.tline2 > self.tline1: self.tline2, self.tline1 = self.tline1, self.tline2 if self.tslab + self.tline2 < 0: raise ValueError("-self.tline > self.tslab") def evaluate(self): if self.fom is None: S = S4.New(self.d, 20) #materials S.AddMaterial("Vacuum", 1) S.AddMaterial("Silicon", 1) #edited later per wavelength #layers S.AddLayer('top', 0, "Vacuum") S.AddLayer('line1', self.tline1 - self.tline2, "Vacuum") S.AddLayer('line2', self.tline2 - self.tslab, "Vacuum") S.AddLayer('slab', self.tslab, "Silicon") S.AddLayer('bottom', 0, "Vacuum") #patterning S.SetRegionRectangle('line1', 'Silicon', (-3 * self.d * self.ff / 8, 0), 0, (self.d * self.ff / 8, 0)) S.SetRegionRectangle('line2', 'Silicon', (-3 * self.d * self.ff / 8, 0), 0, (self.d * self.ff / 8, 0)) S.SetRegionRectangle('line2', 'Silicon', (self.d * self.ff / 8, 0), 0, (self.d * self.ff / 8, 0)) all_trans = [] for theta in (0, self.angle): #light S.SetExcitationPlanewave((0, 0), np.sin(theta), np.cos(theta)) self.trans = [] for wl in np.linspace(*self.wls): S.SetFrequency(1 / wl) S.SetMaterial( 'Silicon', complex(self.__class__.si_n(wl), self.__class__.si_k(wl))**2) self.trans.append( (wl, float(np.real(S.GetPowerFlux('bottom')[0])))) all_trans.append(self.trans) trans_metadata = [] for trans in all_trans: self.trans = trans self.fom, self.peak, self.linewidth = 3 * (None, ) self.findpeak() self._calcfom() trans_metadata.append((self.fom, self.peak, self.linewidth)) self.trans = all_trans self.fom, self.peak, self.linewidth = max(trans_metadata) return self.fom def mutate(self): child = Grating.mutate(self) if random() > 2 / 3: child.params[3] = -min(self.tline2, 0.9 * self.tslab) child.params[5] = self.angle return child def crossbreed(self, rhs): child = Grating.mutate(self) child.params[5] = self.angle return child
import numpy as np import scipy.interpolate as interp import lib.helpers as h import matplotlib.pyplot as plt import numpy as np SPEED_OF_LIGHT = 299792458*10**6 #in um/s si_n = interp.interp1d(*zip(*[[((299792458*10**6)/float(f)),n] for f,n in h.opencsv('../matdat/silicon_n.csv',1)])) si_k = interp.interp1d(*zip(*[[((299792458*10**6)/float(f)),n] for f,n in h.opencsv('../matdat/silicon_k.csv',1)])) saph_n = interp.interp1d(*zip(*[[float(f)*(10**6),n] for f,n in h.opencsv('../matdat/al2o3_n.csv',1)])) saph_k = interp.interp1d(*zip(*[[float(f)*(10**6),n] for f,n in h.opencsv('../matdat/al2o3_k.csv',1)])) sidat = [(wl, si_n(wl)) for wl in np.linspace(3,5,200)] saphdat = [(wl, saph_n(wl)) for wl in np.linspace(3,5,200)] print([float(si_n(wl)) for wl in np.linspace(3,5,10)]) print([float(saph_n(wl)) for wl in np.linspace(3,5,10)]) plt.plot(*zip(*sidat), label='Silicon') plt.plot(*zip(*saphdat), label='Sapphire') plt.legend() plt.show()
class HCG: edge_supp = 15 #peak near edge suppresion SPEED_OF_LIGHT = 299792458*10**6 #in um/s si_n = interp.interp1d(*zip(*[[((299792458*10**6)/float(f)),n] for f,n in h.opencsv('../matdat/silicon_n.csv',1)])) si_k = interp.interp1d(*zip(*[[((299792458*10**6)/float(f)),n] for f,n in h.opencsv('../matdat/silicon_k.csv',1)])) def __init__(self, params, wavelengths): self.d, self.ff, self.tline, self.tair, self.tstep = params self.wls = wavelengths self.fom, self.trans = None, None def __str__(self): lbls = ('d', 'ff', 'tline', 'tair','tstep') #, 'tstep') vals = (self.d, self.ff, self.tline, self.tair,self.tstep) #, self.tstep) strrep = ', '.join([l+' = '+str(round(v, 4)) for l, v in zip(lbls, vals)]) strrep += ', fom: '+str(round(self.fom, 4)) if self.fom is not None else '' return strrep def _calcfom(self): invrms = lambda x: (sum([a**2 for a in x])/len(x))**(-1/2) peak = max(self.trans, key=lambda x:x[1]) leftloc = rightloc = peakloc = self.trans.index(peak) while self.trans[leftloc][1] > peak[1]/2 and leftloc > 0: leftloc -= 1 leftwl = self.trans[leftloc][0] + (self.trans[leftloc+1][0]-self.trans[leftloc][0])\ *(peak[1]/2-self.trans[leftloc][1])/(self.trans[leftloc+1][1]-self.trans[leftloc][1]) while self.trans[rightloc][1] > peak[1]/2 and rightloc < len(self.trans)-1: rightloc += 1 rightwl = self.trans[rightloc][0] + (self.trans[rightloc][0]-self.trans[rightloc-1][0])\ *(self.trans[rightloc][1]-peak[1]/2)/(self.trans[rightloc][1]-self.trans[rightloc-1][1]) if leftloc > 0 and rightloc < len(self.trans): bg = [t for wl, t in self.trans[:leftloc]] + [t for wl, t in self.trans[rightloc:]] self.fom = invrms(bg) if self.fom > 25: peakedge = 1 - exp(-HCG.edge_supp*(peak[0]-self.wls[0])/(self.wls[1]-self.wls[0])) \ - exp(-HCG.edge_supp*(self.wls[1]-peak[0])/(self.wls[1]-self.wls[0])) self.fom *= peakedge*(peak[1]**2)/(rightwl-leftwl) else: self.fom = invrms([t for wl, t in self.trans]) def evaluate(self): if self.fom is None: S = S4.New(self.d, 20) #materials S.AddMaterial("Vacuum",1) S.AddMaterial("Silicon",1) #edited later per wavelength #layers S.AddLayer('top',0,"Vacuum") S.AddLayer('step',self.tstep,"Vacuum") S.AddLayer('lines',self.tline - self.tstep,"Vacuum") S.AddLayer('air gap',self.tair,"Vacuum") S.AddLayer('bottom',0,"Silicon") #patterning S.SetRegionRectangle('step','Silicon',(-self.d*self.ff/4,0),0,(self.d*self.ff/4,0)) S.SetRegionRectangle('lines','Silicon',(0,0),0,(self.d*self.ff/2,0)) #light S.SetExcitationPlanewave((0,0),0,1) self.trans = [] for wl in np.linspace(*self.wls): S.SetFrequency(1/wl) S.SetMaterial('Silicon',complex(HCG.si_n(wl),HCG.si_k(wl))**2) self.trans.append((wl, float(np.real(S.GetPowerFlux('bottom')[0])))) self._calcfom() return self.fom def mutate(self): child = copy.deepcopy(self) child.fom, child.trans = None, None z = lambda x: round(x*random.gauss(1, 0.05), 4) child.d = z(child.d) #child.ff = z(child.ff) child.tline = z(child.tline) child.tair = z(child.tair) child.tstep = z(child.tstep) return child
class BiZCG(Grating): SPEED_OF_LIGHT = 299792458 * 10**6 #in um/s si_n = interp.interp1d(*zip( *[[((299792458 * 10**6) / float(f)), n] for f, n in h.opencsv('../matdat/silicon_n.csv', 1)])) si_k = interp.interp1d(*zip( *[[((299792458 * 10**6) / float(f)), n] for f, n in h.opencsv('../matdat/silicon_k.csv', 1)])) def __init__(self, params, wavelengths, angle=5): Grating.__init__(self, params, wavelengths) self.d, self.ff, self.tline1, self.tline2, self.tslab = params if self.tline2 > self.tline1: self.tline2, self.tline1 = self.tline1, self.tline2 self.angle = angle self.labels = ['d', 'ff', 'tline1', 'tline2', 'tslab'] def __str__(self): strrep = ', '.join([ l + ' = ' + str(round(v, 4)) for l, v in zip(self.labels, self.params) ]) strrep += ", angle = " + str(self.angle) + " deg" if self.fom: strrep += ', fom: ' + str(round(self.fom, 4)) return strrep def evaluate(self): if self.fom is None: S = S4.New(self.d, 20) #materials S.AddMaterial("Vacuum", 1) S.AddMaterial("Silicon", 1) #edited later per wavelength #layers S.AddLayer('top', 0, "Vacuum") S.AddLayer('line1', self.tline1 - self.tline2, "Vacuum") S.AddLayer('line2', self.tline2 - self.tslab, "Vacuum") S.AddLayer('slab', self.tslab, "Silicon") S.AddLayer('bottom', 0, "Vacuum") #patterning S.SetRegionRectangle('line1', 'Silicon', (-3 * self.d * self.ff / 8, 0), 0, (self.d * self.ff / 8, 0)) S.SetRegionRectangle('line2', 'Silicon', (-3 * self.d * self.ff / 8, 0), 0, (self.d * self.ff / 8, 0)) S.SetRegionRectangle('line2', 'Silicon', (self.d * self.ff / 8, 0), 0, (self.d * self.ff / 8, 0)) foms, peaks = [], [] for theta in (0, self.angle): self.trans = [] #light S.SetExcitationPlanewave((0, 0), np.sin(theta), np.cos(theta)) for wl in np.linspace(*self.wls): S.SetFrequency(1 / wl) S.SetMaterial('Silicon', complex(BiZCG.si_n(wl), BiZCG.si_k(wl))**2) self.trans.append( (wl, float(np.real(S.GetPowerFlux('bottom')[0])))) self._calcfom() foms.append(self.fom) peaks.append(self.peak) self.fom = min(foms) if self.fom > 20: self.fom *= exp(-(max(peaks) - min(peaks)) / 0.1) return self.fom
def main(): #parameters #numG = 3 #horizontal dimensions d = 4.3 ff = 0.74 fhi = 1 / 4 #vertical dimensions tline = 2.7 tair = 4 tstep = 0.3 #material properties SPEED_OF_LIGHT = 299792458 * 10**6 #in um/s si_n = interp.interp1d(*zip( *[[(SPEED_OF_LIGHT / float(f)), n] for f, n in h.opencsv('../matdat/silicon_n.csv', 1)])) si_k = interp.interp1d(*zip( *[[(SPEED_OF_LIGHT / float(f)), n] for f, n in h.opencsv('../matdat/silicon_k.csv', 1)])) #S4 for numG in range(1, 6): #create simulation, basic layers S = S4.New(d * numG, 30) S.AddMaterial("Vacuum", 1) S.AddMaterial("Silicon", complex(12.1, 2 * 10**-4)) S.AddLayer('top', 0, "Vacuum") S.AddLayer('step', tstep, "Vacuum") S.AddLayer('lines', tline - tstep, "Vacuum") S.AddLayer('airgap', tair, "Vacuum") S.AddLayer('bottom', 0, 'Silicon') #patterning (remember, period is already baked into cent and fill) print("numG:", numG) for cent in [ j + (0 if numG % 2 else 1 / 2) for j in range((1 - numG) // 2, (1 + numG) // 2) ]: print("line", cent, "is centered on", d * cent, "and is", d * ff / 2, "halfwide") print("step", cent, "is centered on", d * (cent + ff * (1 - fhi) / 2), "and is", d * ff * fhi / 2, "halfwide") S.SetRegionRectangle('lines','Silicon', Angle = 0,\ Center = (d*cent,0), Halfwidths = (d*ff/2,0)) S.SetRegionRectangle('step','Silicon', Angle = 0,\ Center = (cent+ff*(1-fhi)/2,0), Halfwidths = (d*ff*fhi/2,0)) #excitation and measurement S.SetExcitationPlanewave((0, 0), 0, 1) trans = [] wavelengths = np.linspace(7, 13, 21) for wl in wavelengths: S.SetFrequency(1 / wl) S.SetMaterial('Silicon', complex(si_n(wl), si_k(wl))**2) trans.append(float(np.real(S.GetPowerFlux('bottom')[0]))) plt.plot(wavelengths, trans, label="numG: " + str(numG)) plt.legend() plt.show()