コード例 #1
0
        public void Init(MultigridOperator op)
        {
            var M     = op.OperatorMatrix;
            var MgMap = op.Mapping;

            this.m_mgop = op;

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

            Mtx = M;
            int L = M.RowPartitioning.LocalLength;

            diag = new double[L];
            int i0 = Mtx.RowPartitioning.i0;

            for (int i = 0; i < L; i++)
            {
                diag[i] = Mtx[i0 + i, i0 + i];
            }
        }
コード例 #2
0
        /// <summary>
        /// defines the problem matrix
        /// </summary>
        public void Init(MultigridOperator op)
        {
            // init & check
            // ============

            this.m_MgOperator = op;
            //OpMatrix = op.OperatorMatrix;
            OpMatrix = new ilPSP.LinSolvers.monkey.CPU.RefMatrix(op.OperatorMatrix.ToMsrMatrix());
            var MgMap = op.Mapping;

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

            // init solver chain
            // =================
            if (SolverChain == null || SolverChain.Length <= 0)
            {
                throw new NotSupportedException("Illegal configuration.");
            }
            for (int i = 0; i < SolverChain.Length; i++)
            {
                SolverChain[i].Init(op);
            }
        }
コード例 #3
0
        /// <summary>
        /// Updating the <see cref="CurrentLin"/> -- operator;
        /// </summary>
        /// <param name="CurrentState">linearization point</param>
        /// <param name="HomotopyValue">
        /// <see cref="ISpatialOperator.CurrentHomotopyValue"/>
        /// </param>
        protected void UpdateLinearization(IEnumerable <DGField> CurrentState, double HomotopyValue)
        {
            if (!(this.ProblemMapping.BasisS.Count == CurrentState.Count()))
            {
                throw new ArgumentException("mismatch in number of fields.");
            }

            SetHomotopyValue(HomotopyValue);

            // the real call:
            this.m_AssembleMatrix(out BlockMsrMatrix OpMtxRaw, out double[] OpAffineRaw, out BlockMsrMatrix MassMtxRaw, CurrentState.ToArray(), true, out ISpatialOperator abstractOperator);
            AbstractOperator = abstractOperator;

            // blabla:
            CurrentLin = new MultigridOperator(this.m_AggBasisSeq, this.ProblemMapping,
                                               OpMtxRaw.CloneAs(), MassMtxRaw,
                                               this.m_MultigridOperatorConfig,
                                               AbstractOperator.DomainVar.Select(varName => AbstractOperator.FreeMeanValue[varName]).ToArray());

            OpAffineRaw = OpAffineRaw.CloneAs();
            if (this.RHSRaw != null)
            {
                OpAffineRaw.AccV(-1.0, this.RHSRaw);
            }
            if (LinearizationRHS == null || LinearizationRHS.Length != this.CurrentLin.Mapping.LocalLength)
            {
                LinearizationRHS = new double[this.CurrentLin.Mapping.LocalLength];
            }
            else
            {
                LinearizationRHS.ClearEntries();
            }
            CurrentLin.TransformRhsInto(OpAffineRaw, this.LinearizationRHS, true);
            this.LinearizationRHS.ScaleV(-1.0);
        }
コード例 #4
0
        /// <summary>
        /// Performs a mode decay analysis (<see cref="Waterfall(bool, int)"/>) on this solver.
        /// </summary>
        public static Plot2Ddata WaterfallAnalysis(ISolverWithCallback linearSolver, MultigridOperator mgOperator, BlockMsrMatrix MassMatrix)
        {
            int L = mgOperator.BaseGridProblemMapping.LocalLength;

            var RHS   = new double[L];
            var exSol = new double[L];

            ConvergenceObserver co = new ConvergenceObserver(mgOperator, MassMatrix, exSol);
            var bkup = linearSolver.IterationCallback;

            linearSolver.IterationCallback = co.IterationCallback;

            // use a random init for intial guess.
            Random rnd = new Random();

            double[] x0 = new double[L];
            for (int l = 0; l < L; l++)
            {
                x0[l] = rnd.NextDouble();
            }

            // execute solver
            linearSolver.Init(mgOperator);
            mgOperator.UseSolver(linearSolver, x0, RHS);

            // reset and return
            linearSolver.IterationCallback = bkup;
            //var p = co.PlotIterationTrend(true, false, true, true);
            var p = co.Waterfall(true, 100);

            return(p);
        }
コード例 #5
0
        public void ResItCallbackAtDownstep(int iter, double[] xI, double[] rI, MultigridOperator mgOp)
        {
            if (IsDownstep(mgOp.LevelIndex) || IsUpstep(mgOp.LevelIndex))
            {
                var      Ptr_mgOp = mgOp;
                int      iLevel   = mgOp.LevelIndex;
                double[] vec_i    = rI;

                CoordinateVector DecompVec = this.InitProblemDGFields("Res");

                for (int k = iLevel; k > 0; k--)
                {
                    double[] vec_i1 = new double[Ptr_mgOp.FinerLevel.Mapping.LocalLength];
                    Ptr_mgOp.Prolongate(1.0, vec_i1, 0.0, vec_i);
                    vec_i    = vec_i1;
                    Ptr_mgOp = Ptr_mgOp.FinerLevel;
                }

                Ptr_mgOp.TransformSolFrom(DecompVec, vec_i);
                //DecompVec.AccV(1, vec_i);

                string plotName = TecplotOut + "Res-decomp" + "." + Iterationcounter[3] + "." + ItWithinMGCycle();
                Tecplot.Tecplot.PlotFields(DecompVec.Mapping.Fields, plotName, 0.0, 3);
            }
        }
コード例 #6
0
        /// <summary>
        /// Updating the <see cref="CurrentLin"/> -- operator;
        /// </summary>
        /// <param name="CurrentState">linearization point</param>
        protected void UpdateLinearization(IEnumerable <DGField> CurrentState)
        {
            if (!(this.ProblemMapping.BasisS.Count == CurrentState.Count()))
            {
                throw new ArgumentException("mismatch in number of fields.");
            }

            BlockMsrMatrix OpMtxRaw, MassMtxRaw;

            double[] OpAffineRaw;
            this.m_AssembleMatrix(out OpMtxRaw, out OpAffineRaw, out MassMtxRaw, CurrentState.ToArray(), true);

            CurrentLin = new MultigridOperator(this.m_AggBasisSeq, this.ProblemMapping,
                                               OpMtxRaw.CloneAs(), MassMtxRaw,
                                               this.m_MultigridOperatorConfig);

            OpAffineRaw = OpAffineRaw.CloneAs();
            if (this.RHSRaw != null)
            {
                OpAffineRaw.AccV(-1.0, this.RHSRaw);
            }
            if (LinearizationRHS == null || LinearizationRHS.Length != this.CurrentLin.Mapping.LocalLength)
            {
                LinearizationRHS = new double[this.CurrentLin.Mapping.LocalLength];
            }
            else
            {
                LinearizationRHS.ClearEntries();
            }
            CurrentLin.TransformRhsInto(OpAffineRaw, this.LinearizationRHS);
            this.LinearizationRHS.ScaleV(-1.0);
        }
コード例 #7
0
        public void Init(MultigridOperator op)
        {
            int D = op.GridData.SpatialDimension;

            CodName = new string[] { "momX", "momY", "div", "constitutiveXX", "constitutiveXY", "constitutiveYY" };
            Params  = new string[] { "VelocityX_GradientX", "VelocityX_GradientY", "VelocityY_GradientX", "VelocityY_GradientY" };
            DomName = new string[] { "VelocityX", "VelocityY", "Pressure", "StressXX", "StressXY", "StressYY" };

            LocalOp = new SpatialOperator(DomName, Params, CodName, (A, B, C) => 4);

            LocalOp.EquationComponents["constitutiveXX"].Add(new LocalJacobiFlux()
            {
                m_component = 0, We = m_We
            });
            LocalOp.EquationComponents["constitutiveXY"].Add(new LocalJacobiFlux()
            {
                m_component = 1, We = m_We
            });
            LocalOp.EquationComponents["constitutiveYY"].Add(new LocalJacobiFlux()
            {
                m_component = 2, We = m_We
            });

            LocalOp.Commit();

            var   U0      = ((BoSSS.Foundation.CoordinateMapping)op.Mapping.ProblemMapping).Fields.GetSubVector(0, 2);
            Basis U0Basis = new Basis(op.Mapping.GridData, 0);

            VectorField <SinglePhaseField> VelocityXGradient = new VectorField <SinglePhaseField>(D, U0Basis, "VelocityX_Gradient", SinglePhaseField.Factory);
            VectorField <SinglePhaseField> VelocityYGradient = new VectorField <SinglePhaseField>(D, U0Basis, "VelocityY_Gradient", SinglePhaseField.Factory);

            VelocityXGradient.Clear();
            VelocityXGradient.GradientByFlux(1.0, U0[0]);
            VelocityYGradient.Clear();
            VelocityYGradient.GradientByFlux(1.0, U0[1]);

            var Parameters = ArrayTools.Cat <DGField>(VelocityXGradient, VelocityYGradient);

            LocalMatrix = LocalOp.ComputeMatrix(op.BaseGridProblemMapping, Parameters, op.BaseGridProblemMapping);

            ConstEqIdx = op.Mapping.ProblemMapping.GetSubvectorIndices(true, 3, 4, 5);

            P = (BlockMsrMatrix)op.MassMatrix.Clone();

            for (int i = ConstEqIdx[0]; i <= ConstEqIdx.Length; i++)
            {
                for (int j = ConstEqIdx[0]; j <= ConstEqIdx.Length; j++)
                {
                    if (LocalMatrix[i, j] != 0)
                    {
                        P[i, j] = LocalMatrix[i, j];
                    }
                }
            }

            LocalMatrix.SaveToTextFileSparse("LocalMatrix");
            op.MassMatrix.SaveToTextFileSparse("MassMatrix");
            P.SaveToTextFileSparse("PrecondMatrix");
        }
コード例 #8
0
        ilPSP.LinSolvers.monkey.CPU.RefMatrix m_Matrix; // im Moment schneller, ca 5X
        //BlockMsrMatrix m_Matrix;


        public void Init(MultigridOperator op)
        {
            using (new FuncTrace()) {
                var M     = op.OperatorMatrix;
                var MgMap = op.Mapping;
                this.m_MgOp = op;

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

                //this.m_Matrix = M;
                this.m_Matrix = new ilPSP.LinSolvers.monkey.CPU.RefMatrix(M.ToMsrMatrix());

                /*
                 * int n = m_Matrix.RowPartitioning.LocalLength;
                 * if(n > 50000) {
                 *  var _Matrix = new ilPSP.LinSolvers.monkey.CPU.RefMatrix(M.ToMsrMatrix());
                 *
                 *  double[] xTest = new double[n];
                 *  double[] bTest = new double[n];
                 *  Random r = new Random(123);
                 *  for(int i = 0; i < n; i++) {
                 *      xTest[i] = r.NextDouble();
                 *      bTest[i] = r.NextDouble();
                 *  }
                 *
                 *
                 *  double[] b1 = bTest.CloneAs();
                 *  double[] x1 = bTest.CloneAs();
                 *  Stopwatch monkey = new Stopwatch();
                 *  monkey.Start();
                 *  for (int i = 0; i < 100; i++)
                 *      _Matrix.SpMV(1.0, x1, -0.1, b1);
                 *  monkey.Stop();
                 *
                 *  double[] b2 = bTest.CloneAs();
                 *  double[] x2 = bTest.CloneAs();
                 *  Stopwatch block = new Stopwatch();
                 *  block.Start();
                 *  for (int i = 0; i < 100; i++)
                 *      m_Matrix.SpMV(1.0, x1, -0.1, b1);
                 *  block.Stop();
                 *
                 *  Console.WriteLine("SPMV monkey:    " + monkey.Elapsed.TotalSeconds);
                 *  Console.WriteLine("SPMV block MSR: " + block.Elapsed.TotalSeconds);
                 * }
                 */
                if (Precond != null)
                {
                    Precond.Init(op);
                }
            }
        }
コード例 #9
0
        public IList <double[]> OrthonormalMultigridDecomposition(double[] Vec, bool decompose = true)
        {
            // vector length on level 0
            int L0 = DecompositionOperator.Mapping.LocalLength;

            if (Vec.Length != L0)
            {
                throw new ArgumentException("Mismatch in vector length.", "Vec");
            }


            List <double[]> OrthoVecs = new List <double[]>();

            OrthoVecs.Add(Vec.CloneAs());

            double l2pow2_Vec = OrthoVecs[0].L2NormPow2().MPISum();

            MultigridOperator coarsest = null;

            for (var mgop = this.DecompositionOperator.CoarserLevel; mgop != null; mgop = mgop.CoarserLevel)
            {
                int L      = mgop.Mapping.LocalLength;
                int iLevel = mgop.LevelIndex;
                OrthoVecs.Add(new double[L]);

                mgop.Restrict(OrthoVecs[iLevel - 1], OrthoVecs[iLevel]);

                coarsest = mgop;
            }

            double Check_l2pow2_OrthoVecsTotal = 0.0;

            for (var mgop = this.DecompositionOperator.CoarserLevel; mgop != null; mgop = mgop.CoarserLevel)
            {
                int iLevel = mgop.LevelIndex;


                if (decompose)
                {
                    mgop.Prolongate(-1.0, OrthoVecs[iLevel - 1], 1.0, OrthoVecs[iLevel]);
                }


                coarsest = mgop;
            }
            foreach (double[] OrthoVec in OrthoVecs)
            {
                Check_l2pow2_OrthoVecsTotal += OrthoVec.L2NormPow2().MPISum();
            }

            // if the vectors are really orthonormal, their squared L2-norms must be additive!
            if (decompose && this.DecompositionOperator_IsOrthonormal)
            {
                Debug.Assert((Math.Abs(Check_l2pow2_OrthoVecsTotal - l2pow2_Vec) / l2pow2_Vec < 1.0e-8), "something wrong with orthonormal decomposition");
            }

            return(OrthoVecs);
        }
コード例 #10
0
        private void Setup(MultigridOperator muop, BlockMsrMatrix MassMatrix, double[] __ExactSolution)
        {
            if (__ExactSolution != null)
            {
                if (__ExactSolution.Length != muop.BaseGridProblemMapping.LocalLength)
                {
                    throw new ArgumentException();
                }
            }
            this.SolverOperator = muop;

            List <AggregationGridBasis[]> aggBasisSeq = new List <AggregationGridBasis[]>();

            for (var mo = muop; mo != null; mo = mo.CoarserLevel)
            {
                aggBasisSeq.Add(mo.Mapping.AggBasis);
            }

            this.ExactSolution = __ExactSolution;
            int[] Degrees = muop.BaseGridProblemMapping.BasisS.Select(b => b.Degree).ToArray();

            BlockMsrMatrix DummyOpMatrix = new BlockMsrMatrix(muop.BaseGridProblemMapping, muop.BaseGridProblemMapping);

            DummyOpMatrix.AccEyeSp(123);


            MultigridOperator.ChangeOfBasisConfig[][] config = new MultigridOperator.ChangeOfBasisConfig[1][];
            config[0] = new MultigridOperator.ChangeOfBasisConfig[muop.BaseGridProblemMapping.BasisS.Count];
            for (int iVar = 0; iVar < config[0].Length; iVar++)
            {
                config[0][iVar] = new MultigridOperator.ChangeOfBasisConfig()
                {
                    Degree   = Degrees[iVar],
                    mode     = MultigridOperator.Mode.IdMass_DropIndefinite,
                    VarIndex = new int[] { iVar }
                };
            }

            //this.DecompositionOperator = muop; this.DecompositionOperator_IsOrthonormal = false;
            this.DecompositionOperator = new MultigridOperator(aggBasisSeq, muop.BaseGridProblemMapping, DummyOpMatrix, MassMatrix, config);
            this.DecompositionOperator_IsOrthonormal = true;

            ResNormTrend = new Dictionary <Tuple <int, int, int>, List <double> >();
            ErrNormTrend = new Dictionary <Tuple <int, int, int>, List <double> >();
            for (var mgop = this.DecompositionOperator; mgop != null; mgop = mgop.CoarserLevel)
            {
                int[] _Degrees = mgop.Mapping.DgDegree;
                for (int iVar = 0; iVar < _Degrees.Length; iVar++)
                {
                    for (int p = 0; p <= _Degrees[iVar]; p++)
                    {
                        ResNormTrend.Add(new Tuple <int, int, int>(mgop.LevelIndex, iVar, p), new List <double>());
                        ErrNormTrend.Add(new Tuple <int, int, int>(mgop.LevelIndex, iVar, p), new List <double>());
                    }
                }
            }
        }
コード例 #11
0
        /// <summary>
        /// extract the Fields from the solution, Resample them equally spaced and ready to use in an fft
        /// </summary>
        private void Resample(int iterIndex, double[] currentSol, MultigridOperator Mgop, string component)
        {
            if (Mgop.GridData.SpatialDimension == 2 && Mgop.LevelIndex == 0)
            {
                MultidimensionalArray SamplePoints;

                GridData GD = (GridData)Mgop.Mapping.AggGrid.AncestorGrid;

                BoundingBox BB = GD.GlobalBoundingBox;

                double xDist       = BB.Max[0] - BB.Min[0];
                double yDist       = BB.Max[1] - BB.Min[1];
                double aspectRatio = xDist / yDist;

                MGViz     viz    = new MGViz(Mgop);
                DGField[] Fields = viz.ProlongateToDg(currentSol, "Error");

                for (int p = 0; p < Fields.Length; p++)
                {
                    var field = Fields[p];

                    int    DOF = field.DOFLocal;
                    double N   = Math.Sqrt(DOF);
                    int    Nx  = (int)Math.Round(Math.Sqrt(aspectRatio) * N);
                    int    Ny  = (int)Math.Round(1 / Math.Sqrt(aspectRatio) * N);

                    SamplePoints = MultidimensionalArray.Create(Ny, Nx);

                    for (int i = 0; i < Nx; i++)
                    {
                        MultidimensionalArray points = MultidimensionalArray.Create(Ny, 2);

                        for (int k = 0; k < Ny; k++)
                        {
                            points[k, 0] = BB.Min[0] + (i + 1) * xDist / (Nx + 1);
                            points[k, 1] = BB.Min[1] + (k + 1) * yDist / (Ny + 1);
                        }

                        List <DGField> fields = new List <DGField>();
                        fields.Add(field);

                        FieldEvaluation FE = new FieldEvaluation(GD);

                        MultidimensionalArray Result = MultidimensionalArray.Create(Ny, 1);

                        FE.Evaluate(1.0, fields, points, 1.0, Result);

                        SamplePoints.ExtractSubArrayShallow(-1, i).Acc(1.0, Result.ExtractSubArrayShallow(-1, 0));
                    }

                    SamplePoints.SaveToTextFile("ResampleFFT_lvl" + Mgop.LevelIndex + "_" + iterIndex + "_" + component + "_" + field.Identification + ".txt");
                }
            }
        }
コード例 #12
0
        public void Init(MultigridOperator op)
        {
            this.m_OpThisLevel = op;

            if (op.CoarserLevel == null)
            {
                throw new NotSupportedException("Multigrid algorithm cannot be used as a solver on the finest level.");
            }

            this.CoarserLevelSolver.Init(op.CoarserLevel);
        }
コード例 #13
0
        /// <summary>
        /// defines the problem matrix
        /// </summary>
        public void Init(MultigridOperator op)
        {
            this.m_MgOperator = op;
            var Mtx   = op.OperatorMatrix;
            var MgMap = op.Mapping;

            viz = new MGViz(op);

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

            MxxHistory.Clear();
            SolHistory.Clear();

            double Dim = MgMap.ProblemMapping.GridDat.SpatialDimension;

            // set operator
            // ============
            if (op.CoarserLevel == null)
            {
                throw new NotSupportedException("Multigrid algorithm cannot be used as a solver on the finest level.");
            }
            this.OpMatrix = Mtx;


            // initiate coarser level
            // ======================
            if (this.CoarserLevelSolver == null)
            {
                throw new NotSupportedException("Missing coarse level solver.");
            }
            this.CoarserLevelSolver.Init(op.CoarserLevel);


            // init smoother
            // =============
            if (PreSmoother != null)
            {
                PreSmoother.Init(op);
            }
            if (PostSmoother != null && !object.ReferenceEquals(PreSmoother, PostSmoother))
            {
                PostSmoother.Init(op);
            }
        }
コード例 #14
0
ファイル: LevelPmg.cs プロジェクト: rohitvuppala/BoSSS
        private void AssignXdgBlocksModification(SubBlockSelector sbs, MultigridOperator op, bool IsLowSelector)
        {
            var Filter = sbs.ModeFilter;
            Func <int, int, int, int, bool> Modification = delegate(int iCell, int iVar, int iSpec, int pDeg) {
                int NoOfSpec = op.Mapping.AggBasis[0].GetNoOfSpecies(iCell);
                if (NoOfSpec >= 2)
                {
                    return(IsLowSelector);
                }
                else
                {
                    return(Filter(iCell, iVar, iSpec, pDeg));
                }
            };

            sbs.ModeSelector(Modification);
        }
コード例 #15
0
ファイル: SparseSolver.cs プロジェクト: rieckmann/BoSSS
        public void Init(MultigridOperator op)
        {
            var Mtx   = op.OperatorMatrix;
            var MgMap = op.Mapping;

            m_MultigridOp = op;

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

            m_Mtx = Mtx;
        }
コード例 #16
0
 static public ISolverSmootherTemplate InitMultigridChain(MultigridOperator MgOp,
                                                          Func <int, ISolverSmootherTemplate> PreSmootherFactory,
                                                          Func <int, ISolverSmootherTemplate> PostSmootherFactory,
                                                          Action <int, ClassicMultigrid> ParamsSeter,
                                                          Func <ISolverSmootherTemplate> CoarsestSolverFactory) //
 {
     if (MgOp.CoarserLevel == null)
     {
         return(CoarsestSolverFactory());
     }
     else
     {
         var MgTop = new ClassicMultigrid();
         ParamsSeter(MgOp.LevelIndex, MgTop);
         MgTop.PreSmoother        = PreSmootherFactory(MgOp.LevelIndex);
         MgTop.PostSmoother       = PostSmootherFactory(MgOp.LevelIndex);
         MgTop.CoarserLevelSolver = InitMultigridChain(MgOp.CoarserLevel, PreSmootherFactory, PostSmootherFactory, ParamsSeter, CoarsestSolverFactory);
         return(MgTop);
     }
 }
コード例 #17
0
        public void Init(MultigridOperator op)
        {
            var M     = op.OperatorMatrix;
            var MgMap = op.Mapping;

            this.m_mgop = op;

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

            foreach (var pc in PrecondS)
            {
                pc.Init(m_mgop);
            }
        }
コード例 #18
0
        public void Init(MultigridOperator op)
        {
            var Mtx   = op.OperatorMatrix;
            var MgMap = op.Mapping;

            this.m_mgop = op;

            if (!Mtx.RowPartitioning.EqualsPartition(MgMap.Partitioning))
            {
                throw new ArgumentException("Row partitioning mismatch.");
            }
            if (!Mtx.ColPartition.EqualsPartition(MgMap.Partitioning))
            {
                throw new ArgumentException("Column partitioning mismatch.");
            }
            this.Matrix = Mtx;
            if (Precond != null)
            {
                Precond.Init(op);
            }
        }
コード例 #19
0
        static public ISolverSmootherTemplate InitMultigridChain(MultigridOperator MgOp,
                                                                 Action <int, SoftPCG> ParamsSeter,
                                                                 Func <ISolverSmootherTemplate> CoarsestSolverFactory)
        {
            //
            if (MgOp.CoarserLevel == null)
            {
                return(CoarsestSolverFactory());
            }
            else
            {
                var MgTop = new SoftPCG();
                ParamsSeter(MgOp.LevelIndex, MgTop);

                var R = new GenericRestriction();
                MgTop.Precond        = R;
                R.CoarserLevelSolver = InitMultigridChain(MgOp.CoarserLevel, ParamsSeter, CoarsestSolverFactory);

                return(MgTop);
            }
        }
コード例 #20
0
        /// <summary>
        /// Decomposition of some solution vector <paramref name="Solvec"/> into the different multigrid levels.
        /// </summary>
        public void PlotDecomposition <V>(V vec, string plotName)
            where V : IList <double> //
        {
            int L0 = this.DecompositionOperator.Mapping.LocalLength;

            double[] vec0 = new double[L0];
            this.DecompositionOperator.TransformSolInto(vec, vec0);
            var Decomp = this.OrthonormalMultigridDecomposition(vec0, false);

            List <DGField> DecompFields = new List <DGField>();

            MultigridOperator op = this.DecompositionOperator;

            for (int iLevel = 0; iLevel < Decomp.Count; iLevel++)
            {
                double[] vec_i = Decomp[iLevel];

                var DecompVec = this.InitProblemDGFields("Level" + iLevel);

                MultigridOperator opi = op;
                for (int k = iLevel; k > 0; k--)
                {
                    int      Lk1    = Decomp[k - 1].Length;
                    double[] vec_i1 = new double[Lk1];
                    opi.Prolongate(1.0, vec_i1, 0.0, vec_i);
                    vec_i = vec_i1;
                    opi   = opi.FinerLevel;
                }

                this.DecompositionOperator.TransformSolFrom(DecompVec, vec_i);

                DecompFields.AddRange(DecompVec.Mapping.Fields);

                op = op.CoarserLevel;
            }

            Tecplot.Tecplot.PlotFields(DecompFields, plotName, 0.0, 3);
        }
コード例 #21
0
        public double[] ProlongateToTop(double[] V)
        {
            int iLv = FindLevel(V.Length);

            MultigridOperator op_iLv = m_op.FinestLevel;

            for (int i = 0; i < iLv; i++)
            {
                op_iLv = op_iLv.CoarserLevel;
            }
            Debug.Assert(op_iLv.LevelIndex == iLv);
            Debug.Assert(V.Length == op_iLv.Mapping.LocalLength);

            double[] Curr = V;
            for (var Op4Level = op_iLv; Op4Level.FinerLevel != null; Op4Level = Op4Level.FinerLevel)
            {
                double[] Next = new double[Op4Level.FinerLevel.Mapping.LocalLength];
                Op4Level.Prolongate(1.0, Next, 0.0, Curr);
                Curr = Next;
            }

            return(Curr);
        }
コード例 #22
0
        /// <summary>
        /// Initialization of each multi-grid level
        /// </summary>
        public void Init(MultigridOperator op)
        {
            using (new FuncTrace()) {
                // checks
                // ======

                var M     = op.OperatorMatrix;
                var MgMap = op.Mapping;
                this.m_mgop = op;
                int MpiSize = M._RowPartitioning.MpiSize;

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

                // determine which levels to use
                // =============================
                {
                    var tempOp4Level = new List <MultigridOperator>();
                    var Op           = op;
                    do
                    {
                        tempOp4Level.Add(Op);
                        Op = Op.CoarserLevel;
                        if (Op == null)
                        {
                            break;
                        }
                    } while (tempOp4Level.Last().Mapping.TotalLength > LowestLevelDOFthreshold);
                    Op4Level = tempOp4Level.ToArray();

                    Mtx4Level = new BlockMsrMatrix[Op4Level.Length];
                    for (int i = 0; i < Mtx4Level.Length; i++)
                    {
                        Mtx4Level[i] = Op4Level[i].OperatorMatrix;
                    }
                }

                // define preconditioner's
                // =======================
                {
                    PrecondS = new ISolverSmootherTemplate[Op4Level.Length];

                    // all levels except the coarsest one
                    for (int i = 0; i < PrecondS.Length - 1; i++)
                    {
                        int NoOfBlocks = (int)Math.Ceiling((double)(Op4Level[i].Mapping.LocalLength) / (double)LowestLevelDOFthreshold);

                        // we want at least two blocks - otherwise we could use the direct solver directly.
                        if (MpiSize > 1)
                        {
                            // more than one MPI core -> at least one block per core -> globally at least 2 cores
                            NoOfBlocks = Math.Max(1, NoOfBlocks);
                        }
                        else
                        {
                            // singe MPI core -> at least two blocks
                            NoOfBlocks = Math.Max(2, NoOfBlocks);
                        }

                        PrecondS[i] = new Schwarz()
                        {
                            FixedNoOfIterations = 1,
                            CoarseSolver        = null,
                            m_BlockingStrategy  = new Schwarz.METISBlockingStrategy()
                            {
                                NoOfPartsPerProcess = NoOfBlocks
                            },
                            Overlap = 1
                        };
                    }

                    // coarsest level
                    PrecondS[PrecondS.Length - 1] = new DirectSolver()
                    {
                        WhichSolver  = DirectSolver._whichSolver.PARDISO,
                        TestSolution = false
                    };



                    // init each level
                    for (int i = 0; i < PrecondS.Length; i++)
                    {
                        PrecondS[i].Init(Op4Level[i]);
                    }
                }
            }
        }
コード例 #23
0
        /// <summary>
        /// defines the problem matrix
        /// </summary>
        public void Init(MultigridOperator op)
        {
            using (var tr = new FuncTrace()) {
                this.m_MgOperator = op;
                var Mtx   = op.OperatorMatrix;
                var MgMap = op.Mapping;
                //if(op.LevelIndex == 0)
                //    viz = new MGViz(op);

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

                MxxHistory.Clear();
                SolHistory.Clear();


                // set operator
                // ============
                this.OpMatrix = Mtx;


                // initiate coarser level
                // ======================
                if (this.CoarserLevelSolver == null)
                {
                    //throw new NotSupportedException("Missing coarse level solver.");
                    Console.WriteLine("OrthonormalizationMultigrid: running without coarse solver.");
                }
                else
                {
                    if (op.CoarserLevel != null)
                    {
                        this.CoarserLevelSolver.Init(op.CoarserLevel);
                        CoarseOnLovwerLevel = true;
                    }
                    else
                    {
                        Console.WriteLine("OrthonormalizationMultigrid: running coarse solver on same level.");
                        this.CoarserLevelSolver.Init(op);
                        CoarseOnLovwerLevel = false;
                    }
                }

                // init smoother
                // =============
                if (PreSmoother != null)
                {
                    PreSmoother.Init(op);
                }
                if (PostSmoother != null && !object.ReferenceEquals(PreSmoother, PostSmoother))
                {
                    PostSmoother.Init(op);
                }
            }
        }
コード例 #24
0
 /// <summary>
 /// Triggers <see cref="IterationCallback"/>.
 /// </summary>
 protected void OnIterationCallback(int iterIndex, double[] currentSol, double[] currentRes, MultigridOperator Mgop)
 {
     if (IterationCallback != null)
     {
         IterationCallback(iterIndex, currentSol, currentRes, Mgop);
     }
 }
コード例 #25
0
        public void Init(MultigridOperator op)
        {
            int D = op.GridData.SpatialDimension;

            CodName = (new string[] { "mom0", "mom1" });
            Params  = ArrayTools.Cat(
                VariableNames.Velocity0Vector(D));
            DomName = ArrayTools.Cat(VariableNames.VelocityVector(D));

            LocalOp = new SpatialOperator(DomName, Params, CodName, (A, B, C) => 4);

            for (int d = 0; d < D; d++)
            {
                LocalOp.EquationComponents["mom" + d].Add(new LocalDiffusiveFlux()
                {
                    m_component = d, dt = m_dt, muA = m_muA
                });
            }

            LocalOp.Commit();

            //LocalMatrix = op.MassMatrix.CloneAs().ToMsrMatrix();
            //LocalMatrix.Clear();

            //var U0 = new VectorField<SinglePhaseField>(op.BaseGridProblemMapping Take(D).Select(F => (SinglePhaseField)F).ToArray());

            UnsetteledCoordinateMapping test = new UnsetteledCoordinateMapping(op.BaseGridProblemMapping.BasisS.GetSubVector(0, D));

            var U0 = ((BoSSS.Foundation.CoordinateMapping)op.Mapping.ProblemMapping).Fields.GetSubVector(0, 2);

            var empty = new SinglePhaseField[D];

            LocalMatrix = LocalOp.ComputeMatrix(test, empty, test, time: m_dt);


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

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

            ConvDiff = null;                           // new BlockMsrMatrix(Upart, Upart, 1, 1);
            pGrad    = null;                           // new BlockMsrMatrix(Upart, Ppart, 1, 1);
            divVel   = null;                           // new BlockMsrMatrix(Ppart, Upart, 1, 1);
            BlockMsrMatrix VelocityMass        = null; // new BlockMsrMatrix(Upart, Upart, 1, 1);
            BlockMsrMatrix leftChangeBasesVel  = null; // new BlockMsrMatrix(Upart, Upart, 1, 1);
            BlockMsrMatrix rightChangeBasesVel = null; // new BlockMsrMatrix(Upart, Upart, 1, 1);

            op.MassMatrix.AccSubMatrixTo(1.0, VelocityMass, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[]));

            op.LeftChangeOfBasis.AccSubMatrixTo(1.0, leftChangeBasesVel, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[]));
            op.RightChangeOfBasis.AccSubMatrixTo(1.0, rightChangeBasesVel, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[]));

            var temp = BlockMsrMatrix.Multiply(leftChangeBasesVel, LocalMatrix);

            LocalMatrix = BlockMsrMatrix.Multiply(temp, rightChangeBasesVel);

            var M = op.OperatorMatrix;

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

            //LocalMatrix.SaveToTextFileSparse("LocalConvDiffMatrix");
            //ConvDiff.SaveToTextFileSparse("ConvDiff");
            //op.MassMatrix.SaveToTextFileSparse("MassMatrix");
            //VelocityMass.SaveToTextFileSparse("VelocityMass");
        }
コード例 #26
0
        public void Init(MultigridOperator op)
        {
            int D = op.Mapping.GridData.SpatialDimension;
            var M = op.OperatorMatrix;


            //M.SaveToTextFileSparse("OpMatrix2");

            var MgMap = op.Mapping;

            this.m_mgop = op;



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

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


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

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


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

            Mtx = M;

            int L = M.RowPartitioning.LocalLength;

            int i0 = Mtx.RowPartitioning.i0;

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

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


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

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

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

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

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


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

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

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

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

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


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

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

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

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

                return;
            }

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


            //var ConvDiffInvMtx = ConvDiffInv.ToMsrMatrix();


            //// x= inv(P)*b !!!!! To be done with approximate Inverse
            // P.SpMV(1, B, 0, X);
        }
コード例 #27
0
 public MGViz(MultigridOperator op)
 {
     m_op = op;
 }
コード例 #28
0
 public ConvergenceObserver(MultigridOperator muop, BlockMsrMatrix MassMatrix, double[] __ExactSolution, SolverFactory SF)
 {
     m_SF = SF;
     Setup(muop, MassMatrix, __ExactSolution);
 }
コード例 #29
0
 public ConvergenceObserver(MultigridOperator muop, BlockMsrMatrix MassMatrix, double[] __ExactSolution)
 {
     Setup(muop, MassMatrix, __ExactSolution);
 }
コード例 #30
0
        /// <summary>
        /// Callback routine, see <see cref="ISolverWithCallback.IterationCallback"/> or <see cref="NonlinearSolver.IterationCallback"/>.
        /// </summary>
        public void IterationCallback(int iter, double[] xI, double[] rI, MultigridOperator mgOp)
        {
            if (xI.Length != SolverOperator.Mapping.LocalLength)
            {
                throw new ArgumentException();
            }
            if (rI.Length != SolverOperator.Mapping.LocalLength)
            {
                throw new ArgumentException();
            }

            int Lorg = SolverOperator.BaseGridProblemMapping.LocalLength;

            // transform residual and solution back onto the orignal grid
            // ==========================================================

            double[] Res_Org = new double[Lorg];
            double[] Sol_Org = new double[Lorg];

            SolverOperator.TransformRhsFrom(Res_Org, rI);
            SolverOperator.TransformSolFrom(Sol_Org, xI);

            double[] Err_Org = Sol_Org.CloneAs();
            Err_Org.AccV(-1.0, this.ExactSolution);

            if (TecplotOut != null)
            {
                var ErrVec = InitProblemDGFields("Err");
                var ResVec = InitProblemDGFields("Res");
                var SolVec = InitProblemDGFields("Sol");

                ErrVec.SetV(Err_Org);
                ResVec.SetV(Res_Org);
                SolVec.SetV(Sol_Org);
                List <DGField> ErrResSol = new List <DGField>();
                ErrResSol.AddRange(ErrVec.Mapping.Fields);
                ErrResSol.AddRange(ResVec.Mapping.Fields);
                ErrResSol.AddRange(SolVec.Mapping.Fields);

                Tecplot.Tecplot.PlotFields(ErrResSol, TecplotOut + "." + iter, iter, 4);

                PlotDecomposition(xI, TecplotOut + "-sol-decomp." + iter);
                PlotDecomposition(rI, TecplotOut + "-res-decomp." + iter);
            }

            // Console out
            // ===========
            double l2_RES = rI.L2NormPow2().MPISum().Sqrt();
            double l2_ERR = Err_Org.L2NormPow2().MPISum().Sqrt();

            Console.WriteLine("Iter: {0}\tRes: {1:0.##E-00}\tErr: {2:0.##E-00}", iter, l2_RES, l2_ERR);


            // decompose error and residual into orthonormal vectors
            // =====================================================


            int L0 = DecompositionOperator.Mapping.LocalLength;

            double[] Err_0 = new double[L0], Res_0 = new double[L0];
            DecompositionOperator.TransformSolInto(Err_Org, Err_0);
            DecompositionOperator.TransformRhsInto(Res_Org, Res_0);

            IList <double[]> Err_OrthoLevels = OrthonormalMultigridDecomposition(Err_0);
            IList <double[]> Res_OrthoLevels = OrthonormalMultigridDecomposition(Res_0);


            // compute L2 norms on each level
            // ==============================
            for (var mgop = this.DecompositionOperator; mgop != null; mgop = mgop.CoarserLevel)
            {
                int[] _Degrees = mgop.Mapping.DgDegree;

                double[] Resi = Res_OrthoLevels[mgop.LevelIndex];
                double[] Errr = Err_OrthoLevels[mgop.LevelIndex];
                int      JAGG = mgop.Mapping.AggGrid.iLogicalCells.NoOfLocalUpdatedCells;


                for (int iVar = 0; iVar < _Degrees.Length; iVar++)
                {
                    for (int p = 0; p <= _Degrees[iVar]; p++)
                    {
                        List <double> ResNorm = this.ResNormTrend[new Tuple <int, int, int>(mgop.LevelIndex, iVar, p)];
                        List <double> ErrNorm = this.ErrNormTrend[new Tuple <int, int, int>(mgop.LevelIndex, iVar, p)];

                        double ResNormAcc = 0.0;
                        double ErrNormAcc = 0.0;

                        for (int jagg = 0; jagg < JAGG; jagg++)
                        {
                            int[] NN = mgop.Mapping.AggBasis[iVar].ModeIndexForDegree(jagg, p, _Degrees[iVar]);

                            foreach (int n in NN)
                            {
                                int idx = mgop.Mapping.LocalUniqueIndex(iVar, jagg, n);

                                ResNormAcc += Resi[idx].Pow2();
                                ErrNormAcc += Errr[idx].Pow2();
                            }
                        }

                        ResNorm.Add(ResNormAcc.Sqrt());
                        ErrNorm.Add(ErrNormAcc.Sqrt());
                    }
                }
            }
        }