public static double Solve()
        {
            a = 2;
            b = 4;
            Func <double, double> d = new Func <double, double>(ArcLength);
            OneVariableFunction   f = new OneVariableFunction(d);
            double x = f.Integrate(0, 2 * Math.PI);

            return(x);
        }
示例#2
0
        public double Get_Equilibrium_Chemical_Potential()
        {
            OneVariableFunction charge_func = new OneVariableFunction(new Func <double, double>(Get_ChargeDensity));

            // initialise root finder and search for a root for the chemical potential
            RiddersRootFinder finder = new RiddersRootFinder();
            double            result = finder.Find(charge_func, -1.0 * band_gap, band_gap);

            return(result);
        }
示例#3
0
        public static double Solve()
        {
            Func <double, double> d = new Func <double, double>(function);
            OneVariableFunction   f = new OneVariableFunction(d);
            double x         = f.Integrate(0, Math.PI / 2);
            double outVolume = -2 * Math.PI * x;
            double inVolume  = 4 * Math.PI * b * b * a / 3;

            return(outVolume - inVolume);
        }
示例#4
0
        double Interpolate_Fermi_Function_Derivative(DoubleHermitianEigDecomp eig_decomp_old, DoubleHermitianEigDecomp eig_decomp_new, int wavefunction)
        {
            double E0    = eig_decomp_old.EigenValue(wavefunction);
            double dE_dk = (eig_decomp_new.EigenValue(wavefunction) - eig_decomp_old.EigenValue(wavefunction)) / delta_k;

            double beta = 1.0 / (Physics_Base.kB * temperature);
            OneVariableFunction dos_integrand = new OneVariableFunction((Func <double, double>)((double k) => - 1.0 * beta * Math.Exp(beta * (E0 + dE_dk * k)) * Math.Pow(Math.Exp(beta * (E0 + dE_dk * k)) + 1, -2.0)));

            dos_integrand.Integrator = new GaussKronrodIntegrator();

            return(dos_integrand.Integrate(0, delta_k));
        }
示例#5
0
        /// <summary>
        /// calculates the density of electrons in the conduction band for a given chemical potential
        /// </summary>
        double Perform_Integral(Func <double, double> function, double lower_limit, double upper_limit)
        {
            if (chem_pot != double.MaxValue)
            {
                throw new Exception("Error - Something isn't reseting the chemical potential... this is very unsafe");
            }
            chem_pot = mu;

            // integrates the density for a given energy up to a given number of kB * T above the conduction band edge
            OneVariableFunction    integrand = new OneVariableFunction(function);
            GaussKronrodIntegrator tmp       = new GaussKronrodIntegrator();
            double result = tmp.Integrate(integrand, lower_limit, upper_limit);

            // reset chem_pot
            chem_pot = double.MaxValue;

            return(result);
        }
示例#6
0
 protected double Get_OneD_DoS_Deriv(double band_edge, double no_kb_T)
 {
     if (band_edge >= no_kb_T * Physics_Base.kB * temperature)
     {
         return(0.0);
     }
     else if (temperature == 0.0)
     {
         return(-1.0 * Math.Sqrt(-2.0 * mass / band_edge) / (Math.PI * Physics_Base.hbar));
     }
     else
     {
         // calculate the density of states integral directly
         double alpha = 2.0 * Math.Sqrt(2.0 * mass) / (Math.PI * Physics_Base.hbar * Physics_Base.kB * temperature);
         double beta  = 1.0 / (Physics_Base.kB * temperature);
         OneVariableFunction dos_integrand = new OneVariableFunction((Func <double, double>)((double E) => Math.Sqrt(E - band_edge) * Math.Exp(beta * E) * Math.Pow(Math.Exp(beta * E) + 1, -3.0) * (beta * (Math.Exp(beta * E) + 1) - 2.0 * beta * Math.Exp(beta * E))));
         return(Perform_DoS_Deriv_Integral(band_edge, no_kb_T, alpha, dos_integrand));
     }
 }
示例#7
0
        double Perform_DoS_Integral(double band_edge, double no_kb_T, double alpha, OneVariableFunction dos_integrand)
        {
            dos_integrand.Integrator = new GaussKronrodIntegrator();

            // check to see if the band edge is less than a large tolerance... it should be
            // physically, it is difficult for a band edge to dip far below the fermi surface as the charge flowing into the system should pin it
            // here, we use a value of 0.1eV... integral_tol should never be greater than 1.0eV as this is roughly the band gap and holes/electrons
            // should be induced
            double integral_lower = -100.0;

            if (band_edge > integral_lower)
            {
                integral_lower = band_edge;
            }

            double result = alpha * dos_integrand.Integrate(integral_lower, no_kb_T * Physics_Base.kB * temperature);

            return(result);
        }
示例#8
0
 protected double Get_TwoD_DoS(double band_edge, double no_kb_T)
 {
     if (band_edge >= no_kb_T * Physics_Base.kB * temperature)
     {
         return(0.0);
     }
     else if (temperature == 0.0)
     {
         return(-1.0 * band_edge * mass / (Physics_Base.hbar * Physics_Base.hbar * 2.0 * Math.PI));
     }
     else
     {
         // calculate the density of states integral directly
         double alpha = mass / (Physics_Base.hbar * Physics_Base.hbar * 2.0 * Math.PI);
         double beta  = 1.0 / (Physics_Base.kB * temperature);
         OneVariableFunction dos_integrand = new OneVariableFunction((Func <double, double>)((double E) => 1.0 / (Math.Exp(beta * E) + 1)));
         return(Perform_DoS_Integral(band_edge, no_kb_T, alpha, dos_integrand));
     }
 }
示例#9
0
 protected double Get_TwoD_DoS_Deriv(double band_edge, double no_kb_T)
 {
     if (band_edge >= no_kb_T * Physics_Base.kB * temperature)
     {
         return(0.0);
     }
     else if (temperature == 0.0)
     {
         return(mass / (Physics_Base.hbar * Physics_Base.hbar * 2.0 * Math.PI));
     }
     else
     {
         // calculate the derivative of the density of states integral directly
         // NOTE: The 2D DoS is constant so this is just the integral of the derivative of the Fermi function
         double alpha = mass / (Physics_Base.hbar * Physics_Base.hbar * 2.0 * Math.PI);
         double beta  = 1.0 / (Physics_Base.kB * temperature);
         OneVariableFunction dos_integrand = new OneVariableFunction((Func <double, double>)((double E) => beta * Math.Exp(beta * E) * Math.Pow(Math.Exp(beta * E) + 1, -2.0)));
         return(Perform_DoS_Deriv_Integral(band_edge, no_kb_T, alpha, dos_integrand));
     }
 }
示例#10
0
        /// <summary>
        /// calculates the density of electrons in the conduction band for a given chemical potential
        /// </summary>
        double Perform_Integral(Func<double, double> function, double lower_limit, double upper_limit)
        {
            if (chem_pot != double.MaxValue)
                throw new Exception("Error - Something isn't reseting the chemical potential... this is very unsafe");
            chem_pot = mu;

            // integrates the density for a given energy up to a given number of kB * T above the conduction band edge
            OneVariableFunction integrand = new OneVariableFunction(function);
            GaussKronrodIntegrator tmp = new GaussKronrodIntegrator();
            double result = tmp.Integrate(integrand, lower_limit, upper_limit);

            // reset chem_pot
            chem_pot = double.MaxValue;

            return result;
        }
示例#11
0
        public double Get_Equilibrium_Chemical_Potential()
        {
            OneVariableFunction charge_func = new OneVariableFunction(new Func<double, double>(Get_ChargeDensity));

            // initialise root finder and search for a root for the chemical potential
            RiddersRootFinder finder = new RiddersRootFinder();
            double result = finder.Find(charge_func, -1.0 * band_gap, band_gap);

            return result;
        }
示例#12
0
 protected double Get_TwoD_DoS_Deriv(double band_edge, double no_kb_T)
 {
     if (band_edge >= no_kb_T * Physics_Base.kB * temperature)
         return 0.0;
     else if (temperature == 0.0)
         return mass / (Physics_Base.hbar * Physics_Base.hbar * 2.0 * Math.PI);
     else
     {
         // calculate the derivative of the density of states integral directly
         // NOTE: The 2D DoS is constant so this is just the integral of the derivative of the Fermi function
         double alpha = mass / (Physics_Base.hbar * Physics_Base.hbar * 2.0 * Math.PI);
         double beta = 1.0 / (Physics_Base.kB * temperature);
         OneVariableFunction dos_integrand = new OneVariableFunction((Func<double, double>)((double E) => beta * Math.Exp(beta * E) * Math.Pow(Math.Exp(beta * E) + 1, -2.0)));
         return Perform_DoS_Deriv_Integral(band_edge, no_kb_T, alpha, dos_integrand);
     }
 }
示例#13
0
 protected double Get_TwoD_DoS(double band_edge, double no_kb_T)
 {
     if (band_edge >= no_kb_T * Physics_Base.kB * temperature)
         return 0.0;
     else if (temperature == 0.0)
         return -1.0 * band_edge * mass / (Physics_Base.hbar * Physics_Base.hbar * 2.0 * Math.PI);
     else
     {
         // calculate the density of states integral directly
         double alpha = mass / (Physics_Base.hbar * Physics_Base.hbar * 2.0 * Math.PI);
         double beta = 1.0 / (Physics_Base.kB * temperature);
         OneVariableFunction dos_integrand = new OneVariableFunction((Func<double, double>)((double E) => 1.0 / (Math.Exp(beta * E) + 1)));
         return Perform_DoS_Integral(band_edge, no_kb_T, alpha, dos_integrand);
     }
 }
示例#14
0
 protected double Get_OneD_DoS_Deriv(double band_edge, double no_kb_T)
 {
     if (band_edge >= no_kb_T * Physics_Base.kB * temperature)
         return 0.0;
     else if (temperature == 0.0)
         return -1.0 * Math.Sqrt(-2.0 * mass / band_edge) / (Math.PI * Physics_Base.hbar);
     else
     {
         // calculate the density of states integral directly
         double alpha = 2.0 * Math.Sqrt(2.0 * mass) / (Math.PI * Physics_Base.hbar * Physics_Base.kB * temperature);
         double beta = 1.0 / (Physics_Base.kB * temperature);
         OneVariableFunction dos_integrand = new OneVariableFunction((Func<double, double>)((double E) => Math.Sqrt(E - band_edge) * Math.Exp(beta * E) * Math.Pow(Math.Exp(beta * E) + 1, -3.0) * (beta * (Math.Exp(beta * E) + 1) - 2.0 * beta * Math.Exp(beta * E))));
         return Perform_DoS_Deriv_Integral(band_edge, no_kb_T, alpha, dos_integrand);
     }
 }
示例#15
0
        double Perform_DoS_Deriv_Integral(double band_edge, double no_kb_T, double alpha, OneVariableFunction dos_integrand)
        {
            dos_integrand.Integrator = new GaussKronrodIntegrator();

            if (band_edge < -1.0 * no_kb_T * Physics_Base.kB * temperature)
            {
                return(alpha * dos_integrand.Integrate(-1.0 * no_kb_T * Physics_Base.kB * temperature, no_kb_T * Physics_Base.kB * temperature));
            }
            else
            {
                return(alpha * dos_integrand.Integrate(band_edge, no_kb_T * Physics_Base.kB * temperature));
            }
        }
        /// <summary></summary>
        protected static void UpdateContinuousDistribution( ref ChartControl chart, ProbabilityDistribution dist, List<string> titles, DistributionFunction function, int numInterpolatedValues )
        {
            string xTitle = "x";
              string yTitle;

              double xmin = dist.InverseCDF( 0.0001 );
              double xmax = dist.InverseCDF( 0.9999 );

              OneVariableFunction f;

              if( function == DistributionFunction.PDF )
              {
            yTitle = "Probability Density Function";
            f = new OneVariableFunction( new Func<double, double> ( delegate( double x ) { return dist.PDF( x ); } ) );
              }
              else
              {
            yTitle = "Cumulative Distribution Function";
            f = new OneVariableFunction( new Func<double, double> ( delegate( double x ) { return dist.CDF( x ); } ) );
              }

              ChartSeries series = BindXY( f, xmin, xmax, numInterpolatedValues, ChartSeriesType.Line, ChartSymbolShape.None );

              Update( ref chart, series, titles, xTitle, yTitle );
        }
示例#17
0
        double Interpolate_Fermi_Function_Derivative(DoubleHermitianEigDecomp eig_decomp_old, DoubleHermitianEigDecomp eig_decomp_new, int wavefunction)
        {
            double E0 = eig_decomp_old.EigenValue(wavefunction);
            double dE_dk = (eig_decomp_new.EigenValue(wavefunction) - eig_decomp_old.EigenValue(wavefunction)) / delta_k;

            double beta = 1.0 / (Physics_Base.kB * temperature);
            OneVariableFunction dos_integrand = new OneVariableFunction((Func<double, double>)((double k) => -1.0 * beta * Math.Exp(beta * (E0 + dE_dk * k)) * Math.Pow(Math.Exp(beta * (E0 + dE_dk * k)) + 1, -2.0)));
            dos_integrand.Integrator = new GaussKronrodIntegrator();

            return dos_integrand.Integrate(0, delta_k);
        }
示例#18
0
        double Perform_DoS_Deriv_Integral(double band_edge, double no_kb_T, double alpha, OneVariableFunction dos_integrand)
        {
            dos_integrand.Integrator = new GaussKronrodIntegrator();

            if (band_edge < -1.0 * no_kb_T * Physics_Base.kB * temperature)
                return alpha * dos_integrand.Integrate(-1.0 * no_kb_T * Physics_Base.kB * temperature, no_kb_T * Physics_Base.kB * temperature);
            else
                return alpha * dos_integrand.Integrate(band_edge, no_kb_T * Physics_Base.kB * temperature);
        }
示例#19
0
        static void Main(string[] args)
        {
            //начало и конец отрезка
            double a = 0, b = 1;

            //число промежутков деления [a,b]
            int m = 100;

            double h = (b - a) / m;

            //N для пп. 3)+4)
            int N1 = 2;
            //N для п. 5)
            int N2 = 6;

            //для пп. 3)+4)
            double f1(double x)
            {
                //многочлен нулевой степени
                //return 1;
                //многочлен первой степени
                //return x;
                //многочлен третьей степени
                //return Math.Pow(x, 3);
                return(Math.Sin(x));
            }

            //для п. 5)
            double f2(double x)
            {
                return(Math.Cos(x));
            }

            //вес
            double r(double x)
            {
                return(Math.Pow(x, 0.25));
            }

            //первообразная
            double Rk(double x, int k)
            {
                return(Math.Pow(x, k + 1.25) / (k + 1.25));
            }

            Console.WriteLine("Приближённое вычисление интегралов при помощи квадратурных формул\n" +
                              "Наивысшей Алгебраической Степени Точности");
            Console.WriteLine("Вариант №2\n");
            Console.WriteLine("[a, b] = [{0}, {1}], m = {2}", a, b, m);
            Console.WriteLine("Хотите изменить параметры задачи?");
            string answ = Console.ReadLine();

            if (answ == "y")
            {
                Console.WriteLine("Введите параметр a:");
                a = Convert.ToDouble(Console.ReadLine());
                Console.WriteLine("Введите параметр b:");
                b = Convert.ToDouble(Console.ReadLine());
                Console.WriteLine("Введите параметр m:");
                m = Convert.ToInt32(Console.ReadLine());
                Console.WriteLine("Успешно изменёны!\n");
            }

            h = (b - a) / m;

            OneVariableFunction F1 = new OneVariableFunction(x => f1(x) * r(x));
            double J1              = F1.Integrate(a, b);
            double J1_real         = 0.406538;
            OneVariableFunction F2 = new OneVariableFunction(x => f2(x) * (1 / Math.Sqrt(1 - x * x)));
            double J2              = F2.Integrate(-1, 1);
            double J2_real         = 2.4039394306344129982733248925915112237;

            Console.WriteLine("________________________________________________________________________________________________");
            Console.WriteLine("\nf(x) = sin(x)");
            Console.WriteLine("r(x) = x^(1/4)");
            Console.WriteLine("N = {0}", N1);

            double JcompoundQFGauss = compoundQFGauss(N1, m, a, b, h);

            Console.WriteLine("\nСоставная КФ Гаусса с {0} узлами: {1}", N1, JcompoundQFGauss);
            if (!Double.IsNaN(J1))
            {
                Console.WriteLine("Библиотека NMath {0}", Math.Abs(JcompoundQFGauss - J1));
            }
            if (a == 0 && b == 1)
            {
                Console.WriteLine("Wolfram Alpha {0}", Math.Abs(JcompoundQFGauss - J1_real));
            }
            Console.WriteLine("________________________________________________________________________________________________");

            double JQFtypeGauss = QFtypeGauss(N1, a, b);

            Console.WriteLine("\nКФ типа Гаусса с {0} узлами: {1}", N1, JQFtypeGauss);
            if (!Double.IsNaN(J1))
            {
                Console.WriteLine("Библиотека NMath {0}", Math.Abs(JQFtypeGauss - J1));
            }
            if (a == 0 && b == 1)
            {
                Console.WriteLine("Wolfram Alpha {0}", Math.Abs(JQFtypeGauss - J1_real));
            }
            Console.WriteLine("________________________________________________________________________________________________");

            Console.WriteLine("\nКвадратурная формула Мелера");
            Console.WriteLine("\nf(x) = cos(x)");
            Console.WriteLine("r(x) = 1/sqrt(1-x^2)");
            Console.WriteLine("[a, b] = [-1, 1], N = {0}", N2);
            Console.WriteLine("Хотите изменить параметр N для КФ Мелера?");
            answ = Console.ReadLine();
            if (answ == "y")
            {
                Console.WriteLine("Введите параметр N:");
                N2 = Convert.ToInt32(Console.ReadLine());
                Console.WriteLine("Успешно изменён\n");
            }

            double JMehler = Mehler(N2);

            Console.WriteLine("\nКвадратурная формула Мелера с {0} узлами по [a, b] = [-1; 1]: {1}", N2, JMehler);
            if (!Double.IsNaN(J2))
            {
                Console.WriteLine("Библиотека NMath {0}", Math.Abs(JMehler - J2));
            }
            Console.WriteLine("Wolfram Alpha {0}", Math.Abs(JMehler - J2_real));


            double compoundQFGauss(int N, int M, double A, double B, double H)
            {
                double res = 0;
                double z   = A;
                double t1  = 1 / Math.Sqrt(3);
                double t2  = -1 / Math.Sqrt(3);
                double x1  = 0;
                double x2  = 0;

                for (int i = 0; i < M; i++)
                {
                    x1   = (t1 + 1) * H / 2 + z;
                    x2   = (t2 + 1) * H / 2 + z;
                    res += f1(x1) * r(x1) + f1(x2) * r(x2);
                    z   += H;
                }
                res *= H / 2;
                return(res);
            }

            double QFtypeGauss(int N, double A, double B)
            {
                Console.WriteLine("\nКФ типа Гаусса с {0} узлами", N1);

                double [] mu = new double[2 * N];

                Console.WriteLine("\nМоменты весовой функции");
                for (int i = 0; i < mu.Length; i++)
                {
                    mu[i] = Rk(B, i) - Rk(A, i);
                    Console.WriteLine("μ{0} = {1}", i, mu[i]);
                }

                double a1 = (mu[0] * mu[3] - mu[2] * mu[1]) / (mu[1] * mu[1] - mu[2] * mu[0]);
                double a2 = (mu[2] * mu[2] - mu[3] * mu[1]) / (mu[1] * mu[1] - mu[2] * mu[0]);

                Console.WriteLine("\nОртогональный многочлен x^2+{0}x+{1}=0\n", a1, a2);
                //корни уравнения
                double x1 = (-a1 + Math.Sqrt(a1 * a1 - 4 * a2)) / 2;
                double x2 = (-a1 - Math.Sqrt(a1 * a1 - 4 * a2)) / 2;

                Console.WriteLine("Узлы КФ: x1 = {0}, x2 = {1}", x1, x2);

                if (x1 != x2 && x1 > A && x1 < B && x2 > A && x2 < B)
                {
                    Console.WriteLine("Различны и принадлежат (a, b).");
                }
                else
                {
                    Console.WriteLine("Узлаы не различны и/или не принадлежат (a, b).");
                }

                double A1 = (mu[1] - x2 * mu[0]) / (x1 - x2);
                double A2 = (mu[1] - x1 * mu[0]) / (x2 - x1);

                Console.WriteLine("\nКоэффициенты КФ: A1 = {0}, A2 = {1}", A1, A2);

                if (A1 + A2 - mu[0] < 1E-10 && A1 * A2 > 0)
                {
                    Console.WriteLine("Коэффициенты одного знака и A1 + A2 = μ0.");
                }

                double JGauss = A1 * f1(x1) + A2 * f1(x2);

                return(JGauss);
            }

            double Mehler(int N)
            {
                double res = 0;

                for (int k = 1; k <= N; k++)
                {
                    res += f2(Math.Cos((2 * k - 1) * Math.PI / (2 * N)));
                    Console.WriteLine(Math.Cos((2 * k - 1) * Math.PI / (2 * N)));
                }

                res *= Math.PI / N;
                return(res);
            }
        }
示例#20
0
        double Perform_DoS_Integral(double band_edge, double no_kb_T, double alpha, OneVariableFunction dos_integrand)
        {
            dos_integrand.Integrator = new GaussKronrodIntegrator();

            // check to see if the band edge is less than a large tolerance... it should be
            // physically, it is difficult for a band edge to dip far below the fermi surface as the charge flowing into the system should pin it
            // here, we use a value of 0.1eV... integral_tol should never be greater than 1.0eV as this is roughly the band gap and holes/electrons
            // should be induced
            double integral_lower = -100.0;
            if (band_edge > integral_lower)
                integral_lower = band_edge;

            double result = alpha * dos_integrand.Integrate(integral_lower, no_kb_T * Physics_Base.kB * temperature);
            return result;
        }