示例#1
0
int main(int argc, char* argv[])
{
  // Define problem parameters: (x_loc, y_loc) is the center of the circular wave front, R_ZERO is the distance from the 
  // wave front to the center of the circle, and alpha gives the steepness of the wave front.
  double alpha, x_loc, y_loc, r_zero;
  switch(PROB_PARAM) {
    case 0:
      alpha = 20;
      x_loc = -0.05;
      y_loc = -0.05;
      r_zero = 0.7;
      break;
    case 1:
      alpha = 1000;
      x_loc = -0.05;
      y_loc = -0.05;
      r_zero = 0.7;
      break;
    case 2:
      alpha = 1000;
      x_loc = 1.5;
      y_loc = 0.25;
      r_zero = 0.92;
      break;
    case 3:
      alpha = 50;
      x_loc = 0.5;
      y_loc = 0.5;
      r_zero = 0.25;
      break;
    default:   // The same as 0.
      alpha = 20;
      x_loc = -0.05;
      y_loc = -0.05;
      r_zero = 0.7;
      break;
  }
  
  // Instantiate a class with global functions.
  Hermes2D hermes2d;

  // Load the mesh.
  Mesh mesh;
  H2DReader mloader;
  mloader.load("../square_quad.mesh", &mesh);     // quadrilaterals
  // mloader.load("../square_tri.mesh", &mesh);   // triangles

  // Perform initial mesh refinement.
  for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements();
  // Set exact solution.
  CustomExactSolution exact(&mesh, alpha, x_loc, y_loc, r_zero);
  
  // Define right-hand side.
  CustomRightHandSide rhs(alpha, x_loc, y_loc, r_zero);
  
  // Initialize the weak formulation.
  CustomWeakFormPoisson wf(&rhs);
  
  // Initialize boundary conditions.
  DefaultEssentialBCNonConst bc(BDY_DIRICHLET, &exact);
  EssentialBCs bcs(&bc);
  
  // Create an H1 space with default shapeset.
  H1Space space(&mesh, &bcs, P_INIT);  
  
  // Initialize approximate solution.
  Solution sln;

  // Time measurement.
  TimePeriod cpu_time;
  cpu_time.tick();
  
  // Set up the solver, matrix, and rhs according to the solver selection.
  SparseMatrix* matrix = create_matrix(matrix_solver);
  Vector* rhs_vec = create_vector(matrix_solver);
  Solver* solver = create_linear_solver(matrix_solver, matrix, rhs_vec);

  // Adaptivity loop:
  int as = 1;
  bool done = false;
  double err_exact_rel;
  do
  {
    info("---- Adaptivity step %d:", as);

    // Assemble the discrete problem.
    info("Solving.");
    bool is_linear = true;
    DiscreteProblem* dp = new DiscreteProblem(&wf, &space, is_linear);
    dp->assemble(matrix, rhs_vec);

    // Time measurement.
    cpu_time.tick();

    // Solve the linear system. If successful, obtain the solution.
    if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln);
    else error ("Matrix solver failed.\n");

    // Calculate element errors and total error estimate.
    info("Calculating error estimate and exact error.");
    BasicKellyAdapt* adaptivity = new BasicKellyAdapt(&space);
       
    if (USE_RESIDUAL_ESTIMATOR) 
      adaptivity->add_error_estimator_vol(new ResidualErrorForm(&rhs));
    
    double err_est_rel = adaptivity->calc_err_est(&sln) * 100;  
    err_exact_rel = adaptivity->calc_err_exact(&sln, &exact, false) * 100;   
    
    // Time measurement.
    cpu_time.tick();
    
    // Report results.
    info("ndof_coarse: %d", Space::get_num_dofs(&space));
    info("err_est_rel: %1.15g%%, err_exact_rel: %1.15g%%", err_est_rel, err_exact_rel);
    
    // This is to ensure that the two possible approaches to interface error estimators accumulation give
    // same results.
    KellyTypeAdapt* adaptivity2 = new KellyTypeAdapt(&space, HERMES_UNSET_NORM, false);
    adaptivity2->disable_aposteriori_interface_scaling();
    adaptivity2->add_error_estimator_surf(new InterfaceErrorForm);
    
    if (USE_RESIDUAL_ESTIMATOR)
      adaptivity->add_error_estimator_vol(new ResidualErrorForm(&rhs));
    
    double err_est_rel2 = adaptivity2->calc_err_est(&sln) * 100;  
    double err_exact_rel2 = adaptivity2->calc_err_exact(&sln, &exact, false) * 100;
    
    info("err_est_rel_2: %1.15g%%, err_exact_rel_2: %1.15g%%", err_est_rel2, err_exact_rel2);
    
    if (fabs(err_est_rel2 - err_est_rel) >= 1e-13 || fabs(err_exact_rel2 - err_exact_rel) >= 1e-13)
    {
      info("err_est_rel diff: %g, err_exact_rel diff: %g", 
           std::abs(err_est_rel2 - err_est_rel), std::abs(err_exact_rel2 - err_exact_rel));
      err_est_rel = 0;      // to immediately exit the adaptivity loop
      err_exact_rel = 1e20; // to fail the test
    }
     
    // Time measurement.
    cpu_time.tick(HERMES_SKIP);
    
    // If err_est too large, adapt the mesh.
    if (err_est_rel < ERR_STOP) done = true;
    else
    {
      info("Adapting the mesh.");
      done = adaptivity->adapt(THRESHOLD, STRATEGY, MESH_REGULARITY);
    }
    if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true;
    
    // Increase the counter of performed adaptivity steps.
    if (done == false)  as++;

    // Clean up.
    delete adaptivity;
    delete adaptivity2;
    delete dp;
  }
  while (done == false);
  
  // Clean up.
  delete solver;
  delete matrix;
  delete rhs_vec;

  verbose("Total running time: %g s", cpu_time.accumulated());

  int ndof = Space::get_num_dofs(&space);

  int n_dof_allowed = 1450;
  double err_exact_rel_allowed = 9.0;
  printf("n_dof_actual = %d\n", ndof);
  printf("n_dof_allowed = %d\n", n_dof_allowed);
  printf("err_exact_rel_actual = %g%%\n", err_exact_rel);
  printf("err_exact_rel_allowed = %g%%\n", err_exact_rel_allowed);
  if (ndof <= n_dof_allowed && err_exact_rel <= err_exact_rel_allowed) {
    printf("Success!\n");
    return ERR_SUCCESS;
  }
  else {
    printf("Failure!\n");
    return ERR_FAILURE;
  }
  
  // Wait for all views to be closed.
  View::wait();
  return 0;
}
示例#2
0
文件: main.cpp 项目: alieed/hermes
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  H2DReader mloader;
  mloader.load("square_quad.mesh", &mesh);     // quadrilaterals
  // mloader.load("square_tri.mesh", &mesh);   // triangles

  // Perform initial mesh refinement.
  for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements();

  // Enter boundary markers.
  BCTypes bc_types;
  bc_types.add_bc_dirichlet(BDY_DIRICHLET);

  // Enter Dirichlet boudnary values.
  BCValues bc_values;
  bc_values.add_function(BDY_DIRICHLET, essential_bc_values);

  // Create an H1 space with default shapeset.
  H1Space space(&mesh, &bc_types, &bc_values, P_INIT);

  // Initialize the weak formulation.
  WeakForm wf;
  wf.add_matrix_form(callback(bilinear_form), HERMES_SYM);
  wf.add_vector_form(callback(linear_form));
  
  // Initialize approximate solution.
  Solution sln;

  // Set exact solution.
  ExactSolution exact(&mesh, fndd);

  // Time measurement.
  TimePeriod cpu_time;
  cpu_time.tick();
  
  // Initialize the matrix solver.
  SparseMatrix* matrix = create_matrix(matrix_solver);
  Vector* rhs = create_vector(matrix_solver);
  Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);

  // Adaptivity loop:
  int as = 1;
  bool done = false;
  double err_exact_rel;
  do
  {
    info("---- Adaptivity step %d:", as);

    // Assemble the discrete problem.
    info("Solving.");
    bool is_linear = true;
    DiscreteProblem* dp = new DiscreteProblem(&wf, &space, is_linear);
    dp->assemble(matrix, rhs);

    // Time measurement.
    cpu_time.tick();

    // Solve the linear system. If successful, obtain the solution.
    if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln);
    else error ("Matrix solver failed.\n");

    // Calculate element errors and total error estimate.
    info("Calculating error estimate and exact error.");
    BasicKellyAdapt* adaptivity = new BasicKellyAdapt(&space);
    
    if (USE_RESIDUAL_ESTIMATOR)
      adaptivity->add_error_estimator_vol(callback(residual_estimator));
    
    double err_est_rel = adaptivity->calc_err_est(&sln) * 100;  
    err_exact_rel = adaptivity->calc_err_exact(&sln, &exact) * 100;   
    
    // Time measurement.
    cpu_time.tick();
    
    // Report results.
    info("ndof_coarse: %d", Space::get_num_dofs(&space));
    info("err_est_rel: %1.15g%%, err_exact_rel: %1.15g%%", err_est_rel, err_exact_rel);
    
    // This is to ensure that the two possible approaches to interface error estimators accumulation give
    // same results.
    KellyTypeAdapt* adaptivity2 = new KellyTypeAdapt(&space, Hermes::vector<ProjNormType>(), false);
    adaptivity2->disable_aposteriori_interface_scaling();
    adaptivity2->add_error_estimator_surf(callback(interface_estimator));
    
    double err_est_rel2 = adaptivity2->calc_err_est(&sln) * 100;  
    double err_exact_rel2 = adaptivity2->calc_err_exact(&sln, &exact) * 100;
    
    info("err_est_rel_2: %1.15g%%, err_exact_rel_2: %1.15g%%", err_est_rel2, err_exact_rel2);
    
    if (fabs(err_est_rel2 - err_est_rel) >= 1e-13 || fabs(err_exact_rel2 - err_exact_rel) >= 1e-13)
    {
      info("err_est_rel diff: %g, err_exact_rel diff: %g", 
           std::abs(err_est_rel2 - err_est_rel), std::abs(err_exact_rel2 - err_exact_rel));
      err_est_rel = 0;      // to immediately exit the adaptivity loop
      err_exact_rel = 1e20; // to fail the test
    }
     
    // Time measurement.
    cpu_time.tick(HERMES_SKIP);
    
    // If err_est too large, adapt the mesh.
    if (err_est_rel < ERR_STOP) done = true;
    else
    {
      info("Adapting the mesh.");
      done = adaptivity->adapt(THRESHOLD, STRATEGY, MESH_REGULARITY);
    }
    if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true;
    
    // Increase the counter of performed adaptivity steps.
    if (done == false)  as++;

    // Clean up.
    delete adaptivity;
    delete adaptivity2;
    delete dp;
  }
  while (done == false);
  
  // Clean up.
  delete solver;
  delete matrix;
  delete rhs;

  verbose("Total running time: %g s", cpu_time.accumulated());

  int ndof = Space::get_num_dofs(&space);

  int n_dof_allowed = 15555;
  double err_exact_rel_allowed = 4.075;
  printf("n_dof_actual = %d\n", ndof);
  printf("n_dof_allowed = %d\n", n_dof_allowed);
  printf("err_exact_rel_actual = %g%%\n", err_exact_rel);
  printf("err_exact_rel_allowed = %g%%\n", err_exact_rel_allowed);
  if (ndof <= n_dof_allowed && err_exact_rel <= err_exact_rel_allowed) {
    printf("Success!\n");
    return ERR_SUCCESS;
  }
  else {
    printf("Failure!\n");
    return ERR_FAILURE;
  }
  
  // Wait for all views to be closed.
  View::wait();
  return 0;
}
示例#3
0
文件: main.cpp 项目: alieed/hermes
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  H2DReader mloader;
  mloader.load("square_quad.mesh", &mesh);     // quadrilaterals
  // mloader.load("square_tri.mesh", &mesh);   // triangles

  // Perform initial mesh refinement.
  for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements();

  // Enter boundary markers.
  BCTypes bc_types;
  bc_types.add_bc_dirichlet(BDY_DIRICHLET);

  // Enter Dirichlet boudnary values.
  BCValues bc_values;
  bc_values.add_function(BDY_DIRICHLET, essential_bc_values);

  // Create an H1 space with default shapeset.
  H1Space space(&mesh, &bc_types, &bc_values, P_INIT);

  // Initialize the weak formulation.
  WeakForm wf;
  wf.add_matrix_form(callback(bilinear_form), HERMES_SYM);
  wf.add_vector_form(callback(linear_form));
  
  // Initialize approximate solution.
  Solution sln;

  // Set exact solution.
  ExactSolution exact(&mesh, fndd);

  // Initialize views.
  ScalarView sview("Solution", new WinGeom(0, 0, 440, 350));
  sview.show_mesh(false);
  sview.fix_scale_width(50);
  OrderView  oview("Polynomial orders", new WinGeom(450, 0, 640, 480));

  // DOF and CPU convergence graphs.
  SimpleGraph graph_dof, graph_cpu, graph_dof_exact, graph_cpu_exact;

  // Time measurement.
  TimePeriod cpu_time;
  cpu_time.tick();
  
  // Initialize the matrix solver.
  SparseMatrix* matrix = create_matrix(matrix_solver);
  Vector* rhs = create_vector(matrix_solver);
  Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);

  // Adaptivity loop:
  int as = 1;
  bool done = false;
  do
  {
    info("---- Adaptivity step %d:", as);

    // Assemble the discrete problem.
    info("Solving.");
    bool is_linear = true;
    DiscreteProblem* dp = new DiscreteProblem(&wf, &space, is_linear);
    dp->assemble(matrix, rhs);

    // Time measurement.
    cpu_time.tick();

    // Solve the linear system. If successful, obtain the solution.
    if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln);
    else error ("Matrix solver failed.\n");

    // View the approximate solution and polynomial orders.
    sview.show(&sln);
    oview.show(&space);

    // Calculate element errors and total error estimate.
    info("Calculating error estimate and exact error.");
    BasicKellyAdapt* adaptivity = new BasicKellyAdapt(&space);
    
    // Use energy norm for error estimate normalization and measuring of exact error.
    adaptivity->set_error_form(callback(bilinear_form));
    
    if (USE_RESIDUAL_ESTIMATOR) 
      adaptivity->add_error_estimator_vol(callback(residual_estimator));
    
    double err_est_rel = adaptivity->calc_err_est(&sln) * 100;  
    double err_exact_rel = adaptivity->calc_err_exact(&sln, &exact) * 100;

    // Time measurement.
    cpu_time.tick();
    
    // Report results.
    info("ndof_coarse: %d", Space::get_num_dofs(&space));
    info("err_est_rel: %g%%, err_exact_rel: %g%%", err_est_rel, err_exact_rel);

    // Add entry to DOF and CPU convergence graphs.
    graph_dof.add_values(Space::get_num_dofs(&space), err_est_rel);
    graph_dof.save("conv_dof_est.dat");
    graph_cpu.add_values(cpu_time.accumulated(), err_est_rel);
    graph_cpu.save("conv_cpu_est.dat");
    graph_dof_exact.add_values(Space::get_num_dofs(&space), err_exact_rel);
    graph_dof_exact.save("conv_dof_exact.dat");
    graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel);
    graph_cpu_exact.save("conv_cpu_exact.dat");

    // Time measurement.
    cpu_time.tick(HERMES_SKIP);
    
    // If err_est too large, adapt the mesh.
    if (err_est_rel < ERR_STOP) done = true;
    else
    {
      info("Adapting the mesh.");
      done = adaptivity->adapt(THRESHOLD, STRATEGY, MESH_REGULARITY);
    }
    if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true;
    
    // Increase the counter of performed adaptivity steps.
    if (done == false)  as++;

    // Clean up.
    delete adaptivity;
    delete dp;
  }
  while (done == false);
  
  // Clean up.
  delete solver;
  delete matrix;
  delete rhs;

  verbose("Total running time: %g s", cpu_time.accumulated());

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