Пример #1
0
        /// <summary>
        /// Updating the <see cref="CurrentLin"/> -- operator;
        /// </summary>
        /// <param name="CurrentState">linearization point</param>
        protected void Update(IEnumerable <DGField> CurrentState)
        {
            if (!(this.ProblemMapping.BasisS.Count == CurrentState.Count()))
            {
                throw new ArgumentException("missmatch in number of fields.");
            }

            BlockMsrMatrix OpMtxRaw, MassMtxRaw;

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

            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);
        }
Пример #2
0
        /// <summary>
        /// Evaluation of the nonlinear operator.
        /// </summary>
        /// <param name="alpha"></param>
        /// <param name="CurrentState">
        /// Current state of DG fields
        /// </param>
        /// <param name="beta">
        /// Pre-scaling of <paramref name="Output"/>.
        /// </param>
        /// <param name="Output"></param>
        protected void EvaluateOperator(double alpha, IEnumerable <DGField> CurrentState, double[] Output)
        {
            BlockMsrMatrix OpMtxRaw, MassMtxRaw;

            double[] OpAffineRaw;
            this.m_AssembleMatrix(out OpMtxRaw, out OpAffineRaw, out MassMtxRaw, CurrentState.ToArray(), false);
            Debug.Assert(OpMtxRaw == null);

            CurrentLin.TransformRhsInto(OpAffineRaw, Output);
        }
Пример #3
0
        /// <summary>
        /// Evaluation of the nonlinear operator.
        /// </summary>
        /// <param name="alpha"></param>
        /// <param name="CurrentState">
        /// Current state of DG fields
        /// </param>
        /// <param name="beta">
        /// Pre-scaling of <paramref name="Output"/>.
        /// </param>
        /// <param name="Output"></param>
        protected void EvaluateOperator(double alpha, IEnumerable <DGField> CurrentState, double[] Output)
        {
            BlockMsrMatrix OpMtxRaw, MassMtxRaw;

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

            OpMtxRaw.SpMV(alpha, new CoordinateVector(CurrentState.ToArray()), 1.0, OpAffineRaw);

            CurrentLin.TransformRhsInto(OpAffineRaw, Output);
        }
Пример #4
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);
            }


            // 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());
                    }
                }
            }
        }