// l2 product double l2_product(RealFunction *fu, RealFunction *fv) { _F_ Quad3D *quad = get_quadrature(MODE); // integrate with maximum order order3_t o = fu->get_fn_order() + fv->get_fn_order() + order3_t(2, 2, 2); o.limit(); int np = quad->get_num_points(o); QuadPt3D *pt = quad->get_points(o); fu->precalculate(np, pt, FN_DEFAULT); fv->precalculate(np, pt, FN_DEFAULT); scalar *u0, *u1, *u2; u0 = fu->get_fn_values(0); u1 = fu->get_fn_values(1); u2 = fu->get_fn_values(2); scalar *v0, *v1, *v2; v0 = fv->get_fn_values(0); v1 = fv->get_fn_values(1); v2 = fv->get_fn_values(2); // integrating over reference brick -> jacobian is 1.0 (we do not have to bother with refmap) double result = 0.0; for (int i = 0; i < np; i++) result += pt[i].w * (REAL(sqr(u0[i] - v0[i]) + sqr(u1[i] - v1[i]) + sqr(u2[i] - v2[i]))); return result; }
bool test_lin_indep(Shapeset *shapeset) { _F_ printf("I. linear independency\n"); UMFPackMatrix mat; UMFPackVector rhs; UMFPackLinearSolver solver(&mat, &rhs); ShapeFunction pss_u(shapeset), pss_v(shapeset); int n = Hex::NUM_EDGES * shapeset->get_num_edge_fns(H3D_MAX_ELEMENT_ORDER) + Hex::NUM_FACES * shapeset->get_num_face_fns(order2_t(H3D_MAX_ELEMENT_ORDER, H3D_MAX_ELEMENT_ORDER)) + shapeset->get_num_bubble_fns(order3_t(H3D_MAX_ELEMENT_ORDER, H3D_MAX_ELEMENT_ORDER, H3D_MAX_ELEMENT_ORDER)); printf("number of functions = %d\n", n); int *fn_idx = new int[n]; int m = 0; // edge fns for (int i = 0; i < Hex::NUM_EDGES; i++) { int order = H3D_MAX_ELEMENT_ORDER; int *edge_idx = shapeset->get_edge_indices(i, 0, order); for (int j = 0; j < shapeset->get_num_edge_fns(order); j++, m++) fn_idx[m] = edge_idx[j]; } // face fns for (int i = 0; i < Hex::NUM_FACES; i++) { order2_t order(H3D_MAX_ELEMENT_ORDER, H3D_MAX_ELEMENT_ORDER); int *face_idx = shapeset->get_face_indices(i, 0, order); for (int j = 0; j < shapeset->get_num_face_fns(order); j++, m++) fn_idx[m] = face_idx[j]; } // bubble order3_t order(H3D_MAX_ELEMENT_ORDER, H3D_MAX_ELEMENT_ORDER, H3D_MAX_ELEMENT_ORDER); int *bubble_idx = shapeset->get_bubble_indices(order); for (int j = 0; j < shapeset->get_num_bubble_fns(order); j++, m++) fn_idx[m] = bubble_idx[j]; // precalc structure mat.prealloc(n); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) mat.pre_add_ij(i, j); mat.alloc(); rhs.alloc(n); printf("assembling matrix "); for (int i = 0; i < n; i++) { pss_u.set_active_shape(fn_idx[i]); printf("."); fflush(stdout); // prevent caching of output (to see that it did not freeze) for (int j = 0; j < n; j++) { pss_v.set_active_shape(fn_idx[j]); double value = l2_product(&pss_u, &pss_v); mat.add(i, j, value); } } printf("\n"); for (int i = 0; i < n; i++) rhs.add(i, 0.0); printf("solving matrix\n"); // solve the system if (solver.solve()) { double *sln = solver.get_solution(); bool indep = true; for (int i = 1; i < n + 1; i++) { if (sln[i] >= EPS) { indep = false; break; } } if (indep) printf("ok\n"); else printf("Shape functions are not linearly independent\n"); } else { printf("Shape functions are not linearly independent\n"); } delete[] fn_idx; return true; }
/*********************************************************************************** * main program * ************************************************************************************/ int main(int argc, char **args) { #ifdef WITH_PETSC PetscInitialize(NULL, NULL, PETSC_NULL, PETSC_NULL); PetscPushErrorHandler(PetscIgnoreErrorHandler, PETSC_NULL); // Disable PETSc error handler. #endif // Load the inital mesh. Mesh mesh; Mesh3DReader mesh_loader; mesh_loader.load("hexahedron.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", nelem); //Initialize the shapeset and the cache. H1ShapesetLobattoHex shapeset; //Matrix solver. #if defined WITH_UMFPACK UMFPackMatrix mat; UMFPackVector rhs; UMFPackLinearSolver 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 // Graphs of DOF convergence. GnuplotGraph graph; graph.set_captions("", "Degrees of Freedom", "Error [%]"); graph.set_log_y(); graph.add_row("Total error", "k", "-", "O"); // Create H1 space to setup the problem. H1Space space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_essential_bc_values(essential_bc_values); space.set_uniform_order(order3_t(P_INIT, P_INIT, P_INIT)); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(biform<double, double>, biform<ord_t, ord_t>, SYM, ANY); wf.add_vector_form(liform<double, double>, liform<ord_t, ord_t>, ANY); // Initialize the coarse mesh problem. LinProblem lp(&wf); lp.set_space(&space); // Adaptivity loop. int as = 0; bool done = false; do { printf("\n---- Adaptivity step %d:\n", as); printf("\nSolving on coarse mesh:\n"); // Procedures for coarse mesh problem. // Assign DOF. int ndof = space.assign_dofs(); printf(" - Number of DOF: %d\n", ndof); // Assemble stiffness matrix and rhs. printf(" - Assembling... "); fflush(stdout); if (lp.assemble(&mat, &rhs)) printf("done in %lf secs.\n", lp.get_time()); else error("failed!"); // Solve the system. printf(" - Solving... "); fflush(stdout); bool solved = solver.solve(); if (solved) printf("done in %lf secs.\n", solver.get_time()); else { printf("Failed.\n"); break; } // Construct a solution. Solution sln(&mesh); sln.set_fe_solution(&space, solver.get_solution()); // Output the orders and the solution. if (do_output) { out_orders(&space, "order", as); out_fn(&sln, "sln", as); } // Solving fine mesh problem. printf("Solving on fine mesh:\n"); // Matrix solver. #if defined WITH_UMFPACK UMFPackLinearSolver rsolver(&mat, &rhs); #elif defined WITH_PETSC PetscLinearSolver rsolver(&mat, &rhs); #elif defined WITH_MUMPS MumpsSolver rsolver(&mat, &rhs); #endif // Construct the refined mesh for reference(refined) solution. Mesh rmesh; rmesh.copy(mesh); rmesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ); // Setup space for the reference (globally refined) solution. Space *rspace = space.dup(&rmesh); rspace->copy_orders(space, 1); // Initialize the mesh problem for reference solution. LinProblem rlp(&wf); rlp.set_space(rspace); // Assign DOF. int rndof = rspace->assign_dofs(); printf(" - Number of DOF: %d\n", rndof); // Assemble stiffness matric and rhs. printf(" - Assembling... "); fflush(stdout); if (rlp.assemble(&mat, &rhs)) printf("done in %lf secs.\n", rlp.get_time()); else error("failed!"); // Solve the system. printf(" - Solving... "); fflush(stdout); bool rsolved = rsolver.solve(); if (rsolved) printf("done in %lf secs.\n", rsolver.get_time()); else { printf("failed.\n"); break; } // Construct the reference(refined) solution. Solution rsln(&rmesh); rsln.set_fe_solution(rspace, rsolver.get_solution()); // Compare coarse and fine mesh. // Calculate the error estimate wrt. refined mesh solution. double err = h1_error(&sln, &rsln); printf(" - H1 error: % lf\n", err * 100); // Save it to the graph. graph.add_value(0, ndof, err * 100); if (do_output) graph.save("conv.gp"); // Calculate error estimates for adaptivity. printf("Adaptivity\n"); printf(" - calculating error: "); fflush(stdout); H1Adapt hp(&space); double err_est = hp.calc_error(&sln, &rsln) * 100; printf("% lf %%\n", err_est); // If error is too large, adapt the mesh. if (err_est < ERR_STOP) { printf("\nDone\n"); break; } printf(" - adapting... "); fflush(stdout); hp.adapt(THRESHOLD); printf("done in %lf secs (refined %d element(s)).\n", hp.get_adapt_time(), hp.get_num_refined_elements()); if (rndof >= NDOF_STOP) { printf("\nDone.\n"); break; } // Clean up. delete rspace; // Next adaptivity step. as++; mat.free(); rhs.free(); } while (!done); #ifdef WITH_PETSC PetscFinalize(); #endif return 1; }
/*********************************************************************************** * 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 **args) { set_verbose(false); if (argc < 3) error("Not enough parameters"); char *type = args[1]; Mesh mesh; Mesh3DReader mesh_loader; if (!mesh_loader.load(args[2], &mesh)) error("Loading mesh file '%s'\n", args[2]); if (strcmp(type, "sln") == 0) { // Testing on Exact solution which always gives the same value (values from Solution may differ by epsilon) ExactSolution ex_sln(&mesh, exact_solution); output.out(&ex_sln, "U"); } else if (strcmp(type, "vec-sln") == 0) { // Testing on Exact solution which always gives the same value (values from Solution may differ by epsilon) ExactSolution ex_sln(&mesh, exact_vec_solution); output.out(&ex_sln, "U"); } else if (strcmp(type, "3sln") == 0) { // Testing on Exact solution which always gives the same value (values from Solution may differ by epsilon) ExactSolution ex_sln0(&mesh, exact_solution0); ExactSolution ex_sln1(&mesh, exact_solution1); ExactSolution ex_sln2(&mesh, exact_solution2); output.out(&ex_sln0, &ex_sln1, &ex_sln2, "U"); } else if (strcmp(type, "ord") == 0) { H1ShapesetLobattoHex shapeset; H1Space space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_essential_bc_values(essential_bc_values); order3_t order; if (mesh.elements[1]->get_mode() == MODE_HEXAHEDRON) order = order3_t(2, 3, 4); else if (mesh.elements[1]->get_mode() == MODE_TETRAHEDRON) order = order3_t(3); else error(H3D_ERR_NOT_IMPLEMENTED); space.set_uniform_order(order); output.out_orders(&space, "orders"); } else if (strcmp(type, "bc") == 0) { output.out_bc(&mesh); } else if (strcmp(type, "mat") == 0) { StiffMatrix mat; test_mat(&mesh, mat); output.out(&mat); } else if (strcmp(type, "mm") == 0) { test_mm(&mesh); } return 0; }