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