public static MultidimensionalArray LoadResults(string path) { MultidimensionalArray[] parts = new MultidimensionalArray[5]; for (int i = 0; i < 5; i++) { parts[i] = IMatrixExtensions.LoadFromTextFile(path + "Results_" + i + ".txt"); } MultidimensionalArray result = MultidimensionalArray.Create(parts[0].Lengths[0], parts[0].Lengths[1], 5); for (int i = 0; i < result.Lengths[2]; i++) { result.ExtractSubArrayShallow(-1, -1, i).Acc(1.0, parts[i]); } return(result); }
/// <summary> /// Implementation of <see cref="Mode.SymPart_DiagBlockEquilib_DropIndefinite"/> /// </summary> static (int Rank, int[] IndefRows) SymPart_DiagBlockEquilib_DropIndefinite( MultidimensionalArray In_MassMatrixBlock, MultidimensionalArray In_OperatorMatrixBlock, MultidimensionalArray OUT_LeftPC, MultidimensionalArray OUT_rightPC, MultidimensionalArray work) { var SymmPart = work; In_OperatorMatrixBlock.TransposeTo(SymmPart); SymmPart.Acc(1.0, In_OperatorMatrixBlock); SymmPart.Scale(0.5); int[] ZerosEntries = ModifiedInverseChol(In_MassMatrixBlock, OUT_rightPC, 1.0e-12, false); int NoOfZeros = ZerosEntries == null ? 0 : ZerosEntries.Length; int[] _IndefRows = ZerosEntries; int _Rank = OUT_LeftPC.NoOfCols - NoOfZeros; if (NoOfZeros == 0) { // normal cell -- nix indefinite // +++++++++++++++++++++++++++++ SymmInv(SymmPart, OUT_LeftPC, OUT_rightPC); } else { // problem-cell // ++++++++++++++ OUT_rightPC.TransposeTo(OUT_LeftPC); SymmPart = IMatrixExtensions.GEMM(OUT_LeftPC, SymmPart, OUT_rightPC); int[] ZerosEntries2 = ModifiedInverseChol(SymmPart, OUT_rightPC, 1.0e-12, true); OUT_rightPC.TransposeTo(OUT_LeftPC); if (!ZerosEntries2.SetEquals(ZerosEntries)) { throw new ArithmeticException(); } } return(_Rank, _IndefRows); }
/// <summary> /// Imports a quadrature rule from a text file. /// </summary> static Tuple <int, double[, ], double[]> ReadFromTextFile(string FileName) { using (StreamReader txt = new StreamReader(FileName)) { int Order; string header = txt.ReadLine(); if (!header.StartsWith("order")) { throw new IOException(); } Order = int.Parse(header.Replace("order", "")); MultidimensionalArray NodesAndWeights = IMatrixExtensions.LoadFromStream(txt); int K = NodesAndWeights.NoOfRows; int D = NodesAndWeights.NoOfCols - 1; double[,] Nodes = NodesAndWeights.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { K - 1, D - 1 }).To2DArray(); double[] Weigths = NodesAndWeights.ExtractSubArrayShallow(new int[] { 0, D }, new int[] { K - 1, D - 1 }).To1DArray(); return(new Tuple <int, double[, ], double[]>(Order, Nodes, Weigths)); } }
/// <summary> /// executes all commands /// </summary> /// <returns> /// a reader to the standard output of the MATLAB process. /// </returns> public void Execute(bool PrintOutput = true) { ilPSP.MPICollectiveWatchDog.Watch(csMPI.Raw._COMM.WORLD); if (Executed == true) { throw new InvalidOperationException("Execute can be called only once."); } // run MATLAB // ========== Cmd("exit"); // be sure to exit! if (Rank == 0) { CommandFile.Flush(); CommandFile.Close(); //psi.RedirectStandardOutput = true; //psi.RedirectStandardError = true; //psi.RedirectStandardInput = true; var proc = Process.Start(psi); proc.WaitForExit(); } // return // ====== if (Rank == 0) { var p = Path.Combine(WorkingDirectory.FullName, LOGFILE); if (PrintOutput) { var stdout = new StreamReader(p); string line = stdout.ReadLine(); while (line != null) { Console.WriteLine(line); line = stdout.ReadLine(); } stdout.Dispose(); } CreatedFiles.Add(p); } foreach (string key in m_OutputObjects.Keys.ToArray()) { object outputObj = m_OutputObjects[key]; string filepath; if (Rank == 0) { filepath = Path.Combine(WorkingDirectory.FullName, key); } else { filepath = null; } if (outputObj is IMatrix) { // ++++++++++++++++++++++++++ // load pre-allocated matrix // ++++++++++++++++++++++++++ IMatrix outputMtx = (IMatrix)outputObj; if (Rank == 0) { outputMtx.LoadFromTextFile(filepath); } var _outputMtx = ilPSP.MPIEnviroment.Broadcast(outputMtx, 0, csMPI.Raw._COMM.WORLD); if (Rank != 0) { outputMtx.Clear(); outputMtx.Acc(1.0, _outputMtx); } if (!object.ReferenceEquals(outputObj, outputMtx)) { } } else if (outputObj is Type && ((Type)outputObj) == typeof(MultidimensionalArray)) { // ++++++++++++++++++++++++++ // load matrix which is NOT pre-allocated, unknown size // ++++++++++++++++++++++++++ IMatrix outputMtx = null; if (Rank == 0) { outputMtx = IMatrixExtensions.LoadFromTextFile(filepath); } var _outputMtx = ilPSP.MPIEnviroment.Broadcast(outputMtx, 0, csMPI.Raw._COMM.WORLD); m_OutputObjects[key] = _outputMtx; } else if (outputObj is int[][]) { int[][] outputStAry = (int[][])outputObj; if (Rank == 0) { LoadStaggeredArray(outputStAry, filepath); } var _outputStAry = ilPSP.MPIEnviroment.Broadcast(outputStAry, 0, csMPI.Raw._COMM.WORLD); if (Rank != 0) { for (int i = 0; i < Math.Max(_outputStAry.Length, outputStAry.Length); i++) // we use max to ensure an index-out-of-range if something is fishy { outputStAry[i] = _outputStAry[i]; } } } else { throw new NotImplementedException("output object type not implemented."); } } }
private static int[] ComputeChangeOfBasisBlock(MultidimensionalArray In_MassMatrixBlock, MultidimensionalArray In_OperatorMatrixBlock, MultidimensionalArray OUT_LeftPC, MultidimensionalArray OUT_rightPC, Mode PCMode, out int Rank, MultidimensionalArray work) { Rank = In_MassMatrixBlock.NoOfCols; int[] IndefRows = null; switch (PCMode) { case Mode.Eye: { OUT_LeftPC.AccEye(1.0); OUT_rightPC.AccEye(1.0); break; } case Mode.DiagBlockEquilib: { double symmErr = In_OperatorMatrixBlock.SymmetryError(); double infNorm = In_OperatorMatrixBlock.InfNorm(); if (symmErr / infNorm > 1.0e-8) { throw new NotSupportedException(string.Format("LDL_DiagBlock is not supported on unsymmetric matrices (Symm-Err: {0:0.####E-00}, Inf-Norm: {1:0.####E-00}, Quotient {2:0.####E-00}).", symmErr, infNorm, symmErr / infNorm)); } SymmInv(In_OperatorMatrixBlock, OUT_LeftPC, OUT_rightPC); break; } case Mode.SymPart_DiagBlockEquilib: { var SymmPart = work; In_OperatorMatrixBlock.TransposeTo(SymmPart); SymmPart.Acc(1.0, In_OperatorMatrixBlock); SymmPart.Scale(0.5); SymmInv(SymmPart, OUT_LeftPC, OUT_rightPC); break; } case Mode.IdMass: { In_MassMatrixBlock.SymmetricLDLInversion(OUT_rightPC, default(double[])); OUT_rightPC.TransposeTo(OUT_LeftPC); break; } case Mode.LeftInverse_DiagBlock: { In_OperatorMatrixBlock.InvertTo(OUT_LeftPC); OUT_rightPC.AccEye(1.0); break; } case Mode.LeftInverse_Mass: { In_MassMatrixBlock.InvertTo(OUT_LeftPC); OUT_rightPC.AccEye(1.0); break; } case Mode.IdMass_DropIndefinite: { int[] ZerosEntries = ModifiedInverseChol(In_MassMatrixBlock, OUT_rightPC, 1.0e-12, false); int NoOfZeros = ZerosEntries == null ? 0 : ZerosEntries.Length; IndefRows = ZerosEntries; Rank = OUT_LeftPC.NoOfCols - NoOfZeros; OUT_rightPC.TransposeTo(OUT_LeftPC); break; } case Mode.SymPart_DiagBlockEquilib_DropIndefinite: { var SymmPart = work; In_OperatorMatrixBlock.TransposeTo(SymmPart); SymmPart.Acc(1.0, In_OperatorMatrixBlock); SymmPart.Scale(0.5); int[] ZerosEntries = ModifiedInverseChol(In_MassMatrixBlock, OUT_rightPC, 1.0e-12, false); int NoOfZeros = ZerosEntries == null ? 0 : ZerosEntries.Length; IndefRows = ZerosEntries; Rank = OUT_LeftPC.NoOfCols - NoOfZeros; if (NoOfZeros == 0) { // normal cell -- nix indefinite // +++++++++++++++++++++++++++++ SymmInv(SymmPart, OUT_LeftPC, OUT_rightPC); } else { // problem-cell // ++++++++++++++ OUT_rightPC.TransposeTo(OUT_LeftPC); SymmPart = IMatrixExtensions.GEMM(OUT_LeftPC, SymmPart, OUT_rightPC); int[] ZerosEntries2 = ModifiedInverseChol(SymmPart, OUT_rightPC, 1.0e-12, true); OUT_rightPC.TransposeTo(OUT_LeftPC); if (!ZerosEntries2.SetEquals(ZerosEntries)) { throw new ArithmeticException(); } break; } break; } /* * case Mode.LDL_DiagBlock_DropIndefinite: { * if(In_OperatorMatrixBlock.SymmetryError() / In_OperatorMatrixBlock.InfNorm() > 1.0e-8) * throw new NotSupportedException("LDL_DiagBlock is not supported on unsymmetric matrices"); * int N = OUT_LeftPC.NoOfCols; * * MultidimensionalArray PL = MultidimensionalArray.Create(N, N); * MultidimensionalArray PR = MultidimensionalArray.Create(N, N); * * int zeros1 = CRM114(In_MassMatrixBlock, PR, 1.0e-12); * Rank = N - zeros1; * PR.TransposeTo(PL); * * var OpTr = (PL * In_OperatorMatrixBlock) * PR; * * MultidimensionalArray QL = MultidimensionalArray.Create(N, N); * MultidimensionalArray QR = MultidimensionalArray.Create(N, N); * int zeros2 = CRM114(OpTr, QR, 1.0e-12); * QR.TransposeTo(QL); * * if(zeros1 != zeros2) * // I want this to fire also in Release mode, therfore i don't use Debug.Assert(...) * throw new ApplicationException(); * * * OUT_LeftPC.GEMM(1.0, QL, PL, 0.0); * OUT_rightPC.GEMM(1.0, PR, QR, 0.0); * * //if (zeros1 > 0 || zeros2 > 0) { * // Console.WriteLine("zeros introduced: " + zeros1 + ", " + zeros2); * //} * * break; * } */ default: throw new NotImplementedException(); } return(IndefRows); }
/// <summary> /// Orthonormalization for curved elements /// </summary> protected override MultidimensionalArray Compute_OrthonormalizationTrafo(int j0, int Len, int Degree) { // init // ==== int iKref = this.m_Owner.iGeomCells.GetRefElementIndex(j0); PolynomialList Polys = this.GetOrthonormalPolynomials(Degree)[iKref]; int N = Polys.Count; CellType cellType = this.m_Owner.iGeomCells.GetCellType(j0); #if DEBUG // checking for (int j = 1; j < Len; j++) { int jCell = j + j0; if (this.m_Owner.iGeomCells.GetCellType(jCell) != cellType) { throw new NotSupportedException("All cells in chunk must have same type."); } } #endif // storage for result MultidimensionalArray NonlinOrtho = MultidimensionalArray.Create(Len, N, N); if (m_Owner.iGeomCells.IsCellAffineLinear(j0)) { // affine-linear branch // ++++++++++++++++++++ MultidimensionalArray scl = this.Scaling; for (int j = 0; j < Len; j++) { int jCell = j + j0; double scl_j = scl[jCell]; for (int n = 0; n < N; n++) { NonlinOrtho[j, n, n] = scl_j; } } } else { // nonlinear cells branch // ++++++++++++++++++++++ // init // ==== var Kref = m_Owner.iGeomCells.GetRefElement(j0); int deg; // polynomial degree of integrand: Degree of Jacobi determinat + 2* degree of basis polynomials in ref.-space. { int D = m_Owner.SpatialDimension; deg = Kref.GetInterpolationDegree(cellType); if (deg > 1) { deg -= 1; } deg *= D; deg += 2 * Degree; } var qr = Kref.GetQuadratureRule((int)deg); int K = qr.NoOfNodes; // evaluate basis polys in ref space // ================================= MultidimensionalArray BasisValues = this.EvaluateBasis(qr.Nodes, Degree); Debug.Assert(BasisValues.GetLength(0) == K); if (BasisValues.GetLength(0) > N) { BasisValues = BasisValues.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { K - 1, N - 1 }); } // compute \f$ A_{k n m} = \phi_{k n} \phi_{k m} w_{k} \f$ // (cell-INdependentd part of mass matrix computation) // ================================================================== MultidimensionalArray A = MultidimensionalArray.Create(K, N, N); A.Multiply(1.0, qr.Weights, BasisValues, BasisValues, 0.0, "knm", "k", "kn", "km"); // Determine mass matrix \f$ M \f$ in all cells by quadrature // \f$ M_{n m} = \sum_{k} J_k A_{k n m} \f$ // ===================================================== MultidimensionalArray J = m_Owner.JacobianDeterminat.GetValue_Cell(qr.Nodes, j0, Len); // store mass-matrix in 'NonlinOrtho' to save mem alloc NonlinOrtho.Multiply(1.0, A, J, 0.0, "jmn", "knm", "jk"); // Compute change-of-basis for all cells // (invese of cholesky) // ===================================== for (int j = 0; j < Len; j++) { MultidimensionalArray Mj = NonlinOrtho.ExtractSubArrayShallow(j, -1, -1); // mass-matrix of basis on refrence element in cell j+j0 #if DEBUG MultidimensionalArray MjClone = Mj.CloneAs(); #endif //Mj.InvertSymmetrical(); Mj.SymmetricLDLInversion(Mj, null); // clear lower triangular part // Debug.Assert(Mj.NoOfCols == N); for (int n = 1; n < N; n++) { for (int m = 0; m < n; m++) { Mj[n, m] = 0.0; } } #if DEBUG MultidimensionalArray B = NonlinOrtho.ExtractSubArrayShallow(j, -1, -1); MultidimensionalArray Bt = B.Transpose(); double MjNorm = MjClone.InfNorm(); double Bnorm = B.InfNorm(); MultidimensionalArray check = IMatrixExtensions.GEMM(Bt, MjClone, B); check.AccEye(-1.0); double checkNorm = check.InfNorm(); double RelErr = checkNorm / Math.Max(MjNorm, Bnorm); Debug.Assert(RelErr < 1.0e-5, "Fatal error in numerical orthonomalization on nonlinear cell."); #endif } } // return // ========= return(NonlinOrtho); }
public static MultidimensionalArray LoadResultsExtended(string path) { return(IMatrixExtensions.LoadFromTextFile(path + "ResultsExtended.txt")); }