Exemplo n.º 1
0
        public static void CellwiseSubSelection(
            [Values(SelectionType.all_combined, SelectionType.degrees, SelectionType.species, SelectionType.variables)] SelectionType SType
            )
        {
            Utils.TestInit((int)SType);
            Console.WriteLine("SubSelection({0})", SType);

            //Arrange --- extracts entries of matrix according to hardcoded selection
            int            DGdegree       = 2;
            int            GridResolution = 4;
            var            mgo            = Utils.CreateTestMGOperator(XDGusage.all, DGdegree, MatrixShape.full_var_spec, GridResolution);
            int            sampleCellA    = Utils.GetIdxOfFirstBlockWith(mgo.Mapping, false); //1 species
            int            sampleCellB    = Utils.GetIdxOfFirstBlockWith(mgo.Mapping, true);  //2 species
            BlockMsrMatrix compA          = Utils.GetCellCompMatrix(SType, mgo, sampleCellA);
            BlockMsrMatrix compB          = Utils.GetCellCompMatrix(SType, mgo, sampleCellB);

            int iBlock = sampleCellB + mgo.Mapping.AggGrid.CellPartitioning.i0;
            int i0     = mgo.Mapping.GetBlockI0(iBlock);
            var block  = MultidimensionalArray.Create(mgo.Mapping.GetBlockLen(iBlock), mgo.Mapping.GetBlockLen(iBlock));

            mgo.OperatorMatrix.ReadBlock(i0, i0, block);

            //Arrange --- setup masking, which correspond to hardcoded
            SubBlockSelector sbsA = new SubBlockSelector(mgo.Mapping);

            sbsA.GetDefaultSelection(SType, sampleCellA); // single spec
            BlockMask        maskA = new BlockMask(sbsA, null);
            SubBlockSelector sbsB  = new SubBlockSelector(mgo.Mapping);

            sbsB.GetDefaultSelection(SType, sampleCellB); // double spec
            BlockMask maskB = new BlockMask(sbsB, null);

            //Arrange --- some time measurement
            Stopwatch stw = new Stopwatch();

            stw.Reset();

            //Act --- subblock extraction
            stw.Start();
            var blocksA = maskA.GetDiagonalBlocks(mgo.OperatorMatrix, false, false);
            var blocksB = maskB.GetDiagonalBlocks(mgo.OperatorMatrix, false, false);

            stw.Stop();

            //Assert ---
            Assert.IsTrue(blocksA.Length == 1);
            Assert.IsTrue(blocksB.Length == 1);
            Assert.IsTrue(compA.RowPartitioning.LocalLength == blocksA[0].GetLength(0));
            Assert.IsTrue(compB.RowPartitioning.LocalLength == blocksB[0].GetLength(0));

            //Assert --- compare masking of single spec cell
            Debug.Assert(compA.InfNorm() != 0.0);
            compA.AccBlock(0, 0, -1.0, blocksA[0]);
            Assert.IsTrue(compA.InfNorm() == 0.0);

            //Assert --- compare masking of double spec cell
            Debug.Assert(compB.InfNorm() != 0.0);
            compB.AccBlock(0, 0, -1.0, blocksB[0]);
            Assert.IsTrue(compB.InfNorm() == 0.0, String.Format("proc{0}: not fulfilled at block {1}", mgo.Mapping.MpiRank, sampleCellB));
        }
Exemplo n.º 2
0
        void DelComputeOperatorMatrix(BlockMsrMatrix OpMtx, double[] OpAffine, UnsetteledCoordinateMapping Mapping, DGField[] CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double phystime)
        {
            DGField[] Params = null;
            if (this.Control.Eq == Equation.ScalarTransport)
            {
                Params = this.V.ToArray();
            }
            else if (this.Control.Eq == Equation.HeatEq)
            {
                Params = null;
            }
            else if (this.Control.Eq == Equation.Burgers)
            {
                Params = CurrentState;
            }
            else
            {
                throw new NotImplementedException();
            }

            // compute operator
            Debug.Assert(OpMtx.InfNorm() == 0.0);
            Debug.Assert(OpAffine.L2Norm() == 0.0);
            Operator.ComputeMatrixEx(this.LsTrk,
                                     Mapping, Params, Mapping,
                                     OpMtx, OpAffine, false, phystime, true,
                                     AgglomeratedCellLengthScales, null, null,
                                     AgglomeratedCellLengthScales.Keys.ToArray());
        }
Exemplo n.º 3
0
        static void PrlgAndRestMtxTestRec(int p, MultigridMapping[] MgMapSeq)
        {
            var currentLevelMap = MgMapSeq.First();
            var AggBasis        = currentLevelMap.AggBasis[0];

            // extract Restriciton and Prolongation Operators
            BlockMsrMatrix RestOp = new BlockMsrMatrix(MgMapSeq.First(), MgMapSeq.First().ProblemMapping);

            AggBasis.GetRestrictionMatrix(RestOp, MgMapSeq.First(), 0);

            BlockMsrMatrix PrlgOp = RestOp.Transpose();

            // restriction onto level itself
            BlockMsrMatrix ShldBeEye = BlockMsrMatrix.Multiply(RestOp, PrlgOp);

            ShldBeEye.AccEyeSp(-1.0);
            double ErrNorm = ShldBeEye.InfNorm();

            Console.WriteLine("Id norm {0} \t (level {1})", ErrNorm, currentLevelMap.AggGrid.MgLevel);
            Assert.Less(ErrNorm, 1.0e-8);

            if (MgMapSeq.Length > 1)
            {
                PrlgAndRestMtxTestRec(p, MgMapSeq.Skip(1).ToArray());
            }
        }
Exemplo n.º 4
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            //phystime = 1.8;
            LsUpdate(phystime);

            // operator-matrix assemblieren
            OperatorMatrix    = new BlockMsrMatrix(ProblemMapping);
            AltOperatorMatrix = new MsrMatrix(ProblemMapping);
            double[] Affine = new double[OperatorMatrix.RowPartitioning.LocalLength];
            MultiphaseCellAgglomerator Agg;

            // Agglomerator setup
            //Agg = new MultiphaseCellAgglomerator(new CutCellMetrics(MomentFittingVariant, m_quadOrder, LsTrk, LsTrk.GetSpeciesId("B")), this.THRESHOLD, false);
            Agg = LsTrk.GetAgglomerator(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, m_quadOrder, __AgglomerationTreshold: this.THRESHOLD);
            Console.WriteLine("Inter-Process agglomeration? " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.InterProcessAgglomeration);

            // operator matrix assembly
            //Op.ComputeMatrixEx(LsTrk,
            //    ProblemMapping, null, ProblemMapping,
            //    OperatorMatrix, Affine, false, 0.0, true,
            //    Agg.CellLengthScales, null, null,
            //    LsTrk.SpeciesIdS.ToArray());
            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, ProblemMapping, null, ProblemMapping, LsTrk.SpeciesIdS.ToArray());
            mtxBuilder.time = 0.0;
            mtxBuilder.ComputeMatrix(OperatorMatrix, Affine);
            Agg.ManipulateMatrixAndRHS(OperatorMatrix, Affine, this.ProblemMapping, this.ProblemMapping);

            //Op.ComputeMatrixEx(LsTrk,
            //    ProblemMapping, null, ProblemMapping,
            //    AltOperatorMatrix, Affine, false, 0.0, true,
            //    Agg.CellLengthScales, null, null,
            //    LsTrk.SpeciesIdS.ToArray());
            mtxBuilder.ComputeMatrix(AltOperatorMatrix, Affine);
            Agg.ManipulateMatrixAndRHS(AltOperatorMatrix, Affine, this.ProblemMapping, this.ProblemMapping);


            int nnz = this.OperatorMatrix.GetTotalNoOfNonZeros();

            Console.WriteLine("Number of non-zeros in matrix: " + nnz);

            int nnz2 = this.AltOperatorMatrix.GetTotalNoOfNonZeros();

            Assert.IsTrue(nnz == nnz2, "Number of non-zeros in matrix different for " + OperatorMatrix.GetType() + " and " + AltOperatorMatrix.GetType());
            Console.WriteLine("Number of non-zeros in matrix (reference): " + nnz2);

            MsrMatrix Comp = AltOperatorMatrix.CloneAs();

            Comp.Acc(-1.0, OperatorMatrix);
            double CompErr    = Comp.InfNorm();
            double Denom      = Math.Max(AltOperatorMatrix.InfNorm(), OperatorMatrix.InfNorm());
            double CompErrRel = Denom > Math.Sqrt(double.Epsilon) ? CompErr / Denom : CompErr;

            Console.WriteLine("Comparison: " + CompErrRel);

            Assert.LessOrEqual(CompErrRel, 1.0e-7, "Huge difference between MsrMatrix and BlockMsrMatrix.");

            base.TerminationKey = true;
            return(0.0);
        }
Exemplo n.º 5
0
        /// <summary>
        /// computes <see cref="LaplaceMtx"/> and <see cref="LaplaceAffine"/>
        /// </summary>
        private void UpdateMatrices() {
            using (var tr = new FuncTrace()) {
                // time measurement for matrix assembly
                Stopwatch stw = new Stopwatch();
                stw.Start();

                // console
                Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal);

                // quadrature domain
                var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData, MaskType.Geometrical));
                var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData, MaskType.Geometrical));

#if DEBUG
                // in DEBUG mode, we compare 'MsrMatrix' (old, reference implementation) and 'BlockMsrMatrix' (new standard)
                var RefLaplaceMtx = new MsrMatrix(T.Mapping);
#endif
                using (new BlockTrace("SipMatrixAssembly", tr)) {
                    LaplaceMtx = new BlockMsrMatrix(T.Mapping);
                    LaplaceAffine = new double[T.Mapping.LocalLength];

                    LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping,
                                             LaplaceMtx, LaplaceAffine,
                                             volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);
                }
#if DEBUG
                LaplaceAffine.ClearEntries();
                LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping,
                                         RefLaplaceMtx, LaplaceAffine,
                                         volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);
                MsrMatrix ErrMtx = RefLaplaceMtx.CloneAs();
                ErrMtx.Acc(-1.0, LaplaceMtx);
                double err = ErrMtx.InfNorm();
                double infNrm = LaplaceMtx.InfNorm();
                Console.WriteLine("Matrix comparison error: " + err + ", matrix norm is: " + infNrm);
                Assert.Less(err, infNrm * 1e-10, "MsrMatrix2 comparison failed.");
#endif
                stw.Stop();
                Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds);


                //var JB = LapaceIp.GetFDJacobianBuilder(T.Mapping.Fields, null, T.Mapping, edgQrSch, volQrSch);
                //var JacobiMtx = new BlockMsrMatrix(T.Mapping);
                //var JacobiAffine = new double[T.Mapping.LocalLength];
                //JB.ComputeMatrix(JacobiMtx, JacobiAffine);
                //double L2ErrAffine = GenericBlas.L2Dist(JacobiAffine, LaplaceAffine);
                //var ErrMtx2 = LaplaceMtx.CloneAs();
                //ErrMtx2.Acc(-1.0, JacobiMtx);
                //double LinfErrMtx2 = ErrMtx2.InfNorm();

                //JacobiMtx.SaveToTextFileSparse("D:\\tmp\\Jac.txt");
                //LaplaceMtx.SaveToTextFileSparse("D:\\tmp\\Lap.txt");

                //Console.WriteLine("FD Jacobi Mtx: {0:e14}, Affine: {1:e14}", LinfErrMtx2, L2ErrAffine);
            }
        }
Exemplo n.º 6
0
        static void RestictionMatrixTestRec(int p, IEnumerable <MultigridMapping> MgMapSeq)
        {
            var currentLevelMap           = MgMapSeq.First();
            AggregationGridBasis AggBasis = currentLevelMap.AggBasis[0];

            var map = new UnsetteledCoordinateMapping(new Basis(grid, p));

            Random rnd = new Random();

            double[] OrigVec  = map.LocalLength.ForLoop(i => rnd.NextDouble());
            double[] RestVec  = new double[AggBasis.LocalDim];
            double[] PrlgVec  = new double[OrigVec.Length];
            double[] RestVec2 = new double[RestVec.Length];
            double[] PrlgVec2 = new double[OrigVec.Length];


            AggBasis.RestictFromFullGrid(OrigVec, RestVec);
            AggBasis.ProlongateToFullGrid(PrlgVec, RestVec);

            BlockMsrMatrix RestOp = new BlockMsrMatrix(MgMapSeq.First(), MgMapSeq.First().ProblemMapping);

            AggBasis.GetRestrictionMatrix(RestOp, MgMapSeq.First(), 0);
            RestOp.SpMV(1.0, OrigVec, 0.0, RestVec2);

            BlockMsrMatrix PrlgOp = RestOp.Transpose();

            PrlgOp.SpMV(1.0, RestVec2, 0.0, PrlgVec2);

            double RestErrNorm = GenericBlas.L2Dist(RestVec2, RestVec);
            double PrlgErrNorm = GenericBlas.L2Dist(PrlgVec2, PrlgVec);
            double LostInfNorm = GenericBlas.L2Dist(OrigVec, PrlgVec2);

            //Console.WriteLine("Rest. matrix test: {0}, Prolong. matrix test {1}, Lost info {2}", RestErrNorm, PrlgErrNorm, LostInfNorm);
            Assert.IsTrue(RestErrNorm < 1.0e-10);
            Assert.IsTrue(PrlgErrNorm < 1.0e-10);

            // restriction onto level itself
            BlockMsrMatrix RestMtx   = currentLevelMap.FromOtherLevelMatrix(currentLevelMap);
            BlockMsrMatrix ShldBeEye = BlockMsrMatrix.Multiply(RestMtx, RestMtx.Transpose());

            ShldBeEye.AccEyeSp(-1.0);
            double errNorm = ShldBeEye.InfNorm();

            Console.WriteLine("Id norm {0} \t (level {1})", errNorm, currentLevelMap.AggGrid.MgLevel);
            Assert.IsTrue(errNorm < 1.0e-8);


            // recursion
            if (MgMapSeq.Count() > 1)
            {
                RestictionMatrixTestRec(p, MgMapSeq.Skip(1));
            }
        }
Exemplo n.º 7
0
        private void AssembleMatrix(double dt, out BlockMsrMatrix SystemMatrix, out double[] SystemAffine)
        {
            // Init Matrix and Affine Part
            SystemMatrix = new BlockMsrMatrix(Mapping);
            SystemAffine = new double[Mapping.LocalLength];

            // choose TimeStepping-Scheme, based on what has been pushed to the stack,yet
            int Smax = TSCchain[0].S;

            Debug.Assert(Smax == TSCchain.Length);
            Tsc = TSCchain[Smax - PopulatedStackDepth];

            UpdateOperatorMatrix();



            //Implicit Part of RHS
            SystemMatrix.Acc(Tsc.theta1, Stack_OpMatrix[1]);
            SystemAffine.AccV(Tsc.theta1, Stack_OpAffine[1]);



            //Implicit Part of LHS
            SystemMatrix.AccEyeSp(1 / dt);

            // Explicit part of RHS
            Stack_OpMatrix[0].SpMV(-Tsc.theta0, CurrentState, 1.0, SystemAffine);
            SystemAffine.AccV(-Tsc.theta0, Stack_OpAffine[0]);

            //Explicit parts of LHS
            for (int i = 0; i < Tsc.beta.Length; i++)
            {
                SystemAffine.AccV(Tsc.beta[i] * 1 / dt, Stack_u[i]);
            }

            Debug.Assert(SystemMatrix.InfNorm() > 0);
            Debug.Assert(SystemAffine.L2Norm() > 0);

            if (subGrid != null)
            {
                int[] SubVecIdx = Mapping.GetSubvectorIndices(subGrid, true, new int[] { 0 });
                int   L         = SubVecIdx.Length;

                for (int i = 0; i < L; i++)
                {
                    SystemMatrix.ClearRow(SubVecIdx[i]);
                    SystemMatrix[SubVecIdx[i], SubVecIdx[i]] = 1;
                    SystemAffine[SubVecIdx[i]] = 0;
                }
            }
        }
Exemplo n.º 8
0
        public static void SubSelection(
            [Values(SelectionType.all_combined, SelectionType.degrees, SelectionType.species, SelectionType.variables)] SelectionType SType
            )
        {
            Utils.TestInit((int)SType);
            Console.WriteLine("SubSelection({0})", SType);

            //Arrange --- extracts entries of matrix according to hardcoded selection
            int            DGdegree       = 2;
            int            GridResolution = 4;
            var            mgo            = Utils.CreateTestMGOperator(XDGusage.all, DGdegree, MatrixShape.full_var_spec, GridResolution);
            int            sampleCellA    = Utils.GetIdxOfFirstBlockWith(mgo.Mapping, false); //1 species
            int            sampleCellB    = Utils.GetIdxOfFirstBlockWith(mgo.Mapping, true);  //2 species
            BlockMsrMatrix compA          = Utils.GetCellCompMatrix(SType, mgo, sampleCellA);
            BlockMsrMatrix compB          = Utils.GetCellCompMatrix(SType, mgo, sampleCellB);

            //Arrange --- setup masking, which correspond to hardcoded
            SubBlockSelector sbsA = new SubBlockSelector(mgo.Mapping);

            sbsA.GetDefaultSelection(SType, sampleCellA); // single spec
            BlockMask        maskA = new BlockMask(sbsA, null);
            SubBlockSelector sbsB  = new SubBlockSelector(mgo.Mapping);

            sbsB.GetDefaultSelection(SType, sampleCellB); // double spec
            BlockMask maskB = new BlockMask(sbsB, null);

            //Arrange --- stop the watch
            Stopwatch stw = new Stopwatch();

            stw.Reset();

            //Act --- get subblocks
            stw.Start();
            BlockMsrMatrix subA = maskA.GetSubBlockMatrix(mgo.OperatorMatrix);
            BlockMsrMatrix subB = maskB.GetSubBlockMatrix(mgo.OperatorMatrix);

            stw.Stop();

            //Assert --- compare masking of single spec cell
            Debug.Assert(compA.InfNorm() != 0.0);
            subA.Acc(-1.0, compA);
            Assert.IsTrue(subA.InfNorm() == 0.0);

            //Assert --- compare masking of double spec cell
            Debug.Assert(compB.InfNorm() != 0.0);
            subB.Acc(-1.0, compB);
            Assert.IsTrue(subB.InfNorm() == 0.0);
        }
Exemplo n.º 9
0
 protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L)
 {
     AssembleMatrix(this.Control.MU_A, this.Control.MU_B, out Op_Matrix, out Op_Affine, out Op_Agglomeration, out Op_mass);
     Console.WriteLine("Matrix norm: {0}", Op_Matrix.InfNorm());
     Console.WriteLine("Symm. diff: {0}", Op_Matrix.SymmetryDeviation());
 }
Exemplo n.º 10
0
        public void Init(MultigridOperator op)
        {
            using (new FuncTrace()) {
                if (m_MgOp != null)
                {
                    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    // someone is trying to re-use this solver: see if the settings permit that
                    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                    if (op.LevelIndex != m_MgOp.LevelIndex)
                    {
                        throw new ArgumentException("Re-use on different level not possible.");
                    }
                    if (!this.MtxFull._RowPartitioning.EqualsPartition(op.OperatorMatrix._RowPartitioning))
                    {
                        throw new ArgumentException("Matrix has changed, unable to re-use");
                    }
                    if (!this.MtxFull._ColPartitioning.EqualsPartition(op.OperatorMatrix._ColPartitioning))
                    {
                        throw new ArgumentException("Matrix has changed, unable to re-use");
                    }
#if DEBUG
                    if (!object.ReferenceEquals(this.MtxFull, op.OperatorMatrix))
                    {
                        BlockMsrMatrix Check = this.MtxFull.CloneAs();
                        Check.Acc(-1.0, op.OperatorMatrix);
                        if (Check.InfNorm() != 0.0)
                        {
                            throw new ArgumentException("Matrix has changed, unable to re-use");
                        }
                    }
#endif
                    if (this.m_BlockingStrategy.GetNoOfBlocks(op) != this.blockSolvers.Count())
                    {
                        throw new ArgumentException("Blocking, unable to re-use");
                    }


                    return;
                }

                var Mop   = op.OperatorMatrix;
                var MgMap = op.Mapping;
                this.m_MgOp = op;
                int myMpiRank = MgMap.MpiRank;
                int myMpisize = MgMap.MpiSize;

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

                var ag = MgMap.AggGrid;

                int JComp  = ag.iLogicalCells.NoOfLocalUpdatedCells;
                int JGhost = ag.iLogicalCells.NoOfExternalCells;

#if DEBUG
                ilPSP.Connectors.Matlab.BatchmodeConnector matlab;
                if (m_MatlabParalellizationCheck)
                {
                    matlab = new ilPSP.Connectors.Matlab.BatchmodeConnector();
                }
                else
                {
                    matlab = null;
                }
#endif

                //Mop.Clear();
                //for(int i = Mop.RowPartitioning.i0; i < Mop.RowPartitioning.iE; i++) {
                //    Mop[i, i] = i + 1;
                //}


                // get cell blocks
                // ===============

                var _Blocks         = this.m_BlockingStrategy.GetBlocking(op);
                int NoOfSchwzBlocks = _Blocks.Count();

                // test cell blocks
                // ================
#if DEBUG
                {
                    // ensure that each cell is used exactly once, among all blocks
                    bool[] test = new bool[ag.iLogicalCells.NoOfLocalUpdatedCells];
                    foreach (var bi in _Blocks)
                    {
                        foreach (int j in bi)
                        {
                            Debug.Assert(test[j] == false);
                            test[j] = true;
                        }
                        ;
                    }
                    for (int i = 0; i < test.Length; i++)
                    {
                        Debug.Assert(test[i] == true);
                    }
                }
#endif

                // extend blocks according to desired overlap
                // ==========================================
                {
                    BitArray marker = new BitArray(JComp + JGhost);

                    if (Overlap < 0)
                    {
                        throw new ArgumentException();
                    }
                    if (Overlap > 0)
                    {
                        if (Overlap > 1 && Mop.RowPartitioning.MpiSize > 1)
                        {
                            throw new NotSupportedException("In MPI parallel runs, the maximum supported overlap for the Schwarz preconditioner is 1.");
                        }

                        foreach (List <int> bi in _Blocks) // loop over blocks...
                        {
                            marker.SetAll(false);          // marks all cells which are members of the block
                            foreach (int jcomp in bi)
                            {
                                marker[jcomp] = true;
                            }

                            // determine overlap regions
                            for (int k = 0; k < Overlap; k++)
                            {
                                int Jblock = bi.Count;
                                for (int j = 0; j < Jblock; j++)
                                {
                                    int   jCell  = bi[j];
                                    int[] Neighs = ag.iLogicalCells.CellNeighbours[jCell];
                                    foreach (int jNeigh in Neighs)
                                    {
                                        if (marker[jNeigh] == false)
                                        {
                                            // neighbor cell is not already a member of the block
                                            // => add it.
                                            bi.Add(jNeigh);
                                            marker[jNeigh] = true;
                                        }
                                    }
                                }
                            }

                            bi.Sort();
                        }
                    }

                    BlockCells = _Blocks.Select(list => list.ToArray()).ToArray();
                }


                // convert cell blocks to DOF blocks
                // =================================

                List <int>[] BlkIdx_gI_lR;                  //  for each Schwarz block, (global) indices in the local range
                List <int>[] BlkIdx_gI_eR;                  //  for each Schwarz block, (global) indices of external rows and columns
                List <int>[] TempRowIdx_gI;                 // for each Schwarz block, (global) indices into the temporary matrix
                List <int>[] BlkIdx_lI_eR;                  //  for each Schwarz block, (local)  indices of external rows and columns
                List <int>[] LocalBlocks_i0, LocalBlocks_N; // blocking of the Schwarz-Blocks.

                // for matrix 'ExternalRowsTemp': which rows of 'Mop' are required locally
                List <int> ExternalRowsIndices, ExternalRows_BlockI0, ExternalRows_BlockN;
                {
                    int Jup = MgMap.AggGrid.iLogicalCells.NoOfLocalUpdatedCells;
                    int Jgh = MgMap.AggGrid.iLogicalCells.NoOfExternalCells;

                    int LocalizedBlockCounter = 0;

                    BlkIdx_gI_lR   = NoOfSchwzBlocks.ForLoop(iPart => new List <int>(BlockCells[iPart].Length * MgMap.MaximalLength));
                    BlkIdx_gI_eR   = NoOfSchwzBlocks.ForLoop(iPart => new List <int>());
                    LocalBlocks_i0 = NoOfSchwzBlocks.ForLoop(iPart => new List <int>());
                    LocalBlocks_N  = NoOfSchwzBlocks.ForLoop(iPart => new List <int>());

                    TempRowIdx_gI = NoOfSchwzBlocks.ForLoop(iPart => new List <int>());
                    BlkIdx_lI_eR  = NoOfSchwzBlocks.ForLoop(iPart => new List <int>());


                    ExternalRowsIndices  = new List <int>();
                    ExternalRows_BlockI0 = new List <int>();
                    ExternalRows_BlockN  = new List <int>();

                    for (int iPart = 0; iPart < NoOfSchwzBlocks; iPart++)   // loop over parts...
                    {
                        int[] bc    = BlockCells[iPart];
                        var   biI   = BlkIdx_gI_lR[iPart];
                        var   biE   = BlkIdx_gI_eR[iPart];
                        var   l1    = TempRowIdx_gI[iPart];
                        var   l2    = BlkIdx_lI_eR[iPart];
                        var   LBBi0 = LocalBlocks_i0[iPart];
                        var   LBBN  = LocalBlocks_N[iPart];


                        int Jblock         = bc.Length;
                        int anotherCounter = 0;

                        for (int jblk = 0; jblk < Jblock; jblk++)   // loop over cells in blocks...
                        {
                            int j = bc[jblk];
                            int N = MgMap.GetLength(j);

                            if (j < Jup)
                            {
                                // locally updated cell
                                int i0 = MgMap.GlobalUniqueIndex(0, j, 0);

                                for (int n = 0; n < N; n++)
                                {
                                    biI.Add(i0 + n);
                                }
                            }
                            else
                            {
                                // external cell
                                int i0E = MgMap.GlobalUniqueIndex(0, j, 0); //
                                int i0L = MgMap.LocalUniqueIndex(0, j, 0);  //
                                ExternalRows_BlockI0.Add(LocalizedBlockCounter);
                                ExternalRows_BlockN.Add(N);
                                //LEBi0.Add(LocalizedBlockCounter);
                                //LEBn.Add(N);
                                for (int n = 0; n < N; n++)
                                {
                                    biE.Add(i0E + n);
                                    ExternalRowsIndices.Add(i0E + n);
                                    l1.Add(LocalizedBlockCounter + n);
                                    l2.Add(i0L + n);
                                    Debug.Assert(Mop._RowPartitioning.FindProcess(i0E + n) != myMpiRank);
                                }

                                LocalizedBlockCounter += N;
                            }

                            LBBi0.Add(anotherCounter);
                            LBBN.Add(N);

                            anotherCounter += N;
                        }
                    }

                    //this.BlockIndices = _LocallyStoredBlockIndices.Select(bi => bi.ToArray()).ToArray();
                }


                // get rows for blocks that use external cells
                // ===========================================

#if DEBUG
                {
                    if (Overlap == 0)
                    {
                        Debug.Assert(ExternalRowsIndices.Count == 0);
                        Debug.Assert(ExternalRows_BlockI0.Count == 0);
                        Debug.Assert(ExternalRows_BlockN.Count == 0);
                    }

                    foreach (var bi in BlkIdx_gI_lR)
                    {
                        foreach (int idx in bi)
                        {
                            Debug.Assert(idx >= m_MgOp.Mapping.i0);
                            Debug.Assert(idx < m_MgOp.Mapping.iE);
                        }
                    }

                    foreach (var ei in BlkIdx_gI_eR)
                    {
                        foreach (int idx in ei)
                        {
                            Debug.Assert(idx < m_MgOp.Mapping.i0 || idx >= m_MgOp.Mapping.iE);
                        }
                    }


                    int LL   = m_MgOp.Mapping.LocalLength;
                    int jMax = m_MgOp.Mapping.AggGrid.iLogicalCells.NoOfCells - 1;
                    int LE   = m_MgOp.Mapping.LocalUniqueIndex(0, jMax, 0) + m_MgOp.Mapping.GetLength(jMax);


                    foreach (var ci in BlkIdx_lI_eR)
                    {
                        foreach (int idx in ci)
                        {
                            Debug.Assert(idx >= LL);
                            Debug.Assert(idx < LE);
                        }
                    }

                    if (m_MatlabParalellizationCheck)
                    {
                        int globalBlockCounter = 0;
                        for (int rankCounter = 0; rankCounter < myMpisize; rankCounter++)
                        {
                            int rank_NoBlks = NoOfSchwzBlocks.MPIBroadcast(rankCounter);
                            if (rankCounter == myMpiRank)
                            {
                                Debug.Assert(rank_NoBlks == NoOfSchwzBlocks);
                            }

                            for (int iBlock = 0; iBlock < rank_NoBlks; iBlock++)
                            {
                                double[] vec;
                                if (rankCounter == myMpiRank)
                                {
                                    vec = ArrayTools.Cat(BlkIdx_gI_lR[iBlock], BlkIdx_gI_eR[iBlock]).Select(ii => ((double)(ii + 1))).ToArray();
                                }
                                else
                                {
                                    vec = new double[0];
                                }

                                matlab.PutVector(vec, string.Format("BlockIdx{0}", globalBlockCounter));

                                globalBlockCounter++;
                                csMPI.Raw.Barrier(csMPI.Raw._COMM.WORLD);
                            }
                        }
                    }
                }
#endif


                BlockMsrMatrix ExternalRowsTemp;
                if (myMpisize > 1 && Overlap > 0)
                {
                    //int NoOfLocalRows = _ExternalBlockIndices.Sum(L => L.Count);

                    BlockPartitioning PermRow = new BlockPartitioning(ExternalRowsIndices.Count, ExternalRows_BlockI0, ExternalRows_BlockN, Mop.MPI_Comm, i0isLocal: true);

                    // Remark: we use a permutation matrix for MPI-exchange of rows

                    BlockMsrMatrix Perm = new BlockMsrMatrix(PermRow, Mop._RowPartitioning);
                    for (int iRow = 0; iRow < ExternalRowsIndices.Count; iRow++)
                    {
                        Debug.Assert(Mop._RowPartitioning.IsInLocalRange(ExternalRowsIndices[iRow]) == false);
                        Perm[iRow + PermRow.i0, ExternalRowsIndices[iRow]] = 1;
                    }

                    ExternalRowsTemp = BlockMsrMatrix.Multiply(Perm, Mop);

#if DEBUG
                    if (m_MatlabParalellizationCheck)
                    {
                        matlab.PutSparseMatrix(Perm, "Perm");
                        matlab.PutSparseMatrix(ExternalRowsTemp, "ExternalRowsTemp");
                    }
#endif
                }
                else
                {
                    ExternalRowsTemp = null;
                }

                ExternalRowsIndices  = null;
                ExternalRows_BlockI0 = null;
                ExternalRows_BlockN  = null;



                // create solvers
                // ==============


                {
                    blockSolvers = new ISparseSolver[NoOfSchwzBlocks];

#if DEBUG
                    List <BlockMsrMatrix> Blocks = new List <BlockMsrMatrix>();
#endif
                    for (int iPart = 0; iPart < NoOfSchwzBlocks; iPart++)
                    {
                        var bi = BlkIdx_gI_lR[iPart];

                        int Bsz;
                        if (MgMap.MinimalLength == MgMap.MaximalLength)
                        {
                            Bsz = MgMap.MaximalLength;
                        }
                        else
                        {
                            Bsz = 1;
                        }

                        var l1 = TempRowIdx_gI[iPart];

                        //if (M.RowPartitioning.MpiSize > 1) {
                        //    int i0Proc = M.RowPartitioning.i0;
                        //    bi = bi.CloneAs();
                        //    for (int i = 0; i < bi.Length; i++) {
                        //        bi[i] += i0Proc;
                        //    }
                        //}

                        BlockPartitioning localBlocking = new BlockPartitioning(bi.Count + l1.Count, LocalBlocks_i0[iPart], LocalBlocks_N[iPart], csMPI.Raw._COMM.SELF);

                        if (l1.Count > 0)
                        {
                            // convert the indices into 'ExternalRowsTemp' to global indices
                            int l1L    = l1.Count;
                            int offset = ExternalRowsTemp._RowPartitioning.i0;
                            for (int i = 0; i < l1L; i++)
                            {
                                l1[i] += offset;
                            }
                        }

                        BlockMsrMatrix Block = new BlockMsrMatrix(localBlocking, localBlocking);// bi.Length, bi.Length, Bsz, Bsz);
                        Mop.WriteSubMatrixTo(Block, bi, default(int[]), bi, default(int[]));
                        if (l1.Count > 0)
                        {
                            int   offset   = bi.Count;
                            int[] targRows = l1.Count.ForLoop(i => i + offset);

                            var   biE         = BlkIdx_gI_eR[iPart];
                            int[] extTargCols = biE.Count.ForLoop(i => i + offset);

                            Mop.AccSubMatrixTo(1.0, Block, bi, default(int[]), new int[0], default(int[]), biE, extTargCols);
                            ExternalRowsTemp.AccSubMatrixTo(1.0, Block, l1, targRows, bi, default(int[]), biE, extTargCols);
                        }
#if DEBUG
                        if (m_MatlabParalellizationCheck)
                        {
                            Blocks.Add(Block);
                        }
#endif
                        blockSolvers[iPart] = new PARDISOSolver()
                        {
                            CacheFactorization = true,
                            UseDoublePrecision = false
                        };
                        //blockSolvers[iPart] = new FullDirectSolver();
                        //blockSolvers[iPart] = new ilPSP.LinSolvers.MUMPS.MUMPSSolver();
                        blockSolvers[iPart].DefineMatrix(Block);
                    }

#if DEBUG
                    if (m_MatlabParalellizationCheck)
                    {
                        int globalBlockCounter = 0;
                        for (int rankCounter = 0; rankCounter < myMpisize; rankCounter++)
                        {
                            int rank_NoBlks = NoOfSchwzBlocks.MPIBroadcast(rankCounter);
                            for (int iBlock = 0; iBlock < rank_NoBlks; iBlock++)
                            {
                                BlockMsrMatrix Block;
                                if (rankCounter == myMpiRank)
                                {
                                    Block = Blocks[iBlock];
                                }
                                else
                                {
                                    Block = null;
                                }

                                matlab.PutSparseMatrix(Block, string.Format("Block{0}", globalBlockCounter));

                                globalBlockCounter++;
                                csMPI.Raw.Barrier(csMPI.Raw._COMM.WORLD);
                            }
                        }
                    }
#endif
                }

                // Record required indices
                // =======================
                {
                    this.BlockIndices_Local    = new int[NoOfSchwzBlocks][];
                    this.BlockIndices_External = new int[NoOfSchwzBlocks][];
                    int LocalI0     = MgMap.i0;
                    int LocalLength = MgMap.LocalLength;

                    for (int iBlock = 0; iBlock < NoOfSchwzBlocks; iBlock++)
                    {
                        var   _bi = BlkIdx_gI_lR[iBlock];
                        int   L   = _bi.Count;
                        int[] bil = new int[L];
                        this.BlockIndices_Local[iBlock] = bil;

                        for (int l = 0; l < L; l++)
                        {
                            bil[l] = _bi[l] - LocalI0;
                            Debug.Assert(bil[l] >= 0);
                            Debug.Assert(bil[l] < MgMap.LocalLength);
                        }

                        var _biE = BlkIdx_lI_eR[iBlock];
                        if (_biE.Count > 0)
                        {
                            this.BlockIndices_External[iBlock] = _biE.ToArray();
                        }
                    }
                }


                this.MtxFull = Mop;

                if (CoarseSolver != null)
                {
                    CoarseSolver.Init(op.CoarserLevel);
                }

                // Debug & Test-Code
                // =================
#if DEBUG
                if (m_MatlabParalellizationCheck)
                {
                    Console.WriteLine("Matlab dir: " + matlab.WorkingDirectory);

                    matlab.PutSparseMatrix(Mop, "Full");
                    int GlobalNoOfBlocks = NoOfSchwzBlocks.MPISum();



                    for (int iGlbBlock = 0; iGlbBlock < GlobalNoOfBlocks; iGlbBlock++)
                    {
                        matlab.Cmd("BlockErr({0} + 1, 1) = norm( Block{0} - Full( BlockIdx{0}, BlockIdx{0} ), inf );", iGlbBlock);
                    }

                    Random   rnd     = new Random(myMpiRank);
                    double[] testRHS = new double[MgMap.LocalLength];
                    for (int i = 0; i < testRHS.Length; i++)
                    {
                        testRHS[i] = rnd.NextDouble();
                    }
                    matlab.PutVector(testRHS, "testRHS");

                    MPIexchange <double[]> ResExchange = new MPIexchange <double[]>(MgMap, testRHS);
                    ResExchange.TransceiveStartImReturn();
                    ResExchange.TransceiveFinish(0.0);

                    int offset = MgMap.LocalLength;

                    int g = 0;
                    for (int rankCounter = 0; rankCounter < myMpisize; rankCounter++)
                    {
                        int rank_NoBlks = NoOfSchwzBlocks.MPIBroadcast(rankCounter);
                        for (int iBlock = 0; iBlock < rank_NoBlks; iBlock++)
                        {
                            double[] SubVec;
                            if (rankCounter == myMpiRank)
                            {
                                int LL = this.BlockIndices_Local[iBlock].Length;
                                int LE;
                                if (this.BlockIndices_External[iBlock] != null)
                                {
                                    LE = this.BlockIndices_External[iBlock].Length;
                                }
                                else
                                {
                                    LE = 0;
                                }
                                int L = LL + LE;

                                SubVec = new double[L];
                                for (int i = 0; i < LL; i++)
                                {
                                    SubVec[i] = testRHS[this.BlockIndices_Local[iBlock][i]];
                                }
                                if (LE > 0)
                                {
                                    for (int i = 0; i < LE; i++)
                                    {
                                        SubVec[i + LL] = ResExchange.Vector_Ext[this.BlockIndices_External[iBlock][i] - offset];
                                    }
                                }
                            }
                            else
                            {
                                SubVec = new double[0];
                            }

                            matlab.PutVector(SubVec, "SubVec" + g);

                            g++;
                        }
                    }

                    for (int iGlbBlock = 0; iGlbBlock < GlobalNoOfBlocks; iGlbBlock++)
                    {
                        matlab.Cmd("RhsErr({0} + 1, 1) = norm( SubVec{0} - testRHS( BlockIdx{0} ), inf );", iGlbBlock);
                    }

                    double[] testX = new double[testRHS.Length];
                    MPIexchangeInverse <double[]> XExchange = new MPIexchangeInverse <double[]>(MgMap, testX);

                    g = 0;
                    for (int rankCounter = 0; rankCounter < myMpisize; rankCounter++)
                    {
                        int rank_NoBlks = NoOfSchwzBlocks.MPIBroadcast(rankCounter);
                        for (int iBlock = 0; iBlock < rank_NoBlks; iBlock++)
                        {
                            if (rankCounter == myMpiRank)
                            {
                                int LL = this.BlockIndices_Local[iBlock].Length;
                                int LE;
                                if (this.BlockIndices_External[iBlock] != null)
                                {
                                    LE = this.BlockIndices_External[iBlock].Length;
                                }
                                else
                                {
                                    LE = 0;
                                }
                                int L = LL + LE;


                                for (int i = 0; i < LL; i++)
                                {
                                    testX[this.BlockIndices_Local[iBlock][i]] += (g + 1);
                                }
                                if (LE > 0)
                                {
                                    for (int i = 0; i < LE; i++)
                                    {
                                        XExchange.Vector_Ext[this.BlockIndices_External[iBlock][i] - offset] += (g + 1);
                                    }
                                }
                            }
                            else
                            {
                                //nop
                            }

                            g++;
                        }
                    }
                    XExchange.TransceiveStartImReturn();
                    XExchange.TransceiveFinish(1.0);

                    matlab.Cmd("testXref = zeros({0},1);", MgMap.TotalLength);
                    for (int iGlbBlock = 0; iGlbBlock < GlobalNoOfBlocks; iGlbBlock++)
                    {
                        matlab.Cmd("testXref(BlockIdx{0},1) = testXref(BlockIdx{0},1) + ({0} + 1);", iGlbBlock);
                    }

                    matlab.PutVector(testX, "testX");
                    matlab.Cmd("testXErr = norm(testX - testXref, inf);");

                    MultidimensionalArray BlockErr = MultidimensionalArray.Create(GlobalNoOfBlocks, 1);
                    MultidimensionalArray RhsErr   = MultidimensionalArray.Create(GlobalNoOfBlocks, 1);
                    MultidimensionalArray testXErr = MultidimensionalArray.Create(1, 1);

                    matlab.GetMatrix(BlockErr, "BlockErr");
                    matlab.GetMatrix(RhsErr, "RhsErr");
                    matlab.GetMatrix(testXErr, "testXErr");

                    matlab.Execute();

                    for (int iGlbBlock = 0; iGlbBlock < GlobalNoOfBlocks; iGlbBlock++)
                    {
                        Console.WriteLine("Block #{0} Error (external? ) " + BlockErr[iGlbBlock, 0], iGlbBlock);
                        Console.WriteLine("RHS #{0} Error " + RhsErr[iGlbBlock, 0], iGlbBlock);
                        Debug.Assert(BlockErr[iGlbBlock, 0] == 0);
                        Debug.Assert(RhsErr[iGlbBlock, 0] == 0);
                    }

                    Console.WriteLine("X Error " + testXErr[0, 0]);
                    Debug.Assert(testXErr[0, 0] == 0.0);

                    matlab.Dispose();
                }
#endif
            }
        }
Exemplo n.º 11
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;
            }
        }
Exemplo n.º 12
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;
            }
        }
Exemplo n.º 13
0
        public void ComputeOperatorMatrix(BlockMsrMatrix OpMtx, double[] OpAffine, UnsetteledCoordinateMapping Mapping, DGField[] __CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time)
        {
            // compute operator
            Debug.Assert(OpAffine.L2Norm() == 0.0);

            // all kinds of checks
            if (!this.CurrentState.EqualsPartition(Mapping))
            {
                throw new ApplicationException("something is weired");
            }
            if (OpMtx != null)
            {
                if (!OpMtx.RowPartitioning.EqualsPartition(Mapping))
                {
                    throw new ArgumentException("Codomain/Matrix Row mapping mismatch.");
                }
                if (!OpMtx.ColPartition.EqualsPartition(Mapping))
                {
                    throw new ArgumentException("Domain/Matrix column mapping mismatch.");
                }
            }


            if (XdgOperator != null)
            {
                if (OpMtx != null)
                {
                    // +++++++++++++++++++++++++++++
                    // Solver requires linearization
                    // +++++++++++++++++++++++++++++

                    Debug.Assert(OpMtx.InfNorm() == 0.0);
                    switch (XdgOperator.LinearizationHint)
                    {
                    case LinearizationHint.AdHoc: {
                        this.XdgOperator.InvokeParameterUpdate(__CurrentState, this.Parameters.ToArray());

                        var mtxBuilder = XdgOperator.GetMatrixBuilder(LsTrk, Mapping, this.Parameters, Mapping);
                        mtxBuilder.time           = time;
                        mtxBuilder.MPITtransceive = true;
                        mtxBuilder.ComputeMatrix(OpMtx, OpAffine);
                        return;
                    }

                    case LinearizationHint.FDJacobi: {
                        var mtxBuilder = XdgOperator.GetFDJacobianBuilder(LsTrk, __CurrentState, this.Parameters, Mapping);
                        mtxBuilder.time           = time;
                        mtxBuilder.MPITtransceive = true;
                        mtxBuilder.ComputeMatrix(OpMtx, OpAffine);
                        return;
                    }

                    case LinearizationHint.GetJacobiOperator: {
                        var op = GetJacobiXdgOperator();

                        if (JacobiParameterVars == null)
                        {
                            JacobiParameterVars = op.InvokeParameterFactory(this.CurrentState);
                        }

                        op.InvokeParameterUpdate(__CurrentState, JacobiParameterVars);

                        var mtxBuilder = op.GetMatrixBuilder(LsTrk, Mapping, this.JacobiParameterVars, Mapping);
                        mtxBuilder.time           = time;
                        mtxBuilder.MPITtransceive = true;
                        mtxBuilder.ComputeMatrix(OpMtx, OpAffine);
                        return;
                    }
                    }
                }
                else
                {
                    // ++++++++++++++++++++++++
                    // only operator evaluation
                    // ++++++++++++++++++++++++

                    this.XdgOperator.InvokeParameterUpdate(__CurrentState, this.Parameters.ToArray());

                    var eval = XdgOperator.GetEvaluatorEx(__CurrentState, this.Parameters, Mapping);
                    eval.time           = time;
                    eval.MPITtransceive = true;
                    eval.Evaluate(1.0, 0.0, OpAffine);
                }
            }
            else if (DgOperator != null)
            {
                if (OpMtx != null)
                {
                    // +++++++++++++++++++++++++++++
                    // Solver requires linearization
                    // +++++++++++++++++++++++++++++

                    Debug.Assert(OpMtx.InfNorm() == 0.0);
                    switch (DgOperator.LinearizationHint)
                    {
                    case LinearizationHint.AdHoc: {
                        this.DgOperator.InvokeParameterUpdate(__CurrentState, this.Parameters.ToArray());

                        var mtxBuilder = DgOperator.GetMatrixBuilder(Mapping, this.Parameters, Mapping);
                        mtxBuilder.time           = time;
                        mtxBuilder.MPITtransceive = true;
                        mtxBuilder.ComputeMatrix(OpMtx, OpAffine);
                        return;
                    }

                    case LinearizationHint.FDJacobi: {
                        var mtxBuilder = DgOperator.GetFDJacobianBuilder(__CurrentState, this.Parameters, Mapping);
                        mtxBuilder.time           = time;
                        mtxBuilder.MPITtransceive = true;
                        mtxBuilder.ComputeMatrix(OpMtx, OpAffine);
                        return;
                    }

                    case LinearizationHint.GetJacobiOperator: {
                        var op = GetJacobiDgOperator();

                        if (JacobiParameterVars == null)
                        {
                            JacobiParameterVars = op.InvokeParameterFactory(__CurrentState);
                        }
                        op.InvokeParameterUpdate(__CurrentState, JacobiParameterVars);

                        var mtxBuilder = op.GetMatrixBuilder(Mapping, this.JacobiParameterVars, Mapping);
                        mtxBuilder.time           = time;
                        mtxBuilder.MPITtransceive = true;
                        mtxBuilder.ComputeMatrix(OpMtx, OpAffine);
                        return;
                    }
                    }
                }
                else
                {
                    // ++++++++++++++++++++++++
                    // only operator evaluation
                    // ++++++++++++++++++++++++

                    this.DgOperator.InvokeParameterUpdate(__CurrentState, this.Parameters.ToArray());

                    var eval = DgOperator.GetEvaluatorEx(__CurrentState, this.Parameters, Mapping);
                    eval.time           = time;
                    eval.MPITtransceive = true;
                    eval.Evaluate(1.0, 0.0, OpAffine);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Exemplo n.º 14
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            LsUpdate(phystime);

            // operator-matrix assemblieren
            OperatorMatrix    = new BlockMsrMatrix(MG_Mapping.ProblemMapping);
            AltOperatorMatrix = new MsrMatrix(MG_Mapping.ProblemMapping);
            double[] Affine = new double[OperatorMatrix.RowPartitioning.LocalLength];
            MultiphaseCellAgglomerator Agg;

            Agg = LsTrk.GetAgglomerator(this.LsTrk.SpeciesIdS.ToArray(), m_quadOrder, __AgglomerationTreshold: this.THRESHOLD);

            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, MG_Mapping.ProblemMapping, null, MG_Mapping.ProblemMapping);
            mtxBuilder.time = 0.0;
            mtxBuilder.ComputeMatrix(OperatorMatrix, Affine);
            Agg.ManipulateMatrixAndRHS(OperatorMatrix, Affine, MG_Mapping.ProblemMapping, MG_Mapping.ProblemMapping);

            foreach (var S in this.LsTrk.SpeciesNames)
            {
                Console.WriteLine("  Species {0}: no of agglomerated cells: {1}",
                                  S, Agg.GetAgglomerator(this.LsTrk.GetSpeciesId(S)).AggInfo.SourceCells.NoOfItemsLocally);
            }


            MGOp = new MultigridOperator(XAggB, map,
                                         OperatorMatrix,
                                         this.massFact.GetMassMatrix(map, false),
                                         OpConfig, null);
            Debug.Assert(MGOp.OperatorMatrix != null);
            Debug.Assert(MGOp.Mapping != null);

            someVec = GetRHS(Affine, OperatorMatrix);

            mtxBuilder.ComputeMatrix(AltOperatorMatrix, Affine);
            Agg.ManipulateMatrixAndRHS(AltOperatorMatrix, Affine, MG_Mapping.ProblemMapping, MG_Mapping.ProblemMapping);


            //LsTrk.GetSpeciesName(((XdgAggregationBasis)MGOp.Mapping.AggBasis[0]).UsedSpecies[1]);
            //LsTrk.GetSpeciesName(((XdgAggregationBasis)MGOp.Mapping.AggBasis[0]).UsedSpecies[0]);

            int nnz = this.OperatorMatrix.GetTotalNoOfNonZeros();

            Console.WriteLine("Number of non-zeros in matrix: " + nnz);

            int nnz2 = this.AltOperatorMatrix.GetTotalNoOfNonZeros();

            Assert.IsTrue(nnz == nnz2, "Number of non-zeros in matrix different for " + OperatorMatrix.GetType() + " and " + AltOperatorMatrix.GetType());
            Console.WriteLine("Number of non-zeros in matrix (reference): " + nnz2);

            MsrMatrix Comp = AltOperatorMatrix.CloneAs();

            Comp.Acc(-1.0, OperatorMatrix);
            double CompErr    = Comp.InfNorm();
            double Denom      = Math.Max(AltOperatorMatrix.InfNorm(), OperatorMatrix.InfNorm());
            double CompErrRel = Denom > Math.Sqrt(double.Epsilon) ? CompErr / Denom : CompErr;

            Console.WriteLine("Comparison: " + CompErrRel);

            Assert.LessOrEqual(CompErrRel, 1.0e-7, "Huge difference between MsrMatrix and BlockMsrMatrix.");

            base.TerminationKey = true;
            return(0.0);
        }
Exemplo n.º 15
0
        /// <summary>
        /// %
        /// </summary>
        public void Solve <U, V>(U X, V B)
            where U : IList <double>
            where V : IList <double> //
        {
            using (var tr = new FuncTrace()) {
                double[] Residual = this.TestSolution ? B.ToArray() : null;

                string SolverName = "NotSet";
                using (var solver = GetSolver(m_Mtx)) {
                    SolverName = solver.GetType().FullName;
                    //Console.Write("Direct solver run {0}, using {1} ... ", IterCnt, solver.GetType().Name);
                    IterCnt++;
                    solver.Solve(X, B);
                    //Console.WriteLine("done.");
                }


                m_ThisLevelIterations++;

                if (Residual != null)
                {
                    //Console.Write("Checking residual (run {0}) ... ", IterCnt - 1);
                    double RhsNorm       = Residual.L2NormPow2().MPISum().Sqrt();
                    double MatrixInfNorm = m_Mtx.InfNorm();
                    m_Mtx.SpMV(-1.0, X, 1.0, Residual);

                    double ResidualNorm    = Residual.L2NormPow2().MPISum().Sqrt();
                    double SolutionNorm    = X.L2NormPow2().MPISum().Sqrt();
                    double Denom           = Math.Max(MatrixInfNorm, Math.Max(RhsNorm, Math.Max(SolutionNorm, Math.Sqrt(double.Epsilon))));
                    double RelResidualNorm = ResidualNorm / Denom;

                    //Console.WriteLine("done: Abs.: {0}, Rel.: {1}", ResidualNorm, RelResidualNorm);

                    if (RelResidualNorm > 1.0e-10)
                    {
                        //Console.WriteLine("High residual from direct solver: abs {0}, rel {1}", ResidualNorm , ResidualNorm / SolutionNorm);

                        m_Mtx.SaveToTextFileSparse("Mtx.txt");
                        X.SaveToTextFile("X.txt");
                        B.SaveToTextFile("B.txt");

                        string ErrMsg;
                        using (var stw = new StringWriter()) {
                            stw.WriteLine("High residual from direct solver (using {0}).", SolverName);
                            stw.WriteLine("    L2 Norm of RHS:         " + RhsNorm);
                            stw.WriteLine("    L2 Norm of Solution:    " + SolutionNorm);
                            stw.WriteLine("    L2 Norm of Residual:    " + ResidualNorm);
                            stw.WriteLine("    Relative Residual norm: " + RelResidualNorm);
                            stw.WriteLine("    Matrix Inf norm:        " + MatrixInfNorm);
                            stw.WriteLine("Dumping text versions of Matrix, Solution and RHS.");
                            ErrMsg = stw.ToString();
                        }
                        Console.WriteLine(ErrMsg);
                    }
                }

                if (this.IterationCallback != null)
                {
                    double[] _xl = X.ToArray();
                    double[] _bl = B.ToArray();
                    m_Mtx.SpMV(-1.0, _xl, 1.0, _bl);
                    this.IterationCallback(1, _xl, _bl, this.m_MultigridOp);
                }
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Includes assembly of the matrix.
        /// </summary>
        /// <param name="L"></param>
        protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L)
        {
            using (FuncTrace tr = new FuncTrace()) {
                // create operator
                // ===============
                SpatialOperator LapaceIp;
                {
                    double D              = this.GridData.SpatialDimension;
                    double penalty_base   = (T.Basis.Degree + 1) * (T.Basis.Degree + D) / D;
                    double penalty_factor = base.Control.penalty_poisson;

                    BoundaryCondMap <BoundaryType> PoissonBcMap = new BoundaryCondMap <BoundaryType>(this.GridData, this.Control.BoundaryValues, "T");

                    LapaceIp = new SpatialOperator(1, 1, QuadOrderFunc.SumOfMaxDegrees(), "T", "T");
                    var flux = new ipFlux(penalty_base * base.Control.penalty_poisson, this.GridData.Cells.cj, PoissonBcMap);
                    LapaceIp.EquationComponents["T"].Add(flux);

                    LapaceIp.Commit();
                }

                // Create Matrices
                // ===============

                {
                    // time measurement for matrix assembly
                    Stopwatch stw = new Stopwatch();
                    stw.Start();

                    // console
                    Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal);

                    // quadrature domain
                    var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData));
                    var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData));

#if DEBUG
                    // in DEBUG mode, we compare 'MsrMatrix' (old, reference implementation) and 'BlockMsrMatrix' (new standard)
                    var RefLaplaceMtx = new MsrMatrix(T.Mapping);
#endif
                    using (new BlockTrace("SipMatrixAssembly", tr)) {
                        LaplaceMtx    = new BlockMsrMatrix(T.Mapping);
                        LaplaceAffine = new double[T.Mapping.LocalLength];

                        LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping,
                                                 LaplaceMtx, LaplaceAffine,
                                                 volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);
                    }
#if DEBUG
                    LaplaceAffine.ClearEntries();
                    LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping,
                                             RefLaplaceMtx, LaplaceAffine,
                                             volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);
                    MsrMatrix ErrMtx = RefLaplaceMtx.CloneAs();
                    ErrMtx.Acc(-1.0, LaplaceMtx);
                    double err    = ErrMtx.InfNorm();
                    double infNrm = LaplaceMtx.InfNorm();
                    Console.WriteLine("Matrix comparison error: " + err + ", matrix norm is: " + infNrm);
                    Assert.Less(err, infNrm * 1e-10, "MsrMatrix2 comparison failed.");
#endif
                    stw.Stop();
                    Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds);
                }


                //double condNo = LaplaceMtx.condest(BatchmodeConnector.Flavor.Octave);
                //Console.WriteLine("condition number: {0:0.####E-00} ",condNo);
            }
        }