def vs_pol_prof(s, p, A_total):
        profile = np.zeros(len(dist))
        S.SetExcitationPlanewave((theta, phi), s, p, 0)
        S.SetFrequency(1 / wl)
        for j, d in enumerate(dist):
            layer, d_in_layer = tmm.find_in_structure_with_inf(widths, d)
            layer_name = 'layer_' + str(
                layer + 1)  # layer_1 is air above so need to add 1
            data = rcwa_position_resolved(S, layer_name, d_in_layer, A_total)
            profile[j] = data

        return profile
Beispiel #2
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
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)
def calculate_absorption_profile_rcwa(structure,
                                      size,
                                      orders,
                                      wavelength,
                                      rat_output,
                                      z_limit=None,
                                      steps_size=2,
                                      dist=None,
                                      theta=0,
                                      phi=0,
                                      pol='u'):
    """ 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.
    :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 dist is None:
        if z_limit is None:
            stack = OptiStack(structure)
            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)))}

    S, stack_OS, shape_mats_OS = initialise_S(structure, size, orders)

    if pol in 'sp':
        if pol == 's':
            s = 1
            p = 0
        elif pol == 'p':
            s = 0
            p = 1

        S.SetExcitationPlanewave((theta, phi), s, p, 0)
        for i, wl in enumerate(wavelength):
            update_epsilon(S, stack_OS, shape_mats_OS, wl)
            S.SetFrequency(1 / wl)
            A = rat_output['A'][i]
            for j, d in enumerate(dist):
                layer, d_in_layer = tmm.find_in_structure_with_inf(
                    stack_OS.get_widths(), d)  # don't need to change this
                layer_name = 'layer_' + str(
                    layer + 1)  # layer_1 is air above so need to add 1
                data = rcwa_position_resolved(S, layer_name, d_in_layer, A)
                output['absorption'][i, j] = data

    else:
        for i, wl in enumerate(
                wavelength):  # set the material values and indices in here
            update_epsilon(S, stack_OS, shape_mats_OS, wl)
            S.SetFrequency(1 / wl)
            A = rat_output['A'][i]

            for j, d in enumerate(dist):
                layer, d_in_layer = tmm.find_in_structure_with_inf(
                    stack_OS.get_widths(), d)  # don't need to change this
                layer_name = 'layer_' + str(
                    layer + 1)  # layer_1 is air above so need to add 1
                S.SetExcitationPlanewave((theta, phi), 0, 1,
                                         0)  # p-polarization
                data_p = rcwa_position_resolved(S, layer_name, d_in_layer, A)
                S.SetExcitationPlanewave((theta, phi), 1, 0,
                                         0)  # p-polarization
                data_s = rcwa_position_resolved(S, layer_name, d_in_layer, A)
                output['absorption'][i, j] = 0.5 * (data_p + data_s)

    return output
Beispiel #5
0
def calculate_absorption_profile_rcwa(structure,
                                      size,
                                      orders,
                                      wavelength,
                                      rat_output,
                                      z_limit=None,
                                      steps_size=2,
                                      dist=None,
                                      theta=0,
                                      phi=0,
                                      pol='u',
                                      substrate=None):
    """ 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 size: list with 2 entries, size of the unit cell (right now, can only be rectangular
    :param orders: number of orders to retain in the RCWA calculations.
    :param wavelength: Wavelengths (in nm) in which calculate the data.
    :param rat_output: output from calculate_rat_rcwa
    :param z_limit: Maximum value in the z direction at which to calculate depth-dependent absorption (nm)
    :param steps_size: if the dist is not specified, the step size in nm to use in the depth-dependent calculation
    :param dist: the positions (in nm) at which to calculate depth-dependent absorption
    :param theta: polar incidence angle (in degrees) of the incident light. Default: 0 (normal incidence)
    :param phi: azimuthal incidence angle in degrees. Default: 0
    :param pol: Polarisation of the light: 's', 'p' or 'u'. Default: 'u' (unpolarised).
    :param substrate: semi-infinite transmission medium
    :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 dist is None:
        if z_limit is None:
            stack = OptiStack(structure)
            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)))}

    S, stack_OS, shape_mats_OS = initialise_S(structure, size, orders,
                                              substrate)

    if pol in 'sp':
        if pol == 's':
            s = 1
            p = 0
        elif pol == 'p':
            s = 0
            p = 1

        S.SetExcitationPlanewave((theta, phi), s, p, 0)
        for i, wl in enumerate(wavelength):
            update_epsilon(S, stack_OS, shape_mats_OS, wl)
            S.SetFrequency(1 / wl)
            A = rat_output['A'][i]
            for j, d in enumerate(dist):
                layer, d_in_layer = tmm.find_in_structure_with_inf(
                    stack_OS.get_widths(), d)  # don't need to change this
                layer_name = 'layer_' + str(
                    layer + 1)  # layer_1 is air above so need to add 1
                data = rcwa_position_resolved(S, layer_name, d_in_layer, A)
                output['absorption'][i, j] = data

    else:
        for i, wl in enumerate(
                wavelength):  # set the material values and indices in here
            print(i)
            update_epsilon(S, stack_OS, shape_mats_OS, wl)
            S.SetFrequency(1 / wl)
            A = rat_output['A'][i]

            for j, d in enumerate(dist):
                layer, d_in_layer = tmm.find_in_structure_with_inf(
                    stack_OS.get_widths(), d)  # don't need to change this
                layer_name = 'layer_' + str(
                    layer + 1)  # layer_1 is air above so need to add 1
                S.SetExcitationPlanewave((theta, phi), 0, 1,
                                         0)  # p-polarization
                data_p = rcwa_position_resolved(S, layer_name, d_in_layer, A)
                S.SetExcitationPlanewave((theta, phi), 1, 0,
                                         0)  # p-polarization
                data_s = rcwa_position_resolved(S, layer_name, d_in_layer, A)
                output['absorption'][i, j] = 0.5 * (data_p + data_s)

    return output
Beispiel #6
0
    def RCWA_wl_prof(self, wl, rat_output_A, dist, geom_list, layers_oc,
                     shapes_oc, s_names, pol, theta, phi, widths, size, orders,
                     rcwa_options):
        #widths = stack_OS.get_widths()
        S = initialise_S(size, orders, geom_list, layers_oc, shapes_oc,
                         s_names, widths, rcwa_options)
        profile_data = np.zeros(len(dist))

        A = rat_output_A

        if len(pol) == 2:

            S.SetExcitationPlanewave((theta, phi), pol[0], pol[1], 0)
            S.SetFrequency(1 / wl)
            for j, d in enumerate(dist):
                layer, d_in_layer = tmm.find_in_structure_with_inf(
                    widths, d)  # don't need to change this
                layer_name = 'layer_' + str(
                    layer + 1)  # layer_1 is air above so need to add 1
                data = rcwa_position_resolved(S, layer_name, d_in_layer, A)
                profile_data[j] = data

        else:
            if pol in 'sp':
                if pol == 's':
                    s = 1
                    p = 0
                elif pol == 'p':
                    s = 0
                    p = 1

                S.SetExcitationPlanewave((theta, phi), s, p, 0)

                S.SetFrequency(1 / wl)

                for j, d in enumerate(dist):
                    layer, d_in_layer = tmm.find_in_structure_with_inf(
                        widths, d)  # don't need to change this
                    layer_name = 'layer_' + str(
                        layer + 1)  # layer_1 is air above so need to add 1
                    data = rcwa_position_resolved(S, layer_name, d_in_layer, A)
                    profile_data[j] = data

            else:

                S.SetFrequency(1 / wl)
                A = rat_output_A

                for j, d in enumerate(dist):
                    layer, d_in_layer = tmm.find_in_structure_with_inf(
                        widths, d)  # don't need to change this
                    layer_name = 'layer_' + str(
                        layer + 1)  # layer_1 is air above so need to add 1
                    S.SetExcitationPlanewave((theta, phi), 0, 1,
                                             0)  # p-polarization
                    data_p = rcwa_position_resolved(S, layer_name, d_in_layer,
                                                    A)
                    S.SetExcitationPlanewave((theta, phi), 1, 0,
                                             0)  # p-polarization
                    data_s = rcwa_position_resolved(S, layer_name, d_in_layer,
                                                    A)
                    profile_data[j] = 0.5 * (data_s + data_p)

        return profile_data