This notebook demonstrates how to simulate the solar cells with detailed balance model.
In [1]:
%matplotlib inline
%load_ext autoreload
%autoreload 2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from pypvcell.solarcell import SQCell,MJCell,DBCell
from pypvcell.illumination import Illumination
from pypvcell.photocurrent import gen_step_qe
font = {'size' : 12}
matplotlib.rc('font', **font) # pass in the font dict as kwargs
In [2]:
input_ill=Illumination("AM1.5g")
Set up a GaAs (Eg=1.42eV) solar cell using SQCell
.
In [3]:
gaas_cell=SQCell(eg=1.42,cell_T=293,n_c=1,n_s=1)
Set up the desired illumination
In [4]:
gaas_cell.set_input_spectrum(input_ill)
Generate and draw the I-V characteristics
In [5]:
v,i=gaas_cell.get_iv()
In [6]:
plt.plot(v,i,'.-')
plt.xlabel("voltage (V)")
plt.ylabel("current (A/m^2)")
plt.ylim([-400,0])
Out[6]:
In [7]:
# set up an array of different band gaps
eg_array = np.linspace(0.5, 2.0)
eta_array_air_semi_class=[]
for eg in eg_array:
sq_cell = SQCell(eg=eg, cell_T=293, n_c=1, n_s=1)
sq_cell.set_input_spectrum(input_spectrum=input_ill)
eta_array_air_semi_class.append(sq_cell.get_eta())
plt.plot(eg_array, eta_array_air_semi_class, label="nc=1,ns=1 (class)")
plt.xlabel("band gap (eV)")
plt.ylabel("efficiency")
Out[7]:
In [8]:
def get_2j_eta(conc_ill):
top_eg=np.linspace(1.3,2.1,num=50) # Set up range of top cell band gaps
mid_eg=np.linspace(0.9,1.5,num=50)# Set up range of middle cell band gaps
eta=np.zeros((50,50)) # Initialize an array for storing efficiencies
ge_cell=SQCell(eg=0.67,cell_T=293)
for i,teg in enumerate(top_eg):
for j,beg in enumerate(mid_eg):
tc=SQCell(eg=teg,cell_T=293) # Set up top cell
bc=SQCell(eg=beg,cell_T=293) # Set up bottom cell
mj=MJCell([tc, bc]) # Make multijunction cell by "streaming" the 1J cells
mj.set_input_spectrum(conc_ill) # Set up the illumination
eta[i,j]=mj.get_eta() # Store the calculated efficiency in an array
return top_eg,mid_eg,eta
In [9]:
ill=Illumination("AM1.5g",concentration=1)
top_eg,mid_eg,eta=get_2j_eta(ill)
In [10]:
levels=np.unique(np.concatenate((np.arange(0.12,0.7,step=0.04),[0.42,0.44])))
cs=plt.contour(mid_eg,top_eg,eta,levels)
plt.clabel(cs,levels, fontsize=12, inline=1,fmt="%.2f")
plt.xlabel("middle cell band gap (eV)")
plt.ylabel("top cell band gap (eV)")
plt.tight_layout()
plt.savefig("2J_one_sun.pdf")
In [11]:
eta.shape
Out[11]:
In [12]:
print(np.max(eta))
nar=np.argmax(eta)
nar//eta.shape[0]
Out[12]:
In [13]:
print(top_eg[nar//eta.shape[1]])
print(mid_eg[np.mod(nar,eta.shape[1])])
In [14]:
def get_1j_eta_on_si(conc_ill):
top_eg=np.linspace(1.3,2.1,num=50) # Set up range of top cell band gaps
eta=np.zeros(50) # Initialize an array for storing efficiencies
for i,teg in enumerate(top_eg):
tc=SQCell(eg=teg,cell_T=293) # Set up top cell
bc=SQCell(eg=1.1,cell_T=293) # Set up bottom cell
mj=MJCell([tc, bc]) # Make multijunction cell by "streaming" the 1J cells
mj.set_input_spectrum(conc_ill) # Set up the illumination
eta[i]=mj.get_eta() # Store the calculated efficiency in an array
return top_eg,eta
In [15]:
ill=Illumination("AM1.5g",concentration=1)
top_eg,eta=get_1j_eta_on_si(ill)
In [16]:
plt.plot(top_eg,eta)
Out[16]:
In [17]:
nar=np.argmax(eta)
print(top_eg[nar])
print(eta[nar])
In [18]:
def get_3j_eta(conc_ill):
top_eg=np.linspace(1.3,2.1,num=10) # Set up range of top cell band gaps
mid_eg=np.linspace(0.9,1.5,num=50)# Set up range of middle cell band gaps
eta=np.zeros((10,50)) # Initialize an array for storing efficiencies
ge_cell=SQCell(eg=0.67,cell_T=293)
for i,teg in enumerate(top_eg):
for j,beg in enumerate(mid_eg):
tc=SQCell(eg=teg,cell_T=293) # Set up top cell
bc=SQCell(eg=beg,cell_T=293) # Set up bottom cell
mj=MJCell([tc, bc,ge_cell]) # Make multijunction cell by "streaming" the 1J cells
mj.set_input_spectrum(conc_ill) # Set up the illumination
eta[i,j]=mj.get_eta() # Store the calculated efficiency in an array
return top_eg,mid_eg,eta
In [19]:
ill=Illumination("AM1.5d",concentration=240)
top_eg,mid_eg,eta=get_3j_eta(ill)
In [20]:
levels=np.unique(np.concatenate((np.arange(0.12,0.7,step=0.04),[0.44,0.46,0.48,0.50,0.54,0.56])))
cs=plt.contour(mid_eg,top_eg,eta,levels)
plt.clabel(cs,levels, fontsize=12, inline=1,fmt="%.2f")
plt.xlabel("middle cell band gap (eV)")
plt.ylabel("top cell band gap (eV)")
plt.tight_layout()
plt.savefig("3J_2d_240suns.png",dpi=600)
In [21]:
tc=SQCell(eg=1.87,cell_T=293) # Set up top cell
bc=SQCell(eg=1.42,cell_T=293) # Set up bottom cell
ge_cell=SQCell(eg=0.67,cell_T=293)
mj=MJCell([tc, bc,ge_cell]) # Make multijunction cell by "streaming" the 1J cells
mj.set_input_spectrum(ill)
print(mj.get_eta())
In [22]:
# The AM1.5d spectrum has to be normalized to 1000 W/m^2
input_ill=Illumination("AM1.5d",concentration=1000/918)
sq_cell = SQCell(eg=1.13, cell_T=293, n_c=3.5, n_s=1)
sq_cell.set_input_spectrum(input_spectrum=input_ill)
sq_cell.get_eta()
Out[22]:
Condition: 1.84/1.16/0.69
In [23]:
ill=Illumination("AM1.5d",concentration=462000*1000/918)
mj=MJCell([SQCell(eg=1.84,cell_T=293,n_c=1,n_s=1),
SQCell(eg=1.16,cell_T=293,n_c=1,n_s=1),
SQCell(eg=0.69,cell_T=293,n_c=1,n_s=1)])
mj.set_input_spectrum(input_spectrum=ill)
mj.get_eta()
Out[23]:
The result does not seemt to match very well (against 67%).
In [24]:
input_ill=Illumination("AM1.5g",concentration=1)
top_eg=np.linspace(1.6,2,num=100) # Set up range of top cell band gaps
eta=np.zeros(100) # Initialize an array for storing efficiencies
jsc_ratio=np.zeros_like(eta)
si_cell=SQCell(eg=1.12,cell_T=293,n_c=3.5,n_s=1)
for i,teg in enumerate(top_eg):
#qe=gen_step_qe(teg,1)
#tc=DBCell(qe,rad_eta=1,T=293,n_c=3.5,n_s=1) # Set up top cell
tc=SQCell(teg,cell_T=293)
mj=MJCell([tc, si_cell]) # Make multijunction cell by "streaming" the 1J cells
mj.set_input_spectrum(input_ill) # Set up the illumination
eta[i]=mj.get_eta() # Store the calculated efficiency in an array
jsc_a=mj.get_subcell_jsc()
jsc_ratio[i]=jsc_a[0]/jsc_a[1]
#print(jsc_a)
In [25]:
plt.plot(top_eg,eta)
plt.xlabel("band gap of top cell (eV)")
plt.ylabel("efficiency")
plt.savefig("sj_on_si.pdf")
Optimal top cell band gap
In [26]:
top_eg[np.argmax(eta)]
Out[26]:
Maximum efficiency
In [27]:
np.max(eta)
Out[27]:
In [ ]: