int main(int argc, char* argv[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("square.mesh", mesh); // Perform uniform mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh->refine_all_elements(); // Create an L2 space with default shapeset. SpaceSharedPtr<double> space(new L2Space<double>(mesh, P_INIT)); // View basis functions. BaseView<double> bview("BaseView", new WinGeom(0, 0, 600, 500)); bview.show(space); // View::wait(H2DV_WAIT_KEYPRESS); // Initialize the exact and projected solution. MeshFunctionSharedPtr<double> sln(new Solution<double>); MeshFunctionSharedPtr<double> sln_exact(new CustomExactSolution(mesh)); // Project the exact function on the FE space. OGProjection<double> ogProjection; ogProjection.project_global(space, sln_exact, sln); // Visualize the projection. ScalarView view1("Projection", new WinGeom(610, 0, 600, 500)); view1.show(sln); // 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. Mesh mesh; MeshReaderH2D mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinemets. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst<double> left_t("Left", 1.0); EssentialBCs<double> bcs_t(&left_t); DefaultEssentialBCConst<double> left_c("Left", 0.0); EssentialBCs<double> bcs_c(&left_c); // Create H1 spaces with default shapesets. H1Space<double>* t_space = new H1Space<double>(&mesh, &bcs_t, P_INIT); H1Space<double>* c_space = new H1Space<double>(&mesh, &bcs_c, P_INIT); int ndof = Space<double>::get_num_dofs(Hermes::vector<const Space<double>*>(t_space, c_space)); Hermes::Mixins::Loggable::Static::info("ndof = %d.", ndof); // Define initial conditions. InitialSolutionTemperature t_prev_time_1(&mesh, x1); InitialSolutionConcentration c_prev_time_1(&mesh, x1, Le); InitialSolutionTemperature t_prev_time_2(&mesh, x1); InitialSolutionConcentration c_prev_time_2(&mesh, x1, Le); Solution<double> t_prev_newton; Solution<double> c_prev_newton; // Filters for the reaction rate omega and its derivatives. CustomFilter omega(Hermes::vector<Solution<double>*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); CustomFilterDt omega_dt(Hermes::vector<Solution<double>*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); CustomFilterDc omega_dc(Hermes::vector<Solution<double>*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); // Initialize visualization. ScalarView rview("Reaction rate", new WinGeom(0, 0, 800, 230)); // Initialize weak formulation. CustomWeakForm wf(Le, alpha, beta, kappa, x1, TAU, TRILINOS_JFNK, PRECOND, &omega, &omega_dt, &omega_dc, &t_prev_time_1, &c_prev_time_1, &t_prev_time_2, &c_prev_time_2); // Project the functions "t_prev_time_1" and "c_prev_time_1" on the FE space // in order to obtain initial vector for NOX. Hermes::Mixins::Loggable::Static::info("Projecting initial solutions on the FE meshes."); double* coeff_vec = new double[ndof]; OGProjection<double> ogProjection; ogProjection.project_global(Hermes::vector<const Space<double> *>(t_space, c_space), Hermes::vector<MeshFunction<double>*>(&t_prev_time_1, &c_prev_time_1), coeff_vec); // Measure the projection time. double proj_time = cpu_time.tick().last(); // Initialize finite element problem. DiscreteProblem<double> dp(&wf, Hermes::vector<const Space<double>*>(t_space, c_space)); // Initialize NOX solver and preconditioner. NewtonSolverNOX<double> solver(&dp); MlPrecond<double> pc("sa"); if (PRECOND) { if (TRILINOS_JFNK) solver.set_precond(pc); else solver.set_precond("New Ifpack"); } if (TRILINOS_OUTPUT) solver.set_output_flags(NOX::Utils::Error | NOX::Utils::OuterIteration | NOX::Utils::OuterIterationStatusTest | NOX::Utils::LinearSolverDetails); // Time stepping loop: double total_time = 0.0; cpu_time.tick_reset(); for (int ts = 1; total_time <= T_FINAL; ts++) { Hermes::Mixins::Loggable::Static::info("---- Time step %d, t = %g s", ts, total_time + TAU); cpu_time.tick(); try { solver.solve(coeff_vec); } catch(std::exception& e) { std::cout << e.what(); } Solution<double>::vector_to_solutions(solver.get_sln_vector(), Hermes::vector<const Space<double> *>(t_space, c_space), Hermes::vector<Solution<double> *>(&t_prev_newton, &c_prev_newton)); cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Number of nonlin iterations: %d (norm of residual: %g)", solver.get_num_iters(), solver.get_residual()); Hermes::Mixins::Loggable::Static::info("Total number of iterations in linsolver: %d (achieved tolerance in the last step: %g)", solver.get_num_lin_iters(), solver.get_achieved_tol()); // Time measurement. cpu_time.tick(); // Skip visualization time. cpu_time.tick(); // Update global time. total_time += TAU; // Saving solutions for the next time step. if(ts > 1) { t_prev_time_2.copy(&t_prev_time_1); c_prev_time_2.copy(&c_prev_time_1); } t_prev_time_1.copy(&t_prev_newton); c_prev_time_1.copy(&c_prev_newton); // Visualization. rview.set_min_max_range(0.0,2.0); rview.show(&omega); cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Total running time for time level %d: %g s.", ts, cpu_time.tick().last()); } // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", mesh); // Initial mesh refinements. mesh->refine_towards_boundary(BDY_OBSTACLE, 2, false); mesh->refine_towards_boundary(BDY_TOP, 2, true); // '4' is the number of levels, mesh->refine_towards_boundary(BDY_BOTTOM, 2, true); // 'true' stands for anisotropic refinements. mesh->refine_all_elements(); // Initialize boundary conditions. EssentialBCNonConst bc_left_vel_x(BDY_LEFT, VEL_INLET, H, STARTUP_TIME); Hermes::Hermes2D::DefaultEssentialBCConst<double> bc_other_vel_x(Hermes::vector<std::string>(BDY_BOTTOM, BDY_TOP, BDY_OBSTACLE), 0.0); Hermes::Hermes2D::EssentialBCs<double> bcs_vel_x(Hermes::vector<EssentialBoundaryCondition<double> *>(&bc_left_vel_x, &bc_other_vel_x)); Hermes::Hermes2D::DefaultEssentialBCConst<double> bc_vel_y(Hermes::vector<std::string>(BDY_LEFT, BDY_BOTTOM, BDY_TOP, BDY_OBSTACLE), 0.0); Hermes::Hermes2D::EssentialBCs<double> bcs_vel_y(&bc_vel_y); Hermes::Hermes2D::EssentialBCs<double> bcs_pressure; // Spaces for velocity components and pressure. SpaceSharedPtr<double> xvel_space(new H1Space<double>(mesh, &bcs_vel_x, P_INIT_VEL)); SpaceSharedPtr<double> yvel_space(new H1Space<double>(mesh, &bcs_vel_y, P_INIT_VEL)); #ifdef PRESSURE_IN_L2 SpaceSharedPtr<double> p_space(new L2Space<double> (mesh, P_INIT_PRESSURE)); #else SpaceSharedPtr<double> p_space(new H1Space<double> (mesh, &bcs_pressure, P_INIT_PRESSURE)); #endif // Calculate and report the number of degrees of freedom. int ndof = Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(xvel_space, yvel_space, p_space)); // Define projection norms. NormType vel_proj_norm = HERMES_H1_NORM; #ifdef PRESSURE_IN_L2 NormType p_proj_norm = HERMES_L2_NORM; #else NormType p_proj_norm = HERMES_H1_NORM; #endif // Solutions for the Newton's iteration and time stepping. MeshFunctionSharedPtr<double> xvel_prev_time(new ConstantSolution<double> (mesh, 0.0)); MeshFunctionSharedPtr<double> yvel_prev_time(new ConstantSolution<double> (mesh, 0.0)); MeshFunctionSharedPtr<double> p_prev_time(new ConstantSolution<double> (mesh, 0.0)); // Initialize weak formulation. WeakFormNSNewton wf(STOKES, RE, TAU, xvel_prev_time, yvel_prev_time); UExtFunctionSharedPtr<double> fn_0(new CustomUExtFunction(0)); UExtFunctionSharedPtr<double> fn_1(new CustomUExtFunction(1)); wf.set_ext(Hermes::vector<MeshFunctionSharedPtr<double> >(xvel_prev_time, yvel_prev_time)); wf.set_u_ext_fn(Hermes::vector<UExtFunctionSharedPtr<double> >(fn_0, fn_1)); // Initialize the Newton solver. Hermes::Hermes2D::NewtonSolver<double> newton; newton.set_weak_formulation(&wf); Hermes::vector<SpaceSharedPtr<double> > spaces(xvel_space, yvel_space, p_space); newton.set_spaces(spaces); // Initialize views. Views::VectorView vview("velocity[m/s]", new Views::WinGeom(0, 0, 750, 240)); Views::ScalarView pview("pressure[Pa]", new Views::WinGeom(0, 290, 750, 240)); vview.set_min_max_range(0, 1.6); vview.fix_scale_width(80); //pview.set_min_max_range(-0.9, 1.0); pview.fix_scale_width(80); if(HERMES_VISUALIZATION) pview.show_mesh(true); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. double* coeff_vec = new double[Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(xvel_space, yvel_space, p_space))]; OGProjection<double> ogProjection; ogProjection.project_global(Hermes::vector<SpaceSharedPtr<double> >(xvel_space, yvel_space, p_space), Hermes::vector<MeshFunctionSharedPtr<double> >(xvel_prev_time, yvel_prev_time, p_prev_time), coeff_vec, Hermes::vector<NormType>(vel_proj_norm, vel_proj_norm, p_proj_norm)); newton.set_max_allowed_iterations(max_allowed_iterations); newton.set_tolerance(NEWTON_TOL, Hermes::Solvers::ResidualNormAbsolute); newton.set_sufficient_improvement_factor_jacobian(1e-2); //newton.set_jacobian_constant(); // Time-stepping loop: char title[100]; int num_time_steps = T_FINAL / TAU; for (int ts = 1; ts <= num_time_steps; ts++) { current_time += TAU; Hermes::Mixins::Loggable::Static::info("Time step %i, time %f.", ts, current_time); // Update time-dependent essential BCs. newton.set_time(current_time); // Perform Newton's iteration and translate the resulting coefficient vector into previous time level solutions. try { newton.solve(coeff_vec); } catch(Hermes::Exceptions::Exception& e) { e.print_msg(); } Hermes::vector<MeshFunctionSharedPtr<double> > tmp(xvel_prev_time, yvel_prev_time, p_prev_time); Hermes::Hermes2D::Solution<double>::vector_to_solutions(newton.get_sln_vector(), Hermes::vector<SpaceSharedPtr<double> >(xvel_space, yvel_space, p_space), tmp); // Show the solution at the end of time step. if(HERMES_VISUALIZATION) { sprintf(title, "Velocity, time %g", current_time); vview.set_title(title); vview.show(xvel_prev_time, yvel_prev_time); sprintf(title, "Pressure, time %g", current_time); pview.set_title(title); pview.show(p_prev_time); } } delete [] coeff_vec; return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("square.mesh", &mesh); // quadrilaterals // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Define exact solution. CustomExactSolution exact(&mesh, slope); // Define right-hand side. CustomFunction f(slope); // Initialize the weak formulation. WeakFormsH1::DefaultWeakFormPoisson<double> wf(HERMES_ANY, new Hermes1DFunction<double>(1.0), &f); // Initialize boundary conditions DefaultEssentialBCNonConst<double> bc_essential("Bdy", &exact); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // 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, 420, 350)); OrderView oviewa("Polynomial orders", new WinGeom(450, 0, 420, 350)); // DOF and CPU convergence graphs. SimpleGraph graph_dof, graph_cpu, 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 { Hermes::Mixins::Loggable::Static::info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space<double>* ref_space = Space<double>::construct_refined_space(&space); int ndof_ref = Space<double>::get_num_dofs(ref_space); // Initialize reference problem. Hermes::Mixins::Loggable::Static::info("Solving on reference mesh."); DiscreteProblem<double> dp(&wf, ref_space); // Time measurement. cpu_time.tick(); // Initial coefficient vector for the Newton's method. double* coeff_vec = new double[ndof_ref]; memset(coeff_vec, 0, ndof_ref * sizeof(double)); // Initialize NOX solver. NewtonSolverNOX<double> solver(&dp); solver.set_output_flags(message_type); solver.set_ls_tolerance(ls_tolerance); solver.set_conv_iters(max_iters); if (flag_absresid) solver.set_conv_abs_resid(abs_resid); if (flag_relresid) solver.set_conv_rel_resid(rel_resid); // Select preconditioner. MlPrecond<double> pc("sa"); if (PRECOND) { if (TRILINOS_JFNK) solver.set_precond(pc); else solver.set_precond("ML"); } // Time measurement. cpu_time.tick(); Solution<double> sln, ref_sln; Hermes::Mixins::Loggable::Static::info("Assembling by DiscreteProblem, solving by NOX."); try { solver.solve(coeff_vec); } catch(std::exception& e) { std::cout << e.what(); } Solution<double>::vector_to_solution(solver.get_sln_vector(), ref_space, &ref_sln); Hermes::Mixins::Loggable::Static::info("Number of nonlin iterations: %d (norm of residual: %g)", solver.get_num_iters(), solver.get_residual()); Hermes::Mixins::Loggable::Static::info("Total number of iterations in linsolver: %d (achieved tolerance in the last step: %g)", solver.get_num_lin_iters(), solver.get_achieved_tol()); Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh."); OGProjection<double> ogProjection; ogProjection.project_global(&space, &ref_sln, &sln); // View the coarse mesh solution and polynomial orders. sview.show(&sln); oview.show(&space); oviewa.show(ref_space); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate and exact error."); Adapt<double>* adaptivity = new Adapt<double>(&space); double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100; // Calculate exact error. //Solution<double>* exact = new Solution(&mesh, &exact); bool solutions_for_adapt = false; double err_exact_rel = adaptivity->calc_err_exact(&sln, &exact, solutions_for_adapt) * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d", Space<double>::get_num_dofs(&space), Space<double>::get_num_dofs(ref_space)); Hermes::Mixins::Loggable::Static::info("err_est_rel: %g%%, err_exact_rel: %g%%", err_est_rel, err_exact_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"); graph_dof_exact.add_values(Space<double>::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"); // 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, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of adaptivity steps. if (done == false) as++; } if (Space<double>::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete [] coeff_vec; delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; } while (done == false); Hermes::Mixins::Loggable::Static::info("Total running time: %g s", cpu_time.accumulated()); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { Hermes::Mixins::TimeMeasurable m; m.tick(); // Load the mesh. Mesh 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<std::complex<double> > bc_essential("Dirichlet", std::complex<double>(0.0, 0.0)); EssentialBCs<std::complex<double> > bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<std::complex<double> > space(&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, std::complex<double>(J_EXT, 0.0), OMEGA); // Initialize coarse and reference mesh solution. Solution<std::complex<double> > sln, ref_sln; // Initialize refinement selector. H1ProjBasedSelector<std::complex<double> > selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. Views::VectorView sview("Solution", new Views::WinGeom(0, 0, 600, 350)); Views::OrderView oview("Polynomial orders", new Views::WinGeom(610, 0, 520, 350)); // DOF and CPU convergence graphs initialization. SimpleGraph graph_dof, graph_cpu; DiscreteProblem<std::complex<double> > dp(&wf, &space); // Perform Newton's iteration and translate the resulting coefficient vector into a Solution. Hermes::Hermes2D::NewtonSolver<std::complex<double> > newton(&dp); Views::MeshView m1, m2; Views::OrderView o1, o2; // Adaptivity loop: int as = 1; bool done = false; do { // Construct globally refined reference mesh and setup reference space. Space<std::complex<double> >::ReferenceSpaceCreator ref_space_creator(&space, &mesh); Space<std::complex<double> >* 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. std::complex<double>* coeff_vec = new std::complex<double>[ndof_ref]; memset(coeff_vec, 0, ndof_ref * sizeof(std::complex<double>)); // Perform Newton's iteration and translate the resulting coefficient vector into a Solution. // For iterative solver. if(matrix_solver_type == SOLVER_AZTECOO) { newton.set_iterative_method(iterative_method); newton.set_preconditioner(preconditioner); } try { newton.solve_keep_jacobian(coeff_vec); } catch(Hermes::Exceptions::Exception& e) { e.print_msg(); } Hermes::Hermes2D::Solution<std::complex<double> >::vector_to_solution(newton.get_sln_vector(), ref_space, &ref_sln); // Project the fine mesh solution onto the coarse mesh. OGProjection<std::complex<double> > ogProjection; ogProjection.project_global(&space, &ref_sln, &sln); // View the coarse mesh solution and polynomial orders. RealFilter real_filter(&sln); sview.show(&real_filter, &real_filter); oview.show(&space); // Calculate element errors and total error estimate. Adapt<std::complex<double> >* adaptivity = new Adapt<std::complex<double> >(&space); double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100; std::cout << (std::string)"Relative error: " << err_est_rel << std::endl; // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(space.get_num_dofs(), err_est_rel); graph_dof.save("conv_dof_est.dat"); // If err_est too large, adapt the mesh. if(err_est_rel < ERR_STOP) done = true; else { std::cout << (std::string)"Adapting..." << std::endl << std::endl; done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); } if(space.get_num_dofs() >= NDOF_STOP) done = true; // Clean up. delete [] coeff_vec; delete adaptivity; // Increase counter. as++; } while (done == false); // Show the reference solution - the final result. sview.set_title("Fine mesh solution"); RealFilter real_filter(&ref_sln); sview.show(&real_filter, &real_filter); m.tick(); std::cout << m.accumulated(); // Wait for all views to be closed. Views::View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. MeshSharedPtr u_mesh(new Mesh), v_mesh(new Mesh); MeshReaderH2D mloader; mloader.load("elasticity.mesh", u_mesh); // Create initial mesh (master mesh). v_mesh->copy(u_mesh); // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) { u_mesh->refine_all_elements(); v_mesh->refine_all_elements(); } // Set exact solution for each displacement component. MeshFunctionSharedPtr<double> exact_u(new CustomExactSolutionU(u_mesh, E, nu, lambda, Q)); MeshFunctionSharedPtr<double> exact_v(new CustomExactSolutionV(v_mesh, E, nu, lambda, Q)); // Initialize the weak formulation. // NOTE: We pass all four parameters (temporarily) // since in Mitchell's paper (NIST benchmarks) they // are mutually inconsistent. CustomWeakFormElasticityNIST wf(E, nu, mu, lambda); // Initialize boundary conditions. DefaultEssentialBCNonConst<double> bc_u("Bdy", exact_u); EssentialBCs<double> bcs_u(&bc_u); DefaultEssentialBCNonConst<double> bc_v("Bdy", exact_v); 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>(v_mesh, &bcs_v, P_INIT_V)); Hermes::vector<SpaceSharedPtr<double> >spaces(u_space, v_space); // Initialize approximate solution. MeshFunctionSharedPtr<double> u_sln(new Solution<double>()); MeshFunctionSharedPtr<double> u_ref_sln(new Solution<double>()); MeshFunctionSharedPtr<double> v_sln(new Solution<double>()); MeshFunctionSharedPtr<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. MySelector selector(CAND_LIST); // Initialize views. Views::ScalarView s_view_u("Solution for u", new WinGeom(0, 0, 440, 350)); s_view_u.show_mesh(false); Views::OrderView o_view_u("Mesh for u", new WinGeom(450, 0, 420, 350)); Views::ScalarView s_view_v("Solution for v", new WinGeom(0, 405, 440, 350)); s_view_v.show_mesh(false); Views::OrderView o_view_v("Mesh for v", new WinGeom(450, 405, 420, 350)); Views::ScalarView mises_view("Von Mises stress [Pa]", new WinGeom(880, 0, 440, 350)); mises_view.fix_scale_width(50); // 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; // Adaptivity loop: int as = 1; bool done = false; do { cpu_time.tick(); // Construct globally refined reference mesh and setup reference space-> Mesh::ReferenceMeshCreator refMeshCreatorU(u_mesh); MeshSharedPtr ref_u_mesh = refMeshCreatorU.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreatorU(u_space, ref_u_mesh); SpaceSharedPtr<double> ref_u_space = refSpaceCreatorU.create_ref_space(); Mesh::ReferenceMeshCreator refMeshCreatorV(u_mesh); MeshSharedPtr ref_v_mesh = refMeshCreatorV.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreatorV(v_space, ref_v_mesh); SpaceSharedPtr<double> ref_v_space = refSpaceCreatorV.create_ref_space(); Hermes::vector<SpaceSharedPtr<double> > ref_spaces(ref_u_space, ref_v_space); int ndof_ref = Space<double>::get_num_dofs(ref_spaces); 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_spaces); NewtonSolver<double> newton(&dp); 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_solutions(newton.get_sln_vector(), ref_spaces, ref_slns); 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(spaces, ref_slns, slns); // Calculate element errors and total error estimate. DefaultErrorCalculator<double, HERMES_H1_NORM> error_calculator(errorType, 2); error_calculator.calculate_errors(slns, exact_slns); double err_exact_rel_total = error_calculator.get_total_error_squared() * 100.0; error_calculator.calculate_errors(slns, ref_slns); double err_est_rel_total = error_calculator.get_total_error_squared() * 100.0; Adapt<double> adaptivity(spaces, &error_calculator); adaptivity.set_strategy(&stoppingCriterion); cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Error calculation: %g s", cpu_time.last()); // Time measurement. cpu_time.tick(); double accum_time = cpu_time.accumulated(); // View the coarse mesh solution and polynomial orders. s_view_u.show(u_sln); o_view_u.show(u_space); s_view_v.show(v_sln); o_view_v.show(v_space); MeshFunctionSharedPtr<double> stress(new VonMisesFilter(Hermes::vector<MeshFunctionSharedPtr<double> >(u_sln, v_sln), lambda, mu)); mises_view.show(stress, H2D_FN_VAL_0, u_sln, v_sln, 0.03); // 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"); cpu_time.tick(Hermes::Mixins::TimeMeasurable::HERMES_SKIP); // 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."); done = adaptivity.adapt(Hermes::vector<RefinementSelectors::Selector<double> *>(&selector, &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(); 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; }
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()); // Turn off adaptive time stepping if R-K method is not embedded. if (bt.is_embedded() == false && ADAPTIVE_TIME_STEP_ON == true) { Hermes::Mixins::Loggable::Static::warn("R-K method not embedded, turning off adaptive time stepping."); ADAPTIVE_TIME_STEP_ON = false; } // Load the mesh. MeshSharedPtr mesh(new Mesh), basemesh(new Mesh); MeshReaderH2D mloader; mloader.load("wall.mesh", basemesh); mesh->copy(basemesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh->refine_all_elements(); mesh->refine_towards_boundary(BDY_RIGHT, 2); mesh->refine_towards_boundary(BDY_FIRE, INIT_REF_NUM_BDY); // Initialize essential boundary conditions (none). EssentialBCs<double> bcs; // Initialize an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); int ndof = Space<double>::get_num_dofs(space); Hermes::Mixins::Loggable::Static::info("ndof = %d.", ndof); // Convert initial condition into a Solution. MeshFunctionSharedPtr<double> sln_prev_time(new ConstantSolution<double> (mesh, TEMP_INIT)); // Initialize the weak formulation. double current_time = 0; CustomWeakFormHeatRK wf(BDY_FIRE, BDY_AIR, ALPHA_FIRE, ALPHA_AIR, RHO, HEATCAP, TEMP_EXT_AIR, TEMP_INIT, ¤t_time); // 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 sln_view("Initial condition", new WinGeom(0, 0, 1500, 360)); OrderView ordview("Initial mesh", new WinGeom(0, 410, 1500, 360)); ScalarView time_error_view("Temporal error", new WinGeom(0, 800, 1500, 360)); time_error_view.fix_scale_width(40); ScalarView space_error_view("Spatial error", new WinGeom(0, 1220, 1500, 360)); space_error_view.fix_scale_width(40); sln_view.show(sln_prev_time); ordview.show(space); // Graph for time step history. SimpleGraph time_step_graph; if (ADAPTIVE_TIME_STEP_ON) Hermes::Mixins::Loggable::Static::info("Time step history will be saved to file time_step_history.dat."); // Class for projections. OGProjection<double> ogProjection; // Time stepping loop: int ts = 1; do { Hermes::Mixins::Loggable::Static::info("Begin time step %d.", ts); // 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: space->unrefine_all_mesh_elements(); space->set_uniform_order(P_INIT); break; case 3: space->unrefine_all_mesh_elements(); //space->adjust_element_order(-1, P_INIT); space->adjust_element_order(-1, -1, P_INIT, P_INIT); break; default: throw Hermes::Exceptions::Exception("Wrong global derefinement method."); } space->assign_dofs(); ndof = Space<double>::get_num_dofs(space); } // Spatial adaptivity loop. Note: sln_prev_time must not be // changed during spatial adaptivity. MeshFunctionSharedPtr<double> ref_sln(new Solution<double>()); MeshFunctionSharedPtr<double> time_error_fn(new Solution<double>(mesh)); bool done = false; int as = 1; double err_est; do { // 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(); // Initialize Runge-Kutta time stepping on the reference mesh. RungeKutta<double> runge_kutta(&wf, ref_space, &bt); try { ogProjection.project_global(ref_space, sln_prev_time, sln_prev_time); } catch(Exceptions::Exception& e) { std::cout << e.what() << std::endl; Hermes::Mixins::Loggable::Static::error("Projection failed."); return -1; } // Runge-Kutta step on the fine mesh-> Hermes::Mixins::Loggable::Static::info("Runge-Kutta time step on fine mesh (t = %g s, tau = %g s, stages: %d).", current_time, time_step, bt.get_size()); bool verbose = true; bool jacobian_changed = false; 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_FINE); runge_kutta.rk_time_step_newton(sln_prev_time, ref_sln, bt.is_embedded() ? time_error_fn : NULL); } catch(Exceptions::Exception& e) { std::cout << e.what() << std::endl; Hermes::Mixins::Loggable::Static::error("Runge-Kutta time step failed"); return -1; } /* If ADAPTIVE_TIME_STEP_ON == true, estimate temporal error. If too large or too small, then adjust it and restart the time step. */ double rel_err_time = 0; if (bt.is_embedded() == true) { Hermes::Mixins::Loggable::Static::info("Calculating temporal error estimate."); // Show temporal error. char title[100]; sprintf(title, "Temporal error est, spatial adaptivity step %d", as); time_error_view.set_title(title); //time_error_view.show_mesh(false); time_error_view.show(time_error_fn); rel_err_time = Global<double>::calc_norm(time_error_fn.get(), HERMES_H1_NORM) / Global<double>::calc_norm(ref_sln.get(), HERMES_H1_NORM) * 100; if (ADAPTIVE_TIME_STEP_ON == false) Hermes::Mixins::Loggable::Static::info("rel_err_time: %g%%", rel_err_time); } if (ADAPTIVE_TIME_STEP_ON) { if (rel_err_time > TIME_ERR_TOL_UPPER) { Hermes::Mixins::Loggable::Static::info("rel_err_time %g%% is above upper limit %g%%", rel_err_time, TIME_ERR_TOL_UPPER); Hermes::Mixins::Loggable::Static::info("Decreasing tau from %g to %g s and restarting time step.", time_step, time_step * TIME_STEP_DEC_RATIO); time_step *= TIME_STEP_DEC_RATIO; continue; } else if (rel_err_time < TIME_ERR_TOL_LOWER) { Hermes::Mixins::Loggable::Static::info("rel_err_time = %g%% is below lower limit %g%%", rel_err_time, TIME_ERR_TOL_LOWER); Hermes::Mixins::Loggable::Static::info("Increasing tau from %g to %g s.", time_step, time_step * TIME_STEP_INC_RATIO); time_step *= TIME_STEP_INC_RATIO; } else { Hermes::Mixins::Loggable::Static::info("rel_err_time = %g%% is in acceptable interval (%g%%, %g%%)", rel_err_time, TIME_ERR_TOL_LOWER, TIME_ERR_TOL_UPPER); } // Add entry to time step history graph. time_step_graph.add_values(current_time, time_step); time_step_graph.save("time_step_history.dat"); } /* Estimate spatial errors and perform mesh refinement */ Hermes::Mixins::Loggable::Static::info("Spatial adaptivity step %d.", as); // Project the fine mesh solution onto the coarse mesh. MeshFunctionSharedPtr<double> sln(new Solution<double>()); Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh for error estimation."); ogProjection.project_global(space, ref_sln, sln); // Show spatial error. sprintf(title, "Spatial error est, spatial adaptivity step %d", as); MeshFunctionSharedPtr<double> space_error_fn(new DiffFilter<double>(Hermes::vector<MeshFunctionSharedPtr<double> >(ref_sln, sln))); space_error_view.set_title(title); //space_error_view.show_mesh(false); MeshFunctionSharedPtr<double> abs_sef(new AbsFilter(space_error_fn)); space_error_view.show(abs_sef); // Calculate element errors and spatial error estimate. Hermes::Mixins::Loggable::Static::info("Calculating spatial error estimate."); adaptivity.set_space(space); double err_rel_space = errorCalculator.get_total_error_squared() * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof: %d, ref_ndof: %d, err_rel_space: %g%%", Space<double>::get_num_dofs(space), Space<double>::get_num_dofs(ref_space), err_rel_space); // If err_est too large, adapt the mesh. if (err_rel_space < SPACE_ERR_TOL) done = true; else { Hermes::Mixins::Loggable::Static::info("Adapting the coarse mesh."); done = adaptivity.adapt(&selector); if (Space<double>::get_num_dofs(space) >= NDOF_STOP) done = true; else // Increase the counter of performed adaptivity steps. as++; } // Clean up. if(!done) } while (done == false); // Visualize the solution and mesh-> char title[100]; sprintf(title, "Solution, time %g s", current_time); sln_view.set_title(title); //sln_view.show_mesh(false); sln_view.show(ref_sln); sprintf(title, "Mesh, time %g s", current_time); ordview.set_title(title); ordview.show(space); // Copy last reference solution into sln_prev_time sln_prev_time->copy(ref_sln); // 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[]) { // 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[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", mesh); // Perform initial mesh refinemets. for (int i = 0; i < INIT_REF_NUM; i++) mesh->refine_all_elements(); // Initialize solutions. MeshFunctionSharedPtr<double> E_sln(new CustomInitialConditionWave(mesh)); MeshFunctionSharedPtr<double> F_sln(new ZeroSolutionVector<double>(mesh)); Hermes::vector<MeshFunctionSharedPtr<double> > slns(E_sln, F_sln); // Initialize the weak formulation. CustomWeakFormWaveIE wf(time_step, C_SQUARED, E_sln, F_sln); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_essential("Perfect conductor", 0.0); EssentialBCs<double> bcs(&bc_essential); SpaceSharedPtr<double> E_space(new HcurlSpace<double>(mesh, &bcs, P_INIT)); SpaceSharedPtr<double> F_space(new HcurlSpace<double>(mesh, &bcs, P_INIT)); Hermes::vector<SpaceSharedPtr<double> > spaces = Hermes::vector<SpaceSharedPtr<double> >(E_space, F_space); int ndof = HcurlSpace<double>::get_num_dofs(spaces); Hermes::Mixins::Loggable::Static::info("ndof = %d.", ndof); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, spaces); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. // NOTE: If you want to start from the zero vector, just define // coeff_vec to be a vector of ndof zeros (no projection is needed). Hermes::Mixins::Loggable::Static::info("Projecting to obtain initial vector for the Newton's method."); double* coeff_vec = new double[ndof]; OGProjection<double> ogProjection; ogProjection.project_global(spaces, slns, coeff_vec); // Initialize Newton solver. NewtonSolver<double> newton(&dp); // 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 F1_view("Solution F1", new WinGeom(0, 410, 400, 350)); F1_view.fix_scale_width(50); ScalarView F2_view("Solution F2", new WinGeom(410, 410, 400, 350)); F2_view.fix_scale_width(50); // Time stepping loop. double current_time = 0; int ts = 1; do { // Perform one implicit Euler time step. Hermes::Mixins::Loggable::Static::info("Implicit Euler time step (t = %g s, time_step = %g s).", current_time, time_step); // Perform Newton's iteration. try { newton.set_max_allowed_iterations(NEWTON_MAX_ITER); newton.set_tolerance(NEWTON_TOL, Hermes::Solvers::ResidualNormAbsolute); newton.solve(coeff_vec); } catch(Hermes::Exceptions::Exception e) { e.print_msg(); throw Hermes::Exceptions::Exception("Newton's iteration failed."); } // Translate the resulting coefficient vector into Solutions. Solution<double>::vector_to_solutions(newton.get_sln_vector(), spaces, slns); // Visualize the solutions. char title[100]; sprintf(title, "E1, t = %g", current_time + time_step); E1_view.set_title(title); E1_view.show(E_sln, H2D_FN_VAL_0); sprintf(title, "E2, t = %g", current_time + time_step); E2_view.set_title(title); E2_view.show(E_sln, H2D_FN_VAL_1); sprintf(title, "F1, t = %g", current_time + time_step); F1_view.set_title(title); F1_view.show(F_sln, H2D_FN_VAL_0); sprintf(title, "F2, t = %g", current_time + time_step); F2_view.set_title(title); F2_view.show(F_sln, H2D_FN_VAL_1); //View::wait(); // Update time. current_time += time_step; } while (current_time < T_FINAL); // Wait for the view to be closed. View::wait(); return 0; }
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)); Hermes::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)); Hermes::vector<MeshFunctionSharedPtr<double> > slns_time_new(E_time_new, H_time_new, P_time_new); // Initialize the weak formulation. CustomWeakFormMD wf(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)); Hermes::vector<SpaceSharedPtr<double> > spaces = Hermes::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_max_allowed_iterations(NEWTON_MAX_ITER); runge_kutta.set_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(); Hermes::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> ogProjection; ogProjection.project_global(Hermes::vector<SpaceSharedPtr<double> >(E_space, H_space, P_space), Hermes::vector<MeshFunctionSharedPtr<double> >(E_time_new, H_time_new, P_time_new), Hermes::vector<MeshFunctionSharedPtr<double> >(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(Hermes::vector<SpaceSharedPtr<double> >(E_space, H_space, P_space)); errorCalculator.calculate_errors(Hermes::vector<MeshFunctionSharedPtr<double> >(E_time_new_coarse, H_time_new_coarse, P_time_new_coarse), Hermes::vector<MeshFunctionSharedPtr<double> >(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(Hermes::vector<RefinementSelectors::Selector<double> *>(&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[]) { #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. Mesh mesh; MeshReaderH2D mloader; if (ALIGN_MESH) mloader.load("oven_load_circle.mesh", &mesh); else mloader.load("oven_load_square.mesh", &mesh); // Perform initial mesh refinemets. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize boundary conditions DefaultEssentialBCConst<std::complex<double> > bc_essential(BDY_PERFECT_CONDUCTOR, std::complex<double>(0.0, 0.0)); EssentialBCs<std::complex<double> > bcs(&bc_essential); // Create an Hcurl space with default shapeset. HcurlSpace<std::complex<double> > space(&mesh, &bcs, P_INIT); int ndof = space.get_num_dofs(); Hermes::Mixins::Loggable::Static::info("ndof = %d", ndof); // Initialize the weak formulation. CustomWeakForm wf(e_0, mu_0, mu_r, kappa, omega, J, ALIGN_MESH, &mesh, BDY_CURRENT); // Initialize coarse and reference mesh solution. Solution<std::complex<double> > sln, ref_sln; // Initialize refinements selector. HcurlProjBasedSelector<std::complex<double> > selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. ScalarView eview("Electric field", new WinGeom(0, 0, 580, 400)); OrderView oview("Polynomial orders", new WinGeom(590, 0, 550, 400)); // 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); Mesh* ref_mesh = refMeshCreator.create_ref_mesh(); Space<std::complex<double> >::ReferenceSpaceCreator refSpaceCreator(&space, ref_mesh); Space<std::complex<double> >* ref_space = refSpaceCreator.create_ref_space(); int ndof_ref = Space<std::complex<double> >::get_num_dofs(ref_space); // Initialize reference problem. Hermes::Mixins::Loggable::Static::info("Solving on reference mesh."); DiscreteProblem<std::complex<double> > dp(&wf, ref_space); // Time measurement. cpu_time.tick(); // Perform Newton's iteration. Hermes::Hermes2D::NewtonSolver<std::complex<double> > newton(&dp); try { newton.set_newton_max_iter(NEWTON_MAX_ITER); newton.set_newton_tol(NEWTON_TOL); 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<std::complex<double> > sln. Hermes::Hermes2D::Solution<std::complex<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 reference solution on coarse mesh."); OGProjection<std::complex<double> > ogProjection; ogProjection.project_global(&space, &ref_sln, &sln); // View the coarse mesh solution and polynomial orders. RealFilter real(&sln); MagFilter<double> magn(&real); ValFilter limited_magn(&magn, 0.0, 4e3); char title[100]; sprintf(title, "Electric field, adaptivity step %d", as); eview.set_title(title); //eview.set_min_max_range(0.0, 4e3); eview.show(&limited_magn); sprintf(title, "Polynomial orders, adaptivity step %d", as); oview.set_title(title); oview.show(&space); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); Adapt<std::complex<double> >* adaptivity = new Adapt<std::complex<double> >(&space); // Set custom error form and calculate error estimate. CustomErrorForm cef(kappa); adaptivity->set_error_form(0, 0, &cef); double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space<std::complex<double> >::get_num_dofs(&space), Space<std::complex<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<std::complex<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, THRESHOLD, STRATEGY, MESH_REGULARITY); } if (space.get_num_dofs() >= NDOF_STOP) done = true; delete adaptivity; if(!done) { delete ref_space->get_mesh(); delete ref_space; } // Increase counter. as++; } while (done == false); Hermes::Mixins::Loggable::Static::info("Total running time: %g s", cpu_time.accumulated()); RealFilter ref_real(&sln); MagFilter<double> ref_magn(&ref_real); ValFilter ref_limited_magn(&ref_magn, 0.0, 4e3); eview.set_title("Fine mesh solution - magnitude"); eview.show(&ref_limited_magn); // Output solution in VTK format. Linearizer lin; bool mode_3D = true; lin.save_solution_vtk(&ref_limited_magn, "sln.vtk", "Magnitude of E", mode_3D); Hermes::Mixins::Loggable::Static::info("Solution in VTK format saved to file %s.", "sln.vtk"); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh 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. H1Space<double> space(&mesh, &bcs, P_INIT); // Initialize coarse and fine mesh solution. Solution<double> sln, ref_sln; // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, 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); Mesh* ref_mesh = ref_mesh_creator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator ref_space_creator(&space, ref_mesh); Space<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> ogProjection; ogProjection.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(&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."); Adapt<double> adaptivity(&space); bool solutions_for_adapt = true; // In the following function, the Boolean parameter "solutions_for_adapt" determines whether // the calculated errors are intended for use with adaptivity (this may not be the case, for example, // when error wrt. an exact solution is calculated). The default value is solutions_for_adapt = true, // The last parameter "error_flags" determine whether the total and element errors are treated as // absolute or relative. Its default value is error_flags = HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL. // In subsequent examples and benchmarks, these two parameters will be often used with // their default values, and thus they will not be present in the code explicitly. double err_est_rel = adaptivity.calc_err_est(&sln, &ref_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 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, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if (done == false) as++; } if (space.get_num_dofs() >= NDOF_STOP) done = true; // Keep the mesh from final step to allow further work with the final fine mesh solution. if(done == false) delete ref_space->get_mesh(); delete ref_space; } 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* argv[]) { // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("domain.mesh", &mesh); // Perform initial uniform mesh refinement. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Set essential boundary conditions. DefaultEssentialBCConst<double> bc_essential(Hermes::vector<std::string>("right", "top"), 0.0); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); // Associate element markers (corresponding to physical regions) // with material properties (diffusion coefficient, absorption // cross-section, external sources). Hermes::vector<std::string> regions("e1", "e2", "e3", "e4", "e5"); Hermes::vector<double> D_map(D_1, D_2, D_3, D_4, D_5); Hermes::vector<double> Sigma_a_map(SIGMA_A_1, SIGMA_A_2, SIGMA_A_3, SIGMA_A_4, SIGMA_A_5); Hermes::vector<double> Sources_map(Q_EXT_1, 0.0, Q_EXT_3, 0.0, 0.0); // Initialize the weak formulation. WeakFormsNeutronics::Monoenergetic::Diffusion::DefaultWeakFormFixedSource<double> wf(regions, D_map, Sigma_a_map, Sources_map); // Initialize coarse and reference mesh solution. Solution<double> sln, ref_sln; // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // 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); // Time measurement. cpu_time.tick(); // Construct globally refined mesh and setup fine mesh space. Space<double>* ref_space = Space<double>::construct_refined_space(&space); int ndof_ref = ref_space->get_num_dofs(); // Initialize fine mesh problem. Hermes::Mixins::Loggable::Static::info("Solving on fine mesh."); DiscreteProblem<double> dp(&wf, ref_space); NewtonSolver<double> newton(&dp); newton.set_verbose_output(false); // Perform Newton's iteration. try { newton.solve(); } catch(Hermes::Exceptions::Exception e) { e.printMsg(); 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); // Project the fine mesh solution onto the coarse mesh. Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh."); OGProjection<double> ogProjection; ogProjection.project_global(&space, &ref_sln, &sln); // Time measurement. cpu_time.tick(); // Visualize the solution and mesh. 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."); Adapt<double> adaptivity(&space); bool solutions_for_adapt = true; double err_est_rel = adaptivity.calc_err_est(&sln, &ref_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 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(Hermes::Mixins::TimeMeasurable::HERMES_SKIP); // 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, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if (done == false) as++; } if (space.get_num_dofs() >= NDOF_STOP) done = true; // Keep the mesh from final step to allow further work with the final fine mesh solution. if(done == false) { delete ref_space->get_mesh(); delete ref_space; } } 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* argv[]) { // Load the mesh. Mesh mesh, basemesh; MeshReaderH2D mloader; mloader.load("domain.mesh", &basemesh); /* MeshView meshview("mesh", new WinGeom(0, 0, 500, 400)); meshview.show(&basemesh); View::wait();*/ // Perform initial mesh refinements (optional). for (int i=0; i < INIT_REF_NUM; i++) basemesh.refine_all_elements(); mesh.copy(&basemesh); // Initialize boundary conditions. DefaultEssentialBCConst<double> bc_essential(BDY_IN, 0.0); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); // Initialize solution of lower & higher order Solution<double> low_sln, ref_sln, high_sln, sln; PrevSolution u_prev_time; // Previous time level solution (initialized by the initial condition). CustomInitialCondition initial_condition(&mesh); // Initialize the weak formulation. CustomWeakFormMassmatrix massmatrix(time_step); CustomWeakFormConvection convection; // Initialize views. ScalarView sview("Solution", new WinGeom(0, 500, 500, 400)); OrderView mview("mesh", new WinGeom(0, 0, 500, 400)); OrderView ref_mview("ref_mesh", new WinGeom(500, 0, 500, 400)); char title[100]; // Output solution in VTK format. Linearizer lin; Orderizer ord; bool mode_3D = true; // Create a refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); //Initialize UMFPackMatrix<double> * mass_matrix = new UMFPackMatrix<double> ; //M_c/tau UMFPackMatrix<double> * conv_matrix = new UMFPackMatrix<double> ; //K double* u_L = NULL; double* u_H =NULL; double* ref_sln_double =NULL; int ref_ndof, ndof; double err_est_rel_total; Adapt<double> adaptivity(&space, HERMES_L2_NORM); OGProjection<double> ogProjection; Lumped_Projection lumpedProjection; Low_Order lowOrder(theta); High_Order highOrd(theta); Flux_Correction fluxCorrection(theta); Regularity_Estimator regEst(EPS_smooth); DiscreteProblem<double> dp_mass(&massmatrix, &space); DiscreteProblem<double> dp_convection(&convection, &space); // Time stepping loop: double current_time = 0.0; int ts = 1; do { Hermes::Mixins::Loggable::Static::info("Time step %d, time %3.5f", ts, current_time); Hermes::Hermes2D::Hermes2DApi.set_integral_param_value(Hermes::Hermes2D::numThreads,1); // Periodic global derefinement. if ((ts > 1 && ts % UNREF_FREQ == 0)||(space.get_num_dofs() >= NDOF_STOP)) { 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: Exceptions::Exception("Wrong global derefinement method."); } } bool done = false; int as = 1; do { Hermes::Mixins::Loggable::Static::info("Time step %i, adap_step %i", ts, as); ndof = space.get_num_dofs(); //Unrefinement step /* if(as==1) { double* coeff_vec_smooth = new double[ndof]; if(ts==1) ogProjection.project_global(&space,&initial_condition, coeff_vec_smooth, HERMES_L2_NORM); else ogProjection.project_global(&space,&u_prev_time, coeff_vec_smooth, HERMES_L2_NORM); Solution<double>::vector_to_solution(coeff_vec_smooth, &space, &low_sln); // Calculate element errors and total error estimate. if(ts==1) err_est_rel_total = adaptivity.calc_err_est(&low_sln, &initial_condition) * 100; else err_est_rel_total = adaptivity.calc_err_est(&low_sln, &u_prev_time) * 100; adaptivity.unrefine(THRESHOLD_UNREF); delete [] coeff_vec_smooth; // Visualize the solution. if(HERMES_VISUALIZATION) { sprintf(title, "unrefined Mesh: Time %3.2f,timestep %i", current_time,ts); mview.set_title(title); mview.show(&space); } } */ ndof = space.get_num_dofs(); double* coeff_vec_smooth = new double[ndof]; int* smooth_elem_ref; //smoothness-check for projected data Hermes::Mixins::Loggable::Static::info("Projecting..."); if(ts==1) ogProjection.project_global(&space,&initial_condition, coeff_vec_smooth, HERMES_L2_NORM); else ogProjection.project_global(&space,&u_prev_time, coeff_vec_smooth, HERMES_L2_NORM); Hermes::Mixins::Loggable::Static::info("Calling get_smooth_elems()..."); smooth_elem_ref = regEst.get_smooth_elems(&space,coeff_vec_smooth); // Construct reference mesh and setup reference space. Mesh* ref_mesh = new Mesh; ref_mesh->copy(space.get_mesh()); Space<double>::ReferenceSpaceCreator ref_space_creator(&space, ref_mesh, 0); Space<double>* ref_space = ref_space_creator.create_ref_space(); HPAdapt * adapting = new HPAdapt(ref_space, HERMES_L2_NORM); // increase p in smooth regions, h refine in non-smooth regions Hermes::Mixins::Loggable::Static::info("Calling adapt_smooth()..."); if(adapting->adapt_smooth(smooth_elem_ref, P_MAX)==false) throw Exceptions::Exception("reference space couldn't be constructed"); delete adapting; delete [] coeff_vec_smooth; ref_ndof = ref_space->get_num_dofs(); Hermes::Mixins::Loggable::Static::info("Visualization..."); if(HERMES_VISUALIZATION) { sprintf(title, "Ref_Mesh: Time %3.2f,timestep %i,as=%i,", current_time,ts,as); ref_mview.set_title(title); ref_mview.show(ref_space); } dp_mass.set_space(ref_space); dp_convection.set_space(ref_space); fluxCorrection.init(ref_space); double* coeff_vec = new double[ref_ndof]; double* coeff_vec_2 = new double[ref_ndof]; double* limited_flux = new double[ref_ndof]; dp_mass.assemble(mass_matrix); //M_c/tau dp_convection.assemble(conv_matrix, NULL,true); //K //----------------------MassLumping & Artificial Diffusion -------------------------------------------------------------------- UMFPackMatrix<double>* lumped_matrix = fluxCorrection.massLumping(mass_matrix); // M_L/tau UMFPackMatrix<double>* diffusion = fluxCorrection.artificialDiffusion(conv_matrix); //-----------------Assembling of matrices --------------------------------------------------------------------- lowOrder.assemble_Low_Order(conv_matrix,diffusion,lumped_matrix); highOrd.assemble_High_Order(conv_matrix,mass_matrix); mass_matrix->multiply_with_Scalar(time_step); // massmatrix = M_C lumped_matrix->multiply_with_Scalar(time_step); // M_L //--------- Project the previous timestep solution on the FE space (FCT is applied )---------------- // coeff_vec : FCT -Projection, coeff_vec_2: L2 Projection (ogProjection) if(ts==1) fluxCorrection.project_FCT(&initial_condition, coeff_vec, coeff_vec_2,mass_matrix,lumped_matrix,time_step,&ogProjection,&lumpedProjection, ®Est); else fluxCorrection.project_FCT(&u_prev_time, coeff_vec, coeff_vec_2,mass_matrix,lumped_matrix,time_step,&ogProjection,&lumpedProjection, ®Est); //------------------------- lower order solution------------ u_L = lowOrder.solve_Low_Order(lumped_matrix, coeff_vec,time_step); //-------------high order solution (standard galerkin) ------ u_H = highOrd.solve_High_Order(coeff_vec); //------------------------------Assemble antidiffusive fluxes and limit these----------------------------------- fluxCorrection.antidiffusiveFlux(mass_matrix,lumped_matrix,conv_matrix,diffusion,u_H, u_L,coeff_vec, limited_flux,time_step,®Est); //-------------Compute final solution --------------- ref_sln_double = lowOrder.explicit_Correction(limited_flux); Solution<double> ::vector_to_solution(ref_sln_double, ref_space, &ref_sln); // Project the fine mesh solution onto the coarse mesh. ogProjection.project_global(&space, &ref_sln, &sln, HERMES_L2_NORM); // Calculate element errors and total error estimate. err_est_rel_total = adaptivity.calc_err_est(&sln, &ref_sln) * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", ndof,ref_ndof, err_est_rel_total); // If err_est_rel too large, adapt the mesh. if((err_est_rel_total < ERR_STOP)||(as>=ADAPSTEP_MAX)) done = true; else { done = adaptivity.adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if(done == false) as++; } if(space.get_num_dofs() >= NDOF_STOP) done = true; if(done) { u_prev_time.copy(&ref_sln); u_prev_time.set_own_mesh(ref_mesh); //ref_mesh can be deleted } // Visualize the solution and mesh. if(HERMES_VISUALIZATION) { sprintf(title, "Ref-Loesung: Time %3.2f,timestep %i,as=%i,", current_time,ts,as); sview.set_title(title); sview.show(&ref_sln); sprintf(title, "Mesh: Time %3.2f,timestep %i,as=%i,", current_time,ts,as); mview.set_title(title); mview.show(&space); } if((VTK_VISUALIZATION) &&((done==true)&&(ts % VTK_FREQ == 0))) { // Output solution in VTK format. char filename[40]; sprintf(filename, "solution-%i.vtk", ts ); lin.save_solution_vtk(&u_prev_time, filename, "solution", mode_3D); sprintf(filename, "ref_space_order-%i.vtk", ts); ord.save_orders_vtk(ref_space, filename); sprintf(filename, "ref_mesh-%i.vtk", ts ); ord.save_mesh_vtk(ref_space, filename); } // Clean up. delete lumped_matrix; delete diffusion; delete [] coeff_vec_2; delete [] coeff_vec; delete [] limited_flux; delete ref_mesh; delete ref_space; } while (done == false); // Update global time. current_time += time_step; // Increase time step counter ts++; } while (current_time < T_FINAL); // Visualize the solution. if(VTK_VISUALIZATION) { lin.save_solution_vtk(&u_prev_time, "end_solution.vtk", "solution", mode_3D); ord.save_mesh_vtk(&space, "end_mesh"); ord.save_orders_vtk(&space, "end_order.vtk"); } delete mass_matrix; delete conv_matrix; // Wait for the view 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. Mesh mesh, basemesh; 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(Hermes::vector<std::string>("Left", "Right"), 0); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<double> space(&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); CustomWeakFormPoisson wf(new Hermes::Hermes1DFunction<double>(-1.0), &f); // Previous and next time level solution. ZeroSolution<double> sln_time_prev(&mesh); Solution<double> sln_time_new(&mesh); // Create a refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // 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); Mesh* ref_mesh = refMeshCreator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreator(&space, ref_mesh); Space<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_time_step(time_step); runge_kutta.set_newton_max_iter(NEWTON_MAX_ITER); runge_kutta.set_newton_tol(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. Solution<double> sln_coarse; 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."); Adapt<double>* adaptivity = new Adapt<double>(&space); double err_est_rel_total = adaptivity->calc_err_est(&sln_coarse, &sln_time_new) * 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, THRESHOLD, STRATEGY, MESH_REGULARITY); if (space.get_num_dofs() >= NDOF_STOP) done = true; else // Increase the counter of performed adaptivity steps. as++; } // Clean up. delete adaptivity; if(!done) { delete sln_time_new.get_mesh(); delete ref_space; } } 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* 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[]) { // 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* args[]) { // Load the mesh-> HermesSharedPtr 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-> L2Space<double> space(mesh, P_INIT); // Initialize refinement selector. L2ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Disable weighting of refinement candidates. selector.set_error_weights(1, 1, 1); Solution<double> sln; Solution<double> ref_sln; // Initialize the weak formulation. CustomWeakForm wf("Bdy_bottom_left", mesh); // Initialize the FE problem. DiscreteProblemLinear<double> dp(&wf, space); // Initialize linear solver. Hermes::Hermes2D::LinearSolver<double> linear_solver(&dp); int as = 1; bool done = false; do { // Construct globally refined reference mesh // and setup reference space-> Mesh::ReferenceMeshCreator ref_mesh_creator(mesh); Mesh* ref_mesh = ref_mesh_creator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator ref_space_creator(space, ref_mesh); Space<double>* ref_space = ref_space_creator.create_ref_space(); dp.set_space(ref_space); // Solve the linear system. If successful, obtain the solution. try { linear_solver.solve(); Solution<double>::vector_to_solution(linear_solver.get_sln_vector(), ref_space, &ref_sln); } catch(std::exception& e) { std::cout << e.what(); } // Project the fine mesh solution onto the coarse mesh-> OGProjection<double> ogProjection; ogProjection.project_global(space, &ref_sln, &sln, HERMES_L2_NORM); // Calculate element errors and total error estimate. Adapt<double>* adaptivity = new Adapt<double>(space); double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100; // If err_est_rel too large, adapt the mesh-> if(err_est_rel < ERR_STOP) done = true; else { done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); if(Space<double>::get_num_dofs(space) >= NDOF_STOP) { done = true; break; } } // Clean up. delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; as++; } while (done == false); if(done) { printf("Success!\n"); return 0; } else { printf("Failure!\n"); return -1; } }
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[]) { // Initialize refinement selector. MySelector selector(hORpSelectionBasedOnDOFs); HermesCommonApi.set_integral_param_value(Hermes::showInternalWarnings, false); // Time measurement. Hermes::Mixins::TimeMeasurable cpu_time; cpu_time.tick(); // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", mesh); // Error calculation & adaptivity. DefaultErrorCalculator<complex, HERMES_H1_NORM> errorCalculator(RelativeErrorToGlobalNorm, 1); // Stopping criterion for an adaptivity step. AdaptStoppingCriterionSingleElement<complex> stoppingCriterion(THRESHOLD); // Adaptivity processor class. Adapt<complex> adaptivity(&errorCalculator, &stoppingCriterion); // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh->refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst<complex> bc_essential("Source", P_SOURCE); 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<complex>::get_num_dofs(space); //Hermes::Mixins::Loggable::Static::info("ndof = %d", ndof); // Initialize the weak formulation. CustomWeakFormAcoustics wf("Wall", RHO, SOUND_SPEED, OMEGA); // Initialize coarse and reference mesh solution. MeshFunctionSharedPtr<complex> sln(new Solution<complex>), ref_sln(new Solution<complex>); // Initialize views. ScalarView sview("Acoustic pressure", new WinGeom(600, 0, 600, 350)); sview.show_contours(.2); ScalarView eview("Error", new WinGeom(600, 377, 600, 350)); sview.show_mesh(false); sview.fix_scale_width(50); OrderView oview("Polynomial orders", new WinGeom(1208, 0, 600, 350)); ScalarView ref_view("Refined elements", new WinGeom(1208, 377, 600, 350)); ref_view.show_scale(false); ref_view.set_min_max_range(0, 2); // DOF and CPU convergence graphs initialization. SimpleGraph graph_dof, graph_cpu; //Hermes::Mixins::Loggable::Static::info("Solving on reference mesh."); // Time measurement. cpu_time.tick(); // Perform Newton's iteration. Hermes::Hermes2D::NewtonSolver<complex> newton(&wf, space); newton.set_verbose_output(false); // Adaptivity loop: int as = 1; adaptivity.set_space(space); 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<complex>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh); SpaceSharedPtr<complex> ref_space = refSpaceCreator.create_ref_space(); int ndof_ref = Space<complex>::get_num_dofs(ref_space); wf.set_verbose_output(false); newton.set_space(ref_space); // Assemble the reference problem. 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 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. //Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh."); OGProjection<complex> ogProjection; ogProjection.project_global(space, ref_sln, sln); // Time measurement. cpu_time.tick(); // View the coarse mesh solution and polynomial orders. MeshFunctionSharedPtr<double> acoustic_pressure(new RealFilter(sln)); sview.show(acoustic_pressure); oview.show(space); // 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; eview.show(errorCalculator.get_errorMeshFunction()); // Report results. //Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space<complex>::get_num_dofs(space), Space<complex>::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<complex>::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); ref_view.show(adaptivity.get_refinementInfoMeshFunction()); cpu_time.tick(); std::cout << "Adaptivity step: " << as << ", running CPU time: " << cpu_time.accumulated_str() << std::endl; } // Increase counter. 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 magnitude"); MeshFunctionSharedPtr<double> ref_mag(new RealFilter(ref_sln)); sview.show(ref_mag); // Output solution in VTK format. Linearizer lin(FileExport); bool mode_3D = true; lin.save_solution_vtk(ref_mag, "sln.vtk", "Acoustic pressure", mode_3D); //Hermes::Mixins::Loggable::Static::info("Solution in VTK format saved to file %s.", "sln.vtk"); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Define nonlinear thermal conductivity lambda(u) via a cubic spline. // Step 1: Fill the x values and use lambda_macro(u) = 1 + u^4 for the y values. #define lambda_macro(x) (1 + std::pow(x, 4)) Hermes::vector<double> lambda_pts(-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0); Hermes::vector<double> lambda_val; for (unsigned int i = 0; i < lambda_pts.size(); i++) lambda_val.push_back(lambda_macro(lambda_pts[i])); // Step 2: Create the cubic spline (and plot it for visual control). double bc_left = 0.0; double bc_right = 0.0; bool first_der_left = false; bool first_der_right = false; bool extrapolate_der_left = true; bool extrapolate_der_right = true; CubicSpline lambda(lambda_pts, lambda_val, bc_left, bc_right, first_der_left, first_der_right, extrapolate_der_left, extrapolate_der_right); Hermes::Mixins::Loggable::Static::info("Saving cubic spline into a Pylab file spline.dat."); // The interval of definition of the spline will be // extended by "interval_extension" on both sides. double interval_extension = 3.0; lambda.plot("spline.dat", interval_extension); // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary("Bdy", INIT_BDY_REF_NUM); // Initialize boundary conditions. CustomEssentialBCNonConst bc_essential("Bdy"); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); // Initialize the weak formulation Hermes2DFunction<double> f(-heat_src); WeakFormsH1::DefaultWeakFormPoisson<double> wf(HERMES_ANY, &lambda, &f); // Initialize the FE problem. DiscreteProblem<double> dp_coarse(&wf, &space); // Create a selector which will select optimal candidate. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize coarse and reference mesh solution. Solution<double> sln, ref_sln; // Time measurement. Hermes::Mixins::TimeMeasurable cpu_time; cpu_time.tick(); // Initialize views. ScalarView sview("Solution", new WinGeom(0, 0, 440, 350)); sview.show_mesh(false); OrderView oview("Mesh", new WinGeom(450, 0, 400, 350)); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est; // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. Hermes::Mixins::Loggable::Static::info("Projecting initial condition to obtain initial vector on the coarse mesh."); double* coeff_vec_coarse = new double[space.get_num_dofs()]; InitialSolutionHeatTransfer init_sln(&mesh); OGProjection<double> ogProjection; ogProjection.project_global(&space, &init_sln, coeff_vec_coarse); // Initialize Newton solver on coarse mesh. Hermes::Mixins::Loggable::Static::info("Solving on coarse mesh:"); NewtonSolver<double> newton_coarse(&dp_coarse); newton_coarse.set_verbose_output(Hermes::Mixins::Loggable::Static::info); // Perform initial Newton's iteration on coarse mesh, to obtain // good initial guess for the Newton's method on the fine mesh. try { newton_coarse.solve(coeff_vec_coarse); } catch(std::exception& e) { std::cout << e.what(); } // Translate the resulting coefficient vector into the Solution<double> sln. Solution<double>::vector_to_solution(newton_coarse.get_sln_vector(), &space, &sln); // Cleanup after the Newton loop on the coarse mesh. DiscreteProblem<double> dp(&wf, &space); delete [] coeff_vec_coarse; NewtonSolver<double> newton(&dp); newton.set_verbose_output(Hermes::Mixins::Loggable::Static::info); // 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. Space<double>* ref_space = Space<double>::construct_refined_space(&space); // Initialize discrete problem on the reference mesh. // Calculate initial coefficient vector on the reference mesh. double* coeff_vec = new double[ref_space->get_num_dofs()]; if (as == 1) { // In the first step, project the coarse mesh solution. Hermes::Mixins::Loggable::Static::info("Projecting coarse mesh solution to obtain initial vector on new fine mesh."); OGProjection<double> ogProjection; ogProjection.project_global(ref_space, &sln, coeff_vec); } else { // In all other steps, project the previous fine mesh solution. Hermes::Mixins::Loggable::Static::info("Projecting previous fine mesh solution to obtain initial vector on new fine mesh."); OGProjection<double> ogProjection; ogProjection.project_global(ref_space, &ref_sln, coeff_vec); } // Initialize Newton solver on fine mesh. Hermes::Mixins::Loggable::Static::info("Solving on fine mesh:"); // Perform Newton's iteration. newton.set_space(ref_space); try { newton.solve(coeff_vec); } catch(std::exception& e) { std::cout << e.what(); } // Translate the resulting coefficient vector into the Solution<double> ref_sln. Solution<double>::vector_to_solution(newton.get_sln_vector(), ref_space, &ref_sln); // Project the fine mesh solution on the coarse mesh. Hermes::Mixins::Loggable::Static::info("Projecting reference solution on new coarse mesh for error calculation."); OGProjection<double> ogProjection; ogProjection.project_global(&space, &ref_sln, &sln); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); Adapt<double>* adaptivity = new Adapt<double>(&space); double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 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_est.add_values(Space<double>::get_num_dofs(&space), err_est_rel); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu_est.save("conv_cpu_est.dat"); // View the coarse mesh solution. sview.show(&sln); oview.show(&space); // If err_est_rel 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, THRESHOLD, STRATEGY, MESH_REGULARITY); if (Space<double>::get_num_dofs(&space) >= NDOF_STOP) { done = true; break; } } // Clean up. delete [] coeff_vec; delete adaptivity; 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 keyboard or mouse input. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Time measurement. Hermes::Mixins::TimeMeasurable cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("square.mesh", &mesh); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, P_INIT); // Initialize the weak formulation. WeakForm<double> wf_dummy; // Initialize coarse and reference mesh solution. Solution<double> sln; ExactSolutionCustom* ref_sln = NULL; // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. ScalarView sview("Scalar potential Phi", new WinGeom(0, 0, 610, 300)); sview.fix_scale_width(40); sview.show_mesh(false); OrderView oview("Mesh", new WinGeom(620, 0, 600, 300)); // DOF and CPU convergence graphs. SimpleGraph graph_dof, graph_cpu; // 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. Space<double>* ref_space = Space<double>::construct_refined_space(&space); // Assign the function f() to the fine mesh. Hermes::Mixins::Loggable::Static::info("Assigning f() to the fine mesh."); if(ref_sln != NULL) delete ref_sln; ref_sln = new ExactSolutionCustom(ref_space->get_mesh()); // Time measurement. cpu_time.tick(); // 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(&space, ref_sln, &sln); // View the coarse mesh solution and polynomial orders. sview.show(&sln); oview.show(&space); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating exact error."); Adapt<double>* adaptivity = new Adapt<double>(&space); // Note: the error estimate is now equal to the exact error. double err_exact_rel = adaptivity->calc_err_est(&sln, ref_sln) * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_exact_rel: %g%%", Space<double>::get_num_dofs(&space), Space<double>::get_num_dofs(ref_space), err_exact_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_exact_rel); graph_dof.save("conv_dof.dat"); graph_cpu.add_values(cpu_time.accumulated(), err_exact_rel); graph_cpu.save("conv_cpu.dat"); // If err_exact_rel too large, adapt the mesh. if (err_exact_rel < ERR_STOP) done = true; else { Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if (done == false) as++; } if (Space<double>::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete adaptivity; if (done == false) delete ref_space->get_mesh(); delete ref_space; } 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(ref_sln); // 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. Mesh mesh; MeshReaderH2D mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary("Bdy", INIT_BDY_REF_NUM); // Initialize boundary conditions. CustomEssentialBCNonConst bc_essential("Bdy"); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); int ndof = space.get_num_dofs(); Hermes::Mixins::Loggable::Static::info("ndof: %d", ndof); // Initialize the weak formulation CustomNonlinearity lambda(alpha); Hermes2DFunction<double> src(-heat_src); DefaultWeakFormPoisson<double> wf(HERMES_ANY, &lambda, &src); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, &space); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. // NOTE: If you want to start from the zero vector, just define // coeff_vec to be a vector of ndof zeros (no projection is needed). Hermes::Mixins::Loggable::Static::info("Projecting to obtain initial vector for the Newton's method."); double* coeff_vec = new double[ndof]; CustomInitialCondition init_sln(&mesh); OGProjection<double> ogProjection; ogProjection.project_global(&space, &init_sln, coeff_vec); // Initialize Newton solver. NewtonSolver<double> newton(&dp); // Perform Newton's iteration. try { newton.set_newton_max_iter(NEWTON_MAX_ITER); newton.set_newton_tol(NEWTON_TOL); newton.solve(coeff_vec); } catch(std::exception& e) { std::cout << e.what(); } // Translate the resulting coefficient vector into a Solution. Solution<double> sln; Solution<double>::vector_to_solution(newton.get_sln_vector(), &space, &sln); // Get info about time spent during assembling in its respective parts. //dp.get_all_profiling_output(std::cout); // Clean up. delete [] coeff_vec; // Visualise the solution and mesh. ScalarView s_view("Solution", new WinGeom(0, 0, 440, 350)); s_view.show_mesh(false); s_view.show(&sln); OrderView o_view("Mesh", new WinGeom(450, 0, 400, 350)); o_view.show(&space); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinement. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary("Bdy", INIT_REF_NUM_BDY); // Define exact solution. CustomExactSolution exact_sln(&mesh, K); // Define right side vector. CustomFunction f(K); // Initialize the weak formulation. CustomWeakForm wf(&f); // Initialize boundary conditions. DefaultEssentialBCConst<double> bc_essential("Bdy", 0.0); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); // Initialize approximate solution. Solution<double> sln; // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. Views::ScalarView sview("Solution", new Views::WinGeom(0, 0, 440, 350)); sview.show_mesh(false); Views::OrderView oview("Polynomial orders", new Views::WinGeom(450, 0, 400, 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); Mesh* ref_mesh = refMeshCreator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreator(&space, ref_mesh); Space<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); Solution<double> ref_sln; 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. Adapt<double> adaptivity(&space); double err_est_rel = adaptivity.calc_err_est(&sln, &ref_sln) * 100; // Calculate exact error. double err_exact_rel = Global<double>::calc_rel_error(&sln, &exact_sln, HERMES_H1_NORM) * 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 || space.get_num_dofs() >= NDOF_STOP) done = true; else done = adaptivity.adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Adaptation: %g s", cpu_time.last()); // Increase the counter of adaptivity steps. if (done == false) as++; if(done == false) delete ref_space->get_mesh(); delete ref_space; } 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* 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(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; } // Load the mesh. Mesh mesh; MeshReaderH2D mloader; // Quadrilaterals. mloader.load("square_quad.mesh", &mesh); // Triangles. // mloader.load("square_tri.mesh", &mesh); // Perform initial mesh refinement. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Set exact solution. CustomExactSolution exact_sln(&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. CustomWeakForm wf(&rhs); // Equivalent, but slower: // WeakFormsH1::DefaultWeakFormPoisson wf(HERMES_ANY, HERMES_ONE, &rhs); // Initialize boundary conditions. DefaultEssentialBCNonConst<double> bc("Bdy", &exact_sln); EssentialBCs<double> bcs(&bc); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); // Initialize approximate solution. Solution<double> sln; // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // 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; // Adaptivity loop: int as = 1; bool done = false; do { cpu_time.tick(); // Construct globally refined reference mesh and setup reference space. Space<double>* ref_space = Space<double>::construct_refined_space(&space, 1); 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); Solution<double> ref_sln; try { newton.solve(); } catch(Hermes::Exceptions::Exception e) { e.printMsg(); 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. Adapt<double> adaptivity(&space); double err_est_rel = adaptivity.calc_err_est(&sln, &ref_sln) * 100; // Calculate exact error. double err_exact_rel = Global<double>::calc_rel_error(&sln, &exact_sln, HERMES_H1_NORM) * 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 || space.get_num_dofs() >= NDOF_STOP) done = true; else done = adaptivity.adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Adaptation: %g s", cpu_time.last()); // Increase the counter of adaptivity steps. if (done == false) as++; delete ref_space->get_mesh(); delete ref_space; } 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* 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[]) { // Time measurement. Hermes::Mixins::TimeMeasurable cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinements. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst<double> bc("Bdy", 0.0); EssentialBCs<double> bcs(&bc); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); int ndof = Space<double>::get_num_dofs(&space); Hermes::Mixins::Loggable::Static::info("ndof: %d", ndof); Hermes::Mixins::Loggable::Static::info("Assembling by DiscreteProblem, solving by Umfpack:"); // Time measurement. cpu_time.tick(); // Initialize weak formulation, CustomWeakForm wf1; // Initialize the discrete problem. DiscreteProblem<double> dp1(&wf1, &space); // Initialize the Newton solver. Hermes::Hermes2D::NewtonSolver<double> newton(&dp1); // Perform Newton's iteration and translate the resulting coefficient vector into a Solution. Hermes::Hermes2D::Solution<double> sln1; try { newton.solve(); } catch(std::exception& e) { std::cout << e.what(); } // Translate the solution vector into a Solution. Hermes::Hermes2D::Solution<double>::vector_to_solution(newton.get_sln_vector(), &space, &sln1); // CPU time needed by UMFpack double time1 = cpu_time.tick().last(); // Time measurement. cpu_time.tick(); // Show UMFPACK solution. ScalarView view1("Solution 1", new WinGeom(0, 0, 500, 400)); view1.show(&sln1); // Calculate error. CustomExactSolution ex(&mesh); double rel_err_1 = Global<double>::calc_rel_error(&sln1, &ex, HERMES_H1_NORM) * 100; Hermes::Mixins::Loggable::Static::info("Solution 1 : exact H1 error: %g%% (time %g s)", rel_err_1, time1); // TRILINOS PART: // Project the initial condition to obtain the initial // coefficient vector. Hermes::Mixins::Loggable::Static::info("Projecting to obtain initial vector for the Newton's method."); double* coeff_vec = new double[ndof]; ZeroSolution<double> sln_tmp(&mesh); OGProjection<double> ogProjection; ogProjection.project_global(&space, &sln_tmp, coeff_vec); // Measure the projection time. double proj_time = cpu_time.tick().last(); // Initialize the weak formulation for Trilinos. CustomWeakForm wf2(TRILINOS_JFNK, PRECOND == 1, PRECOND == 2); // Initialize DiscreteProblem. DiscreteProblem<double> dp2(&wf2, &space); // Initialize the NOX solver with the vector "coeff_vec". Hermes::Mixins::Loggable::Static::info("Initializing NOX."); NewtonSolverNOX<double> solver_nox(&dp2); solver_nox.set_output_flags(message_type); solver_nox.set_ls_tolerance(ls_tolerance); solver_nox.set_conv_iters(max_iters); if (flag_absresid) solver_nox.set_conv_abs_resid(abs_resid); if (flag_relresid) solver_nox.set_conv_rel_resid(rel_resid); // Choose preconditioning. MlPrecond<double> pc("sa"); if (PRECOND) { if (TRILINOS_JFNK) solver_nox.set_precond(pc); else solver_nox.set_precond("ML"); } // Solve the nonlinear problem using NOX. Hermes::Mixins::Loggable::Static::info("Assembling by DiscreteProblem, solving by NOX."); Solution<double> sln2; try { solver_nox.solve(coeff_vec); } catch(std::exception& e) { std::cout << e.what(); } Solution<double>::vector_to_solution(solver_nox.get_sln_vector(), &space, &sln2); Hermes::Mixins::Loggable::Static::info("Number of nonlin iterations: %d (norm of residual: %g)", solver_nox.get_num_iters(), solver_nox.get_residual()); Hermes::Mixins::Loggable::Static::info("Total number of iterations in linsolver: %d (achieved tolerance in the last step: %g)", solver_nox.get_num_lin_iters(), solver_nox.get_achieved_tol()); // CPU time needed by NOX. double time2 = cpu_time.tick().last(); // Calculate error. double rel_err_2 = Global<double>::calc_rel_error(&sln2, &ex, HERMES_H1_NORM) * 100; Hermes::Mixins::Loggable::Static::info("Solution 2 (NOX): exact H1 error: %g%% (time %g + %g = %g [s])", rel_err_2, proj_time, time2, proj_time+time2); // Show NOX solution. ScalarView view2("Solution 2", new WinGeom(510, 0, 500, 400)); view2.show(&sln2); // Wait for all views to be closed. View::wait(); return 0; }