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); }