def calc_conductance(energies,transmission,temperature=300*Kelvin,mu=0*eV):
    """
    Calculates the conductance for a given transmission.
    """
    energies = energies.inUnitsOf(eV)
    mu = mu.inUnitsOf(eV)
    beta = 1/(temperature*boltzmann_constant).inUnitsOf(eV)
    arg = (energies-mu)*beta
    arg = numpy.where(arg > 50.0, 50.0, arg)
    dFdE = beta*numpy.exp(arg)/(numpy.exp(arg) + 1)**2
    G = numpy.trapz(transmission*dFdE,energies)
    return G*2*elementary_charge**2/planck_constant

#*******************************************************************#
#                                                                   #
# USER DEFINED PARAMETERS                                           #
#                                                                   #
#*******************************************************************#
#------------------------                                           #
# DOPING                                                            #
#------------------------                                           #
# List of doping densities corresponding to the input file above    #
doping_densities = [1e14,1e15,1e16,1e17,1e18,1e19,1e20,1e21]        #
# Number of Si atoms in unit cell                                   #
nua0 = 48                                                           #
# Length of unit cell in z-direction                                #
Lz = 5.431*Angstrom                                                 #
# Volume of each atom in a bulk Si crystal                          #
atom_volume = 0.5*40.039*Angstrom**3                                #
#------------------------                                           #
# HDF5 FILES                                                        #
#------------------------                                           #
# Files with band structures for the doping levels in above list    #
doping_files = [                                                    #
    'sinw_doping_1e+14.hdf5',                                       #
    'sinw_doping_1e+15.hdf5',                                       #
    'sinw_doping_1e+16.hdf5',                                       #
    'sinw_doping_1e+17.hdf5',                                       #
    'sinw_doping_1e+18.hdf5',                                       #
    'sinw_doping_1e+19.hdf5',                                       #
    'sinw_doping_1e+20.hdf5',                                       #
    'sinw_doping_1e+21.hdf5',                                       #
    ]                                                               #
#------------------------                                           #
# DATA FILE TO LOAD                                                 #
#------------------------                                           #
# File for saving calculated data for later analysis                #
loadfile = 'sinw.pckl'                                              #
# PNG or PDF file with plot                                         #
pngfile = 'mobility.png'                                            #
#------------------------                                           #
# MOBILITY                                                          #
#------------------------                                           #
# Set a nanowire length of 1 micron                                 #
L = 10000*Angstrom                                                  #
# Set the temperature                                               #
temperature = 300*Kelvin                                            #
# Conduction band index                                             #
conduction_band_index = 113                                         #
#                                                                   #
#*******************************************************************#
#                                                                   #
# NO CHANGES NEEDED BELOW                                           #
#                                                                   #
#*******************************************************************#

#====================================================================
# Consistency check
#====================================================================
if not len(doping_densities) == len(doping_files):
    raise Error("The number of specified doping levels does not match the number of specified band structure files.")

#====================================================================
# Load previously saved data
#====================================================================
import pickle
f = open(loadfile, 'r')
(E,Ec0,T0,T_doped,Tave,Rc,Rave,Rs) = pickle.load(f)
f.close()

#====================================================================
# Calculate mobility and conductance vs doping concentration
#====================================================================
# Volume of one Si atom in units of cm^3
atom_volume_cm = atom_volume.inUnitsOf(Units.cm**3)
# Cross sectional Area
A = nua0*atom_volume/Lz
# Lists of mobilities and conductances
mobilities = []
mobilities_pristine = []
conductances = []
conductances_pristine = []
# Loop over doping densities
for doping_density,doping_file in zip(doping_densities,doping_files):
    # Load band structure for given doping density
    bandstructure = nlread(doping_file, Bandstructure)[-1]
    bands = bandstructure.evaluate().inUnitsOf(eV)
    # Fermi level relative to conduction band edge
    fermi_level = -bands[0,conduction_band_index]
    # Calculate conduction band electron density
    Ne = doping_density*atom_volume_cm*nua0
    # Charge density n = (charge in one unit cell)/(length of unit cell)
    n = Ne/Lz
    # Average distance between two dopant atoms
    dopant_distance = 1.0/(doping_density * atom_volume_cm * nua0)*Lz
    # Resistance (in units of h/(2e^2) ) of a wire with lenght L
    R_L = Rs*float(L/dopant_distance) + Rc
    # Transmision of wire with length L
    T = 1/(R_L)
    # Conductance of wire with length L
    conductance = calc_conductance(E*eV,T,temperature=temperature,mu=(Ec0+fermi_level)*eV)
    # Conductivity of wire with length L
    conductivity = conductance*L
    # Conductance of pristine wire
    conductance_pristine = calc_conductance(E*eV,T0,temperature=temperature,mu=(Ec0+fermi_level)*eV)
    # Conductivity of pristine wire with length L
    conductivity_pristine = conductance_pristine*L
    # Mobility mu = sigma/(e*n) of wire with length L with defects
    mobility = (conductivity/(1*elementary_charge*n)).inUnitsOf(Meter**2/(Volt*Second))*10**4
    # Mobility of pristine wire
    mobility_pristine = (conductivity_pristine/(1*elementary_charge*n)).inUnitsOf(Meter**2/(Volt*Second))*10**4
    # Save conductances and mobilities in lists
    mobilities.append(mobility)
    mobilities_pristine.append(mobility_pristine)
    conductances.append(conductance.inUnitsOf(G0))
    conductances_pristine.append(conductance_pristine.inUnitsOf(G0))

#====================================================================
# Plotting results
#====================================================================
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(6,7))
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212, sharex=ax1)
# Plot mobilities
ax1.plot(doping_densities,mobilities,'ro-',ms=8,label='Dopant scattering')
ax1.plot(doping_densities,mobilities_pristine,'ks-',ms=8,label='Pristine')
ax1.set_xscale('log')
ax1.set_yscale('log')
ax1.set_ylabel(r'Mobility ($cm^2/(Vs)$)')
ax1.set_xscale('log')
ax1.set_yscale('log')
ax1.legend(loc=3)
# Plot conductances
ax2.plot(doping_densities,conductances ,'ro-',ms=8,label='Dopant scattering')
ax2.plot(doping_densities,conductances_pristine,'ks-',ms=8,label='Pristine')
ax2.set_xlabel(r'Doping density ($cm^{-3}$)')
ax2.set_ylabel(r'Conductance ($2e^2/h$)')
ax2.set_yscale('log')
# Finalize figure
plt.tight_layout()
plt.savefig(pngfile)
plt.show()
