コード例 #1
0
        /// <summary>
        /// Generates a laplacian matrix in one-dimension on a regular grid with Dirichlet BCs wot varying permitivity
        /// </summary>
        DoubleTriDiagMatrix Generate_Laplacian(ILayer[] layers)
        {
            DoubleTriDiagMatrix result = new DoubleTriDiagMatrix(exp.Nz_Pot, exp.Nz_Pot);
            double factor_plus, factor_minus;

            // cycle through the structure and fill in the Laplacian with the correct permittivities
            for (int i = 1; i < exp.Nz_Pot - 1; i++)
            {
                double eps_plus  = Geom_Tool.GetLayer(layers, i * exp.Dz_Pot + 0.5 * exp.Dz_Pot + exp.Zmin_Pot).Permitivity;
                double eps_minus = Geom_Tool.GetLayer(layers, i * exp.Dz_Pot - 0.5 * exp.Dz_Pot + exp.Zmin_Pot).Permitivity;

                // the factor which multiplies the Laplace equation
                factor_plus  = eps_plus / (exp.Dz_Pot * exp.Dz_Pot);
                factor_minus = eps_minus / (exp.Dz_Pot * exp.Dz_Pot);

                // on-diagonal term
                result[i, i] = -1.0 * factor_minus + -1.0 * factor_plus;
                // off-diagonal
                result[i, i - 1] = 1.0 * factor_minus;
                result[i, i + 1] = 1.0 * factor_plus;
            }

            // and fix boundary conditions
            double factor = Geom_Tool.GetLayer(layers, exp.Zmin_Pot).Permitivity / (exp.Dz_Pot * exp.Dz_Pot);

            result[0, 0] = 1.0 * factor;
            result[0, 1] = 0.0;
            factor       = Geom_Tool.GetLayer(layers, (exp.Nz_Pot - 1) * exp.Dz_Pot + exp.Zmin_Pot).Permitivity / (exp.Dz_Pot * exp.Dz_Pot);
            result[exp.Nz_Pot - 1, exp.Nz_Pot - 1] = 1.0 * factor;
            result[exp.Nz_Pot - 1, exp.Nz_Pot - 2] = 0.0;

            return(result);
        }
コード例 #2
0
        public override Band_Data Calculate_Newton_Step(SpinResolved_Data rho_prime, Band_Data g_phi)
        {
            DoubleTriDiagMatrix lap_mat = -1.0 * Generate_Laplacian(exp.Layers);
            Band_Data           rho_prime_spin_summed = rho_prime.Spin_Summed_Data;

            // check that lap_mat and rho_prime have the same dimension
            if (rho_prime_spin_summed.Length != lap_mat.Rows)
            {
                throw new Exception("Error - the Laplacian generated by pois_solv has a different order to rho_prime!");
            }

            for (int i = 0; i < rho_prime_spin_summed.Length; i++)
            {
                lap_mat[i, i] -= rho_prime_spin_summed.vec[i];
            }

            DoubleTriDiagFact lu_newt_step = new DoubleTriDiagFact(lap_mat);

            // calculate newton step and its laplacian
            Band_Data result = new Band_Data(lu_newt_step.Solve(-1.0 * g_phi.vec));

            result.Laplacian = Calculate_Phi_Laplacian(result);

            return(result);
        }
コード例 #3
0
        public OneD_PoissonSolver(Experiment exp, bool using_external_code, Dictionary<string, object> input)
            : base(using_external_code)
        {
            this.exp = exp;

            // generate Laplacian matrix (spin-resolved)
            if (!using_external_code)
            {
                laplacian = Generate_Laplacian(exp.Layers);
                lu_fact = new DoubleTriDiagFact(laplacian);
            }
        }
コード例 #4
0
        public OneD_PoissonSolver(Experiment exp, bool using_external_code, Dictionary <string, object> input)
            : base(using_external_code)
        {
            this.exp = exp;

            // generate Laplacian matrix (spin-resolved)
            if (!using_external_code)
            {
                laplacian = Generate_Laplacian(exp.Layers);
                lu_fact   = new DoubleTriDiagFact(laplacian);
            }
        }
コード例 #5
0
        /// <summary>
        /// Generates a laplacian matrix in one-dimension on a regular grid with Dirichlet BCs wot varying permitivity
        /// </summary>
        DoubleTriDiagMatrix Generate_Laplacian(ILayer[] layers)
        {
            DoubleTriDiagMatrix result = new DoubleTriDiagMatrix(exp.Nz_Pot, exp.Nz_Pot);
            double factor_plus, factor_minus;

            // cycle through the structure and fill in the Laplacian with the correct permittivities
            for (int i = 1; i < exp.Nz_Pot - 1; i++)
            {
                double eps_plus = Geom_Tool.GetLayer(layers, i * exp.Dz_Pot + 0.5 * exp.Dz_Pot + exp.Zmin_Pot).Permitivity;
                double eps_minus = Geom_Tool.GetLayer(layers, i * exp.Dz_Pot - 0.5 * exp.Dz_Pot + exp.Zmin_Pot).Permitivity;

                // the factor which multiplies the Laplace equation
                factor_plus = eps_plus / (exp.Dz_Pot * exp.Dz_Pot);
                factor_minus = eps_minus / (exp.Dz_Pot * exp.Dz_Pot);

                // on-diagonal term
                result[i, i] = -1.0 * factor_minus + -1.0 * factor_plus;
                // off-diagonal
                result[i, i - 1] = 1.0 * factor_minus;
                result[i, i + 1] = 1.0 * factor_plus;
            }

            // and fix boundary conditions
            double factor = Geom_Tool.GetLayer(layers, exp.Zmin_Pot).Permitivity / (exp.Dz_Pot * exp.Dz_Pot);
            result[0, 0] = 1.0 * factor;
            result[0, 1] = 0.0;
            factor = Geom_Tool.GetLayer(layers, (exp.Nz_Pot - 1) * exp.Dz_Pot + exp.Zmin_Pot).Permitivity / (exp.Dz_Pot * exp.Dz_Pot);
            result[exp.Nz_Pot - 1, exp.Nz_Pot - 1] = 1.0 * factor;
            result[exp.Nz_Pot - 1, exp.Nz_Pot - 2] = 0.0;

            return result;
        }
コード例 #6
0
        //       protected override Band_Data Get_ChemPot_From_External(Band_Data density)
        //       {
        //           Save_Data(density, dens_filename);
        //
        //           return Get_Data_From_External(flexpde_script, initcalc_result_filename);
        //       }

        /// <summary>
        /// Calculates the Laplacian for the given band structure of the input potential
        /// ie. returns d(eps * d(input))
        /// NOTE: the input should be a potential so make sure you divide all band energies by q_e
        /// </summary>
        public Band_Data Calculate_Phi_Laplacian(Band_Data input)
        {
            DoubleTriDiagMatrix lap_mat = Generate_Laplacian(exp.Layers);

            return(new Band_Data(MatrixFunctions.Product(lap_mat, input.vec)));
        }