示例#1
0
        ////////////////////////////////////////////////////////////////////////////////////////
        // Φ = φexp(-jβx)と置く方法(SVEA)
        private static void solveSVEAAsQuadraticGeneralizedEigenToStandardWithRealMat(
            int incidentModeIndex,
            double k0,
            double[] KMat0,
            double[] CMat0,
            double[] MMat0,
            bool isPortBc2Reverse,
            int nodeCntPeriodic,
            int freeNodeCntPeriodic_0,
            int freeNodeCnt,
            int nodeCntBPeriodic,
            IList<int> sortedNodesPeriodic,
            Dictionary<int, int> toSortedPeriodic,
            Dictionary<int, int> toNodePeriodic,
            Dictionary<int, int> toNodePeriodicB1,
            IList<int> defectNodePeriodic,
            bool isModeTrace,
            ref KrdLab.clapack.Complex[] PrevModalVec,
            double minBeta,
            double maxBeta,
            double betaNormalizingFactor,
            out KrdLab.clapack.Complex[] betamToSolveList,
            out KrdLab.clapack.Complex[][] resVecList)
        {
            betamToSolveList = null;
            resVecList = null;

            double[] KMat = new double[freeNodeCnt * freeNodeCnt];
            double[] CMat = new double[freeNodeCnt * freeNodeCnt];
            double[] MMat = new double[freeNodeCnt * freeNodeCnt];
            for (int i = 0; i < freeNodeCnt; i++)
            {
                for (int j = 0; j < freeNodeCnt; j++)
                {
                    KMat[i + freeNodeCnt * j] = KMat0[i + freeNodeCntPeriodic_0 * j];
                    CMat[i + freeNodeCnt * j] = CMat0[i + freeNodeCntPeriodic_0 * j];
                    MMat[i + freeNodeCnt * j] = MMat0[i + freeNodeCntPeriodic_0 * j];
                }
            }
            for (int i = 0; i < freeNodeCnt; i++)
            {
                for (int j = 0; j < nodeCntBPeriodic; j++)
                {
                    int jno_B2 = isPortBc2Reverse ? (int)(freeNodeCnt + nodeCntBPeriodic - 1 - j) : (int)(freeNodeCnt + j);
                    KMat[i + freeNodeCnt * j] += KMat0[i + freeNodeCntPeriodic_0 * jno_B2];
                    CMat[i + freeNodeCnt * j] += CMat0[i + freeNodeCntPeriodic_0 * jno_B2];
                    MMat[i + freeNodeCnt * j] += MMat0[i + freeNodeCntPeriodic_0 * jno_B2];
                }
            }
            for (int i = 0; i < nodeCntBPeriodic; i++)
            {
                for (int j = 0; j < freeNodeCnt; j++)
                {
                    int ino_B2 = isPortBc2Reverse ? (int)(freeNodeCnt + nodeCntBPeriodic - 1 - i) : (int)(freeNodeCnt + i);
                    KMat[i + freeNodeCnt * j] += KMat0[ino_B2 + freeNodeCntPeriodic_0 * j];
                    CMat[i + freeNodeCnt * j] += CMat0[ino_B2 + freeNodeCntPeriodic_0 * j];
                    MMat[i + freeNodeCnt * j] += MMat0[ino_B2 + freeNodeCntPeriodic_0 * j];
                }
                for (int j = 0; j < nodeCntBPeriodic; j++)
                {
                    int ino_B2 = isPortBc2Reverse ? (int)(freeNodeCnt + nodeCntBPeriodic - 1 - i) : (int)(freeNodeCnt + i);
                    int jno_B2 = isPortBc2Reverse ? (int)(freeNodeCnt + nodeCntBPeriodic - 1 - j) : (int)(freeNodeCnt + j);
                    KMat[i + freeNodeCnt * j] += KMat0[ino_B2 + freeNodeCntPeriodic_0 * jno_B2];
                    CMat[i + freeNodeCnt * j] += CMat0[ino_B2 + freeNodeCntPeriodic_0 * jno_B2];
                    MMat[i + freeNodeCnt * j] += MMat0[ino_B2 + freeNodeCntPeriodic_0 * jno_B2];
                }
            }
            // 行列要素check
            {
                for (int i = 0; i < freeNodeCnt; i++)
                {
                    for (int j = i; j < freeNodeCnt; j++)
                    {
                        // [K]は対称行列
                        System.Diagnostics.Debug.Assert(Math.Abs(KMat[i + freeNodeCnt * j] - KMat[j + freeNodeCnt * i]) < Constants.PrecisionLowerLimit);
                        // [M]は対称行列
                        System.Diagnostics.Debug.Assert(Math.Abs(MMat[i + freeNodeCnt * j] - MMat[j + freeNodeCnt * i]) < Constants.PrecisionLowerLimit);
                        // [C]は反対称行列
                        System.Diagnostics.Debug.Assert(Math.Abs((-CMat[i + freeNodeCnt * j]) - CMat[j + freeNodeCnt * i]) < Constants.PrecisionLowerLimit);
                    }
                }
            }

            // 非線形固有値問題
            //  { [K] - jβ[C] - β^2[M] }{Φ}= {0}
            //  λ= - jβとおくと
            //  [K] + λ[C] + λ^2[M]{Φ}= {0}
            //
            // Lisys(Lapack)による固有値解析
            // マトリクスサイズは、強制境界及び境界3を除いたサイズ
            int matLen = (int)freeNodeCnt;
            KrdLab.clapack.Complex[] evals = null;
            KrdLab.clapack.Complex[,] evecs = null;

            // [M]の逆行列が存在する緩慢変化包絡線近似の場合のみ有効な方法
            //   Φを直接解く場合は使えない
            System.Diagnostics.Debug.WriteLine("calc [M]-1");
            // [M]の逆行列を求める
            double[] invMMat = MyUtilLib.Matrix.MyMatrixUtil.matrix_Inverse(MMat, matLen);
            System.Diagnostics.Debug.WriteLine("calc [M]-1[K]");
            // [M]-1[K]
            double[] invMKMat = MyUtilLib.Matrix.MyMatrixUtil.product(invMMat, matLen, matLen, KMat, matLen, matLen);
            System.Diagnostics.Debug.WriteLine("calc [M]-1[C]");
            // [M]-1[C]
            double[] invMCMat = MyUtilLib.Matrix.MyMatrixUtil.product(invMMat, matLen, matLen, CMat, matLen, matLen);

            // 標準固有値解析(実行列として解く)
            double[] A = new double[(matLen * 2) * (matLen * 2)];
            System.Diagnostics.Debug.WriteLine("set [A]");
            for (int i = 0; i < matLen; i++)
            {
                for (int j = 0; j < matLen; j++)
                {
                    A[i + j * (matLen * 2)] = 0.0;
                    A[i + (j + matLen) * (matLen * 2)] = (i == j) ? 1.0 : 0.0;
                    //  { [K] - jβ[C] - β^2[M] }{Φ}= {0}
                    // λ = -jβと置いた場合
                    //A[(i + matLen) + j * (matLen * 2)] = -1.0 * invMKMat[i + j * matLen];
                    //A[(i + matLen) + (j + matLen) * (matLen * 2)] = -1.0 * invMCMat[i + j * matLen];
                    // λ = -j(β/k0)と置いた場合
                    //A[(i + matLen) + j * (matLen * 2)] = -1.0 * invMKMat[i + j * matLen] / (k0 * k0);
                    //A[(i + matLen) + (j + matLen) * (matLen * 2)] = -1.0 * invMCMat[i + j * matLen] / (k0);
                    // λ = -j(β/betaNormalizingFactor)と置いた場合
                    A[(i + matLen) + j * (matLen * 2)] = -1.0 * invMKMat[i + j * matLen] / (betaNormalizingFactor * betaNormalizingFactor);
                    A[(i + matLen) + (j + matLen) * (matLen * 2)] = -1.0 * invMCMat[i + j * matLen] / (betaNormalizingFactor);
                }
            }
            double[] ret_r_evals = null;
            double[] ret_i_evals = null;
            double[][] ret_r_evecs = null;
            double[][] ret_i_evecs = null;
            System.Diagnostics.Debug.WriteLine("KrdLab.clapack.FunctionExt.dgeev");
            KrdLab.clapack.FunctionExt.dgeev(A, (matLen * 2), (matLen * 2), ref ret_r_evals, ref ret_i_evals, ref ret_r_evecs, ref ret_i_evecs);

            evals = new KrdLab.clapack.Complex[ret_r_evals.Length];
            // βを格納
            for (int i = 0; i < ret_r_evals.Length; i++)
            {
                KrdLab.clapack.Complex eval = new KrdLab.clapack.Complex(ret_r_evals[i], ret_i_evals[i]);
                //  { [K] - jβ[C] - β^2[M] }{Φ}= {0}
                // λ = -jβと置いた場合(β = jλ)
                //evals[i] = eval * KrdLab.clapack.Complex.ImaginaryOne;
                // λ = -j(β/k0)と置いた場合
                //evals[i] = eval * KrdLab.clapack.Complex.ImaginaryOne * k0;
                // λ = -j(β/betaNormalizingFactor)と置いた場合
                evals[i] = eval * KrdLab.clapack.Complex.ImaginaryOne * betaNormalizingFactor;
            }

            System.Diagnostics.Debug.Assert(ret_r_evals.Length == ret_r_evecs.Length);
            // 2次元配列に格納する
            evecs = new KrdLab.clapack.Complex[ret_r_evecs.Length, (matLen * 2)];
            for (int i = 0; i < ret_r_evecs.Length; i++)
            {
                double[] ret_r_evec = ret_r_evecs[i];
                double[] ret_i_evec = ret_i_evecs[i];
                for (int j = 0; j < ret_r_evec.Length; j++)
                {
                    evecs[i, j] = new KrdLab.clapack.Complex(ret_r_evec[j], ret_i_evec[j]);
                }
            }

            // 固有値をソートする
            System.Diagnostics.Debug.Assert(evecs.GetLength(1) == freeNodeCnt * 2);
            GetSortedModes(
                incidentModeIndex,
                k0,
                nodeCntPeriodic,
                freeNodeCnt,
                nodeCntBPeriodic,
                sortedNodesPeriodic,
                toSortedPeriodic,
                toNodePeriodic,
                defectNodePeriodic,
                isModeTrace,
                ref PrevModalVec,
                minBeta,
                maxBeta,
                evals,
                evecs,
                true, // isDebugShow
                out betamToSolveList,
                out resVecList);
        }
示例#2
0
        //////////////////////////////////////////////////////////////////////////////////////////////////
        // 周期構造導波路固有値問題:Φを直接解く方法
        private static void solveNonSVEAModeAsQuadraticGeneralizedEigenWithRealMat(
            int incidentModeIndex,
            double periodicDistance,
            double k0,
            double[] KMat0,
            bool isPortBc2Reverse,
            int nodeCntPeriodic,
            int freeNodeCntPeriodic_0,
            int freeNodeCntPeriodic,
            int nodeCntBPeriodic,
            IList<int> sortedNodesPeriodic,
            Dictionary<int, int> toSortedPeriodic,
            Dictionary<int, int> toNodePeriodic,
            Dictionary<int, int> toNodePeriodicB1,
            IList<double[]> coordsPeriodic,
            IList<int> defectNodePeriodic,
            bool isModeTrace,
            ref KrdLab.clapack.Complex[] PrevModalVec,
            double minBeta,
            double maxBeta,
            double betaNormalizingFactor,
            out KrdLab.clapack.Complex[] betamToSolveList,
            out KrdLab.clapack.Complex[][] resVecList)
        {
            betamToSolveList = null;
            resVecList = null;

            // 複素モード、エバネセントモードの固有ベクトル計算をスキップする? (計算時間短縮するため)
            bool isSkipCalcComplexAndEvanescentModeVec = true;
            System.Diagnostics.Debug.WriteLine("isSkipCalcComplexAndEvanescentModeVec: {0}", isSkipCalcComplexAndEvanescentModeVec);
            // 緩慢変化包絡線近似? Φを直接解く方法なので常にfalse
            const bool isSVEA = false; // Φを直接解く方法
            // 境界1のみの式に変換
            int inner_node_cnt = freeNodeCntPeriodic - nodeCntBPeriodic;
            double[] P11 = new double[nodeCntBPeriodic * nodeCntBPeriodic];
            double[] P10 = new double[nodeCntBPeriodic * inner_node_cnt];
            double[] P12 = new double[nodeCntBPeriodic * nodeCntBPeriodic];
            double[] P01 = new double[inner_node_cnt * nodeCntBPeriodic];
            double[] P00 = new double[inner_node_cnt * inner_node_cnt];
            double[] P02 = new double[inner_node_cnt * nodeCntBPeriodic];
            double[] P21 = new double[nodeCntBPeriodic * nodeCntBPeriodic];
            double[] P20 = new double[nodeCntBPeriodic * inner_node_cnt];
            double[] P22 = new double[nodeCntBPeriodic * nodeCntBPeriodic];

            for (int i = 0; i < nodeCntBPeriodic; i++)
            {
                int ino_B2 = isPortBc2Reverse ? (int)(freeNodeCntPeriodic + nodeCntBPeriodic - 1 - i) : (int)(freeNodeCntPeriodic + i);
                for (int j = 0; j < nodeCntBPeriodic; j++)
                {
                    int jno_B2 = isPortBc2Reverse ? (int)(freeNodeCntPeriodic + nodeCntBPeriodic - 1 - j) : (int)(freeNodeCntPeriodic + j);
                    // [K11]
                    P11[i + nodeCntBPeriodic * j] = KMat0[i + freeNodeCntPeriodic_0 * j];
                    // [K12]
                    P12[i + nodeCntBPeriodic * j] = KMat0[i + freeNodeCntPeriodic_0 * jno_B2];
                    // [K21]
                    P21[i + nodeCntBPeriodic * j] = KMat0[ino_B2 + freeNodeCntPeriodic_0 * j];
                    // [K22]
                    P22[i + nodeCntBPeriodic * j] = KMat0[ino_B2 + freeNodeCntPeriodic_0 * jno_B2];
                }
                for (int j = 0; j < inner_node_cnt; j++)
                {
                    // [K10]
                    P10[i + nodeCntBPeriodic * j] = KMat0[i + freeNodeCntPeriodic_0 * (j + nodeCntBPeriodic)];
                    // [K20]
                    P20[i + nodeCntBPeriodic * j] = KMat0[ino_B2 + freeNodeCntPeriodic_0 * (j + nodeCntBPeriodic)];
                }
            }
            for (int i = 0; i < inner_node_cnt; i++)
            {
                for (int j = 0; j < nodeCntBPeriodic; j++)
                {
                    int jno_B2 = isPortBc2Reverse ? (int)(freeNodeCntPeriodic + nodeCntBPeriodic - 1 - j) : (int)(freeNodeCntPeriodic + j);
                    // [K01]
                    P01[i + inner_node_cnt * j] = KMat0[(i + nodeCntBPeriodic) + freeNodeCntPeriodic_0 * j];
                    // [K02]
                    P02[i + inner_node_cnt * j] = KMat0[(i + nodeCntBPeriodic) + freeNodeCntPeriodic_0 * jno_B2];
                }
                for (int j = 0; j < inner_node_cnt; j++)
                {
                    // [K00]
                    P00[i + inner_node_cnt * j] = KMat0[(i + nodeCntBPeriodic) + freeNodeCntPeriodic_0 * (j + nodeCntBPeriodic)];
                }
            }

            System.Diagnostics.Debug.WriteLine("setup [K]B [C]B [M]B");
            double[] invP00 = MyMatrixUtil.matrix_Inverse(P00, (int)(freeNodeCntPeriodic - nodeCntBPeriodic));
            double[] P10_invP00 = MyMatrixUtil.product(
                P10, (int)nodeCntBPeriodic, (int)inner_node_cnt,
                invP00, (int)inner_node_cnt, (int)inner_node_cnt);
            double[] P20_invP00 = MyMatrixUtil.product(
                P20, (int)nodeCntBPeriodic, (int)inner_node_cnt,
                invP00, (int)inner_node_cnt, (int)inner_node_cnt);
            // for [C]B
            double[] P10_invP00_P01 = MyMatrixUtil.product(
                P10_invP00, (int)nodeCntBPeriodic, (int)inner_node_cnt,
                P01, (int)inner_node_cnt, (int)nodeCntBPeriodic);
            double[] P20_invP00_P02 = MyMatrixUtil.product(
                P20_invP00, (int)nodeCntBPeriodic, (int)inner_node_cnt,
                P02, (int)inner_node_cnt, (int)nodeCntBPeriodic);
            // for [M]B
            double[] P10_invP00_P02 = MyMatrixUtil.product(
                P10_invP00, (int)nodeCntBPeriodic, (int)inner_node_cnt,
                P02, (int)inner_node_cnt, (int)nodeCntBPeriodic);
            // for [K]B
            double[] P20_invP00_P01 = MyMatrixUtil.product(
                P20_invP00, (int)nodeCntBPeriodic, (int)inner_node_cnt,
                P01, (int)inner_node_cnt, (int)nodeCntBPeriodic);
            // [C]B
            double[] CMatB = new double[nodeCntBPeriodic * nodeCntBPeriodic];
            // [M]B
            double[] MMatB = new double[nodeCntBPeriodic * nodeCntBPeriodic];
            // [K]B
            double[] KMatB = new double[nodeCntBPeriodic * nodeCntBPeriodic];
            for (int i = 0; i < nodeCntBPeriodic; i++)
            {
                for (int j = 0; j < nodeCntBPeriodic; j++)
                {
                    CMatB[i + nodeCntBPeriodic * j] =
                        - P10_invP00_P01[i + nodeCntBPeriodic * j]
                        + P11[i + nodeCntBPeriodic * j]
                        - P20_invP00_P02[i + nodeCntBPeriodic * j]
                        + P22[i + nodeCntBPeriodic * j];
                    MMatB[i + nodeCntBPeriodic * j] =
                        - P10_invP00_P02[i + nodeCntBPeriodic * j]
                        + P12[i + nodeCntBPeriodic * j];
                    KMatB[i + nodeCntBPeriodic * j] =
                        - P20_invP00_P01[i + nodeCntBPeriodic * j]
                        + P21[i + nodeCntBPeriodic * j];
                }
            }

            // 非線形固有値問題
            //  [K] + λ[C] + λ^2[M]{Φ}= {0}
            //
            // Lisys(Lapack)による固有値解析
            // マトリクスサイズは、強制境界及び境界3を除いたサイズ
            int matLen = (int)nodeCntBPeriodic;
            KrdLab.clapack.Complex[] evals = null;
            KrdLab.clapack.Complex[,] evecs = null;

            // 一般化固有値解析(実行列として解く)
            double[] A = new double[(matLen * 2) * (matLen * 2)];
            double[] B = new double[(matLen * 2) * (matLen * 2)];
            for (int i = 0; i < matLen; i++)
            {
                for (int j = 0; j < matLen; j++)
                {
                    A[i + j * (matLen * 2)] = 0.0;
                    A[i + (j + matLen) * (matLen * 2)] = (i == j) ? 1.0 : 0.0;
                    A[(i + matLen) + j * (matLen * 2)] = -1.0 * KMatB[i + j * matLen];
                    A[(i + matLen) + (j + matLen) * (matLen * 2)] = -1.0 * CMatB[i + j * matLen];
                }
            }
            for (int i = 0; i < matLen; i++)
            {
                for (int j = 0; j < matLen; j++)
                {
                    B[i + j * (matLen * 2)] = (i == j) ? 1.0 : 0.0;
                    B[i + (j + matLen) * (matLen * 2)] = 0.0;
                    B[(i + matLen) + j * (matLen * 2)] = 0.0;
                    B[(i + matLen) + (j + matLen) * (matLen * 2)] = MMatB[i + j * matLen];
                }
            }
            double[] ret_r_evals = null;
            double[] ret_i_evals = null;
            double[][] ret_r_evecs = null;
            double[][] ret_i_evecs = null;
            System.Diagnostics.Debug.WriteLine("KrdLab.clapack.FunctionExt.dggev");
            KrdLab.clapack.FunctionExt.dggev(A, (matLen * 2), (matLen * 2), B, (matLen * 2), (matLen * 2), ref ret_r_evals, ref ret_i_evals, ref ret_r_evecs, ref ret_i_evecs);

            evals = new KrdLab.clapack.Complex[ret_r_evals.Length];
            // βを格納
            for (int i = 0; i < ret_r_evals.Length; i++)
            {
                KrdLab.clapack.Complex eval = new KrdLab.clapack.Complex(ret_r_evals[i], ret_i_evals[i]);
                //System.Diagnostics.Debug.WriteLine("exp(-jβd) = {0} + {1} i", eval.Real, eval.Imaginary);
                if ((Math.Abs(eval.Real) < MyUtilLib.Matrix.Constants.PrecisionLowerLimit && Math.Abs(eval.Imaginary) < MyUtilLib.Matrix.Constants.PrecisionLowerLimit)
                    || double.IsInfinity(eval.Real) || double.IsInfinity(eval.Imaginary)
                    || double.IsNaN(eval.Real) || double.IsNaN(eval.Imaginary)
                    )
                {
                    // 無効な固有値
                    //evals[i] = -1.0 * KrdLab.clapack.Complex.ImaginaryOne * double.MaxValue;
                    evals[i] = KrdLab.clapack.Complex.ImaginaryOne * double.MaxValue;
                }
                else
                {
                    //System.Diagnostics.Debug.WriteLine("exp(-jβd) = {0} + {1} i", eval.Real, eval.Imaginary);
                    KrdLab.clapack.Complex betatmp = -1.0 * MyUtilLib.Matrix.MyMatrixUtil.complex_Log(eval) / (KrdLab.clapack.Complex.ImaginaryOne * periodicDistance);
                    evals[i] = new KrdLab.clapack.Complex(betatmp.Real, betatmp.Imaginary);
                }
            }
            System.Diagnostics.Debug.Assert(ret_r_evals.Length == ret_r_evecs.Length);
            // 2次元配列に格納する ({Φ}のみ格納)
            evecs = new KrdLab.clapack.Complex[ret_r_evecs.Length, freeNodeCntPeriodic];

            System.Diagnostics.Debug.WriteLine("calc {Φ}0");
            double[] invP00_P01 = MyMatrixUtil.product(
                invP00, (int)inner_node_cnt, (int)inner_node_cnt,
                P01, (int)inner_node_cnt, (int)nodeCntBPeriodic);
            double[] invP00_P02 = MyMatrixUtil.product(
                invP00, (int)inner_node_cnt, (int)inner_node_cnt,
                P02, (int)inner_node_cnt, (int)nodeCntBPeriodic);
            KrdLab.clapack.Complex[] transMat = new KrdLab.clapack.Complex[inner_node_cnt * nodeCntBPeriodic];
            System.Diagnostics.Debug.Assert(evals.Length == ret_r_evecs.Length);
            System.Diagnostics.Debug.Assert(evals.Length == ret_i_evecs.Length);
            for (int imode = 0; imode < evals.Length; imode++)
            {
                KrdLab.clapack.Complex betam = evals[imode];
                // 複素モード、エバネセントモードの固有モード計算をスキップする?
                if (isSkipCalcComplexAndEvanescentModeVec)
                {
                    if (Math.Abs(betam.Imaginary) >= Constants.PrecisionLowerLimit)
                    {
                        // 複素モード、エバネセントモードの固有モード計算をスキップする
                        continue;
                    }
                }

                KrdLab.clapack.Complex expA = KrdLab.clapack.Complex.Exp(-1.0 * KrdLab.clapack.Complex.ImaginaryOne * betam * periodicDistance);
                double[] ret_r_evec = ret_r_evecs[imode];
                double[] ret_i_evec = ret_i_evecs[imode];
                System.Diagnostics.Debug.Assert(ret_r_evec.Length == nodeCntBPeriodic * 2);
                KrdLab.clapack.Complex[] fVecB = new KrdLab.clapack.Complex[nodeCntBPeriodic];
                ///////////////////////////////
                // {Φ}Bのみ格納
                for (int ino = 0; ino < nodeCntBPeriodic; ino++)
                {
                    KrdLab.clapack.Complex cvalue = new KrdLab.clapack.Complex(ret_r_evec[ino], ret_i_evec[ino]);
                    evecs[imode, ino] = cvalue;
                    fVecB[ino] = cvalue;
                }

                ///////////////////////////////
                // {Φ}0を計算
                //   変換行列を計算
                for (int i = 0; i < inner_node_cnt; i++)
                {
                    for (int j = 0; j < nodeCntBPeriodic; j++)
                    {
                        transMat[i + inner_node_cnt * j] = -1.0 * (invP00_P01[i + inner_node_cnt * j] + expA * invP00_P02[i + inner_node_cnt * j]);
                    }
                }
                //   {Φ}0を計算
                KrdLab.clapack.Complex[] fVecInner = MyMatrixUtil.product(
                    transMat, (int)inner_node_cnt, (int)nodeCntBPeriodic,
                    fVecB, (int)nodeCntBPeriodic);
                //   {Φ}0を格納
                for (int ino = 0; ino < inner_node_cnt; ino++)
                {
                    evecs[imode, ino + nodeCntBPeriodic] = fVecInner[ino];
                }
            }

            ////////////////////////////////////////////////////////////////////

            if (!isSVEA)
            {
                System.Diagnostics.Debug.Assert(freeNodeCntPeriodic == (sortedNodesPeriodic.Count - nodeCntBPeriodic));
                for (int imode = 0; imode < evals.Length; imode++)
                {
                    // 伝搬定数
                    KrdLab.clapack.Complex betatmp = evals[imode];
                    // 界ベクトル
                    KrdLab.clapack.Complex[] fieldVec = MyUtilLib.Matrix.MyMatrixUtil.matrix_GetRowVec(evecs, imode);

                    KrdLab.clapack.Complex beta_d_tmp = betatmp * periodicDistance;
                    if (
                        // [-π, 0]の解を[π, 2π]に移動する
                        ((minBeta * k0 * periodicDistance / (2.0 * pi)) >= (0.5 - MyUtilLib.Matrix.Constants.PrecisionLowerLimit)
                             && (minBeta * k0 * periodicDistance / (2.0 * pi)) < 1.0
                             && Math.Abs(betatmp.Real) >= MyUtilLib.Matrix.Constants.PrecisionLowerLimit
                             && Math.Abs(betatmp.Imaginary) < MyUtilLib.Matrix.Constants.PrecisionLowerLimit
                             && (beta_d_tmp.Real / (2.0 * pi)) >= (-0.5 - MyUtilLib.Matrix.Constants.PrecisionLowerLimit)
                             && (beta_d_tmp.Real / (2.0 * pi)) < 0.0)
                        // [0, π]の解を[2π, 3π]に移動する
                        || ((minBeta * k0 * periodicDistance / (2.0 * pi)) >= (1.0 - MyUtilLib.Matrix.Constants.PrecisionLowerLimit)
                                && (minBeta * k0 * periodicDistance / (2.0 * pi)) < 1.5
                                && Math.Abs(betatmp.Real) >= MyUtilLib.Matrix.Constants.PrecisionLowerLimit
                                && Math.Abs(betatmp.Imaginary) < MyUtilLib.Matrix.Constants.PrecisionLowerLimit
                                && (beta_d_tmp.Real / (2.0 * pi)) >= (0.0 - MyUtilLib.Matrix.Constants.PrecisionLowerLimit)
                                && (beta_d_tmp.Real / (2.0 * pi)) < 0.5)
                        )
                    {
                        // [0, π]の解を2πだけ移動する
                        double delta_phase = 2.0 * pi;
                        beta_d_tmp.Real += delta_phase;
                        betatmp = beta_d_tmp / periodicDistance;
                        //check
                        System.Diagnostics.Debug.WriteLine("shift beta * d / (2π): {0} + {1} i to {2} + {3} i",
                            evals[imode].Real * periodicDistance / (2.0 * pi),
                            evals[imode].Imaginary * periodicDistance / (2.0 * pi),
                            beta_d_tmp.Real / (2.0 * pi),
                            beta_d_tmp.Imaginary / (2.0 * pi));
                        // 再設定
                        evals[imode] = betatmp;
                    }
                }
            }

            // 固有値をソートする
            System.Diagnostics.Debug.Assert(evecs.GetLength(1) == freeNodeCntPeriodic);
            GetSortedModes(
                incidentModeIndex,
                k0,
                nodeCntPeriodic,
                freeNodeCntPeriodic,
                nodeCntBPeriodic,
                sortedNodesPeriodic,
                toSortedPeriodic,
                toNodePeriodic,
                defectNodePeriodic,
                isModeTrace,
                ref PrevModalVec,
                minBeta,
                maxBeta,
                evals,
                evecs,
                true, // isDebugShow
                out betamToSolveList,
                out resVecList);
        }