示例#1
0
    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
示例#2
0
    def solve(self, E, solution_start):
        self._reset_to_default_units()
        E.convert_to(E.units_default)
        N = len(self.potential)
        solution = (spsc_data.WaveFunction(np.zeros(
            (N, ))), spsc_data.WaveFunction(np.zeros((N, ))))
        solution[0][0] = solution_start[0]
        solution[1][0] = solution_start[1]
        h = 1.0 / (N - 1)
        h1 = h / 6
        for i in xrange(1, N):
            (k, q) = self._k_q(i, solution[0][i - 1], solution[1][i - 1], E)
            solution[0][i] = solution[0][i - 1] + h1 * (k[0] + 2 * k[1] +
                                                        2 * k[2] + k[3])
            solution[1][i] = solution[1][i - 1] + h1 * (q[0] + 2 * q[1] +
                                                        2 * q[2] + q[3])

        if len(solution_start) == 4:
            potential_turned = spsc_data.Potential(self.potential.value[::-1],
                                                   self.potential.units)
            iteration_turned = self.__class__(potential_turned, self.mass,
                                              self.length)
            solution_turned = iteration_turned.solve(
                E, (solution_start[2], solution_start[3]))
            reverse_solution = (spsc_data.WaveFunction(
                solution_turned[0].value[::-1]),
                                spsc_data.WaveFunction(
                                    solution_turned[1].value[::-1]))
            solution = (solution[0], solution[1], reverse_solution[0],
                        reverse_solution[1])

        return solution
示例#3
0
 def solve(self, E, solution_start):
     self._reset_to_default_units()
     E.convert_to(E.units_default)
     E = E.value
     N = len(self.potential)
     solution = (spsc_data.WaveFunction(np.zeros(
         (N, ))), spsc_data.WaveFunction(np.zeros((N, ))))
     gamma = 2.0 * (self.length.value**2) / (constants.h_plank**2)
     (A, B) = self._get_initial_AB(E, solution_start)
     potential_level = self.potential[0]
     for i in xrange(N):
         x = float(i) / (N - 1)
         if self.potential[i] != potential_level:
             AB_transition_matrix = self._get_AB_transition_matrix(E, i)
             (A, B) = np.dot(AB_transition_matrix, np.array([A, B]))
             potential_level = self.potential[i]
         if E < potential_level:
             k = np.sqrt((potential_level - E) * gamma * self.mass.value[i])
             solution[0][i] = A * np.exp(k * x) + B * np.exp(-k * x)
             solution[1][i] = A * k * np.exp(k * x) - B * k * np.exp(-k * x)
         else:
             k = np.sqrt((E - potential_level) * gamma * self.mass.value[i])
             solution[0][i] = A * np.sin(k * x) + B * np.cos(k * x)
             solution[1][i] = A * k * np.cos(k * x) - B * k * np.sin(k * x)
     return solution
示例#4
0
 def _prepare_wave_function(self, solution_candidate):
     middle_index = self._get_middle_index()
     k = solution_candidate[0][middle_index] / solution_candidate[2][
         middle_index]
     wave_function_arr = np.concatenate(
         (solution_candidate[0].value[:middle_index + 1],
          k * solution_candidate[2].value[middle_index + 1:]))
     wave_function = spsc_data.WaveFunction(wave_function_arr)
     wave_function.normalize()
     return wave_function
示例#5
0
    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
示例#6
0
    def solve(self, E, solution_start):
        self._reset_to_default_units()
        E.convert_to(E.units_default)
        N = len(self.potential)
        solution = (spsc_data.WaveFunction(np.zeros(
            (N, ))), spsc_data.WaveFunction(np.zeros(
                (N, ))), spsc_data.WaveFunction(np.zeros(
                    (N, ))), spsc_data.WaveFunction(np.zeros((N, ))))
        potential_threshold = abs(2.0 * constants.e * self.slope.value *
                                  self.length.value /
                                  (len(self.potential) - 1))

        (A, B) = self._get_initial_left_AB(E, solution_start[0],
                                           solution_start[1])
        U = self._get_U(0)
        U.convert_to("eV")
        for i in xrange(N * 2 / 3):
            if i > 0 and abs(self.potential[i] -
                             self.potential[i - 1]) > potential_threshold:
                (A, B) = self._get_AB(E, i - 1, i, solution[0][i - 1],
                                      solution[1][i - 1])
                U = self._get_U(i)
            airy_argument = self._get_airy_argument(E, U, i)
            airy = special.airy(airy_argument)
            solution[0][i] = A * airy[0] + B * airy[2]
            solution[1][i] = A * airy[1] + B * airy[3]

        (A, B) = self._get_initial_right_AB(E, solution_start[2],
                                            solution_start[3])
        U = self._get_U(N - 1)
        for i in xrange(N - 1, N / 3, -1):
            if i < N - 1 and abs(self.potential[i] -
                                 self.potential[i + 1]) > potential_threshold:
                (A, B) = self._get_AB(E, i + 1, i, solution[2][i + 1],
                                      solution[3][i + 1])
                U = self._get_U(i)
            airy_argument = self._get_airy_argument(E, U, i)
            airy = special.airy(airy_argument)
            solution[2][i] = A * airy[0] + B * airy[2]
            solution[3][i] = A * airy[1] + B * airy[3]
        return solution
示例#7
0
    def solve(self):
        symmetry_solver = LatticeSymmetrySolver(self.state)
        symmetry_solver.solve()

        # for j in xrange(5):
        #     self.__gamma_shrod()
        #     self.__x_shrod()
        #     self.state.density_potential = self.__solve_puass()

        E_start = spsc_data.EnergyValue(0.001, "eV")
        E_end = spsc_data.EnergyValue(0.3, "eV")
        dE = spsc_data.EnergyValue(0.0001, "eV")

        meta_info = self.state.electron_states[1].static_potential.meta_info
        self.state.electron_states[1].static_potential.convert_to('eV')
        self.state.density_potential.convert_to('eV')
        static_potential_arr = self.state.electron_states[
            1].static_potential.value[
                meta_info['x_solution_start']:meta_info['x_solution_end']]
        density_potential_arr = self.state.density_potential.value[
            meta_info['x_solution_start']:meta_info['x_solution_end']]

        potential_arr = static_potential_arr + density_potential_arr
        potential = spsc_data.Potential(potential_arr, "eV")
        potential_offset = spsc_data.EnergyValue(np.amin(potential_arr), 'eV')
        potential = potential - spsc_data.Potential(
            potential_offset.value * np.ones(
                (len(potential), ), "float64"), potential_offset.units)
        potential.meta_info = meta_info

        mass = self.state.electron_states[1].mass
        length = self.state.length
        iteration_factory = spsc_shrod.SolutionIterationRungeKuttFactory()
        solution_strategy = spsc_shrod.IterableSolutionStrategyNonSymmetricWell(
            E_start, E_end, dE, 1, iteration_factory)
        solutions = solution_strategy.solve(potential, mass, length,
                                            (10.0**-20, 0, 10.0**-25, 0))

        wave_function = solutions[0][1]
        zeros = np.zeros((len(self.state.density_potential), ))
        wave_function_full_arr = np.concatenate(
            (zeros[:meta_info['x_solution_start']], wave_function.value,
             zeros[meta_info['x_solution_end']:]))
        wave_function = spsc_data.WaveFunction(wave_function_full_arr)
        wave_function.mirror()
        wave_function.normalize()
        self.state.electron_states[1].wave_functions.append(wave_function)

        energy_level = solutions[0][0]
        energy_level = energy_level + potential_offset
        self.state.electron_states[1].energy_levels.append(energy_level)