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(); // Initialize boundary conditions. DefaultEssentialBCConst zero_disp(BDY_1, 0.0); EssentialBCs bcs(&zero_disp); // Create x- and y- displacement space using the default H1 shapeset. H1Space u1_space(&mesh, &bcs, P_INIT); H1Space u2_space(&mesh, &bcs, P_INIT); info("ndof = %d.", Space::get_num_dofs(Hermes::vector<Space *>(&u1_space, &u2_space))); // Initialize the weak formulation. CustomWeakFormLinearElasticity wf(E, nu, rho*g1, BDY_3, f0, f1); // 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); u1_space.set_uniform_order(p_init); u2_space.set_uniform_order(p_init); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, Hermes::vector<Space *>(&u1_space, &u2_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 u1_sln, u2_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 *>(&u1_space, &u2_space), Hermes::vector<Solution *>(&u1_sln, &u2_sln)); else error ("Matrix solver failed.\n"); int ndof = Space::get_num_dofs(Hermes::vector<Space *>(&u1_space, &u2_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[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh u1_mesh, u2_mesh; MeshReaderH2D mloader; mloader.load("bracket.mesh", &u1_mesh); // Initial mesh refinements. u1_mesh.refine_element_id(1); u1_mesh.refine_element_id(4); // Create initial mesh for the vertical displacement component. // This also initializes the multimesh hp-FEM. u2_mesh.copy(&u1_mesh); // Initialize boundary conditions. DefaultEssentialBCConst<double> zero_disp(BDY_RIGHT, 0.0); EssentialBCs<double> bcs(&zero_disp); // Create x- and y- displacement space using the default H1 shapeset. H1Space<double> u1_space(&u1_mesh, &bcs, P_INIT); H1Space<double> u2_space(&u2_mesh, &bcs, P_INIT); info("ndof = %d.", Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&u1_space, &u2_space))); // Initialize the weak formulation. // NOTE; These weak forms are identical to those in example P01-linear/08-system. CustomWeakForm wf(E, nu, rho*g1, BDY_TOP, f0, f1); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, Hermes::vector<Space<double> *>(&u1_space, &u2_space)); // Initialize coarse and reference mesh solutions. Solution<double> u1_sln, u2_sln, u1_ref_sln, u2_ref_sln; // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. ScalarView s_view_0("Solution (x-displacement)", new WinGeom(0, 0, 400, 350)); s_view_0.show_mesh(false); ScalarView s_view_1("Solution (y-displacement)", new WinGeom(760, 0, 400, 350)); s_view_1.show_mesh(false); OrderView o_view_0("Mesh (x-displacement)", new WinGeom(410, 0, 340, 350)); OrderView o_view_1("Mesh (y-displacement)", new WinGeom(1170, 0, 340, 350)); ScalarView mises_view("Von Mises stress [Pa]", new WinGeom(0, 405, 400, 350)); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est; // 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> *>(&u1_space, &u2_space)); // Initialize matrix solver. SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type); Vector<double>* rhs = create_vector<double>(matrix_solver_type); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs); // Assemble the reference problem. info("Solving on reference mesh."); DiscreteProblem<double> dp(&wf, *ref_spaces); dp.assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. If successful, obtain the solutions. if(solver->solve()) Solution<double>::vector_to_solutions(solver->get_sln_vector(), *ref_spaces, Hermes::vector<Solution *>(&u1_ref_sln, &u2_ref_sln)); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection<double>::project_global(Hermes::vector<Space<double> *>(&u1_space, &u2_space), Hermes::vector<Solution<double> *>(&u1_ref_sln, &u2_ref_sln), Hermes::vector<Solution<double> *>(&u1_sln, &u2_sln), matrix_solver_type); // View the coarse mesh solution and polynomial orders. s_view_0.show(&u1_sln); o_view_0.show(&u1_space); s_view_1.show(&u2_sln); o_view_1.show(&u2_space); // For von Mises stress Filter. double lambda = (E * nu) / ((1 + nu) * (1 - 2*nu)); double mu = E / (2*(1 + nu)); VonMisesFilter stress(Hermes::vector<MeshFunction<double> *>(&u1_sln, &u2_sln), lambda, mu); mises_view.show(&stress, HERMES_EPS_HIGH, H2D_FN_VAL_0, &u1_sln, &u2_sln, 1e4); // Skip visualization time. cpu_time.tick(HERMES_SKIP); // Initialize adaptivity. Adapt<double>* adaptivity = new Adapt<double>(Hermes::vector<Space<double> *>(&u1_space, &u2_space)); /* // Register custom forms for error calculation. adaptivity->set_error_form(0, 0, bilinear_form_0_0<double, double>, bilinear_form_0_0<Ord, Ord>); adaptivity->set_error_form(0, 1, bilinear_form_0_1<double, double>, bilinear_form_0_1<Ord, Ord>); adaptivity->set_error_form(1, 0, bilinear_form_1_0<double, double>, bilinear_form_1_0<Ord, Ord>); adaptivity->set_error_form(1, 1, bilinear_form_1_1<double, double>, bilinear_form_1_1<Ord, Ord>); */ // Calculate error estimate for each solution component and the total error estimate. info("Calculating error estimate and exact error."); Hermes::vector<double> err_est_rel; double err_est_rel_total = adaptivity->calc_err_est(Hermes::vector<Solution<double> *>(&u1_sln, &u2_sln), Hermes::vector<Solution<double> *>(&u1_ref_sln, &u2_ref_sln), &err_est_rel) * 100; // Time measurement. cpu_time.tick(); // Report results. info("ndof_coarse[0]: %d, ndof_fine[0]: %d, err_est_rel[0]: %g%%", u1_space.Space<double>::get_num_dofs(), Space<double>::get_num_dofs((*ref_spaces)[0]), err_est_rel[0]*100); info("ndof_coarse[1]: %d, ndof_fine[1]: %d, err_est_rel[1]: %g%%", u2_space.Space<double>::get_num_dofs(), Space<double>::get_num_dofs((*ref_spaces)[1]), err_est_rel[1]*100); info("ndof_coarse_total: %d, ndof_fine_total: %d, err_est_rel_total: %g%%", Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&u1_space, &u2_space)), Space<double>::get_num_dofs(*ref_spaces), err_est_rel_total); // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&u1_space, &u2_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"); // 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<Space<double> *>(&u1_space, &u2_space)) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) 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()); // Show the reference solution - the final result. s_view_0.set_title("Fine mesh solution (x-displacement)"); s_view_0.show(&u1_ref_sln); s_view_1.set_title("Fine mesh solution (y-displacement)"); s_view_1.show(&u2_ref_sln); // For von Mises stress Filter. double lambda = (E * nu) / ((1 + nu) * (1 - 2*nu)); double mu = E / (2*(1 + nu)); VonMisesFilter stress(Hermes::vector<MeshFunction<double> *>(&u1_ref_sln, &u2_ref_sln), lambda, mu); mises_view.show(&stress, HERMES_EPS_HIGH, H2D_FN_VAL_0, &u1_ref_sln, &u2_ref_sln, 1e4); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh), mesh1(new Mesh); if (USE_XML_FORMAT == true) { MeshReaderH2DXML mloader; Hermes::Mixins::Loggable::Static::info("Reading mesh in XML format."); mloader.load("domain.xml", mesh); } else { MeshReaderH2D mloader; Hermes::Mixins::Loggable::Static::info("Reading mesh in original format."); mloader.load("domain.mesh", mesh); } // Perform uniform mesh refinement. mesh->refine_all_elements(); // Show mesh. MeshView mv("Mesh", new WinGeom(0, 0, 580, 400)); mv.show(mesh); // Initialize boundary conditions. DefaultEssentialBCConst<double> zero_disp("Bottom", 0.0); EssentialBCs<double> bcs(&zero_disp); // Create x- and y- displacement space using the default H1 shapeset. SpaceSharedPtr<double> u1_space(new H1Space<double>(mesh, &bcs, P_INIT)); SpaceSharedPtr<double> u2_space(new H1Space<double>(mesh, &bcs, P_INIT)); Hermes::vector<SpaceSharedPtr<double> > spaces(u1_space, u2_space); int ndof = Space<double>::get_num_dofs(spaces); Hermes::Mixins::Loggable::Static::info("ndof = %d", ndof); // Initialize the weak formulation. CustomWeakFormLinearElasticity wf(E, nu, rho*g1, "Top", f0, f1); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, spaces); // Initialize Newton solver. NewtonSolver<double> newton(&dp); newton.set_verbose_output(true); // Perform Newton's iteration. try { newton.solve(); } catch(std::exception& e) { std::cout << e.what(); } // Translate the resulting coefficient vector into the Solution sln. MeshFunctionSharedPtr<double> u1_sln(new Solution<double>), u2_sln(new Solution<double>); Solution<double>::vector_to_solutions(newton.get_sln_vector(), spaces, Hermes::vector<MeshFunctionSharedPtr<double> >(u1_sln, u2_sln)); // Visualize the solution. ScalarView view("Von Mises stress [Pa]", new WinGeom(590, 0, 700, 400)); // First Lame constant. double lambda = (E * nu) / ((1 + nu) * (1 - 2*nu)); // Second Lame constant. double mu = E / (2*(1 + nu)); MeshFunctionSharedPtr<double> stress(new VonMisesFilter(Hermes::vector<MeshFunctionSharedPtr<double> >(u1_sln, u2_sln), lambda, mu)); view.show_mesh(false); view.show(stress, HERMES_EPS_HIGH, H2D_FN_VAL_0, u1_sln, u2_sln, 1.5e5); // Wait for the view to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh mesh, mesh1; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform uniform mesh refinement. mesh.refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst zero_disp("Bottom", 0.0); EssentialBCs bcs(&zero_disp); // Create x- and y- displacement space using the default H1 shapeset. H1Space u1_space(&mesh, &bcs, P_INIT); H1Space u2_space(&mesh, &bcs, P_INIT); int ndof = Space::get_num_dofs(Hermes::vector<Space *>(&u1_space, &u2_space)); info("ndof = %d", ndof); // Initialize the weak formulation. CustomWeakFormLinearElasticity wf(E, nu, rho*g1, "Top", f0, f1); // Initialize the FE problem. DiscreteProblem dp(&wf, Hermes::vector<Space *>(&u1_space, &u2_space)); // 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); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof]; memset(coeff_vec, 0, ndof*sizeof(scalar)); // Perform Newton's iteration. bool verbose = true; bool jacobian_changed = true; if (!hermes2d.solve_newton(coeff_vec, &dp, solver, matrix, rhs, jacobian_changed, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution u1_sln, u2_sln; Solution::vector_to_solutions(coeff_vec, Hermes::vector<Space *>(&u1_space, &u2_space), Hermes::vector<Solution *>(&u1_sln, &u2_sln)); // Visualize the solution. ScalarView view("Von Mises stress [Pa]", new WinGeom(0, 0, 800, 400)); double lambda = (E * nu) / ((1 + nu) * (1 - 2*nu)); // First Lame constant. double mu = E / (2*(1 + nu)); // Second Lame constant. VonMisesFilter stress(Hermes::vector<MeshFunction *>(&u1_sln, &u2_sln), lambda, mu); view.show_mesh(false); view.show(&stress, HERMES_EPS_HIGH, H2D_FN_VAL_0, &u1_sln, &u2_sln, 1.5e5); // Wait for the view to be closed. View::wait(); // Clean up. delete [] coeff_vec; delete solver; delete matrix; delete rhs; return 0; }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("../domain.mesh", &mesh); // Perform uniform mesh refinement. mesh.refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst zero_disp("Bottom", 0.0); EssentialBCs bcs(&zero_disp); // Create x- and y- displacement space using the default H1 shapeset. H1Space u1_space(&mesh, &bcs, P_INIT); H1Space u2_space(&mesh, &bcs, P_INIT); info("ndof = %d.", Space::get_num_dofs(Hermes::vector<Space *>(&u1_space, &u2_space))); // Initialize the weak formulation. CustomWeakFormLinearElasticity wf(E, nu, rho*g1, "Top", f0, f1); // 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 <= 6; p_init++) { printf("********* p_init = %d *********\n", p_init); u1_space.set_uniform_order(p_init); u2_space.set_uniform_order(p_init); int ndof = Space::get_num_dofs(Hermes::vector<Space *>(&u1_space, &u2_space)); info("ndof = %d", ndof); // Initialize the FE problem. DiscreteProblem dp(&wf, Hermes::vector<Space *>(&u1_space, &u2_space)); // 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); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof]; memset(coeff_vec, 0, ndof*sizeof(scalar)); // Perform Newton's iteration. bool verbose = true; bool jacobian_changed = true; if (!hermes2d.solve_newton(coeff_vec, &dp, solver, matrix, rhs, jacobian_changed, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution u1_sln, u2_sln; Solution::vector_to_solutions(coeff_vec, Hermes::vector<Space *>(&u1_space, &u2_space), Hermes::vector<Solution *>(&u1_sln, &u2_sln)); double sum = 0; for (int i=0; i < ndof; i++) sum += coeff_vec[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 - 1.41886e-05) > 1e-5) success = 0; if (p_init == 2 && fabs(sum - 1.60006e-05) > 1e-5) success = 0; if (p_init == 3 && fabs(sum - 1.60810e-05) > 1e-5) success = 0; if (p_init == 4 && fabs(sum - 1.61106e-05) > 1e-5) success = 0; if (p_init == 5 && fabs(sum - 1.61065e-05) > 1e-5) success = 0; if (p_init == 6 && fabs(sum - 1.61112e-05) > 1e-5) success = 0; delete [] coeff_vec; delete solver; delete matrix; delete rhs; } if (success == 1) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }