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; }
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; } }