Ejemplo n.º 1
0
def getPolAbs(n, d, freq, theta):
    """
    Gets Polarized Absorption of optical elements

    Parameters
    ----------
    n : list
        Index of refraction for each element in the stack
    d : list
        Thickness for each element in the stack
    freq : float [Hz]
        Frequency
    theta:
        Incident angle
    """

    lam_vac = c / freq * 1000.

    s = tmm.coh_tmm('s', n, d, theta, lam_vac)
    p = tmm.coh_tmm('p', n, d, theta, lam_vac)

    sA = 1 - s['T'] - s['R']
    pA = 1 - p['T'] - p['R']

    return -((sA - pA) / 2)
Ejemplo n.º 2
0
    def spectrum(self, materials, thickness, theta=0, plot=False, title=False):
        '''
        Input:
            materials: list
            thickness: list
            theta: degree, the incidence angle

        Return:
            s: array, spectrum
        '''
        degree = pi / 180
        if self.substrate != 'Air':
            thickness.insert(-1, self.substrate_thick)  # substrate thickness

        R, T, A = [], [], []
        for i, lambda_vac in enumerate(self.wavelength * 1e3):

            # we assume the last layer is glass
            if self.substrate == 'Glass':
                n_list = [1] + [self.nk_dict[mat][i]
                                for mat in materials] + [1.45, 1]
            elif self.substrate == 'Air':
                n_list = [1] + [self.nk_dict[mat][i]
                                for mat in materials] + [1]
            else:
                n_list = [1] + [self.nk_dict[mat][i] for mat in materials
                                ] + [self.nk_dict[self.substrate][i], 1]

            # n_list = [1] + [self.nk_dict[mat][i] for mat in materials] + [self.nk_dict['Cr'][i]]

            # mport pdb; pdb.set_trace()
            res = coh_tmm('s', n_list, thickness, theta * degree, lambda_vac)
            if theta != 0:
                res_t = coh_tmm('p', n_list, thickness, theta * degree,
                                lambda_vac)
                res['R'] = (res['R'] + res_t['R']) / 2
                res['T'] = (res['T'] + res_t['T']) / 2
            R.append(res['R'])
            T.append(res['T'])

        R, T = np.array(R), np.array(T)
        A = 1 - R - T

        if plot:
            self.plot_spectrum(R, T, A)
            if title:
                thick = thickness[1:-1]
                title = ' | '.join(
                    ['{}nm {}'.format(d, m) for d, m in zip(thick, materials)])
                if self.substrate is not 'Air':
                    title = 'Air | ' + title + ' | {}nm {} '.format(
                        self.substrate_thick, self.substrate) + '| Air'
                else:
                    title = 'Air | ' + title + ' | Air'
                plt.title(title, **{'size': '10'})
            # plt.show()

        return R, T, A
Ejemplo n.º 3
0
def test_sample1():
    """
  Here's a thin non-absorbing layer, on top of a thick absorbing layer, with
  air on both sides. Plotting reflected intensity versus wavenumber, at two
  different incident angles.
  """

    # list of layer thicknesses in nm
    d_list = [inf, 100, 300, inf]
    # list of refractive indices
    n_list = [1, 2.2, 3.3 + 0.3j, 1]
    # list of wavenumbers to plot in nm^-1
    ks = linspace(0.0001, .01, num=400)
    # initialize lists of y-values to plot
    Rnorm = []
    R45 = []

    # coh_tmm(pol, n_list, d_list, th_0, lam_vac)

    for k in ks:
        # For normal incidence, s and p polarizations are identical.
        # I arbitrarily decided to use 's'.
        Rnorm.append(coh_tmm('s', n_list, d_list, 0, 1 / k)['R'])
        R45.append(unpolarized_RT(n_list, d_list, 45 * degree, 1 / k)['R'])
    kcm = ks * 1e7  #ks in cm^-1 rather than nm^-1
    plt.figure()
    plt.plot(kcm, Rnorm, 'blue', kcm, R45, 'purple')
    plt.xlabel('k (cm$^{-1}$)')
    plt.ylabel('Fraction reflected')
    plt.title('Reflection of unpolarized light at 0$^\circ$ incidence (blue), '
              '45$^\circ$ (purple)')
    plt.show()

    return 0
Ejemplo n.º 4
0
def calc_rt_pytmm(pol, omega, kx, n, d):
    """API-compatible wrapper around pytmm
    """
    vec_omega = omega.numpy()
    vec_lambda = C0 / vec_omega * 2 * np.pi

    vec_n = n.numpy()

    vec_d = d.numpy()
    vec_d = np.append(np.inf, vec_d)
    vec_d = np.append(vec_d, np.inf)

    vec_kx = kx.numpy().reshape([-1, 1])
    vec_k0 = 2 * np.pi / vec_lambda.reshape([1, -1])

    vec_theta = np.arcsin(vec_kx / vec_k0)

    r = np.zeros((len(kx), len(omega)), dtype=np.complex64)
    t = np.zeros((len(kx), len(omega)), dtype=np.complex64)

    for i, theta in enumerate(vec_theta):
        for j, lam in enumerate(vec_lambda):
            out = coh_tmm(pol, vec_n, vec_d, theta[j], lam)
            r[i, j] = out['r']
            t[i, j] = out['t']

    t = tf.constant(t)
    r = tf.constant(r)

    return tf.constant(t), tf.constant(r)
Ejemplo n.º 5
0
def FabryPerotTest():
    lam_vac = linspace(0.75, 1.7, 100)
    n_outside = 1
    n_inside = 3
    thickness = 1
    incidence_angle = 0
    reflectance, transmittance = FabryPerot(lam_vac, n_outside, n_inside,
                                            thickness, incidence_angle)

    # list of layer thicknesses in nm
    d_list = [inf, thickness, inf]
    # list of refractive indices
    n_list = [n_outside, n_inside, n_outside]

    Rnorm = []
    Tnorm = []
    for lam_vac_current in lam_vac:
        result = coh_tmm('s', n_list, d_list, 0, lam_vac_current)
        Rnorm.append(result['R'])
        Tnorm.append(result['T'])

    plt.figure()
    plt.plot(lam_vac, reflectance, 'red')
    plt.plot(lam_vac, transmittance, 'blue')
    plt.plot(lam_vac, Rnorm, 'ro')
    plt.plot(lam_vac, Tnorm, 'bo')
    plt.xlabel('$\lambda$ (nm)')
    plt.ylabel('reflectance, transmittance')
    plt.title(
        'reflectance (red), transmittance (blue) of unpolarized light at 0$^\circ$ incidence'
    )
    plt.show()
Ejemplo n.º 6
0
def Theory():
    th = tarwave / (4 * nh)
    tl = tarwave / (4 * nl)
    print('tarwave: {}, nh: {:.3f}, nl: {:.3f}'.format(tarwave, nh, nl))
    print('Th: {}, Tl: {}'.format(th, tl))

    n_list = [1, nh, nl, nh, nl, nh, nl, nh, 1]
    d_list = [np.inf, th, tl, th, tl, th, tl, th, np.inf]

    start = time.time()
    Rnorm = []
    for w in wavelength[0]:
        Rnorm.append(tmm.coh_tmm('s', n_list, d_list, 0, w)['R'])
    print("time: ", time.time() - start)

    Rnorm = np.reshape(Rnorm, newshape=(1, wavelength.shape[1]))
    fwhml, fwhmf = pixelDBR.calBand(Rnorm, wavelength, tarwave, minwave,
                                    wavestep, 0.5)
    b99l, b99f = pixelDBR.calBand(Rnorm, wavelength, tarwave, minwave,
                                  wavestep, 0.99)
    print("========        Result      ========")
    print('THeory fwhm: {} um, {:.3f} THz'.format(fwhml, fwhmf * 10**-12))
    print('THeory 99% width: {} um, {:.3f} THz'.format(b99l, b99f * 10**-12))

    plt.figure(1)
    x = np.reshape(wavelength, wavelength.shape[1])
    Rnorm = np.reshape(Rnorm, wavelength.shape[1])
    plt.plot(x, Rnorm)

    plt.figure(2)
    x = (c * (1. / wavelength))
    x = np.reshape(x, wavelength.shape[1])
    Rnorm = np.reshape(Rnorm, wavelength.shape[1])
    plt.plot(x, Rnorm)
    plt.show()
Ejemplo n.º 7
0
Archivo: color.py Proyecto: lulzzz/tmm
def calc_reflectances(n_fn_list, d_list, th_0, pol='s', spectral_range='narrow'):
    """
    Calculate the reflection spectrum of a thin-film stack.
    
    n_fn_list[m] should be a function that inputs wavelength in nm and
    outputs refractive index of the m'th layer. In other words,
    n_fn_list[2](456) == 1.53 + 0.4j mans that layer #2 has a refractive index
    of 1.53 + 0.4j at 456nm. These functions could be defined with
    scipy.interpolate.interp1d() for example.
    
    pol, d_list and th_0 are defined as in tmm.coh_tmm ... but d_list
    MUST be in units of nanometers
    
    spectral_range can be 'full' if all the functions in n_fn_list can take
    wavelength arguments between 360-830nm; or 'narrow' if some or all require
    arguments only in the range 400-700nm. The wavelengths outside the
    'narrow' range make only a tiny difference to the color, because they are
    almost invisible to the eye. If spectral_range is 'narrow', then the n(400)
    values are used for 360-400 and n(700) for 700-830nm
    
    Returns a 2-column array where the first column is wavelength in nm
    (360,361,362,...,830) and the second column is reflectivity (from 0
    to 1, where 1 is a perfect mirror). This range is chosen to be
    consistent with colorpy.illuminants. See  colorpy.ciexyz.start_wl_nm etc.
    """
    
    lam_vac_list = arange(360, 831)
    
    num_layers = len(n_fn_list)
    
    def extend_spectral_range(n_fn):
        """
        Starting with a narrow-spectrum refractive index function
        n_fn(wavelength), create then return the corresponding full-spectrum
        refractive index function
        """
        def extended_n_fn(lam):
            if lam < 400:
                return n_fn(400)
            elif lam > 700:
                return n_fn(700)
            else:
                return n_fn(lam)
        return extended_n_fn
    
    if spectral_range == 'narrow':
        n_fn_list = [extend_spectral_range(n_fn) for n_fn in n_fn_list]
    
    final_answer = []
    
    for lam_vac in lam_vac_list:
        n_list = [n_fn_list[i](lam_vac) for i in range(num_layers)]
        R = tmm.coh_tmm(pol, n_list, d_list, th_0, lam_vac)['R']
        final_answer.append([lam_vac,R])
    final_answer = array(final_answer)

    return final_answer
Ejemplo n.º 8
0
def R(stack):
    R_list = []
    for lambda_vac in LAMBDAS:
        n_list = [1]
        for layer in range(0,stack.num):
            n1 =  round(get_r_index.get_cplx(stack.period.lay1.material, lambda_vac),4)
            n_list.append(n1)
            n2 = round(get_r_index.get_cplx(stack.period.lay2.material, lambda_vac),4)
            n_list.append(n2)
        n_list.append(round(get_r_index.get_cplx('c-Si', lambda_vac), 4))
        R_list.append(tmm.coh_tmm('s', n_list, make_d_list(stack), ANGLE, lambda_vac)['R'])
    return R_list 
Ejemplo n.º 9
0
def calR(s, dx, N_pixel, wavelength, nh, nl):
    # list of layer thickness in nm
    d_list = [np.inf] + [dx for i in range(N_pixel)] + [np.inf]
    # list of refractive
    nht = nh * (s == 1).astype(int)
    nlt = nl * (s == 0).astype(int)
    nt = nht + nlt
    n_list = [1] + nt.tolist() + [1]
    # initialize lists of y-values
    Rnorm = []
    for w in wavelength[0]:
        Rnorm.append(tmm.coh_tmm('s', n_list, d_list, 0, w)['R'])

    return Rnorm
Ejemplo n.º 10
0
def getIP(n, d, freq, theta):
    """
    Gets IP of optical elements

    Parameters
    ----------
    n : list
        Index of refraction for each element in the stack
    d : list
        Thickness for each element in the stack
    freq : float [Hz]
        Frequency
    theta:
        Incident angle
    """
    lam_vac = c / freq * 1000.

    #    lam_vac = 2.0

    s = tmm.coh_tmm('s', n, d, theta, lam_vac)
    p = tmm.coh_tmm('p', n, d, theta, lam_vac)

    return -(s['T'] - p['T']) / 2
Ejemplo n.º 11
0
def calculate_absorption_profile(structure,
                                 wavelength,
                                 z_limit=None,
                                 steps_size=2,
                                 dist=None,
                                 no_back_reflexion=True):
    """ It calculates the absorbed energy density within the material. From the documentation:

    'In principle this has units of [power]/[volume], but we can express it as a multiple of incoming light power
    density on the material, which has units [power]/[area], so that absorbed energy density has units of 1/[length].'

    Integrating this absorption profile in the whole stack gives the same result that the absorption obtained with
    calculate_rat as long as the spacial mesh (controlled by steps_thinest_layer) is fine enough. If the structure is
    very thick and the mesh not thin enough, the calculation might diverege at short wavelengths.

    For now, it only works for normal incident, coherent light.

    :param structure: A solcore structure with layers and materials.
    :param wavelength: Wavelengths in which calculate the data (in nm). An array-like object.
    :param z_limit: Maximum value in the z direction
    :return: A dictionary containing the positions (in nm) and a 2D array with the absorption in the structure as a
    function of the position and the wavelength.
    """

    num_wl = len(wavelength)

    if 'OptiStack' in str(type(structure)):
        stack = structure
        stack.no_back_reflexion = no_back_reflexion
    else:
        stack = OptiStack(structure, no_back_reflexion=no_back_reflexion)

    if dist is None:
        if z_limit is None:
            z_limit = np.sum(np.array(stack.widths))
        dist = np.arange(0, z_limit, steps_size)

    output = {'position': dist, 'absorption': np.zeros((num_wl, len(dist)))}

    for i, wl in enumerate(wavelength):
        out = tmm.coh_tmm('p', stack.get_indices(wl), stack.get_widths(), 0,
                          wl)
        for j, d in enumerate(dist):
            layer, d_in_layer = tmm.find_in_structure_with_inf(
                stack.get_widths(), d)
            data = tmm.position_resolved(layer, d_in_layer, out)
            output['absorption'][i, j] = data['absor']

    return output
Ejemplo n.º 12
0
def cal_pop_fitness(coating_complex_functions, substrate_complex_function, new_population, min, max, type):

    fitness = np.ones(new_population.shape[0])*(-99999999999)
    for i in range(new_population.shape[0]):
        lamda_size = (max-min)//10+1
        lamdas = np.linspace(min, max, num = lamda_size)
        # print('wavelength ranges is', lamdas)
        reflections = []
        for wa in lamdas:
            refractive_element = [1]
            for k in range(len(coating_complex_functions)):
                refractive_element.append(coating_complex_functions[k](wa))
            refractive_element.append(substrate_complex_function(wa))
            reflections.append(tmm.coh_tmm('s', refractive_element, new_population[i].tolist(), 0, wa)['R'])
        if type == 'Antireflection':
            fitness[i] = 1-np.average(reflections)
        if type == 'Highreflection':
            fitness[i] = np.average(reflections)
    return fitness
Ejemplo n.º 13
0
Archivo: tmm.py Proyecto: DuraMAT/pvarc
def thick_slab_reflectance_tmm(polarization, index_substrate, aoi, wavelength):
    """
    Reflection from a thick slab of material.

    Parameters
    ----------
    polarization : str

        Light polarization, can be "s" or "p" or "mixed"

    index_substrate : (N,) ndarray

        Index of refraction of the slab of material evaluated at the
        wavelengths specified in the `wavelength` input.

    aoi : float

        Angle of incidence in degrees

    wavelength : (N,) ndarray

        wavelength in nm, must be the same length as index_substrate.

    Returns
    -------

    """
    wavelength = wavelength.astype('float')
    degree = pi / 180
    R = np.zeros_like(wavelength)
    if polarization in ['s', 'p']:
        for j in range(len(R)):
            R[j] = coh_tmm(polarization, [1.0003, index_substrate[j]],
                           [inf, inf], aoi * degree, wavelength[j])['R']
    elif polarization == 'mixed':
        for j in range(len(R)):
            R[j] = unpolarized_RT([1.0003, index_substrate[j]], [inf, inf],
                                  aoi * degree, wavelength[j])['R']
    else:
        raise Exception("polarization must be 's','p' or 'mixed'")
    return R
Ejemplo n.º 14
0
def main():
    while True:
        try:
            num = int(input('Number of periods: '))
            d = int(input('Thickness of one period (nm): '))
            layer1 = int(
                input('Thickness of the first layer in a period (nm): '))
            mode = input('Transmission (t) or Ellipsometry (e)? ')
            break
        except:
            print('Thats not a valid option!')

    aperiod = period(d, layer1)

    # Setting up the list with thicknesses
    d_list = [inf]  # starts with air at infinity
    for periods in range(0, num):
        d_list.append(aperiod.get_layer1())
        if aperiod.get_layer2() != 0:
            d_list.append(aperiod.get_layer2())
    d_list.append(inf)  # end with wafer(?) at infinity

    # # Starting the calculations:
    if mode == 't':
        T_list = []
        for lambda_vac in lambda_list:
            # Setting up the list with indices of refraction
            n_list = [1]  # starts with air
            for periods in range(0, num):
                n_list.append(get_r_index.get_cplx('ITO', lambda_vac))
                if aperiod.get_layer2() not 0:
                    n_list.append(get_r_index.get_cplx('Al', lambda_vac))
                n_list.append(3.49 + 0)  # Si (wafer)
            T_list.append(
                tmm.coh_tmm('s', n_list, d_list, 70 * degree, lambda_vac)['T'])
        plt.figure()
        plt.xlabel('Wavelength (nm)')
        plt.ylabel('Fraction of power Transmitted')
        plt.plot(lambda_list, T_list)
Ejemplo n.º 15
0
def calR(s, Nslice, wavelength, nh, nl, high: bool):
    # list of layer thickness in nm
    d_list = [np.inf] + s.tolist() + [np.inf]
    # list of refractive indices
    nt = np.empty(s.shape)
    for i in range(Nslice):
        if high:  # high index material start
            if (i % 2) == 1:
                nt[i] = nl
            else:
                nt[i] = nh
        else:  # low index material start
            if (i % 2) == 1:
                nt[i] = nh
            else:
                nt[i] = nl
    n_list = [1] + nt.tolist() + [1]
    # initialize lists of y-values
    Rnorm = []
    for w in wavelength[0]:
        Rnorm.append(tmm.coh_tmm('s', n_list, d_list, 0, w)['R'])

    return Rnorm
Ejemplo n.º 16
0
 def r_fn_coh(d):
     coh_res = coh_tmm('s', [n_air, n_glass, n_air],
                       [np.inf, d, np.inf], 0, wavelength)
     return coh_res['r']
Ejemplo n.º 17
0
def calculateoptimaldesign(request, id):
    design_condition = {}
    coat_mat = []
    coat_mat_id = []
    working_min = list(
        OptimalFilmDesign.objects.filter(id=id).values_list("wave_min",
                                                            flat=True))
    working_max = list(
        OptimalFilmDesign.objects.filter(id=id).values_list("wave_max",
                                                            flat=True))
    plot_min = [working_min[0] - 100]
    plot_max = [working_max[0] + 100]

    for i in range(1, 5):
        mat = list(
            OptimalFilmDesign.objects.filter(id=id).values_list("material_%d" %
                                                                (i),
                                                                flat=True))[0]
        search = Pages.objects.filter(book=mat,
                                      hasrefractive=1,
                                      hasextinction=1,
                                      rangeMax__gte=working_max[0] / 1000,
                                      rangeMin__lte=working_min[0] /
                                      1000).values_list("pageid", flat=True)
        if search.exists():
            mat_id = search
        else:
            mat_id = Pages.objects.filter(book=mat,
                                          hasrefractive=1,
                                          rangeMax__gte=working_max[0] / 1000,
                                          rangeMin__lte=working_min[0] /
                                          1000).values_list("pageid",
                                                            flat=True)
        if mat_id.exists():
            coat_mat_id.append(list(mat_id)[0])
        coat_mat_id = list(set(coat_mat_id))

    for m in range(len(coat_mat_id)):
        new = OpticalMaterial(coat_mat_id[m])
        new.get_refractives()
        coat_mat.append(new)
        working_min.append(new.minwave)
        working_max.append(new.maxwave)
        plot_min.append(new.minwave)
        plot_max.append(new.maxwave)

    sub_mat_name = list(
        OptimalFilmDesign.objects.filter(id=id).values_list(
            "material_substrate", flat=True))[0]
    search_sub = Pages.objects.filter(book=sub_mat_name,
                                      hasrefractive=1,
                                      hasextinction=1).values_list("pageid",
                                                                   flat=True)
    if search_sub.exists():
        substrate_mat_id = list(search_sub)[0]
    else:
        substrate_mat_id = list(
            Pages.objects.filter(book=sub_mat,
                                 hasrefractive=1).values_list("pageid",
                                                              flat=True))[0]

    substrate = OpticalMaterial(substrate_mat_id)
    substrate.get_refractives()
    working_min.append(substrate.minwave)
    working_max.append(substrate.maxwave)
    plot_min.append(substrate.minwave)
    plot_max.append(substrate.maxwave)
    design_condition['substrate'] = substrate
    design_condition['coat_material'] = coat_mat
    design_condition['minrange'] = max(working_min)
    design_condition['maxrange'] = min(working_max)
    design_condition['maxthickness'] = list(
        OptimalFilmDesign.objects.filter(id=id).values_list("max_thickness",
                                                            flat=True))[0]
    design_condition['goal'] = list(
        OptimalFilmDesign.objects.filter(id=id).values_list("filmtype",
                                                            flat=True))[0]

    best_design = optimizedesign(design_condition['substrate'],
                                 design_condition['coat_material'],
                                 design_condition['minrange'],
                                 design_condition['maxrange'],
                                 design_condition['maxthickness'],
                                 design_condition['goal'])

    if best_design != None:
        best_coatings = best_design[0]
        best_ds = best_design[1][0][0]
        best_reflection = best_design[2][0]
        plot_min = max(plot_min)
        plot_max = min(plot_max)
        lamdas = list(np.linspace(plot_min, plot_max, num=100))
        coating_complex_functions = []
        best_coatings_names = []
        for i in range(len(best_coatings)):
            function = best_coatings[i].get_complex_function()
            coating_complex_functions.append(function)
            best_coatings_names.append(best_coatings[i].name)
        substrate_complex_function = substrate.get_complex_function()

        plot_reflection = []
        plot_transmission = []
        for wa in lamdas:
            refractive_element = [1]
            for k in range(len(coating_complex_functions)):
                # print(coating_refractive_functions[i](medium_wavelength))
                refractive_element.append(coating_complex_functions[k](wa))
            refractive_element.append(substrate_complex_function(wa))

            # print(refractive_element)
            plot_reflection.append(
                tmm.coh_tmm('s', refractive_element, best_ds.tolist(), 0,
                            wa)['R'])
            plot_transmission.append(
                tmm.coh_tmm('s', refractive_element, best_ds.tolist(), 0,
                            wa)['T'])
        coating_thickness_lib = []
        for ele in range(len(best_coatings_names)):
            element = {}
            element['order'] = ele + 1
            element['name'] = best_coatings_names[ele]
            element['thickness'] = best_ds[ele + 1]
            coating_thickness_lib.append(element)

    else:
        best_coatings = None
        best_ds = None
        best_reflection = None
        best_coatings_names = None
        lamdas = None
        plot_reflection = None
        plot_transmission = None
        coating_thickness_lib = []

    coating_materials = Pages.objects.filter(pageid__in=coat_mat_id)
    substrate_material = Pages.objects.filter(pageid=substrate_mat_id)

    context = {
        'coat_mat': coating_materials,
        'substrate_mat': substrate_material,
        'design_condition': design_condition,
        'plot_wave': lamdas,
        'plot_reflection': plot_reflection,
        'plot_transmission': plot_transmission,
        'best_coating_name': best_coatings_names,
        'best_design_thickness': best_ds,
        'best_design_coatings': coating_thickness_lib,
        'best_reflectance': best_reflection,
    }
    return render(request, 'optical_parameter/calculateoptimalfilm.html',
                  context)
Ejemplo n.º 18
0
def design(request):
    incident_angle = request.GET.get("Incident_angle")
    incident_angle_radians = 0
    if incident_angle != None:
        incident_angle_radians = math.radians(float(incident_angle))
    if incident_angle == None:
        incident_angle = 0
    lamda_poynting = request.GET.get("lamda_poynting")
    if lamda_poynting == None:
        lamda_poynting = 400
    if request.user.is_authenticated:
        design = Film.objects.filter(optical_designer_id=request.user.id)
    else:
        design = Film.objects.filter(optical_designer_id=1)
    mat_type = list(design.values_list("type", flat=True))
    mat_mat = list(design.values_list("material", flat=True))
    mat_thick = [np.inf]
    mat_thickness = list(design.values_list("thickness", flat=True))
    mat_thick = mat_thick + mat_thickness + [np.inf]
    mat_layer = list(design.values_list("layer_sequence", flat=True))
    working_min = []
    working_max = []
    object = []
    refractives = []
    refrac_fns = []
    miss_ex_mats = []
    for i in range(0, len(mat_type)):
        results = Pages.objects.filter(book=str(mat_mat[i]),
                                       hasrefractive=1,
                                       hasextinction=1).values_list("pageid",
                                                                    flat=True)
        if results.exists():
            objects = results
        else:
            objects = Pages.objects.filter(book=str(mat_mat[i]),
                                           hasrefractive=1).values_list(
                                               "pageid", flat=True)
        if objects.exists():
            object.append(objects[0])
            mat_refractiveindex = Refractiveindex.objects.filter(
                pageid_id=objects[0])
            mat_excoeff = Extcoeff.objects.filter(pageid_id=objects[0])
            wave_r = list(mat_refractiveindex.values_list("wave", flat=True))
            wave_re = [i * 1000 for i in wave_r]
            n_re = list(mat_refractiveindex.values_list("refindex", flat=True))
            wave_e = list(mat_excoeff.values_list("wave", flat=True))
            wave_ex = [i * 1000 for i in wave_e]
            k_ex = [0.000000001] * len(wave_re)
            if mat_excoeff.exists():
                k_ex = list(mat_excoeff.values_list("coeff", flat=True))
            else:
                miss_ex_mats.append(
                    list(
                        Pages.objects.filter(pageid=objects[0]).values_list(
                            "book", flat=True))[0])
            refrac_element = []
            for wa in range(0, len(wave_re)):
                refrac_element.append(
                    [wave_re[wa], complex(n_re[wa], k_ex[wa])])
                # print(refrac_element)
            refrac_array = np.array(refrac_element)
            refractives.append(refrac_array)
            n_fn = interpolate.interp1d(refrac_array[:, 0].real,
                                        refrac_array[:, 1],
                                        kind='quadratic')
            refrac_fns.append(n_fn)
            working_min.append(min(refrac_array[:, 0].real))
            working_max.append(max(refrac_array[:, 0].real))
    working_range = [0, 0]
    if len(working_max) > 0:
        working_range = [max(working_min), min(working_max)]
    lamdas = list(np.linspace(working_range[0], working_range[1], 100))
    Rnorm = []
    Tnorm = []
    d_list = mat_thick
    for lamda in lamdas:
        # For normal incidence, s and p polarizations are identical.
        # I arbitrarily decided to use 's'.
        n_list = [1]
        for lay in range(0, len(mat_type)):
            n_list.append(refrac_fns[lay](lamda))
        n_list.append(1)
        Rnorm.append(
            tmm.coh_tmm('s', n_list, d_list, incident_angle_radians,
                        lamda)['R'])
        Tnorm.append(
            tmm.coh_tmm('s', n_list, d_list, incident_angle_radians,
                        lamda)['T'])

    coh_tmm_data_s = tmm.coh_tmm('s', n_list, d_list, incident_angle_radians,
                                 lamda_poynting)
    coh_tmm_data_p = tmm.coh_tmm('p', n_list, d_list, incident_angle_radians,
                                 lamda_poynting)
    ds = np.linspace(0, sum(d_list[1:-1]), num=100)
    poyn = []
    absor = []
    for d in ds:
        layer, d_in_layer = tmm.find_in_structure_with_inf(d_list, d)
        data = tmm.position_resolved(layer, d_in_layer, coh_tmm_data_s)
        poyn.append(data['poyn'])
        absor.append(data['absor'])
    ds = list(ds)
    context = {
        'Design': design,
        'Wavelength': lamdas,
        'Reflectance': Rnorm,
        'Transmitance': Tnorm,
        'Working_range': working_range,
        'Angle': incident_angle,
        'Absorption': absor,
        'Ponyting': poyn,
        'Depth': ds,
        'Miss_ex_mat': miss_ex_mats,
    }
    return render(request, 'optical_parameter/design.html', context)
Ejemplo n.º 19
0
def getCoeffs(n, d, freq, theta, pol):
    """Returns T, R, A coefficients for an optical stack of polarization pol ('s' or 'p')"""
    lam_vac = c / freq * 1000  #vacuum wavelength in mm
    s = tmm.coh_tmm(pol, n, d, theta, lam_vac)
    return [s['T'], s['R'], 1 - s['T'] - s['R']]
Ejemplo n.º 20
0
import numpy as np
import matplotlib.pyplot as plt
import tmm

degree = np.pi/180

# list of layer thicknesses in nm
d_list = [tmm.inf, 5, tmm.inf]
# list of refractive indices
n_list = [1, 2.68, 1]
nabs_list = [1 ,2.68+0.01j, 1]
# list of wavenumbers to plot in nm^-1
lams = np.linspace(1, 1.25, num=400)
# initialize lists of y-values to plot
Rnorm = []
Rabs = []
for lam in lams:
    # For normal incidence, s and p polarizations are identical.
    # I arbitrarily decided to use 's'.
    Rnorm.append(tmm.coh_tmm('s', n_list, d_list, 0, lam)['R'])
    #R45.append(tmm.unpolarized_RT(n_list, d_list, 45*degree, lam)['R'])
    Rabs.append(tmm.coh_tmm('s', nabs_list, d_list, 0, lam)['R'])

plt.figure()
plt.plot(lams, Rnorm, 'blue', lams, Rabs, 'purple')
plt.xlabel('$\lambda$ ($\mu$m)')
plt.ylabel('Fraction reflected')
plt.title('Modest page 56')
plt.show()

Ejemplo n.º 21
0
Archivo: tmm.py Proyecto: DuraMAT/pvarc
def thin_film_reflectance_tmm(polarization,
                              index_film,
                              index_substrate,
                              film_thickness,
                              aoi,
                              wavelength,
                              vectorize=False):
    """
    Calculate reflection from a thin film on a substrate. dimensions in nm.


    Parameters
    ----------
    polarization
    index_film
    index_substrate
    film_thickness
    aoi
    wavelength
    vectorize

    Returns
    -------

    """
    degree = pi / 180
    wavelength = wavelength.astype('float')

    d_list = [np.inf, film_thickness, np.inf]

    index_air = 1.0003

    R = np.zeros_like(wavelength)
    if polarization in ['s', 'p']:
        for j in range(len(R)):
            n_list = [1.0003, index_film[j], index_substrate[j]]
            R[j] = coh_tmm(polarization, n_list, d_list, aoi * degree,
                           wavelength[j])['R']
    elif polarization == 'mixed':

        if vectorize:

            def unpolarized_RT_func(
                index_film,
                index_substrate,
                aoi,
                film_thickness,
                wavelength,
            ):
                return unpolarized_RT(
                    n_list=[index_air, index_film, index_substrate],
                    d_list=[np.inf, film_thickness, np.inf],
                    th_0=aoi * degree,
                    lam_vac=wavelength)['R']

            unpolarized_RT_vectorized = np.vectorize(unpolarized_RT_func)
            R = unpolarized_RT_vectorized(index_film, index_substrate, aoi,
                                          film_thickness, wavelength)
            print('vectorized done')
        else:

            for j in range(len(R)):
                n_list = [index_air, index_film[j], index_substrate[j]]
                R[j] = unpolarized_RT(n_list, d_list, aoi * degree,
                                      wavelength[j])['R']

    else:
        raise Exception("polarization must be 's','p' or 'mixed'")
    return R
Ejemplo n.º 22
0
def solar_results(activeLayer, AL_thickness,theta,atWL,calc_Efield,calc_Jsc,calc_Jsc_loss,calc_Q): #JB

	# list of layer thicknesses in nm
	d_list[activeLayer]=AL_thickness # JB
	angle=theta
	th0=angle*np.pi/180
	checkwavelength=atWL
	stepsize=1

	# allocate lists of y-values to plot
	R_a_s=[]
	R_a_p=[]
	T_a_s=[]
	T_a_p=[]
	A_a_s=[]
	A_a_p=[]
	E_s=[]
	E_p=[]
	E_xyz_tot=[]
	PA_s=[]
	PA_p=[]
	Gxl=[]
	Gxl_tot=[]
	Gxl_refl=[]
	Gxl_parasitic=[]

	for i,wl in enumerate(wavelengths):
		n_list=n_k[:,i]

		#calculate all data coherent (returns more values) and incoherent
		coh_tmm_data_s = tmm.coh_tmm('s',n_list, d_list, angle*np.pi/180, wl)
		coh_tmm_data_p = tmm.coh_tmm('p',n_list, d_list, angle*np.pi/180, wl)
		incoh_tmm_data_s = tmm.inc_tmm('s',n_list, d_list, c_list, angle*np.pi/180, wl)
		incoh_tmm_data_p = tmm.inc_tmm('p',n_list, d_list, c_list, angle*np.pi/180, wl)

		#use for R,T,A
		R_a_s.append(incoh_tmm_data_s['R'])
		R_a_p.append(incoh_tmm_data_p['R'])
		T_a_s.append(incoh_tmm_data_s['T'])
		T_a_p.append(incoh_tmm_data_p['T'])
		A_a_s.append(tmm.inc_absorp_in_each_layer(incoh_tmm_data_s))
		A_a_p.append(tmm.inc_absorp_in_each_layer(incoh_tmm_data_p))

		E_s.append([])
		E_p.append([])
		E_xyz_tot.append([])
		PA_s.append([])
		PA_p.append([])
		Gxl.append([])
		Gxl_tot.append([])
		Gxl_refl.append([])
		Gxl_parasitic.append([])

		#E-field for every layer different
		if calc_Efield==1:
			x_pos_abs=0
			t=[]
			for j in range(stackBegin,len(d_list)-1):
				if j==1:
					vw_s = incoh_tmm_data_s['VW_list'][j]
					kz_s = coh_tmm_data_s['kz_list'][j]
					vw_p = incoh_tmm_data_p['VW_list'][j]
					kz_p = coh_tmm_data_p['kz_list'][j]
				else:
					vw_s = coh_tmm_data_s['vw_list'][j]
					kz_s = coh_tmm_data_s['kz_list'][j]
					th_s = coh_tmm_data_s['th_list'][j]
					vw_p = coh_tmm_data_p['vw_list'][j]
					kz_p = coh_tmm_data_p['kz_list'][j]
					th_p = coh_tmm_data_p['th_list'][j]

				alpha=4*np.pi*np.imag(n_k[j,i])/wl


				#at every point x
				x_pos_rel=0
				for x in range(x_pos_abs,x_pos_abs+d_list[j]+1):
					t.append(x)

					E_plus_s=vw_s[0] * np.exp(1j * kz_s * x_pos_rel)
					E_minus_s=vw_s[1] * np.exp(-1j * kz_s * x_pos_rel)
					E_plus_p=vw_p[0] * np.exp(1j * kz_p * x_pos_rel)
					E_minus_p=vw_p[1] * np.exp(-1j * kz_p * x_pos_rel)

					E_pos_s=E_plus_s + E_minus_s
					E_pos_p=E_plus_p + E_minus_p

					E_s[i].append(E_pos_s)
					E_p[i].append(E_pos_p)

					E_z_pos=E_pos_s/np.sqrt(np.cos(th0))
					E_y_pos=E_pos_p*np.cos(th_p)/np.sqrt(np.cos(th0))
					E_x_pos=((-1)*E_plus_p + E_minus_p)*n_list[0]*np.sin(th0)/(n_list[j]*np.sqrt(np.cos(th0)))

					E_xyz_pos=0.5*np.square(np.absolute(E_z_pos))+0.5*(np.square(np.absolute(E_y_pos))+np.square(np.absolute(E_x_pos)))
					E_xyz_tot[i].append(E_xyz_pos)

					Q_pos_xyz=alpha*np.real(n_k[j,i])*power[i]*E_xyz_pos

					#calculate Energy dissipation and exciton generation rate
					if j==activeLayer:
						Gxl[i].append(Q_pos_xyz*1e-3*wl*1e-9/(h*c));
						Gxl_tot[i].append(Q_pos_xyz*1e-3*wl*1e-9/(h*c));

					else:
						Q_pos_xyz=alpha*np.real(n_k[j,i])*power[i]*(0.5*np.square(np.absolute(E_z_pos))+0.5*(np.square(np.absolute(E_y_pos))+np.square(np.absolute(E_x_pos))))
						Gxl_parasitic[i].append(Q_pos_xyz*1e-3*wl*1e-9/(h*c));
						Gxl_tot[i].append(Q_pos_xyz*1e-3*wl*1e-9/(h*c));

					R_frac=0.5*incoh_tmm_data_s['R']+0.5*incoh_tmm_data_p['R']
					Q_pos_xyz=Q_pos_xyz*(R_frac/(1-R_frac))
					Gxl_refl[i].append(Q_pos_xyz*1e-3*wl*1e-9/(h*c));

					#calculate pointing vectors
					#PA_s[i].append(tmm.position_resolved(j, x_pos_rel, coh_tmm_data_s)['poyn'])
					#PA_p[i].append(tmm.position_resolved(j, x_pos_rel, coh_tmm_data_p)['poyn'])
					x_pos_rel+=1

				x_pos_abs+=d_list[j]


	#convert all lists to arrays for plotting
	R_a_s=np.array(R_a_s)
	R_a_p=np.array(R_a_p)
	T_a_s=np.array(T_a_s)
	T_a_p=np.array(T_a_p)
	A_a_s=np.array(A_a_s)
	A_a_p=np.array(A_a_p)

	#get the 50% polarized fields
	R_a_tot=0.5*(R_a_s+R_a_p)
	T_a_tot=0.5*(T_a_s+T_a_p)
	A_tot=0.5*A_a_s+0.5*A_a_p
	A_tot2=A_tot # JB

	#plot A in each layer # JB
	plt.figure(6)
	plt.clf()
	plt.plot(wavelengths,A_tot2[:,activeLayer],'blue',label="A_perov")
	plt.xlabel('wavelength (nm)')
	plt.ylabel('A')
	plt.title('Our plot at %s'%angle)
	plt.legend()
	plt.show() 
	np.savetxt('A_tot.out', np.c_[wavelengths,A_tot], delimiter=',') # JB
    
	# delete first and last layer
	A_tot = np.delete(A_tot, 0, 1)  # delete first column of C
	A_tot = np.delete(A_tot, -1, 1)  # delete last column of C
	A_tot=A_tot.sum(axis=1)

    
	#save the data
	np.savetxt('RTA.out', np.c_[wavelengths,T_a_tot,R_a_tot,A_tot,T_a_tot+R_a_tot+A_tot], delimiter=',',header='Wavelength,T,R,A,Sum')
	
	#plot the results for R,T,A
	plt.close('all')
	plt.figure(1)
	plt.clf()
	plt.plot(wavelengths,T_a_tot,'blue',label="Transmission")
	plt.plot(wavelengths,R_a_tot,'purple',label="Reflection")
	plt.plot(wavelengths,A_tot,'red',label="Absorption")
	plt.plot(wavelengths,T_a_tot+R_a_tot+A_tot,'green',label="Sum")
	plt.xlabel('wl (nm)')
	plt.ylabel('Fraction reflected')
	plt.title('Our plot at %s'%angle)
	plt.legend()
	plt.ylim([0,0.2]) # JB
	plt.xlim([300,850]) # JB
	plt.show()


	if calc_Efield==1:
		t_a=np.array(t)
		i_faces= np.array(d_list)
		i_faces = np.delete(i_faces, 0)  # delete first column of C
		i_faces = np.delete(i_faces, 0)  # delete second column of C
		i_faces = np.delete(i_faces, -1)  # delete last column of C

		#calculate power of E-fields for s and p
		E_a_s=np.array(E_s)
		E_a_p=np.array(E_p)
		E_2_s=np.square(np.absolute(E_s[wavelengths.index(checkwavelength)]))
		E_2_p=np.square(np.absolute(E_p[wavelengths.index(checkwavelength)]))

		#save the data for the efield
		np.savetxt('E2_distribution.out', np.c_[t_a,E_2_s,E_2_p,E_2_s*0.5+E_2_p*0.5], delimiter=',',header='Position,E2_s,E2_p,E2_tot')

		#plot E field distrubtion
		plt.figure(2)
		plt.clf()
		plt.plot(t_a,E_2_s,'blue',label="s-pol")
		plt.plot(t_a,E_2_p,'red',label="p-pol")
		plt.plot(t_a,E_2_s*0.5+E_2_p*0.5,'green',label="Tot")
		plt.vlines(np.cumsum(i_faces), 0, 1, colors='k', linestyles='solid', label='')
		plt.xlabel('x (nm)')
		plt.ylabel('E2')
		plt.title('Our plot at %s'%angle)
		plt.legend()
		plt.show()


		#calculate generation and Jsc
		if calc_Jsc==1:
			lambdastep=1
			if np.size(wavelengths)>1:
				lambdastep=(np.amax(wavelengths)-np.amin(wavelengths))/(np.size(wavelengths)-1)

			Gx=np.sum(Gxl,axis=0)*lambdastep;
			Jsc=np.sum(Gx,axis=0)*stepsize*q*1e3
			print("Jsc:")
			print(Jsc)



			if calc_Jsc_loss==1:
				Gx_parasitic=np.sum(Gxl_parasitic,axis=0)*lambdastep;
				Jsc_parasitic=np.sum(Gx_parasitic,axis=0)*stepsize*q*1e3

				Gx_refl=np.sum(Gxl_refl,axis=0)*lambdastep;
				Jsc_refl=np.sum(Gx_refl,axis=0)*stepsize*q*1e3

				print("Jsc Loss from reflection:")
				print(Jsc_refl)
				print("Jsc loss from parasitic absorption:")
				print(Jsc_parasitic)

				#save the data for the generation
				np.savetxt('Jsc_data.out', np.c_[Jsc,Jsc_refl,Jsc_parasitic], delimiter=',',header='Jsc,Jsc_refl,Jsc_parasitic')

			if calc_Q==1:
				Gx_tot=np.sum(Gxl_tot,axis=0)*lambdastep;

				#save the data for the generation
				np.savetxt('G_distribution.out', np.c_[t_a,Gx_tot], delimiter=',',header='Position,G')

				plt.figure(3)
				plt.clf()
				plt.plot(t_a,Gx_tot,'blue')
				plt.vlines(np.cumsum(i_faces), 0, 1, colors='k', linestyles='solid', label='')
				plt.xlabel('x (nm)')
				plt.ylabel('Q')
				plt.title('Charge generation profile')
				plt.show()

			return Jsc
	return A_a_s, A_a_p, A_tot2 #JB 
Ejemplo n.º 23
0
def solar_results(activeLayer, AL_thickness, theta, atWL, calc_Efield,
                  calc_Jsc, calc_Jsc_loss, calc_Q):  #JB

    # list of layer thicknesses in nm
    d_list[activeLayer] = AL_thickness  # JB
    angle = theta
    th0 = angle * np.pi / 180
    checkwavelength = atWL
    stepsize = 1

    # allocate lists of y-values to plot
    R_a_s = []
    R_a_p = []
    T_a_s = []
    T_a_p = []
    A_a_s = []
    A_a_p = []
    E_s = []
    E_p = []
    E_xyz_tot = []
    PA_s = []
    PA_p = []
    Gxl = []
    Gxl_tot = []
    Gxl_refl = []
    Gxl_parasitic = []

    for i, wl in enumerate(wavelengths):
        n_list = n_k[:, i]

        #calculate all data coherent (returns more values) and incoherent
        coh_tmm_data_s = tmm.coh_tmm('s', n_list, d_list, angle * np.pi / 180,
                                     wl)
        coh_tmm_data_p = tmm.coh_tmm('p', n_list, d_list, angle * np.pi / 180,
                                     wl)
        incoh_tmm_data_s = tmm.inc_tmm('s', n_list, d_list, c_list,
                                       angle * np.pi / 180, wl)
        incoh_tmm_data_p = tmm.inc_tmm('p', n_list, d_list, c_list,
                                       angle * np.pi / 180, wl)

        #use for R,T,A
        R_a_s.append(incoh_tmm_data_s['R'])
        R_a_p.append(incoh_tmm_data_p['R'])
        T_a_s.append(incoh_tmm_data_s['T'])
        T_a_p.append(incoh_tmm_data_p['T'])
        A_a_s.append(tmm.inc_absorp_in_each_layer(incoh_tmm_data_s))
        A_a_p.append(tmm.inc_absorp_in_each_layer(incoh_tmm_data_p))

        E_s.append([])
        E_p.append([])
        E_xyz_tot.append([])
        PA_s.append([])
        PA_p.append([])
        Gxl.append([])
        Gxl_tot.append([])
        Gxl_refl.append([])
        Gxl_parasitic.append([])

        #E-field for every layer different
        if calc_Efield == 1:
            x_pos_abs = 0
            t = []
            for j in range(stackBegin, len(d_list) - 1):
                if j == 1:
                    vw_s = incoh_tmm_data_s['VW_list'][j]
                    kz_s = coh_tmm_data_s['kz_list'][j]
                    vw_p = incoh_tmm_data_p['VW_list'][j]
                    kz_p = coh_tmm_data_p['kz_list'][j]
                else:
                    vw_s = coh_tmm_data_s['vw_list'][j]
                    kz_s = coh_tmm_data_s['kz_list'][j]
                    th_s = coh_tmm_data_s['th_list'][j]
                    vw_p = coh_tmm_data_p['vw_list'][j]
                    kz_p = coh_tmm_data_p['kz_list'][j]
                    th_p = coh_tmm_data_p['th_list'][j]

                alpha = 4 * np.pi * np.imag(n_k[j, i]) / wl

                #at every point x
                x_pos_rel = 0
                for x in range(x_pos_abs, x_pos_abs + d_list[j] + 1):
                    t.append(x)

                    E_plus_s = vw_s[0] * np.exp(1j * kz_s * x_pos_rel)
                    E_minus_s = vw_s[1] * np.exp(-1j * kz_s * x_pos_rel)
                    E_plus_p = vw_p[0] * np.exp(1j * kz_p * x_pos_rel)
                    E_minus_p = vw_p[1] * np.exp(-1j * kz_p * x_pos_rel)

                    E_pos_s = E_plus_s + E_minus_s
                    E_pos_p = E_plus_p + E_minus_p

                    E_s[i].append(E_pos_s)
                    E_p[i].append(E_pos_p)

                    E_z_pos = E_pos_s / np.sqrt(np.cos(th0))
                    E_y_pos = E_pos_p * np.cos(th_p) / np.sqrt(np.cos(th0))
                    E_x_pos = ((-1) * E_plus_p +
                               E_minus_p) * n_list[0] * np.sin(th0) / (
                                   n_list[j] * np.sqrt(np.cos(th0)))

                    E_xyz_pos = 0.5 * np.square(np.absolute(E_z_pos)) + 0.5 * (
                        np.square(np.absolute(E_y_pos)) +
                        np.square(np.absolute(E_x_pos)))
                    E_xyz_tot[i].append(E_xyz_pos)

                    Q_pos_xyz = alpha * np.real(n_k[j,
                                                    i]) * power[i] * E_xyz_pos

                    #calculate Energy dissipation and exciton generation rate
                    if j == activeLayer:
                        Gxl[i].append(Q_pos_xyz * 1e-3 * wl * 1e-9 / (h * c))
                        Gxl_tot[i].append(Q_pos_xyz * 1e-3 * wl * 1e-9 /
                                          (h * c))

                    else:
                        Q_pos_xyz = alpha * np.real(n_k[j, i]) * power[i] * (
                            0.5 * np.square(np.absolute(E_z_pos)) + 0.5 *
                            (np.square(np.absolute(E_y_pos)) +
                             np.square(np.absolute(E_x_pos))))
                        Gxl_parasitic[i].append(Q_pos_xyz * 1e-3 * wl * 1e-9 /
                                                (h * c))
                        Gxl_tot[i].append(Q_pos_xyz * 1e-3 * wl * 1e-9 /
                                          (h * c))

                    R_frac = 0.5 * incoh_tmm_data_s[
                        'R'] + 0.5 * incoh_tmm_data_p['R']
                    Q_pos_xyz = Q_pos_xyz * (R_frac / (1 - R_frac))
                    Gxl_refl[i].append(Q_pos_xyz * 1e-3 * wl * 1e-9 / (h * c))

                    #calculate pointing vectors
                    #PA_s[i].append(tmm.position_resolved(j, x_pos_rel, coh_tmm_data_s)['poyn'])
                    #PA_p[i].append(tmm.position_resolved(j, x_pos_rel, coh_tmm_data_p)['poyn'])
                    x_pos_rel += 1

                x_pos_abs += d_list[j]

    #convert all lists to arrays for plotting
    R_a_s = np.array(R_a_s)
    R_a_p = np.array(R_a_p)
    T_a_s = np.array(T_a_s)
    T_a_p = np.array(T_a_p)
    A_a_s = np.array(A_a_s)
    A_a_p = np.array(A_a_p)

    #get the 50% polarized fields
    R_a_tot = 0.5 * (R_a_s + R_a_p)
    T_a_tot = 0.5 * (T_a_s + T_a_p)
    A_tot = 0.5 * A_a_s + 0.5 * A_a_p
    A_tot2 = A_tot  # JB

    #plot A in each layer # JB
    plt.figure(6)
    plt.clf()
    plt.plot(wavelengths, A_tot2[:, activeLayer], 'blue', label="A_perov")
    plt.xlabel('wavelength (nm)')
    plt.ylabel('A')
    plt.title('Our plot at %s' % angle)
    plt.legend()
    plt.show()
    np.savetxt('A_tot.out', np.c_[wavelengths, A_tot], delimiter=',')  # JB

    # delete first and last layer
    A_tot = np.delete(A_tot, 0, 1)  # delete first column of C
    A_tot = np.delete(A_tot, -1, 1)  # delete last column of C
    A_tot = A_tot.sum(axis=1)

    #save the data
    np.savetxt('RTA.out',
               np.c_[wavelengths, T_a_tot, R_a_tot, A_tot,
                     T_a_tot + R_a_tot + A_tot],
               delimiter=',',
               header='Wavelength,T,R,A,Sum')

    #plot the results for R,T,A
    plt.close('all')
    plt.figure(1)
    plt.clf()
    plt.plot(wavelengths, T_a_tot, 'blue', label="Transmission")
    plt.plot(wavelengths, R_a_tot, 'purple', label="Reflection")
    plt.plot(wavelengths, A_tot, 'red', label="Absorption")
    plt.plot(wavelengths, T_a_tot + R_a_tot + A_tot, 'green', label="Sum")
    plt.xlabel('wl (nm)')
    plt.ylabel('Fraction reflected')
    plt.title('Our plot at %s' % angle)
    plt.legend()
    plt.ylim([0, 0.2])  # JB
    plt.xlim([300, 850])  # JB
    plt.show()

    if calc_Efield == 1:
        t_a = np.array(t)
        i_faces = np.array(d_list)
        i_faces = np.delete(i_faces, 0)  # delete first column of C
        i_faces = np.delete(i_faces, 0)  # delete second column of C
        i_faces = np.delete(i_faces, -1)  # delete last column of C

        #calculate power of E-fields for s and p
        E_a_s = np.array(E_s)
        E_a_p = np.array(E_p)
        E_2_s = np.square(np.absolute(E_s[wavelengths.index(checkwavelength)]))
        E_2_p = np.square(np.absolute(E_p[wavelengths.index(checkwavelength)]))

        #save the data for the efield
        np.savetxt('E2_distribution.out',
                   np.c_[t_a, E_2_s, E_2_p, E_2_s * 0.5 + E_2_p * 0.5],
                   delimiter=',',
                   header='Position,E2_s,E2_p,E2_tot')

        #plot E field distrubtion
        plt.figure(2)
        plt.clf()
        plt.plot(t_a, E_2_s, 'blue', label="s-pol")
        plt.plot(t_a, E_2_p, 'red', label="p-pol")
        plt.plot(t_a, E_2_s * 0.5 + E_2_p * 0.5, 'green', label="Tot")
        plt.vlines(np.cumsum(i_faces),
                   0,
                   1,
                   colors='k',
                   linestyles='solid',
                   label='')
        plt.xlabel('x (nm)')
        plt.ylabel('E2')
        plt.title('Our plot at %s' % angle)
        plt.legend()
        plt.show()

        #calculate generation and Jsc
        if calc_Jsc == 1:
            lambdastep = 1
            if np.size(wavelengths) > 1:
                lambdastep = (np.amax(wavelengths) - np.amin(wavelengths)) / (
                    np.size(wavelengths) - 1)

            Gx = np.sum(Gxl, axis=0) * lambdastep
            Jsc = np.sum(Gx, axis=0) * stepsize * q * 1e3
            print("Jsc:")
            print(Jsc)

            if calc_Jsc_loss == 1:
                Gx_parasitic = np.sum(Gxl_parasitic, axis=0) * lambdastep
                Jsc_parasitic = np.sum(Gx_parasitic,
                                       axis=0) * stepsize * q * 1e3

                Gx_refl = np.sum(Gxl_refl, axis=0) * lambdastep
                Jsc_refl = np.sum(Gx_refl, axis=0) * stepsize * q * 1e3

                print("Jsc Loss from reflection:")
                print(Jsc_refl)
                print("Jsc loss from parasitic absorption:")
                print(Jsc_parasitic)

                #save the data for the generation
                np.savetxt('Jsc_data.out',
                           np.c_[Jsc, Jsc_refl, Jsc_parasitic],
                           delimiter=',',
                           header='Jsc,Jsc_refl,Jsc_parasitic')

            if calc_Q == 1:
                Gx_tot = np.sum(Gxl_tot, axis=0) * lambdastep

                #save the data for the generation
                np.savetxt('G_distribution.out',
                           np.c_[t_a, Gx_tot],
                           delimiter=',',
                           header='Position,G')

                plt.figure(3)
                plt.clf()
                plt.plot(t_a, Gx_tot, 'blue')
                plt.vlines(np.cumsum(i_faces),
                           0,
                           1,
                           colors='k',
                           linestyles='solid',
                           label='')
                plt.xlabel('x (nm)')
                plt.ylabel('Q')
                plt.title('Charge generation profile')
                plt.show()

            return Jsc
    return A_a_s, A_a_p, A_tot2  #JB
Ejemplo n.º 24
0
n_list.append(n_vacuum)

distance_list = np.real(
    distance_list)  # Avoids an error that distances have imaginary component

# The wavelengths we want to analyse
wave_length_list = np.linspace(target_wave_length - wave_length_delta,
                               target_wave_length + wave_length_delta, samples)

# These arrays will contain the results of our calculations
reflection_list = []
transmission_list = []
absorption_list = []

for wave_length in wave_length_list:
    coh_tmm_result = tmm.coh_tmm(polarization, n_list, distance_list, theta0,
                                 wave_length)
    tmm_absorption_result = np.sum(
        tmm.absorp_in_each_layer(coh_tmm_result)[1:-1])

    reflection_list.append(coh_tmm_result['R'])
    transmission_list.append(coh_tmm_result['T'])
    absorption_list.append(tmm_absorption_result)

# Plot RT
plt.title('Transmission and reflection for various wave lengths')
plt.plot(wave_length_list, transmission_list, label="T")
plt.plot(wave_length_list, reflection_list, label="R")

plt.xlabel('Wavelength (nm)')
plt.ylabel('Fraction of incoming power')
Ejemplo n.º 25
0
n.append(n0**(2. / 3))
d.append(lam0 / (4.0 * real(n0)**(2. / 3)))
n.append(n0)
d.append(2.0)
n.append(n0**(2. / 3))
d.append(lam0 / (4.0 * real(n0)**(2. / 3)))
n.append(n0**(1. / 3))
d.append(lam0 / (4.0 * real(n0)**(1. / 3)))
n.append(1.0)
d.append(inf)

ips = []

lam_vac = 299.792458 / 150.
# p-wave
p = tmm.coh_tmm('p', n, d, deg2rad(12.5), lam_vac)
# s-wave
s = tmm.coh_tmm('s', n, d, deg2rad(12.5), lam_vac)

# ips += [(p['T']-s['T'])/2.0]

for f in frequency:
    lam_vac = 299.792458 / f
    # p-wave
    p = tmm.coh_tmm('p', n, d, deg2rad(12.5), lam_vac)
    # s-wave
    s = tmm.coh_tmm('s', n, d, deg2rad(12.5), lam_vac)

    ips += [(p['T'] - s['T']) / (p['T'] + s['T'])]

print(mean(ips[130:171]))
Ejemplo n.º 26
0
def test_DBR(args):
    # .. todo:: find way to visualize DBR, maybe TMM module has something for that or use PIL module or similar

    n_low = 2.94
    n_high = 3.55
    n_cav = n_high
    wavelength_0_nm = 910

    t_low = wavelength_0_nm / (4 * n_low)
    t_high = wavelength_0_nm / (4 * n_high)
    t_cav = 4 * wavelength_0_nm / (4 * n_high)

    # TMM for 33/24 DBR with lambda cavity leads to Q = 3.1335e+05

    #lam_range = 0.01
    #N_top = 24
    ##N_bottom = 16 # 33
    #N_bottom = 33 #int(round(N_top*33/24))

    #lam_range = args.lam_range
    N_top = args.N_top
    N_bottom = args.N_bottom

    # list of layer thicknesses in nm
    # list of refractive indices

    d_list = [inf]
    n_list = [1]

    for i in range(N_top):
        d_list.extend([t_high, t_low])
        n_list.extend([n_high, n_low])

    if args.no_cavity:
        d_list.extend([t_high])
        n_list.extend([n_high])
    else:
        d_list.extend([t_cav])
        n_list.extend([n_cav])

    for i in range(N_bottom):
        d_list.extend([t_low, t_high])
        n_list.extend([n_low, n_high])

    d_list.extend([inf])
    n_list.extend([1])

    print(d_list)
    print(n_list)
    print(len(d_list))
    print(len(n_list))

    # lambda range to use
    main_points = [wavelength_0_nm]
    for r in args.lam_range:
        main_points.append(wavelength_0_nm - r)
        main_points.append(wavelength_0_nm + r)
    main_points.sort()
    print('main_points = {}'.format(main_points))
    lam_vac = linspaces(main_points, (len(main_points) - 1) * [args.Npoints])
    #print('lam_vac = {}'.format(lam_vac))
    #raise
    #if lam_range <= 0.01:
    #lam_vac = linspace(wavelength_0_nm-lam_range, wavelength_0_nm+lam_range, args.Npoints)
    #else:
    #lam_vac = linspaces(wavelength_0_nm-lam_range, wavelength_0_nm-0.01, wavelength_0_nm+lam_range, args.Npoints,wavelength_0_nm+lam_range, args.Npoints)

    Rnorm = []
    Tnorm = []
    for lam_vac_current in lam_vac:
        result = coh_tmm('s', n_list, d_list, 0, lam_vac_current)
        Rnorm.append(result['R'])
        Tnorm.append(result['T'])

    info = DBRinfo(n_low, n_high)
    print(info)
    a = t_high + t_low
    lam_bot = a / info['topgap']
    lam_mid = a / info['midgap']
    lam_top = a / info['botgap']
    print([lam_bot, lam_mid, lam_top])

    Tnorm = numpy.array(Tnorm)
    if args.normalize:
        Tnorm = Tnorm / max(Tnorm)

    plt.figure()
    if args.plot_reflection:
        plt.plot(lam_vac, Rnorm, 'r')
    plt.plot(lam_vac, Tnorm, 'b')

    #plt.axvline(lam_bot, linestyle='--', color='g')
    plt.axvline(lam_mid, linestyle='--', color='g')
    #plt.axvline(lam_top, linestyle='--', color='g')

    plt.xlabel('$\lambda$ (nm)')
    plt.ylabel('reflectance, transmittance')
    plt.title(
        'reflectance (red), transmittance (blue) of unpolarized light at 0$^\circ$ incidence'
    )
    plt.show()

    if args.csvfile:
        csvfile = args.csvfile
    else:
        csvfile = 'DBR_Nbot-{}_Ntop-{}_N-{}_r-{}_norm-{}_cav-{}.csv'.format(
            args.N_bottom, args.N_top, args.Npoints, args.lam_range,
            args.normalize, not args.no_cavity)
    #numpy.savetxt('test_TMM.csv', numpy.transpose([lam_vac,Tnorm]), delimiter=';', header='lam_vac;Tnorm')
    numpy.savetxt(csvfile,
                  numpy.transpose([lam_vac, Tnorm, Rnorm]),
                  delimiter=';',
                  header='lam_vac;Tnorm;Rnorm')

    return
Ejemplo n.º 27
0
    def Simulate(self, n_Sub, n_Space, n_File, n=2.38):
        """This function simulates the reflectivity of the DBR structure using Rnorm from the TMM package"""
        # n_File is a string that is the filename of one of the included refractive index files for GaN. If it's false then a constant value is used.

        # Run the sims
        print(self.Period)

        # Using constant value for n_GaN
        if n_File == False:
            # Initialise Wavelength range to model (Resolution is a nm)
            self.Wav = linspace(200, 1000, 800)

            # Make Layer Thickness List
            Repeat = [self.T_GaN] + self.T_Graded
            self.d_list = [inf] + Repeat * self.NLayers + [self.T_Temp] + [inf]

            # initialize lists of y-values to plot
            self.Rnorm = []

            ############ Calculations ############

            n_Por = porosity_to_n(self.Por_Graded, n, n_Space).tolist()
            # Make list of refractive indices
            Repeat = [n] + n_Por
            self.n_list = [1] + Repeat * self.NLayers + [n] + [n_Sub]

            for Lambda in self.Wav:
                # For normal incidence, s and p polarizations are identical.
                # I arbitrarily decided to use 's'.
                self.Rnorm.append(
                    coh_tmm('s', self.n_list, self.d_list, 0, Lambda)['R'])

        # Using data file for n_GaN
        else:
            # Load GaN refractive index data
            self.n_File = n_File
            data = np.loadtxt(self.n_File + '.csv', delimiter=',', skiprows=1)

            [self.Wav, n_GaN] = np.transpose(
                data)  # Transpose data and assign the two columns

            self.Wav = self.Wav * 1000  # Convert Wavelength to nm (from um)

            n_func = interp1d(
                self.Wav, n_GaN
            )  # This interpolation function allows the look up of n for any wavelength

            # Initialise Wavelength range to model (Resolution is a nm)
            self.Wav = linspace(min(self.Wav),
                                min(1000, self.Wav[-1]),
                                num=int((1000 - min(self.Wav))))

            # Make Layer Thickness List
            Repeat = [self.T_GaN] + self.T_Graded
            self.d_list = [inf] + Repeat * self.NLayers + [self.T_Temp] + [inf]

            # initialize lists of y-values to plot
            self.Rnorm = []

            ############ Calculations ############

            for Lambda in self.Wav:
                n = n_func(Lambda).tolist()

                n_Por = porosity_to_n(self.Por_Graded, n, n_Space).tolist()
                self.nPor.append(n_Por)
                # Make list of refractive indices
                Repeat = [n] + n_Por
                self.n_list = [1] + Repeat * self.NLayers + [n] + [n_Sub]

                # For normal incidence, s and p polarizations are identical.
                # I arbitrarily decided to use 's'.
                self.Rnorm.append(
                    coh_tmm('s', self.n_list, self.d_list, 0, Lambda)['R'])
Ejemplo n.º 28
0
def FabryPerotTest():
    n_outside = 1
    n_inside = 3
    thickness = 1
    lam_vac = linspace(0.4, 1.0, 100)
    incidence_angle = linspace(-45, 45, 91)

    # x = linspace(-3,3,100)
    # y = linspace(-3,3,20)
    # Z = numpy.random.rand(len(x), len(y))

    X, Y = numpy.meshgrid(incidence_angle, lam_vac)
    # X, Y = numpy.meshgrid(x, y)

    # Z = (1 - X / 2. + X ** 5 + Y ** 3) * numpy.exp(-X ** 2 - Y ** 2)
    # Z = numpy.sin((2*numpy.pi/6) * X )
    # Z = numpy.sin((2*numpy.pi/6) * Y )

    # Z = numpy.zeros((len(y), len(x)))
    # Z = numpy.zeros((len(y), len(x)))
    Z_theory = numpy.zeros(X.shape)
    Z_TMM = numpy.zeros(X.shape)
    # for i in range(X.shape[0]):
    # Z[i, :] = numpy.sin((2*numpy.pi/6) * (incidence_angle-i) )

    for idx, cur_incidence_angle_deg in enumerate(incidence_angle):
        cur_incidence_angle_rad = numpy.deg2rad(cur_incidence_angle_deg)
        reflectance, transmittance = FabryPerot(lam_vac, n_outside, n_inside,
                                                thickness,
                                                cur_incidence_angle_rad)

        Z_theory[:, idx] = reflectance

        # list of layer thicknesses in nm
        d_list = [inf, thickness, inf]
        # list of refractive indices
        n_list = [n_outside, n_inside, n_outside]

        Rnorm = []
        Tnorm = []
        for lam_vac_current in lam_vac:
            result = coh_tmm('s', n_list, d_list, cur_incidence_angle_rad,
                             lam_vac_current)
            Rnorm.append(result['R'])
            Tnorm.append(result['T'])

        Z_TMM[:, idx] = Rnorm

    # plt.figure()
    # plt.plot(lam_vac, reflectance, 'red')
    # plt.plot(lam_vac, transmittance, 'blue')
    # plt.plot(lam_vac, Rnorm, 'ro')
    # plt.plot(lam_vac, Tnorm, 'bo')
    # plt.xlabel('$\lambda$ (nm)')
    # plt.ylabel('reflectance, transmittance')
    # plt.title('reflectance (red), transmittance (blue) of unpolarized light at 0$^\circ$ incidence')
    # plt.show()

    fig, (ax0, ax1) = plt.subplots(1, 2)

    xlabel = 'Incidence angle (degrees)'
    ylabel = 'Wavelength (um)'
    # plt.pcolor(X,Y,Z);
    c = ax0.pcolor(X, Y, Z_theory)
    ax0.set_title('Theory')
    ax0.set(xlabel=xlabel, ylabel=ylabel)

    c = ax1.pcolor(X, Y, Z_TMM)
    ax1.set_title('TMM')
    ax1.set(xlabel=xlabel, ylabel=ylabel)

    ax1.label_outer()

    fig.suptitle('Fabry-Perot reflectance')
    plt.show()
    return
Ejemplo n.º 29
0
def calculate_rat(structure,
                  wavelength,
                  angle=0,
                  pol='u',
                  coherent=True,
                  coherency_list=None,
                  no_back_reflexion=True):
    """ Calculates the reflected, absorbed and transmitted intensity of the structure for the wavelengths and angles
    defined.

    :param structure: A solcore Structure object with layers and materials or a OptiStack object.
    :param wavelength: Wavelengths (in nm) in which calculate the data.
    :param angle: Angle (in degrees) of the incident light. Default: 0 (normal incidence).
    :param pol: Polarisation of the light: 's', 'p' or 'u'. Default: 'u' (unpolarised).
    :param coherent: If the light is coeherent or not. If not, a coherency list must be added.
    :param coherency_list: A list indicating in which layers light should be treated as coeherent ('c') and in which
    incoherent ('i'). It needs as many elements as layers in the structure.
    :param no_back_reflexion: If reflexion from the back must be supressed. Default=True.
    :return: A dictionary with the R, A and T at the specified wavelengths and angle.
    """
    num_wl = len(wavelength)

    if 'OptiStack' in str(type(structure)):
        stack = structure
        stack.no_back_reflexion = no_back_reflexion
    else:
        stack = OptiStack(structure, no_back_reflexion=no_back_reflexion)

    if not coherent:
        if coherency_list is not None:
            assert len(coherency_list) == stack.num_layers, \
                'Error: The coherency list must have as many elements (now {}) as the ' \
                'number of layers (now {}).'.format(len(coherency_list), stack.num_layers)
            coherency_list = ['i'] + coherency_list + ['i']

        else:
            raise Exception(
                'Error: For incoherent or partly incoherent calculations you must supply the '
                'coherency_list parameter with as many elements as the number of layers in the '
                'structure')

    output = {
        'R': np.zeros(num_wl),
        'A': np.zeros(num_wl),
        'T': np.zeros(num_wl),
        'all_p': [],
        'all_s': []
    }

    if pol in 'sp':
        if coherent:
            for i, wl in enumerate(wavelength):
                out = tmm.coh_tmm(pol, stack.get_indices(wl),
                                  stack.get_widths(), angle * degree, wl)
                output['R'][i] = out['R']
                output['A'][i] = 1 - out['R'] - out['T']
                output['T'][i] = out['T']
        else:
            for i, wl in enumerate(wavelength):
                out = tmm.inc_tmm(pol, stack.get_indices(wl),
                                  stack.get_widths(), coherency_list,
                                  angle * degree, wl)
                output['R'][i] = out['R']
                output['A'][i] = 1 - out['R'] - out['T']
                output['T'][i] = out['T']

    else:
        if coherent:
            for i, wl in enumerate(wavelength):
                out = tmm.unpolarized_RT(stack.get_indices(wl),
                                         stack.get_widths(), angle * degree,
                                         wl)
                output['R'][i] = out['R']
                output['A'][i] = 1 - out['R'] - out['T']
                output['T'][i] = out['T']
        else:
            for i, wl in enumerate(wavelength):
                out_p = tmm.inc_tmm('p', stack.get_indices(wl),
                                    stack.get_widths(), coherency_list,
                                    angle * degree, wl)
                out_s = tmm.inc_tmm('s', stack.get_indices(wl),
                                    stack.get_widths(), coherency_list,
                                    angle * degree, wl)

                output['R'][i] = 0.5 * (out_p['R'] + out_s['R'])
                output['T'][i] = 0.5 * (out_p['T'] + out_s['T'])
                output['A'][i] = 1 - output['R'][i] - output['T'][i]
                output['all_p'].append(out_p['power_entering_list'])
                output['all_s'].append(out_s['power_entering_list'])

    return output
Ejemplo n.º 30
0
    def SimulateParts(self, n_Sub, n_Space, n_File, TopDBR, n=2.38):
        """This function is an alternative to SImulate for structures made up of two different DBRs. Takes another DBR structure as an additional argument and calculates the reflectivity of the combined structure"""
        # Run the sims
        print(self.Period)

        # Using constant value for n_GaN
        if n_File == False:
            # Initialise Wavelength range to model (Resolution is a nm)
            self.Wav = linspace(200, 1000, 800)

            # Make Layer Thickness List
            Repeat = [self.T_GaN] + self.T_Graded
            RepeatTop = [TopDBR.T_GaN] + TopDBR.T_Graded
            self.d_list = [
                inf
            ] + RepeatTop * TopDBR.NLayers + Repeat * self.NLayers + [
                self.T_Temp
            ] + [inf]

            # initialize lists of y-values to plot
            self.Rnorm = []

            ############ Calculations ############

            n_Por = porosity_to_n(self.Por_Graded, n, n_Space).tolist()
            n_PorTop = porosity_to_n(TopDBR.Por_Graded, n, n_Space).tolist()
            # Make list of refractive indices
            Repeat = [n] + n_Por
            RepeatTop = [n] + n_PorTop
            self.n_list = [
                1
            ] + RepeatTop * TopDBR.NLayers + Repeat * self.NLayers + [n] + [
                n_Sub
            ]

            for Lambda in self.Wav:
                # For normal incidence, s and p polarizations are identical.
                # I arbitrarily decided to use 's'.
                self.Rnorm.append(
                    coh_tmm('s', self.n_list, self.d_list, 0, Lambda)['R'])

        # Using data file for n_GaN
        else:
            # Load GaN refractive index data
            self.n_File = n_File
            data = np.loadtxt(self.n_File + '.csv', delimiter=',', skiprows=1)

            [self.Wav, n_GaN] = np.transpose(
                data)  # Transpose data and assign the two columns

            self.Wav = self.Wav * 1000  # Convert Wavelength to nm (from um)

            n_func = interp1d(
                self.Wav, n_GaN
            )  # This interpolation function allows the look up of n for any wavelength

            # Initialise Wavelength range to model (Resolution is a nm)
            self.Wav = linspace(min(self.Wav),
                                min(1000, self.Wav[-1]),
                                num=int((1000 - min(self.Wav))))

            # Make Layer Thickness List
            Repeat = [self.T_GaN] + self.T_Graded
            RepeatTop = [TopDBR.T_GaN] + TopDBR.T_Graded
            self.d_list = [
                inf
            ] + RepeatTop * TopDBR.NLayers + Repeat * self.NLayers + [
                self.T_Temp
            ] + [inf]

            # initialize lists of y-values to plot
            self.Rnorm = []

            ############ Calculations ############

            for Lambda in self.Wav:
                n = n_func(Lambda).tolist()

                n_Por = porosity_to_n(self.Por_Graded, n, n_Space).tolist()
                self.nPor.append(n_Por)
                n_PorTop = porosity_to_n(TopDBR.Por_Graded, n,
                                         n_Space).tolist()
                TopDBR.nPor.append(n_PorTop)
                # Make list of refractive indices
                Repeat = [n] + n_Por
                RepeatTop = [n] + n_PorTop
                self.n_list = [
                    1
                ] + RepeatTop * TopDBR.NLayers + Repeat * self.NLayers + [
                    n
                ] + [n_Sub]

                # For normal incidence, s and p polarizations are identical.
                # I arbitrarily decided to use 's'.
                self.Rnorm.append(
                    coh_tmm('s', self.n_list, self.d_list, 0, Lambda)['R'])