int main(int argc, char* argv[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", mesh); // Define exact solution. MeshFunctionSharedPtr<double> exact_sln(new CustomExactSolution(mesh)); // Initialize the weak formulation. CustomWeakForm wf("Right"); // Initialize boundary conditions. DefaultEssentialBCConst<double> bc_essential("Left", 0.0); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); // Set the space to adaptivity. adaptivity.set_space(space); // Initialize approximate solution. MeshFunctionSharedPtr<double> sln(new Solution<double>()); // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST); // Initialize views. Views::ScalarView sview("Solution", new Views::WinGeom(0, 0, 440, 350)); sview.show_mesh(false); sview.fix_scale_width(50); Views::OrderView oview("Polynomial orders", new Views::WinGeom(450, 0, 420, 350)); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est, graph_dof_exact, graph_cpu_exact; // Time measurement. Hermes::Mixins::TimeMeasurable cpu_time; cpu_time.tick(); // Adaptivity loop: int as = 1; bool done = false; do { cpu_time.tick(); // Construct globally refined reference mesh and setup reference space. Mesh::ReferenceMeshCreator refMeshCreator(mesh); MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh); SpaceSharedPtr<double> ref_space = refSpaceCreator.create_ref_space(); int ndof_ref = ref_space->get_num_dofs(); Hermes::Mixins::Loggable::Static::info("---- Adaptivity step %d (%d DOF):", as, ndof_ref); cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Solving on reference mesh."); // Assemble the discrete problem. DiscreteProblem<double> dp(&wf, ref_space); NewtonSolver<double> newton(&dp); //newton.set_verbose_output(false); MeshFunctionSharedPtr<double> ref_sln(new Solution<double>()); try { newton.solve(); } catch(Hermes::Exceptions::Exception e) { e.print_msg(); throw Hermes::Exceptions::Exception("Newton's iteration failed."); }; // Translate the resulting coefficient vector into the instance of Solution. Solution<double>::vector_to_solution(newton.get_sln_vector(), ref_space, ref_sln); cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Solution: %g s", cpu_time.last()); // Project the fine mesh solution onto the coarse mesh. Hermes::Mixins::Loggable::Static::info("Calculating error estimate and exact error."); OGProjection<double> ogProjection; ogProjection.project_global(space, ref_sln, sln); // Calculate element errors and total error estimate. errorCalculator.calculate_errors(sln, exact_sln, false); double err_exact_rel = errorCalculator.get_total_error_squared() * 100; errorCalculator.calculate_errors(sln, ref_sln, true); double err_est_rel = errorCalculator.get_total_error_squared() * 100; cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Error calculation: %g s", cpu_time.last()); // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d", space->get_num_dofs(), ref_space->get_num_dofs()); Hermes::Mixins::Loggable::Static::info("err_est_rel: %g%%, err_exact_rel: %g%%", err_est_rel, err_exact_rel); // Time measurement. cpu_time.tick(); double accum_time = cpu_time.accumulated(); // View the coarse mesh solution and polynomial orders. sview.show(sln); oview.show(space); // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(space->get_num_dofs(), err_est_rel); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(accum_time, err_est_rel); graph_cpu_est.save("conv_cpu_est.dat"); graph_dof_exact.add_values(space->get_num_dofs(), err_exact_rel); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.add_values(accum_time, err_exact_rel); graph_cpu_exact.save("conv_cpu_exact.dat"); cpu_time.tick(Hermes::Mixins::TimeMeasurable::HERMES_SKIP); // If err_est too large, adapt the mesh. The NDOF test must be here, so that the solution may be visualized // after ending due to this criterion. if (err_exact_rel < ERR_STOP) done = true; else done = adaptivity.adapt(&selector); cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Adaptation: %g s", cpu_time.last()); // Increase the counter of adaptivity steps. if (done == false) 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(); }
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 mesh(new Mesh), basemesh(new Mesh); MeshReaderH2D mloader; mloader.load("square.mesh", basemesh); mesh->copy(basemesh); // Initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh->refine_all_elements(); mesh->refine_towards_boundary("Top", INIT_REF_NUM_BDY); // Initialize boundary conditions. CustomEssentialBCNonConst bc_essential(Hermes::vector<std::string>("Bottom", "Right", "Top", "Left")); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); int ndof_coarse = Space<double>::get_num_dofs(space); adaptivity.set_space(space); Hermes::Mixins::Loggable::Static::info("ndof_coarse = %d.", ndof_coarse); // Zero initial solution. This is why we use H_OFFSET. MeshFunctionSharedPtr<double> h_time_prev(new ZeroSolution<double>(mesh)), h_time_new(new ZeroSolution<double>(mesh)); // Initialize the constitutive relations. ConstitutiveRelations* constitutive_relations; if(constitutive_relations_type == CONSTITUTIVE_GENUCHTEN) constitutive_relations = new ConstitutiveRelationsGenuchten(ALPHA, M, N, THETA_S, THETA_R, K_S, STORATIVITY); else constitutive_relations = new ConstitutiveRelationsGardner(ALPHA, THETA_S, THETA_R, K_S); // Initialize the weak formulation. CustomWeakFormRichardsRK wf(constitutive_relations); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, space); // Create a refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST); // Visualize initial condition. char title[100]; ScalarView view("Initial condition", new WinGeom(0, 0, 440, 350)); OrderView ordview("Initial mesh", new WinGeom(445, 0, 440, 350)); view.show(h_time_prev); ordview.show(space); // DOF and CPU convergence graphs initialization. SimpleGraph graph_dof, graph_cpu; // Time measurement. Hermes::Mixins::TimeMeasurable cpu_time; cpu_time.tick(); // Time stepping loop. double current_time = 0; int ts = 1; do { // Periodic global derefinement. if (ts > 1 && ts % UNREF_FREQ == 0) { Hermes::Mixins::Loggable::Static::info("Global mesh derefinement."); switch (UNREF_METHOD) { case 1: mesh->copy(basemesh); space->set_uniform_order(P_INIT); break; case 2: mesh->unrefine_all_elements(); space->set_uniform_order(P_INIT); break; case 3: space->unrefine_all_mesh_elements(); space->adjust_element_order(-1, -1, P_INIT, P_INIT); break; default: throw Hermes::Exceptions::Exception("Wrong global derefinement method."); } space->assign_dofs(); ndof_coarse = Space<double>::get_num_dofs(space); } // Spatial adaptivity loop. Note: h_time_prev must not be changed // during spatial adaptivity. bool done = false; int as = 1; double err_est; 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 refMeshCreator(mesh); MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh); SpaceSharedPtr<double> ref_space = refSpaceCreator.create_ref_space(); int ndof_ref = Space<double>::get_num_dofs(ref_space); // Time measurement. cpu_time.tick(); // Initialize Runge-Kutta time stepping. RungeKutta<double> runge_kutta(&wf, ref_space, &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_max_allowed_iterations(NEWTON_MAX_ITER); runge_kutta.set_tolerance(NEWTON_TOL); runge_kutta.rk_time_step_newton(h_time_prev, h_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 mesh. MeshFunctionSharedPtr<double> sln_coarse(new Solution<double>); Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh for error estimation."); OGProjection<double> ogProjection; ogProjection.project_global(space, h_time_new, sln_coarse); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); errorCalculator.calculate_errors(sln_coarse, h_time_new, true); double err_est_rel_total = errorCalculator.get_total_error_squared() * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_ref: %d, err_est_rel: %g%%", Space<double>::get_num_dofs(space), Space<double>::get_num_dofs(ref_space), err_est_rel_total); // Time measurement. cpu_time.tick(); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) done = true; else { Hermes::Mixins::Loggable::Static::info("Adapting the coarse mesh."); done = adaptivity.adapt(&selector); // Increase the counter of performed adaptivity steps. as++; } } while (done == false); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(current_time, Space<double>::get_num_dofs(space)); graph_dof.save("conv_dof_est.dat"); graph_cpu.add_values(current_time, cpu_time.accumulated()); graph_cpu.save("conv_cpu_est.dat"); // Visualize the solution and mesh-> char title[100]; sprintf(title, "Solution, time %g", current_time); view.set_title(title); view.show_mesh(false); view.show(h_time_new); sprintf(title, "Mesh, time %g", current_time); ordview.set_title(title); ordview.show(space); // Copy last reference solution into h_time_prev. h_time_prev->copy(h_time_new); // Increase current time and counter of time steps. current_time += time_step; ts++; } while (current_time < T_FINAL); // Wait for all views to be closed. View::wait(); 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 mesh(new Mesh), basemesh(new Mesh); MeshReaderH2D mloader; mloader.load("square.mesh", basemesh); // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) basemesh->refine_all_elements(0, true); mesh->copy(basemesh); // Initialize boundary conditions. EssentialBCNonConst bc_essential("Bdy"); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); adaptivity.set_space(space); int ndof_coarse = space->get_num_dofs(); // Previous time level solution (initialized by initial condition). MeshFunctionSharedPtr<double> sln_time_prev(new CustomInitialCondition(mesh)); // Initialize the weak formulation CustomNonlinearity lambda(alpha); Hermes2DFunction<double> f(heat_src); WeakFormSharedPtr<double> wf(new CustomWeakFormPoisson(&lambda, &f)); // Next time level solution. MeshFunctionSharedPtr<double> sln_time_new(new Solution<double>(mesh)); // Create a refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST); // Visualize initial condition. ScalarView view("Initial condition", new WinGeom(0, 0, 440, 350)); OrderView ordview("Initial mesh", new WinGeom(445, 0, 410, 350)); if (HERMES_VISUALIZATION) { view.show(sln_time_prev); ordview.show(space); } // Initialize Runge-Kutta time stepping. RungeKutta<double> runge_kutta(wf, space, &bt); // Time stepping loop. double current_time = 0; int ts = 1; do { // Periodic global derefinement. if (ts > 1 && ts % UNREF_FREQ == 0) { Hermes::Mixins::Loggable::Static::info("Global mesh derefinement."); switch (UNREF_METHOD) { case 1: mesh->copy(basemesh); space->set_uniform_order(P_INIT); break; case 2: mesh->unrefine_all_elements(); space->set_uniform_order(P_INIT); break; case 3: mesh->unrefine_all_elements(); space->adjust_element_order(-1, -1, P_INIT, P_INIT); break; } space->assign_dofs(); ndof_coarse = Space<double>::get_num_dofs(space); } // Spatial adaptivity loop. Note: sln_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 ref_mesh_creator(mesh); MeshSharedPtr ref_mesh = ref_mesh_creator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator ref_space_creator(space, ref_mesh); SpaceSharedPtr<double> ref_space = ref_space_creator.create_ref_space(); int ndof_ref = Space<double>::get_num_dofs(ref_space); // Perform one Runge-Kutta time step according to the selected Butcher's table. try { runge_kutta.set_space(ref_space); runge_kutta.set_verbose_output(true); runge_kutta.set_time(current_time); runge_kutta.set_time_step(time_step); runge_kutta.set_tolerance(NEWTON_TOL); runge_kutta.rk_time_step_newton(sln_time_prev, sln_time_new); } catch (Exceptions::Exception& e) { std::cout << e.info(); } catch (std::exception& e) { std::cout << e.what(); } // Project the fine mesh solution onto the coarse mesh. MeshFunctionSharedPtr<double> sln_coarse(new Solution<double>()); Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh for error estimation."); OGProjection<double> ogProjection; ogProjection.project_global(space, sln_time_new, sln_coarse); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); errorCalculator.calculate_errors(sln_coarse, sln_time_new); double err_est_rel = errorCalculator.get_total_error_squared() * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_ref: %d, err_est_rel: %g%%", Space<double>::get_num_dofs(space), Space<double>::get_num_dofs(ref_space), err_est_rel); // If err_est too large, adapt the mesh-> if (err_est_rel < ERR_STOP) done = true; else { Hermes::Mixins::Loggable::Static::info("Adapting the coarse mesh."); done = adaptivity.adapt(&selector); as++; } if (HERMES_VISUALIZATION) { // Visualize the solution and mesh-> char title[100]; sprintf(title, "Solution<double>, time %g", current_time); view.set_title(title); view.show_mesh(false); view.show(sln_time_new); sprintf(title, "Mesh, time %g", current_time); ordview.set_title(title); ordview.show(space); } } while (done == false); sln_time_prev->copy(sln_time_new); // Increase current time and counter of time steps. current_time += time_step; ts++; } while (current_time < T_FINAL); // Wait for all views to be closed. if (HERMES_VISUALIZATION) View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", mesh); // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh->refine_all_elements(); // Initialize boundary conditions. Hermes::Hermes2D::DefaultEssentialBCConst<complex> bc_essential("Dirichlet", complex(0.0, 0.0)); EssentialBCs<complex> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<complex> space(new H1Space<complex>(mesh, &bcs, P_INIT)); // Initialize the weak formulation. CustomWeakForm wf("Air", MU_0, "Iron", MU_IRON, GAMMA_IRON, "Wire", MU_0, complex(J_EXT, 0.0), OMEGA); // Initialize coarse and reference mesh solution. MeshFunctionSharedPtr<complex> sln(new Hermes::Hermes2D::Solution<complex>()); MeshFunctionSharedPtr<complex> ref_sln(new Hermes::Hermes2D::Solution<complex>()); // Initialize refinement selector. H1ProjBasedSelector<complex> selector(CAND_LIST); // DOF and CPU convergence graphs initialization. SimpleGraph graph_dof, graph_cpu; DiscreteProblem<complex> dp(&wf, space); // Perform Newton's iteration and translate the resulting coefficient vector into a Solution. Hermes::Hermes2D::NewtonSolver<complex> newton(&dp); // Adaptivity loop: int as = 1; bool done = false; adaptivity.set_space(space); do { // Construct globally refined reference mesh and setup reference space-> Mesh::ReferenceMeshCreator ref_mesh_creator(mesh); MeshSharedPtr ref_mesh = ref_mesh_creator.create_ref_mesh(); Space<complex>::ReferenceSpaceCreator ref_space_creator(space, ref_mesh); SpaceSharedPtr<complex> ref_space = ref_space_creator.create_ref_space(); newton.set_space(ref_space); int ndof_ref = ref_space->get_num_dofs(); // Initialize reference problem. // Initial coefficient vector for the Newton's method. complex* coeff_vec = new complex[ndof_ref]; memset(coeff_vec, 0, ndof_ref * sizeof(complex)); // Perform Newton's iteration and translate the resulting coefficient vector into a Solution. try { newton.solve(coeff_vec); } catch(Hermes::Exceptions::Exception& e) { e.print_msg(); } Hermes::Hermes2D::Solution<complex>::vector_to_solution(newton.get_sln_vector(), ref_space, ref_sln); // Project the fine mesh solution onto the coarse mesh. OGProjection<complex> ogProjection; ogProjection.project_global(space, ref_sln, sln); // Calculate element errors and total error estimate. errorCalculator.calculate_errors(sln, ref_sln); // If err_est too large, adapt the mesh-> if(errorCalculator.get_total_error_squared() * 100. < ERR_STOP) done = true; else { adaptivity.adapt(&selector); } // Clean up. delete [] coeff_vec; // Increase counter. as++; } while (done == false); complex sum = 0; for (int i = 0; i < space->get_num_dofs(); i++) sum += newton.get_sln_vector()[i]; printf("coefficient sum = %f\n", sum); complex expected_sum; expected_sum.real(1.4685364e-005); expected_sum.imag(-5.45632171e-007); bool success = true; if(std::abs(sum - expected_sum) > 1e-6) success = false; int ndof = space->get_num_dofs(); if(ndof != 82) // Tested value as of May 2013. success = false; if(success) { printf("Success!\n"); return 0; } else { printf("Failure!\n"); return -1; } }
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; }
int main(int argc, char* args[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("square.mesh", mesh); // Perform initial mesh refinement. for (int i=0; i<INIT_REF; i++) mesh->refine_all_elements(); // Create an L2 space-> SpaceSharedPtr<double> space(new L2Space<double>(mesh, P_INIT)); // Initialize refinement selector. L2ProjBasedSelector<double> selector(CAND_LIST); // Display the mesh. #ifdef SHOW_OUTPUT OrderView oview("Coarse mesh", new WinGeom(0, 0, 440, 350)); oview.show(space); #endif MeshFunctionSharedPtr<double> sln(new Solution<double>); MeshFunctionSharedPtr<double> ref_sln(new Solution<double>); // Initialize the weak formulation. CustomWeakForm wf("Bdy_bottom_left", mesh); #ifdef SHOW_OUTPUT ScalarView view1("Solution", new WinGeom(900, 0, 450, 350)); view1.fix_scale_width(60); #endif // Initialize linear solver. Hermes::Hermes2D::LinearSolver<double> linear_solver(&wf, space); int as = 1; bool done = false; do { // Construct globally refined reference mesh // and setup reference space-> Mesh::ReferenceMeshCreator ref_mesh_creator(mesh); MeshSharedPtr ref_mesh = ref_mesh_creator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator ref_space_creator(space, ref_mesh); SpaceSharedPtr<double> ref_space = ref_space_creator.create_ref_space(); ref_space->save("space-real.xml"); ref_space->free(); ref_space->load("space-real.xml"); #ifdef WITH_BSON ref_space->save_bson("space-real.bson"); ref_space->free(); ref_space->load_bson("space-real.bson"); #endif linear_solver.set_space(ref_space); // Solve the linear system. If successful, obtain the solution. linear_solver.solve(); Solution<double>::vector_to_solution(linear_solver.get_sln_vector(), ref_space, ref_sln); // Project the fine mesh solution onto the coarse mesh. OGProjection<double> ogProjection; ogProjection.project_global(space, ref_sln, sln, HERMES_L2_NORM); #ifdef SHOW_OUTPUT MeshFunctionSharedPtr<double> val_filter(new ValFilter(ref_sln, 0.0, 1.0)); // View the coarse mesh solution. view1.show(val_filter); oview.show(space); #endif // Calculate element errors and total error estimate. errorCalculator.calculate_errors(sln, ref_sln); double err_est_rel = errorCalculator.get_total_error_squared() * 100; adaptivity.set_space(space); #ifdef SHOW_OUTPUT std::cout << "Error: " << err_est_rel << "%." << std::endl; #endif // If err_est_rel too large, adapt the mesh-> if(err_est_rel < ERR_STOP) done = true; else done = adaptivity.adapt(&selector); as++; } while (done == false); // Wait for keyboard or mouse input. #ifdef SHOW_OUTPUT View::wait(); #endif return as; }
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 mesh(new Mesh), basemesh(new Mesh); MeshReaderH1DXML mloader; try { mloader.load("domain.xml", basemesh); } catch (Hermes::Exceptions::MeshLoadFailureException& e) { e.print_msg(); return -1; } // Perform initial mesh refinements. int refinement_type = 2; // Split elements vertically. for (int i = 0; i < INIT_REF_NUM; i++) basemesh->refine_all_elements(refinement_type, true); mesh->copy(basemesh); // Exact solution. CustomExactSolution exact_sln(mesh, x_0, x_1, y_0, y_1, ¤t_time, s, c); // Initialize boundary conditions. DefaultEssentialBCConst<double> bc_essential(std::vector<std::string>({ "Left", "Right" }), 0); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); int ndof_coarse = space->get_num_dofs(); // Initialize the weak formulation CustomFunction f(x_0, x_1, y_0, y_1, s, c); WeakFormSharedPtr<double> wf(new CustomWeakFormPoisson(new Hermes::Hermes1DFunction<double>(-1.0), &f)); // Previous and next time level solution. MeshFunctionSharedPtr<double> sln_time_prev(new ZeroSolution<double>(mesh)); MeshFunctionSharedPtr<double> sln_time_new(new Solution<double>(mesh)); // Create a refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST); // Visualize initial condition. char title[100]; Views::ScalarView sview("Initial condition", new Views::WinGeom(0, 0, 1200, 200)); Views::OrderView oview("Initial mesh", new Views::WinGeom(0, 260, 1200, 200)); sview.show(sln_time_prev); oview.show(space); // Graph for dof history. SimpleGraph dof_history_graph; // Time stepping loop. int ts = 1; do { // Periodic global derefinement. if (ts > 1 && ts % UNREF_FREQ == 0) { Hermes::Mixins::Loggable::Static::info("Global mesh derefinement."); switch (UNREF_METHOD) { case 1: mesh->copy(basemesh); space->set_uniform_order(P_INIT); break; case 2: mesh->unrefine_all_elements(); space->set_uniform_order(P_INIT); break; case 3: mesh->unrefine_all_elements(); space->adjust_element_order(-1, -1, P_INIT, P_INIT); break; default: throw Hermes::Exceptions::Exception("Wrong global derefinement method."); } space->assign_dofs(); ndof_coarse = space->get_num_dofs(); } // Spatial adaptivity loop. Note: sln_time_prev must not be changed // during spatial adaptivity. bool done = false; int as = 1; double err_est; do { Hermes::Mixins::Loggable::Static::info("Time step %d, adaptivity step %d:", ts, as); // Construct globally refined reference mesh and setup reference space. // FIXME: This should be increase in the x-direction only. int order_increase = 1; // FIXME: This should be '2' but that leads to a segfault. int refinement_type = 0; Mesh::ReferenceMeshCreator refMeshCreator(mesh); MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh); SpaceSharedPtr<double> ref_space = refSpaceCreator.create_ref_space(); int ndof_ref = ref_space->get_num_dofs(); // Initialize Runge-Kutta time stepping. RungeKutta<double> runge_kutta(wf, ref_space, &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()); bool freeze_jacobian = true; bool block_diagonal_jacobian = false; bool verbose = true; try { runge_kutta.set_time(current_time); runge_kutta.set_verbose_output(true); 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(sln_time_prev, sln_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 mesh. MeshFunctionSharedPtr<double> sln_coarse(new Solution<double>); Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh for error estimation."); OGProjection<double>::project_global(space, sln_time_new, sln_coarse); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); adaptivity.set_space(space); errorCalculator.calculate_errors(sln_coarse, sln_time_new); double err_est_rel_total = errorCalculator.get_total_error_squared() * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_ref: %d, err_est_rel: %g%%", space->get_num_dofs(), ref_space->get_num_dofs(), err_est_rel_total); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) done = true; else { Hermes::Mixins::Loggable::Static::info("Adapting the coarse mesh."); done = adaptivity.adapt(&selector); // Increase the counter of performed adaptivity steps. as++; } } while (done == false); // Visualize the solution and mesh. char title[100]; sprintf(title, "Solution, time %g", current_time); sview.set_title(title); sview.show_mesh(false); sview.show(sln_time_new); sprintf(title, "Mesh, time %g", current_time); oview.set_title(title); oview.show(space); // Copy last reference solution into sln_time_prev-> sln_time_prev->copy(sln_time_new); dof_history_graph.add_values(current_time, space->get_num_dofs()); dof_history_graph.save("dof_history.dat"); // Increase current time and counter of time steps. current_time += time_step; ts++; } while (current_time < T_FINAL); // Wait for all views to be closed. Views::View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", mesh); // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh->refine_all_elements(); // Initialize boundary conditions. Hermes::Hermes2D::DefaultEssentialBCConst<complex> bc_essential("Dirichlet", complex(0.0, 0.0)); EssentialBCs<complex> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<complex> space(new H1Space<complex>(mesh, &bcs, P_INIT)); int ndof = space->get_num_dofs(); // Initialize the weak formulation. CustomWeakForm wf("Air", MU_0, "Iron", MU_IRON, GAMMA_IRON, "Wire", MU_0, complex(J_EXT, 0.0), OMEGA); // Initialize coarse and reference mesh solution. MeshFunctionSharedPtr<complex> sln(new Hermes::Hermes2D::Solution<complex>()); MeshFunctionSharedPtr<complex> ref_sln(new Hermes::Hermes2D::Solution<complex>()); // Initialize refinement selector. H1ProjBasedSelector<complex> selector(CAND_LIST); // Initialize views. #ifdef SHOW_OUTPUT Views::ScalarView sview("Solution", new Views::WinGeom(0, 0, 600, 350)); Views::ScalarView sview2("Ref. Solution", new Views::WinGeom(0, 0, 600, 350)); Views::OrderView oview("Polynomial orders", new Views::WinGeom(610, 0, 520, 350)); #endif DiscreteProblem<complex> dp(&wf, space); // Perform Newton's iteration and translate the resulting coefficient vector into a Solution. Hermes::Hermes2D::NewtonSolver<complex> newton(&dp); // Adaptivity loop: int as = 1; bool done = false; adaptivity.set_space(space); do { // Construct globally refined reference mesh and setup reference space-> Mesh::ReferenceMeshCreator ref_mesh_creator(mesh); MeshSharedPtr ref_mesh = ref_mesh_creator.create_ref_mesh(); Space<complex>::ReferenceSpaceCreator ref_space_creator(space, ref_mesh); SpaceSharedPtr<complex> ref_space = ref_space_creator.create_ref_space(); newton.set_space(ref_space); ref_space->save("space-complex.xml"); ref_space->free(); ref_space->load("space-complex.xml"); #ifdef WITH_BSON ref_space->save_bson("space-complex.bson"); ref_space->free(); ref_space->load_bson("space-complex.bson"); #endif int ndof_ref = ref_space->get_num_dofs(); // Initialize reference problem. // Initial coefficient vector for the Newton's method. complex* coeff_vec = new complex[ndof_ref]; memset(coeff_vec, 0, ndof_ref * sizeof(complex)); // Perform Newton's iteration and translate the resulting coefficient vector into a Solution. SpaceSharedPtr<complex> space_test = Space<complex>::load("space-complex.xml", ref_mesh, false, &bcs); newton.set_space(space_test); newton.solve(coeff_vec); Hermes::Hermes2D::Solution<complex>::vector_to_solution(newton.get_sln_vector(), ref_space, ref_sln); // Project the fine mesh solution onto the coarse mesh. OGProjection<complex> ogProjection; #ifdef WITH_BSON space->save_bson("space-complex-coarse.bson"); SpaceSharedPtr<complex> space_test2 = Space<complex>::load_bson("space-complex-coarse.bson", mesh, &bcs); ogProjection.project_global(space_test2, ref_sln, sln); #else space->save("space-complex-coarse.xml2"); SpaceSharedPtr<complex> space_test2 = Space<complex>::load("space-complex-coarse.xml2", mesh, false, &bcs); ogProjection.project_global(space_test2, ref_sln, sln); #endif // View the coarse mesh solution and polynomial orders. #ifdef SHOW_OUTPUT MeshFunctionSharedPtr<double> real_filter(new RealFilter(sln)); MeshFunctionSharedPtr<double> rreal_filter(new RealFilter(ref_sln)); sview2.show(rreal_filter); oview.show(space); #endif // Calculate element errors and total error estimate. errorCalculator.calculate_errors(sln, ref_sln); #ifdef SHOW_OUTPUT std::cout << "Relative error: " << errorCalculator.get_total_error_squared() * 100. << '%' << std::endl; #endif // Add entry to DOF and CPU convergence graphs. #ifdef SHOW_OUTPUT sview.show(errorCalculator.get_errorMeshFunction()); #endif // If err_est too large, adapt the mesh-> if(errorCalculator.get_total_error_squared() * 100. < ERR_STOP) done = true; else { std::cout << "Adapting..." << std::endl << std::endl; adaptivity.adapt(&selector); } // Clean up. delete [] coeff_vec; // Increase counter. as++; } while (done == false); #ifdef SHOW_OUTPUT // Show the reference solution - the final result. sview.set_title("Fine mesh solution"); MeshFunctionSharedPtr<double> real_filter(new RealFilter(ref_sln)); sview.show(real_filter); // Wait for all views to be closed. Views::View::wait(); #endif return as; }
int main(int argc, char* argv[]) { #ifdef THREAD_TESTING HermesCommonApi.set_integral_param_value(numThreads, 8); #endif // Load the mesh. MeshSharedPtr mesh(new Mesh); Hermes::vector<MeshSharedPtr> meshes; meshes.push_back(mesh); MeshReaderH2DXML mloader; mloader.load("agrosMesh.msh", meshes); // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh->refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst<complex> bc_essential("4", P_SOURCE); EssentialBCs<complex> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<complex> space(new H1Space<complex> (mesh, &bcs, P_INIT)); adaptivity.set_space(space); // Initialize the weak formulation. CustomWeakFormAcoustics wf("0", RHO, SOUND_SPEED, OMEGA); // Initialize coarse and reference mesh solution. MeshFunctionSharedPtr<complex> sln(new Solution<complex>), ref_sln(new Solution<complex>); // Initialize refinement selector. H1ProjBasedSelector<complex> selector(CAND_LIST); Hermes::Hermes2D::NewtonSolver<complex> newton; newton.set_weak_formulation(&wf); // 2 Adaptivity steps: int as = 1; bool done = false; do { // Construct globally refined reference mesh and setup reference space. Mesh::ReferenceMeshCreator refMeshCreator(mesh); MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh(); Space<complex>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh); SpaceSharedPtr<complex> ref_space = refSpaceCreator.create_ref_space(); // Perform Newton's iteration. try { newton.set_space(ref_space); newton.solve(); } catch(Hermes::Exceptions::Exception& e) { e.print_msg(); throw Hermes::Exceptions::Exception("Newton's iteration failed."); }; // Translate the resulting coefficient vector into the Solution<complex> sln-> Hermes::Hermes2D::Solution<complex>::vector_to_solution(newton.get_sln_vector(), ref_space, ref_sln); // Project the fine mesh solution onto the coarse mesh. OGProjection<complex> ogProjection; ogProjection.project_global(space, ref_sln, sln); // Calculate element errors and total error estimate. errorCalculator.calculate_errors(sln, ref_sln); adaptivity.adapt(&selector); } while (as++ < 2); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", mesh); // Initialize the weak formulation. CustomWeakFormPoisson wf("Motor", EPS_MOTOR, "Air", EPS_AIR); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_essential_out("Outer", 0.0); DefaultEssentialBCConst<double> bc_essential_stator("Stator", VOLTAGE); EssentialBCs<double> bcs(Hermes::vector<EssentialBoundaryCondition<double> *>(&bc_essential_out, &bc_essential_stator)); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); // Set the space to adaptivity. adaptivity.set_space(space); // Initialize coarse and fine mesh solution. MeshFunctionSharedPtr<double> sln(new Solution<double>), ref_sln(new Solution<double>); // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, H2DRS_DEFAULT_ORDER); // Initialize views. Views::ScalarView sview("Solution", new Views::WinGeom(0, 0, 410, 600)); sview.fix_scale_width(50); sview.show_mesh(false); Views::OrderView oview("Polynomial orders", new Views::WinGeom(420, 0, 400, 600)); // DOF and CPU convergence graphs initialization. SimpleGraph graph_dof, graph_cpu; // Time measurement. Hermes::Mixins::TimeMeasurable cpu_time; DiscreteProblem<double> dp(&wf, space); NewtonSolver<double> newton(&dp); newton.set_verbose_output(true); // Adaptivity loop: int as = 1; bool done = false; do { Hermes::Mixins::Loggable::Static::info("---- Adaptivity step %d:", as); // Time measurement. cpu_time.tick(); // Construct globally refined mesh and setup fine mesh space. Mesh::ReferenceMeshCreator ref_mesh_creator(mesh); MeshSharedPtr ref_mesh = ref_mesh_creator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator ref_space_creator(space, ref_mesh); SpaceSharedPtr<double> ref_space = ref_space_creator.create_ref_space(); int ndof_ref = ref_space->get_num_dofs(); // Initialize fine mesh problem. Hermes::Mixins::Loggable::Static::info("Solving on fine mesh."); newton.set_space(ref_space); // Perform Newton's iteration. try { newton.solve(); } catch(std::exception& e) { std::cout << e.what(); } // Translate the resulting coefficient vector into the instance of Solution. Solution<double>::vector_to_solution(newton.get_sln_vector(), ref_space, ref_sln); // Project the fine mesh solution onto the coarse mesh. Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh."); OGProjection<double>::project_global(space, ref_sln, sln); // Time measurement. cpu_time.tick(); // VTK output. if (VTK_VISUALIZATION) { // Output solution in VTK format. Views::Linearizer lin; char* title = new char[100]; sprintf(title, "sln-%d.vtk", as); lin.save_solution_vtk(ref_sln, title, "Potential", false); Hermes::Mixins::Loggable::Static::info("Solution in VTK format saved to file %s.", title); // Output mesh and element orders in VTK format. Views::Orderizer ord; sprintf(title, "ord-%d.vtk", as); ord.save_orders_vtk(space, title); Hermes::Mixins::Loggable::Static::info("Element orders in VTK format saved to file %s.", title); } // View the coarse mesh solution and polynomial orders. if (HERMES_VISUALIZATION) { sview.show(sln); oview.show(space); } // Skip visualization time. cpu_time.tick(); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); errorCalculator.calculate_errors(sln, ref_sln); double err_est_rel = errorCalculator.get_total_error_squared() * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", space->get_num_dofs(), ref_space->get_num_dofs(), err_est_rel); // Add entry to DOF and CPU convergence graphs. cpu_time.tick(); graph_cpu.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu.save("conv_cpu_est.dat"); graph_dof.add_values(space->get_num_dofs(), err_est_rel); graph_dof.save("conv_dof_est.dat"); // Skip the time spent to save the convergence graphs. cpu_time.tick(); // If err_est too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh."); done = adaptivity.adapt(&selector); // Increase the counter of performed adaptivity steps. if (done == false) as++; } } while (done == false); Hermes::Mixins::Loggable::Static::info("Total running time: %g s", cpu_time.accumulated()); // Show the fine mesh solution - final result. sview.set_title("Fine mesh solution"); sview.show_mesh(false); sview.show(ref_sln); // Wait for all views to be closed. Views::View::wait(); return 0; }
int main(int argc, char* args[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("square.mesh", mesh); // Perform initial mesh refinement. for (int i = 0; i < INIT_REF; i++) mesh->refine_all_elements(); // Create an L2 space. SpaceSharedPtr<double> fine_space(new L2Space<double>(mesh, USE_TAYLOR_SHAPESET ? std::max(P_INIT, 2) : P_INIT, (USE_TAYLOR_SHAPESET ? (Shapeset*)(new L2ShapesetTaylor) : (Shapeset*)(new L2ShapesetLegendre)))); // Initialize refinement selector. L2ProjBasedSelector<double> selector(CAND_LIST); selector.set_error_weights(1., 1., 1.); MeshFunctionSharedPtr<double> sln(new Solution<double>); MeshFunctionSharedPtr<double> refsln(new Solution<double>); // Initialize the weak formulation. WeakFormSharedPtr<double> wf(new CustomWeakForm("Bdy_bottom_left", mesh)); ScalarView view1("Solution", new WinGeom(900, 0, 450, 350)); view1.fix_scale_width(60); // Initialize linear solver. Hermes::Hermes2D::LinearSolver<double> linear_solver; linear_solver.set_weak_formulation(wf); adaptivity.set_space(fine_space); int as = 1; bool done = false; do { // Construct globally refined reference mesh // and setup reference space-> Mesh::ReferenceMeshCreator ref_mesh_creator(mesh); MeshSharedPtr ref_mesh = ref_mesh_creator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refspace_creator(fine_space, ref_mesh, 0); SpaceSharedPtr<double> refspace = refspace_creator.create_ref_space(); try { linear_solver.set_space(refspace); linear_solver.solve(); if (USE_TAYLOR_SHAPESET) { PostProcessing::VertexBasedLimiter limiter(refspace, linear_solver.get_sln_vector(), P_INIT); refsln = limiter.get_solution(); } else { Solution<double>::vector_to_solution(linear_solver.get_sln_vector(), refspace, refsln); } view1.show(refsln); OGProjection<double>::project_global(fine_space, refsln, sln, HERMES_L2_NORM); } catch (Exceptions::Exception& e) { std::cout << e.info(); } catch (std::exception& e) { std::cout << e.what(); } // Calculate element errors and total error estimate. errorCalculator.calculate_errors(sln, refsln); double err_est_rel = errorCalculator.get_total_error_squared() * 100; std::cout << "Error: " << err_est_rel << "%." << std::endl; // If err_est_rel too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else done = adaptivity.adapt(&selector); as++; } while (done == false); // Wait for keyboard or mouse input. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("square_quad.mesh", mesh); // mloader.load("square_tri.mesh", mesh); // Perform initial mesh refinement. for (int i = 0; i < INIT_REF_NUM; i++) mesh->refine_all_elements(); mesh->refine_towards_boundary("Layer", INIT_REF_NUM_BDY); // Initialize the weak formulation. WeakFormSharedPtr<double> wf(new WeakFormLinearAdvectionDiffusion(STABILIZATION_ON, SHOCK_CAPTURING_ON, B1, B2, EPSILON)); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_rest("Rest", 1.0); EssentialBCNonConst bc_layer("Layer"); EssentialBCs<double> bcs({ &bc_rest, &bc_layer }); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); WinGeom* sln_win_geom = new WinGeom(0, 0, 440, 350); WinGeom* mesh_win_geom = new WinGeom(450, 0, 400, 350); // Initialize coarse and reference mesh solution. MeshFunctionSharedPtr<double> sln(new Solution<double>), ref_sln(new Solution<double>); // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST); // Initialize views. ScalarView sview("Solution", new WinGeom(0, 0, 440, 350)); sview.fix_scale_width(50); sview.show_mesh(false); OrderView oview("Polynomial orders", new WinGeom(450, 0, 400, 350)); // DOF and CPU convergence graphs initialization. SimpleGraph graph_dof, graph_cpu; // Time measurement. Hermes::Mixins::TimeMeasurable cpu_time; cpu_time.tick(); // 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 refMeshCreator(mesh); MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh); SpaceSharedPtr<double> ref_space = refSpaceCreator.create_ref_space(); // Assemble the reference problem. Hermes::Mixins::Loggable::Static::info("Solving on reference mesh."); LinearSolver<double> solver(wf, ref_space); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. // If successful, obtain the solution. solver.solve(); Solution<double>::vector_to_solution(solver.get_sln_vector(), ref_space, ref_sln); // Project the fine mesh solution onto the coarse mesh. Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh."); OGProjection<double>::project_global(space, ref_sln, sln); // Time measurement. cpu_time.tick(); // View the coarse mesh solution and polynomial orders. sview.show(sln); oview.show(space); // Skip visualization time. cpu_time.tick(Hermes::Mixins::TimeMeasurable::HERMES_SKIP); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); adaptivity.set_space(space); errorCalculator.calculate_errors(sln, ref_sln); double err_est_rel = 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(space), Space<double>::get_num_dofs(ref_space), err_est_rel); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(Space<double>::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"); // If err_est too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh."); done = adaptivity.adapt(&selector); // Increase the counter of performed adaptivity steps. if (done == false) as++; } } while (done == false); Hermes::Mixins::Loggable::Static::info("Total running time: %g s", cpu_time.accumulated()); // Show the reference solution - the final result. sview.set_title("Fine mesh solution"); sview.show_mesh(false); sview.show(ref_sln); // Wait for all views to be closed. View::wait(); return 0; }