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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        /// <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));
            }
        }
Example #4
0
        /// <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);
        }
Example #6
0
            /// <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"));
 }