Esempio n. 1
0
        override public void SolverDriver <S>(CoordinateVector SolutionVec, S RHS)
        {
            // initial guess and its residual
            // ==============================
            double[] Solution, Residual;
            base.Init(SolutionVec, RHS, out Solution, out Residual);
            double[] Correction     = new double[Solution.Length];
            double   ResidualNorm   = Residual.L2NormPow2().MPISum().Sqrt();
            int      NoOfIterations = 0;

            if (m_LinearSolver.GetType() == typeof(SoftGMRES))
            {
                ((SoftGMRES)m_LinearSolver).m_SessionPath = m_SessionPath;
            }

            OnIterationCallback(NoOfIterations, Solution.CloneAs(), Residual.CloneAs(), this.CurrentLin);

            if (LastIteration_Converged == null)
            {
                LastIteration_Converged = delegate(double ResNorm) {
                    return(ResNorm < ConvCrit);
                }
            }
            ;

            // iterate...
            // ==========
            while ((!LastIteration_Converged(ResidualNorm) && NoOfIterations < MaxIter) || (NoOfIterations < MinIter))
            {
                NoOfIterations++;

                //DirectSolver ds = new DirectSolver();
                //ds.Init(this.CurrentLin);
                //double L2_Res = Residual.L2Norm();
                this.m_LinearSolver.Init(this.CurrentLin);
                Correction.ClearEntries();
                if (Correction.Length != Residual.Length)
                {
                    Correction = new double[Residual.Length];
                }
                this.m_LinearSolver.Solve(Correction, Residual);

                // Residual may be invalid from now on...
                Solution.AccV(UnderRelax, Correction);

                // transform solution back to 'original domain'
                // to perform the linearization at the new point...
                // (and for Level-Set-Updates ...)
                this.CurrentLin.TransformSolFrom(SolutionVec, Solution);

                // update linearization
                base.Update(SolutionVec.Mapping.Fields, ref Solution);

                // residual evaluation & callback
                base.EvalResidual(Solution, ref Residual);
                ResidualNorm = Residual.L2NormPow2().MPISum().Sqrt();
                OnIterationCallback(NoOfIterations, Solution.CloneAs(), Residual.CloneAs(), this.CurrentLin);
            }
        }
    }
Esempio n. 2
0
        //bool solveVelocity = true;

        //double VelocitySolver_ConvergenceCriterion = 1e-5;

        //double StressSolver_ConvergenceCriterion = 1e-5;


        override public void SolverDriver <S>(CoordinateVector SolutionVec, S RHS)
        {
            using (var tr = new FuncTrace()) {
                // initial guess and its residual
                // ==============================
                double[] Solution, Residual;

                using (new BlockTrace("Slv Init", tr)) {
                    base.Init(SolutionVec, RHS, out Solution, out Residual);
                }
                double[] Correction     = new double[Solution.Length];
                double   ResidualNorm   = Residual.L2NormPow2().MPISum().Sqrt();
                int      NoOfIterations = 0;
                if (m_LinearSolver.GetType() == typeof(SoftGMRES))
                {
                    ((SoftGMRES)m_LinearSolver).m_SessionPath = m_SessionPath;
                }

                OnIterationCallback(NoOfIterations, Solution.CloneAs(), Residual.CloneAs(), this.CurrentLin);

                if (CoupledIteration_Converged == null)
                {
                    CoupledIteration_Converged = delegate() {
                        return(true);
                    }
                }
                ;

                int NoOfCoupledIteration = 0;
                if (Iteration_Count == null)
                {
                    Iteration_Count = delegate(int NoIter, ref int coupledIter) {
                        return(NoIter + 1);
                    }
                }
                ;

                //int[] Velocity_idx = SolutionVec.Mapping.GetSubvectorIndices(false, 0, 1, 2);
                //int[] Stresses_idx = SolutionVec.Mapping.GetSubvectorIndices(false, 3, 4, 5);

                //int[] Velocity_fields = new int[] { 0, 1, 2 };
                //int[] Stress_fields = new int[] { 3, 4, 5 };

                //int NoCoupledIterations = 10;

                // iterate...
                // ==========
                //int NoOfMainIterations = 0;
                using (new BlockTrace("Slv Iter", tr)) {
                    while ((!(ResidualNorm < ConvCrit && CoupledIteration_Converged()) && NoOfIterations < MaxIter && NoOfCoupledIteration < MaxCoupledIter) || (NoOfIterations < MinIter))
                    {
                        NoOfIterations = Iteration_Count(NoOfIterations, ref NoOfCoupledIteration);
                        //Console.WriteLine("NoOfIterations = {0}", NoOfIterations);

                        //DirectSolver ds = new DirectSolver();
                        //ds.Init(this.CurrentLin);
                        //double L2_Res = Residual.L2Norm();
                        this.m_LinearSolver.Init(this.CurrentLin);
                        Correction.ClearEntries();
                        if (Correction.Length != Residual.Length)
                        {
                            Correction = new double[Residual.Length];
                        }
                        this.m_LinearSolver.Solve(Correction, Residual);

                        //if (NoOfIterations > NoCoupledIterations)
                        //{
                        //    if (solveVelocity)
                        //    {
                        //        Console.WriteLine("stress correction = 0");
                        //        foreach (int idx in Stresses_idx)
                        //        {
                        //            Correction[idx] = 0.0;
                        //        }
                        //    }
                        //    else
                        //    {
                        //        Console.WriteLine("velocity correction = 0");
                        //        foreach (int idx in Velocity_idx)
                        //        {
                        //            Correction[idx] = 0.0;
                        //        }
                        //    }
                        //}

                        // Residual may be invalid from now on...
                        Solution.AccV(UnderRelax, Correction);

                        // transform solution back to 'original domain'
                        // to perform the linearization at the new point...
                        // (and for Level-Set-Updates ...)
                        this.CurrentLin.TransformSolFrom(SolutionVec, Solution);

                        // update linearization
                        base.Update(SolutionVec.Mapping.Fields, ref Solution);

                        // residual evaluation & callback
                        base.EvalResidual(Solution, ref Residual);
                        ResidualNorm = Residual.L2NormPow2().MPISum().Sqrt();

                        //if (NoOfIterations > NoCoupledIterations)
                        //{

                        //    double coupledL2Res = 0.0;
                        //    if (solveVelocity)
                        //    {
                        //        foreach (int idx in Velocity_idx)
                        //        {
                        //            coupledL2Res += Residual[idx].Pow2();
                        //        }
                        //    }
                        //    else
                        //    {
                        //        foreach (int idx in Stresses_idx)
                        //        {
                        //            coupledL2Res += Residual[idx].Pow2();
                        //        }
                        //    }
                        //    coupledL2Res = coupledL2Res.Sqrt();

                        //    Console.WriteLine("coupled residual = {0}", coupledL2Res);

                        //    if (solveVelocity && coupledL2Res < this.VelocitySolver_ConvergenceCriterion)
                        //    {
                        //        Console.WriteLine("SolveVelocity = false");
                        //        this.solveVelocity = false;
                        //    }
                        //    else if (!solveVelocity && coupledL2Res < this.StressSolver_ConvergenceCriterion)
                        //    {
                        //        Console.WriteLine("SolveVelocity = true");
                        //        this.solveVelocity = true;
                        //    }
                        //}

                        OnIterationCallback(NoOfIterations, Solution.CloneAs(), Residual.CloneAs(), this.CurrentLin);
                    }
                }
            }
        }
    }
}