예제 #1
0
        /// <summary>
        /// returns the maximum and minimum eigenvalues of the matrix
        /// </summary>
        /// <returns>Array myeigs =[MaximumEig, MinimumEig]</returns>
        public double[] Eigenval()
        {
            double[] eigenvalues         = new double[2];
            MultidimensionalArray eigs   = MultidimensionalArray.Create(1, 2);
            MultidimensionalArray output = MultidimensionalArray.Create(2, 1);

            int[]    DepVars        = this.VarGroup;
            double[] DepVars_subvec = this.m_map.GetSubvectorIndices(true, DepVars).Select(i => i + 1.0).ToArray();

            using (BatchmodeConnector bmc = new BatchmodeConnector()){
                // if Octave should be used instead of Matlab....
                //BatchmodeConnector.Flav = BatchmodeConnector.Flavor.Octave;

                bmc.PutSparseMatrix(m_OpMtx, "FullMatrix");
                bmc.PutVector(DepVars_subvec, "DepVars_subvec");
                bmc.Cmd("output = zeros(2,1)");
                bmc.Cmd("output(1) = eigs(FullMatrix(DepVars_subvec,DepVars_subvec),1,'lm');");
                bmc.Cmd("output(2) = eigs(FullMatrix(DepVars_subvec,DepVars_subvec),1,'sm');");
                bmc.GetMatrix(output, "output");
                bmc.Execute(false);
            }

            double[] myeigs = new double[] { output[0, 0], output[1, 0] };
            Debug.Assert(output[0, 0].MPIEquals(), "value does not match on procs");
            Debug.Assert(output[1, 0].MPIEquals(), "value does not match on procs");
            return(myeigs);
        }
예제 #2
0
        public static void GetExternalRowsTest(
            [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg,
            [Values(2)] int DGOrder,
            [Values(4)] int Res)
        {
            //Matlabaufruf --> gesamte Matrix nach Matlab schreiben
            //Teilmatritzen gemäß Globalid extrahieren
            //Mit ExternalRows vergleichen
            //Die große Frage: funktioniert der batchmode connector parallel? Beim rausschreiben beachten

            Utils.TestInit((int)UseXdg, DGOrder);
            Console.WriteLine("GetExternalRowsTest({0},{1})", UseXdg, DGOrder);

            //Arrange --- setup mgo and mask
            MultigridOperator mgo = Utils.CreateTestMGOperator(UseXdg, DGOrder, MatrixShape.laplace, Res);
            MultigridMapping  map = mgo.Mapping;
            BlockMsrMatrix    M   = mgo.OperatorMatrix;

            //Delete this plz ...
            //M.SaveToTextFileSparse("M");
            //int[] A = Utils.GimmeAllBlocksWithSpec(map, 9);
            //int[] B = Utils.GimmeAllBlocksWithSpec(map, 18);
            //if (map.MpiRank == 0) {
            //    A.SaveToTextFileDebug("ACells");
            //    B.SaveToTextFileDebug("BCells");
            //}
            var selector = new SubBlockSelector(map);
            var dummy    = new BlockMsrMatrix(map); // we are only interested in getting indices, so a dummy is sufficient
            var mask     = new BlockMask(selector, dummy);

            //Arrange --- get stuff to put into matlab
            int[]    GlobalIdx_ext = Utils.GetAllExtCellIdc(map);
            double[] GlobIdx       = GlobalIdx_ext.Length.ForLoop(i => (double)GlobalIdx_ext[i] + 1.0);

            //Arrange --- get external rows by mask
            BlockMsrMatrix extrows = BlockMask.GetAllExternalRows(mgo.Mapping, mgo.OperatorMatrix);

            //Assert --- idc and rows of extrows have to be the same
            Assert.IsTrue(GlobIdx.Length == extrows._RowPartitioning.LocalLength);

            //Arrange --- get external rows by matlab
            var infNorm = MultidimensionalArray.Create(1, 1);

            using (BatchmodeConnector matlab = new BatchmodeConnector()) {
                //note: BatchmodeCon maybe working on proc0 but savetotxt file, etc. (I/O) is full mpi parallel
                //so concider this as full mpi-parallel
                matlab.PutSparseMatrix(M, "M");
                matlab.PutSparseMatrix(extrows, "M_test");
                matlab.PutVector(GlobIdx, "Idx");
                matlab.Cmd(String.Format("M_ext = M(Idx, :);"));
                matlab.Cmd("n=norm(M_test-M_ext,inf)");
                matlab.GetMatrix(infNorm, "n");
                matlab.Execute();
            }

            //Assert --- test if we actually got the right Matrix corresponding to Index
            Assert.IsTrue(infNorm[0, 0] == 0.0);
        }
예제 #3
0
        /// <summary>
        /// returns the condition number of the full matrix
        /// </summary>
        public double CondNumMatlab()
        {
            int[] DepVars       = this.VarGroup;
            var   grd           = m_map.GridDat;
            int   NoOfCells     = grd.Grid.NumberOfCells;
            int   NoOfBdryCells = grd.GetBoundaryCells().NoOfItemsLocally_WithExternal;


            var Mtx = m_MultigridOp.OperatorMatrix;



            // Blocks and selectors
            // ====================
            var InnerCellsMask = grd.GetBoundaryCells().Complement();

            var FullSel = new SubBlockSelector(m_MultigridOp.Mapping);

            FullSel.VariableSelector(this.VarGroup);


            // Matlab
            // ======

            double[] Full_0Vars = (new BlockMask(FullSel)).GlobalIndices.Select(i => i + 1.0).ToArray();

            MultidimensionalArray output = MultidimensionalArray.Create(2, 1);

            string[] names = new string[] { "Full_0Vars", "Inner_0Vars" };

            using (BatchmodeConnector bmc = new BatchmodeConnector()) {
                // if Octave should be used instead of Matlab....
                // BatchmodeConnector.Flav = BatchmodeConnector.Flavor.Octave;

                bmc.PutSparseMatrix(Mtx, "FullMatrix");

                bmc.PutVector(Full_0Vars, "Full_0Vars");

                bmc.Cmd("output = ones(2,1);");

                bmc.Cmd("output(1) = condest(FullMatrix(Full_0Vars,Full_0Vars));");


                bmc.GetMatrix(output, "output");
                bmc.Execute(false);

                double condestFull = output[0, 0];
                Debug.Assert(condestFull.MPIEquals(), "value does not match on procs");


                Console.WriteLine($"MATLAB condition number: {condestFull:0.###e-00}");


                return(condestFull);
            }
        }
예제 #4
0
        public static IntersectionMesh CreateMesh(MultidimensionalArray nodes)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            IntersectionMesh mesh;

            using (var Matlab = new BatchmodeConnector())
            {
                Matlab.PutMatrix(nodes, "Nodes");

                // compute Voronoi diagramm
                Matlab.Cmd("[V, C] = voronoin(Nodes);");

                // output (export from matlab)
                int[][] VocellVertexIndex = new int[nodes.NoOfRows][];
                Matlab.GetStaggeredIntArray(VocellVertexIndex, "C");
                Matlab.GetMatrix(null, "V");

                // run matlab
                Matlab.Execute(false);

                // Vertices: List<Vertex>
                //---------------------------
                MultidimensionalArray matlabVertexCoordinates = (MultidimensionalArray)(Matlab.OutputObjects["V"]);
                List <Vertex>         vertexCoordinates       = new List <Vertex>(matlabVertexCoordinates.NoOfRows);
                for (int i = 0; i < matlabVertexCoordinates.NoOfRows; ++i)
                {
                    Vertex tmp = new Vertex();
                    tmp.Position = new Vector(matlabVertexCoordinates.GetRow(i));
                    tmp.ID       = i;
                    vertexCoordinates.Add(tmp);
                }

                //Cells: int[][]
                //--------------------------------------------
                // correct indices (1-based index to 0-based index)

                for (int i = 0; i < VocellVertexIndex.Length; ++i)
                {
                    for (int k = 0; k < VocellVertexIndex[i].Length; k++)
                    {
                        VocellVertexIndex[i][k]--;
                    }
                }

                stopwatch.Stop();
                Console.WriteLine(stopwatch.ElapsedMilliseconds);
                //Convert to mesh data types
                //--------------------------------------------
                mesh = new IntersectionMesh(new OrderedMatlabMesh(VocellVertexIndex, vertexCoordinates));
            }

            return(mesh);
        }
예제 #5
0
        public static void SubSelection(
            [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg,
            [Values(2)] int DGOrder,
            [Values(MatrixShape.full_var_spec, MatrixShape.full_spec, MatrixShape.full_var, MatrixShape.full)] MatrixShape MShape,
            [Values(4)] int Res)
        {
            Utils.TestInit((int)UseXdg, DGOrder, (int)MShape, Res);
            Console.WriteLine("SubSelection({0},{1},{2},{3})", UseXdg, DGOrder, MShape, Res);

            //Arrange --- create test matrix, MG mapping
            MultigridOperator mgo = Utils.CreateTestMGOperator(UseXdg, DGOrder, MShape, Res);
            MultigridMapping  map = mgo.Mapping;
            BlockMsrMatrix    M   = mgo.OperatorMatrix;

            //Arrange --- get mask
            int[] cells = Utils.GetCellsOfOverlappingTestBlock(map);
            Array.Sort(cells);
            var sbs = new SubBlockSelector(map);

            sbs.CellSelector(cells, false);
            BlockMsrMatrix M_ext = BlockMask.GetAllExternalRows(map, M);
            var            mask  = new BlockMask(sbs, M_ext);

            //Arrange --- get GlobalIdxList
            int[]  idc  = Utils.GetIdcOfSubBlock(map, cells);
            bool[] coup = Utils.SetCoupling(MShape);

            var M_sub = mask.GetSubBlockMatrix(M, false, coup[0], coup[1]);

            var infNorm = MultidimensionalArray.Create(4, 1);
            int rank    = map.MpiRank;

            using (BatchmodeConnector matlab = new BatchmodeConnector()) {
                double[] GlobIdx = idc.Count().ForLoop(i => (double)idc[i] + 1.0);
                Assert.IsTrue(GlobIdx.Length == M_sub.NoOfRows);

                matlab.PutSparseMatrix(M, "M");
                // note: M_sub lives on Comm_Self, therefore we have to distinguish between procs ...
                matlab.PutSparseMatrixRankExclusive(M_sub, "M_sub");
                matlab.PutVectorRankExclusive(GlobIdx, "Idx");
                matlab.Cmd("M_0 = full(M(Idx_0, Idx_0));");
                matlab.Cmd("M_1 = full(M(Idx_1, Idx_1));");
                matlab.Cmd("M_2 = full(M(Idx_2, Idx_2));");
                matlab.Cmd("M_3 = full(M(Idx_3, Idx_3));");
                matlab.Cmd("n=[0; 0; 0; 0];");
                matlab.Cmd("n(1,1)=norm(M_0-M_sub_0,inf);");
                matlab.Cmd("n(2,1)=norm(M_1-M_sub_1,inf);");
                matlab.Cmd("n(3,1)=norm(M_2-M_sub_2,inf);");
                matlab.Cmd("n(4,1)=norm(M_3-M_sub_3,inf);");
                matlab.GetMatrix(infNorm, "n");
                matlab.Execute();
            }
            Assert.IsTrue(infNorm[rank, 0] == 0.0);
        }
예제 #6
0
        private void OperatorAnalysis()
        {
            AggregationGridBasis[][] XAggB = AggregationGridBasis.CreateSequence(base.MultigridSequence, u.Mapping.BasisS);

            XAggB.UpdateXdgAggregationBasis(this.Op_Agglomeration);

            var MultigridOp = new MultigridOperator(XAggB, this.u.Mapping,
                                                    this.Op_Matrix,
                                                    this.Op_mass.GetMassMatrix(new UnsetteledCoordinateMapping(this.u.Basis), false),
                                                    OpConfig);

            var PcOpMatrix = MultigridOp.OperatorMatrix;
            //PcOpMatrix.SaveToTextFileSparse("C:\\temp\\Xpoisson.txt");

            MultidimensionalArray ret = MultidimensionalArray.Create(1, 4);

            using (BatchmodeConnector bmc = new BatchmodeConnector()) {
                bmc.PutSparseMatrix(PcOpMatrix, "OpMtx");
                bmc.Cmd("OpMtxSym = 0.5*(OpMtx + OpMtx');");
                bmc.Cmd("condNo = condest(OpMtxSym);");
                bmc.Cmd("eigMaxi = eigs(OpMtxSym,1,'lm')");
                bmc.Cmd("eigMini = eigs(OpMtxSym,1,'sm')");
                bmc.Cmd("lasterr");
                bmc.Cmd("[V,r]=chol(OpMtxSym);");
                bmc.Cmd("ret = [condNo, eigMaxi, eigMini, r]");
                bmc.GetMatrix(ret, "ret");

                bmc.Execute(false);
            }

            double condNo  = ret[0, 0];
            double eigMaxi = ret[0, 1];
            double eigMini = ret[0, 2];
            double posDef  = ret[0, 3] == 0 ? 1 : 0;

            Console.WriteLine("Condition number: {0:0.####E-00}", condNo);

            if (posDef == 0.0)
            {
                Console.WriteLine("WARNING: Operator matrix is not positive definite.");
            }

            base.QueryHandler.ValueQuery("condNo", condNo, false);
            base.QueryHandler.ValueQuery("eigMaxi", eigMaxi, false);
            base.QueryHandler.ValueQuery("eigMini", eigMini, false);
            base.QueryHandler.ValueQuery("posDef", posDef, false);
        }
예제 #7
0
        /// <summary>
        ///
        /// </summary>
        public void AnalyzeOperators(out MultidimensionalArray ret)
        {
            ret = MultidimensionalArray.Create(1, 7);
            // MultidimensionalArray ret = MultidimensionalArray.Create(1, 4);
            Console.WriteLine("Calling MATLAB/Octave...");
            using (BatchmodeConnector bmc = new BatchmodeConnector()) {
                bmc.PutSparseMatrix(OpMatrix, "OpMatrix");
                bmc.Cmd("condNoOpMatrix = condest(OpMatrix)");
                bmc.Cmd("OpRank = rank(full(OpMatrix))");
                bmc.Cmd("OpSize = size(OpMatrix)");
                bmc.Cmd("eigiMaxi = eigs(OpMatrix,1,'lm')");
                bmc.Cmd("eigiMini = eigs(OpMatrix,1,'sm')");
                bmc.Cmd("lasterr");
                bmc.Cmd("[V,r]=chol(OpMatrix);");
                bmc.Cmd("ret = [condNoOpMatrix, eigiMaxi, eigiMini, r, OpRank, OpSize]");
                bmc.GetMatrix(ret, "ret");

                bmc.Execute(true);
            }

            double condNoOpMatrix = ret[0, 0];
            double eigiMaxi       = ret[0, 1];
            double eigiMini       = ret[0, 2];
            double posDef         = ret[0, 3] == 0 ? 1 : 0;

            Console.WriteLine("Condition number operator: {0:0.####E-00}", condNoOpMatrix);

            if (posDef == 0.0)
            {
                Console.WriteLine("WARNING: Operator matrix is not positive definite.");
            }
            else
            {
                Console.WriteLine("Good news: Operator matrix seems to be positive definite.");
            }
        }
예제 #8
0
        public static void SpMVTest(
            [Values(XDGusage.none, XDGusage.mixed1, XDGusage.mixed2, XDGusage.all)] XDGusage UseXdg,
            [Values(1, 3)] int DGOrder,
            [Values(false, true)] bool compressL1,
            [Values(false, true)] bool compressL2)
        {
            unsafe
            {
                int[] Params = new int[8], ParamsGlob = new int[8];
                fixed(int *pParams = Params, pParamsGlob = ParamsGlob)
                {
                    pParams[0] = (int)UseXdg;
                    pParams[1] = DGOrder;
                    pParams[2] = compressL1 ? 1 : 0;
                    pParams[3] = compressL2 ? 1 : 0;
                    pParams[4] = -pParams[0];
                    pParams[5] = -pParams[1];
                    pParams[6] = -pParams[2];
                    pParams[7] = -pParams[3];

                    csMPI.Raw.Allreduce((IntPtr)pParams, (IntPtr)pParamsGlob, 8, csMPI.Raw._DATATYPE.INT, csMPI.Raw._OP.MIN, csMPI.Raw._COMM.WORLD);
                }

                int[] ParamsMin = ParamsGlob.GetSubVector(0, 4);
                int[] ParamsMax = ParamsGlob.GetSubVector(4, 4);
                for (int i = 0; i < 4; i++)
                {
                    if (Params[i] != ParamsMin[i])
                    {
                        throw new ApplicationException();
                    }
                    if (Params[i] != -ParamsMax[i])
                    {
                        throw new ApplicationException();
                    }
                }

                Console.WriteLine("SpMVTest({0},{1},{2},{3})", UseXdg, DGOrder, compressL1, compressL2);
            }

            using (var solver = new Matrix_MPItestMain()
            {
                m_UseXdg = UseXdg, m_DGorder = DGOrder
            }) {
                // create the test data
                // ====================

                BoSSS.Solution.Application.CommandLineOptions opts = null;
                //opts = new BoSSS.Solution.Application.CommandLineOptions();
                solver.Init(null, opts);
                solver.RunSolverMode();

                Stopwatch stw = new Stopwatch();
                stw.Reset();

                BlockMsrMatrix M = solver.OperatorMatrix;
                double[]       B = new double[M.RowPartitioning.LocalLength];
                double[]       X = new double[M.ColPartition.LocalLength];

                Random R = new Random();
                for (int i = 0; i < X.Length; i++)
                {
                    X[i] = R.NextDouble();
                }
                for (int i = 0; i < B.Length; i++)
                {
                    B[i] = R.NextDouble();
                }

                double[] Bb4 = B.CloneAs();

                double RefNorm = B.L2NormPow2().MPISum().Sqrt() * 1e-10;

                stw.Start();

                M.SpMV(1.6, X, 0.5, B);

                stw.Stop();

                //M.SaveToTextFileSparse(@"C:\tmp\M.txt");
                //M11.SaveToTextFileSparse(@"C:\tmp\M11.txt");
                //M12.SaveToTextFileSparse(@"C:\tmp\M12.txt");
                //M21.SaveToTextFileSparse(@"C:\tmp\M21.txt");
                //M22.SaveToTextFileSparse(@"C:\tmp\M22.txt");
                //M22xM21.SaveToTextFileSparse(@"C:\tmp\M22xM21.txt");


                using (var MatlabRef = new BatchmodeConnector()) {
                    MultidimensionalArray CheckRes = MultidimensionalArray.Create(1, 1);

                    MatlabRef.PutSparseMatrix(M, "M");
                    MatlabRef.PutVector(Bb4, "Bref");
                    MatlabRef.PutVector(B, "B");
                    MatlabRef.PutVector(X, "X");


                    MatlabRef.Cmd("Bref = Bref*0.5 + M*X*1.6;");
                    MatlabRef.Cmd("errB = norm(B - Bref, 2);");

                    MatlabRef.Cmd("CheckRes = [errB];");
                    MatlabRef.GetMatrix(CheckRes, "CheckRes");



                    MatlabRef.Execute();

                    Console.WriteLine("Matlab check SpMV: " + CheckRes[0, 0]);


                    Assert.LessOrEqual(CheckRes[0, 0], RefNorm, "Error in SpMV");
                }


                Console.WriteLine("Time spend in matrix operations: " + stw.Elapsed.TotalSeconds + " sec.");

                TotTime_MatrixOp += stw.Elapsed;
            }
        }
예제 #9
0
        public static void SubMatrixTest(
            [Values(XDGusage.none, XDGusage.mixed1, XDGusage.mixed2, XDGusage.all)] XDGusage UseXdg,
            [Values(1, 3)] int DGOrder,
            [Values(false, true)] bool compressL1,
            [Values(false, true)] bool compressL2)
        {
            unsafe
            {
                int[] Params = new int[8], ParamsGlob = new int[8];
                fixed(int *pParams = Params, pParamsGlob = ParamsGlob)
                {
                    pParams[0] = (int)UseXdg;
                    pParams[1] = DGOrder;
                    pParams[2] = compressL1 ? 1 : 0;
                    pParams[3] = compressL2 ? 1 : 0;
                    pParams[4] = -pParams[0];
                    pParams[5] = -pParams[1];
                    pParams[6] = -pParams[2];
                    pParams[7] = -pParams[3];

                    csMPI.Raw.Allreduce((IntPtr)pParams, (IntPtr)pParamsGlob, 8, csMPI.Raw._DATATYPE.INT, csMPI.Raw._OP.MIN, csMPI.Raw._COMM.WORLD);
                }

                int[] ParamsMin = ParamsGlob.GetSubVector(0, 4);
                int[] ParamsMax = ParamsGlob.GetSubVector(4, 4);
                for (int i = 0; i < 4; i++)
                {
                    if (Params[i] != ParamsMin[i])
                    {
                        throw new ApplicationException();
                    }
                    if (Params[i] != -ParamsMax[i])
                    {
                        throw new ApplicationException();
                    }
                }

                Console.WriteLine("SubMatrixTest({0},{1},{2},{3})", UseXdg, DGOrder, compressL1, compressL2);
            }

            using (var solver = new Matrix_MPItestMain()
            {
                m_UseXdg = UseXdg, m_DGorder = DGOrder
            }) {
                // create the test data
                // ====================

                BoSSS.Solution.Application.CommandLineOptions opts = null;
                //opts = new BoSSS.Solution.Application.CommandLineOptions();
                solver.Init(null, opts);
                solver.RunSolverMode();

                Stopwatch stw = new Stopwatch();
                stw.Reset();
                stw.Start();

                BlockMsrMatrix M = solver.OperatorMatrix;

                int[] Ilist1 = solver.ProblemMapping.GetSubvectorIndices(false, 0);
                int[] Ilist2 = solver.ProblemMapping.GetSubvectorIndices(false, 1);

                foreach (int i in Ilist1)
                {
                    Assert.IsTrue(solver.ProblemMapping.IsInLocalRange(i));
                }
                foreach (int i in Ilist2)
                {
                    Assert.IsTrue(solver.ProblemMapping.IsInLocalRange(i));
                }

                var Blk1 = solver.ProblemMapping.GetSubBlocking(Ilist1, csMPI.Raw._COMM.WORLD, compressL1 ? -1 : 0);
                var Blk2 = solver.ProblemMapping.GetSubBlocking(Ilist2, csMPI.Raw._COMM.WORLD, compressL2 ? -1 : 0);



                int[] Tlist1 = compressL1 ? default(int[]) : Blk1.GetOccupiedIndicesList();
                int[] Tlist2 = compressL2 ? default(int[]) : Blk2.GetOccupiedIndicesList();
                if (Tlist1 != null)
                {
                    Assert.AreEqual(Tlist1.Length, Ilist1.Length);
                    foreach (int i in Tlist1)
                    {
                        Assert.IsTrue(Blk1.IsInLocalRange(i));
                    }
                }
                if (Tlist2 != null)
                {
                    Assert.AreEqual(Tlist2.Length, Ilist2.Length);
                    foreach (int i in Tlist2)
                    {
                        Assert.IsTrue(Blk2.IsInLocalRange(i));
                    }
                }
                BlockMsrMatrix M11 = new BlockMsrMatrix(Blk1, Blk1);
                BlockMsrMatrix M12 = new BlockMsrMatrix(Blk1, Blk2);
                BlockMsrMatrix M21 = new BlockMsrMatrix(Blk2, Blk1);
                BlockMsrMatrix M22 = new BlockMsrMatrix(Blk2, Blk2);

                M.AccSubMatrixTo(1.0, M11, Ilist1, Tlist1, Ilist1, Tlist1);
                M.AccSubMatrixTo(1.0, M12, Ilist1, Tlist1, Ilist2, Tlist2);
                M.AccSubMatrixTo(1.0, M21, Ilist2, Tlist2, Ilist1, Tlist1);
                M.AccSubMatrixTo(1.0, M22, Ilist2, Tlist2, Ilist2, Tlist2);

                BlockMsrMatrix restored_M = new BlockMsrMatrix(M._RowPartitioning, M._ColPartitioning);
                int[]          Idx1       = compressL1 ? Blk1.LocalLength.ForLoop(i => i + Blk1.i0) : Tlist1;
                int[]          Idx2       = compressL2 ? Blk2.LocalLength.ForLoop(i => i + Blk2.i0) : Tlist2;
                M11.AccSubMatrixTo(1.0, restored_M, Idx1, Ilist1, Idx1, Ilist1);
                M12.AccSubMatrixTo(1.0, restored_M, Idx1, Ilist1, Idx2, Ilist2);
                M21.AccSubMatrixTo(1.0, restored_M, Idx2, Ilist2, Idx1, Ilist1);
                M22.AccSubMatrixTo(1.0, restored_M, Idx2, Ilist2, Idx2, Ilist2);

                // test transpose-operator
                var M_TT   = M.Transpose().Transpose();
                var M11_TT = M11.Transpose().Transpose();
                var M12_TT = M12.Transpose().Transpose();
                var M21_TT = M21.Transpose().Transpose();
                var M22_TT = M22.Transpose().Transpose();
                M_TT.Acc(-1.0, M);
                M11_TT.Acc(-1.0, M11);
                M12_TT.Acc(-1.0, M12);
                M21_TT.Acc(-1.0, M21);
                M22_TT.Acc(-1.0, M22);
                double M_TT_norm   = M_TT.InfNorm();
                double M11_TT_norm = M11_TT.InfNorm();
                double M12_TT_norm = M12_TT.InfNorm();
                double M21_TT_norm = M21_TT.InfNorm();
                double M22_TT_norm = M22_TT.InfNorm();
                Assert.IsTrue(M_TT_norm == 0.0, "Transpose^2 is not identity.");
                Assert.IsTrue(M11_TT_norm == 0.0, "Transpose^2 is not identity.");
                Assert.IsTrue(M12_TT_norm == 0.0, "Transpose^2 is not identity.");
                Assert.IsTrue(M21_TT_norm == 0.0, "Transpose^2 is not identity.");
                Assert.IsTrue(M22_TT_norm == 0.0, "Transpose^2 is not identity.");

                //M.SaveToTextFileSparse(@"C:\tmp\M.txt");
                //M11.SaveToTextFileSparse(@"C:\tmp\M11.txt");
                //M12.SaveToTextFileSparse(@"C:\tmp\M12.txt");
                //M21.SaveToTextFileSparse(@"C:\tmp\M21.txt");
                //M22.SaveToTextFileSparse(@"C:\tmp\M22.txt");
                //restored_M.SaveToTextFileSparse(@"C:\tmp\Mr.txt");

                stw.Stop();

                using (var MatlabRef = new BatchmodeConnector()) {
                    MatlabRef.PutVector(Ilist1.Select(i => (double)i + 1.0).ToArray(), "Ilist1");
                    MatlabRef.PutVector(Ilist2.Select(i => (double)i + 1.0).ToArray(), "Ilist2");
                    MatlabRef.PutVector(Tlist1 == null ? Ilist1.Length.ForLoop(i => (double)i + 1.0 + Blk1.i0) : Tlist1.Select(i => (double)i + 1.0).ToArray(), "Tlist1");
                    MatlabRef.PutVector(Tlist2 == null ? Ilist2.Length.ForLoop(i => (double)i + 1.0 + Blk2.i0) : Tlist2.Select(i => (double)i + 1.0).ToArray(), "Tlist2");

                    MultidimensionalArray CheckRes = MultidimensionalArray.Create(1, 4);

                    MatlabRef.PutSparseMatrix(M, "M");
                    MatlabRef.PutSparseMatrix(M11, "M11");
                    MatlabRef.PutSparseMatrix(M12, "M12");
                    MatlabRef.PutSparseMatrix(M21, "M21");
                    MatlabRef.PutSparseMatrix(M22, "M22");

                    MatlabRef.Cmd("L1 = {0};", Blk1.TotalLength);
                    MatlabRef.Cmd("L2 = {0};", Blk2.TotalLength);
                    MatlabRef.Cmd("refM11 = sparse(L1, L1);");
                    MatlabRef.Cmd("refM12 = sparse(L1, L2);");
                    MatlabRef.Cmd("refM21 = sparse(L2, L1);");
                    MatlabRef.Cmd("refM22 = sparse(L2, L2);");

                    MatlabRef.Cmd("refM11(Tlist1, Tlist1) = M(Ilist1, Ilist1);");
                    MatlabRef.Cmd("refM12(Tlist1, Tlist2) = M(Ilist1, Ilist2);");
                    MatlabRef.Cmd("refM21(Tlist2, Tlist1) = M(Ilist2, Ilist1);");
                    MatlabRef.Cmd("refM22(Tlist2, Tlist2) = M(Ilist2, Ilist2);");

                    MatlabRef.Cmd("err11 = norm(refM11 - M11, inf);");
                    MatlabRef.Cmd("err12 = norm(refM12 - M12, inf);");
                    MatlabRef.Cmd("err21 = norm(refM21 - M21, inf);");
                    MatlabRef.Cmd("err22 = norm(refM22 - M22, inf);");

                    MatlabRef.Cmd("CheckRes = [err11, err12, err21, err22];");
                    MatlabRef.GetMatrix(CheckRes, "CheckRes");

                    MatlabRef.Execute();

                    Console.WriteLine("Matlab check 11: " + CheckRes[0, 0]);
                    Console.WriteLine("Matlab check 12: " + CheckRes[0, 1]);
                    Console.WriteLine("Matlab check 21: " + CheckRes[0, 2]);
                    Console.WriteLine("Matlab check 22: " + CheckRes[0, 3]);

                    Assert.IsTrue(CheckRes[0, 0] == 0.0);
                    Assert.IsTrue(CheckRes[0, 1] == 0.0);
                    Assert.IsTrue(CheckRes[0, 2] == 0.0);
                    Assert.IsTrue(CheckRes[0, 3] == 0.0);
                }

                stw.Start();

                restored_M.Acc(-1.0, M);
                double err = restored_M.InfNorm();
                Console.WriteLine("Submatrix operations error: " + err);
                Assert.IsTrue(err == 0.0);

                restored_M.Clear();
                restored_M.Acc(1.0, M);
                IMutuableMatrixEx_Extensions.Acc(restored_M, -1.0, M);
                double err2 = restored_M.InfNorm();
                Console.WriteLine("Submatrix operations error: " + err2);
                Assert.IsTrue(err2 == 0.0);

                stw.Stop();

                Console.WriteLine("Time spend in matrix operations: " + stw.Elapsed.TotalSeconds + " sec.");

                TotTime_MatrixOp += stw.Elapsed;
            }
        }
예제 #10
0
        /// <summary>
        ///
        /// </summary>
        public void AnalyzeOperators(out MultidimensionalArray ret)
        {
            int length = OpMatrix.NoOfRows / Extension.Basis.Length;
            //int[,] PatternMatrix = new int[length, length]; // lässt sich besser anschauen?
            MsrMatrix PatternMatrix = new MsrMatrix(length);

            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < length; j++)
                {
                    if (OpMatrix[i * Extension.Basis.Length, j *Extension.Basis.Length] != 0)
                    {
                        PatternMatrix[i, j] = 1;
                    }
                }
            }



            ret = MultidimensionalArray.Create(1, 4);
            Console.WriteLine("Calling MATLAB/Octave...");
            MultidimensionalArray L = MultidimensionalArray.Create(PatternMatrix.NoOfRows, PatternMatrix.NoOfRows);
            MultidimensionalArray U = MultidimensionalArray.Create(PatternMatrix.NoOfRows, PatternMatrix.NoOfRows);
            MultidimensionalArray P = MultidimensionalArray.Create(PatternMatrix.NoOfRows, PatternMatrix.NoOfRows);

            using (BatchmodeConnector bmc = new BatchmodeConnector()) {
                bmc.PutSparseMatrix(PatternMatrix, "PatternMatrix");
                bmc.Cmd("[L, U, P] = lu(PatternMatrix);");


                bmc.PutSparseMatrix(OpMatrix, "OpMatrix");
                bmc.Cmd("condNoOpMatrix = condest(OpMatrix);");
                bmc.Cmd("eigiMaxi = eigs(OpMatrix,1,'lm')");
                bmc.Cmd("eigiMini = eigs(OpMatrix,1,'sm')");
                bmc.Cmd("lasterr");
                bmc.Cmd("[V,r]=chol(OpMatrix);");
                bmc.Cmd("ret = [condNoOpMatrix, eigiMaxi, eigiMini, r]");

                bmc.GetMatrix(L, "full(L)");
                bmc.GetMatrix(U, "full(U)");
                bmc.GetMatrix(P, "full(P)");
                bmc.GetMatrix(ret, "ret");

                bmc.Execute(true);
            }
            //PatternMatrix.SaveToTextFile("Patternmatrix.txt");
            //PatternMatrix.SaveToTextFileSparse("PatternmatrixSparse.txt");

            double condNoOpMatrix = ret[0, 0];
            double eigiMaxi       = ret[0, 1];
            double eigiMini       = ret[0, 2];
            double posDef         = ret[0, 3] == 0 ? 1 : 0;

            Console.WriteLine("Condition number operator: {0:0.####E-00}", condNoOpMatrix);

            if (posDef == 0.0)
            {
                Console.WriteLine("WARNING: Operator matrix is not positive definite.");
            }
            else
            {
                Console.WriteLine("Good news: Operator matrix seems to be positive definite.");
            }
        }
예제 #11
0
        public static void MultiplyTest(
            [Values(XDGusage.none, XDGusage.mixed1, XDGusage.mixed2, XDGusage.all)] XDGusage UseXdg,
            [Values(1, 3)] int DGOrder,
            [Values(false, true)] bool compressL1,
            [Values(false, true)] bool compressL2)
        {
            unsafe
            {
                int[] Params = new int[8], ParamsGlob = new int[8];
                fixed(int *pParams = Params, pParamsGlob = ParamsGlob)
                {
                    pParams[0] = (int)UseXdg;
                    pParams[1] = DGOrder;
                    pParams[2] = compressL1 ? 1 : 0;
                    pParams[3] = compressL2 ? 1 : 0;
                    pParams[4] = -pParams[0];
                    pParams[5] = -pParams[1];
                    pParams[6] = -pParams[2];
                    pParams[7] = -pParams[3];

                    csMPI.Raw.Allreduce((IntPtr)pParams, (IntPtr)pParamsGlob, 8, csMPI.Raw._DATATYPE.INT, csMPI.Raw._OP.MIN, csMPI.Raw._COMM.WORLD);
                }

                int[] ParamsMin = ParamsGlob.GetSubVector(0, 4);
                int[] ParamsMax = ParamsGlob.GetSubVector(4, 4);
                for (int i = 0; i < 4; i++)
                {
                    if (Params[i] != ParamsMin[i])
                    {
                        throw new ApplicationException();
                    }
                    if (Params[i] != -ParamsMax[i])
                    {
                        throw new ApplicationException();
                    }
                }

                Console.WriteLine("MultiplyTest({0},{1},{2},{3})", UseXdg, DGOrder, compressL1, compressL2);
            }

            using (var solver = new Matrix_MPItestMain()
            {
                m_UseXdg = UseXdg, m_DGorder = DGOrder
            }) {
                // create the test data
                // ====================

                solver.Init(null);
                solver.RunSolverMode();

                Stopwatch stw = new Stopwatch();
                stw.Reset();
                stw.Start();

                BlockMsrMatrix M = solver.OperatorMatrix;

                int[] Ilist1 = solver.ProblemMapping.GetSubvectorIndices(false, 0);
                int[] Ilist2 = solver.ProblemMapping.GetSubvectorIndices(false, 1);

                foreach (int i in Ilist1)
                {
                    Assert.IsTrue(solver.ProblemMapping.IsInLocalRange(i));
                }
                foreach (int i in Ilist2)
                {
                    Assert.IsTrue(solver.ProblemMapping.IsInLocalRange(i));
                }

                var Blk1 = solver.ProblemMapping.GetSubBlocking(Ilist1, csMPI.Raw._COMM.WORLD, compressL1 ? -1 : 0);
                var Blk2 = solver.ProblemMapping.GetSubBlocking(Ilist2, csMPI.Raw._COMM.WORLD, compressL2 ? -1 : 0);



                int[] Tlist1 = compressL1 ? default(int[]) : Blk1.GetOccupiedIndicesList();
                int[] Tlist2 = compressL2 ? default(int[]) : Blk2.GetOccupiedIndicesList();
                if (Tlist1 != null)
                {
                    Assert.AreEqual(Tlist1.Length, Ilist1.Length);
                    foreach (int i in Tlist1)
                    {
                        Assert.IsTrue(Blk1.IsInLocalRange(i));
                    }
                }
                if (Tlist2 != null)
                {
                    Assert.AreEqual(Tlist2.Length, Ilist2.Length);
                    foreach (int i in Tlist2)
                    {
                        Assert.IsTrue(Blk2.IsInLocalRange(i));
                    }
                }
                BlockMsrMatrix M11 = new BlockMsrMatrix(Blk1, Blk1);
                BlockMsrMatrix M12 = new BlockMsrMatrix(Blk1, Blk2);
                BlockMsrMatrix M21 = new BlockMsrMatrix(Blk2, Blk1);
                BlockMsrMatrix M22 = new BlockMsrMatrix(Blk2, Blk2);

                M.AccSubMatrixTo(1.0, M11, Ilist1, Tlist1, Ilist1, Tlist1);
                M.AccSubMatrixTo(1.0, M12, Ilist1, Tlist1, Ilist2, Tlist2);
                M.AccSubMatrixTo(1.0, M21, Ilist2, Tlist2, Ilist1, Tlist1);
                M.AccSubMatrixTo(1.0, M22, Ilist2, Tlist2, Ilist2, Tlist2);

                /*
                 * MultidimensionalArray CheckRes2 = MultidimensionalArray.Create(1, 4);
                 * using (var MatlabRef = new BatchmodeConnector()) {
                 *
                 *  MatlabRef.PutVector(Ilist1.Select(i => (double)i + 1.0).ToArray(), "Ilist1");
                 *  MatlabRef.PutVector(Ilist2.Select(i => (double)i + 1.0).ToArray(), "Ilist2");
                 *  MatlabRef.PutVector(Tlist1 == null ? Ilist1.Length.ForLoop(i => (double)i + 1.0 + Blk1.i0) : Tlist1.Select(i => (double)i + 1.0).ToArray(), "Tlist1");
                 *  MatlabRef.PutVector(Tlist2 == null ? Ilist2.Length.ForLoop(i => (double)i + 1.0 + Blk2.i0) : Tlist2.Select(i => (double)i + 1.0).ToArray(), "Tlist2");
                 *
                 *  MatlabRef.PutSparseMatrix(solver.AltOperatorMatrix, "M");
                 *
                 *
                 *  MatlabRef.Cmd("L1 = {0};", Blk1.TotalLength);
                 *  MatlabRef.Cmd("L2 = {0};", Blk2.TotalLength);
                 *  //MatlabRef.Cmd("refM11 = sparse(L1, L1);");
                 *  //MatlabRef.Cmd("refM12 = sparse(L1, L2);");
                 *  MatlabRef.Cmd("refM21 = sparse(L2, L1);");
                 *  //MatlabRef.Cmd("refM22 = sparse(L2, L2);");
                 *
                 *  //MatlabRef.Cmd("refM11(Tlist1, Tlist1) = M(Ilist1, Ilist1);");
                 *  //MatlabRef.Cmd("refM12(Tlist1, Tlist2) = M(Ilist1, Ilist2);");
                 *  MatlabRef.Cmd("refM21(Tlist2, Tlist1) = M(Ilist2, Ilist1);");
                 *  //MatlabRef.Cmd("refM22(Tlist2, Tlist2) = M(Ilist2, Ilist2);");
                 *
                 *  //MatlabRef.Cmd("err11 = norm(refM11 - M11, inf);");
                 *  //MatlabRef.Cmd("err12 = norm(refM12 - M12, inf);");
                 *  //MatlabRef.Cmd("err21 = norm(refM21 - M21, inf);");
                 *  //MatlabRef.Cmd("err22 = norm(refM22 - M22, inf);");
                 *
                 *  MatlabRef.Cmd("CheckRes = [refM21(1339, 1321), 0.0, 1.567, 0 ];");
                 *  MatlabRef.GetMatrix(CheckRes2, "CheckRes");
                 *
                 *  MatlabRef.Execute();
                 * }
                 */

                // test multipliation (later verified by matlab)
                BlockMsrMatrix M11xM12 = new BlockMsrMatrix(M11._RowPartitioning, M12._ColPartitioning);
                M11xM12.Acc(1.0, M12);
                BlockMsrMatrix.Multiply(M11xM12, M11, M12);

                BlockMsrMatrix M22xM21 = new BlockMsrMatrix(M22._RowPartitioning, M21._ColPartitioning);
                BlockMsrMatrix.Multiply(M22xM21, M22, M21);
                double ProdNorm = M22xM21.InfNorm();



                stw.Stop();

                //M.SaveToTextFileSparse(@"C:\tmp\M.txt");
                //M11.SaveToTextFileSparse(@"C:\tmp\M11.txt");
                //M12.SaveToTextFileSparse(@"C:\tmp\M12.txt");
                //M21.SaveToTextFileSparse(@"C:\tmp\M21.txt");
                //M22.SaveToTextFileSparse(@"C:\tmp\M22.txt");
                //M22xM21.SaveToTextFileSparse(@"C:\tmp\M22xM21.txt");


                using (var MatlabRef = new BatchmodeConnector()) {
                    MultidimensionalArray CheckRes = MultidimensionalArray.Create(1, 4);

                    MatlabRef.PutSparseMatrix(M11, "M11");
                    MatlabRef.PutSparseMatrix(M12, "M12");
                    MatlabRef.PutSparseMatrix(M21, "M21");
                    MatlabRef.PutSparseMatrix(M22, "M22");
                    MatlabRef.PutSparseMatrix(M11xM12, "M11xM12");
                    MatlabRef.PutSparseMatrix(M22xM21, "M22xM21");

                    MatlabRef.Cmd("refM11xM12 = M12 + M11*M12;");
                    MatlabRef.Cmd("refM22xM21 = M22*M21;");

                    MatlabRef.Cmd("err1112 = norm(refM11xM12 - M11xM12, inf);");
                    MatlabRef.Cmd("err2221 = norm(refM22xM21 - M22xM21, inf);");

                    MatlabRef.Cmd("CheckRes = [err1112, err2221, 0, 0];");
                    MatlabRef.GetMatrix(CheckRes, "CheckRes");

                    MatlabRef.Execute();

                    Console.WriteLine("Matlab check M11*M12: " + CheckRes[0, 0]);
                    Console.WriteLine("Matlab check M22*M21: " + CheckRes[0, 1]);

                    Assert.IsTrue(CheckRes[0, 0] == 0.0);
                    Assert.IsTrue(CheckRes[0, 1] < 1.0e-10 * ProdNorm);
                    //Assert.IsTrue(CheckRes[0, 2] == 0.0);
                    //Assert.IsTrue(CheckRes[0, 3] == 0.0);
                }


                Console.WriteLine("Time spend in matrix operations: " + stw.Elapsed.TotalSeconds + " sec.");

                TotTime_MatrixOp += stw.Elapsed;
            }
        }
예제 #12
0
        /// <summary>
        /// Spatial operator matrix analysis method
        /// </summary>
        public void SpatialOperatorMatrixAnalysis(bool CheckAssertions, int AnalysisLevel)
        {
            using (var solver = new Rheology()) {
                int D = solver.Grid.SpatialDimension;

                if (AnalysisLevel < 0 || AnalysisLevel > 2)
                {
                    throw new ArgumentException();
                }


                BlockMsrMatrix OpMatrix;
                double[]       OpAffine;

                solver.AssembleMatrix(out OpMatrix, out OpAffine, solver.CurrentSolution.Mapping.ToArray(), true);


                // =============================
                // AnalysisLevel 0
                // =============================
                {
                    var OpMatrixT = OpMatrix.Transpose();

                    CoordinateVector TestVec = new CoordinateVector(solver.CurrentSolution.Mapping.Fields.Select(f => f.CloneAs()).ToArray());

                    double testsumPos = 0.0;
                    double testsumNeg = 0.0;
                    for (int rnd_seed = 0; rnd_seed < 20; rnd_seed++)
                    {
                        // fill the pressure components of the test vector
                        TestVec.Clear();
                        Random  rnd      = new Random(rnd_seed);
                        DGField Pressack = TestVec.Mapping.Fields[D] as DGField;
                        int     J        = solver.GridData.iLogicalCells.NoOfLocalUpdatedCells;
                        for (int j = 0; j < J; j++)
                        {
                            int N = Pressack.Basis.GetLength(j);

                            for (int n = 0; n < N; n++)
                            {
                                Pressack.Coordinates[j, n] = rnd.NextDouble();
                            }
                        }

                        // Gradient times P:
                        double[] R1 = new double[TestVec.Count];
                        OpMatrix.SpMV(1.0, TestVec, 0.0, R1);       // R1 = Grad * P
                        //Console.WriteLine("L2 of 'Grad * P': " + R1.L2Norm());

                        // transpose of Divergence times P:
                        double[] R2 = new double[TestVec.Count];
                        OpMatrix.SpMV(1.0, TestVec, 0.0, R2);      // R2 = divT * P
                        //Console.WriteLine("L2 of 'divT * P': " + R2.L2Norm());

                        TestVec.Clear();
                        TestVec.Acc(1.0, R1);
                        TestVec.Acc(1.0, R2);


                        // analyze!
                        testsumNeg += GenericBlas.L2Dist(R1, R2);

                        R2.ScaleV(-1.0);
                        testsumPos += GenericBlas.L2Dist(R1, R2);
                    }

                    Console.WriteLine("Pressure/Divergence Symmetry error in all tests (+): " + testsumPos);
                    Console.WriteLine("Pressure/Divergence Symmetry error in all tests (-): " + testsumNeg);

                    if (CheckAssertions)
                    {
                        Assert.LessOrEqual(Math.Abs(testsumNeg), testsumPos * 1.0e-13);
                    }
                }


                // =============================
                // AnalysisLevel 1 and 2
                // =============================

                if (AnalysisLevel > 0)
                {
                    AggregationGridBasis[][] MgBasis = AggregationGridBasis.CreateSequence(solver.MultigridSequence, solver.CurrentSolution.Mapping.BasisS);

                    MultigridOperator mgOp = new MultigridOperator(MgBasis, solver.CurrentSolution.Mapping, OpMatrix, null, solver.MultigridOperatorConfig);

                    // extract
                    ////////////

                    MsrMatrix FullMatrix = mgOp.OperatorMatrix.ToMsrMatrix();

                    MsrMatrix DiffMatrix;
                    {
                        int[] VelVarIdx = D.ForLoop(d => d);

                        int[] USubMatrixIdx_Row = mgOp.Mapping.GetSubvectorIndices(VelVarIdx);
                        int[] USubMatrixIdx_Col = mgOp.Mapping.GetSubvectorIndices(VelVarIdx);
                        int   L = USubMatrixIdx_Row.Length;

                        DiffMatrix = new MsrMatrix(L, L, 1, 1);
                        FullMatrix.WriteSubMatrixTo(DiffMatrix, USubMatrixIdx_Row, default(int[]), USubMatrixIdx_Col, default(int[]));

                        double DiffMatrix_sd = DiffMatrix.SymmetryDeviation();
                        Console.WriteLine("Diffusion assymetry:" + DiffMatrix_sd);
                    }

                    MsrMatrix SaddlePointMatrix;
                    {
                        int[] VelPVarIdx = new int[] { 0, 1, 2 };

                        int[] VelPSubMatrixIdx_Row = mgOp.Mapping.GetSubvectorIndices(VelPVarIdx);
                        int[] VelPSubMatrixIdx_Col = mgOp.Mapping.GetSubvectorIndices(VelPVarIdx);
                        int   L = VelPSubMatrixIdx_Row.Length;

                        SaddlePointMatrix = new MsrMatrix(L, L, 1, 1);
                        FullMatrix.WriteSubMatrixTo(SaddlePointMatrix, VelPSubMatrixIdx_Row, default(int[]), VelPSubMatrixIdx_Col, default(int[]));
                    }
                    //SaddlePointMatrix.SaveToTextFileSparse("C:\\Users\\kikker\\Documents\\MATLAB\\spm.txt");

                    MsrMatrix ConstitutiveMatrix;
                    {
                        int[] StressVarIdx = new int[] { 3, 4, 5 };

                        int[] StressSubMatrixIdx_Row = mgOp.Mapping.GetSubvectorIndices(StressVarIdx);
                        int[] StressSubMatrixIdx_Col = mgOp.Mapping.GetSubvectorIndices(StressVarIdx);
                        int   L = StressSubMatrixIdx_Row.Length;

                        ConstitutiveMatrix = new MsrMatrix(L, L, 1, 1);
                        FullMatrix.WriteSubMatrixTo(ConstitutiveMatrix, StressSubMatrixIdx_Row, default(int[]), StressSubMatrixIdx_Col, default(int[]));
                    }

                    // operator analysis
                    //////////////////////

                    bool posDef;
                    if (AnalysisLevel > 1)
                    {
                        // +++++++++++++++++++++++++++++++
                        // check condition number, etc
                        // +++++++++++++++++++++++++++++++

                        MultidimensionalArray ret = MultidimensionalArray.Create(1, 5);
                        Console.WriteLine("Calling MATLAB/Octave...");
                        using (BatchmodeConnector bmc = new BatchmodeConnector()) {
                            bmc.PutSparseMatrix(FullMatrix, "FullMatrix");
                            bmc.PutSparseMatrix(SaddlePointMatrix, "SaddlePointMatrix");
                            bmc.PutSparseMatrix(ConstitutiveMatrix, "ConstitutiveMatrix");
                            bmc.PutSparseMatrix(DiffMatrix, "DiffMatrix");
                            bmc.Cmd("DiffMatrix = 0.5*(DiffMatrix + DiffMatrix');");

                            bmc.Cmd("condNoFullMatrix = condest(FullMatrix);");
                            bmc.Cmd("condNoSaddlePointMatrix = condest(SaddlePointMatrix);");
                            bmc.Cmd("condNoConstitutiveMatrix = condest(ConstitutiveMatrix);");
                            bmc.Cmd("condNoDiffMatrix = condest(DiffMatrix);");

                            //bmc.Cmd("eigiMaxiSaddle = 1.0; % eigs(SaddlePointMatrix,1,'lm')");
                            //bmc.Cmd("eigiMiniSaddle = 1.0; % eigs(SaddlePointMatrix,1,'sm')");
                            //bmc.Cmd("eigiMaxiConst = 1.0; % eigs(ConstitutiveMatrix,1,'lm')");
                            //bmc.Cmd("eigiMiniConst = 1.0; % eigs(ConstitutiveMatrix,1,'sm')");
                            //bmc.Cmd("eigiMaxiDiff = 1.0; % eigs(DiffMatrix,1,'lm')");
                            //bmc.Cmd("eigiMiniDiff = 1.0; % eigs(DiffMatrix,1,'sm')");

                            bmc.Cmd("lasterr");
                            bmc.Cmd("[V,r]=chol(SaddlePointMatrix);");
                            bmc.Cmd("[V,r]=chol(ConstitutiveMatrix);");
                            bmc.Cmd("ret = [condNoFullMatrix, condNoSaddlePointMatrix, condNoConstitutiveMatrix, condNoDiffMatrix, r]"); //eigiMaxiSaddle, eigiMiniSaddle, eigiMaxiConst, eigiMiniConst, eigiMaxiDiff, eigiMiniDiff,
                            bmc.GetMatrix(ret, "ret");

                            bmc.Execute(false);
                        }

                        double condNoFullMatrix         = ret[0, 0];
                        double condNoSaddlePMatrix      = ret[0, 1];
                        double condNoConstitutiveMatrix = ret[0, 2];
                        double condNoDiffMatrix         = ret[0, 3];
                        //double eigiMaxiSaddle = ret[0, 4];
                        //double eigiMiniSaddle = ret[0, 5];
                        //double eigiMaxiConst = ret[0, 6];
                        //double eigiMiniConst = ret[0, 7];
                        //double eigiMaxiDiff = ret[0, 8];
                        //double eigiMiniDiff = ret[0, 9];
                        posDef = ret[0, 4] == 0;

                        //Console.WriteLine("Eigenvalue range of saddle point matrix: {0} to {1}", eigiMiniSaddle, eigiMaxiSaddle);
                        //Console.WriteLine("Eigenvalue range of constitutive matrix: {0} to {1}", eigiMiniConst, eigiMaxiConst);
                        //Console.WriteLine("Eigenvalue range of diffusion matrix: {0} to {1}", eigiMiniDiff, eigiMaxiDiff);

                        Console.WriteLine("Condition number full operator: {0:0.####E-00}", condNoFullMatrix);
                        Console.WriteLine("Condition number saddle point operator: {0:0.####E-00}", condNoSaddlePMatrix);
                        Console.WriteLine("Condition number constitutive operator: {0:0.####E-00}", condNoConstitutiveMatrix);
                        Console.WriteLine("Condition number diffusion operator: {0:0.####E-00}", condNoDiffMatrix);

                        //base.QueryHandler.ValueQuery("ConditionNumber", condNoFullMatrix);
                    }
                    else
                    {
                        // +++++++++++++++++++++++++++++++++++++++
                        // test only for positive definiteness
                        // +++++++++++++++++++++++++++++++++++++++

                        var SaddlePMatrixFull = SaddlePointMatrix.ToFullMatrixOnProc0();
                        var ConstMatrixFull   = ConstitutiveMatrix.ToFullMatrixOnProc0();


                        posDef = true;
                        try {
                            SaddlePMatrixFull.Cholesky();
                        } catch (ArithmeticException) {
                            posDef = false;
                        }

                        posDef = true;
                        try {
                            ConstMatrixFull.Cholesky();
                        } catch (ArithmeticException) {
                            posDef = false;
                        }
                    }


                    double SaddlePSymm = SaddlePointMatrix.SymmetryDeviation();
                    Console.WriteLine("Symmetry deviation of saddle point matrix: " + SaddlePSymm);

                    if (posDef)
                    {
                        Console.WriteLine("Good news: Saddle point operator matrix seems to be positive definite.");
                    }
                    else
                    {
                        Console.WriteLine("WARNING: Saddle point operator matrix is not positive definite.");
                    }


                    double ConstSymm = ConstitutiveMatrix.SymmetryDeviation();
                    Console.WriteLine("Symmetry deviation of constitutive matrix: " + ConstSymm);

                    if (posDef)
                    {
                        Console.WriteLine("Good news: constitutive operator matrix seems to be positive definite.");
                    }
                    else
                    {
                        Console.WriteLine("WARNING: constitutive operator matrix is not positive definite.");
                    }

                    //if (CheckAssertions) {
                    //    if (Control.AdvancedDiscretizationOptions.ViscosityMode == ViscosityMode.FullySymmetric && Control.PhysicalParameters.IncludeConvection == false) {
                    //        Assert.IsTrue(posDef, "Positive definiteness test failed.");
                    //        double compVal = DiffMatrix.InfNorm() * 1e-13;
                    //        Assert.LessOrEqual(DiffSymm, compVal, "Diffusion matrix seems to be non-symmetric.");
                    //    }
                    //}
                }
            }
        }
예제 #13
0
        public void Solve <U, V>(U X, V B)
            where U : IList <double>
            where V : IList <double>
        {
            var Bu = new double[Uidx.Length];
            var Xu = Bu.CloneAs();

            Bu = B.GetSubVector(Uidx, default(int[]));
            var Bp = new double[Pidx.Length];
            var Xp = Bp.CloneAs();

            Bp = B.GetSubVector(Pidx, default(int[]));

            Xu = X.GetSubVector(Uidx, default(int[]));
            Xp = X.GetSubVector(Pidx, default(int[]));

            P = new BlockMsrMatrix(null, null);// Pidx.Length, Pidx.Length); //

            MultidimensionalArray Schur = MultidimensionalArray.Create(Pidx.Length, Pidx.Length);

            using (BatchmodeConnector bmc = new BatchmodeConnector()) {
                bmc.PutSparseMatrix(LocalMatrix, "LocalMatrix");
                bmc.PutSparseMatrix(divVel, "divVel");
                bmc.PutSparseMatrix(pGrad, "pGrad");
                bmc.Cmd("invLocalMatrix = inv(full(LocalMatrix))");
                bmc.Cmd("Poisson = invLocalMatrix*pGrad");
                bmc.Cmd("Schur= divVel*Poisson");
                bmc.GetMatrix(Schur, "Schur");
                bmc.Execute(false);
            }

            P = null; // Schur.ToMsrMatrix();

            //P.SaveToTextFileSparse("LocalSchur");

            using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) {
                solver.DefineMatrix(P);
                solver.Solve(Xp, Bp);
            }

            //var temp2 = Xp.CloneAs();

            //LocalMatrix.SpMV(1, Xp, 0, temp2);

            //using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver())
            //{
            //    solver.DefineMatrix(divVel);
            //    solver.Solve(Xp, temp2);
            //}


            // Solve ConvD           iff*w=v-q*pGrad
            pGrad.SpMV(-1, Xp, 1, Bu);

            using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) {
                solver.DefineMatrix(ConvDiff);
                solver.Solve(Xu, Bu);
            }

            var temp = new double[Uidx.Length + Pidx.Length];

            for (int i = 0; i < Uidx.Length; i++)
            {
                temp[Uidx[i]] = Xu[i];
            }

            for (int i = 0; i < Pidx.Length; i++)
            {
                temp[Pidx[i]] = Xp[i];
            }

            X.SetV(temp);
            m_ThisLevelIterations++;
        }
예제 #14
0
        /// <summary>
        /// According to the Rouché-Capelli theorem, the system is inconsistent if rank(augMatrix) > rank(Matrix).
        /// If rank(augMatrix) == rank(Matrix), the system has at least one solution.
        /// Additionally, if the rank is equal to the number of variables, the solution of the system is unique.
        /// Remark: This requires the whole RHS not only local!!!
        /// </summary>
        /// <param name="OpMatrix"></param>
        /// <param name="RHS"></param>
        public void rankAnalysis(BlockMsrMatrix OpMatrix, double[] RHS)
        {
            int RHSlen = this.localRHS.Length;

            Debug.Assert(RHSlen == m_OpMtx.RowPartitioning.LocalLength);

            MultidimensionalArray outputArray = MultidimensionalArray.Create(2, 1); // The two rank values

            //At this point OpMatrix and RHS are local, they are collected within bmc on proc rank==0
            using (var bmc = new BatchmodeConnector()){
                bmc.PutSparseMatrix(OpMatrix, "OpMatrix");
                bmc.PutVector(RHS, "RHS");
                bmc.Cmd("output = zeros(2,1)"); // First value is rank(OpMatrix), second the rank of the augmented matrix = rank([Matrix|RHS])
                bmc.Cmd("");
                bmc.Cmd("fullMtx = full(OpMatrix);");
                bmc.Cmd("augmentedMtx = [fullMtx RHS];");
                bmc.Cmd("output(1) = rank(fullMtx)");
                bmc.Cmd("output(2) = rank(augmentedMtx)");
                bmc.GetMatrix(outputArray, "output");
                bmc.Execute(false);
            }


            double[] output = new double[2];
            output[0] = outputArray[0, 0]; //Rank matrix
            output[1] = outputArray[1, 0]; //Rank augmented matrix ( [Matrix|RHS])

            double rnkMtx          = output[0];
            double rnkAugmentedMtx = output[1];

            // Some tests
            Console.WriteLine("==================================================================");

            //Output
            {
                Console.WriteLine("Results of rank analysis:");
                if (rnkAugmentedMtx > rnkMtx)
                {
                    //throw new Exception("The rank of the augmented matrix shouldn't be greater than the one of the original matrix!!");
                    Console.WriteLine("======================================================");
                    Console.WriteLine("WARNING!!!!!!! The rank of the augmented matrix shouldn't be greater than the one of the original matrix!!");
                    Console.WriteLine("This means that the system doesnt have a solution!");
                }

                if (rnkAugmentedMtx == rnkMtx)
                {
                    Console.WriteLine("The system has at least a solution");
                }

                //RHS and OpMatrix will be collected in Bmc, so total length has to be considered for RHS: RHS.length will lead to errors in parallel execution
                if (rnkMtx < RHSlen)
                {
                    Console.WriteLine("The rank of the matrix is smaller than the number of variables. There are {0} free parameters", (RHS.Length - rnkMtx));
                }

                else if (rnkMtx == RHSlen)
                {
                    Console.WriteLine("The system has a unique solution :) ");
                }

                else
                {
                    throw new Exception("what? should not happen");
                }

                Console.WriteLine("Rank of the matrix : {0} \n" + "Rank of the augmented matrix : {1} \n" + "Number of variables: {2}", output[0], output[1], RHS.Length);
                Console.WriteLine("==================================================================");
            }

            Debug.Assert(output[0].MPIEquals(), "value does not match on procs");
            Debug.Assert(output[1].MPIEquals(), "value does not match on procs");
        }
예제 #15
0
        /// <summary>
        /// Test on a 2D Voronoi mesh
        /// </summary>
        /// <param name="Res">
        /// number of randomly chosen Delaunay vertices
        /// </param>
        /// <param name="deg">
        /// polynomial degree
        /// </param>
        /// <param name="solver_name">
        /// Name of solver to use.
        /// </param>
        public static SipControl TestVoronoi(int Res, SolverCodes solver_name = SolverCodes.classic_pardiso, int deg = 3)
        {
            if (System.Environment.MachineName.ToLowerInvariant().EndsWith("rennmaschin")
                //|| System.Environment.MachineName.ToLowerInvariant().Contains("jenkins")
                )
            {
                // This is Florians Laptop;
                // he is to poor to afford MATLAB, so he uses OCTAVE
                BatchmodeConnector.Flav = BatchmodeConnector.Flavor.Octave;
                BatchmodeConnector.MatlabExecuteable = "C:\\cygwin64\\bin\\bash.exe";
            }


            var R = new SipControl();

            R.ProjectName = "SipPoisson-Voronoi";
            R.SessionName = "testrun";
            R.savetodb    = false;

            R.FieldOptions.Add("T", new FieldOpts()
            {
                Degree = deg, SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            R.FieldOptions.Add("Tex", new FieldOpts()
            {
                Degree = deg * 2
            });
            R.InitialValues_Evaluators.Add("RHS", X => 1.0);
            R.InitialValues_Evaluators.Add("Tex", X => 0.0);
            R.ExactSolution_provided = false;
            R.NoOfMultigridLevels    = int.MaxValue;
            R.solver_name            = solver_name;
            //R.TargetBlockSize = 100;



            bool IsIn(params double[] X)
            {
                Debug.Assert(X.Length == 2);
                double xi = X[0];
                double yi = X[1];

                //for(int l = 0; l < bndys.Length; l++) {
                //    Debug.Assert(bndys[l].Normal.Length == 2);
                //    if (bndys[l].PointDistance(xi, yi) > 0.0)
                //        return false;
                //}
                if (xi > 1.0)
                {
                    return(false);
                }
                if (yi > 1.0)
                {
                    return(false);
                }
                if (xi < 0 && yi < 0)
                {
                    return(false);
                }
                if (xi < -1)
                {
                    return(false);
                }
                if (yi < -1)
                {
                    return(false);
                }

                return(true);
            }

            int Mirror(ref double[] _x, ref double[] _y, AffineManifold[] bndys)
            {
                if (_x.Length != _y.Length)
                {
                    throw new ArgumentException();
                }
                var x = _x.ToList();
                var y = _y.ToList();
                int N = _x.Length;



                // filter all points that are outside of the domain
                for (int n = 0; n < N; n++)
                {
                    if (!IsIn(x[n], y[n]))
                    {
                        x.RemoveAt(n);
                        y.RemoveAt(n);
                        N--;
                        n--;
                    }
                }
                Debug.Assert(x.Count == N);
                Debug.Assert(y.Count == N);
                for (int n = 0; n < N; n++)
                {
                    Debug.Assert(IsIn(x[n], y[n]));
                }

                // mirror each point
                for (int n = 0; n < N; n++)
                {
                    double xn = x[n];
                    double yn = y[n];
                    for (int l = 0; l < bndys.Length; l++)
                    {
                        var bndy_l = bndys[l];

                        double dist = bndy_l.PointDistance(xn, yn);

                        if (dist < 0)
                        {
                            double xMirr = xn - bndy_l.Normal[0] * dist * 2;
                            double yMirr = yn - bndy_l.Normal[1] * dist * 2;

                            Debug.Assert(bndy_l.PointDistance(xMirr, yMirr) > 0);

                            if (!IsIn(xMirr, yMirr))
                            {
                                x.Add(xMirr);
                                y.Add(yMirr);
                            }
                        }
                    }
                }

                // return
                _x = x.ToArray();
                _y = y.ToArray();
                return(N);
            }

            GridCommons GridFunc()
            {
                GridCommons grd = null;

                var Matlab = new BatchmodeConnector();

                // boundaries for L-domain
                AffineManifold[] Boundaries = new AffineManifold[6];
                Boundaries[0] = new AffineManifold(new[] { 0.0, 1.0 }, new[] { 0.0, 1.0 });
                Boundaries[1] = new AffineManifold(new[] { 1.0, 0.0 }, new[] { 1.0, 0.0 });
                Boundaries[2] = new AffineManifold(new[] { -1.0, 0.0 }, new[] { -1.0, 0.0 });
                Boundaries[3] = new AffineManifold(new[] { -1.0, 0.0 }, new[] { 0.0, 0.0 });
                Boundaries[4] = new AffineManifold(new[] { 0.0, -1.0 }, new[] { 0.0, -1.0 });
                Boundaries[5] = new AffineManifold(new[] { 0.0, -1.0 }, new[] { 0.0, 0.0 });


                // generate Delaunay vertices
                Random rnd = new Random(0);

                double[] xNodes = Res.ForLoop(idx => rnd.NextDouble() * 2 - 1);
                double[] yNodes = Res.ForLoop(idx => rnd.NextDouble() * 2 - 1);
                int      ResFix = Mirror(ref xNodes, ref yNodes, Boundaries);


                var Nodes = MultidimensionalArray.Create(xNodes.Length, 2);

                Nodes.SetColumn(0, xNodes);
                Nodes.SetColumn(1, yNodes);

                Matlab.PutMatrix(Nodes, "Nodes");

                // compute Voronoi diagramm
                Matlab.Cmd("[V, C] = voronoin(Nodes);");

                // output (export from matlab)
                int[][] OutputVertexIndex = new int[Nodes.NoOfRows][];
                Matlab.GetStaggeredIntArray(OutputVertexIndex, "C");
                Matlab.GetMatrix(null, "V");

                // run matlab
                Matlab.Execute(false);

                // import here
                MultidimensionalArray VertexCoordinates = (MultidimensionalArray)(Matlab.OutputObjects["V"]);

                // correct indices (1-based index to 0-based index)
                foreach (int[] cell in OutputVertexIndex)
                {
                    int K = cell.Length;
                    for (int k = 0; k < K; k++)
                    {
                        cell[k]--;
                    }
                }

                // tessellation
                List <Cell>  cells       = new List <Cell>();
                List <int[]> aggregation = new List <int[]>();

                for (int jV = 0; jV < ResFix; jV++)  // loop over Voronoi Cells
                {
                    Debug.Assert(IsIn(Nodes.GetRow(jV)));
                    int[] iVtxS = OutputVertexIndex[jV];
                    int   NV    = iVtxS.Length;

                    List <int> Agg2Pt = new List <int>();

                    for (int iTri = 0; iTri < NV - 2; iTri++)  // loop over triangles of voronoi cell
                    {
                        int iV0 = iVtxS[0];
                        int iV1 = iVtxS[iTri + 1];
                        int iV2 = iVtxS[iTri + 2];

                        double[] V0 = VertexCoordinates.GetRow(iV0);
                        double[] V1 = VertexCoordinates.GetRow(iV1);
                        double[] V2 = VertexCoordinates.GetRow(iV2);

                        double[] D1 = V1.Minus(V0);
                        double[] D2 = V2.Minus(V0);
                        Debug.Assert(D1.CrossProduct2D(D2).Abs() > 1.0e-8);
                        if (D1.CrossProduct2D(D2) < 0)
                        {
                            double[] T = V2;
                            int      t = iV2;
                            V2  = V1;
                            iV2 = iV1;
                            V1  = T;
                            iV1 = t;
                        }

                        double[] Center = V0.Plus(V1).Plus(V2).Mul(1.0 / 3.0);
                        //Debug.Assert(IsIn(Center[0], Center[1]));

                        Cell Cj = new Cell();
                        Cj.GlobalID             = cells.Count;
                        Cj.Type                 = CellType.Triangle_3;
                        Cj.TransformationParams = MultidimensionalArray.Create(3, 2);
                        Cj.NodeIndices          = new int[] { iV0, iV1, iV2 };
                        Cj.TransformationParams.SetRow(0, V0);
                        Cj.TransformationParams.SetRow(1, V1);
                        Cj.TransformationParams.SetRow(2, V2);

                        Agg2Pt.Add(cells.Count);

                        cells.Add(Cj);
                    }

                    aggregation.Add(Agg2Pt.ToArray());
                }

                // return grid
                grd       = new Grid2D(Triangle.Instance);
                grd.Cells = cells.ToArray();
                grd.EdgeTagNames.Add(1, BoundaryType.Dirichlet.ToString());
                grd.DefineEdgeTags(X => (byte)1);

                //grd.Plot2DGrid();

                // create aggregation grid
                //var agrd = new AggregationGrid(grd, aggregation.ToArray());
                return(grd);
            };
            R.GridFunc = GridFunc;

            R.AddBoundaryValue(BoundaryType.Dirichlet.ToString(), "T",
                               delegate(double[] X) {
                //double x = X[0], y = X[1];

                return(0.0);
                //if(Math.Abs(X[0] - (0.0)) < 1.0e-8)
                //    return 0.0;
                //
                //throw new ArgumentOutOfRangeException();
            });



            return(R);
        }
예제 #16
0
        /// <summary>
        /// returns the condition number of the full matrix and the inner matrix without boundary terms
        /// </summary>
        /// <returns>Array condestOut=[ConditionNumberFullOp, ConditionNumberInnerOp]</returns>
        public double[] CondNum()
        {
            int[] DepVars       = this.VarGroup;
            var   grd           = m_map.GridDat;
            int   NoOfCells     = grd.Grid.NumberOfCells;
            int   NoOfBdryCells = grd.GetBoundaryCells().NoOfItemsLocally_WithExternal;

            // only for full matrix, if there are no inner cells
            if (NoOfCells == NoOfBdryCells)
            {
                Console.WriteLine("");
                Console.WriteLine("Since there are only boundary cells, the condest of the non-existing inner matrix is set to zero!");

                double[] Full_0Vars          = this.m_map.GetSubvectorIndices(true, DepVars).Select(i => i + 1.0).ToArray();
                MultidimensionalArray output = MultidimensionalArray.Create(1, 1);

                using (BatchmodeConnector bmc = new BatchmodeConnector()){
                    // if Octave should be used instead of Matlab....
                    //BatchmodeConnector.Flav = BatchmodeConnector.Flavor.Octave;

                    bmc.PutSparseMatrix(m_OpMtx, "FullMatrix");
                    bmc.PutVector(Full_0Vars, "Full_0Vars");
                    bmc.Cmd("output = zeros(1,1)");
                    bmc.Cmd("output = condest(FullMatrix(Full_0Vars,Full_0Vars));");
                    bmc.GetMatrix(output, "output");
                    bmc.Execute(false);
                }

                double condestFull  = output[0, 0];
                double condestInner = 0;

                double[] condestOut = new double[] { condestFull, condestInner };
                return(condestOut);
            }
            // for full and inner matrix
            else
            {
                CellMask InnerCellsMask = grd.GetBoundaryCells().Complement();
                SubGrid  InnerCells     = new SubGrid(InnerCellsMask);

                double[] Full_0Vars  = this.m_map.GetSubvectorIndices(true, DepVars).Select(i => i + 1.0).ToArray();
                double[] Inner_0Vars = this.m_map.GetSubvectorIndices(InnerCells, true, DepVars).Select(i => i + 1.0).ToArray();

                MultidimensionalArray output = MultidimensionalArray.Create(2, 1);
                string[] names = new string[] { "Full_0Vars", "Inner_0Vars" };

                using (BatchmodeConnector bmc = new BatchmodeConnector()){
                    // if Octave should be used instead of Matlab....
                    // BatchmodeConnector.Flav = BatchmodeConnector.Flavor.Octave;

                    bmc.PutSparseMatrix(m_OpMtx, "FullMatrix");
                    bmc.PutVector(Inner_0Vars, "Inner_0Vars");
                    bmc.PutVector(Full_0Vars, "Full_0Vars");
                    bmc.Cmd("output = zeros(2,1)");

                    int k = 1;
                    foreach (var s in names)
                    {
                        bmc.Cmd("output({1}) = condest(FullMatrix({0},{0}));", s, k);
                        k++;
                    }

                    bmc.GetMatrix(output, "output");
                    bmc.Execute(false);

                    double condestFull  = output[0, 0];
                    double condestInner = output[1, 0];

                    double[] condestOut = new double[] { condestFull, condestInner };


                    Debug.Assert(condestOut[0].MPIEquals(), "value does not match on procs");
                    Debug.Assert(condestOut[1].MPIEquals(), "value does not match on procs");
                    return(condestOut);
                }
            }
        }
예제 #17
0
파일: Newton.cs 프로젝트: xj361685640/BoSSS
        public override void SolverDriver <S>(CoordinateVector SolutionVec, S RHS)
        {
            using (var tr = new FuncTrace()) {
                m_SolutionVec = SolutionVec;

                int itc;
                itc = 0;
                double[] x, xt, xOld, f0, deltaX, ft;
                double   rat;
                double   alpha = 1E-4, sigma0 = 0.1, sigma1 = 0.5, maxarm = 20, gamma = 0.9;

                // Eval_F0
                using (new BlockTrace("Slv Init", tr)) {
                    base.Init(SolutionVec, RHS, out x, out f0);
                };

                Console.WriteLine("Residual base.init:   " + f0.L2NormPow2().MPISum().Sqrt());


                deltaX = new double[x.Length];
                xt     = new double[x.Length];
                ft     = new double[x.Length];


                this.CurrentLin.TransformSolFrom(SolutionVec, x);
                base.EvalResidual(x, ref f0);


                // fnorm
                double    fnorm  = f0.L2NormPow2().MPISum().Sqrt();
                double    fNormo = 1;
                double    errstep;
                double[]  step    = new double[x.Length];
                double[]  stepOld = new double[x.Length];
                MsrMatrix CurrentJac;

                Console.WriteLine("Start residuum for nonlinear iteration:  " + fnorm);

                OnIterationCallback(itc, x.CloneAs(), f0.CloneAs(), this.CurrentLin);

                //int[] Velocity_idx = SolutionVec.Mapping.GetSubvectorIndices(false, 0, 1, 2);
                //int[] Stresses_idx = SolutionVec.Mapping.GetSubvectorIndices(false, 3, 4, 5);

                //int[] Velocity_fields = new int[] { 0, 1, 2 };
                //int[] Stress_fields = new int[] { 3, 4, 5 };

                //int NoCoupledIterations = 1;

                using (new BlockTrace("Slv Iter", tr)) {
                    while (fnorm > ConvCrit && itc < MaxIter)
                    {
                        rat    = fnorm / fNormo;
                        fNormo = fnorm;
                        itc++;

                        // How should the inverse of the Jacobian be approximated?
                        if (ApproxJac == ApproxInvJacobianOptions.GMRES)
                        {
                            CurrentJac = new MsrMatrix(x.Length);
                            if (Precond != null)
                            {
                                Precond.Init(CurrentLin);
                            }
                            step = Krylov(SolutionVec, x, f0, out errstep);
                        }
                        else if (ApproxJac == ApproxInvJacobianOptions.DirectSolver)
                        {
                            CurrentJac = diffjac(SolutionVec, x, f0);
                            CurrentJac.SaveToTextFileSparse("Jacobi");
                            CurrentLin.OperatorMatrix.SaveToTextFileSparse("OpMatrix");
                            var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver();
                            solver.DefineMatrix(CurrentJac);
                            step.ClearEntries();
                            solver.Solve(step, f0);
                        }
                        else if (ApproxJac == ApproxInvJacobianOptions.DirectSolverHybrid)
                        {
                            //EXPERIMENTAL_____________________________________________________________________
                            MultidimensionalArray OpMatrixMatl = MultidimensionalArray.Create(x.Length, x.Length);
                            CurrentJac = diffjac(SolutionVec, x, f0);
                            //Console.WriteLine("Calling MATLAB/Octave...");
                            using (BatchmodeConnector bmc = new BatchmodeConnector())
                            {
                                bmc.PutSparseMatrix(CurrentJac, "Jacobi");
                                bmc.PutSparseMatrix(CurrentLin.OperatorMatrix, "OpMatrix");
                                bmc.Cmd("Jacobi(abs(Jacobi) < 10^-6)=0; dim = length(OpMatrix);");
                                bmc.Cmd("dim = length(OpMatrix);");
                                bmc.Cmd(@"for i=1:dim

                                if (i >= 16) && (i <= 33) && (i + 6 <= 33) && (i + 12 <= 33)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end

                                if (i >= 49) && (i <= 66) && (i + 6 <= 66) && (i + 12 <= 66)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end

                                if (i >= 82) && (i <= 99) && (i + 6 <= 99) && (i + 12 <= 99)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end

                                if (i >= 115) && (i <= 132) && (i + 6 <= 132) && (i + 12 <= 132)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end

                                if (i >= 148) && (i <= 165) && (i + 6 <= 165) && (i + 12 <= 165)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end 

                                if (i >= 181) && (i <= 198) && (i + 6 <= 198) && (i + 12 <= 198)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end  

                                if (i >= 214) && (i <= 231) && (i + 6 <= 231) && (i + 12 <= 231)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end
                                if (i >= 247) && (i <= 264) && (i + 6 <= 264) && (i + 12 <= 264)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end
                                if (i >= 280) && (i <= 297) && (i + 6 <= 297) && (i + 12 <= 297)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end
                                if (i >= 313) && (i <= 330) && (i + 6 <= 330) && (i + 12 <= 330)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end
                                if (i >= 346) && (i <= 363) && (i + 6 <= 363) && (i + 12 <= 363)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end
                                if (i >= 379) && (i <= 396) && (i + 6 <= 396) && (i + 12 <= 396)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end
                                if (i >= 412) && (i <= 429) && (i + 6 <= 429) && (i + 12 <= 429)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end
                                if (i >= 445) && (i <= 462) && (i + 6 <= 462) && (i + 12 <= 462)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end
                                if (i >= 478) && (i <= 495) && (i + 6 <= 495) && (i + 12 <= 495)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end
                                if (i >= 511) && (i <= 528) && (i + 6 <= 528) && (i + 12 <= 528)
                                    OpMatrix(i, i) = Jacobi(i, i);
                                    OpMatrix(i, i + 6) = Jacobi(i, i + 6);
                                    OpMatrix(i + 6, i) = Jacobi(i + 6, i);
                                    OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6);
                                    OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12);
                                end
                                end");
                                bmc.Cmd("OpMatrix = full(OpMatrix)");
                                bmc.GetMatrix(OpMatrixMatl, "OpMatrix");
                                bmc.Execute(false);
                            }

                            MsrMatrix OpMatrix = OpMatrixMatl.ToMsrMatrix();
                            var       solver   = new ilPSP.LinSolvers.MUMPS.MUMPSSolver();

                            //Console.WriteLine("USING HIGH EXPERIMENTAL OPMATRIX WITH JAC! only for p=1, GridLevel=2");
                            solver.DefineMatrix(OpMatrix);
                            //______________________________________________________________________________________________________

                            step.ClearEntries();
                            solver.Solve(step, f0);
                        }
                        else if (ApproxJac == ApproxInvJacobianOptions.DirectSolverOpMatrix)
                        {
                            CurrentJac = new MsrMatrix(x.Length);
                            CurrentJac = CurrentLin.OperatorMatrix.ToMsrMatrix();
                            var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver();
                            solver.DefineMatrix(CurrentJac);
                            step.ClearEntries();
                            solver.Solve(step, f0);
                        }
                        else
                        {
                            throw new NotImplementedException("Your approximation option for the jacobian seems not to be existent.");
                        }

                        //if (itc > NoCoupledIterations)
                        //{
                        //    if (solveVelocity)
                        //    {
                        //        Console.WriteLine("stress correction = 0");
                        //        foreach (int idx in Stresses_idx)
                        //        {
                        //            step[idx] = 0.0;
                        //        }
                        //    }
                        //    else
                        //    {
                        //        Console.WriteLine("velocity correction = 0");
                        //        foreach (int idx in Velocity_idx)
                        //        {
                        //            step[idx] = 0.0;
                        //        }
                        //    }
                        //}

                        // Start line search
                        xOld = x;
                        double lambda = 1;
                        double lamm   = 1;
                        double lamc   = lambda;
                        double iarm   = 0;
                        xt = x.CloneAs();
                        xt.AccV(lambda, step);
                        this.CurrentLin.TransformSolFrom(SolutionVec, xt);
                        EvaluateOperator(1, SolutionVec.Mapping.Fields, ft);
                        var nft = ft.L2NormPow2().MPISum().Sqrt(); var nf0 = f0.L2NormPow2().MPISum().Sqrt(); var ff0 = nf0 * nf0; var ffc = nft * nft; var ffm = nft * nft;

                        // Control of the the step size
                        while (nft >= (1 - alpha * lambda) * nf0 && iarm < maxStep)
                        {
                            // Line search starts here

                            if (iarm == 0)
                            {
                                lambda = sigma1 * lambda;
                            }
                            else
                            {
                                lambda = parab3p(lamc, lamm, ff0, ffc, ffm);
                            }

                            // Update x;
                            xt = x.CloneAs();
                            xt.AccV(lambda, step);
                            lamm = lamc;
                            lamc = lambda;

                            this.CurrentLin.TransformSolFrom(SolutionVec, xt);

                            EvaluateOperator(1, SolutionVec.Mapping.Fields, ft);

                            nft = ft.L2NormPow2().MPISum().Sqrt();
                            ffm = ffc;
                            ffc = nft * nft;
                            iarm++;

#if DEBUG
                            Console.WriteLine("Step size:  " + lambda + "with Residuum:  " + nft);
#endif
                        }
                        // transform solution back to 'original domain'
                        // to perform the linearization at the new point...
                        // (and for Level-Set-Updates ...)
                        this.CurrentLin.TransformSolFrom(SolutionVec, xt);

                        // update linearization
                        base.Update(SolutionVec.Mapping.Fields, ref xt);

                        // residual evaluation & callback
                        base.EvalResidual(xt, ref ft);

                        // EvaluateOperator(1, SolutionVec.Mapping.Fields, ft);

                        //base.Init(SolutionVec, RHS, out x, out f0);

                        fnorm = ft.L2NormPow2().MPISum().Sqrt();

                        x  = xt;
                        f0 = ft.CloneAs();

                        //if (itc > NoCoupledIterations)
                        //{

                        //    double coupledL2Res = 0.0;
                        //    if (solveVelocity)
                        //    {
                        //        foreach (int idx in Velocity_idx)
                        //        {
                        //            coupledL2Res += f0[idx].Pow2();
                        //        }
                        //    }
                        //    else
                        //    {
                        //        foreach (int idx in Stresses_idx)
                        //        {
                        //            coupledL2Res += f0[idx].Pow2();
                        //        }
                        //    }
                        //    coupledL2Res = coupledL2Res.Sqrt();

                        //    Console.WriteLine("coupled residual = {0}", coupledL2Res);

                        //    if (solveVelocity && coupledL2Res < this.VelocitySolver_ConvergenceCriterion)
                        //    {
                        //        Console.WriteLine("SolveVelocity = false");
                        //        this.solveVelocity = false;
                        //    }
                        //    else if (!solveVelocity && coupledL2Res < this.StressSolver_ConvergenceCriterion)
                        //    {
                        //        Console.WriteLine("SolveVelocity = true");
                        //        this.solveVelocity = true;
                        //    }
                        //}

                        OnIterationCallback(itc, x.CloneAs(), f0.CloneAs(), this.CurrentLin);
                    }
                }

                SolutionVec = m_SolutionVec;
            }
        }
예제 #18
0
파일: VoronoiGrid.cs 프로젝트: xyuan/BoSSS
        public void CreateWithMatlab()
        {
            // ================================
            // generate voronoi graph in matlab
            // ================================


            int J = this.DelaunayVertices.NoOfRows;
            int D = this.DelaunayVertices.NoOfCols;

            if (D != 2)
            {
                throw new NotSupportedException("todo");
            }


            int[][] OutputVertexIndex = new int[J * 5][];
            MultidimensionalArray VertexCoordinates;
            {
                var Matlab = new BatchmodeConnector();

                Matlab.PutMatrix(this.DelaunayVertices, "X");

                // create mirror points
                Matlab.Cmd("[J, D] = size(X);");
                Matlab.Cmd("Xneg = [-X(:, 1), X(:, 2)];");
                Matlab.Cmd("Yneg = [X(:, 1), -X(:, 2)];");
                Matlab.Cmd("X2 = [ones(J, 1) * 2, zeros(J, 1)];");
                Matlab.Cmd("Y2 = [zeros(J, 1), ones(J, 1) * 2];");

                Matlab.Cmd("Xm = X;");
                Matlab.Cmd("Xm = [Xm; Xneg];    % mirror at x = 0");
                Matlab.Cmd("Xm = [Xm; X2 + Xneg]; % mirror at x = 1");
                Matlab.Cmd("Xm = [Xm; Yneg];    % mirror at x = 0");
                Matlab.Cmd("Xm = [Xm; Y2 + Yneg]; % mirror at x = 1");

                // compute Voronoi diagramm
                Matlab.Cmd("[V, C] = voronoin(Xm);");

                // output (export from matlab)
                Matlab.GetStaggeredIntArray(OutputVertexIndex, "C");
                Matlab.GetMatrix(null, "V");

                // run matlab
                Matlab.Execute(false);

                // import here
                VertexCoordinates = (MultidimensionalArray)(Matlab.OutputObjects["V"]);

                // correct indices (1-based index to 0-based index)
                foreach (int[] cell in OutputVertexIndex)
                {
                    int K = cell.Length;
                    for (int k = 0; k < K; k++)
                    {
                        cell[k]--;
                    }
                }
            }

            // ===============
            // record internal
            // ===============

            {
                // define Cell data
                {
                    this.m_CellData         = new CellData();
                    this.m_CellData.m_Owner = this;
                    this.m_VertexData       = new VertexData();
                    this.m_LogEdges         = new LogEdgeData();

                    this.m_VertexData.Coordinates = VertexCoordinates;
                    this.m_CellData.CellVertices  = OutputVertexIndex.GetSubVector(0, J);

                    this.m_CellData.InfoFlags = new CellInfo[J];
                    ArrayTools.SetAll(this.m_CellData.InfoFlags, CellInfo.CellIsAffineLinear | CellInfo.IsAggregate);
                }

                // decomposition of Voronoi cells to triangles/tetrahedrons
                {
                    m_CellData.AggregateCellToParts = new int[J][];
                    if (D == 2)
                    {
                        var Tri = RefElements.Triangle.Instance;
                        m_CellData.RefElements = new RefElement[] { Tri };

                        int cnt = 0;
                        for (int j = 0; j < J; j++)
                        {
                            int[] VtxIndices = m_CellData.CellVertices[j];

                            int[] PartIdx = new int[VtxIndices.Length - 2];
                            for (int i = 0; i < PartIdx.Length; i++)
                            {
                                PartIdx[i] = cnt;
                                cnt++;
                            }
                            m_CellData.AggregateCellToParts[j] = PartIdx;
                        }

                        int NoOfParts = cnt;
                        m_CellData.PartTransformation = MultidimensionalArray.Create(NoOfParts, D, D);
                        m_CellData.PartCenter         = MultidimensionalArray.Create(NoOfParts, D);

                        MultidimensionalArray TriangleVtx = MultidimensionalArray.Create(3, D);
                        for (int j = 0; j < J; j++)
                        {
                            int[] VtxIndices = m_CellData.CellVertices[j];
                            int[] PartIdx    = m_CellData.AggregateCellToParts[j];

                            for (int i = 0; i < PartIdx.Length; i++)
                            {
                                int iV0 = VtxIndices[0];
                                int iV1 = VtxIndices[i + 1];
                                int iV2 = VtxIndices[i + 2];

                                TriangleVtx[0, 0] = m_VertexData.Coordinates[iV0, 0];
                                TriangleVtx[0, 1] = m_VertexData.Coordinates[iV0, 1];
                                TriangleVtx[1, 0] = m_VertexData.Coordinates[iV1, 0];
                                TriangleVtx[1, 1] = m_VertexData.Coordinates[iV1, 1];
                                TriangleVtx[2, 0] = m_VertexData.Coordinates[iV2, 0];
                                TriangleVtx[2, 1] = m_VertexData.Coordinates[iV2, 1];

                                var TR = AffineTrafo.FromPoints(Tri.Vertices, TriangleVtx);

                                m_CellData.PartTransformation.ExtractSubArrayShallow(PartIdx[i], -1, -1).Set(TR.Matrix);
                                m_CellData.PartCenter.ExtractSubArrayShallow(PartIdx[i], -1).SetVector(TR.Affine);
                            }
                        }
                    }
                    else if (D == 3)
                    {
                        throw new NotImplementedException("todo");
                    }
                    else
                    {
                        throw new NotSupportedException("Unknown spatial dimension.");
                    }
                }

                // bounding boxes, transformations
                {
                    BoundingBox BB = new BoundingBox(D);
                    m_CellData.BoundingBoxTransformation = MultidimensionalArray.Create(J, D, D);
                    m_CellData.BoundingBoxCenter         = MultidimensionalArray.Create(J, D);
                    for (int j = 0; j < J; j++)
                    {
                        m_CellData.GetCellBoundingBox(j, BB);
                        for (int d = 0; d < D; d++)
                        {
                            double lo = BB.Min[d];
                            double hi = BB.Max[d];
                            m_CellData.BoundingBoxCenter[j, d]            = 0.5 * (lo + hi);
                            m_CellData.BoundingBoxTransformation[j, d, d] = 0.5 * (hi - lo);
                        }
                    }
                }

                // mapping: vertex to cell
                {
                    List <int>[] VertexToCell = new List <int> [VertexCoordinates.Length];
                    for (int j = 0; j < J; j++)
                    {
                        foreach (int iVtx in OutputVertexIndex[j])
                        {
                            if (VertexToCell[iVtx] == null)
                            {
                                VertexToCell[iVtx] = new List <int>();
                            }

                            if (!VertexToCell[iVtx].Contains(j))
                            {
                                VertexToCell[iVtx].Add(j);
                            }
                        }
                    }

                    m_VertexData.VerticeToCell = new int[VertexToCell.Length][];
                    for (int i = 0; i < VertexToCell.Length; i++)
                    {
                        if (VertexToCell[i] == null)
                        {
                            m_VertexData.VerticeToCell[i] = new int[0];
                        }
                        else
                        {
                            m_VertexData.VerticeToCell[i] = VertexToCell[i].ToArray();
                        }
                    }
                    VertexToCell = null;
                }

                // cell neighbors, edges
                {
                    m_CellData.CellNeighbours = new int[J][];
                    var tmpCells2Edges = new List <int> [J];

                    Dictionary <int, int> ShareCount = new Dictionary <int, int>(); // key: cell index; value: number of vertices shared with this cell
                    var        EdgesTemp             = new List <EdgeTemp>();
                    List <int> Neighs            = new List <int>();
                    List <int> EdgeVtx           = new List <int>();
                    List <int> IdedEdgsAtOneCell = new List <int>();
                    for (int jCell = 0; jCell < J; jCell++)   // loop over cells
                    {
                        ShareCount.Clear();
                        Neighs.Clear();
                        IdedEdgsAtOneCell.Clear();

                        // determine how many vertices 'jCell' shares with other cells
                        foreach (int iVtx in m_CellData.CellVertices[jCell])
                        {
                            foreach (int jOtherCell in m_VertexData.VerticeToCell[iVtx])
                            {
                                if (jOtherCell != jCell)
                                {
                                    if (!ShareCount.ContainsKey(jOtherCell))
                                    {
                                        ShareCount.Add(jOtherCell, 1);
                                    }
                                    else
                                    {
                                        ShareCount[jOtherCell]++;
                                    }
                                }
                            }
                        }

                        // find faces
                        int[][] FaceIdx = ConvexHullFaces(m_VertexData.Coordinates, m_CellData.CellVertices[jCell]);

                        // determine cell neighbors and edges
                        int NoOfFacesFound = 0;
                        foreach (var kv in ShareCount)
                        {
                            int jCellNeigh    = kv.Key;
                            int NoOfSharedVtx = kv.Value;
                            if (NoOfSharedVtx >= D)
                            {
                                // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                                // cells 'jCell' and 'jCellNeigh' share more than 'D' vertices - this is an edge to another cell,
                                // resp. a face of 'jCell'.
                                // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                                Debug.Assert(jCellNeigh != jCell);
                                Debug.Assert(!Neighs.Contains(jCellNeigh));
                                Neighs.Add(jCellNeigh);
                                NoOfFacesFound++;

                                EdgeVtx.Clear();
                                foreach (int iVtx in m_CellData.CellVertices[jCell])
                                {
                                    if (Array.IndexOf(m_VertexData.VerticeToCell[iVtx], jCellNeigh) >= 0)
                                    {
                                        EdgeVtx.Add(iVtx);
                                    }
                                }


                                if (jCell < jCellNeigh)
                                {
                                    // the pairing 'jCell'/'jCellNeigh' will be discovered twice;
                                    // we only want to record once

                                    var Etmp = new EdgeTemp()
                                    {
                                        jCell1   = jCell,
                                        jCell2   = jCellNeigh,
                                        Vertices = EdgeVtx.ToArray()
                                    };
                                    EdgesTemp.Add(Etmp);
                                    IdedEdgsAtOneCell.Add(EdgesTemp.Count - 1);
                                    if (tmpCells2Edges[jCell] == null)
                                    {
                                        tmpCells2Edges[jCell] = new List <int>();
                                    }
                                    if (tmpCells2Edges[jCellNeigh] == null)
                                    {
                                        tmpCells2Edges[jCellNeigh] = new List <int>();
                                    }
                                    tmpCells2Edges[jCell].Add(EdgesTemp.Count);       // the funky convention for edges-to-cell: the index is
                                    tmpCells2Edges[jCellNeigh].Add(-EdgesTemp.Count); // shifted by 1, out-cell is negative
                                }
                                else
                                {
                                    Debug.Assert(jCellNeigh < jCell);

                                    int MatchCount = 0;
                                    foreach (int i in tmpCells2Edges[jCellNeigh])
                                    {
                                        int iEdge = Math.Abs(i) - 1;

                                        if (EdgesTemp[iEdge].jCell1 == jCellNeigh && EdgesTemp[iEdge].jCell2 == jCell)
                                        {
                                            MatchCount++;
                                            IdedEdgsAtOneCell.Add(iEdge);
                                        }
                                    }
                                    Debug.Assert(MatchCount == 1);
                                }
#if DEBUG
                                if (D == 2)
                                {
                                    Debug.Assert(EdgeVtx.Count == 2);
                                }
                                else if (D == 3)
                                {
                                    // verify that all vertices of the edge are geometrically in one plane

                                    Debug.Assert(EdgeVtx.Count >= 3);
                                    var FacePlane = AffineManifold.FromPoints(
                                        m_VertexData.Coordinates.GetRowPt(EdgeVtx[0]),
                                        m_VertexData.Coordinates.GetRowPt(EdgeVtx[1]),
                                        m_VertexData.Coordinates.GetRowPt(EdgeVtx[2])
                                        );

                                    BoundingBox BB = new BoundingBox(D);
                                    m_CellData.GetCellBoundingBox(jCell, BB);
                                    double h = BB.Diameter;

                                    foreach (int iVtx in EdgeVtx)
                                    {
                                        double dist = Math.Abs(FacePlane.PointDistance(m_VertexData.Coordinates.GetRow(iVtx)));
                                        Debug.Assert(dist < h * 1e-8);
                                    }
                                }
                                else
                                {
                                    throw new NotSupportedException("Unknown spatial dimension.");
                                }
#endif
                            }
                        }
                        m_CellData.CellNeighbours[jCell] = Neighs.ToArray();
                        Debug.Assert(NoOfFacesFound <= FaceIdx.Length);
                        Debug.Assert(NoOfFacesFound == IdedEdgsAtOneCell.Count);

                        // boundary edges
                        if (NoOfFacesFound == FaceIdx.Length)
                        {
                            // nothing to do - all faces/edges identified
#if DEBUG
                            for (int i = 0; i < NoOfFacesFound; i++)
                            {
                                int Matches = 0;
                                for (int l = 0; l < NoOfFacesFound; l++)
                                {
                                    if (FaceIdx[i].SetEquals(EdgesTemp[IdedEdgsAtOneCell[l]].Vertices))
                                    {
                                        Matches++;
                                    }
                                }
                                Debug.Assert(Matches == 1);
                            }
#endif
                        }
                        else
                        {
                            // missing boundary

                            for (int i = 0; i < FaceIdx.Length; i++)
                            {
                                int Matches = 0;
                                for (int l = 0; l < NoOfFacesFound; l++)
                                {
                                    if (FaceIdx[i].SetEquals(EdgesTemp[IdedEdgsAtOneCell[l]].Vertices))
                                    {
                                        Matches++;
                                    }
                                }
                                Debug.Assert(Matches <= 1);

                                if (Matches == 0)
                                {
                                    // boundary edge found
                                    var Etmp = new EdgeTemp()
                                    {
                                        jCell1   = jCell,
                                        jCell2   = int.MinValue,
                                        Vertices = EdgeVtx.ToArray()
                                    };
                                    EdgesTemp.Add(Etmp);
                                    tmpCells2Edges[jCell].Add(EdgesTemp.Count); // index shifted by 1
                                }
                            }
                        }
                    }

                    // convert temporary data structures to the final ones
                    m_CellData.Cells2Edges = new int[J][];
                    var C2E = m_CellData.Cells2Edges;
                    for (int j = 0; j < J; j++)
                    {
                        C2E[j] = tmpCells2Edges[j] != null ? tmpCells2Edges[j].ToArray() : new int[0];
                    }


                    m_GeomEdges = new GeomEdgeData();
                    int NoOfEdges = EdgesTemp.Count;
                    m_GeomEdges.Info          = new EdgeInfo[NoOfEdges];
                    m_LogEdges.CellIndices    = new int[NoOfEdges, 2];
                    m_GeomEdges.VertexIndices = new int[NoOfEdges][];
                    var Evtx = m_GeomEdges.VertexIndices;
                    var E2C  = m_LogEdges.CellIndices;
                    var Einf = m_GeomEdges.Info;
                    for (int iEdge = 0; iEdge < NoOfEdges; iEdge++)
                    {
                        var Etmp = EdgesTemp[iEdge];
                        E2C[iEdge, 0] = Etmp.jCell1;
                        E2C[iEdge, 1] = Etmp.jCell2;
                        Einf[iEdge]   = EdgeInfo.EdgeIsAffineLinear | EdgeInfo.IsAggregate;
                        if (Etmp.jCell2 < 0)
                        {
                            Einf[iEdge] |= EdgeInfo.Boundary;
                        }
                        Evtx[iEdge] = Etmp.Vertices;
                    }
                }


                // edge metrics
                {
                    if (D == 2)
                    {
                        m_GeomEdges.EdgeRefElements = new RefElement[] { Line.Instance };
                    }
                    else if (D == 3)
                    {
                        m_GeomEdges.EdgeRefElements = new RefElement[] { Triangle.Instance };
                    }
                    else
                    {
                        throw new NotSupportedException("Unknown spatial dimension.");
                    }

                    int[][] Evtx = m_GeomEdges.VertexIndices;

                    int NoOfParts = 0;
                    int NoOfEdges = m_GeomEdges.Count;
                    for (int iEdge = 0; iEdge < NoOfEdges; iEdge++)
                    {
                        NoOfParts += Evtx[iEdge].Length - D + 1;
                    }
                    Debug.Assert(D != 2 || NoOfParts == NoOfEdges);

                    m_GeomEdges.Edge2CellTrafoIndex = new int[NoOfParts, 2];
                    var tmpEdg2CellTrafo = new Dictionary <int, Tuple <int, AffineTrafo> >();

                    // unsolved problem:
                    // (D-1) -- dimensional tesselation of edge is given by D -- dimensional tesselation of adjacent cells
                    // * case D == 2: trivial
                    // * case D == 3: the problem is that two adjacent cells will induce _two different_ tesselations, which
                    //                wont match in the general case.


                    MultidimensionalArray PreImage = m_GeomEdges.EdgeRefElements[0].Vertices;
                    MultidimensionalArray Image    = MultidimensionalArray.Create(PreImage.NoOfRows, D);

                    //for(int iEdge )
                }
            }
        }
예제 #19
0
        public static void FastSubMatrixExtraction(
            [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg,
            [Values(2)] int DGOrder,
            [Values(MatrixShape.laplace)] MatrixShape MShape,
            [Values(4)] int Res
            )
        {
            Utils.TestInit((int)UseXdg, DGOrder, (int)MShape);
            Console.WriteLine("FastSubMatrixExtraction({0},{1},{2})", UseXdg, DGOrder, MShape);

            //Arrange ---
            MultigridOperator mgo = Utils.CreateTestMGOperator(UseXdg, DGOrder, MShape, Res);
            MultigridMapping  map = mgo.Mapping;
            BlockMsrMatrix    M   = mgo.OperatorMatrix;

            var sbs = new SubBlockSelector(map);

            int[] extcells = sbs.AllExternalCellsSelection();
            var   M_ext    = BlockMask.GetAllExternalRows(map, M);
            var   mask     = new BlockMask(sbs, M_ext);

            //Arrange --- get index list of all external cells
            int[]    idc     = Utils.GetAllExtCellIdc(map);
            double[] GlobIdx = idc.Count().ForLoop(i => (double)idc[i] + 1.0);

            //Arrange --- stopwatch
            var stw = new Stopwatch();

            stw.Reset();

            //Act --- Extract SubMatrix
            stw.Start();
            BlockMsrMatrix subM = mask.GetSubBlockMatrix(M);

            stw.Stop();

            //Arrange --- Extract Blocks in Matlab and substract
            var infNorm = MultidimensionalArray.Create(4, 1);
            int rank    = map.MpiRank;

            using (BatchmodeConnector matlab = new BatchmodeConnector()) {
                matlab.PutSparseMatrix(M, "M");
                // note: M_sub lives on Comm_Self, therefore we have to distinguish between procs ...
                matlab.PutSparseMatrixRankExclusive(subM, "M_sub");
                matlab.PutVectorRankExclusive(GlobIdx, "Idx");
                matlab.Cmd("M_0 = M(Idx_0, Idx_0);");
                matlab.Cmd("M_1 = M(Idx_1, Idx_1);");
                matlab.Cmd("M_2 = M(Idx_2, Idx_2);");
                matlab.Cmd("M_3 = M(Idx_3, Idx_3);");
                matlab.Cmd("n=[0; 0; 0; 0];");
                matlab.Cmd("n(1,1)=norm(M_0-M_sub_0,inf);");
                matlab.Cmd("n(2,1)=norm(M_1-M_sub_1,inf);");
                matlab.Cmd("n(3,1)=norm(M_2-M_sub_2,inf);");
                matlab.Cmd("n(4,1)=norm(M_3-M_sub_3,inf);");
                matlab.GetMatrix(infNorm, "n");
                matlab.Execute();
            }

            //Assert --- mask blocks and extracted blocks are the same
            Assert.IsTrue(infNorm[rank, 0] == 0.0);
        }
예제 #20
0
        public void Init(MultigridOperator op)
        {
            int D     = op.Mapping.GridData.SpatialDimension;
            var M     = op.OperatorMatrix;
            var MgMap = op.Mapping;

            this.m_mgop = op;

            if (!M.RowPartitioning.EqualsPartition(MgMap.Partitioning))
            {
                throw new ArgumentException("Row partitioning mismatch.");
            }
            if (!M.ColPartition.EqualsPartition(MgMap.Partitioning))
            {
                throw new ArgumentException("Column partitioning mismatch.");
            }

            Uidx = MgMap.ProblemMapping.GetSubvectorIndices(true, D.ForLoop(i => i));
            Pidx = MgMap.ProblemMapping.GetSubvectorIndices(true, D);

            int Upart = Uidx.Length;
            int Ppart = Pidx.Length;

            ConvDiff = new MsrMatrix(Upart, Upart, 1, 1);
            pGrad    = new MsrMatrix(Upart, Ppart, 1, 1);
            divVel   = new MsrMatrix(Ppart, Upart, 1, 1);
            var PxP = new MsrMatrix(Ppart, Ppart, 1, 1);

            M.AccSubMatrixTo(1.0, ConvDiff, Uidx, default(int[]), Uidx, default(int[]));
            M.AccSubMatrixTo(1.0, pGrad, Uidx, default(int[]), Pidx, default(int[]));
            M.AccSubMatrixTo(1.0, divVel, Pidx, default(int[]), Uidx, default(int[]));
            M.AccSubMatrixTo(1.0, PxP, Pidx, default(int[]), Pidx, default(int[]));

            Mtx = M;

            int L = M.RowPartitioning.LocalLength;

            int i0 = Mtx.RowPartitioning.i0;

            P = new MsrMatrix(Mtx);
            P.Clear();

            // Debugging output
            //ConvDiff.SaveToTextFileSparse("ConvDiff");
            //divVel.SaveToTextFileSparse("divVel");
            //pGrad.SaveToTextFileSparse("pGrad");
            //PxP.SaveToTextFileSparse("PxP");


            velMassMatrix = new MsrMatrix(Upart, Upart, 1, 1);
            op.MassMatrix.AccSubMatrixTo(1.0, velMassMatrix, Uidx, default(int[]), Uidx, default(int[]));

            switch (SchurOpt)
            {
            case SchurOptions.exact:
            {
                // Building complete Schur and Approximate Schur
                MultidimensionalArray Poisson       = MultidimensionalArray.Create(Pidx.Length, Pidx.Length);
                MultidimensionalArray SchurConvPart = MultidimensionalArray.Create(Pidx.Length, Pidx.Length);
                MultidimensionalArray Schur         = MultidimensionalArray.Create(Pidx.Length, Pidx.Length);
                using (BatchmodeConnector bmc = new BatchmodeConnector())
                {
                    bmc.PutSparseMatrix(ConvDiff, "ConvDiff");
                    bmc.PutSparseMatrix(velMassMatrix, "MassMatrix");
                    bmc.PutSparseMatrix(divVel, "divVel");
                    bmc.PutSparseMatrix(pGrad, "pGrad");
                    bmc.Cmd("Qdiag = diag(diag(MassMatrix))");
                    bmc.Cmd("invT= inv(Qdiag)");
                    bmc.Cmd("Poisson = full(invT)*pGrad");
                    bmc.Cmd("ConvPart = ConvDiff*Poisson");
                    bmc.Cmd("ConvPart= full(invT)*ConvPart");
                    bmc.Cmd("ConvPart= divVel*ConvPart");
                    bmc.Cmd("Poisson = divVel*Poisson");
                    bmc.Cmd("ConvDiffInv = inv(full(ConvDiff))");
                    bmc.Cmd("Schur = divVel*ConvDiffInv");
                    bmc.Cmd("Schur = Schur*pGrad");
                    bmc.GetMatrix(Poisson, "Poisson");
                    bmc.GetMatrix(SchurConvPart, "ConvPart");
                    bmc.GetMatrix(Schur, "-Schur");
                    bmc.Execute(false);
                }
                PoissonMtx_T = Poisson.ToMsrMatrix();
                PoissonMtx_H = Poisson.ToMsrMatrix();
                SchurConvMtx = SchurConvPart.ToMsrMatrix();
                SchurMtx     = Schur.ToMsrMatrix();
                SchurMtx.Acc(PxP, 1);

                ConvDiff.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Uidx);
                pGrad.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Pidx);
                SchurMtx.AccSubMatrixTo(1.0, P, default(int[]), Pidx, default(int[]), Pidx);
                return;
            }

            case SchurOptions.decoupledApprox:
            {
                // Do assembly for approximate Schur inverse
                invVelMassMatrix = velMassMatrix.CloneAs();
                invVelMassMatrix.Clear();
                invVelMassMatrixSqrt = invVelMassMatrix.CloneAs();
                for (int i = velMassMatrix.RowPartitioning.i0; i < velMassMatrix.RowPartitioning.iE; i++)
                {
                    if (ApproxScaling)
                    {
                        invVelMassMatrix.SetDiagonalElement(i, 1 / (velMassMatrix[i, i]));
                        invVelMassMatrixSqrt.SetDiagonalElement(i, 1 / (Math.Sqrt(velMassMatrix[i, i])));
                    }
                    else
                    {
                        invVelMassMatrix.SetDiagonalElement(i, 1);
                        invVelMassMatrixSqrt.SetDiagonalElement(i, 1);
                    }
                }

                //invVelMassMatrix.SaveToTextFileSparse("invVelMassMatrix");
                //velMassMatrix.SaveToTextFileSparse("velMassMatrix");


                //ConvDiffPoissonMtx = MsrMatrix.Multiply(ConvDiff, pGrad);
                //ConvDiffPoissonMtx = MsrMatrix.Multiply(divVel, ConvDiffPoissonMtx);

                // Inverse of mass matrix in Matlab
                //MultidimensionalArray temp = MultidimensionalArray.Create(Uidx.Length, Uidx.Length);
                //using (BatchmodeConnector bmc = new BatchmodeConnector())
                //{
                //    bmc.PutSparseMatrix(velMassMatrix, "velMassMatrix");
                //    bmc.Cmd("invVelMassMatrix = inv(full(velMassMatrix))");
                //    bmc.GetMatrix(temp, "invVelMassMatrix");
                //    bmc.Execute(false);
                //}
                //invVelMassMatrix = temp.ToMsrMatrix();

                //ConvDiffPoissonMtx = MsrMatrix.Multiply(ConvDiffPoissonMtx, PoissonMtx);
                //ConvDiffPoissonMtx = MsrMatrix.Multiply(PoissonMtx, ConvDiffPoissonMtx);

                //ConvDiff.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Uidx);
                //pGrad.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Pidx);
                //ConvDiffPoissonMtx.AccSubMatrixTo(1.0, P, default(int[]), Pidx, default(int[]), Pidx);

                //op.MassMatrix.SaveToTextFileSparse("MassMatrix");
                //velMassMatrix.SaveToTextFileSparse("velMassMatrix2");


                // Possion scaled by inverse of the velocity mass matrix
                PoissonMtx_T = MsrMatrix.Multiply(invVelMassMatrix, pGrad);
                PoissonMtx_T = MsrMatrix.Multiply(divVel, PoissonMtx_T);
                ////PoissonMtx_T.Acc(PxP, 1); // p.379

                // Poisson scaled by sqrt of inverse of velocity mass matrix
                PoissonMtx_H = MsrMatrix.Multiply(invVelMassMatrixSqrt, pGrad);
                PoissonMtx_H = MsrMatrix.Multiply(divVel, PoissonMtx_H);
                //PoissonMtx_H.Acc(PxP, 1); // p.379
                return;
            }

            case SchurOptions.SIMPLE:
            {
                var invdiag_ConvDiff = ConvDiff.CloneAs();
                invdiag_ConvDiff.Clear();
                for (int i = ConvDiff.RowPartitioning.i0; i < ConvDiff.RowPartitioning.iE; i++)
                {
                    invdiag_ConvDiff[i, i] = 1 / ConvDiff[i, i];
                }

                simpleSchur = MsrMatrix.Multiply(invdiag_ConvDiff, pGrad);
                simpleSchur = MsrMatrix.Multiply(divVel, simpleSchur);

                return;
            }

            default:
                throw new NotImplementedException("SchurOption");
            }


            //var ConvDiffInvMtx = ConvDiffInv.ToMsrMatrix();


            //// x= inv(P)*b !!!!! To be done with approximate Inverse
            // P.SpMV(1, B, 0, X);
        }
예제 #21
0
        public static void SubBlockExtraction(
            [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg,
            [Values(2)] int DGOrder,
            [Values(MatrixShape.diagonal_var_spec, MatrixShape.diagonal_spec, MatrixShape.diagonal_var, MatrixShape.diagonal)] MatrixShape MShape,
            [Values(4)] int Res
            )
        {
            Utils.TestInit((int)UseXdg, DGOrder, (int)MShape);
            Console.WriteLine("SubMatrixIgnoreCoupling({0},{1},{2})", UseXdg, DGOrder, MShape);

            //Arrange --- create test matrix and MG mapping
            MultigridOperator mgo = Utils.CreateTestMGOperator(UseXdg, DGOrder, MShape, Res);
            MultigridMapping  map = mgo.Mapping;
            BlockMsrMatrix    M   = mgo.OperatorMatrix;

            //Arrange --- masking of all external cells
            var sbs = new SubBlockSelector(map);

            sbs.AllExternalCellsSelection();
            var M_ext = BlockMask.GetAllExternalRows(map, M);
            var mask  = new BlockMask(sbs, M_ext);
            //bool[] coup = Utils.SetCoupling(MShape);

            //Arrange --- get index dictonary of all external cell indices
            Dictionary <int, int[]> Didc = Utils.GetDictOfAllExtCellIdc(map);

            //Arrange --- stopwatch
            var stw = new Stopwatch();

            stw.Reset();

            //Act --- Extract subblocks
            stw.Start();
            //var eblocks = mask.GetSubBlocks(M,coup[0],coup[1],coup[2]);
            var eblocks = mask.GetDiagonalBlocks(M, false, false);

            stw.Stop();

            //Assert --- same number of blocks?
            Assert.IsTrue(eblocks.Length == M_ext._RowPartitioning.LocalNoOfBlocks);

            bool test = eblocks.Length.MPIEquals();

            Debug.Assert(test);
            for (int iBlock = 0; iBlock < eblocks.Length; iBlock++)
            {
                var infNorm     = MultidimensionalArray.Create(4, 1);
                int rank        = map.MpiRank;
                int ExtBlockIdx = iBlock + map.AggGrid.iLogicalCells.NoOfLocalUpdatedCells;
                Didc.TryGetValue(ExtBlockIdx, out int[] idc);

                using (BatchmodeConnector matlab = new BatchmodeConnector()) {
                    double[] GlobIdx = idc.Count().ForLoop(i => (double)idc[i] + 1.0);
                    Assert.IsTrue(GlobIdx.Length == eblocks[iBlock].Lengths[0]);
                    MsrMatrix M_sub = eblocks[iBlock].ConvertToMsr();

                    matlab.PutSparseMatrix(M, "M");
                    // note: M_sub lives on Comm_Self, therefore we have to distinguish between procs ...
                    matlab.PutSparseMatrixRankExclusive(M_sub, "M_sub");
                    matlab.PutVectorRankExclusive(GlobIdx, "Idx");
                    matlab.Cmd("M_0 = full(M(Idx_0, Idx_0));");
                    matlab.Cmd("M_1 = full(M(Idx_1, Idx_1));");
                    matlab.Cmd("M_2 = full(M(Idx_2, Idx_2));");
                    matlab.Cmd("M_3 = full(M(Idx_3, Idx_3));");
                    matlab.Cmd("n=[0; 0; 0; 0];");
                    matlab.Cmd("n(1,1)=norm(M_0-M_sub_0,inf);");
                    matlab.Cmd("n(2,1)=norm(M_1-M_sub_1,inf);");
                    matlab.Cmd("n(3,1)=norm(M_2-M_sub_2,inf);");
                    matlab.Cmd("n(4,1)=norm(M_3-M_sub_3,inf);");
                    matlab.GetMatrix(infNorm, "n");
                    matlab.Execute();
                }
                Assert.IsTrue(infNorm[rank, 0] == 0.0); //
            }
        }