Exemplo n.º 1
0
        public static void Init()
        {
            //GridCommons grd = Grid2D.Cartesian2DGrid(RandomSpacing(), RandomSpacing());
            //grid = new GridData(Grid2D.Cartesian2DGrid(GenericBlas.Linspace(-7, 7, 8), GenericBlas.Linspace(-1, 1, 2)));
            //grid = new GridData(Grid2D.Cartesian2DGrid(new double[] { -6, -4, -2, 2, 4, 6 }, GenericBlas.Linspace(-1, 1, 2)));
            //if (curved)
            //{
            //    grid = Grid2D.CurvedSquareGrid(GenericBlas.Linspace(1, 2, 5), GenericBlas.Linspace(0, 1, 17), CellType.Square_9, true).GridData;
            //}
            //else
            //{
            //    grid = (Grid2D.Cartesian2DGrid(GenericBlas.Linspace(-1.5, 1.5, 17), GenericBlas.Linspace(-1.5, 1.5, 17))).GridData;
            //}
            grid  = (Grid2D.Cartesian2DGrid(GenericBlas.Linspace(-1.5, 1.5, 17), GenericBlas.Linspace(-1.5, 1.5, 17))).GridData;
            MgSeq = CoarseningAlgorithms.CreateSequence(grid);

            for (int p = 0; p <= 3; p++)   // loop over polynomial degrees...
            {
                var uMapping = new UnsetteledCoordinateMapping(new Basis(grid, p));

                var MgMapSeq = new MultigridMapping[MgSeq.Length];
                var BasisSeq = AggregationGridBasis.CreateSequence(MgSeq, uMapping.BasisS);
                for (int iLevel = 0; iLevel < MgSeq.Length; iLevel++)
                {
                    MgMapSeq[iLevel] = new MultigridMapping(uMapping, BasisSeq[iLevel], new int[] { p });
                }
                MultigrigMap.Add(p, MgMapSeq);
            }
        }
Exemplo n.º 2
0
        public static void Init()
        {
            bool dummy;

            ilPSP.Environment.Bootstrap(
                new string[0],
                BoSSS.Solution.Application.GetBoSSSInstallDir(),
                out dummy);

            //GridCommons grd = Grid2D.Cartesian2DGrid(RandomSpacing(), RandomSpacing());
            //grid = new GridData(Grid2D.Cartesian2DGrid(GenericBlas.Linspace(-7, 7, 8), GenericBlas.Linspace(-1, 1, 2)));
            //grid = new GridData(Grid2D.Cartesian2DGrid(new double[] { -6, -4, -2, 2, 4, 6 }, GenericBlas.Linspace(-1, 1, 2)));
            grid  = new GridData(Grid2D.Cartesian2DGrid(GenericBlas.Linspace(-1.5, 1.5, 17), GenericBlas.Linspace(-1.5, 1.5, 17)));
            MgSeq = CoarseningAlgorithms.CreateSequence(grid);

            for (int p = 0; p <= 3; p++)   // loop over polynomial degrees...
            {
                var uMapping = new UnsetteledCoordinateMapping(new Basis(grid, p));

                var MgMapSeq = new MultigridMapping[MgSeq.Length];
                var BasisSeq = AggregationGridBasis.CreateSequence(MgSeq, uMapping.BasisS);
                for (int iLevel = 0; iLevel < MgSeq.Length; iLevel++)
                {
                    MgMapSeq[iLevel] = new MultigridMapping(uMapping, BasisSeq[iLevel], new int[] { p });
                }
                MultigrigMap.Add(p, MgMapSeq);
            }
        }
Exemplo n.º 3
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());
        }
Exemplo n.º 4
0
        private static int[] ConvertRowIndices(
            int jCell,
            AggregationGridBasis basis, int[] Degrees,
            ChangeOfBasisConfig conf,
            int E, int[] _i0s,
            int[] LocIdx)
        {
            int NN = conf.VarIndex.Sum(iVar => basis.GetLength(jCell, Degrees[iVar]));

            int[] Loc2glob = new int[NN];

            int i0Rowloc = 0;

            for (int eRow = 0; eRow < E; eRow++)   // loop over variables in configuration
            {
                int i0Row   = _i0s[eRow];
                int iVarRow = conf.VarIndex[eRow];

                int NRow = basis.GetLength(jCell, Degrees[iVarRow]);

                for (int n_row = 0; n_row < NRow; n_row++)   // row loop...
                //n_row = LocIdx[k];

                {
                    int iRowLoc = n_row + i0Rowloc;
                    int iRowGlb = n_row + i0Row;

                    Loc2glob[iRowLoc] = iRowGlb;
                }
                i0Rowloc += NRow;
            }

            return(LocIdx.Select(i => Loc2glob[i]).ToArray());
        }
Exemplo n.º 5
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.º 6
0
        private void OperatorAnalysis()
        {
            AggregationGridBasis[][] XAggB = AggregationGridBasis.CreateSequence(base.MultigridSequence, u.Mapping.BasisS);

            XAggB.UpdateXdgAggregationBasis(this.Op_Agglomeration);

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

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

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

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

                bmc.Execute(false);
            }

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

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

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

            base.QueryHandler.ValueQuery("condNo", condNo, false);
            base.QueryHandler.ValueQuery("eigMaxi", eigMaxi, false);
            base.QueryHandler.ValueQuery("eigMini", eigMini, false);
            base.QueryHandler.ValueQuery("posDef", posDef, false);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Initialization of the solver/preconditioner.
        /// </summary>
        protected void InitMultigrid(DGField[] Fields, bool useX)
        {
            Basis[] bs;
            if (useX)
            {
                bs = new Basis[Fields.Length];
                for (int i = 0; i < bs.Length; i++)
                {
                    bs[i] = new XDGBasis(m_LsTrk, Fields[i].Basis.Degree);
                }
            }
            else
            {
                bs = Fields.Select(f => f.Basis).ToArray();
            }

            this.MultigridBasis = AggregationGridBasis.CreateSequence(this.MultigridSequence, bs);
        }
Exemplo n.º 8
0
        public static void Init()
        {
            grid  = Grid2D.CurvedSquareGrid(GenericBlas.Linspace(1, 2, 17), GenericBlas.Linspace(0, 1, 17), CellType.Square_9, true).GridData;
            MgSeq = CoarseningAlgorithms.CreateSequence(grid);

            for (int p = 0; p <= 3; p++)
            { // loop over polynomial degrees...
                var uMapping = new UnsetteledCoordinateMapping(new Basis(grid, p));

                var MgMapSeq = new MultigridMapping[MgSeq.Length];
                var BasisSeq = AggregationGridBasis.CreateSequence(MgSeq, uMapping.BasisS);
                for (int iLevel = 0; iLevel < MgSeq.Length; iLevel++)
                {
                    MgMapSeq[iLevel] = new MultigridMapping(uMapping, BasisSeq[iLevel], new int[] { p });
                }
                MultigrigMap.Add(p, MgMapSeq);
            }
        }
Exemplo n.º 9
0
        private void Setup()
        {
            MgSeq = CoarseningAlgorithms.CreateSequence(m_grid.iGridData);

            int p = m_DGorder;

            var uMapping = new UnsetteledCoordinateMapping(u1.Basis, u2.Basis);

            //var uMapping = new UnsetteledCoordinateMapping(u1.Basis);
            //var uMapping = new UnsetteledCoordinateMapping(new Basis(m_grid.iGridData, p));

            XAggB = AggregationGridBasis.CreateSequence(MgSeq, uMapping.BasisS);
            var bla = LsTrk.SpeciesIdS.ToArray();
            var agg = LsTrk.GetAgglomerator(bla, m_quadOrder, THRESHOLD, AgglomerateNewborn: false, AgglomerateDecased: false, ExceptionOnFailedAgglomeration: true);

            XAggB.UpdateXdgAggregationBasis(agg);
            var VarDegrees = uMapping.BasisS.Count.ForLoop(i => uMapping.BasisS[i].Degree);

            MG_Mapping = new MultigridMapping(uMapping, XAggB[0], VarDegrees);
            map        = uMapping;
        }
Exemplo n.º 10
0
        static void RestictionMatrixTestRec(int p, IEnumerable <MultigridMapping> MgMapSeq)
        {
            AggregationGridBasis AggBasis = MgMapSeq.First().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);
            Debug.Assert(RestErrNorm < 1.0e-10);
            Debug.Assert(PrlgErrNorm < 1.0e-10);

            if (MgMapSeq.Count() > 1)
            {
                RestictionMatrixTestRec(p, MgMapSeq.Skip(1));
            }
        }
Exemplo n.º 11
0
        public static void RestrictionOfSystemOpTest()
        {
            Basis B1 = new Basis(grid, 0), B2 = new Basis(grid, 2);
            var   Map = new UnsetteledCoordinateMapping(B1, B2);

            var Lev0Basis = new AggregationGridBasis(B2, TestProgram.MgSeq[0]);
            var Lev1Basis = new AggregationGridBasis(B2, TestProgram.MgSeq[1]);


            var Lev0 = new MultigridMapping(Map, new AggregationGridBasis[] { Lev0Basis, Lev0Basis }, new int[] { B1.Degree, B2.Degree });
            var Lev1 = new MultigridMapping(Map, new AggregationGridBasis[] { Lev1Basis, Lev1Basis }, new int[] { B1.Degree, B2.Degree });


            int[] I0col = Lev0.GetSubvectorIndices(new int[] { 0 });
            int[] I1col = Lev0.GetSubvectorIndices(new int[] { 1 });
            int[] I0row = Lev1.GetSubvectorIndices(new int[] { 0 });
            int[] I1row = Lev1.GetSubvectorIndices(new int[] { 1 });

            var RestMtx = Lev1.FromOtherLevelMatrix(Lev0);

            MsrMatrix Rest00 = new MsrMatrix(I0row.Length, I0col.Length, 1, 1);

            RestMtx.WriteSubMatrixTo(Rest00, I0row, default(int[]), I0col, default(int[]));
            MsrMatrix Rest01 = new MsrMatrix(I0row.Length, I1col.Length, 1, 1);

            RestMtx.WriteSubMatrixTo(Rest01, I0row, default(int[]), I1col, default(int[]));
            MsrMatrix Rest10 = new MsrMatrix(I1row.Length, I0col.Length, 1, 1);

            RestMtx.WriteSubMatrixTo(Rest10, I1row, default(int[]), I0col, default(int[]));
            MsrMatrix Rest11 = new MsrMatrix(I1row.Length, I1col.Length, 1, 1);

            RestMtx.WriteSubMatrixTo(Rest11, I1row, default(int[]), I1col, default(int[]));

            Debug.Assert(Rest10.InfNorm() == 0.0);
            Debug.Assert(Rest01.InfNorm() == 0.0);
            Debug.Assert(Rest00.InfNorm() != 0.0);
            Debug.Assert(Rest11.InfNorm() != 0.0);
        }
Exemplo n.º 12
0
        public static void RestrictionOfSystemOpTest()
        {
            Basis B1 = new Basis(grid, 0), B2 = new Basis(grid, 2);
            var   Map = new UnsetteledCoordinateMapping(B1, B2);

            AggregationGridBasis[][] aB = AggregationGridBasis.CreateSequence(TestProgram.MgSeq.Take(2), new Basis[] { B1, B2 });

            var Lev0 = new MultigridMapping(Map, aB[0], new int[] { B1.Degree, B2.Degree });
            var Lev1 = new MultigridMapping(Map, aB[1], new int[] { B1.Degree, B2.Degree });


            int[] I0col = Lev0.GetSubvectorIndices(new int[] { 0 });
            int[] I1col = Lev0.GetSubvectorIndices(new int[] { 1 });
            int[] I0row = Lev1.GetSubvectorIndices(new int[] { 0 });
            int[] I1row = Lev1.GetSubvectorIndices(new int[] { 1 });

            var RestMtx = Lev1.FromOtherLevelMatrix(Lev0);

            MsrMatrix Rest00 = new MsrMatrix(I0row.Length, I0col.Length, 1, 1);

            RestMtx.WriteSubMatrixTo(Rest00, I0row, default(int[]), I0col, default(int[]));
            MsrMatrix Rest01 = new MsrMatrix(I0row.Length, I1col.Length, 1, 1);

            RestMtx.WriteSubMatrixTo(Rest01, I0row, default(int[]), I1col, default(int[]));
            MsrMatrix Rest10 = new MsrMatrix(I1row.Length, I0col.Length, 1, 1);

            RestMtx.WriteSubMatrixTo(Rest10, I1row, default(int[]), I0col, default(int[]));
            MsrMatrix Rest11 = new MsrMatrix(I1row.Length, I1col.Length, 1, 1);

            RestMtx.WriteSubMatrixTo(Rest11, I1row, default(int[]), I1col, default(int[]));

            Assert.IsTrue(Rest10.InfNorm() == 0.0);
            Assert.IsTrue(Rest01.InfNorm() == 0.0);
            Assert.IsTrue(Rest00.InfNorm() != 0.0);
            Assert.IsTrue(Rest11.InfNorm() != 0.0);
        }
Exemplo n.º 13
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);

                }
            }
        }
Exemplo n.º 14
0
        /// <summary>
        /// applies the pre-conditioning to the operator matrix
        /// (passed in the constructor)
        /// and returns the pre-conditioned matrix
        /// </summary>
        /// <param name="LeftPreCond">
        /// left pre-conditioning matrix
        /// </param>
        /// <param name="RightPreCond">
        /// right pre-conditioning matrix
        /// </param>
        /// <param name="RightPreCondInv">
        /// the inverse of <paramref name="RightPreCond"/> -- usually required to transform an initial guess.
        /// </param>
        /// <param name="LeftPreCondInv"></param>
        /// <param name="MassMatrix">
        /// on entry the mass matrix w.r.t. the XDG basis
        /// </param>
        /// <param name="OpMatrix">
        /// </param>
        /// <returns>
        /// List of indefinite row indices.
        /// </returns>
        int[] ComputeChangeOfBasis(BlockMsrMatrix OpMatrix, BlockMsrMatrix MassMatrix, out BlockMsrMatrix LeftPreCond, out BlockMsrMatrix RightPreCond, out BlockMsrMatrix LeftPreCondInv, out BlockMsrMatrix RightPreCondInv)
        {
            using (var tr = new FuncTrace()) {
                // test arguments
                // ==============
                VerifyConfig();
                Debug.Assert(OpMatrix.RowPartitioning.LocalLength == this.Mapping.LocalLength);
                Debug.Assert(OpMatrix.ColPartition.LocalLength == this.Mapping.LocalLength);
                Debug.Assert(MassMatrix == null || (MassMatrix.RowPartitioning.LocalLength == this.Mapping.LocalLength));
                Debug.Assert(MassMatrix == null || (MassMatrix.ColPartition.LocalLength == this.Mapping.LocalLength));

                AggregationGridBasis[] basisS = this.Mapping.AggBasis;
                int[] Degrees = this.Mapping.DgDegree;

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


                // compute preconditioner matrices
                // ===============================
                using (var bt = new BlockTrace("compute-pc", tr)) {
                    Stopwatch stw_Data = new Stopwatch(); stw_Data.Reset();
                    Stopwatch stw_Comp = new Stopwatch(); stw_Comp.Reset();


                    LeftPreCond     = new BlockMsrMatrix(OpMatrix._RowPartitioning, OpMatrix._ColPartitioning);
                    RightPreCond    = new BlockMsrMatrix(OpMatrix._RowPartitioning, OpMatrix._ColPartitioning);
                    RightPreCondInv = new BlockMsrMatrix(OpMatrix._RowPartitioning, OpMatrix._ColPartitioning);
                    LeftPreCondInv  = new BlockMsrMatrix(OpMatrix._RowPartitioning, OpMatrix._ColPartitioning);
                    LeftPreCond.AccEyeSp(1.0);
                    RightPreCond.AccEyeSp(1.0);
                    LeftPreCondInv.AccEyeSp(1.0);
                    RightPreCondInv.AccEyeSp(1.0);


                    int LL = this.m_Config.Length;
                    MultidimensionalArray[] MassBlock        = new MultidimensionalArray[LL];
                    MultidimensionalArray[] OperatorBlock    = new MultidimensionalArray[LL];
                    MultidimensionalArray[] PCleftBlock      = new MultidimensionalArray[LL];
                    MultidimensionalArray[] work             = new MultidimensionalArray[LL];
                    MultidimensionalArray[] PCrightBlock_inv = new MultidimensionalArray[LL];
                    MultidimensionalArray[] PCleftBlock_inv  = new MultidimensionalArray[LL];
                    MultidimensionalArray[] PCrightBlock     = new MultidimensionalArray[LL];
                    int[][] __i0s = new int[LL][];

                    for (int i = 0; i < LL; i++)
                    {
                        var conf = m_Config[i];
                        __i0s[i] = new int[conf.VarIndex.Length];
                    }

                    int J  = this.Mapping.AggGrid.iLogicalCells.NoOfLocalUpdatedCells;
                    int i0 = this.Mapping.Partitioning.i0;
                    for (int jCell = 0; jCell < J; jCell++)   // loop over cells...
                    //ReducedRegionCode rrc;
                    //int NoOfSpc = LsTrk.GetNoOfSpecies(jCell, out rrc);

                    //if (this.Mapping.GetLength(jCell) == 0)
                    //    // void cell
                    //    continue;

                    {
                        for (int i = 0; i < LL; i++)   // for each configuration item...
                        {
                            var conf = m_Config[i];

                            int   E    = conf.VarIndex.Length;
                            int[] _i0s = __i0s[i];
                            AggregationGridBasis basis = null;

                            int  DOF           = 0;
                            bool AnyZeroLength = false;
                            for (int e1 = 0; e1 < E; e1++)
                            {
                                int dof_var = this.Mapping.GetLengthForVar(jCell, conf.VarIndex[e1]);
                                DOF           += dof_var;
                                AnyZeroLength |= (dof_var == 0);
                            }
                            if (AnyZeroLength && DOF > 0)
                            {
                                throw new ApplicationException();
                            }

                            if (DOF == 0)
                            {
                                // void cell
                                continue;
                            }

                            for (int e = 0; e < E; e++)
                            {
                                _i0s[e] = this.Mapping.LocalUniqueIndex(conf.VarIndex[e], jCell, 0) + i0;
                                if (e == 0)
                                {
                                    basis = basisS[conf.VarIndex[e]];
                                }
                                else
                                {
                                    if (!object.ReferenceEquals(basis, basisS[conf.VarIndex[e]]))
                                    {
                                        throw new NotSupportedException("All variables in a configuration item must share the same basis.");
                                    }
                                }
                            }

                            // extract blocks from operator and mass matrix
                            // --------------------------------------------

                            stw_Data.Start();
                            ExtractBlock(jCell, basis, Degrees, conf, E, _i0s, true, MassMatrix, ref MassBlock[i]);
                            ExtractBlock(jCell, basis, Degrees, conf, E, _i0s, true, OpMatrix, ref OperatorBlock[i]);
                            stw_Data.Stop();
                            double MassBlkNrm     = MassBlock[i].InfNorm();
                            double OperatorBlkNrm = OperatorBlock[i].InfNorm();
                            int    NN             = MassBlock[i].NoOfRows;

                            if (MassBlkNrm == 0)
                            {
                                //throw new ArithmeticException("absolute zero Mass block in cell " + jCell + ".");
                                //Console.WriteLine("absolute zero Mass block in cell " + jCell + ".");

                                if (conf.mode == Mode.IdMass_DropIndefinite || conf.mode == Mode.SymPart_DiagBlockEquilib_DropIndefinite)
                                {
                                    // we can deal with this ...
                                }
                                else
                                {
                                    throw new ArithmeticException("absolute zero Mass block in cell " + jCell + ".");
                                }
                            }
                            //if(OperatorBlkNrm == 0) {
                            //    throw new ArithmeticException("absolute zero Operator block in cell " + jCell + ".");
                            //}

                            // mem alloc
                            // ---------

                            if (PCleftBlock[i] == null || PCleftBlock[i].NoOfRows != NN)
                            {
                                PCleftBlock[i] = MultidimensionalArray.Create(NN, NN);
                            }
                            if (PCrightBlock[i] == null || PCrightBlock[i].NoOfRows != NN)
                            {
                                PCrightBlock[i] = MultidimensionalArray.Create(NN, NN);
                            }
                            if (work[i] == null || work[i].NoOfRows != NN)
                            {
                                work[i] = MultidimensionalArray.Create(NN, NN);
                            }

                            // compute precond
                            // ---------------


                            stw_Comp.Start();
                            int Rank;
                            PCleftBlock[i].Clear();
                            PCrightBlock[i].Clear();
                            int[] idr = ComputeChangeOfBasisBlock(MassBlock[i], OperatorBlock[i], PCleftBlock[i], PCrightBlock[i], conf.mode, out Rank, work[i]);
                            if (Rank != NN)
                            {
                                IndefRows.AddRange(ConvertRowIndices(jCell, basis, Degrees, conf, E, _i0s, idr));
                            }
                            else
                            {
                                Debug.Assert(idr == null);
                            }
                            stw_Comp.Stop();

                            // write block back
                            // ----------------
                            stw_Data.Start();
                            ExtractBlock(jCell, basis, Degrees, conf, E, _i0s, false, LeftPreCond, ref PCleftBlock[i]);
                            ExtractBlock(jCell, basis, Degrees, conf, E, _i0s, false, RightPreCond, ref PCrightBlock[i]);


                            // inverse precond-matrix
                            // ----------------------
                            // right-inverse: (required for transforming solution guess)
                            if (PCrightBlock_inv[i] == null || PCrightBlock_inv[i].NoOfRows != NN)
                            {
                                PCrightBlock_inv[i] = MultidimensionalArray.Create(NN, NN);
                            }
                            if (Rank == NN)
                            {
                                PCrightBlock[i].InvertTo(PCrightBlock_inv[i]);
                            }
                            else
                            {
                                RankDefInvert(PCrightBlock[i], PCrightBlock_inv[i]);
                            }
                            ExtractBlock(jCell, basis, Degrees, conf, E, _i0s, false, RightPreCondInv, ref PCrightBlock_inv[i]);

                            // left-inverse: (required for analysis purposes, to transform residuals back onto original grid)
                            if (PCleftBlock_inv[i] == null || PCleftBlock_inv[i].NoOfRows != NN)
                            {
                                PCleftBlock_inv[i] = MultidimensionalArray.Create(NN, NN);
                            }
                            if (Rank == NN)
                            {
                                PCleftBlock[i].InvertTo(PCleftBlock_inv[i]);
                            }
                            else
                            {
                                RankDefInvert(PCleftBlock[i], PCleftBlock_inv[i]);
                            }
                            ExtractBlock(jCell, basis, Degrees, conf, E, _i0s, false, LeftPreCondInv, ref PCleftBlock_inv[i]);

                            stw_Data.Stop();
                        }
                    }

                    bt.LogDummyblock(stw_Data.Elapsed.Ticks, "Change_of_Basis_data_copy");
                    bt.LogDummyblock(stw_Comp.Elapsed.Ticks, "Change_of_Basis_compute");
                }


                return(IndefRows.ToArray());
            }
        }
Exemplo n.º 15
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ProblemMapping"></param>
        /// <param name="MultigridSequence"></param>
        /// <param name="useX">
        /// Create an XDG aggregation basis even if <paramref name="ProblemMapping"/> only contains DG basis.
        /// </param>
        /// <returns></returns>
        public static AggregationGridBasis[][] CreateAggregationGridBasis(UnsetteledCoordinateMapping ProblemMapping, LevelSetTracker _LsTrk, AggregationGrid[] MultigridSequence, bool useX)
        {
            Debug.Assert(object.ReferenceEquals(_LsTrk.GridDat, ProblemMapping.GridDat));
            Basis[] BasisS = ProblemMapping.BasisS.ToArray();
            Debug.Assert(BasisS.Where(b => !object.ReferenceEquals(b.GridDat, _LsTrk.GridDat)).Count() == 0);
            AggregationGridBasis[][] MultigridBasis = new AggregationGridBasis[MultigridSequence.Length][];



            XDGBasis maxXDGbasis = null;
            Basis    maxDGbasis  = null;

            foreach (var b in BasisS)
            {
                if (b is XDGBasis)
                {
                    XDGBasis xb = (XDGBasis)b;
                    if (maxXDGbasis == null || maxXDGbasis.Degree < xb.Degree)
                    {
                        maxXDGbasis = xb;
                    }
                }
                else
                {
                    if (maxDGbasis == null || maxDGbasis.Degree < b.Degree)
                    {
                        maxDGbasis = b;
                    }
                }
            }

            if (useX)
            {
                if (maxDGbasis != null)
                {
                    if (maxXDGbasis == null || maxXDGbasis.Degree < maxDGbasis.Degree)
                    {
                        maxXDGbasis = new XDGBasis(_LsTrk, maxDGbasis.Degree);
                    }
                }
            }


            XdgAggregationBasis[] mgXdgB;
            if (maxXDGbasis != null)
            {
                mgXdgB = MultigridSequence.Select(aggGrd => new XdgAggregationBasis(maxXDGbasis, aggGrd)).ToArray();
            }
            else
            {
                mgXdgB = null;
            }


            AggregationGridBasis[] mgDgB;
            if (maxDGbasis != null)
            {
                mgDgB = MultigridSequence.Select(aggGrd => new AggregationGridBasis(maxDGbasis, aggGrd)).ToArray();
            }
            else
            {
                mgDgB = null;
            }

            for (int iLevel = 0; iLevel < MultigridSequence.Length; iLevel++)
            {
                MultigridBasis[iLevel] = new AggregationGridBasis[BasisS.Length];
                for (int r = 0; r < BasisS.Length; r++)
                {
                    if (BasisS[r] is XDGBasis || useX)
                    {
                        MultigridBasis[iLevel][r] = mgXdgB[iLevel];
                    }
                    else
                    {
                        MultigridBasis[iLevel][r] = mgDgB[iLevel];
                    }
                }
            }

            return(MultigridBasis);
        }
Exemplo n.º 16
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.");
                    //    }
                    //}
                }
            }
        }
Exemplo n.º 17
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
                        }
                    }
                });
            }
Exemplo n.º 18
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);
             *
             * }
             */
        }
Exemplo n.º 19
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.");
            }
        }
Exemplo n.º 20
0
        /// <summary>
        /// Prolongation/Injection operator to finer grid level.
        /// </summary>
        public BlockMsrMatrix GetProlongationOperator(MultigridMapping finerLevel)
        {
            using (new FuncTrace()) {
                // Argument checking
                // =================

                if (!object.ReferenceEquals(finerLevel.AggGrid, this.AggGrid.ParentGrid))
                {
                    throw new ArgumentException("Only prolongation/injection to next level is supported.");
                }
                if (finerLevel.AggBasis.Length != this.AggBasis.Length)
                {
                    throw new ArgumentException("");
                }
                int NoOfVar = this.AggBasis.Length;

                MultidimensionalArray[][] InjOp = new MultidimensionalArray[NoOfVar][];
                AggregationGridBasis[]    B     = new AggregationGridBasis[NoOfVar];
                bool[] useX        = new bool[NoOfVar];
                int[]  DegreeS     = new int[NoOfVar];
                int[]  DegreeSfine = new int[NoOfVar];

                for (int iVar = 0; iVar < NoOfVar; iVar++)
                {
                    InjOp[iVar]       = this.AggBasis[iVar].InjectionOperator;
                    B[iVar]           = AggBasis[iVar];
                    DegreeS[iVar]     = this.DgDegree[iVar];
                    DegreeSfine[iVar] = finerLevel.DgDegree[iVar];
                    if (DegreeSfine[iVar] < DegreeS[iVar])
                    {
                        throw new ArgumentException("Lower DG degree on finer grid is not supported by this method ");
                    }
                    useX[iVar] = this.AggBasis[iVar] is XdgAggregationBasis;
                    if (useX[iVar] != (finerLevel.AggBasis[iVar] is XdgAggregationBasis))
                    {
                        throw new ArgumentException("XDG / DG mismatch between this and finer level for " + iVar + "-th variable.");
                    }
                }

                XdgAggregationBasis XB  = null;
                XdgAggregationBasis XBf = null;
                int[][,] spcIdxMap = null;
                SpeciesId[][] spc = null;
                //SpeciesId[][] spcf = null;
                for (int iVar = 0; iVar < NoOfVar; iVar++)
                {
                    if (useX[iVar])
                    {
                        XB        = (XdgAggregationBasis)(B[iVar]);
                        XBf       = (XdgAggregationBasis)(finerLevel.AggBasis[iVar]);
                        spcIdxMap = XB.SpeciesIndexMapping;
                        spc       = XB.AggCellsSpecies;
                        //spcf = XBf.AggCellsSpecies;
                        break;
                    }
                }

                int[] Np      = this.AggBasis[0].GetNp();
                int[] Np_fine = finerLevel.AggBasis[0].GetNp();



                // create matrix
                // =============

                // init retval
                var PrlgMtx = new BlockMsrMatrix(finerLevel, this);

                int[][] C2F     = this.AggGrid.jCellCoarse2jCellFine;
                int     JCoarse = this.AggGrid.iLogicalCells.NoOfLocalUpdatedCells;
                //Debug.Assert((JCoarse == C2F.Length) || ());
                for (int jc = 0; jc < JCoarse; jc++)  // loop over coarse cells...
                {
                    int[] AggCell = C2F[jc];
                    int   I       = AggCell.Length;

                    for (int iVar = 0; iVar < NoOfVar; iVar++)
                    {
                        int DgDeg  = DegreeS[iVar];
                        int DgDegF = DegreeSfine[iVar];
                        MultidimensionalArray Inj_iVar_jc = InjOp[iVar][jc];
                        Debug.Assert(Inj_iVar_jc.GetLength(0) == I);

                        bool useX_iVar = false;
                        if (useX[iVar])
                        {
                            if (spcIdxMap[jc] != null)
                            {
                                useX_iVar = true;
                            }
                        }


                        if (useX_iVar)
                        {
                            //throw new NotImplementedException("todo");

                            int NoOfSpc = XB.GetNoOfSpecies(jc);
                            int Np_col  = Np[DgDeg];
                            Debug.Assert(Np_col * NoOfSpc == B[iVar].GetLength(jc, DgDeg));

                            for (int iSpc = 0; iSpc < NoOfSpc; iSpc++)  // loop over species
                            {
                                SpeciesId spc_jc_i = spc[jc][iSpc];

                                int Col0 = this.GlobalUniqueIndex(iVar, jc, Np_col * iSpc);


                                for (int i = 0; i < I; i++)   // loop over finer cells
                                {
                                    int jf = AggCell[i];

                                    int iSpc_Row = XBf.GetSpeciesIndex(jf, spc_jc_i);
                                    if (iSpc_Row < 0)
                                    {
                                        // nothing to do
                                        continue;
                                    }

                                    int Np_row = Np_fine[DgDegF];
                                    Debug.Assert(Np_row * XBf.GetNoOfSpecies(jf) == finerLevel.AggBasis[iVar].GetLength(jf, DgDegF));

                                    int Row0 = finerLevel.GlobalUniqueIndex(iVar, jf, Np_row * iSpc_Row);

                                    //if(Row0 <= 12 &&  12 < Row0 + Np_row) {
                                    //    if(Col0 <= 3 && 3 < Col0 + Np_col) {
                                    //        Debugger.Break();
                                    //    }
                                    //}
                                    PrlgMtx.AccBlock(Row0, Col0, 1.0, Inj_iVar_jc.ExtractSubArrayShallow(new[] { i, 0, 0 }, new[] { i - 1, Np_row - 1, Np_col - 1 }));
                                }
                            }
                        }
                        else
                        {
                            // ++++++++++++++++++
                            // standard DG branch
                            // ++++++++++++++++++

                            int Np_col = Np[DgDeg];
                            Debug.Assert(Np_col == B[iVar].GetLength(jc, DgDeg));
                            int Col0 = this.GlobalUniqueIndex(iVar, jc, 0);

                            for (int i = 0; i < I; i++)  // loop over finer cells
                            {
                                int jf     = AggCell[i];
                                int Np_row = Np_fine[DgDegF];
                                Debug.Assert(Np_row == finerLevel.AggBasis[iVar].GetLength(jf, DgDegF));

                                int Row0 = finerLevel.GlobalUniqueIndex(iVar, jf, 0);

                                PrlgMtx.AccBlock(Row0, Col0, 1.0, Inj_iVar_jc.ExtractSubArrayShallow(new[] { i, 0, 0 }, new[] { i - 1, Np_row - 1, Np_col - 1 }));
                                //if(Row0 <= 12 &&  12 < Row0 + Np_row) {
                                //        if(Col0 <= 3 && 3 < Col0 + Np_col) {
                                //            Debugger.Break();
                                //        }
                                //    }
                            }
                        }
                    }
                }


                // return
                // ======

                return(PrlgMtx);
            }
        }
Exemplo n.º 21
0
        private static void ExtractBlock(int jCell,
                                         AggregationGridBasis basis, int[] Degrees,
                                         ChangeOfBasisConfig conf,
                                         int E, int[] _i0s, bool Sp2Full,
                                         BlockMsrMatrix MtxSp, ref MultidimensionalArray MtxFl)
        {
            int NN = conf.VarIndex.Sum(iVar => basis.GetLength(jCell, Degrees[iVar]));

            if (MtxFl == null || MtxFl.NoOfRows != NN)
            {
                Debug.Assert(Sp2Full == true);
                MtxFl = MultidimensionalArray.Create(NN, NN);
            }
            else
            {
                if (Sp2Full)
                {
                    MtxFl.Clear();
                }
            }

            if (!Sp2Full)
            {
                Debug.Assert(MtxSp != null);
            }


            int i0Rowloc = 0;

            for (int eRow = 0; eRow < E; eRow++)   // loop over variables in configuration
            {
                int i0Row   = _i0s[eRow];
                int iVarRow = conf.VarIndex[eRow];

                int NRow = basis.GetLength(jCell, Degrees[iVarRow]);

                int i0Colloc = 0;
                for (int eCol = 0; eCol < E; eCol++)   // loop over variables in configuration

                {
                    int i0Col   = _i0s[eCol];
                    int iVarCol = conf.VarIndex[eCol];

                    int NCol = basis.GetLength(jCell, Degrees[iVarCol]);

                    MultidimensionalArray MtxFl_blk;
                    if (i0Rowloc == 0 && NRow == MtxFl.GetLength(0) && i0Colloc == 0 && NCol == MtxFl.GetLength(1))
                    {
                        MtxFl_blk = MtxFl;
                    }
                    else
                    {
                        MtxFl_blk = MtxFl.ExtractSubArrayShallow(new[] { i0Rowloc, i0Colloc }, new[] { i0Rowloc + NRow - 1, i0Colloc + NCol - 1 });
                    }

                    /*
                     * for(int n_row = 0; n_row < NRow; n_row++) { // row loop...
                     *  for(int n_col = 0; n_col < NCol; n_col++) { // column loop...
                     *      if(Sp2Full) {
                     *          // copy from sparse to full
                     *          MtxFl[n_row + i0Rowloc, n_col + i0Colloc] = (MtxSp != null) ? ( MtxSp[n_row + i0Row, n_col + i0Col]) : (n_col == n_row ? 1.0 : 0.0);
                     *      } else {
                     *          // the other way around.
                     *          MtxSp[n_row + i0Row, n_col + i0Col] = MtxFl[n_row + i0Rowloc, n_col + i0Colloc];
                     *      }
                     *  }
                     * }
                     */

                    if (Sp2Full)
                    {
                        if (MtxSp != null)
                        {
                            MtxSp.ReadBlock(i0Row, i0Col, MtxFl_blk);
                        }
                        else
                        {
                            MtxFl_blk.AccEye(1.0);
                        }
                    }
                    else
                    {
#if DEBUG
                        Debug.Assert(MtxSp != null);
                        //for (int n_row = 0; n_row < NRow; n_row++) { // row loop...
                        //    for (int n_col = 0; n_col < NCol; n_col++) { // column loop...
                        //        Debug.Assert(MtxSp[n_row + i0Row, n_col + i0Col] == 0.0);
                        //    }
                        //}
#endif
                        MtxSp.AccBlock(i0Row, i0Col, 1.0, MtxFl_blk, 0.0);
                    }
#if DEBUG
                    for (int n_row = 0; n_row < NRow; n_row++)     // row loop...
                    {
                        for (int n_col = 0; n_col < NCol; n_col++) // column loop...
                        {
                            Debug.Assert(MtxFl[n_row + i0Rowloc, n_col + i0Colloc] == ((MtxSp != null) ? (MtxSp[n_row + i0Row, n_col + i0Col]) : (n_col == n_row ? 1.0 : 0.0)));
                        }
                    }
#endif


                    i0Colloc += NCol;
                }
                i0Rowloc += NRow;
            }
        }