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