public bool IsStable() { foreach (double element in EigenValues.Real()) { if (element > 0) { return(false); } } return(true); }
/// <summary> /// 平行ビームの電子回折計算 /// </summary> /// <param name="maxNumOfBloch"></param> /// <param name="voltage"></param> /// <param name="rotation"></param> /// <param name="thickness"></param> /// <returns></returns> public Beam[] GetDifractedBeamAmpriltudes(int maxNumOfBloch, double voltage, Matrix3D rotation, double thickness) { var useEigen = !MathNet.Numerics.Control.TryUseNativeMKL(); if (AccVoltage != voltage) { uDictionary = new Dictionary <int, (Complex, Complex)>(); } //波数を計算 var k_vac = UniversalConstants.Convert.EnergyToElectronWaveNumber(voltage); //U0を計算 var u0 = getU(voltage, (0, 0, 0), 0).Real.Real; var vecK0 = getVecK0(k_vac, u0); if (MaxNumOfBloch != maxNumOfBloch || AccVoltage != voltage || EigenValues == null || EigenVectors == null || !rotation.Equals(BaseRotation)) { MaxNumOfBloch = maxNumOfBloch; AccVoltage = voltage; BaseRotation = new Matrix3D(rotation); Thickness = thickness; //計算対象のg-Vectorsを決める。 Beams = Find_gVectors(BaseRotation, vecK0); if (Beams == null || Beams.Length == 0) { return(new Beam[0]); } var potentialMatrix = getEigenProblemMatrix(Beams); //A行列に関する固有値、固有ベクトルを取得 if (useEigen) { (EigenValues, EigenVectors) = NativeWrapper.EigenSolver(potentialMatrix); } else { var evd = DMat.OfArray(potentialMatrix).Evd(Symmetricity.Asymmetric); EigenValues = evd.EigenValues.AsArray(); EigenVectors = (DMat)evd.EigenVectors; } //(EigenVectors, EigenValues) = RefineEigenProblem(DMat.OfArray(potentialMatrix), (DMat)evd.EigenVectors, evd.EigenValues.ToArray()); } int len = EigenValues.Count(); var psi0 = DVec.OfArray(new Complex[len]);//入射面での波動関数を定義 psi0[0] = 1; var alpha = EigenVectors.Inverse() * psi0;//アルファベクトルを求める //ガンマの対称行列×アルファを作成 var gamma_alpha = new DVec(Enumerable.Range(0, len).Select(n => Exp(TwoPiI * EigenValues[n] * thickness) * alpha[n]).ToArray()); //出射面での境界条件を考慮した位相にするため、以下の1行を追加 (20190827) var p = new DiagonalMatrix(len, len, Beams.Select(b => Exp(PiI * (b.P - 2 * k_vac * Surface.Z) * thickness)).ToArray()); //var p = new DiagonalMatrix(len, len, Beams.Select(b => new Complex(1, 0)).ToArray()); //深さZにおけるψを求める var psi_atZ = p * EigenVectors * gamma_alpha; for (int i = 0; i < Beams.Length && i < len; i++) { Beams[i].Psi = psi_atZ[i]; } return(Beams); }
// AD conversion functions private double CheckAliasing(double coeff = 0.1) { double lambda_max = EigenValues.AbsoluteMaximum().Magnitude; return(coeff / lambda_max); }