public void Solve <U, V>(U X, V B) where U : IList <double> where V : IList <double> { //using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) { // solver.DefineMatrix(P); // solver.Solve(X, B); //} switch (SchurOpt) { case SchurOptions.exact: { // Directly invert Preconditioning Matrix using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) { solver.DefineMatrix(P); solver.Solve(X, B); } return; } case SchurOptions.decoupledApprox: { SolveSubproblems(X, B); return; } case SchurOptions.SIMPLE: { SolveSIMPLE(X, B); return; } } }
/// <summary> /// Solve with a SIMPLE like approcation of the Schur complement /// </summary> /// <typeparam name="U"></typeparam> /// <typeparam name="V"></typeparam> /// <param name="X"></param> /// <param name="B"></param> public void SolveSIMPLE <U, V>(U X, V B) where U : IList <double> where V : IList <double> { var Bu = new double[Uidx.Length]; var Xu = Bu.CloneAs(); // For MPI var idxU = Uidx[0]; for (int i = 0; i < Uidx.Length; i++) { Uidx[i] -= idxU; } var idxP = Pidx[0]; for (int i = 0; i < Pidx.Length; i++) { Pidx[i] -= idxP; } Bu = B.GetSubVector(Uidx, default(int[])); var Bp = new double[Pidx.Length]; var Xp = Bp.CloneAs(); Bp = B.GetSubVector(Pidx, default(int[])); Xu = X.GetSubVector(Uidx, default(int[])); Xp = X.GetSubVector(Pidx, default(int[])); // Solve SIMPLE Schur using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) { solver.DefineMatrix(simpleSchur); solver.Solve(Xp, Bp); } // Solve ConvDiff*w=v-q*pGrad pGrad.SpMVpara(-1, Xp, 1, Bu); using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) { solver.DefineMatrix(ConvDiff); solver.Solve(Xu, Bu); } var temp = new double[Uidx.Length + Pidx.Length]; for (int i = 0; i < Uidx.Length; i++) { temp[Uidx[i]] = Xu[i]; } for (int i = 0; i < Pidx.Length; i++) { temp[Pidx[i]] = Xp[i]; } X.SetV(temp); }
public void Solve <U, V>(U X, V B) where U : IList <double> where V : IList <double> { using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) { solver.DefineMatrix(P); solver.Solve(X, B); } m_ThisLevelIterations++; }
/// <summary> /// Solves a linear system using a direct solver. /// </summary> /// <param name="Matrix">the matrix of the linear problem.</param> /// <param name="X">Output, (hopefully) the solution.</param> /// <param name="B">Input, the right-hand-side.</param> /// <returns>Actual number of iterations.</returns> static public void Solve_Direct <V, W>(this IMutableMatrixEx Matrix, V X, W B) where V : IList <double> where W : IList <double> // { /* * using (var slv = new ilPSP.LinSolvers.PARDISO.PARDISOSolver()) { * slv.DefineMatrix(Matrix); * var SolRes = slv.Solve(X, B.ToArray()); * } */ using (var slv = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) { slv.DefineMatrix(Matrix); var SolRes = slv.Solve(X, B.ToArray()); } }
/// <summary> /// Condition number estimate by MUMPS; Rem.: MUMPS manual does not tell in which norm; it does not seem to be as reliable as MATLAB condest /// </summary> public static double Condest_MUMPS(this IMutableMatrixEx Mtx) { using (new FuncTrace()) { using (var slv = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) { slv.Statistics = MUMPS.MUMPSStatistics.AllStatistics; slv.DefineMatrix(Mtx); double[] dummyRHS = new double[Mtx.RowPartitioning.LocalLength]; double[] dummySol = new double[dummyRHS.Length]; dummyRHS.SetAll(1.11); slv.Solve(dummySol, dummyRHS); return(slv.LastCondNo); } } }
/// <summary> /// Approximate the inverse of the Schur matrix and perform two Poisson solves and Matrix-Vector products. Finite elements and Fast Iterative Solvers p.383 /// </summary> public void ApproxAndSolveSchur <U, V>(U Xp, V Bp) where U : IList <double> where V : IList <double> { var temp = new double[Xp.Count]; var sol = new double[pGrad.RowPartitioning.LocalLength]; // Poisson solve using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) { solver.DefineMatrix(PoissonMtx_T); solver.Solve(temp, Bp); } // Schur Convective part with scaling pGrad.SpMVpara(1, temp, 0, sol); temp = sol.ToArray(); sol.Clear(); invVelMassMatrix.SpMVpara(1, temp, 0, sol); temp = sol.ToArray(); sol.Clear(); ConvDiff.SpMVpara(1, temp, 0, sol); temp = sol.ToArray(); sol.Clear(); invVelMassMatrixSqrt.SpMVpara(1, temp, 0, sol); temp = sol.ToArray(); divVel.SpMVpara(1, temp, 0, Xp); // Poisson solve using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) { solver.DefineMatrix(PoissonMtx_H); solver.Solve(Xp, Xp); } }
public void Solve <U, V>(U X, V B) where U : IList <double> where V : IList <double> { var Bu = new double[Uidx.Length]; var Xu = Bu.CloneAs(); Bu = B.GetSubVector(Uidx, default(int[])); var Bp = new double[Pidx.Length]; var Xp = Bp.CloneAs(); Bp = B.GetSubVector(Pidx, default(int[])); Xu = X.GetSubVector(Uidx, default(int[])); Xp = X.GetSubVector(Pidx, default(int[])); P = new BlockMsrMatrix(null, null);// Pidx.Length, Pidx.Length); // MultidimensionalArray Schur = MultidimensionalArray.Create(Pidx.Length, Pidx.Length); using (BatchmodeConnector bmc = new BatchmodeConnector()) { bmc.PutSparseMatrix(LocalMatrix, "LocalMatrix"); bmc.PutSparseMatrix(divVel, "divVel"); bmc.PutSparseMatrix(pGrad, "pGrad"); bmc.Cmd("invLocalMatrix = inv(full(LocalMatrix))"); bmc.Cmd("Poisson = invLocalMatrix*pGrad"); bmc.Cmd("Schur= divVel*Poisson"); bmc.GetMatrix(Schur, "Schur"); bmc.Execute(false); } P = null; // Schur.ToMsrMatrix(); //P.SaveToTextFileSparse("LocalSchur"); using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) { solver.DefineMatrix(P); solver.Solve(Xp, Bp); } //var temp2 = Xp.CloneAs(); //LocalMatrix.SpMV(1, Xp, 0, temp2); //using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) //{ // solver.DefineMatrix(divVel); // solver.Solve(Xp, temp2); //} // Solve ConvD iff*w=v-q*pGrad pGrad.SpMV(-1, Xp, 1, Bu); using (var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) { solver.DefineMatrix(ConvDiff); solver.Solve(Xu, Bu); } var temp = new double[Uidx.Length + Pidx.Length]; for (int i = 0; i < Uidx.Length; i++) { temp[Uidx[i]] = Xu[i]; } for (int i = 0; i < Pidx.Length; i++) { temp[Pidx[i]] = Xp[i]; } X.SetV(temp); m_ThisLevelIterations++; }
public override void SolverDriver <S>(CoordinateVector SolutionVec, S RHS) { using (var tr = new FuncTrace()) { m_SolutionVec = SolutionVec; int itc; itc = 0; double[] x, xt, xOld, f0, deltaX, ft; double rat; double alpha = 1E-4, sigma0 = 0.1, sigma1 = 0.5, maxarm = 20, gamma = 0.9; // Eval_F0 base.Init(SolutionVec, RHS, out x, out f0); Console.WriteLine("Residual base.init: " + f0.L2NormPow2().MPISum().Sqrt()); deltaX = new double[x.Length]; xt = new double[x.Length]; ft = new double[x.Length]; this.CurrentLin.TransformSolFrom(SolutionVec, x); base.EvalResidual(x, ref f0); // fnorm double fnorm = f0.L2NormPow2().MPISum().Sqrt(); double fNormo = 1; double errstep; double[] step = new double[x.Length]; double[] stepOld = new double[x.Length]; MsrMatrix CurrentJac; Console.WriteLine("Start residuum for nonlinear iteration: " + fnorm); OnIterationCallback(itc, x.CloneAs(), f0.CloneAs(), this.CurrentLin); while (fnorm > ConvCrit && itc < MaxIter) { rat = fnorm / fNormo; fNormo = fnorm; itc++; // How should the inverse of the Jacobian be approximated? if (ApproxJac == ApproxInvJacobianOptions.GMRES) { CurrentJac = new MsrMatrix(x.Length); if (Precond != null) { Precond.Init(CurrentLin); } step = Krylov(SolutionVec, x, f0, out errstep); } else if (ApproxJac == ApproxInvJacobianOptions.DirectSolver) { CurrentJac = diffjac(SolutionVec, x, f0); var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver(); solver.DefineMatrix(CurrentJac); step.ClearEntries(); solver.Solve(step, f0); } else { throw new NotImplementedException("Your approximation option for the jacobian seems not to be existent."); } // Start line search xOld = x; double lambda = 1; double lamm = 1; double lamc = lambda; double iarm = 0; xt = x.CloneAs(); xt.AccV(lambda, step); this.CurrentLin.TransformSolFrom(SolutionVec, xt); EvaluateOperator(1, SolutionVec.Mapping.Fields, ft); var nft = ft.L2NormPow2().MPISum().Sqrt(); var nf0 = f0.L2NormPow2().MPISum().Sqrt(); var ff0 = nf0 * nf0; var ffc = nft * nft; var ffm = nft * nft; // Control of the the step size while (nft >= (1 - alpha * lambda) * nf0 && iarm < maxStep) { // Line search starts here if (iarm == 0) { lambda = sigma1 * lambda; } else { lambda = parab3p(lamc, lamm, ff0, ffc, ffm); } // Update x; xt = x.CloneAs(); xt.AccV(lambda, step); lamm = lamc; lamc = lambda; this.CurrentLin.TransformSolFrom(SolutionVec, xt); EvaluateOperator(1, SolutionVec.Mapping.Fields, ft); nft = ft.L2NormPow2().MPISum().Sqrt(); ffm = ffc; ffc = nft * nft; iarm++; #if DEBUG Console.WriteLine("Step size: " + lambda + "with Residuum: " + nft); #endif } // transform solution back to 'original domain' // to perform the linearization at the new point... // (and for Level-Set-Updates ...) this.CurrentLin.TransformSolFrom(SolutionVec, xt); // update linearization base.Update(SolutionVec.Mapping.Fields, ref xt); // residual evaluation & callback base.EvalResidual(xt, ref ft); // EvaluateOperator(1, SolutionVec.Mapping.Fields, ft); //base.Init(SolutionVec, RHS, out x, out f0); fnorm = ft.L2NormPow2().MPISum().Sqrt(); x = xt; f0 = ft.CloneAs(); OnIterationCallback(itc, x.CloneAs(), f0.CloneAs(), this.CurrentLin); } SolutionVec = m_SolutionVec; } }
public override void SolverDriver <S>(CoordinateVector SolutionVec, S RHS) { using (var tr = new FuncTrace()) { m_SolutionVec = SolutionVec; int itc; itc = 0; double[] x, xt, xOld, f0, deltaX, ft; double rat; double alpha = 1E-4, sigma0 = 0.1, sigma1 = 0.5, maxarm = 20, gamma = 0.9; // Eval_F0 using (new BlockTrace("Slv Init", tr)) { base.Init(SolutionVec, RHS, out x, out f0); }; Console.WriteLine("Residual base.init: " + f0.L2NormPow2().MPISum().Sqrt()); deltaX = new double[x.Length]; xt = new double[x.Length]; ft = new double[x.Length]; this.CurrentLin.TransformSolFrom(SolutionVec, x); base.EvalResidual(x, ref f0); // fnorm double fnorm = f0.L2NormPow2().MPISum().Sqrt(); double fNormo = 1; double errstep; double[] step = new double[x.Length]; double[] stepOld = new double[x.Length]; MsrMatrix CurrentJac; Console.WriteLine("Start residuum for nonlinear iteration: " + fnorm); OnIterationCallback(itc, x.CloneAs(), f0.CloneAs(), this.CurrentLin); //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 = 1; using (new BlockTrace("Slv Iter", tr)) { while (fnorm > ConvCrit && itc < MaxIter) { rat = fnorm / fNormo; fNormo = fnorm; itc++; // How should the inverse of the Jacobian be approximated? if (ApproxJac == ApproxInvJacobianOptions.GMRES) { CurrentJac = new MsrMatrix(x.Length); if (Precond != null) { Precond.Init(CurrentLin); } step = Krylov(SolutionVec, x, f0, out errstep); } else if (ApproxJac == ApproxInvJacobianOptions.DirectSolver) { CurrentJac = diffjac(SolutionVec, x, f0); CurrentJac.SaveToTextFileSparse("Jacobi"); CurrentLin.OperatorMatrix.SaveToTextFileSparse("OpMatrix"); var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver(); solver.DefineMatrix(CurrentJac); step.ClearEntries(); solver.Solve(step, f0); } else if (ApproxJac == ApproxInvJacobianOptions.DirectSolverHybrid) { //EXPERIMENTAL_____________________________________________________________________ MultidimensionalArray OpMatrixMatl = MultidimensionalArray.Create(x.Length, x.Length); CurrentJac = diffjac(SolutionVec, x, f0); //Console.WriteLine("Calling MATLAB/Octave..."); using (BatchmodeConnector bmc = new BatchmodeConnector()) { bmc.PutSparseMatrix(CurrentJac, "Jacobi"); bmc.PutSparseMatrix(CurrentLin.OperatorMatrix, "OpMatrix"); bmc.Cmd("Jacobi(abs(Jacobi) < 10^-6)=0; dim = length(OpMatrix);"); bmc.Cmd("dim = length(OpMatrix);"); bmc.Cmd(@"for i=1:dim if (i >= 16) && (i <= 33) && (i + 6 <= 33) && (i + 12 <= 33) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 49) && (i <= 66) && (i + 6 <= 66) && (i + 12 <= 66) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 82) && (i <= 99) && (i + 6 <= 99) && (i + 12 <= 99) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 115) && (i <= 132) && (i + 6 <= 132) && (i + 12 <= 132) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 148) && (i <= 165) && (i + 6 <= 165) && (i + 12 <= 165) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 181) && (i <= 198) && (i + 6 <= 198) && (i + 12 <= 198) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 214) && (i <= 231) && (i + 6 <= 231) && (i + 12 <= 231) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 247) && (i <= 264) && (i + 6 <= 264) && (i + 12 <= 264) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 280) && (i <= 297) && (i + 6 <= 297) && (i + 12 <= 297) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 313) && (i <= 330) && (i + 6 <= 330) && (i + 12 <= 330) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 346) && (i <= 363) && (i + 6 <= 363) && (i + 12 <= 363) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 379) && (i <= 396) && (i + 6 <= 396) && (i + 12 <= 396) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 412) && (i <= 429) && (i + 6 <= 429) && (i + 12 <= 429) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 445) && (i <= 462) && (i + 6 <= 462) && (i + 12 <= 462) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 478) && (i <= 495) && (i + 6 <= 495) && (i + 12 <= 495) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end if (i >= 511) && (i <= 528) && (i + 6 <= 528) && (i + 12 <= 528) OpMatrix(i, i) = Jacobi(i, i); OpMatrix(i, i + 6) = Jacobi(i, i + 6); OpMatrix(i + 6, i) = Jacobi(i + 6, i); OpMatrix(i + 12, i + 6) = Jacobi(i + 12, i + 6); OpMatrix(i + 6, i + 12) = Jacobi(i + 6, i + 12); end end"); bmc.Cmd("OpMatrix = full(OpMatrix)"); bmc.GetMatrix(OpMatrixMatl, "OpMatrix"); bmc.Execute(false); } MsrMatrix OpMatrix = OpMatrixMatl.ToMsrMatrix(); var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver(); //Console.WriteLine("USING HIGH EXPERIMENTAL OPMATRIX WITH JAC! only for p=1, GridLevel=2"); solver.DefineMatrix(OpMatrix); //______________________________________________________________________________________________________ step.ClearEntries(); solver.Solve(step, f0); } else if (ApproxJac == ApproxInvJacobianOptions.DirectSolverOpMatrix) { CurrentJac = new MsrMatrix(x.Length); CurrentJac = CurrentLin.OperatorMatrix.ToMsrMatrix(); var solver = new ilPSP.LinSolvers.MUMPS.MUMPSSolver(); solver.DefineMatrix(CurrentJac); step.ClearEntries(); solver.Solve(step, f0); } else { throw new NotImplementedException("Your approximation option for the jacobian seems not to be existent."); } //if (itc > NoCoupledIterations) //{ // if (solveVelocity) // { // Console.WriteLine("stress correction = 0"); // foreach (int idx in Stresses_idx) // { // step[idx] = 0.0; // } // } // else // { // Console.WriteLine("velocity correction = 0"); // foreach (int idx in Velocity_idx) // { // step[idx] = 0.0; // } // } //} // Start line search xOld = x; double lambda = 1; double lamm = 1; double lamc = lambda; double iarm = 0; xt = x.CloneAs(); xt.AccV(lambda, step); this.CurrentLin.TransformSolFrom(SolutionVec, xt); EvaluateOperator(1, SolutionVec.Mapping.Fields, ft); var nft = ft.L2NormPow2().MPISum().Sqrt(); var nf0 = f0.L2NormPow2().MPISum().Sqrt(); var ff0 = nf0 * nf0; var ffc = nft * nft; var ffm = nft * nft; // Control of the the step size while (nft >= (1 - alpha * lambda) * nf0 && iarm < maxStep) { // Line search starts here if (iarm == 0) { lambda = sigma1 * lambda; } else { lambda = parab3p(lamc, lamm, ff0, ffc, ffm); } // Update x; xt = x.CloneAs(); xt.AccV(lambda, step); lamm = lamc; lamc = lambda; this.CurrentLin.TransformSolFrom(SolutionVec, xt); EvaluateOperator(1, SolutionVec.Mapping.Fields, ft); nft = ft.L2NormPow2().MPISum().Sqrt(); ffm = ffc; ffc = nft * nft; iarm++; #if DEBUG Console.WriteLine("Step size: " + lambda + "with Residuum: " + nft); #endif } // transform solution back to 'original domain' // to perform the linearization at the new point... // (and for Level-Set-Updates ...) this.CurrentLin.TransformSolFrom(SolutionVec, xt); // update linearization base.Update(SolutionVec.Mapping.Fields, ref xt); // residual evaluation & callback base.EvalResidual(xt, ref ft); // EvaluateOperator(1, SolutionVec.Mapping.Fields, ft); //base.Init(SolutionVec, RHS, out x, out f0); fnorm = ft.L2NormPow2().MPISum().Sqrt(); x = xt; f0 = ft.CloneAs(); //if (itc > NoCoupledIterations) //{ // double coupledL2Res = 0.0; // if (solveVelocity) // { // foreach (int idx in Velocity_idx) // { // coupledL2Res += f0[idx].Pow2(); // } // } // else // { // foreach (int idx in Stresses_idx) // { // coupledL2Res += f0[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(itc, x.CloneAs(), f0.CloneAs(), this.CurrentLin); } } SolutionVec = m_SolutionVec; } }