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[]) { // Load the mesh. MeshSharedPtr u_mesh(new Mesh), v_mesh(new Mesh); MeshReaderH2DXML mloader; mloader.load("domain.xml", u_mesh); u_mesh->refine_all_elements(); v_mesh->copy(u_mesh); v_mesh->refine_towards_boundary("Bdy", INIT_REF_BDY); // Define right-hand sides. CustomRightHandSide1* g1 = new CustomRightHandSide1(K, D_u, SIGMA); CustomRightHandSide2* g2 = new CustomRightHandSide2(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>(v_mesh, &bcs_v, P_INIT_V)); Hermes::vector<SpaceSharedPtr<double> > spaces(u_space, v_space); NewtonSolver<double> newton(&wf, spaces); MeshFunctionSharedPtr<double> u_sln(new Solution<double>()); MeshFunctionSharedPtr<double> u_sln1(new Solution<double>()); MeshFunctionSharedPtr<double> v_sln(new Solution<double>()); MeshFunctionSharedPtr<double> v_sln1(new Solution<double>()); Hermes::vector<MeshFunctionSharedPtr<double> > slns(u_sln, v_sln); Hermes::vector<MeshFunctionSharedPtr<double> > slns1(u_sln1, v_sln1); newton.solve(); Solution<double>::vector_to_solutions(newton.get_sln_vector(), spaces, slns); u_sln1->copy(u_sln); v_sln1->copy(v_sln); u_sln->free(); v_sln->free(); u_sln->copy(u_sln1); v_sln->copy(v_sln1); newton.solve(slns); Solution<double>::vector_to_solutions(newton.get_sln_vector(), spaces, slns1); Linearizer lin(FileExport); lin.process_solution(u_sln); lin.process_solution(u_sln1); lin.process_solution(v_sln1); lin.process_solution(u_sln1); lin.process_solution(u_sln1); lin.process_solution(v_sln1); return 0; }
int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh u_mesh, v_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. ExactSolutionFitzHughNagumo1 exact_u(&u_mesh); ExactSolutionFitzHughNagumo2 exact_v(&v_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. H1Space<double> u_space(&u_mesh, &bcs_u, P_INIT_U); H1Space<double> v_space(MULTI ? &v_mesh : &u_mesh, &bcs_v, P_INIT_V); // Initialize coarse and reference mesh solutions. Solution<double> u_sln, v_sln, u_ref_sln, v_ref_sln; // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // 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; // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Hermes::vector<Space<double> *>* ref_spaces = Space<double>::construct_refined_spaces(Hermes::vector<Space<double> *>(&u_space, &v_space)); Space<double>* u_ref_space = (*ref_spaces)[0]; Space<double>* v_ref_space = (*ref_spaces)[1]; Hermes::vector<const Space<double> *> ref_spaces_const((*ref_spaces)[0], (*ref_spaces)[1]); int ndof_ref = Space<double>::get_num_dofs(ref_spaces_const); // Initialize reference problem. info("Solving on reference mesh."); DiscreteProblem<double> dp(&wf, ref_spaces_const); NewtonSolver<double> newton(&dp, matrix_solver); //newton.set_verbose_output(false); // Time measurement. cpu_time.tick(); // Perform Newton's iteration. try { newton.solve(); } catch(Hermes::Exceptions::Exception e) { e.printMsg(); error("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_const, Hermes::vector<Solution<double> *>(&u_ref_sln, &v_ref_sln)); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection<double>::project_global(Hermes::vector<const Space<double> *>(&u_space, &v_space), Hermes::vector<Solution<double> *>(&u_ref_sln, &v_ref_sln), Hermes::vector<Solution<double> *>(&u_sln, &v_sln), matrix_solver); 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. info("Calculating error estimate and exact error."); Adapt<double>* adaptivity = new Adapt<double>(Hermes::vector<Space<double> *>(&u_space, &v_space)); // Calculate error estimate for each solution component and the total error estimate. Hermes::vector<double> err_est_rel; double err_est_rel_total = adaptivity->calc_err_est(Hermes::vector<Solution<double> *>(&u_sln, &v_sln), Hermes::vector<Solution<double> *>(&u_ref_sln, &v_ref_sln), &err_est_rel) * 100; // Calculate exact error for each solution component and the total exact error. Hermes::vector<double> err_exact_rel; bool solutions_for_adapt = false; double err_exact_rel_total = adaptivity->calc_err_exact(Hermes::vector<Solution<double> *>(&u_sln, &v_sln), Hermes::vector<Solution<double> *>(&exact_u, &exact_v), &err_exact_rel, solutions_for_adapt) * 100; // Time measurement. cpu_time.tick(); // Report results. info("ndof_coarse[0]: %d, ndof_fine[0]: %d", u_space.get_num_dofs(), u_ref_space->get_num_dofs()); info("err_est_rel[0]: %g%%, err_exact_rel[0]: %g%%", err_est_rel[0]*100, err_exact_rel[0]*100); info("ndof_coarse[1]: %d, ndof_fine[1]: %d", v_space.get_num_dofs(), v_ref_space->get_num_dofs()); info("err_est_rel[1]: %g%%, err_exact_rel[1]: %g%%", err_est_rel[1]*100, err_exact_rel[1]*100); info("ndof_coarse_total: %d, ndof_fine_total: %d", Space<double>::get_num_dofs(Hermes::vector<const Space<double> *>(&u_space, &v_space)), Space<double>::get_num_dofs(ref_spaces_const)); 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<const Space<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<const Space<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 { info("Adapting coarse mesh."); done = adaptivity->adapt(Hermes::vector<RefinementSelectors::Selector<double> *>(&selector, &selector), THRESHOLD, STRATEGY, MESH_REGULARITY); } if (Space<double>::get_num_dofs(Hermes::vector<const Space<double> *>(&u_space, &v_space)) >= NDOF_STOP) done = true; // Clean up. delete adaptivity; for(unsigned int i = 0; i < ref_spaces->size(); i++) delete (*ref_spaces)[i]->get_mesh(); delete ref_spaces; // Increase counter. as++; } while (done == false); verbose("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()) info("Using a %d-stage explicit R-K method.", bt.get_size()); if (bt.is_diagonally_implicit()) info("Using a %d-stage diagonally implicit R-K method.", bt.get_size()); if (bt.is_fully_implicit()) info("Using a %d-stage fully implicit R-K method.", bt.get_size()); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("../domain.mesh", &mesh); // Convert to quadrilaterals. mesh.convert_triangles_to_quads(); // Refine towards boundary. mesh.refine_towards_boundary("Bdy", 1, true); // Refine once towards vertex #4. mesh.refine_towards_vertex(4, 1); // Initialize solutions. CustomInitialConditionWave u_sln(&mesh); Solution v_sln(&mesh, 0.0); Hermes::vector<Solution*> slns(&u_sln, &v_sln); // Initialize the weak formulation. CustomWeakFormWave wf(time_step, C_SQUARED, &u_sln, &v_sln); // Initialize boundary conditions DefaultEssentialBCConst bc_essential("Bdy", 0.0); EssentialBCs bcs(&bc_essential); // Create x- and y- displacement space using the default H1 shapeset. H1Space u_space(&mesh, &bcs, P_INIT); H1Space v_space(&mesh, &bcs, P_INIT); info("ndof = %d.", Space::get_num_dofs(Hermes::vector<Space *>(&u_space, &v_space))); // Initialize the FE problem. DiscreteProblem dp(&wf, Hermes::vector<Space *>(&u_space, &v_space)); // Initialize Runge-Kutta time stepping. RungeKutta runge_kutta(&dp, &bt, matrix_solver); // Time stepping loop. double current_time = 0; int ts = 1; do { // Perform one Runge-Kutta time step according to the selected Butcher's table. info("Runge-Kutta time step (t = %g s, time_step = %g s, stages: %d).", current_time, time_step, bt.get_size()); bool jacobian_changed = false; bool verbose = true; if (!runge_kutta.rk_time_step(current_time, time_step, slns, slns, jacobian_changed, verbose)) error("Runge-Kutta time step failed, try to decrease time step size."); // Update time. current_time += time_step; } while (current_time < T_FINAL); double coord_x[4] = {1, 3, 5, 7}; double coord_y[4] = {1, 3, 5, 7}; info("Coordinate (1.0, 0.0) value = %lf", u_sln.get_pt_value(coord_x[0], coord_y[0])); info("Coordinate (3.0, 3.0) value = %lf", u_sln.get_pt_value(coord_x[1], coord_y[1])); info("Coordinate (5.0, 5.0) value = %lf", u_sln.get_pt_value(coord_x[2], coord_y[2])); info("Coordinate (7.0, 7.0) value = %lf", u_sln.get_pt_value(coord_x[3], coord_y[3])); info("Coordinate (1.0, 0.0) value = %lf", v_sln.get_pt_value(coord_x[0], coord_y[0])); info("Coordinate (3.0, 3.0) value = %lf", v_sln.get_pt_value(coord_x[1], coord_y[1])); info("Coordinate (5.0, 5.0) value = %lf", v_sln.get_pt_value(coord_x[2], coord_y[2])); info("Coordinate (7.0, 7.0) value = %lf", v_sln.get_pt_value(coord_x[3], coord_y[3])); double t_value[8] = {0.212655, 0.000163, 0.000000, 0.000000, -0.793316, 0.007255, 0.000001, 0.000000}; bool success = true; for (int i = 0; i < 4; i++) { if (fabs(t_value[i] - u_sln.get_pt_value(coord_x[i], coord_y[i])) > 1E-6) success = false; } for (int i = 4; i < 8; i++) { if (fabs(t_value[i] - v_sln.get_pt_value(coord_x[i-4], coord_y[i-4])) > 1E-6) success = false; } if (success) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } // Wait for the view to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh file. Mesh mesh; H2DReader mloader; mloader.load("sample.mesh", &mesh); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_1); bc_types.add_bc_neumann(Hermes::Tuple<int>(BDY_2, BDY_3, BDY_4, BDY_5)); // Enter Dirichlet boundary values; BCValues bc_values; bc_values.add_zero(BDY_1); // Create x- and y- displacement space using the default H1 shapeset. H1Space u_space(&mesh, &bc_types, &bc_values, P_INIT); H1Space v_space(&mesh, &bc_types, &bc_values, P_INIT); info("ndof = %d.", Space::get_num_dofs(Hermes::Tuple<Space *>(&u_space, &v_space))); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, callback(bilinear_form_0_0), HERMES_SYM); // Note that only one symmetric part is wf.add_matrix_form(0, 1, callback(bilinear_form_0_1), HERMES_SYM); // added in the case of symmetric bilinear wf.add_matrix_form(1, 1, callback(bilinear_form_1_1), HERMES_SYM); // forms. wf.add_vector_form_surf(0, callback(linear_form_surf_0), BDY_3); wf.add_vector_form_surf(1, callback(linear_form_surf_1), BDY_3); // Testing n_dof and correctness of solution vector // for p_init = 1, 2, ..., 10 int success = 1; Solution xsln, ysln; for (int p_init = 1; p_init <= 10; p_init++) { printf("********* p_init = %d *********\n", p_init); u_space.set_uniform_order(p_init); v_space.set_uniform_order(p_init); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, Hermes::Tuple<Space *>(&u_space, &v_space), is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the solutions. Solution u_sln, v_sln; // Assemble the stiffness matrix and right-hand side vector. info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); // Solve the linear system and if successful, obtain the solutions. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), Hermes::Tuple<Space *>(&u_space, &v_space), Hermes::Tuple<Solution *>(&u_sln, &v_sln)); else error ("Matrix solver failed.\n"); int ndof = Space::get_num_dofs(Hermes::Tuple<Space *>(&u_space, &v_space)); printf("ndof = %d\n", ndof); double sum = 0; for (int i=0; i < ndof; i++) sum += solver->get_solution()[i]; printf("coefficient sum = %g\n", sum); // Actual test. The values of 'sum' depend on the // current shapeset. If you change the shapeset, // you need to correct these numbers. if (p_init == 1 && fabs(sum - 3.50185e-06) > 1e-3) success = 0; if (p_init == 2 && fabs(sum - 4.34916e-06) > 1e-3) success = 0; if (p_init == 3 && fabs(sum - 4.60553e-06) > 1e-3) success = 0; if (p_init == 4 && fabs(sum - 4.65616e-06) > 1e-3) success = 0; if (p_init == 5 && fabs(sum - 4.62893e-06) > 1e-3) success = 0; if (p_init == 6 && fabs(sum - 4.64336e-06) > 1e-3) success = 0; if (p_init == 7 && fabs(sum - 4.63724e-06) > 1e-3) success = 0; if (p_init == 8 && fabs(sum - 4.64491e-06) > 1e-3) success = 0; if (p_init == 9 && fabs(sum - 4.64582e-06) > 1e-3) success = 0; if (p_init == 10 && fabs(sum - 4.65028e-06) > 1e-3) success = 0; } if (success == 1) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform uniform mesh refinement. mesh.refine_all_elements(); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_1); bc_types.add_bc_neumann(Hermes::vector<int>(BDY_2, BDY_3, BDY_4, BDY_5)); // Enter Dirichlet boundary values; BCValues bc_values; bc_values.add_zero(BDY_1); // Create x- and y- displacement space using the default H1 shapeset. H1Space u_space(&mesh, &bc_types, &bc_values, P_INIT); H1Space v_space(&mesh, &bc_types, &bc_values, P_INIT); info("ndof = %d.", Space::get_num_dofs(Hermes::vector<Space *>(&u_space, &v_space))); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, callback(bilinear_form_0_0), HERMES_SYM); // Note that only one symmetric part is wf.add_matrix_form(0, 1, callback(bilinear_form_0_1), HERMES_SYM); // added in the case of symmetric bilinear wf.add_matrix_form(1, 1, callback(bilinear_form_1_1), HERMES_SYM); // forms. wf.add_vector_form_surf(0, callback(linear_form_surf_0), BDY_3); wf.add_vector_form_surf(1, callback(linear_form_surf_1), BDY_3); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, Hermes::vector<Space *>(&u_space, &v_space), is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the solutions. Solution u_sln, v_sln; // Assemble the stiffness matrix and right-hand side vector. info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); // Solve the linear system and if successful, obtain the solutions. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), Hermes::vector<Space *>(&u_space, &v_space), Hermes::vector<Solution *>(&u_sln, &v_sln)); else error ("Matrix solver failed.\n"); // Visualize the solution. ScalarView view("Von Mises stress [Pa]", new WinGeom(0, 0, 800, 400)); VonMisesFilter stress(Hermes::vector<MeshFunction *>(&u_sln, &v_sln), lambda, mu); view.show_mesh(false); view.show(&stress, HERMES_EPS_HIGH, H2D_FN_VAL_0, &u_sln, &v_sln, 1.5e5); // Wait for the view to be closed. View::wait(); // Clean up. delete solver; delete matrix; delete rhs; return 0; }