static void Calculate_1D_Band_Structure(Dictionary <string, object> inputs) { OneD_ThomasFermiPoisson.Experiment exp_init = new OneD_ThomasFermiPoisson.Experiment(); Console.WriteLine("Performing density dopent calculation"); Dictionary <string, object> inputs_init = new Dictionary <string, object>(); if ((int)(double)inputs["dim"] != 1) { inputs_init = inputs.Where(s => s.Key.ToLower().EndsWith("_1d")).ToDictionary(dict => dict.Key.Remove(dict.Key.Length - 3), dict => dict.Value); inputs_init.Add("BandStructure_File", inputs["BandStructure_File"]); inputs_init.Add("output_suffix", "_1d.dat"); inputs_init.Add("T", inputs["T"]); } else { inputs_init = inputs.Where(s => s.Key.ToLower().EndsWith("")).ToDictionary(dict => dict.Key, dict => dict.Value); } // Inputs_to_Dictionary.Add_Input_Parameters_to_Dictionary(ref inputs_init, "Input_Parameters_1D.txt"); exp_init.Initialise(inputs_init); exp_init.Run(); inputs.Add("Carrier_Density", exp_init.Carrier_Density); inputs.Add("Dopent_Density", exp_init.Dopent_Density); inputs.Add("Chemical_Potential", exp_init.Chemical_Potential); inputs.Add("nz_pot_1d", inputs_init["nz"]); inputs.Add("zmin_pot_1d", inputs_init["zmin"]); inputs.Add("zmax_pot_1d", inputs_init["zmax"]); // get the frozen out surface charge at 70K if (!inputs.ContainsKey("surface_charge")) { inputs.Add("surface_charge", exp_init.Surface_Charge(70.0)); } else { Console.WriteLine("Surface charge set from Input_Parameters.txt to " + ((double)inputs["surface_charge"]).ToString()); } Console.WriteLine("Calculated 1D density for dopents"); if ((int)(double)inputs["dim"] == 2) { // create a scaled data file containing the dopent density double scaling_factor = ((double)inputs["ny"] * (double)inputs["dy"]) / ((double)inputs["nz"] * (double)inputs["dz"]); Input_Band_Structure.Expand_BandStructure(exp_init.Dopent_Density, (int)(double)inputs["ny_1d"]).Spin_Summed_Data.Save_2D_Data("dens_2D_dopents.dat", (double)inputs["dy"] * ((double)inputs["ny"] + 2.0) / ((double)inputs["ny_1d"] - 1.0), scaling_factor * (double)inputs_init["dz"], -1.0 * (double)inputs["dy"] * ((double)inputs["ny"] + 2.0) / 2.0, scaling_factor * Geom_Tool.Get_Zmin(exp_init.Layers)); } else if ((int)(double)inputs["dim"] == 3) { // this is a scaled version for the dopents! double y_scaling = ((double)inputs["nx"] * (double)inputs["dx"]) / ((double)inputs["ny"] * (double)inputs["dy"]); double z_scaling = ((double)inputs["nx"] * (double)inputs["dx"]) / ((double)inputs["nz"] * (double)inputs["dz"]); // extract the dopent layer (leaving the top and bottom set to zero) int dopent_min = -1; int dopent_max = -2; ILayer dopent_layer = exp_init.Layers[0]; for (int i = 0; i < exp_init.Layers.Length; i++) { if (exp_init.Layers[i].Donor_Conc != 0.0 || exp_init.Layers[i].Acceptor_Conc != 0) { dopent_layer = exp_init.Layers[i]; dopent_min = (int)Math.Round((dopent_layer.Zmin - Geom_Tool.Get_Zmin(exp_init.Layers)) / (int)(double)inputs_init["dz"]); dopent_max = (int)Math.Round((dopent_layer.Zmax - Geom_Tool.Get_Zmin(exp_init.Layers)) / (int)(double)inputs_init["dz"]); } } Band_Data tmp_dop_dens_1D = new Band_Data(dopent_max - dopent_min, 0.0); for (int i = dopent_min + 1; i < dopent_max - 1; i++) { tmp_dop_dens_1D.vec[i - dopent_min] = exp_init.Dopent_Density.Spin_Summed_Data.vec[i]; } // and expand into the correct data structure Band_Data tmp_dop_dens = Input_Band_Structure.Expand_BandStructure(tmp_dop_dens_1D.vec, (int)(double)inputs["nx_1d"], (int)(double)inputs["ny_1d"]); tmp_dop_dens.Save_3D_Data("dens_3D_dopents.dat", (double)inputs["dx"] * ((double)inputs["nx"] + 1.0) / ((double)inputs["nx_1d"] - 1.0), y_scaling * (double)inputs["dy"] * ((double)inputs["ny"] + 1.0) / ((double)inputs["ny_1d"] - 1.0), z_scaling * (double)inputs["dz_1d"], -1.0 * (double)inputs["dx"] * ((double)inputs["nx"] + 1.0) / 2.0, -1.0 * y_scaling * (double)inputs["dy"] * ((double)inputs["ny"] + 1.0) / 2.0, z_scaling * dopent_layer.Zmin); Console.WriteLine("Saved 1D dopent density"); } }
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, dx_dens, dy_dens, dz_dens, nx_dens, ny_dens, nz_dens, xmin_dens, ymin_dens, zmin_dens) - chem_pot).Save_Data("bare_pot.dat"); 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); // ThreeD_ThomasFermiSolver dens_solv = new ThreeD_ThomasFermiSolver(this); //ThreeD_EffectiveBandSolver dft_solv = new ThreeD_EffectiveBandSolver(this); // TwoplusOneD_ThomasFermiSolver dft_solv = new TwoplusOneD_ThomasFermiSolver(this); bool converged = false; // start without dft if carrier density is empty if (no_dft || carrier_charge_density.Spin_Summed_Data.Min() == 0.0) { 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) //if(true) { 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.dat"); sw.WriteLine(boundary_conditions["surface"].ToString()); sw.Close(); // save eigen-energies /*DoubleVector energies = dft_solv.Get_EnergyLevels(layers, chem_pot); * StreamWriter sw_e = new StreamWriter("energies.dat"); * for (int i = 0; i < energies.Length; i++) * sw_e.WriteLine(energies[i]); * sw_e.Close();*/ dens_solv.Output(carrier_charge_density, "carrier_density.dat"); dens_solv.Output(carrier_charge_density - dens_solv.Get_ChargeDensity(layers, carrier_charge_density, dopent_charge_density, chem_pot), "density_error.dat"); (Input_Band_Structure.Get_BandStructure_Grid(layers, dx_dens, dy_dens, dz_dens, nx_dens, ny_dens, nz_dens, xmin_dens, ymin_dens, zmin_dens) - chem_pot).Save_Data("potential.dat"); 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.dat"); (Input_Band_Structure.Get_BandStructure_Grid(layers, dx_dens, dy_dens, dz_dens, nx_dens, ny_dens, nz_dens, xmin_dens, ymin_dens, zmin_dens) - chem_pot + pot_exc).Save_Data("pot_KS.dat"); // 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("carrier_density.dat"); File.Delete("charge_density.dat"); File.Delete("potential.dat"); File.Delete("lap.dat"); Close(dens_solv.Unit_Charge, converged, max_iterations); return(converged); }
static void Main(string[] args) { // set nmath license key CenterSpace.NMath.Core.NMathConfiguration.LicenseKey = License.NMath_License_Key; Console.WriteLine("Program starting"); Console.WriteLine("Loading input parameters from file"); Dictionary <string, object> inputs = new Dictionary <string, object>(); Inputs_to_Dictionary.Add_Input_Parameters_to_Dictionary(ref inputs, "Input_Parameters.txt"); Inputs_to_Dictionary.Add_Input_Parameters_to_Dictionary(ref inputs, "Solver_Config.txt"); Console.WriteLine("Input parameters loaded"); // read in the value of vsg to be used Console.WriteLine("Enter split gate voltage"); inputs["split_V"] = double.Parse(Console.ReadLine()); Console.WriteLine("Setting \"split_V\" to " + ((double)inputs["split_V"]).ToString() + "V"); // check to make sure it's negative if ((double)inputs["split_V"] > 0) { Console.WriteLine("\"split_V\" has been set positive at " + ((double)inputs["split_V"]).ToString() + "V. Are you sure you want to do this?"); Console.ReadKey(); } // temporarily, just set the output suffix to something boring inputs.Add("output_suffix", ".dat"); // initialise the band structure experiment Experiment exp = new Experiment(); OneD_ThomasFermiPoisson.Experiment exp_init = new OneD_ThomasFermiPoisson.Experiment(); Console.WriteLine("Performing density dopent calculation"); Dictionary <string, object> inputs_init = new Dictionary <string, object>(); inputs_init = inputs.Where(s => s.Key.ToLower().EndsWith("_1d")).ToDictionary(dict => dict.Key.Remove(dict.Key.Length - 3), dict => dict.Value); inputs_init.Add("BandStructure_File", inputs["BandStructure_File"]); inputs_init.Add("T", inputs["T"]); inputs_init.Add("output_suffix", "_1d.dat"); exp_init.Initialise(inputs_init); exp_init.Run(); inputs.Add("SpinResolved_Density", exp_init.Carrier_Density); inputs.Add("Dopent_Density", exp_init.Dopent_Density); inputs.Add("Chemical_Potential", exp_init.Chemical_Potential); inputs.Add("nz_pot_1d", inputs_init["nz"]); inputs.Add("zmin_pot_1d", inputs_init["zmin"]); inputs.Add("zmax_pot_1d", inputs_init["zmax"]); // get the frozen out surface charge at 70K if (!inputs.ContainsKey("surface_charge")) { inputs.Add("surface_charge", exp_init.Surface_Charge(70.0)); } else { Console.WriteLine("Surface charge set from Input_Parameters.txt to " + ((double)inputs["surface_charge"]).ToString()); } Console.WriteLine("Calculated 1D density for dopents"); // this is a scaled version for the dopents! double y_scaling = ((double)inputs["nx"] * (double)inputs["dx"]) / ((double)inputs["ny"] * (double)inputs["dy"]); double z_scaling = ((double)inputs["nx"] * (double)inputs["dx"]) / ((double)inputs["nz"] * (double)inputs["dz"]); // extract the dopent layer (leaving the top and bottom set to zero) int dopent_min = -1; int dopent_max = -2; ILayer dopent_layer = exp_init.Layers[0]; for (int i = 0; i < exp_init.Layers.Length; i++) { if (exp_init.Layers[i].Donor_Conc != 0.0 || exp_init.Layers[i].Acceptor_Conc != 0) { dopent_layer = exp_init.Layers[i]; dopent_min = (int)Math.Round((dopent_layer.Zmin - Geom_Tool.Get_Zmin(exp_init.Layers)) / (int)(double)inputs_init["dz"]); dopent_max = (int)Math.Round((dopent_layer.Zmax - Geom_Tool.Get_Zmin(exp_init.Layers)) / (int)(double)inputs_init["dz"]); } } Band_Data tmp_dop_dens_1D = new Band_Data(dopent_max - dopent_min, 0.0); for (int i = dopent_min + 1; i < dopent_max - 1; i++) { tmp_dop_dens_1D.vec[i - dopent_min] = exp_init.Dopent_Density.Spin_Summed_Data.vec[i]; } // and expand into the correct data structure Band_Data tmp_dop_dens = Input_Band_Structure.Expand_BandStructure(tmp_dop_dens_1D.vec, (int)(double)inputs["nx_1d"], (int)(double)inputs["ny_1d"]); tmp_dop_dens.Save_3D_Data("dens_3D_dopents.dat", (double)inputs["dx"] * ((double)inputs["nx"] + 1.0) / ((double)inputs["nx_1d"] - 1.0), y_scaling * (double)inputs["dy"] * ((double)inputs["ny"] + 1.0) / ((double)inputs["ny_1d"] - 1.0), z_scaling * (double)inputs["dz_1d"], -1.0 * (double)inputs["dx"] * ((double)inputs["nx"] + 1.0) / 2.0, -1.0 * y_scaling * (double)inputs["dy"] * ((double)inputs["ny"] + 1.0) / 2.0, z_scaling * dopent_layer.Zmin); Console.WriteLine("Saved 1D dopent density"); Console.WriteLine("Starting experiment"); exp.Initialise(inputs); Console.WriteLine("Experiment initialised"); exp.Run(); Console.WriteLine("Experiment complete"); }
static void Main(string[] args) { Console.WriteLine("Setting Centerspace key"); // set nmath license key CenterSpace.NMath.Core.NMathConfiguration.LicenseKey = License.NMath_License_Key; Console.WriteLine("Program starting"); Console.WriteLine("Loading input parameters from file"); Dictionary <string, object> inputs = new Dictionary <string, object>(); Inputs_to_Dictionary.Add_Input_Parameters_to_Dictionary(ref inputs, "Input_Parameters.txt"); Inputs_to_Dictionary.Add_Input_Parameters_to_Dictionary(ref inputs, "Solver_Config.txt"); Console.WriteLine("Input parameters loaded"); //////////////////////////////////////////////// // // EDITS FOR BATCH RUNS // //////////////////////////////////////////////// // read in the value of vsg to be used Console.WriteLine("Enter split gate voltage"); // inputs["split_V"] = double.Parse(Console.ReadLine()); int index = int.Parse(args[0]); int maxval = (int)(double)inputs["nVsg"]; int i1 = index % maxval; int i2 = (index - i1) / maxval; // split gate with bias // double v1 = -0.5 - 0.25 * (double)i1; // double v2 = -0.5 - 0.02 * (double)i2; // if (v1 + v2 < -2.2 || v1 < v2) // return; // inputs["split_V1"] = v1; // inputs["split_V2"] = v2; // inputs["voltages"] = "{" + v1.ToString() + ", " + v2.ToString() + "}"; // Console.WriteLine("Setting \"split_V1\" to " + ((double)inputs["split_V1"]).ToString() + "V"); // Console.WriteLine("Setting \"split_V2\" to " + ((double)inputs["split_V2"]).ToString() + "V"); // inputs["top_V"] = 0.0; // Console.WriteLine("Setting \"top_V\" to " + ((double)inputs["top_V"]).ToString() + "V"); // inputs["output_suffix"] = "_sg1" + ((double)inputs["split_V1"]).ToString("F2") + "_sg2" + ((double)inputs["split_V2"]).ToString("F2") + ".dat"; //top gated with constant side gate double v1 = (double)inputs["sg_init"] + (double)inputs["dVsg"] * (double)i1; inputs["split_V"] = v1; Console.WriteLine("Setting \"split_V\" to " + ((double)inputs["split_V"]).ToString() + "V"); inputs["top_V"] = (double)inputs["tg_init"] + (double)inputs["dVtg"] * (double)i2; Console.WriteLine("Setting \"top_V\" to " + ((double)inputs["top_V"]).ToString() + "V"); inputs["output_suffix"] = "_sg" + ((double)inputs["split_V"]).ToString("F3") + "_tg" + ((double)inputs["top_V"]).ToString("F3") + ".dat"; //////////////////////////////////////////////// inputs["voltages"] = "{" + v1.ToString() + ", " + v1.ToString() + "}"; // check to make sure it's negative if ((double)inputs["split_V"] > 0) { Console.WriteLine("\"split_V\" has been set positive at " + ((double)inputs["split_V"]).ToString() + "V. Are you sure you want to do this?"); Console.ReadKey(); } // initialise the band structure experiment Experiment exp = new Experiment(); OneD_ThomasFermiPoisson.Experiment exp_init = new OneD_ThomasFermiPoisson.Experiment(); // check if we should start from a precalculated density // consistency of band-structure, etc is the responsibility of the user... //if (!(bool)inputs["hot_start"]) { Console.WriteLine("Performing density dopent calculation"); Dictionary <string, object> inputs_init = new Dictionary <string, object>(); inputs_init = inputs.Where(s => s.Key.ToLower().EndsWith("_1d")).ToDictionary(dict => dict.Key.Remove(dict.Key.Length - 3), dict => dict.Value); inputs_init.Add("BandStructure_File", inputs["BandStructure_File"]); inputs_init.Add("T", inputs["T"]); // Inputs_to_Dictionary.Add_Input_Parameters_to_Dictionary(ref inputs_init, "Input_Parameters_1D.txt"); exp_init.Initialise(inputs_init); exp_init.Run(); inputs.Add("Carrier_Density", exp_init.Carrier_Density); inputs.Add("Dopent_Density", exp_init.Dopent_Density); inputs.Add("Chemical_Potential", exp_init.Chemical_Potential); inputs.Add("nz_pot_1d", inputs_init["nz"]); inputs.Add("zmin_pot_1d", inputs_init["zmin"]); inputs.Add("zmax_pot_1d", inputs_init["zmax"]); // get the frozen out surface charge at 70K if (!inputs.ContainsKey("surface_charge")) { inputs.Add("surface_charge", exp_init.Surface_Charge(70.0)); } else { Console.WriteLine("Surface charge set from Input_Parameters.txt to " + ((double)inputs["surface_charge"]).ToString()); } Console.WriteLine("Calculated 1D density for dopents"); //Input_Band_Structure.Expand_BandStructure(exp_init.Dopent_Density, (int)(double)inputs_init["ny_1d"]).Spin_Summed_Data.Save_2D_Data("dens_2D_dopents.dat", (double)inputs["dy"] * (double)inputs["ny"] / (double)inputs_init["ny_1d"], (double)inputs_init["dz"], -1.0 * (double)inputs["dy"] * (double)inputs["ny"] / 2.0, Geom_Tool.Get_Zmin(exp_init.Layers)); // this is a scaled version for the dopents! double scaling_factor = ((double)inputs["ny"] * (double)inputs["dy"]) / ((double)inputs["nz"] * (double)inputs["dz"]); Input_Band_Structure.Expand_BandStructure(exp_init.Dopent_Density, (int)(double)inputs["ny_1d"]).Spin_Summed_Data.Save_2D_Data("dens_2D_dopents.dat", (double)inputs["dy"] * ((double)inputs["ny"] + 2.0) / ((double)inputs["ny_1d"] - 1.0), scaling_factor * (double)inputs_init["dz"], -1.0 * (double)inputs["dy"] * ((double)inputs["ny"] + 2.0) / 2.0, scaling_factor * Geom_Tool.Get_Zmin(exp_init.Layers)); // Input_Band_Structure.Expand_BandStructure(exp_init.Carrier_Density, (int)(double)inputs_init["ny_1d"]).Spin_Summed_Data.Save_2D_Data("dens_2D.dat", (double)inputs["dy"] * ((double)inputs["ny"] + 2.0) / ((double)inputs_init["ny_1d"] - 1.0), (double)inputs_init["dz"], -1.0 * (double)inputs["dy"] * ((double)inputs["ny"] + 2.0) / 2.0, Geom_Tool.Get_Zmin(exp_init.Layers)); Console.WriteLine("Saved 1D dopent density"); } if ((bool)inputs["batch_run"]) { Run_Multiple_SGs(inputs); } else { Console.WriteLine("Starting experiment"); exp.Initialise(inputs); // check that the dz_pot are the same for both simulations as this is needed for the interpolation of SpinResolved_Density if (!(bool)inputs["hot_start"] && exp_init.Dz_Pot != exp.Dz_Pot) { throw new Exception("Error - the dz values for the potentials must be the same for \"Input_Parameters.txt\" and \"Input_Parameters_1D.txt\""); } Console.WriteLine("Experiment initialised"); exp.Run(); Console.WriteLine("Experiment complete"); } }
public override bool Run() { // get temperatures to run the experiment at double[] run_temps = Freeze_Out_Temperatures(); double target_temp = temperature; // run experiment using Thomas-Fermi solver for (int i = 0; i < run_temps.Length; i++) { current_temperature = run_temps[i]; this.temperature = current_temperature; if (surface_charge.ContainsKey(current_temperature)) { no_dft = false; continue; } OneD_ThomasFermiSolver dens_solv = new OneD_ThomasFermiSolver(this, Dz_Pot, Zmin_Pot, Nz_Pot); dens_solv.DFT_Mixing_Parameter = 0.0; if (!Geom_Tool.GetLayer(layers, zmin_pot).Dopents_Frozen_Out(current_temperature) && !fix_bottom_V) { boundary_conditions["bottom_V"] = dens_solv.Get_Chemical_Potential(zmin_pot, layers, current_temperature) / (Physics_Base.q_e * Physics_Base.energy_V_to_meVpzC); } // reset the converged flag for every temperature converged = false; if (dopents_calculated) { continue; } if (illuminated && i == run_temps.Length - 1) { for (int j = 0; j < dopent_charge_density.Spin_Summed_Data.Length - 1; j++) { double pos = Zmin_Pot + j * Dz_Pot; dopent_charge_density.Spin_Up[j] = 0.5 * Physics_Base.q_e * (Geom_Tool.GetLayer(layers, pos).Donor_Conc - Geom_Tool.GetLayer(layers, pos).Acceptor_Conc); dopent_charge_density.Spin_Down[j] = 0.5 * Physics_Base.q_e * (Geom_Tool.GetLayer(layers, pos).Donor_Conc - Geom_Tool.GetLayer(layers, pos).Acceptor_Conc); } } converged = Run_Iteration_Routine(dens_solv, pois_solv, tol, max_iterations); if (!converged) { temperature = target_temp; no_dft = true; return(converged); } // save the surface charge for this temperature surface_charge.Add(current_temperature, pois_solv.Get_Surface_Charge(chem_pot, layers)); pois_solv.Reset(); } if (!no_dft) { // reset the converged flag for the quantum calculation converged = false; // get the correct density solver IOneD_Density_Solve dft_solv; if (carrier_type == Carrier.electron || carrier_type == Carrier.hole) { dft_solv = new OneD_DFTSolver(this, carrier_type); } else if (carrier_type == Carrier.both) { dft_solv = new OneD_eh_DFTSolver(this); } else { throw new NotImplementedException(); } dft_solv.DFT_Mixing_Parameter = 1.0; //NOTE: This method doesn't mix in the DFT potential, it is stable enough when V_xc is calculated every iteration dft_solv.Zmin_Pot = zmin_pot; dft_solv.Dz_Pot = dz_pot; // and then run the DFT solver at the base temperature Console.WriteLine("Starting DFT calculation"); converged = Run_Iteration_Routine(dft_solv, pois_solv, tol, max_iterations); pois_solv.Reset(); (Input_Band_Structure.Get_BandStructure_Grid(layers, dz_pot, nz_pot, zmin_pot) - chem_pot).Save_Data("potential" + output_suffix); } // calculate the density of the negative and positive charges separately double neg_dens = (from val in carrier_charge_density.Spin_Summed_Data.vec where val < 0.0 select - 1.0e14 * val * dz_dens / Physics_Base.q_e).ToArray().Sum(); double pos_dens = (from val in carrier_charge_density.Spin_Summed_Data.vec where val > 0.0 select 1.0e14 * val * dz_dens / Physics_Base.q_e).ToArray().Sum(); double unit_charge = -1.0 * Physics_Base.q_e; if (pos_dens == 0.0) { Console.WriteLine("Electron carrier density at heterostructure interface: \t" + neg_dens.ToString("e3") + " cm^-2"); } else if (neg_dens == 0.0) { Console.WriteLine("Hole carrier density at heterostructure interface: \t" + pos_dens.ToString("e3") + " cm^-2"); unit_charge = Physics_Base.q_e; } else { Console.WriteLine("WARNING! Carriers of both charges found on the interface"); Console.WriteLine("Electron density at heterostructure interface: \t" + neg_dens.ToString("e3") + " cm^-2"); Console.WriteLine("Hole density at heterostructure interface: \t" + pos_dens.ToString("e3") + " cm^-2"); } // there is no iteration timeout for the 1D solver so if it gets to this point the solution will definitely have converged Close(unit_charge, converged, max_iterations); return(converged); }
private void step_button_Click(object sender, EventArgs e) { dimension = 1; conduction_band.Series["conduction_band_data"].Points.Clear(); conduction_band.Series["valence_band_data"].Points.Clear(); conduction_band.Series["x_data"].Points.Clear(); density.Series["car_dens_data"].Points.Clear(); density.Series["dop_dens_data"].Points.Clear(); density.Series["gphi_data"].Points.Clear(); int nz; int i = int.Parse(count_no_label.Text); if (!int.TryParse(nz1Dval.Text, out nz)) { MessageBox.Show("Format of Nz for dopent potential is invalid"); return; } // initialise dopent experiment if the count is zero if (i == 0) { exp1d = new OneD_ThomasFermiPoisson.Experiment(); car_dens = new SpinResolved_Data(nz); dop_dens = new SpinResolved_Data(nz); Dictionary <string, object> inputs_tmp = Create_Dictionary(); foreach (KeyValuePair <string, object> option in inputs_tmp) { inputs.Add(option.Key.Replace("_1d", ""), option.Value); } inputs["surface_charge"] = 0.0; inputs["max_iterations"] = 0.0; exp1d.Initialise(inputs); } converged = exp1d.Run(); ILayer[] layers = exp1d.Layers; double dz = exp1d.Dz_Pot; double zmin = exp1d.Zmin_Pot; car_dens = exp1d.Carrier_Density; dop_dens = exp1d.Dopent_Density; Band_Data x = Physics_Base.q_e * exp1d.X; Band_Data gphi = exp1d.GPhi; chem_pot = (Input_Band_Structure.Get_BandStructure_Grid(layers, dz, nz, zmin) - exp1d.Chemical_Potential); // + x); val_pot = (-1.0 * Input_Band_Structure.Get_BandStructure_Grid(layers, dz, nz, zmin) - exp1d.Chemical_Potential); // + x); for (int j = 0; j < chem_pot.Length; j++) { double pos = zmin + dz * j; conduction_band.Series["conduction_band_data"].Points.AddXY(pos, chem_pot[j]); conduction_band.Series["valence_band_data"].Points.AddXY(pos, val_pot[j]); conduction_band.Series["x_data"].Points.AddXY(pos, x[j]); density.Series["car_dens_data"].Points.AddXY(pos, car_dens.Spin_Summed_Data[j]); density.Series["dop_dens_data"].Points.AddXY(pos, dop_dens.Spin_Summed_Data[j]); density.Series["gphi_data"].Points.AddXY(pos, gphi[j]); } Set_Plot_Axes(dens_xmin_val.Text, dens_xmax_val.Text, density.ChartAreas["ChartArea1"].AxisX); Set_Plot_Axes(dens_ymin_val.Text, dens_ymax_val.Text, density.ChartAreas["ChartArea1"].AxisY); Set_Plot_Axes(pot_xmin_val.Text, pot_xmax_val.Text, conduction_band.ChartAreas["ChartArea1"].AxisX); Set_Plot_Axes(pot_ymin_val.Text, pot_ymax_val.Text, conduction_band.ChartAreas["ChartArea1"].AxisY); conduction_band.Refresh(); density.Refresh(); this.count_no_label.Text = (i + 1).ToString(); this.temperature_val_label.Text = exp1d.Current_Temperature.ToString() + " K"; this.carrier_dopent_density_Text.Text = (from val in car_dens.Spin_Summed_Data.vec where val < 0.0 select - 1.0e14 * val * dz / Physics_Base.q_e).ToArray().Sum().ToString("e3"); }