def simple_superlattice(file): f = open(file, 'r') data = yaml.load(f) f.close() well_length = spsc_data.LengthValue(data['well_length'], 'nm') lattice_well_length = spsc_data.LengthValue(data['lattice_well_length'], 'nm') lattice_barrier_length = spsc_data.LengthValue( data['lattice_barrier_length'], 'nm') state = superlattice_well(data['periods_number'], well_length, lattice_well_length, lattice_barrier_length) electron_state = state.electron_states[0] electron_state.mass = electron_state.mass * data['mass'] electron_state.sum_density = spsc_data.DensityValue( data['density'], "m^-2") electron_state.static_potential.value = electron_state.static_potential.value * data[ 'lattice_amplitude'] lattice_well_length.convert_to("nm") lattice_barrier_length.convert_to("nm") delta_layer_index = (data['delta_layer_period'] - 1) * ( lattice_well_length.value + lattice_barrier_length.value) * DOTS_PER_NM + \ lattice_well_length.value * DOTS_PER_NM / 2 + lattice_barrier_length.value * DOTS_PER_NM delta_layer_index = int(delta_layer_index) state.static_density.convert_to('m^-2') state.static_density[delta_layer_index] = data['delta_layer_density'] state.static_density.mirror() state.electron_states[0].static_potential.meta_info[ 'delta_layer_index'] = delta_layer_index return state
def solve(self, E, solution_start): self._reset_to_default_units() E.convert_to(E.units_default) lattice_potential = spsc_data.Potential( self.potential[:self.well_start], self.potential.units) flat_lattice_potential = self._flatten_potential(lattice_potential) lattice_length = spsc_data.LengthValue( self.length.value * (len(flat_lattice_potential) - 1) / (len(self.potential) - 1), self.length.units) iteration = SolutionIterationFlatPotential(flat_lattice_potential, self.mass, lattice_length) lattice_solution = iteration.solve(E, solution_start) well_solution_start = (lattice_solution[0][-1], lattice_solution[1][-1]) well_potential = spsc_data.Potential( self.potential[self.well_start:self.well_end], self.potential.units) well_length = spsc_data.LengthValue( self.length.value * len(well_potential) / (len(self.potential) - 1), self.length.units) iteration = SolutionIterationRungeKutt(well_potential, self.mass, well_length) well_solution = iteration.solve(E, well_solution_start) N = len(self.potential) solution = (spsc_data.WaveFunction(np.zeros( (N, ))), spsc_data.WaveFunction(np.zeros((N, )))) solution[0][:len(lattice_solution[0])] = lattice_solution[0] solution[0][len(lattice_solution[0]) - 1:len(lattice_solution[0]) + len(well_solution[0]) - 1] = well_solution[0] solution[1][:len(lattice_solution[1])] = lattice_solution[1] solution[1][len(lattice_solution[1]) - 1:len(lattice_solution[1]) + len(well_solution[1]) - 1] = well_solution[1] return solution
def superlattice_well(periods_num, well_length, lattice_well_length, lattice_barrier_length): well_length.convert_to("nm") lattice_well_length.convert_to("nm") lattice_barrier_length.convert_to("nm") state = spsc_core.StateSimple() electron_state = spsc_core.ElectronStateSimple() length = spsc_data.LengthValue(0, "nm") lattice_length = spsc_data.LengthValue(0, "nm") for i in range(periods_num): lattice_length += lattice_well_length + lattice_barrier_length length += lattice_barrier_length * 2 + well_length + lattice_length * 2 potential = spsc_data.Potential( np.ones((int(lattice_barrier_length.value * DOTS_PER_NM), ), "float64"), "eV") next_index = lattice_barrier_length.value * DOTS_PER_NM for i in range(periods_num): potential.append( spsc_data.Potential( np.zeros((int(lattice_well_length.value * DOTS_PER_NM), ), "float64"), "eV")) potential.append( spsc_data.Potential( np.ones((int(lattice_barrier_length.value * DOTS_PER_NM), ), "float64"), "eV")) next_index += lattice_well_length.value * DOTS_PER_NM + lattice_barrier_length.value * DOTS_PER_NM meta_info = { "well_start": int(next_index), "lattice_bar_width": int(lattice_barrier_length.value * DOTS_PER_NM), "lattice_well_width": int(lattice_well_length.value * DOTS_PER_NM) } potential.append( spsc_data.Potential( np.zeros((int(well_length.value * DOTS_PER_NM), ), "float64"), "eV")) next_index += well_length.value * DOTS_PER_NM meta_info["well_end"] = int(next_index) empty_dots = int(length.value * DOTS_PER_NM) + 1 - len(potential) potential.append( spsc_data.Potential(np.zeros((empty_dots, ), "float64"), "eV")) potential.mirror() potential.meta_info = meta_info electron_state.static_potential = potential electron_state.mass = spsc_data.MassValue(constants.m_e) electron_state.sum_density = spsc_data.DensityValue(0, "m^-2") state.electron_states = [electron_state] state.length = length state.static_density = spsc_data.Density( np.zeros((len(potential, )), "float64"), "m^-2") state.density_potential = spsc_data.Potential( np.zeros((len(potential, )), "float64")) return state
def simple_superlattice_diff_mass(file): f = open(file, 'r') data = yaml.load(f) f.close() well_length = spsc_data.LengthValue(data['well_length'], 'nm') lattice_well_length = spsc_data.LengthValue(data['lattice_well_length'], 'nm') lattice_barrier_length = spsc_data.LengthValue( data['lattice_barrier_length'], 'nm') state = superlattice_well(data['periods_number'], well_length, lattice_well_length, lattice_barrier_length) electron_state = state.electron_states[0] mass = spsc_data.MassArray(data['barrier_mass'] * np.ones( (int(lattice_barrier_length.value * DOTS_PER_NM), ), "float64")) for i in xrange(data['periods_number']): mass.append( spsc_data.MassArray(data['well_mass'] * np.ones( (int(lattice_well_length.value * DOTS_PER_NM), ), "float64"))) mass.append( spsc_data.MassArray(data['barrier_mass'] * np.ones( (int(lattice_barrier_length.value * DOTS_PER_NM), ), "float64"))) mass.append( spsc_data.MassArray(data['well_mass'] * np.ones( (int(well_length.value * DOTS_PER_NM), ), "float64"))) empty_dots = len(electron_state.static_potential) - len(mass) mass.append(spsc_data.MassArray(np.zeros((empty_dots, ), "float64"))) mass = mass * constants.m_e mass.mirror() electron_state.mass = mass electron_state.sum_density = spsc_data.DensityValue( data['density'], "m^-2") electron_state.static_potential.value = electron_state.static_potential.value * data[ 'lattice_amplitude'] lattice_well_length.convert_to("nm") lattice_barrier_length.convert_to("nm") delta_layer_index = (data['delta_layer_period'] - 1) * ( lattice_well_length.value + lattice_barrier_length.value) * DOTS_PER_NM + \ lattice_well_length.value * DOTS_PER_NM / 2 + lattice_barrier_length.value * DOTS_PER_NM delta_layer_index = int(delta_layer_index) state.static_density.convert_to('m^-2') state.static_density[delta_layer_index] = data['delta_layer_density'] state.static_density.mirror() state.electron_states[0].static_potential.meta_info[ 'delta_layer_index'] = delta_layer_index return state
def x_electrons_superlattice_diff_mass(file): f = open(file, 'r') data = yaml.load(f) f.close() well_length = spsc_data.LengthValue(data['well_length'], 'nm') lattice_well_length = spsc_data.LengthValue(data['lattice_well_length'], 'nm') lattice_barrier_length = spsc_data.LengthValue( data['lattice_barrier_length'], 'nm') state = superlattice_well(data['periods_number'], well_length, lattice_well_length, lattice_barrier_length) x_electron_state = state.electron_states[0] x_electron_state.mass = x_electron_state.mass * data['well_mass_x'] x_electron_state.sum_density = spsc_data.DensityValue(0, "m^-2") x_electron_state.static_potential.value = x_electron_state.static_potential.value - 1 x_electron_state.static_potential.value = x_electron_state.static_potential.value * ( -data['x_lattice_amplitude']) x_electron_state.static_potential.value = x_electron_state.static_potential.value + data[ 'x_lattice_offset'] state = simple_superlattice_diff_mass(file) # Denote start and end indexes for X-electron solutions delta_layer_index = state.electron_states[0].static_potential.meta_info[ 'delta_layer_index'] delta_layer_offset = 2 * (lattice_well_length.value + lattice_barrier_length.value) * DOTS_PER_NM x_solution_start_index = delta_layer_index - delta_layer_offset if x_solution_start_index < 0: x_solution_start_index = 0 x_solution_end_index = delta_layer_index + delta_layer_offset if x_solution_end_index > (len(x_electron_state.static_potential) - 1): x_solution_end_index = len(x_electron_state.static_potential) - 1 x_electron_state.static_potential.meta_info['x_solution_start'] = int( x_solution_start_index) x_electron_state.static_potential.meta_info['x_solution_end'] = int( x_solution_end_index) middle_index = (int(x_solution_end_index) - int(x_solution_start_index)) / 2 middle_index -= (lattice_well_length.value + lattice_barrier_length.value) / 2 * DOTS_PER_NM x_electron_state.static_potential.meta_info['middle_index'] = int( middle_index) state.electron_states.append(x_electron_state) return state
def solve(self, E, solution_start): self._reset_to_default_units() E.convert_to(E.units_default) lattice_potential = spsc_data.Potential( self.potential[:self.well_start], self.potential.units) flat_lattice_potential = self._flatten_potential(lattice_potential) lattice_length = spsc_data.LengthValue( self.length.value * (len(flat_lattice_potential) - 1) / (len(self.potential) - 1), self.length.units) lattice_mass = spsc_data.MassArray( self.mass[:len(flat_lattice_potential)]) # Need this because the last point in the lattice potential is artificial, # and we need to keep the same mass as it was in the last point. lattice_mass.value[-1] = lattice_mass.value[-2] iteration = SolutionIterationFlatPotentialDiffMass( flat_lattice_potential, lattice_mass, lattice_length) lattice_solution = iteration.solve(E, solution_start) well_solution_start = (lattice_solution[0][-1], lattice_solution[1][-1]) well_potential = spsc_data.Potential( self.potential[self.well_start:self.well_end], self.potential.units) well_length = spsc_data.LengthValue( self.length.value * len(well_potential) / (len(self.potential) - 1), self.length.units) well_mass = spsc_data.MassValue(self.mass.value[self.well_start]) iteration = SolutionIterationRungeKutt(well_potential, well_mass, well_length) well_solution = iteration.solve(E, well_solution_start) N = len(self.potential) solution = (spsc_data.WaveFunction(np.zeros( (N, ))), spsc_data.WaveFunction(np.zeros((N, )))) solution[0][:len(lattice_solution[0])] = lattice_solution[0] solution[0][len(lattice_solution[0]) - 1:len(lattice_solution[0]) + len(well_solution[0]) - 1] = well_solution[0] solution[1][:len(lattice_solution[1])] = lattice_solution[1] solution[1][len(lattice_solution[1]) - 1:len(lattice_solution[1]) + len(well_solution[1]) - 1] = well_solution[1] return solution
def __init__(self, potential, mass, length): super(SolutionIterationSlopePotential, self).__init__(potential, mass, length) self.slope = spsc_data.ElectricFieldValue(0) self.x0 = spsc_data.LengthValue(0) self.eps0 = spsc_data.EnergyValue(0) self._reset_to_default_units() # Calculate slope energy_difference = self.potential[SolutionIterationSlopePotential.SLOPE_RESOLUTION_DOTS_NUM - 1] - \ self.potential[0] energy_difference = spsc_data.EnergyValue(energy_difference) voltage_difference = energy_difference.value / constants.e length_piece = self.length.value * ( SolutionIterationSlopePotential.SLOPE_RESOLUTION_DOTS_NUM - 1) / (len(self.potential) - 1) self.slope.value = voltage_difference / length_piece self.x0.value = np.power( constants.h_plank**2 / (2 * self.mass.value * constants.e * self.slope.value), float(1) / 3) self.eps0.value = constants.e * self.slope.value * self.x0.value
def __init__(self): self.electron_states = [] self.static_density = spsc_data.Density([]) self.density_potential = spsc_data.Potential([]) self.length = spsc_data.LengthValue(0)