Example #1
0
        public override bool Run()
        {
            if (!initialise_from_restart)
            {
                // calculate the bare potential
                Console.WriteLine("Calculating bare potential");
                chem_pot = Physics_Base.q_e * pois_solv.Get_Potential(0.0 * carrier_charge_density.Spin_Summed_Data);
                Console.WriteLine("Saving bare potential");
                (Input_Band_Structure.Get_BandStructure_Grid(layers, dy_dens, dz_dens, ny_dens, nz_dens, ymin_dens, zmin_dens) - chem_pot).Save_Data("bare_pot" + output_suffix);
                Console.WriteLine("Bare potential saved");

                // if the initial carrier density was not zero, recalculate the chemical potential
                if (carrier_charge_density.Spin_Summed_Data.Max() != 0.0 || carrier_charge_density.Spin_Summed_Data.Min() != 0.0)
                {
                    chem_pot = Physics_Base.q_e * pois_solv.Get_Potential(carrier_charge_density.Spin_Summed_Data);
                }
            }

            // get the dopent density from the Poisson equation
            dopent_charge_density.Spin_Up   = -0.5 * (chem_pot.Laplacian / Physics_Base.q_e + carrier_charge_density.Spin_Summed_Data);
            dopent_charge_density.Spin_Down = -0.5 * (chem_pot.Laplacian / Physics_Base.q_e + carrier_charge_density.Spin_Summed_Data);

            // and then run the DFT solver at the base temperature over a limited range
            //       TwoD_DFTSolver dft_solv = new TwoD_DFTSolver(this);
            //       TwoD_EffectiveBandSolver dft_solv = new TwoD_EffectiveBandSolver(this);
            //        TwoD_SO_DFTSolver dft_solv = new TwoD_SO_DFTSolver(this);
            //     dens_solv.Xmin_Pot = ymin_pot; dens_solv.Dx_Pot = dy_pot;
            //     dens_solv.Ymin_Pot = zmin_pot; dens_solv.Dy_Pot = dz_pot;
            //       TwoD_ThomasFermiSolver dft_solv = new TwoD_ThomasFermiSolver(this);

            // start without dft if carrier density is empty
            if (no_dft)
            {
                dens_solv.DFT_Mixing_Parameter = 0.0;
            }
            else
            {
                dens_solv.DFT_Mixing_Parameter = dft_mixing_parameter;
            }

            // do preliminary run to correct for initial discretised form of rho_prime
            if (initial_run)
            {
                converged = Run_Iteration_Routine(dens_solv, pois_solv, tol, initial_run_steps);
                // and calculate the potential given the density from this initial run
                pois_solv.Initiate_Poisson_Solver(device_dimensions, boundary_conditions);
                chem_pot = Physics_Base.q_e * pois_solv.Get_Potential(carrier_charge_density.Spin_Summed_Data);
            }
            if (!converged || !initial_run)
            {
                int count = 0;
                while (pot_init > tol_anneal && count < 20)
                {
                    if (count != 0)
                    {
                        pois_solv.Initiate_Poisson_Solver(device_dimensions, boundary_conditions);
                        chem_pot = Physics_Base.q_e * pois_solv.Get_Potential(carrier_charge_density.Spin_Summed_Data);
                    }

                    // run the iteration routine!
                    converged = Run_Iteration_Routine(dens_solv, pois_solv, tol, max_iterations);

                    count++;
                }
            }


            // save surface charge
            StreamWriter sw = new StreamWriter("surface_charge" + output_suffix); sw.WriteLine(boundary_conditions["surface"].ToString()); sw.Close();
            // save eigen-energies
            DoubleVector energies = dens_solv.Get_EnergyLevels(layers, chem_pot);
            StreamWriter sw_e     = new StreamWriter("energies" + output_suffix);

            for (int i = 0; i < energies.Length; i++)
            {
                sw_e.WriteLine(energies[i]);
            }
            sw_e.Close();

            //         dft_solv.Get_ChargeDensity(layers, carrier_density, dopent_density, chem_pot).Spin_Summed_Data.Save_Data("dens_2D_raw_calc.dat");
            (carrier_charge_density - dens_solv.Get_ChargeDensity(layers, carrier_charge_density, dopent_charge_density, chem_pot)).Spin_Summed_Data.Save_Data("density_error" + output_suffix);
            (Input_Band_Structure.Get_BandStructure_Grid(layers, dy_dens, dz_dens, ny_dens, nz_dens, ymin_dens, zmin_dens) - chem_pot).Save_Data("potential" + output_suffix);
            Band_Data pot_exc = dens_solv.DFT_diff(carrier_charge_density) + dens_solv.Get_XC_Potential(carrier_charge_density);

            pot_exc.Save_Data("xc_pot" + output_suffix);
            (Input_Band_Structure.Get_BandStructure_Grid(layers, dy_dens, dz_dens, ny_dens, nz_dens, ymin_dens, zmin_dens) - chem_pot + pot_exc).Save_Data("pot_KS" + output_suffix);
            //         Band_Data ks_ke = dft_solv.Get_KS_KE(layers, chem_pot);
            //         ks_ke.Save_Data("ks_ke.dat");

            // clean up intermediate data files
            //           File.Delete("phi.dat");
            //           File.Delete("new_phi.dat");
            //           File.Delete("x.dat");
            //           File.Delete("y.dat");
            //           File.Delete("gphi.dat");
            //           File.Delete("car_dens.dat");
            //           File.Delete("rho_prime.dat");
            //           File.Delete("xc_pot.dat");
            //           File.Delete("xc_pot_calc.dat");
            //           File.Delete("pot.dat");
            //           File.Delete("charge_density.dat");
            //           File.Delete("potential.dat");
            //           File.Delete("lap.dat");

            Close(dens_solv.Unit_Charge, converged, max_iterations);

            return(converged);
        }