Пример #1
0
 public bool IsStable()
 {
     foreach (double element in EigenValues.Real())
     {
         if (element > 0)
         {
             return(false);
         }
     }
     return(true);
 }
Пример #2
0
        /// <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);
        }
Пример #3
0
        // AD conversion functions
        private double CheckAliasing(double coeff = 0.1)
        {
            double lambda_max = EigenValues.AbsoluteMaximum().Magnitude;

            return(coeff / lambda_max);
        }