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