using System; using ODE = Science.Mathematics.OrdinaryDifferentialEquation; namespace Science.Physics.QuantumMechanics { /// /// SchroedingerEquation for One Dimensional Space /// In units of hbar=m=1. /// public class SchroedingerEquation1D { public SchroedingerEquation1D() { } private int numberOfVariables = 5; private int numberOfParameters = 2; private double start = -10.0; private double end = 0.0; private double left = -9.0, right = 9.0; public double LeftBoundary { set{left = value;} } public double RightBoundary { set{right = value;} } private Science.Mathematics.Function.ToLastType potential; public Science.Mathematics.Function.ToLastType PotentialEnergy { set{potential=value;} } private double energyguess = 1.0; public double EnergyGuess { set{energyguess=value;} } private double slope = 1.0E-15; public double SlopeGuess { set{slope=value;} } private double[] waveFunctionX; public double[] WaveFunctionXCoordinate { get{return waveFunctionX;} } private double[] waveFunction; public double[] WaveFunction { get { return waveFunction; } } private double[] waveFunctionD; public double[] WaveFunctionDerivative { get { return waveFunctionD; } } private double energy; public double Energy { get{return energy;} } private bool ok; public bool SolvedQ { get { return ok; } } public void Solve() { start = (start < left ? start : left); start = (right < -start ? start : -right); Science.Mathematics.Function.ToLastType load = new Science.Mathematics.Function.ToLastType(ValuesAtStart); Science.Mathematics.Function.ToLastType score = new Science.Mathematics.Function.ToLastType(RestrictionOfContinium); ODE.BoundaryCondition bc = new ODE.BoundaryCondition(start,load,end,score); Science.Mathematics.Function.ToLastType func = new Science.Mathematics.Function.ToLastType(Derivs); ODE.EquationWithBoundaryCondition eq = new ODE.EquationWithBoundaryCondition(); eq.FirstDerivativeFunction = func; eq.Condition = bc; eq.HowMany = 20; double[] initialParameter = new Double[numberOfParameters]; initialParameter[0] = energyguess; initialParameter[1] = 0.0; eq.InitialGuess = initialParameter; eq.Solve(); if (Math.Abs((Convert.ToDouble(eq.Solution[1][eq.IndependentVariable.Count - 1]) + slope) / (Convert.ToDouble(eq.Solution[3][eq.IndependentVariable.Count - 1]) + slope) - 1.0) > 0.001 || Math.Abs((Convert.ToDouble(eq.Solution[2][eq.IndependentVariable.Count - 1]) + slope) / (Convert.ToDouble(eq.Solution[4][eq.IndependentVariable.Count - 1]) + slope) - 1.0) > 0.001) { ok = false; try { throw new Science.Error(); } catch (Science.Error e) { e.Write("Bad initial guess. Try again with modification."); } } else ok = true; waveFunctionX = new Double[eq.IndependentVariable.Count * 2]; waveFunction = new Double[eq.IndependentVariable.Count * 2]; waveFunctionD = new Double[eq.IndependentVariable.Count * 2]; for(int k = 0; k < eq.IndependentVariable.Count; k++) { waveFunctionX[k] = Convert.ToDouble(eq.IndependentVariable[k]); waveFunction[k] = Convert.ToDouble(eq.Solution[1][k]); waveFunctionD[k] = Convert.ToDouble(eq.Solution[2][k]); } for(int k = 0; k < eq.IndependentVariable.Count; k++) { waveFunctionX[eq.IndependentVariable.Count + k] = -1.0*Convert.ToDouble(eq.IndependentVariable[eq.IndependentVariable.Count-1-k]); waveFunction[eq.IndependentVariable.Count + k] = Convert.ToDouble(eq.Solution[3][eq.IndependentVariable.Count - 1 - k]); waveFunctionD[eq.IndependentVariable.Count + k] = Convert.ToDouble(eq.Solution[4][eq.IndependentVariable.Count - 1 - k]); } energy = Convert.ToDouble(eq.Solution[0][0]); } private double[] ValuesAtStart(double start, double[] p) { double[] y = new Double[numberOfVariables]; y[0] = p[0]; y[1] = 0.0; y[2] = slope; y[3] = 0.0; y[4] = y[2]*p[1]; return y; } private double[] RestrictionOfContinium(double end, double[] v, double[] p) { double[] f = new Double[numberOfParameters]; f[0] = v[1]-v[3]; f[1] = v[2]-v[4]; return f; } private double[] Derivs(double x, double[] y) // Schroedinger Equation in First Order { double[] dydx = new Double[y.Length]; dydx[0]=0.0; dydx[1]=y[2]; dydx[2]=2.0*(potential(x)*y[1]-y[0]*y[1]); dydx[3]=-y[4]; dydx[4]=-2.0*(potential(-x)*y[3]-y[0]*y[3]); return dydx; } } }