示例#1
0
        /// <summary>
        /// Constructor for XDG solvers
        /// </summary>
        public OpAnalysisBase(LevelSetTracker LsTrk, BlockMsrMatrix Mtx, double[] RHS, UnsetteledCoordinateMapping Mapping, MultiphaseCellAgglomerator CurrentAgglomeration, BlockMsrMatrix _mass, IEnumerable <MultigridOperator.ChangeOfBasisConfig[]> OpConfig, ISpatialOperator abstractOperator)
        {
            int RHSlen = Mapping.TotalLength;

            m_map    = Mapping;                              // mapping
            VarGroup = Mapping.BasisS.Count.ForLoop(i => i); //default: all dependent variables are included in operator matrix

            m_LsTrk = LsTrk;

            m_OpMtx  = Mtx.CloneAs();
            localRHS = RHS.CloneAs();

            // create the Dummy XDG aggregation basis
            var baseGrid = Mapping.GridDat;
            var mgSeq    = Foundation.Grid.Aggregation.CoarseningAlgorithms.CreateSequence(baseGrid, 1);

            AggregationGridBasis[][] XAggB = AggregationGridBasis.CreateSequence(mgSeq, Mapping.BasisS);

            //
            XAggB.UpdateXdgAggregationBasis(CurrentAgglomeration);

            // create multigrid operator
            m_MultigridOp = new MultigridOperator(XAggB, Mapping,
                                                  m_OpMtx,
                                                  _mass,
                                                  OpConfig,
                                                  abstractOperator.DomainVar.Select(varName => abstractOperator.FreeMeanValue[varName]).ToArray());
        }
示例#2
0
        public static void MapConsistencyTest(
            [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg,
            [Values(2)] int DGOrder
            )
        {
            //if no selection is chosen mapping should be the same as of origin
            //assume: indexing is right 'cause of other tests
            Utils.TestInit((int)UseXdg, DGOrder);
            Console.WriteLine("MapConsistencyTest({0},{1})", UseXdg, DGOrder);

            //Arrange
            MultigridOperator MGOp = Utils.CreateTestMGOperator(UseXdg, DGOrder);
            var sbs  = new SubBlockSelector(MGOp.Mapping);
            var mask = new BlockMask(sbs);
            var stw  = new Stopwatch();

            stw.Restart();

            //Act --- Create Mapping from mask
            stw.Start();
            var submatrix = mask.GetSubBlockMatrix(MGOp.OperatorMatrix);

            stw.Stop();
            var rowpart = submatrix._RowPartitioning;
            var colpart = submatrix._ColPartitioning;

            //Assert --- Equal Partition of mask and origin
            Assert.AreEqual(rowpart, colpart);
            Assert.IsTrue(rowpart.IsLocallyEqual(MGOp.Mapping));
        }
示例#3
0
        private static void MgConsistencyTestRec(MultigridOperator mgOp, double[] mgSolVec, double[] mgRhsVec)
        {
            double[] mgResidual = mgRhsVec.CloneAs();
            mgOp.OperatorMatrix.SpMV(1.0, mgSolVec, -1.0, mgResidual);
            double scale = 1.0 / (mgRhsVec.L2Norm() + mgSolVec.L2Norm());

            int DOFs = mgOp.Mapping.TotalLength;

            Debug.Assert(DOFs == mgOp.OperatorMatrix.NoOfRows);
            Debug.Assert(DOFs == mgOp.OperatorMatrix.NoOfCols);


            double mgResidual_l2Norm = mgResidual.L2Norm();

            Console.WriteLine("Multigrid Residual norm, level {0}: {1} ({2} DOFs)", mgOp.LevelIndex, mgResidual_l2Norm, DOFs);
            Assert.LessOrEqual(scale * mgResidual_l2Norm, 1.0e-8);

            if (mgOp.CoarserLevel != null)
            {
                double[] mgCoarseSolVec = new double[mgOp.CoarserLevel.Mapping.LocalLength];
                double[] mgCoarseRhsVec = new double[mgOp.CoarserLevel.Mapping.LocalLength];

                mgOp.CoarserLevel.Restrict(mgSolVec, mgCoarseSolVec);
                mgOp.CoarserLevel.Restrict(mgRhsVec, mgCoarseRhsVec);

                MgConsistencyTestRec(mgOp.CoarserLevel, mgCoarseSolVec, mgCoarseRhsVec);
            }
        }
示例#4
0
        /// <summary>
        /// Restricts some solution vector down to a certain multigrid level and prolongates it back.
        /// </summary>
        /// <param name="i">
        /// Multigrid level index; usually 0 at start of recursion.
        /// </param>
        /// <param name="iEnd">
        /// End level index.
        /// </param>
        /// <param name="mgOp"></param>
        /// <param name="FineIn">
        /// Input; solution vector which will be restricted down to level <paramref name="iEnd"/>.
        /// </param>
        /// <param name="FineOut">
        /// Output; vector <paramref name="FineIn"/> restricted to level <paramref name="iEnd"/>, and prolongated back to level <paramref name="i"/>.
        /// </param>
        static void XDG_Recursive(int i, int iEnd, MultigridOperator mgOp, double[] FineIn, double[] FineOut)
        {
            MultigridMapping mgMap = mgOp.Mapping;

            int Lfin = mgMap.LocalLength;
            int Lcrs = mgOp.CoarserLevel.Mapping.LocalLength;

            Assert.IsTrue(FineIn.Length == Lfin);
            Assert.IsTrue(FineOut.Length == Lfin);

            double[] Coarse1 = new double[Lcrs];
            double[] Coarse2 = new double[Lcrs];

            mgOp.CoarserLevel.Restrict(FineIn, Coarse1);

            if (i == iEnd)
            {
                Coarse2.SetV(Coarse1);
            }
            else
            {
                XDG_Recursive(i + 1, iEnd, mgOp.CoarserLevel, Coarse1, Coarse2);
            }

            mgOp.CoarserLevel.Prolongate(1.0, FineOut, 0.0, Coarse2);
        }
示例#5
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);
        }
示例#6
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);
        }
示例#7
0
 private static List <ChangeOfBasisConfig[]> MgDescend(MultigridOperator mgo, List <ChangeOfBasisConfig[]> cobc)
 {
     cobc.Add(mgo.Config);
     if (mgo.CoarserLevel != null)
     {
         return(MgDescend(mgo.CoarserLevel, cobc));
     }
     else
     {
         return(cobc);
     }
 }
        public void Init(MultigridOperator op)
        {
            this.m_MgOp = op;
            int D = this.LsTrk.GridDat.SpatialDimension;

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

            this.USubMatrixIdx_Row = this.m_MgOp.Mapping.GetSubvectorIndices(VelVarIdx);
            this.PSubMatrixIdx_Row = this.m_MgOp.Mapping.GetSubvectorIndices(new int[] { D });

            this.ExtractMatrices();
        }
示例#9
0
 private static List <AggregationGridBasis[]> MgDescend(MultigridOperator mgo, List <AggregationGridBasis[]> agggb)
 {
     agggb.Add(mgo.Mapping.AggBasis);
     if (mgo.CoarserLevel != null)
     {
         return(MgDescend(mgo.CoarserLevel, agggb));
     }
     else
     {
         return(agggb);
     }
 }
示例#10
0
        public static void VectorSplitOperation(
            [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg,
            [Values(2)] int DGOrder,
            [Values(MatrixShape.full_var_spec, MatrixShape.full_spec, MatrixShape.full)] MatrixShape MShape,
            [Values(4)] int Res)
        {
            Utils.TestInit((int)UseXdg, DGOrder, (int)MShape, Res);
            Console.WriteLine("VectorSplitOperation({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;
            BlockMsrMatrix    M_ext = BlockMask.GetAllExternalRows(map, M);

            double[] Vec = Utils.GetRandomVector(M_ext.RowPartitioning.LocalLength);

            //Arrange --- setup masking
            SubBlockSelector sbsA = new SubBlockSelector(map);

            sbsA.SetDefaultSplitSelection(MShape, true, false);
            BlockMask maskA = new BlockMask(sbsA, M_ext);

            SubBlockSelector sbsB = new SubBlockSelector(map);

            sbsB.SetDefaultSplitSelection(MShape, false, false);
            BlockMask maskB = new BlockMask(sbsB, M_ext);

            double[] VecAB = new double[Vec.Length];

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

            stw.Reset();

            //Act ---
            stw.Start();
            var VecA = maskA.GetSubVec(Vec, new double[0]);
            var VecB = maskB.GetSubVec(Vec, new double[0]);

            maskA.AccSubVec(VecA, VecAB, new double[0]);
            maskB.AccSubVec(VecB, VecAB, new double[0]);
            stw.Stop();

            Debug.Assert(Vec.L2Norm() != 0);
            double fac = ((MShape == MatrixShape.full_var || MShape == MatrixShape.diagonal_var) && UseXdg == XDGusage.none) ? -2.0 : -1.0;

            VecAB.AccV(fac, Vec);

            //Assert --- are extracted blocks and
            Assert.IsTrue(VecAB.L2Norm() == 0.0, String.Format("L2Norm neq 0!"));
        }
示例#11
0
        private ConvergenceObserver ActivateCObserver(MultigridOperator mop, BlockMsrMatrix Massmatrix, SolverFactory SF, List <Action <int, double[], double[], MultigridOperator> > Callback)
        {
            Console.WriteLine("===Convergence Observer activated===");
            //string AnalyseOutputpath = String.Join(@"\",this.Control.DbPath, this.CurrentSessionInfo.ID);
            string AnalyseOutputpath = System.IO.Directory.GetCurrentDirectory();
            var    CO = new ConvergenceObserver(mop, Massmatrix, uEx.CoordinateVector.ToArray(), SF);

            //CO.TecplotOut = String.Concat(AnalyseOutputpath, @"\Xdg_conv");
            Callback.Add(CO.IterationCallback);
            Console.WriteLine("Analysis output will be written to: {0}", AnalyseOutputpath);
            Console.WriteLine("====================");
            return(CO);
        }
示例#12
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);
        }
示例#13
0
        public static void SubMatrixExtractionWithCoupling(
            [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg,
            [Values(2)] int DGOrder,
            [Values(MatrixShape.diagonal, MatrixShape.diagonal_var, MatrixShape.full_spec, MatrixShape.full_var_spec)] MatrixShape MShape
            )
        {
            Utils.TestInit((int)UseXdg, DGOrder, (int)MShape);
            Console.WriteLine("ExtractSubMatrixAndIgnoreCoupling({0},{1},{2})", UseXdg, DGOrder, MShape);

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

            //Arrange --- setup masking
            SubBlockSelector SBS  = new SubBlockSelector(map);
            BlockMask        mask = new BlockMask(SBS, null);

            bool[] coup = Utils.SetCoupling(MShape);

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

            stw.Reset();

            //Act --- establish submatrix
            stw.Start();
            //var Ones = M.CloneAs();
            //Ones.Clear();
            //Ones.SetAll(1);
            //var extractOnes = mask.GetSubBlockMatrix(Ones, false, coup[0], coup[1]);
            var Mext = mask.GetSubBlockMatrix(M, false, coup[0], coup[1]);

            stw.Stop();
            var Mquad = M.ConvertToQuadraticBMsr(mask.GlobalIList_Internal.ToArray(), true);

            Mext.Acc(-1.0, Mquad);

            //Assert --- Mext conains only diagonal blocks of M
            Assert.IsTrue(Mext.InfNorm() == 0);
        }
示例#14
0
文件: SIMPLE.cs 项目: xyuan/BoSSS
        public void Init(MultigridOperator op)
        {
            this.m_MgOp = op;
            int D = this.LsTrk.GridDat.SpatialDimension;

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

            this.USubMatrixIdx_Row = this.m_MgOp.Mapping.GetSubvectorIndices(VelVarIdx);
            this.PSubMatrixIdx_Row = this.m_MgOp.Mapping.GetSubvectorIndices(new int[] { D });

            this.USpcSubMatrix_Row = new int[this.LsTrk.SpeciesIdS.Count][];
            this.PSpcSubMatrix_Row = new int[this.LsTrk.SpeciesIdS.Count][];
            for (int iSpc = 0; iSpc < this.LsTrk.SpeciesIdS.Count; iSpc++)
            {
                this.USpcSubMatrix_Row[iSpc] = this.m_MgOp.Mapping.GetSubvectorIndices(this.LsTrk.SpeciesIdS[iSpc], VelVarIdx);
                this.PSpcSubMatrix_Row[iSpc] = this.m_MgOp.Mapping.GetSubvectorIndices(this.LsTrk.SpeciesIdS[iSpc], D);
            }

            this.ExtractMatrices();
            this.ApproximationMatrix();
        }
示例#15
0
        public static void ExternalIndexTest(
            [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg,
            [Values(2)] int DGOrder,
            [Values(4)] int Res
            )
        {
            Utils.TestInit((int)UseXdg, DGOrder);
            Console.WriteLine("ExternalIndexTest({0},{1})", UseXdg, DGOrder);

            //Arrange --- Get global index by mapping
            MultigridOperator MGOp = Utils.CreateTestMGOperator(UseXdg, DGOrder, MatrixShape.laplace, Res);
            var map = MGOp.Mapping;

            int[] GlobalIdxMap_ext = Utils.GetAllExtCellIdc(map);

            //Arrange --- Prepare stuff for mask
            var selector = new SubBlockSelector(map);
            var dummy    = new BlockMsrMatrix(map); // we are only interested in getting indices, so a dummy is sufficient
            var stw      = new Stopwatch();

            stw.Reset();

            //Act --- do the masking to get index lists
            stw.Start();
            var mask = new BlockMask(selector, dummy);

            stw.Stop();
            int[] GlobalIdxMask_ext = mask.GlobalIList_External.ToArray();

            //Assert --- Idx lists are of same length
            Assert.IsTrue(GlobalIdxMap_ext.Length == GlobalIdxMask_ext.Length);

            //Assert --- Compare map and mask indices
            for (int iLoc = 0; iLoc < GlobalIdxMask_ext.Length; iLoc++)
            {
                Assert.IsTrue(GlobalIdxMask_ext[iLoc] == GlobalIdxMap_ext[iLoc]);
            }
        }
示例#16
0
        public static BlockMsrMatrix GetCellCompMatrix(SelectionType SType, MultigridOperator mop, int iB)
        {
            int rank   = mop.Mapping.MpiRank;
            int iBlock = mop.Mapping.AggGrid.CellPartitioning.i0 + iB;
            int i0     = mop.Mapping.GetBlockI0(iBlock);

            //int jBlock = i0 + jB;
            int R = mop.Mapping.GetBlockLen(iBlock);
            //int C = mop.Mapping.GetBlockLen(jBlock);

            bool ZwoSpecR = Math.Max(mop.Mapping.GetSubblkLen(0)[0], mop.Mapping.GetSubblkLen(1)[0]) == R;
            //bool ZwoSpecC = (mop.Mapping.AggBasis[0].GetMaximalLength(DGdegree) + mop.Mapping.AggBasis[0].GetMaximalLength(DGdegree - 1)) == C;

            SpeciesId A       = ((XdgAggregationBasis)mop.Mapping.AggBasis[0]).UsedSpecies[0];
            int       Specpos = ((XdgAggregationBasis)mop.Mapping.AggBasis[0]).GetSpeciesIndex(iB, A);

            int[] SubIdcR = GetSubIndices(SType, ZwoSpecR, Specpos);
            //int[] SubIdcC = GetSubIndices(SType, ZwoSpecC);

            for (int i = 0; i < SubIdcR.Length; i++)
            {
                Debug.Assert(SubIdcR[i] < R);
                SubIdcR[i] += i0;
            }
            //for (int i = 0; i < SubIdcC.Length; i++) {
            //    Debug.Assert(SubIdcC[i] < C);
            //    SubIdcC[i] += i0;
            //}
            //return mop.OperatorMatrix.GetSubMatrix(SubIdcR, SubIdcC);
            var part = new BlockPartitioning(SubIdcR.Length, new int[] { 0 }, new int[] { SubIdcR.Length }, csMPI.Raw._COMM.SELF);

            BlockMsrMatrix sub = new BlockMsrMatrix(part);

            mop.OperatorMatrix.WriteSubMatrixTo(sub, SubIdcR, default(int[]), SubIdcR, default(int[]));
            return(sub);

            //return mop.OperatorMatrix.GetSubMatrix(SubIdcR, SubIdcR);
        }
示例#17
0
        public static void LocalIndexTest(
            [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg,
            [Values(2)] int DGOrder)
        {
            Utils.TestInit((int)UseXdg, DGOrder);
            Console.WriteLine("LocalLIndexTest({0},{1})", UseXdg, DGOrder);

            //Arrange --- Get global index by mapping
            MultigridOperator MGOp = Utils.CreateTestMGOperator(UseXdg, DGOrder);
            var map = MGOp.Mapping;

            int[] fields           = map.NoOfVariables.ForLoop(i => i);
            int[] GlobalIdxMap_loc = map.GetSubvectorIndices(fields);

            //Arrange --- Prepare stuff for mask
            var selector = new SubBlockSelector(map);
            var stw      = new Stopwatch();

            stw.Reset();

            //Act --- do the masking to get index lists
            stw.Start();
            var mask = new BlockMask(selector, null);

            stw.Stop();
            int[] GlobalIdxMask_loc = mask.GlobalIList_Internal.ToArray();

            //Assert --- Idx lists are of same length
            Assert.IsTrue(GlobalIdxMap_loc.Length == GlobalIdxMask_loc.Length);

            //Assert --- Compare map and mask indices
            for (int iLoc = 0; iLoc < GlobalIdxMask_loc.Length; iLoc++)
            {
                Assert.True(GlobalIdxMap_loc[iLoc] == GlobalIdxMask_loc[iLoc]);
            }
        }
示例#18
0
            public XDGTestSetup(
                int p,
                double AggregationThreshold,
                int TrackerWidth,
                MultigridOperator.Mode mumo,
                XQuadFactoryHelper.MomentFittingVariants momentFittingVariant,
                ScalarFunction LevSetFunc = null)
            {
                // Level set, tracker and XDG basis
                // ================================

                if (LevSetFunc == null)
                {
                    LevSetFunc = ((_2D)((x, y) => 0.8 * 0.8 - x * x - y * y)).Vectorize();
                }
                LevSet = new LevelSet(new Basis(grid, 2), "LevelSet");
                LevSet.Clear();
                LevSet.ProjectField(LevSetFunc);
                LsTrk = new LevelSetTracker(grid, XQuadFactoryHelper.MomentFittingVariants.Classic, TrackerWidth, new string[] { "A", "B" }, LevSet);
                LsTrk.UpdateTracker();

                XB = new XDGBasis(LsTrk, p);

                XSpatialOperator Dummy = new XSpatialOperator(1, 0, 1, QuadOrderFunc.SumOfMaxDegrees(RoundUp: true), "C1", "u");

                //Dummy.EquationComponents["c1"].Add(new
                Dummy.Commit();

                //Tecplot.PlotFields(new DGField[] { LevSet }, "agglo", 0.0, 3);


                // operator
                // ========

                Debug.Assert(p <= 4);
                XDGBasis opXB = new XDGBasis(LsTrk, 4); // we want to have a very precise quad rule
                var      map  = new UnsetteledCoordinateMapping(opXB);

                int quadOrder = Dummy.QuadOrderFunction(map.BasisS.Select(bs => bs.Degree).ToArray(), new int[0], map.BasisS.Select(bs => bs.Degree).ToArray());

                //agg = new MultiphaseCellAgglomerator(new CutCellMetrics(momentFittingVariant, quadOrder, LsTrk, LsTrk.SpeciesIdS.ToArray()), AggregationThreshold, false);
                agg = LsTrk.GetAgglomerator(LsTrk.SpeciesIdS.ToArray(), quadOrder, __AgglomerationTreshold: AggregationThreshold);


                foreach (var S in LsTrk.SpeciesIdS)
                {
                    Console.WriteLine("Species {0}, no. of agglomerated cells {1} ",
                                      LsTrk.GetSpeciesName(S),
                                      agg.GetAgglomerator(S).AggInfo.SourceCells.Count());
                }

                // mass matrix factory
                // ===================

                // Basis maxB = map.BasisS.ElementAtMax(b => b.Degree);
                //MassFact = new MassMatrixFactory(maxB, agg);
                MassFact = LsTrk.GetXDGSpaceMetrics(LsTrk.SpeciesIdS.ToArray(), quadOrder, 1).MassMatrixFactory;


                // Test field
                // ==========

                // set the test field: this is a polynomial function,
                // but different for each species; On this field, restriction followed by prolongation should be the identity
                this.Xdg_uTest = new XDGField(this.XB, "uTest");
                Dictionary <SpeciesId, double> dumia = new Dictionary <SpeciesId, double>();
                int i = 2;

                foreach (var Spc in LsTrk.SpeciesIdS)
                {
                    dumia.Add(Spc, i);
                    i -= 1;
                }
                SetTestValue(Xdg_uTest, dumia);


                // dummy operator matrix which fits polynomial degree p
                // ====================================================

                Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping);
                Xdg_opMtx.AccEyeSp(120.0);

                // XDG Aggregation BasiseS
                // =======================

                //XAggB = MgSeq.Select(agGrd => new XdgAggregationBasis[] { new XdgAggregationBasis(uTest.Basis, agGrd) }).ToArray();
                XAggB = new XdgAggregationBasis[MgSeq.Length][];
                var _XAggB = AggregationGridBasis.CreateSequence(MgSeq, Xdg_uTest.Mapping.BasisS);

                for (int iLevel = 0; iLevel < XAggB.Length; iLevel++)
                {
                    XAggB[iLevel] = new[] { (XdgAggregationBasis)(_XAggB[iLevel][0]) };
                    XAggB[iLevel][0].Update(agg);
                }

                // Multigrid Operator
                // ==================



                Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping);
                Xdg_opMtx.AccEyeSp(120.0);

                XdgMultigridOp = new MultigridOperator(XAggB, Xdg_uTest.Mapping,
                                                       Xdg_opMtx,
                                                       MassFact.GetMassMatrix(Xdg_uTest.Mapping, false),
                                                       new MultigridOperator.ChangeOfBasisConfig[][] {
                    new MultigridOperator.ChangeOfBasisConfig[] {
                        new MultigridOperator.ChangeOfBasisConfig()
                        {
                            VarIndex = new int[] { 0 }, mode = mumo, Degree = p
                        }
                    }
                });
            }
示例#19
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.");
                    //    }
                    //}
                }
            }
        }
示例#20
0
        /// <summary>
        /// Logging of residuals (provisional).
        /// </summary>
        virtual protected void LogResis(int iterIndex, double[] currentSol, double[] currentRes, MultigridOperator Mgop)
        {
            if (m_ResLogger != null)
            {
                int NF = this.CurrentStateMapping.Fields.Count;
                m_ResLogger.IterationCounter = iterIndex;

                if (m_TransformedResi)
                {
                    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    // transform current solution and residual back to the DG domain
                    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                    var R = this.Residuals;
                    R.Clear();

                    Mgop.TransformRhsFrom(R, currentRes);
                    //Mgop.TransformSolFrom(X, currentSol);
                    //this.m_Agglomerator.Extrapolate(X, X.Mapping);
                    this.m_CurrentAgglomeration.Extrapolate(R.Mapping);

                    /*
                     * CoordinateVector Solution = new CoordinateVector(this.Residuals.Fields.Select(delegate (DGField f) {
                     *  DGField r = f.CloneAs();
                     *  r.Identification = "Sol_" + r.Identification;
                     *  return r;
                     * }));
                     * Mgop.TransformSolFrom(Solution, currentSol);
                     * Tecplot.Tecplot.PlotFields(Solution.Fields.Cat(this.Residuals.Fields), "DuringNewton-" + iterIndex, iterIndex, 3);
                     */

                    for (int i = 0; i < NF; i++)
                    {
                        double L2Res = R.Mapping.Fields[i].L2Norm();
                        m_ResLogger.CustomValue(L2Res, m_ResidualNames[i]);
                    }
                }
                else
                {
                    // +++++++++++++++++++++++
                    // un-transformed residual
                    // +++++++++++++++++++++++

                    var VarIdx = NF.ForLoop(i => Mgop.Mapping.GetSubvectorIndices(i));

                    for (int i = 0; i < VarIdx.Length; i++)
                    {
                        double L2Res = 0.0;

                        foreach (int idx in VarIdx[i])
                        {
                            L2Res += currentRes[idx - Mgop.Mapping.i0].Pow2();
                        }
                        L2Res = L2Res.MPISum().Sqrt(); // would be better to do the MPISum for all L2Res together,
                                                       //                                but this implementation is anyway inefficient....

                        m_ResLogger.CustomValue(L2Res, m_ResidualNames[i]);
                    }
                }

                if (Config_LevelSetHandling == LevelSetHandling.Coupled_Iterative)
                {
                    m_ResLogger.CustomValue(m_LastLevelSetResidual, "LevelSet");
                }

                m_ResLogger.NextIteration(true);
            }
        }
示例#21
0
        private void RKstageImplicit(double PhysTime, double dt, double[][] k, int s, BlockMsrMatrix[] Mass, CoordinateVector u0, double ActualLevSetRelTime, double[] RK_as, double RelTime)
        {
            Debug.Assert(s < m_RKscheme.Stages);
            Debug.Assert(m_RKscheme.c[s] > 0);
            Debug.Assert(RK_as[s] != 0);

            int Ndof = m_CurrentState.Count;

            // =========
            // RHS setup
            // =========

            m_ImplStParams = new ImplicitStage_AssiParams()
            {
                m_CurrentDt           = dt,
                m_CurrentPhystime     = PhysTime,
                m_IterationCounter    = 0,
                m_ActualLevSetRelTime = ActualLevSetRelTime,
                m_RelTime             = RelTime,
                m_k     = k,
                m_u0    = u0,
                m_Mass  = Mass,
                m_RK_as = RK_as,
                m_s     = s
            };


            // ================
            // solve the system
            // ================

            NonlinearSolver         nonlinSolver;
            ISolverSmootherTemplate linearSolver;

            GetSolver(out nonlinSolver, out linearSolver);


            if (RequiresNonlinearSolver)
            {
                // Nonlinear Solver (Navier-Stokes)
                // --------------------------------

                nonlinSolver.SolverDriver(m_CurrentState, default(double[])); // Note: the RHS is passed as the affine part via 'this.SolverCallback'
            }
            else
            {
                // Linear Solver (Stokes)
                // ----------------------


                // build the saddle-point matrix
                BlockMsrMatrix System, MaMa;
                double[]       RHS;
                this.AssembleMatrixCallback(out System, out RHS, out MaMa, CurrentStateMapping.Fields.ToArray(), true);
                RHS.ScaleV(-1);

                // update the multigrid operator
                MultigridOperator mgOperator = new MultigridOperator(this.MultigridBasis, CurrentStateMapping,
                                                                     System, MaMa,
                                                                     this.Config_MultigridOperator);

                // init linear solver
                linearSolver.Init(mgOperator);

                // try to solve the saddle-point system.
                mgOperator.UseSolver(linearSolver, m_CurrentState, RHS);

                // 'revert' agglomeration
                m_CurrentAgglomeration.Extrapolate(CurrentStateMapping);
            }

            // ================
            // reset
            // ================
            m_ImplStParams = null;
        }
示例#22
0
        private void ConsistencyTest()
        {
            // consistency test on the original matrix
            // -----------------------------------------------------

            this.residual.Clear();
            double[] RHSvec = this.GetRHS();
            this.residual.CoordinateVector.SetV(RHSvec, 1.0);
            this.Op_Matrix.SpMV(-1.0, this.u.CoordinateVector, 1.0, residual.CoordinateVector);

            double residual_L2Norm = this.residual.L2Norm();

            Console.WriteLine("Residual norm: " + residual_L2Norm);

            Assert.LessOrEqual(residual_L2Norm, 1.0e-8);



            // consistency test on the multigrid
            // --------------------------------------------------------------------

            AggregationGridBasis[][] XAggB = AggregationGridBasis.CreateSequence(base.MultigridSequence, u.Mapping.BasisS);
            XAggB.UpdateXdgAggregationBasis(this.Op_Agglomeration);


            int p           = this.u.Basis.Degree;
            var MultigridOp = new MultigridOperator(XAggB, this.u.Mapping,
                                                    this.Op_Matrix,
                                                    this.Op_mass.GetMassMatrix(new UnsetteledCoordinateMapping(this.u.Basis), false),
                                                    new MultigridOperator.ChangeOfBasisConfig[][] {
                new MultigridOperator.ChangeOfBasisConfig[] {
                    new MultigridOperator.ChangeOfBasisConfig()
                    {
                        VarIndex = new int[] { 0 }, mode = MultigridOperator.Mode.Eye, Degree = u.Basis.Degree
                    }
                }
            });

            double[] mgSolVec = new double[MultigridOp.Mapping.LocalLength];
            double[] mgRhsVec = new double[MultigridOp.Mapping.LocalLength];
            MultigridOp.TransformSolInto(this.u.CoordinateVector, mgSolVec);
            MultigridOp.TransformRhsInto(RHSvec, mgRhsVec);

            MgConsistencyTestRec(MultigridOp, mgSolVec, mgRhsVec);

            //

            /*
             * {
             *  int Jagg1 = MgSeq[1].NoOfAggregateCells;
             *  MultigridOperator MgOp0 = MultigridOp;
             *  MultigridOperator MgOp1 = MultigridOp.CoarserLevel;
             *  MultigridMapping Map0 = MgOp0.Mapping;
             *  MultigridMapping Map1 = MgOp1.Mapping;
             *
             *
             *  double[] V0 = new double[MgOp0.Mapping.LocalLength];
             *  double[] V1 = new double[MgOp1.Mapping.LocalLength];
             *
             *  for(int j = 0; j < Jagg1; j++) {
             *      int idx = Map1.LocalUniqueIndex(0, j, 0);
             *      V1[idx] = j;
             *  }
             *
             *  MgOp1.Prolongate(1.0, V0, 0.0, V1);
             *
             *  XDGField Marker = new XDGField(this.u.Basis, "Tracker");
             *
             *  MgOp0.TransformSolFrom(Marker.CoordinatesAsVector, V0);
             *  this.Op_Agglomeration.Extrapolate(Marker.CoordinatesAsVector, Marker.Mapping);
             *
             *  Tecplot.PlotFields(new DGField[] { Marker }, "Tracker", "Tracker", 0.0, 5);
             *
             * }
             */
        }
示例#23
0
 protected void CustomItCallback(int iterIndex, double[] currentSol, double[] currentRes, MultigridOperator Mgop)
 {
     //currentSol.SaveToTextFile("X_"+ iterIndex);
     //currentRes.SaveToTextFile("Res_" + iterIndex);
     MaxMlevel = Mgop.LevelIndex;
 }
示例#24
0
 protected void CustomItCallback(int iterIndex, double[] currentSol, double[] currentRes, MultigridOperator Mgop)
 {
     //noch nix ...
     MaxMlevel = Mgop.LevelIndex;
 }
示例#25
0
        private void ExperimentalSolver(out double mintime, out double maxtime, out bool Converged, out int NoOfIter, out int DOFs)
        {
            using (var tr = new FuncTrace()) {
                mintime   = double.MaxValue;
                maxtime   = 0;
                Converged = false;
                NoOfIter  = int.MaxValue;
                DOFs      = 0;

                AggregationGridBasis[][] XAggB;
                using (new BlockTrace("Aggregation_basis_init", tr)) {
                    XAggB = AggregationGridBasis.CreateSequence(base.MultigridSequence, u.Mapping.BasisS);
                }
                XAggB.UpdateXdgAggregationBasis(this.Op_Agglomeration);

                var      MassMatrix = this.Op_mass.GetMassMatrix(this.u.Mapping, new double[] { 1.0 }, false, this.LsTrk.SpeciesIdS.ToArray());
                double[] _RHSvec    = this.GetRHS();



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

                Console.WriteLine("Setting up multigrid operator...");

                int p           = this.u.Basis.Degree;
                var MultigridOp = new MultigridOperator(XAggB, this.u.Mapping,
                                                        this.Op_Matrix,
                                                        this.Op_mass.GetMassMatrix(new UnsetteledCoordinateMapping(this.u.Basis), false),
                                                        OpConfig);
                Assert.True(MultigridOp != null);

                int L = MultigridOp.Mapping.LocalLength;
                DOFs = MultigridOp.Mapping.TotalLength;

                double[] RHSvec = new double[L];
                MultigridOp.TransformRhsInto(_RHSvec, RHSvec);


                ISolverSmootherTemplate exsolver;

                SolverFactory SF = new SolverFactory(this.Control.NonLinearSolver, this.Control.LinearSolver);
                List <Action <int, double[], double[], MultigridOperator> > Callbacks = new List <Action <int, double[], double[], MultigridOperator> >();
                Callbacks.Add(CustomItCallback);
                SF.GenerateLinear(out exsolver, MultigridSequence, OpConfig, Callbacks);



                using (new BlockTrace("Solver_Init", tr)) {
                    exsolver.Init(MultigridOp);
                }

                /*
                 * string filename = "XdgPoisson" + this.Grid.SpatialDimension + "p" + this.u.Basis.Degree + "R" + this.Grid.CellPartitioning.TotalLength;
                 * MultigridOp.OperatorMatrix.SaveToTextFileSparse(filename + ".txt");
                 * RHSvec.SaveToTextFile(filename + "_rhs.txt");
                 *
                 * var uEx = this.u.CloneAs();
                 * Op_Agglomeration.ClearAgglomerated(uEx.Mapping);
                 * var CO = new ConvergenceObserver(MultigridOp, MassMatrix, uEx.CoordinateVector.ToArray());
                 * uEx = null;
                 * CO.TecplotOut = "PoissonConvergence";
                 * //CO.PlotDecomposition(this.u.CoordinateVector.ToArray());
                 *
                 * if (exsolver is ISolverWithCallback) {
                 *  ((ISolverWithCallback)exsolver).IterationCallback = CO.IterationCallback;
                 * }
                 * //*/
                XDGField u2 = u.CloneAs();
                using (new BlockTrace("Solver_Run", tr)) {
                    // use solver (on XDG-field 'u2').
                    u2.Clear();
                    MultigridOp.UseSolver(exsolver, u2.CoordinateVector, _RHSvec);
                    Console.WriteLine("Solver: {0}, converged? {1}, {2} iterations.", exsolver.GetType().Name, exsolver.Converged, exsolver.ThisLevelIterations);
                    this.Op_Agglomeration.Extrapolate(u2.Mapping);
                    Assert.IsTrue(exsolver.Converged, "Iterative solver did not converge.");
                }
                stw.Stop();
                mintime   = Math.Min(stw.Elapsed.TotalSeconds, mintime);
                maxtime   = Math.Max(stw.Elapsed.TotalSeconds, maxtime);
                Converged = exsolver.Converged;
                NoOfIter  = exsolver.ThisLevelIterations;

                // compute error between reference solution and multigrid solver
                XDGField ErrField = u2.CloneAs();
                ErrField.Acc(-1.0, u);
                double ERR    = ErrField.L2Norm();
                double RelERR = ERR / u.L2Norm();
                Assert.LessOrEqual(RelERR, 1.0e-6, "Result from iterative solver above threshold.");
            }
        }
示例#26
0
        /// <summary>
        /// Solution of the system
        /// <see cref="LaplaceMtx"/>*<see cref="T"/> + <see cref="LaplaceAffine"/> = <see cref="RHS"/>
        /// using the modular solver framework.
        /// </summary>
        private void ExperimentalSolve(out double mintime, out double maxtime, out bool Converged, out int NoOfIter) {
            using (var tr = new FuncTrace()) {
                int p = this.T.Basis.Degree;
                var MgSeq = this.MultigridSequence;
                mintime = double.MaxValue;
                maxtime = 0;
                Converged = false;
                NoOfIter = int.MaxValue;

                Console.WriteLine("Construction of Multigrid basis...");
                Stopwatch mgBasis = new Stopwatch();
                mgBasis.Start();
                AggregationGridBasis[][] AggBasis;
                using (new BlockTrace("Aggregation_basis_init", tr)) {
                    AggBasis = AggregationGridBasis.CreateSequence(MgSeq, new Basis[] { this.T.Basis });
                }
                mgBasis.Stop();
                Console.WriteLine("done. (" + mgBasis.Elapsed.TotalSeconds + " sec)");


                //foreach (int sz in new int[] { 1000, 2000, 5000, 10000, 20000 }) {
                //    base.Control.TargetBlockSize = sz;

                for (int irun = 0; irun < base.Control.NoOfSolverRuns; irun++) {
                    Stopwatch stw = new Stopwatch();
                    stw.Reset();
                    stw.Start();

                    Console.WriteLine("Setting up multigrid operator...");
                    var mgsetup = new Stopwatch();
                    mgsetup.Start();
                    var MultigridOp = new MultigridOperator(AggBasis, this.T.Mapping, this.LaplaceMtx, null, MgConfig);
                    mgsetup.Stop();
                    Console.WriteLine("done. (" + mgsetup.Elapsed.TotalSeconds + " sec)");


                    Console.WriteLine("Setting up solver...");
                    var solverSetup = new Stopwatch();
                    solverSetup.Start();
                    ISolverSmootherTemplate solver;
                    switch (base.Control.solver_name) {
                        case SolverCodes.exp_direct:
                            solver = new DirectSolver() {
                                WhichSolver = DirectSolver._whichSolver.PARDISO
                            };
                            break;

                        case SolverCodes.exp_direct_lapack:
                            solver = new DirectSolver() {
                                WhichSolver = DirectSolver._whichSolver.Lapack
                            };
                            break;

                        case SolverCodes.exp_softpcg_schwarz_directcoarse: {
                                double LL = this.LaplaceMtx._RowPartitioning.LocalLength;
                                int NoOfBlocks = (int)Math.Max(1, Math.Round(LL / (double)this.Control.TargetBlockSize));
                                Console.WriteLine("Additive Schwarz w. direct coarse, No of blocks: " + NoOfBlocks.MPISum());
                                solver = new SoftPCG() {
                                    m_MaxIterations = 50000,
                                    m_Tolerance = 1.0e-10,
                                    Precond = new Schwarz() {
                                        m_MaxIterations = 1,
                                        //CoarseSolver = new GenericRestriction() {
                                        //    CoarserLevelSolver = new GenericRestriction() {
                                        CoarseSolver = new DirectSolver() {
                                            WhichSolver = DirectSolver._whichSolver.PARDISO
                                            //            }
                                            //}
                                        },
                                        m_BlockingStrategy = new Schwarz.METISBlockingStrategy() {
                                            NoOfPartsPerProcess = NoOfBlocks
                                        },
                                        Overlap = 1,

                                    }
                                };
                                break;
                            }

                        case SolverCodes.exp_softpcg_schwarz: {
                                double LL = this.LaplaceMtx._RowPartitioning.LocalLength;
                                int NoOfBlocks = (int)Math.Max(1, Math.Round(LL / (double)this.Control.TargetBlockSize));
                                Console.WriteLine("Additive Schwarz, No of blocks: " + NoOfBlocks.MPISum());

                                solver = new SoftPCG() {
                                    m_MaxIterations = 50000,
                                    m_Tolerance = 1.0e-10,
                                    Precond = new Schwarz() {
                                        m_MaxIterations = 1,
                                        CoarseSolver = null,
                                        m_BlockingStrategy = new Schwarz.METISBlockingStrategy {
                                            NoOfPartsPerProcess = NoOfBlocks
                                        },
                                        Overlap = 1
                                    }
                                };
                                break;
                            }

                        case SolverCodes.exp_softpcg_mg:
                            solver = MultilevelSchwarz(MultigridOp);
                            break;


                        case SolverCodes.exp_Kcycle_schwarz:
                            solver = KcycleMultiSchwarz(MultigridOp);
                            break;

                        default:
                            throw new ApplicationException("unknown solver: " + this.Control.solver_name);
                    }

                    T.Clear();
                    T.AccLaidBack(1.0, Tex);
                    ConvergenceObserver CO = null;
                    //CO = new ConvergenceObserver(MultigridOp, null, T.CoordinateVector.ToArray());
                    //CO.TecplotOut = "oasch";
                    if (solver is ISolverWithCallback) {

                        if (CO == null) {
                            ((ISolverWithCallback)solver).IterationCallback = delegate (int iter, double[] xI, double[] rI, MultigridOperator mgOp) {
                                double l2_RES = rI.L2NormPow2().MPISum().Sqrt();

                                double[] xRef = new double[xI.Length];
                                MultigridOp.TransformSolInto(T.CoordinateVector, xRef);

                                double l2_ERR = GenericBlas.L2DistPow2(xI, xRef).MPISum().Sqrt();
                                Console.WriteLine("Iter: {0}\tRes: {1:0.##E-00}\tErr: {2:0.##E-00}\tRunt: {3:0.##E-00}", iter, l2_RES, l2_ERR, stw.Elapsed.TotalSeconds);
                                //Tjac.CoordinatesAsVector.SetV(xI);
                                //Residual.CoordinatesAsVector.SetV(rI);
                                //PlotCurrentState(iter, new TimestepNumber(iter), 3);
                            };
                        } else {
                            ((ISolverWithCallback)solver).IterationCallback = CO.IterationCallback;
                        }
                    }


                    using (new BlockTrace("Solver_Init", tr)) {
                        solver.Init(MultigridOp);
                    }
                    solverSetup.Stop();
                    Console.WriteLine("done. (" + solverSetup.Elapsed.TotalSeconds + " sec)");

                    Console.WriteLine("Running solver...");
                    var solverIteration = new Stopwatch();
                    solverIteration.Start();
                    double[] T2 = this.T.CoordinateVector.ToArray();
                    using (new BlockTrace("Solver_Run", tr)) {
                        solver.ResetStat();
                        T2.Clear();
                        var RHSvec = RHS.CoordinateVector.ToArray();
                        BLAS.daxpy(RHSvec.Length, -1.0, this.LaplaceAffine, 1, RHSvec, 1);
                        MultigridOp.UseSolver(solver, T2, RHSvec);
                        T.CoordinateVector.SetV(T2);
                    }
                    solverIteration.Stop();
                    Console.WriteLine("done. (" + solverIteration.Elapsed.TotalSeconds + " sec)");

                    Console.WriteLine("Pardiso phase 11: " + ilPSP.LinSolvers.PARDISO.PARDISOSolver.Phase_11.Elapsed.TotalSeconds);
                    Console.WriteLine("Pardiso phase 22: " + ilPSP.LinSolvers.PARDISO.PARDISOSolver.Phase_22.Elapsed.TotalSeconds);
                    Console.WriteLine("Pardiso phase 33: " + ilPSP.LinSolvers.PARDISO.PARDISOSolver.Phase_33.Elapsed.TotalSeconds);

                    // time measurement, statistics
                    stw.Stop();
                    mintime = Math.Min(stw.Elapsed.TotalSeconds, mintime);
                    maxtime = Math.Max(stw.Elapsed.TotalSeconds, maxtime);
                    Converged = solver.Converged;
                    NoOfIter = solver.ThisLevelIterations;

                    if (CO != null)
                        CO.PlotTrend(true, true, true);

                }
            }
        }
示例#27
0
        /// <summary>
        /// 
        /// </summary>
        ISolverSmootherTemplate KcycleMultiSchwarz(MultigridOperator op) {
            var solver = new OrthonormalizationScheme() {
                MaxIter = 500,
                Tolerance = 1.0e-10,

            };

            // my tests show that the ideal block size may be around 10'000
            int DirectKickIn = base.Control.TargetBlockSize;


            MultigridOperator Current = op;
            var PrecondChain = new List<ISolverSmootherTemplate>();
            for (int iLevel = 0; iLevel < base.MultigridSequence.Length; iLevel++) {
                int SysSize = Current.Mapping.TotalLength;
                int NoOfBlocks = (int)Math.Ceiling(((double)SysSize) / ((double)DirectKickIn));

                bool useDirect = false;
                useDirect |= (SysSize < DirectKickIn);
                useDirect |= iLevel == base.MultigridSequence.Length - 1;
                useDirect |= NoOfBlocks.MPISum() <= 1;


                ISolverSmootherTemplate levelSolver;
                if (useDirect) {
                    levelSolver = new DirectSolver() {
                        WhichSolver = DirectSolver._whichSolver.PARDISO,
                        TestSolution = false
                    };
                } else {

                    Schwarz swz1 = new Schwarz() {
                        m_MaxIterations = 1,
                        CoarseSolver = null,
                        m_BlockingStrategy = new Schwarz.METISBlockingStrategy() {
                            NoOfPartsPerProcess = NoOfBlocks
                        },
                        Overlap = 2 // overlap seems to help
                    };

                    SoftPCG pcg1 = new SoftPCG() {
                        m_MinIterations = 5,
                        m_MaxIterations = 5
                    };

                    //*/

                    var pre = new SolverSquence() {
                        SolverChain = new ISolverSmootherTemplate[] { swz1, pcg1 }
                    };

                    levelSolver = swz1;
                }

                if (iLevel > 0) {

                    GenericRestriction[] R = new GenericRestriction[iLevel];
                    for (int ir = 0; ir < R.Length; ir++) {
                        R[ir] = new GenericRestriction();
                        if (ir >= 1)
                            R[ir - 1].CoarserLevelSolver = R[ir];
                    }
                    R[iLevel - 1].CoarserLevelSolver = levelSolver;
                    PrecondChain.Add(R[0]);

                } else {
                    PrecondChain.Add(levelSolver);
                }


                if (useDirect) {
                    Console.WriteLine("Kswz: using {0} levels, lowest level DOF is {1}, target size is {2}.", iLevel + 1, SysSize, DirectKickIn);
                    break;
                }



                Current = Current.CoarserLevel;

            }


            if (PrecondChain.Count > 1) {
                /*
                // construct a V-cycle
                for (int i = PrecondChain.Count - 2; i>= 0; i--) {
                    PrecondChain.Add(PrecondChain[i]);
                }
                */

                var tmp = PrecondChain.ToArray();
                for (int i = 0; i < PrecondChain.Count; i++) {
                    PrecondChain[i] = tmp[PrecondChain.Count - 1 - i];
                }
            }



            solver.PrecondS = PrecondChain.ToArray();
            solver.MaxKrylovDim = solver.PrecondS.Length * 4;

            return solver;
        }
示例#28
0
 protected void CustomItCallback(int iterIndex, double[] currentSol, double[] currentRes, MultigridOperator Mgop)
 {
     MaxMlevel = Mgop.LevelIndex;
     //currentRes.SaveToTextFileDebug(String.Format("Res_{0}_proc",iterIndex));
     //currentSol.SaveToTextFileDebug(String.Format("Sol_{0}_proc",iterIndex));
     //Console.WriteLine("Callback executed {0} times",iterIndex);
 }
示例#29
0
        /// <summary>
        /// Ganz ok.
        /// </summary>
        ISolverSmootherTemplate MultilevelSchwarz(MultigridOperator op) {
            var solver = new SoftPCG() {
                m_MaxIterations = 500,
                m_Tolerance = 1.0e-12
            };
            //var solver = new OrthonormalizationScheme() {
            //    MaxIter = 500,
            //    Tolerance = 1.0e-10,
            //};
            //var solver = new SoftGMRES() {
            //    m_MaxIterations = 500,
            //    m_Tolerance = 1.0e-10,

            //};

            // my tests show that the ideal block size may be around 10'000
            int DirectKickIn = base.Control.TargetBlockSize;


            MultigridOperator Current = op;
            ISolverSmootherTemplate[] MultigridChain = new ISolverSmootherTemplate[base.MultigridSequence.Length];
            for (int iLevel = 0; iLevel < base.MultigridSequence.Length; iLevel++) {
                int SysSize = Current.Mapping.TotalLength;
                int NoOfBlocks = (int)Math.Ceiling(((double)SysSize) / ((double)DirectKickIn));

                bool useDirect = false;
                useDirect |= (SysSize < DirectKickIn);
                useDirect |= iLevel == base.MultigridSequence.Length - 1;
                useDirect |= NoOfBlocks.MPISum() <= 1;

                if (useDirect) {
                    MultigridChain[iLevel] = new DirectSolver() {
                        WhichSolver = DirectSolver._whichSolver.PARDISO,
                        TestSolution = false
                    };
                } else {

                    ClassicMultigrid MgLevel = new ClassicMultigrid() {
                        m_MaxIterations = 1,
                        m_Tolerance = 0.0 // termination controlled by top level PCG
                    };


                    MultigridChain[iLevel] = MgLevel;


                    
                    ISolverSmootherTemplate pre, pst;
                    if (iLevel > 0) {

                        Schwarz swz1 = new Schwarz() {
                            m_MaxIterations = 1,
                            CoarseSolver = null,
                            m_BlockingStrategy = new Schwarz.METISBlockingStrategy() {
                                NoOfPartsPerProcess = NoOfBlocks
                            },
                            Overlap = 0 // overlap does **NOT** seem to help
                        };

                        SoftPCG pcg1 = new SoftPCG() {
                            m_MinIterations = 5,
                            m_MaxIterations = 5
                        };

                        SoftPCG pcg2 = new SoftPCG() {
                            m_MinIterations = 5,
                            m_MaxIterations = 5
                        };

                        var preChain = new ISolverSmootherTemplate[] { swz1, pcg1 };
                        var pstChain = new ISolverSmootherTemplate[] { swz1, pcg2 };

                        pre = new SolverSquence() { SolverChain = preChain };
                        pst = new SolverSquence() { SolverChain = pstChain };
                    } else {
                        // +++++++++++++++++++++++++++++++++++++++++++++++++++
                        // top level - use only iterative (non-direct) solvers
                        // +++++++++++++++++++++++++++++++++++++++++++++++++++

                        pre = new BlockJacobi() {
                            NoOfIterations = 3,
                            omega = 0.5
                        };

                        pst = new BlockJacobi() {
                            NoOfIterations = 3,
                            omega = 0.5
                        };

                        //preChain = new ISolverSmootherTemplate[] { pcg1 };
                        //pstChain = new ISolverSmootherTemplate[] { pcg2 };
                    }





                    //if (iLevel > 0) {
                    //    MgLevel.PreSmoother = pre;
                    //    MgLevel.PostSmoother = pst;
                    //} else {
                    //    //MgLevel.PreSmoother = pcg1;   // ganz schlechte Idee, konvergiert gegen FALSCHE lösung
                    //    //MgLevel.PostSmoother = pcg2;  // ganz schlechte Idee, konvergiert gegen FALSCHE lösung
                    //    MgLevel.PreSmoother = pre;
                    //    MgLevel.PostSmoother = pst;
                    //}

                    MgLevel.PreSmoother = pre;
                    MgLevel.PostSmoother = pst;
                }

                if (iLevel > 0) {
                    ((ClassicMultigrid)(MultigridChain[iLevel - 1])).CoarserLevelSolver = MultigridChain[iLevel];
                }

                if (useDirect) {
                    Console.WriteLine("MG: using {0} levels, lowest level DOF is {1}, target size is {2}.", iLevel + 1, SysSize, DirectKickIn);
                    break;
                }



                Current = Current.CoarserLevel;

            } // end of level loop


            solver.Precond = MultigridChain[0];
            //solver.PrecondS = new[] { MultigridChain[0] };

            return solver;
        }
示例#30
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);
        }