def test_scattering_matrix_calculation_fabryperot(self): index_air = sm.single_index_function(1.0) index_glass = sm.single_index_function(1.5) wavelengths = np.array( [1.5 * sm.Units.um, 0.75 * sm.Units.um, 6.0 / 5.0 * sm.Units.um]) structure = sm.LayerList() structure.append(sm.SingleLayer(index_air, 1.0 * sm.Units.um)) structure.append(sm.SingleLayer(index_glass, 1.0 * sm.Units.um)) structure.append(sm.SingleLayer(index_air, 1.0 * sm.Units.um)) calculate_powers = sm.scattering_matrix_calculation( structure, wavelengths) calc_transmission = calculate_powers[0] calc_reflection = calculate_powers[1] calc_absorption = calculate_powers[2] reflection_face = sm.reflected_power_TE(1.0, 1.5, 0.0) expected_transmission = np.array([ 1.0, 1.0, 1.0 - (4 * reflection_face / ((1 + reflection_face)**2.0)) ]) #expected_reflection = 1.0-expected_transmission ratio_t = calc_transmission / expected_transmission #ratio_r = calc_reflection/expected_reflection npt.assert_array_almost_equal(ratio_t, np.array([1.0, 1.0, 1.0]), decimal=5) #npt.assert_array_almost_equal(ratio_r,np.array([1.0]),decimal=5) npt.assert_array_almost_equal(calc_absorption, np.array([0.0, 0.0, 0.0]), decimal=5)
def test_scattering_matrix_calculation_singlethickness_complex_TM(self): i1 = 1.0 i2 = 1.5 - 2.0j angle = np.pi / 3 #Calculated index_air = sm.single_index_function(i1) index_complex = sm.single_index_function(i2) structure = sm.LayerList() structure.append(sm.SingleLayer(index_air, 1.0 * sm.Units.um)) structure.append(sm.SingleLayer(index_complex, 1.0 * sm.Units.um)) calculate_powers = sm.scattering_matrix_calculation( structure, 1.0 * sm.Units.um, incident_angle=angle, mode="TM") calc_transmission = calculate_powers[0] calc_reflection = calculate_powers[1] #Expected t_angle = sm.transmission_angle(i1, i2, angle) kz = sm.get_kz(i2, t_angle, 1.0 * sm.Units.um) expected_transmission = ( sm.transmitted_power_TM(1.0, 1.5 - 2.0j, angle) * np.exp( (-2.0j * kz * 1.0 * sm.Units.um).real)) expected_reflection = sm.reflected_power_TM(1.0, 1.5 - 2.0j, angle) #Check ratio_t = calc_transmission / expected_transmission ratio_r = calc_reflection / expected_reflection sum_t_r = calc_transmission + calc_reflection npt.assert_array_almost_equal(ratio_t, np.array([1.0]), decimal=5) npt.assert_array_almost_equal(ratio_r, np.array([1.0]), decimal=5) self.assertTrue((sum_t_r < 1.0).all())
def test_SMthickCalc_energy_conserved(self): wavelengths = np.linspace(200.0, 2500.0, 461) * sm.Units.nm index_air = sm.single_index_function(1.0) index_1 = sm.single_index_function(1.3) index_complex = sm.single_index_function(1.5 - 2.0j) structure = sm.LayerList() structure.append(sm.SingleLayer(index_air, 1.0 * sm.Units.um)) structure.append(sm.SingleLayer(index_1, 100.0 * sm.Units.nm)) structure.append(sm.SingleLayer(index_complex, 2.0 * sm.Units.um)) structure.append(sm.SingleLayer(index_air, 1.0 * sm.Units.um)) calculate_powers = sm.smatrix_with_thick_layers(structure, wavelengths) calc_transmission = calculate_powers[0] calc_reflection = calculate_powers[1] #Check sum_t_r = calc_transmission + calc_reflection self.assertTrue((sum_t_r < 1.0).all())
def test_TRParamCalc_energy_conserved(self): wavelengths = np.linspace(200.0, 2500.0, 461) * sm.Units.nm index_air = sm.single_index_function(1.0) index_complex = sm.single_index_function(1.5 - 2.0j) structure = sm.LayerList() structure.append(sm.SingleLayer(index_air, 1.0 * sm.Units.um)) structure.append(sm.SingleLayer(index_complex, 1.0 * sm.Units.um)) structure.append(sm.SingleLayer(index_air, 1.0 * sm.Units.um)) calculate_powers = sm.calc_TR_parameters(structure, wavelengths) calc_transmission_fwd = calculate_powers[0] calc_reflection_fwd = calculate_powers[1] calc_transmission_rev = calculate_powers[0] calc_reflection_rev = calculate_powers[1] #Check sum_t_r = calc_transmission_fwd + calc_reflection_fwd sum_t_r_rev = calc_transmission_fwd + calc_reflection_fwd self.assertTrue((sum_t_r < 1.0).all()) self.assertTrue((sum_t_r_rev < 1.0).all())
def test_scattering_matrix_calculation_singlethickness_complex(self): index_air = sm.single_index_function(1.0) index_complex = sm.single_index_function(1.5 - 2.0j) structure = sm.LayerList() structure.append(sm.SingleLayer(index_air, 1.0 * sm.Units.um)) structure.append(sm.SingleLayer(index_complex, 1.0 * sm.Units.um)) calculate_powers = sm.scattering_matrix_calculation( structure, 1.0 * sm.Units.um) calc_transmission = calculate_powers[0] calc_reflection = calculate_powers[1] expected_transmission = ( sm.transmitted_power_TE(1.0, 1.5 - 2.0j, 0.0) * np.exp( (-4.0 * np.pi) * 2)) expected_reflection = sm.reflected_power_TE(1.0, 1.5 - 2.0j, 0.0) ratio_t = calc_transmission / expected_transmission ratio_r = calc_reflection / expected_reflection sum_t_r = calc_transmission + calc_reflection npt.assert_array_almost_equal(ratio_t, np.array([1.0]), decimal=5) npt.assert_array_almost_equal(ratio_r, np.array([1.0]), decimal=5) self.assertTrue((sum_t_r < 1.0).all())
def test_scattering_matrix_calculation_singleinterface_complex(self): index_air = sm.single_index_function(1.0) index_complex = sm.single_index_function(1.5 - 2.0j) structure = sm.LayerList() structure.append(sm.SingleLayer(index_air, 1.0 * sm.Units.um)) structure.append(sm.SingleLayer(index_complex, 0.0 * sm.Units.um)) calculate_powers = sm.scattering_matrix_calculation( structure, 1.0 * sm.Units.um) calc_transmission = calculate_powers[0] calc_reflection = calculate_powers[1] calc_absorption = calculate_powers[2] expected_transmission = sm.transmitted_power_TE(1.0, 1.5 - 2.0j, 0.0) expected_reflection = sm.reflected_power_TE(1.0, 1.5 - 2.0j, 0.0) ratio_t = calc_transmission / expected_transmission ratio_r = calc_reflection / expected_reflection npt.assert_array_almost_equal(ratio_t, np.array([1.0]), decimal=5) npt.assert_array_almost_equal(ratio_r, np.array([1.0]), decimal=5) npt.assert_array_almost_equal(calc_absorption, np.array([0.0]), decimal=5)
def test_scattering_matrix_calculation_energy_conservation_TE(self): wavelengths = np.linspace(200.0, 2500.0, 461) * sm.Units.nm i1 = 1.0 i2 = 1.5 - 2.0j angle = np.pi / 3 #Calculated index_air = sm.single_index_function(i1) index_complex = sm.single_index_function(i2) structure = sm.LayerList() structure.append(sm.SingleLayer(index_air, 1.0 * sm.Units.um)) structure.append(sm.SingleLayer(index_complex, 10.0 * sm.Units.nm)) structure.append(sm.SingleLayer(index_air, 1.0 * sm.Units.um)) calculate_powers = sm.scattering_matrix_calculation( structure, wavelengths, incident_angle=angle, mode="TE") calc_transmission = calculate_powers[0] calc_reflection = calculate_powers[1] #Check sum_t_r = calc_transmission + calc_reflection self.assertTrue((sum_t_r < 1.0).all())
Declare Structure ''' #Defining index functions. Any function that returns a complex value given #a specific wavelength (in meters) can be used. Here, we declare functions that #always return the same index, regardless of wavelength index_air = sm.single_index_function(1.0) index_glass = sm.single_index_function(1.5) index_Si3N4 = sm.single_index_function(2.0) #A 1D optical structure is a list of layers. We declare two of the layers here film = sm.SingleLayer(index_Si3N4, 60.0 * sm.Units.NANOMETERS) substrate = sm.SingleLayer(index_glass, 1.1 * sm.Units.MILLIMETERS) #Here we declare the actual list and append the layers. structure = sm.LayerList() structure.append(sm.SingleLayer(index_air, sm.Units.MICROMETERS)) structure.append(film) structure.append(substrate) structure.append(sm.SingleLayer(index_air, sm.Units.MICROMETERS)) ''' Calculate transmission and reflection at 0 degrees ''' wavelengths = np.linspace(300.0, 1200.0, 91) * sm.Units.NANOMETERS #Data is returned in an array of arrays. results = sm.scattering_matrix_calculation(structure, wavelengths) print("Selected Wavelength Data") print("----------------------------") print("Incident Angle:", results[4]) print("Mode:", results[5])