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); } }
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; } }
//bool solveVelocity = true; //double VelocitySolver_ConvergenceCriterion = 1e-5; //double StressSolver_ConvergenceCriterion = 1e-5; 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; //double sigma0 = 0.1; double sigma1 = 0.5; //double maxarm = 20; //double 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); EvaluateOperator(1, SolutionVec.Mapping.ToArray(), f0); Console.WriteLine("Residual base.init: " + f0.L2NormPow2().MPISum().Sqrt()); //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]; //BlockMsrMatrix CurrentJac; OnIterationCallback(itc, x.CloneAs(), f0.CloneAs(), this.CurrentLin); using (new BlockTrace("Slv Iter", tr)) { while ((fnorm > ConvCrit * fNormo * 0 + ConvCrit && itc < MaxIter) || itc < MinIter) { rat = fnorm / fNormo; fNormo = fnorm; itc++; // How should the inverse of the Jacobian be approximated? if (ApproxJac == ApproxInvJacobianOptions.GMRES) { if (Precond != null) { Precond.Init(CurrentLin); } //base.EvalResidual(x, ref f0); f0.ScaleV(-1.0); step = Krylov(SolutionVec, x, f0, out errstep); } else if (ApproxJac == ApproxInvJacobianOptions.DirectSolver) { /* * double[] _step = step.ToArray(); * double[] _f0 = f0.ToArray(); * double _check_norm; * { * var CurrentJac = CurrentLin.OperatorMatrix; * var _solver = new ilPSP.LinSolvers.PARDISO.PARDISOSolver(); // .MUMPS.MUMPSSolver(); * _solver.DefineMatrix(CurrentJac); * _step.ClearEntries(); * var _check = _f0.CloneAs(); * _f0.ScaleV(-1.0); * _solver.Solve(_step, _f0); * * CurrentLin.OperatorMatrix.SpMV(-1.0, _step, -1.0, _check); * _check_norm = _check.L2Norm(); * } */ var solver = linsolver; //var mgo = new MultigridOperator(m_AggBasisSeq, SolutionVec.Mapping, CurrentJac, null, m_MultigridOperatorConfig); solver.Init(CurrentLin); step.ClearEntries(); var check = f0.CloneAs(); f0.ScaleV(-1.0); solver.ResetStat(); solver.Solve(step, f0); /* * double check_norm; * { * CurrentLin.OperatorMatrix.SpMV(-1.0, step, -1.0, check); * check_norm = check.L2Norm(); * } * * * double dist = GenericBlas.L2Dist(step, _step); * * * Console.WriteLine(" conv: " + solver.Converged + " /iter = " + solver.ThisLevelIterations + " /dist = " + dist + " /resNrm = " + check_norm + " /parresNrm = " + _check_norm); */ //step.SetV(step); //if (solver.Converged == false) // Debugger.Launch(); } 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); double nft = ft.L2NormPow2().MPISum().Sqrt(); double nf0 = f0.L2NormPow2().MPISum().Sqrt(); double ff0 = nf0 * nf0; double ffc = nft * nft; double ffm = nft * nft; // Console.WriteLine(" Residuum 0:" + nf0); // 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(" Residuum: " + nft + " lambda = " + lambda); #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 if (itc % constant_newton_it == 0) { base.Update(SolutionVec.Mapping.Fields, ref xt); if (constant_newton_it != 1) { Console.WriteLine("Jacobian is updated: it {0}", itc); } } // residual evaluation & callback base.EvalResidual(xt, ref ft); EvaluateOperator(1, SolutionVec.Mapping.Fields, ft); 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; } }