//////////////////////////////////////////////////////////////////////////////////////// // Φ = φ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); }
////////////////////////////////////////////////////////////////////////////////////////////////// // 周期構造導波路固有値問題:Φを直接解く方法 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); }