Example #1
0
int main(int argc, char* argv[])
{
  // 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 previous iteration solution for the Picard's method.
  MeshFunctionSharedPtr<double> init_condition(new ConstantSolution<double>(mesh, INIT_COND_CONST));

  // Initialize the weak formulation.
  CustomNonlinearity lambda(alpha);
  Hermes2DFunction<double> src(-heat_src);
  CustomWeakFormPicard wf(init_condition, &lambda, &src);

  // Initialize the Picard solver.
  PicardSolver<double> picard(&wf, space);
  picard.set_max_allowed_iterations(PICARD_MAX_ITER);
  logger.info("Default tolerance");
  try
  {
    picard.solve(init_condition);
  }
  catch(std::exception& e)
  {
    std::cout << e.what();
  }

  int iter_1 = picard.get_num_iters();

  logger.info("Adjusted tolerance without Anderson");
  // Perform the Picard's iteration (Anderson acceleration on by default).
  picard.clear_tolerances();
  picard.set_tolerance(PICARD_TOL, Hermes::Solvers::SolutionChangeAbsolute);
  try
  {
    picard.solve(init_condition);
  }
  catch(std::exception& e)
  {
    std::cout << e.what();
  }
  int iter_2 = picard.get_num_iters();

  // Translate the coefficient vector into a Solution. 
  MeshFunctionSharedPtr<double> sln(new Solution<double>);
  Solution<double>::vector_to_solution(picard.get_sln_vector(), space, sln);
  logger.info("Default tolerance without Anderson and good initial guess");
  PicardSolver<double> picard2(&wf, space);
  picard2.set_tolerance(1e-3, Hermes::Solvers::SolutionChangeRelative);
  picard2.set_max_allowed_iterations(PICARD_MAX_ITER);
  try
  {
    picard2.solve(sln);
  }
  catch(std::exception& e)
  {
    std::cout << e.what();
  }
  int iter_3 = picard2.get_num_iters();

  logger.info("Default tolerance with Anderson and good initial guess");
  picard2.use_Anderson_acceleration(true);
  picard2.set_num_last_vector_used(PICARD_NUM_LAST_ITER_USED);
  picard2.set_anderson_beta(PICARD_ANDERSON_BETA);
  try
  {
    picard2.solve(sln);
  }
  catch(std::exception& e)
  {
    std::cout << e.what();
  }
  int iter_4 = picard2.get_num_iters();

#ifdef SHOW_OUTPUT
  // 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 o_view("Mesh", new WinGeom(450, 0, 420, 350));
  o_view.show(space);

  // Wait for all views to be closed.
  View::wait();
#endif

  bool success = Testing::test_value(iter_1, 14, "# of iterations 1", 1); // Tested value as of September 2013.
  success = Testing::test_value(iter_2, 12, "# of iterations 2", 1) & success; // Tested value as of September 2013.
  success = Testing::test_value(iter_3, 3, "# of iterations 3", 1) & success; // Tested value as of September 2013.
  success = Testing::test_value(iter_4, 3, "# of iterations 4", 1) & success; // Tested value as of September 2013.

  if(success)
  {
    printf("Success!\n");
    return 0;
  }
  else
  {
    printf("Failure!\n");
    return -1;
  }
}
Example #2
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  mloader.load("square.mesh", &mesh);

  // Initial mesh refinements.
  for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements();
  mesh.refine_towards_boundary("Top", INIT_REF_NUM_BDY);

  // Initialize boundary conditions.
  CustomEssentialBCNonConst bc_essential(Hermes::vector<std::string>("Bottom", 
      "Right", "Top", "Left"));
  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);

  // Zero initial solutions. This is why we use H_OFFSET.
  ZeroSolution h_time_prev(&mesh), h_iter_prev(&mesh);

  // Initialize views.
  ScalarView view("Initial condition", new WinGeom(0, 0, 600, 500));
  view.fix_scale_width(80);

  // Visualize the initial condition.
  view.show(&h_time_prev);

  // Initialize the constitutive relations.
  ConstitutiveRelations* constitutive_relations;
  if(constitutive_relations_type == CONSTITUTIVE_GENUCHTEN)
    constitutive_relations = new ConstitutiveRelationsGenuchten(ALPHA, M, N, THETA_S, THETA_R, K_S, STORATIVITY);
  else
    constitutive_relations = new ConstitutiveRelationsGardner(ALPHA, THETA_S, THETA_R, K_S);

  // Initialize the weak formulation.
  double current_time = 0;
  CustomWeakFormRichardsIEPicard wf(time_step, &h_time_prev, &h_iter_prev, constitutive_relations);

  // Initialize the FE problem.
  DiscreteProblem<double> dp(&wf, &space);

  // Initialize the Picard solver.
  PicardSolver<double> picard(&dp, &h_iter_prev, matrix_solver);
  picard.set_verbose_output(true);

  // Time stepping:
  int ts = 1;
  do 
  {
    info("---- Time step %d, time %3.5f s", ts, current_time);

    // Perform the Picard's iteration (Anderson acceleration on by default).
    if (!picard.solve(PICARD_TOL, PICARD_MAX_ITER, PICARD_NUM_LAST_ITER_USED, 
        PICARD_ANDERSON_BETA)) error("Picard's iteration failed.");

    // Translate the coefficient vector into a Solution. 
    Solution<double>::vector_to_solution(picard.get_sln_vector(), &space, &h_iter_prev);

    // Increase current time and time step counter.
    current_time += time_step;
    ts++;

    // Visualize the solution.
    char title[100];
    sprintf(title, "Time %g s", current_time);
    view.set_title(title);
    view.show(&h_iter_prev);

    // Save the next time level solution.
    h_time_prev.copy(&h_iter_prev);
  }
  while (current_time < T_FINAL);

  // Wait for the view to be closed.
  View::wait();
  return 0;
}