0% found this document useful (0 votes)
169 views14 pages

CW Generation Rate

Uploaded by

mymunasadiaa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
169 views14 pages

CW Generation Rate

Uploaded by

mymunasadiaa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

##############################################

# CW generation rate

# This script calculates the electrical generation

# rate by assuming that each absorbed photon generates

# one electron-hole pair.

# The illumination is assumed to be single frequency. The actual

# source intensity is set as an input parameter of this object.

# This object also saves the data to a data file that

# can be imported into the Generation rate object within

# Lumerical's DEVICE, for further electrical simulation.

# Notes:

# Exporting the generation rate for DEVICE

# This object exports the generation rate data

# in a form that can be easily imported into

# the Import Generation rate object.

# Exporting multiple periods

changedevice multipleperado
ty
# Typical FDTD simulations include a single period

# of the structure, while typical DEVICE simulations


-82
=

CIRIN multiple period 8T


# include many periods. This script will array the
mem

# generation rate data to several periods, simplifying


~

# the process of importing the data into DEVICE.


-

# Jsc calculation in 2D/3D simulations

# When calculating Jsc in 3D simulations, we assume the source

# propagation is along Z. In 2D, propagation along Y.


#

# Input properties

# export filename: file name used to export generation rate data to DEVICE

# axis to average: the 2D DEVICE solver can only import 2D generation rate data.

# average dimension: the dimension to compress, by averaging the generation rate over
that dimension. 'x' or 'y', or 'none'. Only for 3D simulations. 4
-

T
# periods: the number of periods to array the generation rate. X
absorption & generation
# implemented when compressing in one dimension. & plot 82Es
& we a by
# make plots: if set to 1, the analysis script will create plots of the absorption and make
generation rate making
plot = 1
.

# source intensity: Intensity of the real illumination, in Watts/m^2. The illumination is


assumed to be single

# frequency. If the monitors have data at multiple frequency points, the data will
be averaged

# over frequency.

# Output properties

# Pabs: power absorbed per unit volume at each position (units: fraction of source
vin
power/m^3)
~

# Pabs_total: total absorbed power vs frequency


-pesunittime
per
-
unit volume
# G: electrical generation rate as a function of x,y,z (units: charge pairs/m^3/s) I
generated
change
- - -

# G_export the generation rate exported to DEVICE (averaged and/or arrayed) (units: pains
-
charge pairs/m^3/s) difference between
Go G-export
# Jsc: short circuit current density (units: Amp/m^2 in both 3D and 2D)

# Tags: generation rate electron hole charge device short circuit current

#
# Copyright 2012 Lumerical Solutions Inc

##############################################

# get position vectors from monitor

# Note that the monitor interpolation is disabled, so we also need the offset vectors

f=getdata("field","f");

x=getdata("field","x",1);

y=getdata("field","y",1);
>
-

load the spatial grid (4 Y 2) and .


,

z=getdata("field","z",1); data (f) of the simulated


delta_x=getdata("field","delta_x",1);
frequency
[ field from monitorin FDTD
offsets the .

delta_y=getdata("field","delta_y",1);

if (havedata("field","dimension")==3) {

delta_z=getdata("field","delta_z",1);

} else {

delta_z = 0;

of
Nx = length(x);
These defines the dimension the
grid . (r . y , 2) & the
of
Ny = length(y);
number
frequency points .

Nz = length(z);

Nf = length(f);

########################################################################
##

# Calculate spatial absorption


Create far
a yD
amay angulars
-

>
?"Starting absorption (Pabs) calculation";

requency
3DS2- W = meshgrid4d(4,x,y,z,f*2*pi); # create 4D matrix of f .
git
SP = meshgrid4d(4,x,y,z,sourcepower(f)); # 4D matrix of source power > GD for power
point18- array
-

freg & powers


data
at each
frequency
# calculate spatial absorption from each field component separately (watts/m^3)

if (havedata("index","index_x")) {
~
Pabs_x = 0.5*eps0*W*(abs(getdata("field","Ex",1))^2*imag(getdata("index","index_x",1)^2));

Pabs_y =
Related a
-A
loss.
0.5*eps0*W*(abs(getdata("field","Ey",1))^2*imag(getdata("index","index_y",1)^2)); t
-
} else { Pabs = S/E12Im (incess 2
Pabs_x = matrix(Nx,Ny,Nz,Nf); initialize
Tower absorbed by the material
matrice due to the electric field
empty
>
-

.
component
Pabs_y = matrix(Nx,Ny,Nz,Nf); if no index data .

if (havedata("index","index_z")) {

Pabs_z = 0.5*eps0*W*(abs(getdata("field","Ez",1))^2*imag(getdata("index","index_z",1)^2));
> If
} else { powers calculation forzar's
same .
have data

Pabs_z = matrix(Nx,Ny,Nz,Nf); i
e

} Mater
# spatially interpolate absorption to standard mesh cell locations
&

Pabs_matrix = ( interp(Pabs_x,x+delta_x,y,z,f,x,y,z,f) + Interpolate the


data
power absorption
interp(Pabs_y,x,y+delta_y,z,f,x,y,z,f) +
to align with the mech
normalization
.

grid .
>
-

interp(Pabs_z,x,y,z+delta_z,f,x,y,z,f) ) / SP;

Pabs_x=0; Pabs_y=0; Pabs_z=0; W=0; SP=0; # Clear variables to free memory

# end absorption calculation

> absorbed powers per unit volume in (att/m3)


########################################################################
##

# Calculate generation rate

?"Starting generation rate (G) calculation";

# Calculate number of absorbed photon per unit volume



# assume this is equal to the number of generated electron/hole pairs
F
if (havedata("index","index_x")) {

gx = abs(getdata("field","Ex",1))^2 * imag(eps0*getdata("index","index_x",1)^2);

gy = abs(getdata("field","Ey",1))^2 * imag(eps0*getdata("index","index_y",1)^2);

} else { photon absorption


>
-
nate for each
gx = matrix(Nx,Ny,Nz,Nf); if
- >
Nata electric field

component using
gy = matrix(Nx,Ny,Nz,Nf);
same principle
} as Pabs .

if (havedata("index","index_z")) {

gz = abs(getdata("field","Ez",1))^2 * imag(eps0*getdata("index","index_z",1)^2);

} else {

gz = matrix(Nx,Ny,Nz,Nf);

# sum contribution from each component, multiply by required constants, and

# interpolate absorption to standard mesh cell locations and solar frequency vector

g = 0.5 * ( interp(gx,x+delta_x,y,z,f,x,y,z,f) +
number of absorbed photons per unit volume
interp(gy,x,y+delta_y,z,f,x,y,z,f) +
,

-
> normalized Planaks constant
by
.

interp(gz,x,y,z+delta_z,f,x,y,z,f) ) / hbar;
2
generationpaime ris
s

previous
gx=0; gy=0; gz=0; # clear variables, to free memory
generation enepationquency
# Calculate the generation rate by integrating 'g' over wavelength

# The generate rate is the number of electron hole pairs per unit volume per second. (units:
mu

1/m^3/s)

# For a CW or narrow band source with an %source intensity% (units: W/m^2)

lam_nm = c/f*1e9; # wavelength (1/nm)

vokanaya
normalize to the actual sources
to >
-

norma = %source intensity%/sourceintensity(f); # unitless


intensity
norma = meshgrid4d(4,x,y,z,norma);

S
if (Nf>1) {
>
-
normalizationwavdgt
G_matrix = integrate2(g*norma,4,lam_nm)/(lam_nm(Nf)-lam_nm(1)); # Average
a wavelengths &
use wavelengthpange
over .

} else {

G_matrix = g*norma; zen


,
freg
a sair
}

g=0;

# end generation rate calculation

##########################################################

# unfold data if symmetry BC's were used.

?"Unfolding";

if ( (length(getdata("field","x",1)) != length(getdata("field","x",2))) ) {

xTemp = x;

x = [-flip(x-x(1),1)+x(1); x(2:Nx)];

PabsTemp = Pabs_matrix;

Pabs_matrix = matrix(2*Nx-1,Ny,Nz,Nf);

GTemp = G_matrix;
G_matrix = matrix(2*Nx-1,Ny,Nz);

Pabs_matrix(1:(Nx-1),1:Ny,1:Nz,1:Nf) = PabsTemp(Nx:-1:2,1:Ny,1:Nz,1:Nf);

Pabs_matrix(Nx:(2*Nx-1),1:Ny,1:Nz,1:Nf) = PabsTemp;

G_matrix(1:(Nx-1),1:Ny,1:Nz) = GTemp(Nx:-1:2,1:Ny,1:Nz);

G_matrix(Nx:(2*Nx-1),1:Ny,1:Nz) = GTemp;

Nx = length(x);

if (length(getdata("field","y",1)) != length(getdata("field","y",2))) {

yTemp = y;

y = [-flip(y-y(1),1)+y(1); y(2:Ny)];

PabsTemp = Pabs_matrix;

Pabs_matrix = matrix(Nx,2*Ny-1,Nz,Nf);

GTemp = G_matrix;

G_matrix = matrix(Nx,2*Ny-1,Nz);

Pabs_matrix(1:Nx,1:(Ny-1),1:Nz,1:Nf) = PabsTemp(1:Nx,Ny:-1:2,1:Nz,1:Nf);

Pabs_matrix(1:Nx,Ny:(2*Ny-1),1:Nz,1:Nf) = PabsTemp;

G_matrix(1:Nx,1:(Ny-1),1:Nz) = GTemp(1:Nx,Ny:-1:2,1:Nz);

G_matrix(1:Nx,Ny:(2*Ny-1),1:Nz) = GTemp;

Ny = length(y);

PabsTemp=0; GTemp=0; # Clear memory

# end of unfolding

##########################################################
# Export data to DEVICE. Compress data in 3rd dimension, and Array the generation rate
'periods' time

# check inputs

dim = getdata("field","dimension");

if ((%average dimension% != "x") & (%average dimension% != "y")) { %average dimension%


= "none"; }

if ( periods < 1 ) { periods=1; }

if ( (dim==2) & (%average dimension% != "none") ) { message("Warning! Should not


average in 2D simulations."); }

# average data over 3rd dimension for export to DEVICE

if (%average dimension% == "x") {

G_temp = matrix(2,Ny,Nz);

G_temp(1,1:Ny,1:Nz) = integrate2(G_matrix,1,x)/(max(x)-min(x));

G_temp(2,1:Ny,1:Nz) = integrate2(G_matrix,1,x)/(max(x)-min(x));

x_export = [min(x), max(x)];

G_matrix_export = G_temp;

y_export = y;

z_export = z;

if (%average dimension% == "y") {

G_temp = matrix(Nx,2,Nz);

G_temp(1:Nx,1,1:Nz) = integrate2(G_matrix,2,y)/(max(y)-min(y));

G_temp(1:Nx,2,1:Nz) = integrate2(G_matrix,2,y)/(max(y)-min(y));

y_export = [min(y), max(y)];


G_matrix_export = G_temp;

x_export = x;

z_export = z;

if ((dim==3) & (%average dimension% == "none")) {

G_matrix_export = G_matrix;

x_export = x;

y_export = y;

z_export = z;

if ((dim==2) & (%average dimension% == "none")) {

G_matrix_export = matrix(Nx,Ny,2);

G_matrix_export(1:Nx,1:Ny,1) = G_matrix;

G_matrix_export(1:Nx,1:Ny,2) = G_matrix;

x_export = x;

y_export = y;

z_export = [-1e-6,1e-6];

Nz=2;

# array data to include multiple periods for export to DEVICE.

if ( (%average dimension% == "x") & (periods>1) ) {

temp = G_matrix_export;

for(i=1;i<periods;i=i+1){

G_matrix_export = [G_matrix_export, temp(1:length(x_export),2:Ny,1:Nz)];

y_export = [y_export; y(2:Ny)+max(y_export)-min(y_export)];

}
y_export = y_export - (max(y_export) + min(y_export))/2; # re-center at zero

if ( ((dim==3) | (%average dimension%=="y")) & (periods>1) ) { # for 3D, stretch in x direction


only

temp = G_matrix_export;

for(i=1;i<periods;i=i+1){

G_matrix_export = [G_matrix_export; temp(2:Nx,1:length(y_export),1:Nz)];

x_export = [x_export; x(2:Nx)+max(x_export)-min(x_export)];

x_export = x_export - (max(x_export) + min(x_export))/2; # re-center at zero

temp=0;

# Use proper variable name for export to DEVICE data file.

# create backup copy of original data

x_original=x;

y_original=y;

z_original=z;

G=G_matrix_export;

x=x_export;

y=y_export;

z=z_export;

if(length(%export filename%)>0){

?"save data file for DEVICE";

matlabsave(%export filename%,x,y,z,G);
}

# revert back to standard position vectors

x = x_original;

y = y_original;

z = z_original;

Nz=length(z);

##########################################################

# Calculate the short circuit current (Jsc)

normLengthX = max(x) - min(x);

paies/my electron
normLengthY = max(y) - min(y);
~ orn
Igen = e*integrate2(G_matrix,1:3,x,y,z); #A =

photon
if (dim==3) {

Jsc = Igen/(normLengthX*normLengthY); # A/m^2


apar
} else { my

Jsc = Igen/(normLengthX); # A/m^2

}
> in case
of 2D .

zenzwe
# end Jsc calculation calculatecan
-
exporteddata
# re-calculate Jsc for exported data, to confirm result is the same

normLengthX = max(x_export) - min(x_export);

normLengthY = max(y_export) - min(y_export);

normLengthZ = max(z_export) - min(z_export);

Igen_export = e*integrate2(G_matrix_export,1:3,x_export,y_export,z_export); # A
if (dim==3) {

Jsc_export = Igen_export/(normLengthX*normLengthY); # A/m^2

} else {

Jsc_export = Igen_export/(normLengthX*normLengthZ); # A/m^2

# create data sets

Pabs = rectilineardataset("Pabs",x,y,z);

Pabs.addparameter("lambda",c/f,"f",f);

Pabs.addattribute("Pabs",Pabs_matrix);

G = rectilineardataset("G",x,y,z);

G.addattribute("G",G_matrix);

G_export = rectilineardataset("G export",x_export,y_export,z_export);

G_export.addattribute("G",G_matrix_export);

Pabs_total = matrixdataset("Pabs total");

Pabs_total.addparameter("lambda",c/f,"f",f);

Pabs_total.addattribute("Pabs_total",integrate2(Pabs_matrix,1:3,x,y,z));

#Jsc_matrix=Jsc;

#Jsc = matrixdataset("Jsc");

#Jsc.addattribute("Jsc",Jsc_matrix);

Jsc=Jsc; # return as a simple matrix, rather than dataset


##########################################################

# create plots and output results to prompt

?"Current from simulation volume: " + num2str(Igen) + " A";

?"Short circuit current: " + num2str(Jsc) + " A/m^2 ("+num2str(Jsc/10)+" mA/cm^2)";

?"Exported data short circuit current: " + num2str(Jsc_export) + " A/m^2";

?"Max generation rate: " + num2str(max(G.G)) + " 1/m^3/s";

# plot results

if (%make plots%) {

pos = (max(y)+min(y))/2;

val = log10(pinch(G.G,2,find(y,pos)));

image(x*1e9,z*1e9,val,"x (nm)","z (nm)","G at y=" + num2str(round(pos*1e9)) + "nm");

val = pinch(pinch(Pabs.Pabs,4,Nf/2),2,find(y,pos));

image(x*1e9,z*1e9,val,"x (nm)","z (nm)","Pabs at y=" + num2str(round(pos*1e9)) + "nm,


lambda="+num2str(round(c/f(Nf/2)*1e9))+" nm");

pos = (max(x)+min(x))/2;

val = log10(pinch(G.G,1,find(x,pos)));

image(y*1e9,z*1e9,val,"y (nm)","z (nm)","G at x=" + num2str(round(pos*1e9)) + "nm");

val = pinch(pinch(Pabs.Pabs,4,Nf/2),1,find(x,pos));

image(y*1e9,z*1e9,val,"y (nm)","z (nm)","Pabs at x=" + num2str(round(pos*1e9)) + "nm,


lambda="+num2str(round(c/f(Nf/2)*1e9))+" nm");

pos = (max(z)+min(z))/2;
val = log10(pinch(G.G,3,find(z,pos)));

image(x*1e9,y*1e9,val,"x (nm)","y (nm)","G at z=" + num2str(round(pos*1e9)) + "nm");

val = pinch(pinch(Pabs.Pabs,4,Nf/2),3,find(z,pos));

image(x*1e9,y*1e9,val,"x (nm)","y (nm)","Pabs at z=" + num2str(round(pos*1e9)) + "nm,


lambda="+num2str(round(c/f(Nf/2)*1e9))+" nm");

plot(c/f*1e9,integrate2(Pabs.Pabs,1:3,x,y,z),"wavelength (nm)","absorbed power");

``

You might also like