int main(int argc, char* argv[]) { // load the mesh file Mesh mesh; mesh.load("sample.mesh"); // initialize the shapeset and the cache H1Shapeset shapeset; PrecalcShapeset pss(&shapeset); // create the x displacement space H1Space xdisp(&mesh, &shapeset); xdisp.set_bc_types(bc_types); xdisp.set_bc_values(bc_values); xdisp.set_uniform_order(P_INIT); int ndofs = xdisp.assign_dofs(0); // create the y displacement space H1Space ydisp(&mesh, &shapeset); ydisp.set_bc_types(bc_types); ydisp.set_bc_values(bc_values); ydisp.set_uniform_order(P_INIT); ndofs += ydisp.assign_dofs(ndofs); // initialize the weak formulation WeakForm wf(2); wf.add_biform(0, 0, callback(bilinear_form_0_0), SYM); // Note that only one symmetric part is wf.add_biform(0, 1, callback(bilinear_form_0_1), SYM); // added in the case of symmetric bilinear wf.add_biform(1, 1, callback(bilinear_form_1_1), SYM); // forms. wf.add_liform_surf(0, callback(linear_form_surf_0), 3); wf.add_liform_surf(1, callback(linear_form_surf_1), 3); // initialize the linear system and solver UmfpackSolver umfpack; LinSystem sys(&wf, &umfpack); sys.set_spaces(2, &xdisp, &ydisp); sys.set_pss(1, &pss); // assemble the stiffness matrix and solve the system Solution xsln, ysln; sys.assemble(); sys.solve(2, &xsln, &ysln); // visualize the solution ScalarView view("Von Mises stress [Pa]", 50, 50, 1200, 600); VonMisesFilter stress(&xsln, &ysln, lambda, mu); view.show(&stress, EPS_HIGH, FN_VAL_0, &xsln, &ysln, 1.5e5); // wait for keyboard or mouse input View::wait("Waiting for keyboard or mouse input."); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("sample.mesh", &mesh); // Perform uniform mesh refinement. mesh.refine_all_elements(); // Create x- and y- displacement space using the default H1 shapeset. H1Space xdisp(&mesh, bc_types, essential_bc_values, P_INIT); H1Space ydisp(&mesh, bc_types, essential_bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, callback(bilinear_form_0_0), H2D_SYM); // Note that only one symmetric part is wf.add_matrix_form(0, 1, callback(bilinear_form_0_1), H2D_SYM); // added in the case of symmetric bilinear wf.add_matrix_form(1, 1, callback(bilinear_form_1_1), H2D_SYM); // forms. wf.add_vector_form_surf(0, callback(linear_form_surf_0), GAMMA_3_BDY); wf.add_vector_form_surf(1, callback(linear_form_surf_1), GAMMA_3_BDY); // Initialize the linear system. LinSystem ls(&wf, Tuple<Space*>(&xdisp, &ydisp)); // Assemble and solve the matrix problem. Solution xsln, ysln; ls.assemble(); ls.solve(Tuple<Solution*>(&xsln, &ysln)); // Visualize the solution. ScalarView view("Von Mises stress [Pa]", 0, 0, 800, 400); VonMisesFilter stress(&xsln, &ysln, lambda, mu); view.show_mesh(false); view.show(&stress, H2D_EPS_HIGH, H2D_FN_VAL_0, &xsln, &ysln, 1.5e5); // Wait for the view to be closed. View::wait(); return 0; }
int main(int argc, char **args) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; ExodusIIReader mloader; mloader.load("brick_with_hole_hex.e", &mesh); // Perform initial mesh refinement. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ); // Create H1 space with default shapeset for x-displacement component. H1Space xdisp(&mesh, bc_types_x, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); // Create H1 space with default shapeset for y-displacement component. H1Space ydisp(&mesh, bc_types_y, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); // Create H1 space with default shapeset for z-displacement component. H1Space zdisp(&mesh, bc_types_z, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); // Initialize weak formulation. WeakForm wf(3); wf.add_matrix_form(0, 0, callback(bilinear_form_0_0), HERMES_SYM); wf.add_matrix_form(0, 1, callback(bilinear_form_0_1), HERMES_SYM); wf.add_matrix_form(0, 2, callback(bilinear_form_0_2), HERMES_SYM); wf.add_vector_form_surf(0, callback(surf_linear_form_x), bdy_force); wf.add_matrix_form(1, 1, callback(bilinear_form_1_1), HERMES_SYM); wf.add_matrix_form(1, 2, callback(bilinear_form_1_2), HERMES_SYM); wf.add_vector_form_surf(1, callback(surf_linear_form_y), bdy_force); wf.add_matrix_form(2, 2, callback(bilinear_form_2_2), HERMES_SYM); wf.add_vector_form_surf(2, callback(surf_linear_form_z), bdy_force); // Initialize discrete problem. bool is_linear = true; DiscreteProblem dp(&wf, Hermes::Tuple<Space *>(&xdisp, &ydisp, &zdisp), 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 preconditioner in the case of SOLVER_AZTECOO. if (matrix_solver == SOLVER_AZTECOO) { ((AztecOOSolver*) solver)->set_solver(iterative_method); ((AztecOOSolver*) solver)->set_precond(preconditioner); // Using default iteration parameters (see solver/aztecoo.h). } // Assemble stiffness matrix and load vector. info("Assembling the linear problem (ndof: %d).", Space::get_num_dofs(Hermes::Tuple<Space *>(&xdisp, &ydisp, &zdisp))); dp.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving the linear problem."); Solution xsln(xdisp.get_mesh()); Solution ysln(ydisp.get_mesh()); Solution zsln(zdisp.get_mesh()); if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), Hermes::Tuple<Space *>(&xdisp, &ydisp, &zdisp), Hermes::Tuple<Solution *>(&xsln, &ysln, &zsln)); else error ("Matrix solver failed.\n"); // Output all components of the solution. if (solution_output) out_fn_vtk(&xsln, &ysln, &zsln, "sln"); // Time measurement. cpu_time.tick(); // Print timing information. info("Solutions saved. Total running time: %g s.", cpu_time.accumulated()); // Clean up. delete matrix; delete rhs; delete solver; return 0; }
int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh xmesh, ymesh, tmesh; MeshReaderH2D mloader; mloader.load("domain.mesh", &xmesh); // Master mesh. // Initialize multimesh hp-FEM. ymesh.copy(&xmesh); // Ydisp will share master mesh with xdisp. tmesh.copy(&xmesh); // Temp will share master mesh with xdisp. // Initialize boundary conditions. BCTypes bc_types_x_y; bc_types_x_y.add_bc_dirichlet(BDY_BOTTOM); bc_types_x_y.add_bc_neumann(Hermes::vector<int>(BDY_SIDES, BDY_TOP, BDY_HOLES)); BCTypes bc_types_t; bc_types_t.add_bc_dirichlet(BDY_HOLES); bc_types_t.add_bc_neumann(Hermes::vector<int>(BDY_SIDES, BDY_TOP, BDY_BOTTOM)); // Enter Dirichlet boundary values. BCValues bc_values_x_y; bc_values_x_y.add_zero(BDY_BOTTOM); BCValues bc_values_t; bc_values_t.add_const(BDY_HOLES, TEMP_INNER); // Create H1 spaces with default shapesets. H1Space<double> xdisp(&xmesh, &bc_types_x_y, &bc_values_x_y, P_INIT_DISP); H1Space<double> ydisp(MULTI ? &ymesh : &xmesh, &bc_types_x_y, &bc_values_x_y, P_INIT_DISP); H1Space<double> temp(MULTI ? &tmesh : &xmesh, &bc_types_t, &bc_values_t, P_INIT_TEMP); // Initialize the weak formulation. WeakForm wf(3); wf.add_matrix_form(0, 0, callback(bilinear_form_0_0)); wf.add_matrix_form(0, 1, callback(bilinear_form_0_1), HERMES_SYM); wf.add_matrix_form(0, 2, callback(bilinear_form_0_2)); wf.add_matrix_form(1, 1, callback(bilinear_form_1_1)); wf.add_matrix_form(1, 2, callback(bilinear_form_1_2)); wf.add_matrix_form(2, 2, callback(bilinear_form_2_2)); wf.add_vector_form(1, callback(linear_form_1)); wf.add_vector_form(2, callback(linear_form_2)); wf.add_vector_form_surf(2, callback(linear_form_surf_2)); // Initialize coarse and reference mesh solutions. Solution<double> xdisp_sln, ydisp_sln, temp_sln, ref_xdisp_sln, ref_ydisp_sln, ref_temp_sln; // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. ScalarView s_view_0("Solution[xdisp]", new WinGeom(0, 0, 450, 350)); s_view_0.show_mesh(false); ScalarView s_view_1("Solution[ydisp]", new WinGeom(460, 0, 450, 350)); s_view_1.show_mesh(false); ScalarView s_view_2("Solution[temp]", new WinGeom(920, 0, 450, 350)); s_view_1.show_mesh(false); OrderView o_view_0("Mesh[xdisp]", new WinGeom(0, 360, 450, 350)); OrderView o_view_1("Mesh[ydisp]", new WinGeom(460, 360, 450, 350)); OrderView o_view_2("Mesh[temp]", new WinGeom(920, 360, 450, 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> *>(&xdisp, &ydisp, &temp)); // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, *ref_spaces, is_linear); 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); 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::vector_to_solutions(solver->get_solution(), *ref_spaces, Hermes::vector<Solution *>(&ref_xdisp_sln, &ref_ydisp_sln, &ref_temp_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::project_global(Hermes::vector<Space<double> *>(&xdisp, &ydisp, &temp), Hermes::vector<Solution *>(&ref_xdisp_sln, &ref_ydisp_sln, &ref_temp_sln), Hermes::vector<Solution *>(&xdisp_sln, &ydisp_sln, &temp_sln), matrix_solver_type); // View the coarse mesh solution and polynomial orders. s_view_0.show(&xdisp_sln); o_view_0.show(&xdisp); s_view_1.show(&ydisp_sln); o_view_1.show(&ydisp); s_view_2.show(&temp_sln); o_view_2.show(&temp); // Skip visualization time. cpu_time.tick(HERMES_SKIP); // Calculate element errors. info("Calculating error estimate and exact error."); Adapt* adaptivity = new Adapt(Hermes::vector<Space<double> *>(&xdisp, &ydisp, &temp)); 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(0, 2, bilinear_form_0_2<double, double>, bilinear_form_0_2<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>); adaptivity->set_error_form(1, 2, bilinear_form_1_2<double, double>, bilinear_form_1_2<Ord, Ord>); adaptivity->set_error_form(2, 2, bilinear_form_2_2<double, double>, bilinear_form_2_2<Ord, Ord>); // 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 *>(&xdisp_sln, &ydisp_sln, &temp_sln), Hermes::vector<Solution *>(&ref_xdisp_sln, &ref_ydisp_sln, &ref_temp_sln), &err_est_rel) * 100; // Time measurement. cpu_time.tick(); // Report results. info("ndof_coarse[xdisp]: %d, ndof_fine[xdisp]: %d, err_est_rel[xdisp]: %g%%", xdisp.Space<double>::get_num_dofs(), Space<double>::get_num_dofs((*ref_spaces)[0]), err_est_rel[0]*100); info("ndof_coarse[ydisp]: %d, ndof_fine[ydisp]: %d, err_est_rel[ydisp]: %g%%", ydisp.Space<double>::get_num_dofs(), Space<double>::get_num_dofs((*ref_spaces)[1]), err_est_rel[1]*100); info("ndof_coarse[temp]: %d, ndof_fine[temp]: %d, err_est_rel[temp]: %g%%", temp.Space<double>::get_num_dofs(), Space<double>::get_num_dofs((*ref_spaces)[2]), err_est_rel[2]*100); info("ndof_coarse_total: %d, ndof_fine_total: %d, err_est_rel_total: %g%%", Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&xdisp, &ydisp, &temp)), 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> *>(&xdisp, &ydisp, &temp)), 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 *>(&selector, &selector, &selector), THRESHOLD, STRATEGY, MESH_REGULARITY); } if (Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&xdisp, &ydisp, &temp)) >= 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; delete dp; // 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[xdisp]"); s_view_0.show(&ref_xdisp_sln); s_view_1.set_title("Fine mesh Solution[ydisp]"); s_view_1.show(&ref_ydisp_sln); s_view_1.set_title("Fine mesh Solution[temp]"); s_view_1.show(&ref_temp_sln); // Wait for all views 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); // Create the x- and y-displacement spaces. H1Space xdisp(&mesh, bc_types, essential_bc_values, P_INIT); H1Space ydisp(&mesh, bc_types, essential_bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, callback(bilinear_form_0_0), H2D_SYM); // Note that only one symmetric part is wf.add_matrix_form(0, 1, callback(bilinear_form_0_1), H2D_SYM); // added in the case of symmetric bilinear wf.add_matrix_form(1, 1, callback(bilinear_form_1_1), H2D_SYM); // forms. wf.add_vector_form_surf(0, callback(linear_form_surf_0), GAMMA_3_BDY); wf.add_vector_form_surf(1, callback(linear_form_surf_1), GAMMA_3_BDY); // Initialize the linear system. LinSystem sys(&wf, Tuple<Space*>(&xdisp, &ydisp)); // 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); xdisp.set_uniform_order(p_init); ydisp.set_uniform_order(p_init); // Assemble and solve the matrix problem. sys.assemble(); sys.solve(Tuple<Solution*>(&xsln, &ysln)); scalar *sol_vector; int n_dof; sys.get_solution_vector(sol_vector, n_dof); printf("n_dof = %d\n", n_dof); double sum = 0; for (int i=0; i < n_dof; i++) sum += sol_vector[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; } #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 if (success == 1) { printf("Success!\n"); return ERROR_SUCCESS; } else { printf("Failure!\n"); return ERROR_FAILURE; } }
int main(int argc, char* argv[]) { // load the mesh Mesh xmesh, ymesh; H2DReader mloader; mloader.load("bracket.mesh", &xmesh); // create initial mesh for the vertical displacement component, // identical to the mesh for the horizontal displacement // (bracket.mesh becomes a master mesh) ymesh.copy(&xmesh); // initialize the shapeset and the cache H1Shapeset shapeset; PrecalcShapeset xpss(&shapeset); PrecalcShapeset ypss(&shapeset); // create the x displacement space H1Space xdisp(&xmesh, &shapeset); xdisp.set_bc_types(bc_types); xdisp.set_bc_values(bc_values); xdisp.set_uniform_order(P_INIT); // create the y displacement space H1Space ydisp(MULTI ? &ymesh : &xmesh, &shapeset); ydisp.set_bc_types(bc_types); ydisp.set_bc_values(bc_values); ydisp.set_uniform_order(P_INIT); // enumerate basis functions int ndofs = xdisp.assign_dofs(); ndofs += ydisp.assign_dofs(ndofs); // initialize the weak formulation WeakForm wf(2); wf.add_biform(0, 0, callback(bilinear_form_0_0), SYM); // note that only one symmetric part is wf.add_biform(0, 1, callback(bilinear_form_0_1), SYM); // added in the case of symmetric bilinear wf.add_biform(1, 1, callback(bilinear_form_1_1), SYM); // forms wf.add_liform_surf(1, callback(linear_form_surf_1), marker_top); // visualization of solution and meshes OrderView xoview("X polynomial orders", 0, 0, 500, 500); OrderView yoview("Y polynomial orders", 510, 0, 500, 500); ScalarView sview("Von Mises stress [Pa]", 1020, 0, 500, 500); // matrix solver UmfpackSolver umfpack; // DOF and CPU convergence graphs SimpleGraph graph_dof, graph_cpu; // adaptivity loop int it = 1; bool done = false; double cpu = 0.0; Solution x_sln_coarse, y_sln_coarse; Solution x_sln_fine, y_sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); //calculating the number of degrees of freedom ndofs = xdisp.assign_dofs(); ndofs += ydisp.assign_dofs(ndofs); printf("xdof=%d, ydof=%d\n", xdisp.get_num_dofs(), ydisp.get_num_dofs()); // solve the coarse mesh problem LinSystem ls(&wf, &umfpack); ls.set_spaces(2, &xdisp, &ydisp); ls.set_pss(2, &xpss, &ypss); ls.assemble(); ls.solve(2, &x_sln_coarse, &y_sln_coarse); // time measurement cpu += end_time(); // view the solution -- this can be slow; for illustration only VonMisesFilter stress_coarse(&x_sln_coarse, &y_sln_coarse, mu, lambda); sview.set_min_max_range(0, 3e4); sview.show(&stress_coarse); xoview.show(&xdisp); yoview.show(&ydisp); // time measurement begin_time(); // solve the fine mesh problem RefSystem rs(&ls); rs.assemble(); rs.solve(2, &x_sln_fine, &y_sln_fine); // calculate element errors and total error estimate H1OrthoHP hp(2, &xdisp, &ydisp); hp.set_biform(0, 0, bilinear_form_0_0<scalar, scalar>, bilinear_form_0_0<Ord, Ord>); hp.set_biform(0, 1, bilinear_form_0_1<scalar, scalar>, bilinear_form_0_1<Ord, Ord>); hp.set_biform(1, 0, bilinear_form_1_0<scalar, scalar>, bilinear_form_1_0<Ord, Ord>); hp.set_biform(1, 1, bilinear_form_1_1<scalar, scalar>, bilinear_form_1_1<Ord, Ord>); double err_est = hp.calc_error_2(&x_sln_coarse, &y_sln_coarse, &x_sln_fine, &y_sln_fine) * 100; info("Estimate of error: %g%%", err_est); // time measurement cpu += end_time(); // add entry to DOF convergence graph graph_dof.add_values(xdisp.get_num_dofs() + ydisp.get_num_dofs(), err_est); graph_dof.save("conv_dof.dat"); // add entry to CPU convergence graph graph_cpu.add_values(cpu, err_est); graph_cpu.save("conv_cpu.dat"); // if err_est too large, adapt the mesh if (err_est < ERR_STOP) done = true; else { hp.adapt(THRESHOLD, STRATEGY, ADAPT_TYPE, ISO_ONLY, MESH_REGULARITY, CONV_EXP, MAX_ORDER, SAME_ORDERS); ndofs = xdisp.assign_dofs(); ndofs += ydisp.assign_dofs(ndofs); if (ndofs >= NDOF_STOP) done = true; } } while (!done); verbose("Total running time: %g sec", cpu); // show the fine solution - this is the final result VonMisesFilter stress_fine(&x_sln_fine, &y_sln_fine, mu, lambda); sview.set_title("Final solution"); sview.set_min_max_range(0, 3e4); sview.show(&stress_fine); // wait for all views to be closed View::wait(); return 0; }
/*********************************************************************************** * main program * ***********************************************************************************/ int main(int argc, char **argv) { #ifdef WITH_PETSC PetscInitialize(&argc, &argv, (char *) PETSC_NULL, PETSC_NULL); PetscPushErrorHandler(PetscIgnoreErrorHandler, PETSC_NULL); // Disable PETSc error handler. #endif // Load the initial mesh. Mesh mesh; Mesh3DReader mloader; mloader.load("l-beam.mesh3d", &mesh); // Initial uniform mesh refinements. printf("Performing %d initial mesh refinements.\n", INIT_REF_NUM); for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ); Word_t (nelem) = mesh.get_num_elements(); printf("New number of elements is %d.\n", (int) nelem); // Initialize the shapeset and the cache. H1ShapesetLobattoHex shapeset; #if defined WITH_UMFPACK UMFPackMatrix mat; UMFPackVector rhs; UMFPackLinearSolver solver(&mat, &rhs); #elif defined WITH_PARDISO PardisoMatrix mat; PardisoVector rhs; PardisoLinearSolver solver(&mat, &rhs); #elif defined WITH_PETSC PetscMatrix mat; PetscVector rhs; PetscLinearSolver solver(&mat, &rhs); #elif defined WITH_MUMPS MumpsMatrix mat; MumpsVector rhs; MumpsSolver solver(&mat, &rhs); #endif // Create H1 spaces x-displacement component. H1Space xdisp(&mesh, &shapeset); xdisp.set_bc_types(bc_types_x); xdisp.set_uniform_order(order3_t(P_INIT, P_INIT, P_INIT)); // Create H1 spaces y-displacement component. H1Space ydisp(&mesh, &shapeset); ydisp.set_bc_types(bc_types_y); ydisp.set_uniform_order(order3_t(P_INIT, P_INIT, P_INIT)); // Create H1 spaces z-displacement component. H1Space zdisp(&mesh, &shapeset); zdisp.set_bc_types(bc_types_z); zdisp.set_uniform_order(order3_t(P_INIT, P_INIT, P_INIT)); // Assign DOF. int ndofs = 0; ndofs += xdisp.assign_dofs(ndofs); ndofs += ydisp.assign_dofs(ndofs); ndofs += zdisp.assign_dofs(ndofs); printf(" - Number of DOFs: %d\n", ndofs); // Initialized the Weak formulation. WeakForm wf(3); wf.add_matrix_form(0, 0, bilinear_form_0_0<double, scalar>, bilinear_form_0_0<ord_t, ord_t>, SYM); wf.add_matrix_form(0, 1, bilinear_form_0_1<double, scalar>, bilinear_form_0_1<ord_t, ord_t>, SYM); wf.add_matrix_form(0, 2, bilinear_form_0_2<double, scalar>, bilinear_form_0_2<ord_t, ord_t>, SYM); wf.add_vector_form_surf(0, surf_linear_form_0<double, scalar>, surf_linear_form_0<ord_t, ord_t>); wf.add_matrix_form(1, 1, bilinear_form_1_1<double, scalar>, bilinear_form_1_1<ord_t, ord_t>, SYM); wf.add_matrix_form(1, 2, bilinear_form_1_2<double, scalar>, bilinear_form_1_2<ord_t, ord_t>, SYM); wf.add_vector_form_surf(1, surf_linear_form_1<double, scalar>, surf_linear_form_1<ord_t, ord_t>); wf.add_matrix_form(2, 2, bilinear_form_2_2<double, scalar>, bilinear_form_2_2<ord_t, ord_t>, SYM); wf.add_vector_form_surf(2, surf_linear_form_2<double, scalar>, surf_linear_form_2<ord_t, ord_t>, 5); // Initialize the mesh problem. LinearProblem lp(&wf); lp.set_spaces(Tuple<Space *>(&xdisp, &ydisp, &zdisp)); // Assemble stiffness matrix printf(" - Assembling... "); fflush(stdout); Timer tmr_assemble; tmr_assemble.start(); bool assembled = lp.assemble(&mat, &rhs); tmr_assemble.stop(); if (assembled) printf("done in %s (%lf secs)\n", tmr_assemble.get_human_time(), tmr_assemble.get_seconds()); else error("failed!"); // Solve the stiffness matrix. printf(" - Solving... "); fflush(stdout); Timer tmr_solve; tmr_solve.start(); bool solved = solver.solve(); tmr_solve.stop(); if (solved) printf("done in %s (%lf secs)\n", tmr_solve.get_human_time(), tmr_solve.get_seconds()); else { printf("failed\n"); } // Construct a solution. double *s = solver.get_solution(); Solution xsln(&mesh), ysln(&mesh), zsln(&mesh); xsln.set_fe_solution(&xdisp, s); ysln.set_fe_solution(&ydisp, s); zsln.set_fe_solution(&zdisp, s); // Output the solutions. printf(" - Output... "); fflush(stdout); out_fn(&xsln, &ysln, &zsln, "disp"); printf("done\n"); #ifdef WITH_PETSC mat.free(); rhs.free(); PetscFinalize(); #endif return 1; }
int main(int argc, char* argv[]) { // load the mesh file Mesh mesh; H2DReader mloader; mloader.load("sample.mesh", &mesh); // initialize the shapeset and the cache H1Shapeset shapeset; PrecalcShapeset pss(&shapeset); // create the x displacement space H1Space xdisp(&mesh, &shapeset); xdisp.set_bc_types(bc_types); xdisp.set_bc_values(bc_values); // create the y displacement space H1Space ydisp(&mesh, &shapeset); ydisp.set_bc_types(bc_types); ydisp.set_bc_values(bc_values); // initialize the weak formulation WeakForm wf(2); wf.add_biform(0, 0, callback(bilinear_form_0_0), SYM); // Note that only one symmetric part is wf.add_biform(0, 1, callback(bilinear_form_0_1), SYM); // added in the case of symmetric bilinear wf.add_biform(1, 1, callback(bilinear_form_1_1), SYM); // forms. wf.add_liform_surf(0, callback(linear_form_surf_0), 3); wf.add_liform_surf(1, callback(linear_form_surf_1), 3); // initialize the linear system and solver UmfpackSolver umfpack; LinSystem sys(&wf, &umfpack); sys.set_spaces(2, &xdisp, &ydisp); sys.set_pss(1, &pss); // testing n_dof and correctness of solution vector // for p_init = 1, 2, ..., 10 int success = 1; for (int p_init = 1; p_init <= 10; p_init++) { printf("********* p_init = %d *********\n", p_init); xdisp.set_uniform_order(p_init); int ndofs = xdisp.assign_dofs(0); ydisp.set_uniform_order(p_init); ndofs += ydisp.assign_dofs(ndofs); // assemble the stiffness matrix and solve the system Solution xsln, ysln; sys.assemble(); sys.solve(2, &xsln, &ysln); scalar *sol_vector; int n_dof; sys.get_solution_vector(sol_vector, n_dof); printf("n_dof = %d\n", n_dof); double sum = 0; for (int i=0; i < n_dof; i++) sum += sol_vector[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; } #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 if (success == 1) { printf("Success!\n"); return ERROR_SUCCESS; } else { printf("Failure!\n"); return ERROR_FAILURE; } }