int main(int argc, char* argv[]) { try { // Sanity check for omega. double K_squared = Hermes::sqr(OMEGA / M_PI) * (OMEGA - 2) / (1 - OMEGA); if (K_squared <= 0) throw Hermes::Exceptions::Exception("Wrong choice of omega, K_squared < 0!"); double K_norm_coeff = std::sqrt(K_squared) / std::sqrt(Hermes::sqr(K_x) + Hermes::sqr(K_y)); Hermes::Mixins::Loggable::Static::info("Wave number K = %g", std::sqrt(K_squared)); K_x *= K_norm_coeff; K_y *= K_norm_coeff; // Wave number. double K = std::sqrt(Hermes::sqr(K_x) + Hermes::sqr(K_y)); // Choose a Butcher's table or define your own. ButcherTable bt(butcher_table); if (bt.is_explicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage explicit R-K method.", bt.get_size()); if (bt.is_diagonally_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage diagonally implicit R-K method.", bt.get_size()); if (bt.is_fully_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage fully implicit R-K method.", bt.get_size()); // Load the mesh. MeshSharedPtr E_mesh(new Mesh), H_mesh(new Mesh), P_mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", E_mesh); mloader.load("domain.mesh", H_mesh); mloader.load("domain.mesh", P_mesh); // Perform initial mesh refinemets. for (int i = 0; i < INIT_REF_NUM; i++) { E_mesh->refine_all_elements(); H_mesh->refine_all_elements(); P_mesh->refine_all_elements(); } // Initialize solutions. double current_time = 0; MeshFunctionSharedPtr<double> E_time_prev(new CustomInitialConditionE(E_mesh, current_time, OMEGA, K_x, K_y)); MeshFunctionSharedPtr<double> H_time_prev(new CustomInitialConditionH(H_mesh, current_time, OMEGA, K_x, K_y)); MeshFunctionSharedPtr<double> P_time_prev(new CustomInitialConditionP(P_mesh, current_time, OMEGA, K_x, K_y)); std::vector<MeshFunctionSharedPtr<double> > slns_time_prev({ E_time_prev, H_time_prev, P_time_prev }); MeshFunctionSharedPtr<double> E_time_new(new Solution<double>(E_mesh)), H_time_new(new Solution<double>(H_mesh)), P_time_new(new Solution<double>(P_mesh)); MeshFunctionSharedPtr<double> E_time_new_coarse(new Solution<double>(E_mesh)), H_time_new_coarse(new Solution<double>(H_mesh)), P_time_new_coarse(new Solution<double>(P_mesh)); std::vector<MeshFunctionSharedPtr<double> > slns_time_new({ E_time_new, H_time_new, P_time_new }); // Initialize the weak formulation. WeakFormSharedPtr<double> wf(new CustomWeakFormMD(OMEGA, K_x, K_y, MU_0, EPS_0, EPS_INF, EPS_Q, TAU)); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_essential("Bdy", 0.0); EssentialBCs<double> bcs(&bc_essential); SpaceSharedPtr<double> E_space(new HcurlSpace<double>(E_mesh, &bcs, P_INIT)); SpaceSharedPtr<double> H_space(new H1Space<double>(H_mesh, NULL, P_INIT)); //L2Space<double> H_space(mesh, P_INIT)); SpaceSharedPtr<double> P_space(new HcurlSpace<double>(P_mesh, &bcs, P_INIT)); std::vector<SpaceSharedPtr<double> > spaces = std::vector<SpaceSharedPtr<double> >({ E_space, H_space, P_space }); // Initialize views. ScalarView E1_view("Solution E1", new WinGeom(0, 0, 400, 350)); E1_view.fix_scale_width(50); ScalarView E2_view("Solution E2", new WinGeom(410, 0, 400, 350)); E2_view.fix_scale_width(50); ScalarView H_view("Solution H", new WinGeom(0, 410, 400, 350)); H_view.fix_scale_width(50); ScalarView P1_view("Solution P1", new WinGeom(410, 410, 400, 350)); P1_view.fix_scale_width(50); ScalarView P2_view("Solution P2", new WinGeom(820, 410, 400, 350)); P2_view.fix_scale_width(50); // Visualize initial conditions. char title[100]; sprintf(title, "E1 - Initial Condition"); E1_view.set_title(title); E1_view.show(E_time_prev, H2D_FN_VAL_0); sprintf(title, "E2 - Initial Condition"); E2_view.set_title(title); E2_view.show(E_time_prev, H2D_FN_VAL_1); sprintf(title, "H - Initial Condition"); H_view.set_title(title); H_view.show(H_time_prev); sprintf(title, "P1 - Initial Condition"); P1_view.set_title(title); P1_view.show(P_time_prev, H2D_FN_VAL_0); sprintf(title, "P2 - Initial Condition"); P2_view.set_title(title); P2_view.show(P_time_prev, H2D_FN_VAL_1); // Initialize Runge-Kutta time stepping. RungeKutta<double> runge_kutta(wf, spaces, &bt); runge_kutta.set_newton_max_allowed_iterations(NEWTON_MAX_ITER); runge_kutta.set_newton_tolerance(NEWTON_TOL); runge_kutta.set_verbose_output(true); // Initialize refinement selector. H1ProjBasedSelector<double> H1selector(CAND_LIST); HcurlProjBasedSelector<double> HcurlSelector(CAND_LIST); // Time stepping loop. int ts = 1; do { // Perform one Runge-Kutta time step according to the selected Butcher's table. Hermes::Mixins::Loggable::Static::info("\nRunge-Kutta time step (t = %g s, time_step = %g s, stages: %d).", current_time, time_step, bt.get_size()); // Periodic global derefinements. if (ts > 1 && ts % UNREF_FREQ == 0 && REFINEMENT_COUNT > 0) { Hermes::Mixins::Loggable::Static::info("Global mesh derefinement."); REFINEMENT_COUNT = 0; E_space->unrefine_all_mesh_elements(true); H_space->unrefine_all_mesh_elements(true); P_space->unrefine_all_mesh_elements(true); E_space->adjust_element_order(-1, P_INIT); H_space->adjust_element_order(-1, P_INIT); P_space->adjust_element_order(-1, P_INIT); E_space->assign_dofs(); H_space->assign_dofs(); P_space->assign_dofs(); } // Adaptivity loop: int as = 1; bool done = false; do { Hermes::Mixins::Loggable::Static::info("Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. int order_increase = 1; Mesh::ReferenceMeshCreator refMeshCreatorE(E_mesh); Mesh::ReferenceMeshCreator refMeshCreatorH(H_mesh); Mesh::ReferenceMeshCreator refMeshCreatorP(P_mesh); MeshSharedPtr ref_mesh_E = refMeshCreatorE.create_ref_mesh(); MeshSharedPtr ref_mesh_H = refMeshCreatorH.create_ref_mesh(); MeshSharedPtr ref_mesh_P = refMeshCreatorP.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreatorE(E_space, ref_mesh_E, order_increase); SpaceSharedPtr<double> ref_space_E = refSpaceCreatorE.create_ref_space(); Space<double>::ReferenceSpaceCreator refSpaceCreatorH(H_space, ref_mesh_H, order_increase); SpaceSharedPtr<double> ref_space_H = refSpaceCreatorH.create_ref_space(); Space<double>::ReferenceSpaceCreator refSpaceCreatorP(P_space, ref_mesh_P, order_increase); SpaceSharedPtr<double> ref_space_P = refSpaceCreatorP.create_ref_space(); std::vector<SpaceSharedPtr<double> > ref_spaces({ ref_space_E, ref_space_H, ref_space_P }); int ndof = Space<double>::get_num_dofs(ref_spaces); Hermes::Mixins::Loggable::Static::info("ndof = %d.", ndof); try { runge_kutta.set_spaces(ref_spaces); runge_kutta.set_time(current_time); runge_kutta.set_time_step(time_step); runge_kutta.rk_time_step_newton(slns_time_prev, slns_time_new); } catch (Exceptions::Exception& e) { e.print_msg(); throw Hermes::Exceptions::Exception("Runge-Kutta time step failed"); } // Visualize the solutions. char title[100]; sprintf(title, "E1, t = %g", current_time + time_step); E1_view.set_title(title); E1_view.show(E_time_new, H2D_FN_VAL_0); sprintf(title, "E2, t = %g", current_time + time_step); E2_view.set_title(title); E2_view.show(E_time_new, H2D_FN_VAL_1); sprintf(title, "H, t = %g", current_time + time_step); H_view.set_title(title); H_view.show(H_time_new); sprintf(title, "P1, t = %g", current_time + time_step); P1_view.set_title(title); P1_view.show(P_time_new, H2D_FN_VAL_0); sprintf(title, "P2, t = %g", current_time + time_step); P2_view.set_title(title); P2_view.show(P_time_new, H2D_FN_VAL_1); // Project the fine mesh solution onto the coarse mesh. Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh."); OGProjection<double>::project_global({ E_space, H_space, P_space }, { E_time_new, H_time_new, P_time_new }, { E_time_new_coarse, H_time_new_coarse, P_time_new_coarse }); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); adaptivity.set_spaces({ E_space, H_space, P_space }); errorCalculator.calculate_errors({ E_time_new_coarse, H_time_new_coarse, P_time_new_coarse }, { E_time_new, H_time_new, P_time_new }); double err_est_rel_total = errorCalculator.get_total_error_squared() * 100.; // Report results. Hermes::Mixins::Loggable::Static::info("Error estimate: %g%%", err_est_rel_total); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) { Hermes::Mixins::Loggable::Static::info("Error estimate under the specified threshold -> moving to next time step."); done = true; } else { Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh."); REFINEMENT_COUNT++; done = adaptivity.adapt({ &HcurlSelector, &H1selector, &HcurlSelector }); if (!done) as++; } } while (!done); //View::wait(); E_time_prev->copy(E_time_new); H_time_prev->copy(H_time_new); P_time_prev->copy(P_time_new); // Update time. current_time += time_step; ts++; } while (current_time < T_FINAL); // Wait for the view to be closed. View::wait(); } catch (std::exception& e) { std::cout << e.what(); } return 0; }
int main(int argc, char* argv[]) { // Choose a Butcher's table or define your own. ButcherTable bt(butcher_table_type); if (bt.is_explicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage explicit R-K method.", bt.get_size()); if (bt.is_diagonally_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage diagonally implicit R-K method.", bt.get_size()); if (bt.is_fully_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage fully implicit R-K method.", bt.get_size()); // Load the mesh. MeshSharedPtr basemesh(new Mesh), T_mesh(new Mesh), w_mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", basemesh); // Create temperature and moisture meshes. // This also initializes the multimesh hp-FEM. T_mesh->copy(basemesh); w_mesh->copy(basemesh); // Initialize boundary conditions. EssentialBCNonConst temp_reactor("bdy_react", REACTOR_START_TIME, T_INITIAL, T_REACTOR_MAX); EssentialBCs<double> bcs_T(&temp_reactor); SpaceSharedPtr<double> T_space(new H1Space<double>(T_mesh, &bcs_T, P_INIT)); SpaceSharedPtr<double> w_space(new H1Space<double>(MULTI ? w_mesh : T_mesh, P_INIT)); std::vector<SpaceSharedPtr<double> > spaces({ T_space, w_space }); adaptivity.set_spaces(spaces); // Define constant initial conditions. Hermes::Mixins::Loggable::Static::info("Setting initial conditions."); MeshFunctionSharedPtr<double> T_time_prev(new ConstantSolution<double>(T_mesh, T_INITIAL)); MeshFunctionSharedPtr<double> w_time_prev(new ConstantSolution<double>(w_mesh, W_INITIAL)); MeshFunctionSharedPtr<double> T_time_new(new Solution<double>(T_mesh)); MeshFunctionSharedPtr<double> w_time_new(new Solution<double>(w_mesh)); // Solutions. MeshFunctionSharedPtr<double> T_coarse(new Solution<double>), w_coarse(new Solution<double>); // Initialize the weak formulation. WeakFormSharedPtr<double> wf(new CustomWeakFormHeatMoistureRK(c_TT, c_ww, d_TT, d_Tw, d_wT, d_ww, k_TT, k_ww, T_EXTERIOR, W_EXTERIOR, "bdy_ext")); // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST); // Geometry and position of visualization windows. WinGeom* T_sln_win_geom = new WinGeom(0, 0, 300, 450); WinGeom* w_sln_win_geom = new WinGeom(310, 0, 300, 450); WinGeom* T_mesh_win_geom = new WinGeom(620, 0, 280, 450); WinGeom* w_mesh_win_geom = new WinGeom(910, 0, 280, 450); // Initialize views. ScalarView T_sln_view("Temperature", T_sln_win_geom); ScalarView w_sln_view("Moisture (scaled)", w_sln_win_geom); OrderView T_order_view("Temperature mesh", T_mesh_win_geom); OrderView w_order_view("Moisture mesh", w_mesh_win_geom); // Show initial conditions. T_sln_view.show(T_time_prev); w_sln_view.show(w_time_prev); T_order_view.show(T_space); w_order_view.show(w_space); // Time stepping loop: int ts = 1; while (current_time < SIMULATION_TIME) { Hermes::Mixins::Loggable::Static::info("Simulation time = %g s (%d h, %d d, %d y)", current_time, (int)current_time / 3600, (int)current_time / (3600 * 24), (int)current_time / (3600 * 24 * 364)); // Update time-dependent essential BCs. if (current_time <= REACTOR_START_TIME) { Hermes::Mixins::Loggable::Static::info("Updating time-dependent essential BC."); Space<double>::update_essential_bc_values({ T_space, w_space }, current_time); } // Uniform mesh derefinement. if (ts > 1 && ts % UNREF_FREQ == 0) { Hermes::Mixins::Loggable::Static::info("Global mesh derefinement."); switch (UNREF_METHOD) { case 1: T_mesh->copy(basemesh); w_mesh->copy(basemesh); T_space->set_uniform_order(P_INIT); w_space->set_uniform_order(P_INIT); break; case 2: T_mesh->unrefine_all_elements(); if (MULTI) w_mesh->unrefine_all_elements(); T_space->set_uniform_order(P_INIT); w_space->set_uniform_order(P_INIT); break; case 3: T_mesh->unrefine_all_elements(); if (MULTI) w_mesh->unrefine_all_elements(); T_space->adjust_element_order(-1, -1, P_INIT, P_INIT); w_space->adjust_element_order(-1, -1, P_INIT, P_INIT); break; default: throw Hermes::Exceptions::Exception("Wrong global derefinement method."); } T_space->assign_dofs(); w_space->assign_dofs(); Space<double>::assign_dofs(spaces); } // Spatial adaptivity loop. Note: T_time_prev and w_time_prev must not be changed during // spatial adaptivity. bool done = false; int as = 1; do { Hermes::Mixins::Loggable::Static::info("Time step %d, adaptivity step %d:", ts, as); // Construct globally refined reference mesh and setup reference space. Mesh::ReferenceMeshCreator refMeshCreatorU(T_mesh); MeshSharedPtr ref_T_mesh = refMeshCreatorU.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreatorT(T_space, ref_T_mesh); SpaceSharedPtr<double> ref_T_space = refSpaceCreatorT.create_ref_space(); Mesh::ReferenceMeshCreator refMeshCreatorW(w_mesh); MeshSharedPtr ref_w_mesh = refMeshCreatorW.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreatorW(w_space, ref_w_mesh); SpaceSharedPtr<double> ref_w_space = refSpaceCreatorW.create_ref_space(); std::vector<SpaceSharedPtr<double> > ref_spaces({ ref_T_space, ref_w_space }); // Initialize Runge-Kutta time stepping. RungeKutta<double> runge_kutta(wf, ref_spaces, &bt); // Perform one Runge-Kutta time step according to the selected Butcher's table. Hermes::Mixins::Loggable::Static::info("Runge-Kutta time step (t = %g s, tau = %g s, stages: %d).", current_time, time_step, bt.get_size()); try { runge_kutta.set_time(current_time); runge_kutta.set_time_step(time_step); runge_kutta.set_newton_max_allowed_iterations(NEWTON_MAX_ITER); runge_kutta.set_newton_tolerance(NEWTON_TOL); runge_kutta.rk_time_step_newton({ T_time_prev, w_time_prev }, { T_time_new, w_time_new }); } catch (Exceptions::Exception& e) { e.print_msg(); throw Hermes::Exceptions::Exception("Runge-Kutta time step failed"); } // Project the fine mesh solution onto the coarse meshes. Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solutions on coarse meshes for error estimation."); OGProjection<double>::project_global({ T_space, w_space }, { T_time_new, w_time_new }, { T_coarse, w_coarse }); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); errorCalculator.calculate_errors({ T_coarse, w_coarse }, { T_time_new, w_time_new }); double err_est_rel_total = errorCalculator.get_total_error_squared() * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space<double>::get_num_dofs({ T_space, w_space }), Space<double>::get_num_dofs(ref_spaces), err_est_rel_total); // If err_est too large, adapt the meshes. if (err_est_rel_total < ERR_STOP) done = true; else { Hermes::Mixins::Loggable::Static::info("Adapting the coarse mesh."); done = adaptivity.adapt({ &selector, &selector }); // Increase the counter of performed adaptivity steps. as++; } } while (done == false); // Update time. current_time += time_step; // Show new coarse meshes and solutions. char title[100]; sprintf(title, "Temperature, t = %g days", current_time / 3600. / 24); T_sln_view.set_title(title); T_sln_view.show(T_coarse); sprintf(title, "Moisture (scaled), t = %g days", current_time / 3600. / 24); w_sln_view.set_title(title); w_sln_view.show(w_coarse); T_order_view.show(T_space); w_order_view.show(w_space); // Save fine mesh solutions for the next time step. T_time_prev->copy(T_time_new); w_time_prev->copy(w_time_new); ts++; } // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Time measurement. Hermes::Mixins::TimeMeasurable cpu_time; cpu_time.tick(); // Load the mesh. MeshSharedPtr u_mesh(new Mesh), v_mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", u_mesh); if (MULTI == false) u_mesh->refine_towards_boundary("Bdy", INIT_REF_BDY); // Create initial mesh (master mesh). v_mesh->copy(u_mesh); // Initial mesh refinements in the v_mesh towards the boundary. if (MULTI == true) v_mesh->refine_towards_boundary("Bdy", INIT_REF_BDY); // Set exact solutions. MeshFunctionSharedPtr<double> exact_u(new ExactSolutionFitzHughNagumo1(u_mesh)); MeshFunctionSharedPtr<double> exact_v(new ExactSolutionFitzHughNagumo2(MULTI ? v_mesh : u_mesh, K)); // Define right-hand sides. CustomRightHandSide1 g1(K, D_u, SIGMA); CustomRightHandSide2 g2(K, D_v); // Initialize the weak formulation. CustomWeakForm wf(&g1, &g2); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_u("Bdy", 0.0); EssentialBCs<double> bcs_u(&bc_u); DefaultEssentialBCConst<double> bc_v("Bdy", 0.0); EssentialBCs<double> bcs_v(&bc_v); // Create H1 spaces with default shapeset for both displacement components. SpaceSharedPtr<double> u_space(new H1Space<double>(u_mesh, &bcs_u, P_INIT_U)); SpaceSharedPtr<double> v_space(new H1Space<double>(MULTI ? v_mesh : u_mesh, &bcs_v, P_INIT_V)); // Initialize coarse and reference mesh solutions. MeshFunctionSharedPtr<double> u_sln(new Solution<double>()), v_sln(new Solution<double>()), u_ref_sln(new Solution<double>()), v_ref_sln(new Solution<double>()); Hermes::vector<MeshFunctionSharedPtr<double> > slns(u_sln, v_sln); Hermes::vector<MeshFunctionSharedPtr<double> > ref_slns(u_ref_sln, v_ref_sln); Hermes::vector<MeshFunctionSharedPtr<double> > exact_slns(exact_u, exact_v); // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST); //HOnlySelector<double> selector; // Initialize views. Views::ScalarView s_view_0("Solution[0]", new Views::WinGeom(0, 0, 440, 350)); s_view_0.show_mesh(false); Views::OrderView o_view_0("Mesh[0]", new Views::WinGeom(450, 0, 420, 350)); Views::ScalarView s_view_1("Solution[1]", new Views::WinGeom(880, 0, 440, 350)); s_view_1.show_mesh(false); Views::OrderView o_view_1("Mesh[1]", new Views::WinGeom(1330, 0, 420, 350)); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est; SimpleGraph graph_dof_exact, graph_cpu_exact; NewtonSolver<double> newton; newton.set_weak_formulation(&wf); // Adaptivity loop: int as = 1; bool done = false; do { Hermes::Mixins::Loggable::Static::info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space-> Mesh::ReferenceMeshCreator u_ref_mesh_creator(u_mesh); MeshSharedPtr u_ref_mesh = u_ref_mesh_creator.create_ref_mesh(); Mesh::ReferenceMeshCreator v_ref_mesh_creator(v_mesh); MeshSharedPtr v_ref_mesh = v_ref_mesh_creator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator u_ref_space_creator(u_space, u_ref_mesh); SpaceSharedPtr<double> u_ref_space = u_ref_space_creator.create_ref_space(); Space<double>::ReferenceSpaceCreator v_ref_space_creator(v_space, MULTI ? v_ref_mesh : u_ref_mesh); SpaceSharedPtr<double> v_ref_space = v_ref_space_creator.create_ref_space(); Hermes::vector<SpaceSharedPtr<double> > ref_spaces_const(u_ref_space, v_ref_space); newton.set_spaces(ref_spaces_const); int ndof_ref = Space<double>::get_num_dofs(ref_spaces_const); // Initialize reference problem. Hermes::Mixins::Loggable::Static::info("Solving on reference mesh."); // Time measurement. cpu_time.tick(); // Perform Newton's iteration. try { newton.solve(); } catch (Hermes::Exceptions::Exception& e) { std::cout << e.info(); } catch (std::exception& e) { std::cout << e.what(); } // Translate the resulting coefficient vector into the instance of Solution. Solution<double>::vector_to_solutions(newton.get_sln_vector(), ref_spaces_const, Hermes::vector<MeshFunctionSharedPtr<double> >(u_ref_sln, v_ref_sln)); // Project the fine mesh solution onto the coarse mesh. Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh."); OGProjection<double> ogProjection; ogProjection.project_global(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space), ref_slns, slns); cpu_time.tick(); // View the coarse mesh solution and polynomial orders. s_view_0.show(u_sln); o_view_0.show(u_space); s_view_1.show(v_sln); o_view_1.show(v_space); // Calculate element errors. Hermes::Mixins::Loggable::Static::info("Calculating error estimate and exact error."); errorCalculator.calculate_errors(slns, exact_slns, false); double err_exact_rel_total = errorCalculator.get_total_error_squared() * 100; Hermes::vector<double> err_exact_rel; err_exact_rel.push_back(errorCalculator.get_error_squared(0) * 100); err_exact_rel.push_back(errorCalculator.get_error_squared(1) * 100); errorCalculator.calculate_errors(slns, ref_slns, true); double err_est_rel_total = errorCalculator.get_total_error_squared() * 100; Hermes::vector<double> err_est_rel; err_est_rel.push_back(errorCalculator.get_error_squared(0) * 100); err_est_rel.push_back(errorCalculator.get_error_squared(1) * 100); adaptivity.set_spaces(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space)); // Time measurement. cpu_time.tick(); // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse[0]: %d, ndof_fine[0]: %d", u_space->get_num_dofs(), u_ref_space->get_num_dofs()); Hermes::Mixins::Loggable::Static::info("err_est_rel[0]: %g%%, err_exact_rel[0]: %g%%", err_est_rel[0], err_exact_rel[0]); Hermes::Mixins::Loggable::Static::info("ndof_coarse[1]: %d, ndof_fine[1]: %d", v_space->get_num_dofs(), v_ref_space->get_num_dofs()); Hermes::Mixins::Loggable::Static::info("err_est_rel[1]: %g%%, err_exact_rel[1]: %g%%", err_est_rel[1], err_exact_rel[1]); Hermes::Mixins::Loggable::Static::info("ndof_coarse_total: %d, ndof_fine_total: %d", Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space)), Space<double>::get_num_dofs(ref_spaces_const)); Hermes::Mixins::Loggable::Static::info("err_est_rel_total: %g%%, err_est_exact_total: %g%%", err_est_rel_total, err_exact_rel_total); // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space)), err_est_rel_total); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel_total); graph_cpu_est.save("conv_cpu_est.dat"); graph_dof_exact.add_values(Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space)), err_exact_rel_total); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel_total); graph_cpu_exact.save("conv_cpu_exact.dat"); // If err_est too large, adapt the mesh-> if (err_est_rel_total < ERR_STOP) done = true; else { Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh."); Hermes::vector<RefinementSelectors::Selector<double> *> selectors(&selector, &selector); done = adaptivity.adapt(selectors); } // Increase counter. as++; } while (done == false); Hermes::Mixins::Loggable::Static::info("Total running time: %g s", cpu_time.accumulated()); // Wait for all views to be closed. Views::View::wait(); return 0; }