Beispiel #1
0
    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;
    }
Beispiel #2
0
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;
}
Beispiel #4
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;
}
Beispiel #5
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;
}