Beispiel #1
0
        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;
        }
Beispiel #2
0
        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);
        }