Ejemplo n.º 1
0
int main(int argc, char* argv[])
{
  // Time measurement.
  TimePeriod cpu_time;
  cpu_time.tick();

  info("TIME_MAX_ITER = %d", TIME_MAX_ITER);

  // Load the mesh file.
  Mesh mesh;
  H2DReader mloader;
  mloader.load("domain.mesh", &mesh);

  // Perform initial mesh refinements.
  for (int i=0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements();
  mesh.refine_towards_boundary(1, INIT_BDY_REF_NUM);

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

  // Enter Dirichlet boudnary values.
  BCValues bc_values;
  bc_values.add_zero(BDY_DIRICHLET);

  // Create H1 spaces with default shapesets.
  H1Space space_T(&mesh, &bc_types, &bc_values, P_INIT);
  H1Space space_phi(&mesh, &bc_types, &bc_values, P_INIT);
  Hermes::Tuple<Space*> spaces(&space_T, &space_phi);

  // Exact solutions for error evaluation.
  ExactSolution T_exact_solution(&mesh, T_exact),
                phi_exact_solution(&mesh, phi_exact);

  // Initialize solution views (their titles will be2 updated in each time step).
  ScalarView sview_T("", new WinGeom(0, 0, 500, 400));
  sview_T.fix_scale_width(50);
  ScalarView sview_phi("", new WinGeom(0, 500, 500, 400));
  sview_phi.fix_scale_width(50);
  ScalarView sview_T_exact("", new WinGeom(550, 0, 500, 400));
  sview_T_exact.fix_scale_width(50);
  ScalarView sview_phi_exact("", new WinGeom(550, 500, 500, 400));
  sview_phi_exact.fix_scale_width(50);
  char title[100]; // Character array to store the title for an actual view and time step.

  // Solutions in the previous time step.
  Solution T_prev_time, phi_prev_time;
  Hermes::Tuple<MeshFunction*> time_iterates(&T_prev_time, &phi_prev_time);
  
  // Solutions in the previous Newton's iteration.
  Solution T_prev_newton, phi_prev_newton;
  Hermes::Tuple<Solution*> newton_iterates(&T_prev_newton, &phi_prev_newton);

  // Initialize the weak formulation.
  WeakForm wf(2);
  wf.add_matrix_form(0, 0, jac_TT, jac_TT_ord);
  wf.add_matrix_form(0, 1, jac_Tphi, jac_Tphi_ord);
  wf.add_vector_form(0, res_T, res_T_ord, HERMES_ANY, &T_prev_time);
  wf.add_matrix_form(1, 0, jac_phiT, jac_phiT_ord);
  wf.add_matrix_form(1, 1, jac_phiphi, jac_phiphi_ord);
  wf.add_vector_form(1, res_phi, res_phi_ord, HERMES_ANY, &phi_prev_time);
  
  // Set initial conditions.
  T_prev_time.set_exact(&mesh, T_exact);
  phi_prev_time.set_exact(&mesh, phi_exact);
  
  // Set up the solver, matrix, and rhs according to the solver selection.
  SparseMatrix* matrix = create_matrix(matrix_solver);
  Vector* rhs = create_vector(matrix_solver);
  Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);
  solver->set_factorization_scheme(HERMES_REUSE_MATRIX_REORDERING);

  // Time stepping.
  int t_step = 1;
  do {
    TIME += TAU;

    info("---- Time step %d, t = %g s:", t_step, TIME); t_step++;
    info("Projecting to obtain initial vector for the Newton's method.");

    scalar* coeff_vec = new scalar[Space::get_num_dofs(spaces)];
    OGProjection::project_global(spaces, time_iterates, coeff_vec, matrix_solver);
    Solution::vector_to_solutions(coeff_vec, Hermes::Tuple<Space*>(&space_T, &space_phi), 
                                  Hermes::Tuple<Solution*>(&T_prev_newton, &phi_prev_newton));
    
    // Initialize the FE problem.
    bool is_linear = false;
    DiscreteProblem dp(&wf, spaces, is_linear);

    // Perform Newton's iteration.
    info("Newton's iteration...");
    bool verbose = true;
    if(!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose))
      error("Newton's iteration failed.");
        
    // Translate the resulting coefficient vector into the Solution sln.
    Solution::vector_to_solutions(coeff_vec, spaces, newton_iterates);
    delete [] coeff_vec;
    
    // Show the new time level solution.
    sprintf(title, "Approx. solution for T, t = %g s", TIME);
    sview_T.set_title(title); 
    sview_T.show(&T_prev_newton);
    
    sprintf(title, "Approx. solution for phi, t = %g s", TIME);
    sview_phi.set_title(title);
    sview_phi.show(&phi_prev_newton);

    // Exact solution for comparison with computational results.
    T_exact_solution.update(&mesh, T_exact);
    phi_exact_solution.update(&mesh, phi_exact);

    // Show exact solution.
    sview_T_exact.show(&T_exact_solution);
    sprintf(title, "Exact solution for T, t = %g s", TIME);
    sview_T_exact.set_title(title);
    
    sview_phi_exact.show(&phi_exact_solution);
    sprintf(title, "Exact solution for phi, t = %g s", TIME);
    sview_phi_exact.set_title(title);
    
    // Calculate exact error.
    info("Calculating error (exact).");
    Hermes::Tuple<double> exact_errors;
    Adapt adaptivity_exact(spaces, Hermes::Tuple<ProjNormType>(HERMES_H1_NORM, HERMES_H1_NORM));
    bool solutions_for_adapt = false;
    adaptivity_exact.calc_err_exact(Hermes::Tuple<Solution *>(&T_prev_newton, &phi_prev_newton), Hermes::Tuple<Solution *>(&T_exact_solution, &phi_exact_solution), solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL, &exact_errors);
    
    double maxerr = std::max(exact_errors[0], exact_errors[1])*100;
    info("Exact solution error for T (H1 norm): %g %%", exact_errors[0]*100);
    info("Exact solution error for phi (H1 norm): %g %%", exact_errors[1]*100);
    info("Exact solution error (maximum): %g %%", maxerr);
    
    // Prepare previous time level solution for the next time step.
    T_prev_time.copy(&T_prev_newton);
    phi_prev_time.copy(&phi_prev_newton);
  }
  while (t_step <= TIME_MAX_ITER);

  // Cleanup.
  delete matrix;
  delete rhs;
  delete solver;
  
  // Wait for all views to be closed.
  View::wait();

  return 0;
}
Ejemplo n.º 2
0
int main(int argc, char* argv[])
{
    // Time measurement.
    TimePeriod cpu_time;
    cpu_time.tick();

    info("TIME_MAX_ITER = %d", TIME_MAX_ITER);

    // Load the mesh file.
    Mesh mesh;
    H2DReader mloader;
    mloader.load("domain.mesh", &mesh);

    // Perform initial mesh refinements.
    for (int i=0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements();
    mesh.refine_towards_boundary(1, INIT_BDY_REF_NUM);

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

    // Enter Dirichlet boudnary values.
    BCValues bc_values;
    bc_values.add_zero(BDY_DIRICHLET);

    // Create H1 spaces with default shapesets.
    H1Space space_T(&mesh, &bc_types, &bc_values, P_INIT);
    H1Space space_phi(&mesh, &bc_types, &bc_values, P_INIT);
    Hermes::vector<Space*> spaces(&space_T, &space_phi);

    // Exact solutions for error evaluation.
    ExactSolution T_exact_solution(&mesh, T_exact),
                  phi_exact_solution(&mesh, phi_exact);

    // Solutions in the previous time step.
    Solution T_prev_time, phi_prev_time;
    Hermes::vector<MeshFunction*> time_iterates(&T_prev_time, &phi_prev_time);

    // Solutions in the previous Newton's iteration.
    Solution T_prev_newton, phi_prev_newton;
    Hermes::vector<Solution*> newton_iterates(&T_prev_newton, &phi_prev_newton);

    // Initialize the weak formulation.
    WeakForm wf(2);
    wf.add_matrix_form(0, 0, jac_TT, jac_TT_ord);
    wf.add_matrix_form(0, 1, jac_Tphi, jac_Tphi_ord);
    wf.add_vector_form(0, res_T, res_T_ord, HERMES_ANY, &T_prev_time);
    wf.add_matrix_form(1, 0, jac_phiT, jac_phiT_ord);
    wf.add_matrix_form(1, 1, jac_phiphi, jac_phiphi_ord);
    wf.add_vector_form(1, res_phi, res_phi_ord, HERMES_ANY, &phi_prev_time);

    // Set initial conditions.
    T_prev_time.set_exact(&mesh, T_exact);
    phi_prev_time.set_exact(&mesh, phi_exact);

    // Set up the solver, matrix, and rhs according to the solver selection.
    SparseMatrix* matrix = create_matrix(matrix_solver);
    Vector* rhs = create_vector(matrix_solver);
    Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);
    solver->set_factorization_scheme(HERMES_REUSE_MATRIX_REORDERING);

    // Time stepping.
    int t_step = 1;
    do {
        TIME += TAU;

        info("---- Time step %d, t = %g s:", t_step, TIME);
        t_step++;
        info("Projecting to obtain initial vector for the Newton's method.");

        scalar* coeff_vec = new scalar[Space::get_num_dofs(spaces)];
        OGProjection::project_global(spaces, time_iterates, coeff_vec, matrix_solver);
        Solution::vector_to_solutions(coeff_vec, Hermes::vector<Space*>(&space_T, &space_phi),
                                      Hermes::vector<Solution*>(&T_prev_newton, &phi_prev_newton));

        // Initialize the FE problem.
        bool is_linear = false;
        DiscreteProblem dp(&wf, spaces, is_linear);

        // Perform Newton's iteration.
        info("Newton's iteration...");
        bool verbose = false;
        if(!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose))
            error("Newton's iteration failed.");

        // Translate the resulting coefficient vector into the Solution sln.
        Solution::vector_to_solutions(coeff_vec, spaces, newton_iterates);
        delete [] coeff_vec;

        // Exact solution for comparison with computational results.
        T_exact_solution.update(&mesh, T_exact);
        phi_exact_solution.update(&mesh, phi_exact);

        // Calculate exact error.
        info("Calculating error (exact).");
        Hermes::vector<double> exact_errors;
        Adapt adaptivity_exact(spaces);
        bool solutions_for_adapt = false;
        adaptivity_exact.calc_err_exact(Hermes::vector<Solution *>(&T_prev_newton, &phi_prev_newton), Hermes::vector<Solution *>(&T_exact_solution, &phi_exact_solution), &exact_errors, solutions_for_adapt);

        double maxerr = std::max(exact_errors[0], exact_errors[1])*100;
        info("Exact solution error for T (H1 norm): %g %%", exact_errors[0]*100);
        info("Exact solution error for phi (H1 norm): %g %%", exact_errors[1]*100);
        info("Exact solution error (maximum): %g %%", maxerr);

        // Prepare previous time level solution for the next time step.
        T_prev_time.copy(&T_prev_newton);
        phi_prev_time.copy(&phi_prev_newton);
    }
    while (t_step <= TIME_MAX_ITER);

    // Cleanup.
    delete matrix;
    delete rhs;
    delete solver;

    info("Coordinate (  0,  0) T value = %lf", T_prev_time.get_pt_value(0.0, 0.0));
    info("Coordinate ( 25, 25) T value = %lf", T_prev_time.get_pt_value(25.0, 25.0));
    info("Coordinate ( 75, 25) T value = %lf", T_prev_time.get_pt_value(75.0, 25.0));
    info("Coordinate ( 25, 75) T value = %lf", T_prev_time.get_pt_value(25.0, 75.0));
    info("Coordinate ( 75, 75) T value = %lf", T_prev_time.get_pt_value(75.0, 75.0));

    info("Coordinate (  0,  0) phi value = %lf", phi_prev_time.get_pt_value(0.0, 0.0));
    info("Coordinate ( 25, 25) phi value = %lf", phi_prev_time.get_pt_value(25.0, 25.0));
    info("Coordinate ( 75, 25) phi value = %lf", phi_prev_time.get_pt_value(75.0, 25.0));
    info("Coordinate ( 25, 75) phi value = %lf", phi_prev_time.get_pt_value(25.0, 75.0));
    info("Coordinate ( 75, 75) phi value = %lf", phi_prev_time.get_pt_value(75.0, 75.0));

    int success = 1;
    double eps = 1e-5;
    if (fabs(T_prev_time.get_pt_value(0.0, 0.0) - 0.000000) > eps) {
        printf("Coordinate (  0,  0) T value = %lf\n", T_prev_time.get_pt_value(0.0, 0.0));
        success = 0;
    }

    if (fabs(T_prev_time.get_pt_value(25.0, 25.0) - 0.915885) > eps) {
        printf("Coordinate ( 25, 25) T value = %lf\n", T_prev_time.get_pt_value(25.0, 25.0));
        success = 0;
    }

    if (fabs(T_prev_time.get_pt_value(75.0, 25.0) - 0.915885) > eps) {
        printf("Coordinate ( 75, 25) T value = %lf\n", T_prev_time.get_pt_value(75.0, 25.0));
        success = 0;
    }

    if (fabs(T_prev_time.get_pt_value(25.0, 75.0) - 0.915885) > eps) {
        printf("Coordinate ( 25, 75) T value = %lf\n", T_prev_time.get_pt_value(25.0, 75.0));
        success = 0;
    }

    if (fabs(T_prev_time.get_pt_value(75.0, 75.0) - 0.915885) > eps) {
        printf("Coordinate ( 75, 75) T value = %lf\n", T_prev_time.get_pt_value(75.0, 75.0));
        success = 0;
    }

    if (fabs(phi_prev_time.get_pt_value(0.0, 0.0) - 0.000000) > eps) {
        printf("Coordinate (  0,  0) phi value = %lf\n", phi_prev_time.get_pt_value(0.0, 0.0));
        success = 0;
    }

    if (fabs(phi_prev_time.get_pt_value(25.0, 25.0) - 0.071349) > eps) {
        printf("Coordinate ( 25, 25) phi value = %lf\n", phi_prev_time.get_pt_value(25.0, 25.0));
        success = 0;
    }

    if (fabs(phi_prev_time.get_pt_value(75.0, 25.0) - 0.214063) > eps) {
        printf("Coordinate ( 75, 25) phi value = %lf\n", phi_prev_time.get_pt_value(75.0, 25.0));
        success = 0;
    }

    if (fabs(phi_prev_time.get_pt_value(25.0, 75.0) - 0.214063) > eps) {
        printf("Coordinate ( 25, 75) phi value = %lf\n", phi_prev_time.get_pt_value(25.0, 75.0));
        success = 0;
    }

    if (fabs(phi_prev_time.get_pt_value(75.0, 75.0) - 0.642226) > eps) {
        printf("Coordinate ( 75, 75) phi value = %lf\n", phi_prev_time.get_pt_value(75.0, 75.0));
        success = 0;
    }

    if (success == 1) {
        printf("Success!\n");
        return ERR_SUCCESS;
    }
    else {
        printf("Failure!\n");
        return ERR_FAILURE;
    }
}