# Source code for solcore.analytic_solar_cells.tunnel_junctions

```import numpy as np
from solcore.constants import kb, q

[docs]def resistive_tunnel_junction(junction, options):
""" Calculates the IV curve of a tunnel junction when it is modelled as a simple resistor. The minimum resistance of the junction is always 1e-16.

:param junction: A junction object.
:param options: Solver options.
:return: None.
"""

def iv(v):
return v / junction.R

def vi(j):
return j * junction.R

junction.voltage = options.internal_voltages
junction.current = iv(junction.voltage)
junction.iv = iv
junction.vi = vi

[docs]def parametric_tunnel_junction(junction, options):
""" Calculates the IV curve of a tunnel junction when it is modelled using a set of empirical parameters, such as peak curent and voltage, valley current and voltage, etc. The total current of the tunnel junction is summ of 3 components: the tunnel current, the excess current and the difussion current.

:param junction: A junction object.
:param options: Solver options.
:return: None.
"""

T = options.T
junction.voltage = options.internal_voltages

try:
# First we calculate the tunnel current
jp = junction.j_peak
vp = junction.v_peak

def tunnel_current(v):
return jp * v / vp * np.exp(1 - v / vp)

junction.tunnel_current = tunnel_current

# Now we calculate the excess current due to carrier tunnelling by way of states within the forbidden gap
jva = junction.j_valley
vv = junction.v_valley
pref = junction.prefactor

def excess_current(v):
return jva * np.exp(pref * (v - vv))

junction.excess_current = excess_current

# Finally we calculate the diffusion current
j01 = junction.j01

def diffusion_current(v):
return j01 * np.exp(q * v / kb / T)

junction.diffusion_current = diffusion_current
except AttributeError:
raise

# And we put everything together in an IV curve function
def iv(v):
return junction.tunnel_current(v) + junction.excess_current(v) + junction.diffusion_current(v)

junction.current = iv(junction.voltage)

# Also, we calculate the inverse, needed for the calculation of the IV curve in MJ solar cells
MJ_current = np.where(junction.voltage <= junction.v_peak, junction.current,
np.maximum(iv(junction.v_peak), junction.current))

# And the corresponding function doing that
if junction.pn:
def vi(j):
return np.interp(-j, MJ_current, -junction.voltage)
else:
def vi(j):
return np.interp(j, MJ_current, junction.voltage)

junction.iv = iv
junction.vi = vi

[docs]def external_tunnel_junction(junction, options):
""" Calculates the IV curve of a tunnel junction when it is modelled with external data. The external voltage and current must be defined with the input parameters external_voltage and external_current, respectively. It assumes that the interesting part of the curve is in the 1st quadrant (V>0 and I>0).

:param junction: A junction object.
:param options: Solver options.
:return: None.
"""

try:
# We put everything together in an IV curve function using the external data
def iv(v):
return np.interp(v, junction.external_voltage, junction.external_current)

except AttributeError:
raise

# Also, we calculate the inverse, needed for the calculation of the IV curve in MJ solar cells
MJ_current = np.zeros_like(junction.external_current)
MJ_current[0] = junction.external_current[0]
for i in range(len(junction.external_current) - 1):
MJ_current[i + 1] = max(MJ_current[i], junction.current[i + 1])

# And the corresponding function doing that
def vi(j):
return np.interp(j, MJ_current, junction.external_voltage)

junction.voltage = options.internal_voltages
junction.current = iv(junction.voltage)
junction.iv = iv
junction.vi = vi

[docs]def example_resistive_tunnel_junction(show=True):
from solcore.structure import TunnelJunction
from solcore.solar_cell_solver import default_options
import matplotlib.pyplot as plt

# Parametric tunnel example
my_tunnel = TunnelJunction(R=0.05)
resistive_tunnel_junction(my_tunnel, default_options)

if show:
v = my_tunnel.voltage

plt.plot(v, my_tunnel.current, 'k', linewidth=2, label='Total')

plt.legend(fontsize=12)
plt.ylim(0, 1.5)
plt.xlim(0, 1)
plt.ylabel('Current Density(A/\$m^2\$)', fontsize=12)
plt.xlabel('Voltage(V)', fontsize=12)
plt.tick_params(labelsize=12)
plt.tight_layout()
plt.show()

return my_tunnel

[docs]def example_parametric_tunnel_junction(show=True):
from solcore.structure import TunnelJunction
from solcore.solar_cell_solver import default_options
import matplotlib.pyplot as plt

# Parametric tunnel example
my_tunnel = TunnelJunction(v_peak=0.1, j_peak=1, v_valley=0.5, j_valley=0.1, prefactor=10, j01=1e-11)
parametric_tunnel_junction(my_tunnel, default_options)

if show:
v = my_tunnel.voltage

plt.plot(v, my_tunnel.tunnel_current(v), 'r--', label='Tunnel')
plt.plot(v, my_tunnel.excess_current(v), 'g--', label='Excess')
plt.plot(v, my_tunnel.diffusion_current(v), 'b--', label='Diffusion')
plt.plot(v, my_tunnel.current, 'k', linewidth=2, label='Total')

plt.legend(fontsize=12)
plt.ylim(0, 1.5)
plt.xlim(0, 1)
plt.ylabel('Current Density(A/\$m^2\$)', fontsize=12)
plt.xlabel('Voltage(V)', fontsize=12)
plt.tick_params(labelsize=12)
plt.tight_layout()
plt.show()

return my_tunnel

if __name__ == '__main__':
import matplotlib.pyplot as plt
from solcore.structure import TunnelJunction
from solcore.solar_cell_solver import default_options

# tunnel = example_parametric_tunnel_junction(False)
# example_resistive_tunnel_junction()

tunnel = TunnelJunction(v_peak=0.2, j_peak=7.5e4, v_valley=1, j_valley=40000, prefactor=5, j01=1e-23, kind='parametric')
parametric_tunnel_junction(tunnel, default_options)

v = tunnel.voltage

I = np.linspace(0, 105000, 100)

plt.plot(v, tunnel.tunnel_current(v), 'r--', label='Tunnel')
plt.plot(v, tunnel.excess_current(v), 'g--', label='Excess')
plt.plot(v, tunnel.diffusion_current(v), 'b--', label='Diffusion')
plt.plot(v, tunnel.current, 'k', linewidth=3, color='DimGray', label='Total')
# plt.plot(v, MJ_current, 'k-o', linewidth=2, label='MJ current')
# plt.plot(tunnel.vi(I), I, '--', color='grey', linewidth=2, label='MJ current')
plt.plot((0.2, 0.9), (100, 10), 'ko')

plt.annotate('V\$_P\$, J\$_P\$', xy=(0.2, 110), fontsize=12)
plt.annotate('V\$_V\$, J\$_V\$', xy=(0.6, 10), fontsize=12)

plt.legend(fontsize=12, frameon=False)
plt.ylim(0, 105000)
plt.xlim(0, 2)
plt.ylabel('Current Density(A/\$m^2\$)', fontsize=12)
plt.xlabel('Voltage(V)', fontsize=12)
plt.tick_params(labelsize=12)
plt.tight_layout()

plt.show()
```