bool NoxSolver<Scalar>::solve(Scalar* coeff_vec) { // Put the initial coeff_vec into the inner structure for the initial guess. /// \todo Put this into a separate method. Hermes::Algebra::EpetraVector<Scalar> temp_init_sln; temp_init_sln.alloc(this->dp->get_num_dofs()); for (int i = 0; i < this->dp->get_num_dofs(); i++) temp_init_sln.set(i, coeff_vec[i]); NOX::Epetra::Vector init_sln(*temp_init_sln.vec); // Create the top level parameter list Teuchos::RCP<Teuchos::ParameterList> nl_pars_ptr = Teuchos::rcp(new Teuchos::ParameterList); Teuchos::ParameterList &nl_pars = *nl_pars_ptr.get(); // Set the nonlinear solver method nl_pars.set("Nonlinear Solver", "Line Search Based"); // Set the printing parameters in the "Printing" sublist Teuchos::ParameterList &print_pars = nl_pars.sublist("Printing"); print_pars.set("Output Information", output_flags); // Sublist for line search Teuchos::ParameterList &search_pars = nl_pars.sublist("Line Search"); search_pars.set("Method", "Full Step"); // Sublist for direction Teuchos::ParameterList &dir_pars = nl_pars.sublist("Direction"); dir_pars.set("Method", nl_dir); Teuchos::ParameterList &newton_pars = dir_pars.sublist(nl_dir); if(strcmp(nl_dir, "Newton") == 0) newton_pars.set("Forcing Term Method", "Constant"); // Sublist for linear solver for the Newton method Teuchos::ParameterList &ls_pars = newton_pars.sublist("Linear Solver"); ls_pars.set("Aztec Solver", ls_type); ls_pars.set("Max Iterations", ls_max_iters); ls_pars.set("Tolerance", ls_tolerance); ls_pars.set("Size of Krylov Subspace", ls_sizeof_krylov_subspace); /// \todo parametrize me. ls_pars.set("Preconditioner Reuse Policy", "Recompute"); ls_pars.set("Output Frequency", AZ_all); // precond stuff Teuchos::RCP<Precond<Scalar> > precond = this->get_precond(); if(this->precond_yes == false) ls_pars.set("Preconditioner", "None"); else if(this->dp->is_matrix_free()) ls_pars.set("Preconditioner", "User Defined"); else { if(strcasecmp(precond_type, "ML") == 0) ls_pars.set("Preconditioner", "ML"); else if(strcasecmp(precond_type, "Ifpack") == 0) ls_pars.set("Preconditioner", "Ifpack"); else { warn("Unsupported type of preconditioner."); ls_pars.set("Preconditioner", "None"); } } /// \todo Parametrize me. ls_pars.set("Max Age Of Prec", 999); Teuchos::RCP<NOX::Epetra::Interface::Required> i_req = Teuchos::rcp(this); Teuchos::RCP<NOX::Epetra::Interface::Jacobian> i_jac = Teuchos::rcp(this); Teuchos::RCP<NOX::Epetra::Interface::Preconditioner> i_prec = Teuchos::rcp(this); Teuchos::RCP<Epetra_RowMatrix> jac_mat; Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> lin_sys; if(this->dp->is_matrix_free()) { // Matrix<Scalar>-Free (Epetra_Operator) if(precond == Teuchos::null) { Teuchos::RCP<NOX::Epetra::MatrixFree> mf = Teuchos::rcp(new NOX::Epetra::MatrixFree(print_pars, Teuchos::rcp(this), init_sln)); i_jac = mf; lin_sys = Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(print_pars, ls_pars, i_req, i_jac, mf, init_sln)); } else { const Teuchos::RCP<Epetra_Operator> pc = precond; lin_sys = Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(print_pars, ls_pars, i_req, i_prec, pc, init_sln)); } } else { // not Matrix<Scalar> Free // Create the Epetra_RowMatrix. jac_mat = Teuchos::rcp(this->get_jacobian()->mat); i_jac = Teuchos::rcp(this); lin_sys = Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(print_pars, ls_pars, i_req, i_jac, jac_mat, init_sln)); } // Create the Group Teuchos::RCP<NOX::Epetra::Group> grp = Teuchos::rcp(new NOX::Epetra::Group(print_pars, i_req, init_sln, lin_sys)); // Create convergence tests Teuchos::RCP<NOX::StatusTest::Combo> converged = Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND)); if(conv_flag.absresid) { Teuchos::RCP<NOX::StatusTest::NormF> absresid = Teuchos::rcp(new NOX::StatusTest::NormF(conv.abs_resid, conv.norm_type, conv.stype)); converged->addStatusTest(absresid); } if(conv_flag.relresid) { Teuchos::RCP<NOX::StatusTest::NormF> relresid = Teuchos::rcp(new NOX::StatusTest::NormF(*grp.get(), conv.rel_resid)); converged->addStatusTest(relresid); } if(conv_flag.update) { Teuchos::RCP<NOX::StatusTest::NormUpdate> update = Teuchos::rcp(new NOX::StatusTest::NormUpdate(conv.update)); converged->addStatusTest(update); } if(conv_flag.wrms) { Teuchos::RCP<NOX::StatusTest::NormWRMS> wrms = Teuchos::rcp(new NOX::StatusTest::NormWRMS(conv.wrms_rtol, conv.wrms_atol)); converged->addStatusTest(wrms); } Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters = Teuchos::rcp(new NOX::StatusTest::MaxIters(conv.max_iters)); Teuchos::RCP<NOX::StatusTest::FiniteValue> fv = Teuchos::rcp(new NOX::StatusTest::FiniteValue); Teuchos::RCP<NOX::StatusTest::Combo> cmb = Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR)); cmb->addStatusTest(fv); cmb->addStatusTest(converged); cmb->addStatusTest(maxiters); Teuchos::RCP<Teuchos::ParameterList> final_pars = nl_pars_ptr; // Create the method Teuchos::RCP<NOX::Solver::Generic> solver = NOX::Solver::buildSolver(grp, cmb, final_pars); /// Solve. NOX::StatusTest::StatusType status = solver->solve(); if(!this->dp->is_matrix_free()) jac_mat.release(); // release the ownership (we take care of jac_mat by ourselves) bool success; if(status == NOX::StatusTest::Converged) { num_iters = solver->getNumIterations(); residual = solver->getSolutionGroup().getNormF(); num_lin_iters = final_pars->sublist("Direction").sublist(nl_dir).sublist("Linear Solver").sublist("Output").get("Total Number of Linear Iterations", -1); achieved_tol = final_pars->sublist("Direction").sublist(nl_dir).sublist("Linear Solver").sublist("Output").get("Achieved Tolerance", 0.0); // Get the Epetra_Vector with the final solution from the solver get_final_solution(solver); success = true; } else { // not converged num_iters = -1; success = false; } return success; }
bool NoxSolver::solve() { #ifdef HAVE_NOX // Create the top level parameter list Teuchos::RCP<Teuchos::ParameterList> nl_pars_ptr = Teuchos::rcp(new Teuchos::ParameterList); Teuchos::ParameterList &nl_pars = *nl_pars_ptr.get(); // Set the nonlinear solver method nl_pars.set("Nonlinear Solver", "Line Search Based"); // Set the printing parameters in the "Printing" sublist Teuchos::ParameterList &print_pars = nl_pars.sublist("Printing"); print_pars.set("Output Information", output_flags); // Sublist for line search Teuchos::ParameterList &search_pars = nl_pars.sublist("Line Search"); search_pars.set("Method", "Full Step"); // Sublist for direction Teuchos::ParameterList &dir_pars = nl_pars.sublist("Direction"); dir_pars.set("Method", nl_dir); Teuchos::ParameterList &newton_pars = dir_pars.sublist(nl_dir); if(strcmp(nl_dir, "Newton") == 0) newton_pars.set("Forcing Term Method", "Constant"); // Sublist for linear solver for the Newton method Teuchos::ParameterList &ls_pars = newton_pars.sublist("Linear Solver"); ls_pars.set("Aztec Solver", ls_type); ls_pars.set("Max Iterations", ls_max_iters); ls_pars.set("Tolerance", ls_tolerance); ls_pars.set("Size of Krylov Subspace", ls_sizeof_krylov_subspace); ls_pars.set("Preconditioner Reuse Policy", "Recompute"); ls_pars.set("Output Frequency", AZ_all); // precond stuff Teuchos::RCP<Precond> precond = interface_->get_precond(); if(precond_yes == false) ls_pars.set("Preconditioner", "None"); else if(interface_->fep->is_matrix_free()) ls_pars.set("Preconditioner", "User Defined"); else if(strcasecmp(precond_type, "ML") == 0) ls_pars.set("Preconditioner", "ML"); else if(strcasecmp(precond_type, "Ifpack") == 0) ls_pars.set("Preconditioner", "Ifpack"); else { warn("Unsupported type of preconditioner."); ls_pars.set("Preconditioner", "None"); } ls_pars.set("Max Age Of Prec", 999); Teuchos::RCP<NOX::Epetra::Interface::Required> i_req = interface_; Teuchos::RCP<NOX::Epetra::Interface::Jacobian> i_jac = interface_; Teuchos::RCP<NOX::Epetra::Interface::Preconditioner> i_prec = interface_; Teuchos::RCP<Epetra_RowMatrix> jac_mat; Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> lin_sys; NOX::Epetra::Vector init_sln(*interface_->get_init_sln()->vec); if(interface_->fep->is_matrix_free()) { // Matrix-Free (Epetra_Operator) if(precond == Teuchos::null) { Teuchos::RCP<NOX::Epetra::MatrixFree> mf = Teuchos::rcp(new NOX::Epetra::MatrixFree(print_pars, interface_, init_sln)); i_jac = mf; lin_sys = Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(print_pars, ls_pars, i_req, i_jac, mf, init_sln)); } else { const Teuchos::RCP<Epetra_Operator> pc = precond; lin_sys = Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(print_pars, ls_pars, i_req, i_prec, pc, init_sln)); } } else { // not Matrix Free // Create the Epetra_RowMatrix. jac_mat = Teuchos::rcp(interface_->get_jacobian()->mat); i_jac = interface_; lin_sys = Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(print_pars, ls_pars, i_req, i_jac, jac_mat, init_sln)); } // Create the Group Teuchos::RCP<NOX::Epetra::Group> grp = Teuchos::rcp(new NOX::Epetra::Group(print_pars, i_req, init_sln, lin_sys)); // Create convergence tests Teuchos::RCP<NOX::StatusTest::Combo> converged = Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND)); if(conv_flag.absresid) { Teuchos::RCP<NOX::StatusTest::NormF> absresid = Teuchos::rcp(new NOX::StatusTest::NormF(conv.abs_resid, conv.norm_type, conv.stype)); converged->addStatusTest(absresid); } if(conv_flag.relresid) { Teuchos::RCP<NOX::StatusTest::NormF> relresid = Teuchos::rcp(new NOX::StatusTest::NormF(*grp.get(), conv.rel_resid)); converged->addStatusTest(relresid); } if(conv_flag.update) { Teuchos::RCP<NOX::StatusTest::NormUpdate> update = Teuchos::rcp(new NOX::StatusTest::NormUpdate(conv.update)); converged->addStatusTest(update); } if(conv_flag.wrms) { Teuchos::RCP<NOX::StatusTest::NormWRMS> wrms = Teuchos::rcp(new NOX::StatusTest::NormWRMS(conv.wrms_rtol, conv.wrms_atol)); converged->addStatusTest(wrms); } Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters = Teuchos::rcp(new NOX::StatusTest::MaxIters(conv.max_iters)); Teuchos::RCP<NOX::StatusTest::FiniteValue> fv = Teuchos::rcp(new NOX::StatusTest::FiniteValue); Teuchos::RCP<NOX::StatusTest::Combo> cmb = Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR)); cmb->addStatusTest(fv); cmb->addStatusTest(converged); cmb->addStatusTest(maxiters); Teuchos::RCP<Teuchos::ParameterList> final_pars = nl_pars_ptr; // Create the method Teuchos::RCP<NOX::Solver::Generic> solver = NOX::Solver::buildSolver(grp, cmb, final_pars); ////////////////// /// Solve //////// NOX::StatusTest::StatusType status = solver->solve(); ////////////////// if(!interface_->fep->is_matrix_free()) jac_mat.release(); // release the ownership (we take care of jac_mat by ourselves) bool success; if(status == NOX::StatusTest::Converged) { num_iters = solver->getNumIterations(); residual = solver->getSolutionGroup().getNormF(); num_lin_iters = final_pars->sublist("Direction").sublist(nl_dir).sublist("Linear Solver").sublist("Output").get("Total Number of Linear Iterations", -1); achieved_tol = final_pars->sublist("Direction").sublist(nl_dir).sublist("Linear Solver").sublist("Output").get("Achieved Tolerance", 0.0); // Get the Epetra_Vector with the final solution from the solver #ifndef HERMES_COMMON_COMPLEX const NOX::Epetra::Group &f_grp = dynamic_cast<const NOX::Epetra::Group &>(solver->getSolutionGroup()); const Epetra_Vector &f_sln = (dynamic_cast<const NOX::Epetra::Vector &>(f_grp.getX())).getEpetraVector(); #endif // extract solution int n = interface_->fep->get_num_dofs(); delete [] sln; sln = new scalar[n]; memset(sln, 0, n * sizeof(double)); #ifndef HERMES_COMMON_COMPLEX f_sln.ExtractCopy(sln); #else #endif return true; } else { // not converged num_iters = -1; return false; } #else return false; #endif }
int main(int argc, char* argv[]) { // Define nonlinear thermal conductivity lambda(u) via a cubic spline. // Step 1: Fill the x values and use lambda_macro(u) = 1 + u^4 for the y values. #define lambda_macro(x) (1 + Hermes::pow(x, 4)) Hermes::vector<double> lambda_pts(-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0); Hermes::vector<double> lambda_val; for (unsigned int i = 0; i < lambda_pts.size(); i++) lambda_val.push_back(lambda_macro(lambda_pts[i])); // Step 2: Create the cubic spline (and plot it for visual control). double bc_left = 0.0; double bc_right = 0.0; bool first_der_left = false; bool first_der_right = false; bool extrapolate_der_left = true; bool extrapolate_der_right = true; CubicSpline lambda(lambda_pts, lambda_val, bc_left, bc_right, first_der_left, first_der_right, extrapolate_der_left, extrapolate_der_right); info("Saving cubic spline into a Pylab file spline.dat."); double interval_extension = 3.0; // The interval of definition of the spline will be // extended by "interval_extension" on both sides. lambda.plot("spline.dat", interval_extension); // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary("Bdy", INIT_BDY_REF_NUM); // Initialize boundary conditions. CustomEssentialBCNonConst bc_essential("Bdy"); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); int ndof = space.get_num_dofs(); info("ndof: %d", ndof); // Initialize the weak formulation. Hermes2DFunction<double> src(-heat_src); DefaultWeakFormPoisson<double> wf(HERMES_ANY, &lambda, &src); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, &space); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. // NOTE: If you want to start from the zero vector, just define // coeff_vec to be a vector of ndof zeros (no projection is needed). info("Projecting to obtain initial vector for the Newton's method."); double* coeff_vec = new double[ndof]; CustomInitialCondition init_sln(&mesh); OGProjection<double>::project_global(&space, &init_sln, coeff_vec, matrix_solver); // Initialize Newton solver. NewtonSolver<double> newton(&dp, matrix_solver); // Perform Newton's iteration. bool freeze_jacobian = false; if (!newton.solve(coeff_vec, NEWTON_TOL, NEWTON_MAX_ITER, freeze_jacobian)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into a Solution. Solution<double> sln; Solution<double>::vector_to_solution(newton.get_sln_vector(), &space, &sln); // Get info about time spent during assembling in its respective parts. //dp.get_all_profiling_output(std::cout); // Clean up. delete [] coeff_vec; // Visualise the solution and mesh. ScalarView s_view("Solution", new WinGeom(0, 0, 440, 350)); s_view.show_mesh(false); s_view.show(&sln); OrderView<double> o_view("Mesh", new WinGeom(450, 0, 400, 350)); o_view.show(&space); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char **argv) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinemets. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Set exact solution. CustomExactSolution exact(&mesh); // Initialize boundary conditions DefaultEssentialBCNonConst<double> bc_essential("Bdy", &exact); EssentialBCs<double> bcs(&bc_essential); // Initialize the weak formulation. CustomWeakFormPoisson wf1; // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); int ndof = Space<double>::get_num_dofs(&space); info("ndof: %d", ndof); info("---- Assembling by DiscreteProblem, solving by %s:", MatrixSolverNames[matrix_solver].c_str()); // Initialize the linear discrete problem. DiscreteProblem<double> dp1(&wf1, &space); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver); Vector<double>* rhs = create_vector<double>(matrix_solver); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver, matrix, rhs); #ifdef HAVE_AZTECOO if (matrix_solver == SOLVER_AZTECOO) { (dynamic_cast<AztecOOSolver<double>*>(solver))->set_solver(iterative_method); (dynamic_cast<AztecOOSolver<double>*>(solver))->set_precond(preconditioner); // Using default iteration parameters (see solver/aztecoo.h). } #endif // Begin time measurement of assembly. cpu_time.tick(HERMES_SKIP); // Initial coefficient vector for the Newton's method. double* coeff_vec = new double[ndof]; memset(coeff_vec, 0, ndof*sizeof(double)); // Initialize the Newton solver. Hermes::Hermes2D::NewtonSolver<double> newton(&dp1, matrix_solver); // Perform Newton's iteration and translate the resulting coefficient vector into a Solution. Hermes::Hermes2D::Solution<double> sln1; try { newton.solve(coeff_vec); } catch(Hermes::Exceptions::Exception e) { e.printMsg(); error("Newton's iteration failed."); } Hermes::Hermes2D::Solution<double>::vector_to_solution(newton.get_sln_vector(), &space, &sln1); // CPU time measurement. double time = cpu_time.tick().last(); // Calculate errors. double rel_err_1 = Global<double>::calc_rel_error(&sln1, &exact, HERMES_H1_NORM) * 100; info("CPU time: %g s.", time); info("Exact H1 error: %g%%.", rel_err_1); delete(matrix); delete(rhs); delete(solver); // View the solution and mesh. ScalarView sview("Solution", new WinGeom(0, 0, 440, 350)); sview.show(&sln1); //OrderView oview("Polynomial orders", new WinGeom(450, 0, 400, 350)); //oview.show(&space); // TRILINOS PART: info("---- Assembling by DiscreteProblem, solving by NOX:"); // Initialize the weak formulation for Trilinos. CustomWeakFormPoisson wf2(TRILINOS_JFNK); // Initialize DiscreteProblem. DiscreteProblem<double> dp2(&wf2, &space); // Time measurement. cpu_time.tick(HERMES_SKIP); // Set initial vector for NOX. // NOTE: Using zero vector was causing convergence problems. info("Projecting to obtain initial vector for the Newton's method."); ZeroSolution init_sln(&mesh); // Initialize the NOX solver with the vector "coeff_vec". info("Initializing NOX."); NewtonSolverNOX<double> nox_solver(&dp2); nox_solver.set_output_flags(message_type); nox_solver.set_ls_type(iterative_method); nox_solver.set_ls_tolerance(ls_tolerance); nox_solver.set_conv_iters(max_iters); if (flag_absresid) nox_solver.set_conv_abs_resid(abs_resid); if (flag_relresid) nox_solver.set_conv_rel_resid(rel_resid); // Choose preconditioning. MlPrecond<double> pc("sa"); if (PRECOND) { if (TRILINOS_JFNK) nox_solver.set_precond(pc); else nox_solver.set_precond(preconditioner); } // Assemble and solve using NOX. Solution<double> sln2; OGProjection<double>::project_global(&space, &init_sln, coeff_vec); try { nox_solver.solve(coeff_vec); } catch(Hermes::Exceptions::Exception e) { e.printMsg(); error("NOX failed."); } Solution<double>::vector_to_solution(nox_solver.get_sln_vector(), &space, &sln2); info("Number of nonlin iterations: %d (norm of residual: %g)", nox_solver.get_num_iters(), nox_solver.get_residual()); info("Total number of iterations in linsolver: %d (achieved tolerance in the last step: %g)", nox_solver.get_num_lin_iters(), nox_solver.get_achieved_tol()); // CPU time needed by NOX. time = cpu_time.tick().last(); // Show the NOX solution. ScalarView view2("Solution<double> 2", new WinGeom(450, 0, 460, 350)); view2.show(&sln2); //view2.show(&exact); // Calculate errors. double rel_err_2 = Global<double>::calc_rel_error(&sln2, &exact, HERMES_H1_NORM) * 100; info("CPU time: %g s.", time); info("Exact H1 error: %g%%.", rel_err_2); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { #ifdef WITH_PARALUTION HermesCommonApi.set_integral_param_value(matrixSolverType, SOLVER_PARALUTION_ITERATIVE); // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("square.mesh", mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh->refine_all_elements(); mesh->refine_towards_boundary("Bdy", INIT_BDY_REF_NUM); // Initialize boundary conditions. CustomEssentialBCNonConst bc_essential("Bdy"); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); int ndof = space->get_num_dofs(); // Initialize the weak formulation CustomNonlinearity lambda(alpha); Hermes2DFunction<double> src(-heat_src); DefaultWeakFormPoisson<double> wf(HERMES_ANY, &lambda, &src); #ifdef SHOW_OUTPUT ScalarView s_view("Solution"); #endif double* coeff_vec = new double[ndof]; MeshFunctionSharedPtr<double> init_sln(new CustomInitialCondition(mesh)); OGProjection<double> ogProjection; ogProjection.project_global(space, init_sln, coeff_vec); MeshFunctionSharedPtr<double> sln(new Solution<double>); // Testing is happening here. Hermes::vector<int> numbers_of_nonlinear_iterations; Hermes::vector<int> numbers_of_linear_iterations_in_last_nonlinear_step; // Iterative - original initial guess. HermesCommonApi.set_integral_param_value(matrixSolverType, SOLVER_PARALUTION_ITERATIVE); { // Initialize Newton solver. NewtonSolver<double> newton(&wf, space); newton.set_tolerance(NEWTON_TOL, ResidualNormAbsolute); newton.set_max_steps_with_reused_jacobian(0); newton.get_linear_matrix_solver()->as_IterSolver()->set_solver_type(Solvers::GMRES); newton.get_linear_matrix_solver()->as_IterSolver()->set_tolerance(1e-5); // Perform Newton's iteration. newton.solve(coeff_vec); numbers_of_nonlinear_iterations.push_back(newton.get_num_iters()); numbers_of_linear_iterations_in_last_nonlinear_step.push_back(newton.get_linear_matrix_solver()->as_IterSolver()->get_num_iters()); // Translate the resulting coefficient vector into a Solution. Solution<double>::vector_to_solution(newton.get_sln_vector(), space, sln); #ifdef SHOW_OUTPUT s_view.show(sln); #endif } // Iterative - "exact" initial guess. { // Initialize Newton solver. NewtonSolver<double> newton(&wf, space); newton.set_tolerance(NEWTON_TOL, ResidualNormAbsolute); newton.get_linear_matrix_solver()->as_IterSolver()->set_solver_type(Solvers::GMRES); // Perform Newton's iteration. newton.solve(sln); numbers_of_nonlinear_iterations.push_back(newton.get_num_iters()); numbers_of_linear_iterations_in_last_nonlinear_step.push_back(newton.get_linear_matrix_solver()->as_IterSolver()->get_num_iters()); // Translate the resulting coefficient vector into a Solution. Solution<double>::vector_to_solution(newton.get_sln_vector(), space, sln); #ifdef SHOW_OUTPUT s_view.show(sln); #endif } bool success = true; success = Hermes::Testing::test_value(numbers_of_nonlinear_iterations[0], 10, "Nonlinear iterations[0]", 1) && success; success = Hermes::Testing::test_value(numbers_of_nonlinear_iterations[1], 1, "Nonlinear iterations[1]", 1) && success; success = Hermes::Testing::test_value(numbers_of_linear_iterations_in_last_nonlinear_step[0], 5, "Linear iterations[0]", 1) && success; success = Hermes::Testing::test_value(numbers_of_linear_iterations_in_last_nonlinear_step[1], 7, "Linear iterations[1]", 1) && success; if(success == true) { printf("Success!\n"); return 0; } else { printf("Failure!\n"); return -1; } #endif return 0; }