// [X] = alpha * [A] public static MyDoubleSymmetricBandMatrix product(double alpha, MyDoubleSymmetricBandMatrix matA) { MyDoubleSymmetricBandMatrix matX = new MyDoubleSymmetricBandMatrix(matA.RowSize, matA.SubdiaSize, matA.SuperdiaSize); for (int i = 0; i < matA.RowSize; i++) { //for (int j = 0; j < matA.ColumnSize; j++) for (int j = i; j < matA.ColumnSize; j++) { matX[i, j] = alpha * matA[i, j]; } } return(matX); }
public static MyDoubleSymmetricBandMatrix matrix_FromBuffer(double[] mat_, int nRowCol, int nSubdia, int nSuperdia, bool copyFlg = true) { MyDoubleSymmetricBandMatrix mat = null; if (copyFlg) { mat = new MyDoubleSymmetricBandMatrix(mat_, nRowCol, nSubdia, nSuperdia); } else { mat = new MyDoubleSymmetricBandMatrix(nRowCol, nSubdia, nSuperdia); mat._body = mat_; } return mat; }
public static MyDoubleSymmetricBandMatrix matrix_FromBuffer(double[] mat_, int nRowCol, int nSubdia, int nSuperdia, bool copyFlg = true) { MyDoubleSymmetricBandMatrix mat = null; if (copyFlg) { mat = new MyDoubleSymmetricBandMatrix(mat_, nRowCol, nSubdia, nSuperdia); } else { mat = new MyDoubleSymmetricBandMatrix(nRowCol, nSubdia, nSuperdia); mat._body = mat_; } return(mat); }
public static double[] matrix_ToBuffer(MyDoubleSymmetricBandMatrix mat, bool copyFlg = true) { double[] mat_ = null; if (copyFlg) { int size = mat._rsize * mat._csize; mat_ = new double[size]; mat._body.CopyTo(mat_, 0); } else { mat_ = mat._body; } return(mat_); }
// [X] = [A] - [B] public static MyDoubleSymmetricBandMatrix minus(MyDoubleSymmetricBandMatrix matA, MyDoubleSymmetricBandMatrix matB) { System.Diagnostics.Debug.Assert(matA.RowSize == matB.RowSize); System.Diagnostics.Debug.Assert(matA.ColumnSize == matB.ColumnSize); int rowcolSize = matA.RowSize; int subdiaSize = matA.SubdiaSize >= matB.SubdiaSize ? matA.SubdiaSize : matB.SubdiaSize; int superdiaSize = matA.SuperdiaSize >= matB.SuperdiaSize ? matA.SuperdiaSize : matB.SuperdiaSize; MyDoubleSymmetricBandMatrix matX = new MyDoubleSymmetricBandMatrix(rowcolSize, subdiaSize, superdiaSize); for (int i = 0; i < matA.RowSize; i++) { //for (int j = 0; j < matA.ColumnSize; j++) for (int j = i; j < matA.ColumnSize; j++) { matX[i, j] = matA[i, j] - matB[i, j]; } } return(matX); }
// [X] = alpha * [A] public static MyDoubleSymmetricBandMatrix product(double alpha, MyDoubleSymmetricBandMatrix matA) { MyDoubleSymmetricBandMatrix matX = new MyDoubleSymmetricBandMatrix(matA.RowSize, matA.SubdiaSize, matA.SuperdiaSize); for (int i = 0; i < matA.RowSize; i++) { //for (int j = 0; j < matA.ColumnSize; j++) for (int j = i; j < matA.ColumnSize; j++) { matX[i, j] = alpha * matA[i, j]; } } return matX; }
// [X] = [A] + [B] public static MyDoubleSymmetricBandMatrix plus(MyDoubleSymmetricBandMatrix matA, MyDoubleSymmetricBandMatrix matB) { System.Diagnostics.Debug.Assert(matA.RowSize == matB.RowSize); System.Diagnostics.Debug.Assert(matA.ColumnSize == matB.ColumnSize); int rowcolSize = matA.RowSize; int subdiaSize = matA.SubdiaSize >= matB.SubdiaSize ? matA.SubdiaSize : matB.SubdiaSize; int superdiaSize = matA.SuperdiaSize >= matB.SuperdiaSize ? matA.SuperdiaSize : matB.SuperdiaSize; MyDoubleSymmetricBandMatrix matX = new MyDoubleSymmetricBandMatrix(rowcolSize, subdiaSize, superdiaSize); for (int i = 0; i < matA.RowSize; i++) { //for (int j = 0; j < matA.ColumnSize; j++) for (int j = i; j < matA.ColumnSize; j++) { matX[i, j] = matA[i, j] + matB[i, j]; } } return matX; }
public static double[] matrix_ToBuffer(MyDoubleSymmetricBandMatrix mat, bool copyFlg = true) { double[] mat_ = null; if (copyFlg) { int size = mat._rsize * mat._csize; mat_ = new double[size]; mat._body.CopyTo(mat_, 0); } else { mat_ = mat._body; } return mat_; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// ポート境界の1D FEM行列 ryy_1dを取得する /// </summary> /// <param name="WaveModeDv"></param> /// <param name="waveLength"></param> /// <param name="latticeA"></param> /// <param name="Nodes"></param> /// <param name="EdgeToElementNoH"></param> /// <param name="Elements"></param> /// <param name="Medias"></param> /// <param name="ForceNodeNumberH"></param> /// <param name="nodesBoundary"></param> /// <param name="ryy_1d"></param> private static void getPortFemMat1D( FemSolver.WaveModeDV WaveModeDv, double waveLength, double latticeA, IList<FemNode> Nodes, Dictionary<string, IList<int>> EdgeToElementNoH, IList<FemElement> Elements, MediaInfo[] Medias, Dictionary<int, bool> ForceNodeNumberH, IList<int> portNodes, out int[] nodesBoundary, out MyDoubleMatrix ryy_1d ) { nodesBoundary = null; ryy_1d = null; // 2D次元数 const int ndim2d = Constants.CoordDim2D; //2; // 波数 double k0 = 2.0 * pi / waveLength; // 角周波数 double omega = k0 * c0; // 節点番号リスト(要素インデックス: 1D節点番号 - 1 要素:2D節点番号) IList<int> nodes = portNodes; // 2D→1D節点番号マップ Dictionary<int, int> to1dNodes = new Dictionary<int, int>(); // 節点座標リスト IList<double> coords = new List<double>(); // 要素リスト IList<FemLineElement> elements = new List<FemLineElement>(); // 1D節点番号リスト(ソート済み) IList<int> sortedNodes = new List<int>(); // 1D節点番号→ソート済みリストインデックスのマップ Dictionary<int, int> toSorted = new Dictionary<int, int>(); // 2Dの要素から次数を取得する Constants.FemElementShapeDV elemShapeDv2d; int order; int vertexCnt2d; FemMeshLogic.GetElementShapeDvAndOrderByElemNodeCnt(Elements[0].NodeNumbers.Length, out elemShapeDv2d, out order, out vertexCnt2d); // 2D→1D節点番号マップ作成 for (int i = 0; i < nodes.Count; i++) { int nodeNumber2d = nodes[i]; if (!to1dNodes.ContainsKey(nodeNumber2d)) { to1dNodes.Add(nodeNumber2d, i + 1); } } // 原点 int nodeNumber0 = nodes[0]; int nodeIndex0 = nodeNumber0 - 1; FemNode node0 = Nodes[nodeIndex0]; double[] coord0 = new double[ndim2d]; coord0[0] = node0.Coord[0]; coord0[1] = node0.Coord[1]; // 座標リスト作成 double[] coord = new double[ndim2d]; foreach (int nodeNumber in nodes) { int nodeIndex = nodeNumber - 1; FemNode node = Nodes[nodeIndex]; coord[0] = node.Coord[0]; coord[1] = node.Coord[1]; double x = FemMeshLogic.GetDistance(coord, coord0); //System.Diagnostics.Debug.WriteLine("{0},{1},{2},{3}", nodeIndex, coord[0], coord[1], x); coords.Add(x); } // 線要素を作成する if (order == Constants.FirstOrder) { // 1次線要素 FemMat_Line_First.MkElements( nodes, EdgeToElementNoH, Elements, ref elements); } else { // 2次線要素 FemMat_Line_Second.MkElements( nodes, EdgeToElementNoH, Elements, ref elements); } // 強制境界節点と内部領域節点を分離 foreach (int nodeNumber2d in nodes) { int nodeNumber = to1dNodes[nodeNumber2d]; if (ForceNodeNumberH.ContainsKey(nodeNumber2d)) { System.Diagnostics.Debug.WriteLine("{0}: {1} {2}", nodeNumber, Nodes[nodeNumber2d - 1].Coord[0], Nodes[nodeNumber2d - 1].Coord[1]); } else { sortedNodes.Add(nodeNumber); toSorted.Add(nodeNumber, sortedNodes.Count - 1); } } // 対称バンド行列のパラメータを取得する int rowcolSize = 0; int subdiaSize = 0; int superdiaSize = 0; { bool[,] matPattern = null; FemSolverPort.GetMatNonzeroPatternForEigen(elements, toSorted, out matPattern); FemSolverPort.GetBandMatrixSubDiaSizeAndSuperDiaSizeForEigen(matPattern, out rowcolSize, out subdiaSize, out superdiaSize); } // ソート済み1D節点インデックス→2D節点番号マップ nodesBoundary = new int[sortedNodes.Count]; for (int i = 0; i < sortedNodes.Count; i++) { int nodeNumber = sortedNodes[i]; int nodeIndex = nodeNumber - 1; int nodeNumber2d = nodes[nodeIndex]; nodesBoundary[i] = nodeNumber2d; } // 節点数 int nodeCnt = sortedNodes.Count; // 固有モード解析でのみ使用するuzz_1d, txx_1d MyDoubleMatrix txx_1d = new MyDoubleSymmetricBandMatrix(nodeCnt, subdiaSize, superdiaSize); MyDoubleMatrix uzz_1d = new MyDoubleSymmetricBandMatrix(nodeCnt, subdiaSize, superdiaSize); // ryy_1dマトリクス (線要素) ryy_1d = new MyDoubleSymmetricBandMatrix(nodeCnt, subdiaSize, superdiaSize); for (int elemIndex = 0; elemIndex < elements.Count; elemIndex++) { // 線要素 FemLineElement element = elements[elemIndex]; // 1Dヘルムホルツ方程式固有値問題の要素行列を加算する if (order == Constants.FirstOrder) { // 1次線要素 FemMat_Line_First.AddElementMatOf1dEigenValueProblem( waveLength, // E面の場合のみ使用 element, coords, toSorted, Medias, WaveModeDv, ref txx_1d, ref ryy_1d, ref uzz_1d); } else { // 2次線要素 FemMat_Line_Second.AddElementMatOf1dEigenValueProblem( waveLength, // E面の場合のみ使用 element, coords, toSorted, Medias, WaveModeDv, ref txx_1d, ref ryy_1d, ref uzz_1d); } } }
/// <summary> /// 指定された行列をコピーして,新しい行列を作成する. /// </summary> /// <param name="m">コピーされる行列</param> public MyDoubleSymmetricBandMatrix(MyDoubleSymmetricBandMatrix m) { CopyFrom(m); }
/// <summary> /// 指定された行列をコピーする. /// </summary> /// <param name="m">コピーされる行列</param> /// <returns>コピー後の自身への参照</returns> public virtual MyDoubleSymmetricBandMatrix CopyFrom(MyDoubleSymmetricBandMatrix m) { return(CopyFrom(m._body, m._rowcolSize, m._superdiaSize, m._superdiaSize)); }
/// <summary> /// �w�肳�ꂽ�s���R�s�[���āC�V�����s���쐬����D /// </summary> /// <param name="m">�R�s�[�����s��</param> public MyDoubleSymmetricBandMatrix(MyDoubleSymmetricBandMatrix m) { CopyFrom(m); }
/// <summary> /// �w�肳�ꂽ�s���R�s�[����D /// </summary> /// <param name="m">�R�s�[�����s��</param> /// <returns>�R�s�[��̎��g�ւ̎Q��</returns> public virtual MyDoubleSymmetricBandMatrix CopyFrom(MyDoubleSymmetricBandMatrix m) { return CopyFrom(m._body, m._rowcolSize, m._superdiaSize, m._superdiaSize); }