########################################################################### # Scriptfile: oled.lsf # # Description: # This file is used to calculate the incoherent angular emission # from an istropic ensemble of dipole emitters for oled applications. # For each structure it calculates an x, y and z oriented dipole # and then adds |E|^2 in the far field to calculate the response of # isotropic dipoles. # # The data is then exported to an ASAP *.inr file as a rayset so # that it can be used as a source to design the packaging and # other macroscopic components of an oled. # # The file is organized into 3 sections. Each section can # be run independently # 1) Setup and running of FDTD simulations # 2) Analysis of FDTD simulations # 3) Export of results to ASAP *.inr file # # # Currently, there is an assumption that the position of the dipole # in the x-y plane is not important, and the structure must # be symmetric with respect to reflection in the x=0 plane and the # y=0 plane. The script could be modified to break the assumptions # of symmetry and to model several dipole positions with respect # to any patterning of the layers. # # # Copyright 2007, Lumerical Solutions, Inc. ########################################################################### # Choose which components to run (1 for yes, 0 for no) # The first time, each component needs to be run rerun_simulations = 1; rerun_analysis = 1; rerun_asap_export = 1; # Choose the name of the template fsp file. In this example, the file should # either oled1 or oled2, but can be changed to run the user's own file. basefilename = "oled1"; # Choose the size and position of the emission region when exporting to ASAP x1_asap = -0.25e-3; x2_asap = 0.25e-3; y1_asap = -0.25e-3; y2_asap = 0.25e-3; z_asap = 0; # Choose how many copies of the original rayset to export N_export = 10; ############################################################ # Setup and running of FDTD simulations ############################################################ # rerun the simulations if requested if(rerun_simulations) { # Choose how the simulations are run # 1: standard with graphical interface # 2: no graphical window # 3: parallel runtype = 3; # load the desired template file load(basefilename+".fsp"); # x dipole simulation, setup appropriate boundary conditions # and orient the dipole appropriately switchtolayout; setnamed("FDTD","x min bc","Anti-Symmetric"); setnamed("FDTD","y min bc","Symmetric"); setnamed("Source1","theta",90); setnamed("Source1","phi",0); save(basefilename+"_x.fsp"); run(runtype); # y dipole simulation, setup appropriate boundary conditions # and orient the dipole appropriately switchtolayout; setnamed("FDTD","x min bc","Symmetric"); setnamed("FDTD","y min bc","Anti-Symmetric"); setnamed("Source1","theta",90); setnamed("Source1","phi",90); save(basefilename+"_y.fsp"); run(runtype); # z dipole simulation, setup appropriate boundary conditions # and orient the dipole appropriately switchtolayout; setnamed("FDTD","x min bc","Symmetric"); setnamed("FDTD","y min bc","Symmetric"); setnamed("Source1","theta",0); setnamed("Source1","phi",0); save(basefilename+"_z.fsp"); run(runtype); } ############################################################ # Analysis of the results of the FDTD simulations ############################################################ if(rerun_analysis) { # Ensure that CW Normalization is used during the analysis # This should always be used when exporting data to ASAP cwnorm; # Choose a far field filter setting to reduce erroneous ripple # in the far field data due to the finite size of the simulation # in the x-y plane farfieldfilter(0.25); # Choose a resolution for the far field calculation # The far field data will have size resXres # The number should be odd to get a data point at precisely normal (theta=0) res = 201; # Choose the frequency point for the calculation # In the example files, we had 50 frequency points from 400 to 700 nm # Point 27 corresponds to approximately 500 nm fpoint = 27; # set the name of the monitor that records the field transmitted to the substrate monname = "substrate_monitor"; # load the x-dipole results load(basefilename+"_x.fsp"); # calculate the far field and near fields E2_near = getelectric(monname); # returns |E|^2 in near field E2_far = farfield3d(monname,fpoint,res,res); # return |E|^2 at 1 m distance # load the y-dipole results load(basefilename+"_y.fsp"); # calculate the far field and near fields E2_near = E2_near + getelectric(monname); # add to previous result E2_far = E2_far + farfield3d(monname,fpoint,res,res); #add to previous result # load the z-dipole results load(basefilename+"_z.fsp"); # calculate the far field and near fields E2_near = E2_near + getelectric(monname); # add to previous result E2_far = E2_far + farfield3d(monname,fpoint,res,res); #add to previous result # select the appropriate frequency point for the near field data E2_near = pinch(E2_near,4,fpoint); # normalize the far field distribution to have a maximum value of 1 E2_far = E2_far/max(E2_far); # get the vector of frequencies recorded f = getdata(monname,"f"); # output to the user the current wavelength of the calculation based on # the choise of fpoint ?"working at a wavelength of: " + num2str(c/f(fpoint)*1e9) + " nm"; # collect the x and y vectors for the near field data x = getdata(monname,"x"); y = getdata(monname,"y"); # image the near field results on linear and logarithmic scale image(x*1e6,y*1e6,E2_near,"x (microns)","y (microns)","|E|^2 vs x,y near field"); image(x*1e6,y*1e6,E2_near,"x (microns)","y (microns)","|E|^2 vs x,y near field, logscale","logplot"); # get the direction cosines for the far field projections ux = farfieldux(monname,fpoint,res,res); uy = farfielduy(monname,fpoint,res,res); # image the far field results (note the polar option in the plot options) image(ux,uy,E2_far,"","","|E|^2 in far field","polar"); } ############################################################ # Export the results to ASAP ############################################################ if(rerun_asap_export) { # set the output file name to the same as basefilename with the *.inr extension filename = basefilename+".inr"; # make sure the file is deleted if it already exists rm(filename); # create a 2D mesh of direction cosines Ux = meshgridx(ux,uy); Uy = meshgridy(ux,uy); Uz = real(sqrt(1-Ux^2-Uy^2)); # create a filter to remove rays at imaginary angles filter = Ux^2 + Uy^2 < 0.99; # add the asap command EMITTING RAYS write(filename,"emitting rays"); # initialize a counter of the total number of exported rays ray_counter = 0; # initialize a counter to output progress to user counter = 0; for(ii=1:N_export) { # output progress to screen ?"Completed " + num2str(counter/N_export*100) +"%"; counter = counter+1; # reserve a matrix for exporting the entire rayset (once) outresult = matrix(length(ux)*length(uy),7); # fill in the matrix with the correct data pos=0; for(i=1:length(ux)) { for(j=1:length(uy)) { if(filter(i,j)) { ray_counter = ray_counter+1; pos = pos+1; xrand = rand*(x2_asap-x1_asap) + x1_asap; yrand = rand*(y2_asap-y1_asap) + y1_asap; outresult(pos,1) = xrand; outresult(pos,2) = yrand; outresult(pos,3) = z_asap; outresult(pos,4) = Ux(i,j); outresult(pos,5) = Uy(i,j); outresult(pos,6) = Uz(i,j); # divide the ray flux by cos(theta) to account for the # the uneven angular sampling outresult(pos,7) = E2_far(i,j)/Uz(i,j); } } } # cut down the result to remove zeros at the end outresult = outresult(1:pos,1:7); # write the rayset to the file write(filename,num2str(outresult)); } # write the ASAP RETURN command write(filename,"return"); # inform the user of the total number of exported rays ?"output: " + num2str(ray_counter) + " rays"; }