void RefMap::set_active_element(Element *e) { _F_ assert(e != NULL); ElementMode3D mode = e->get_mode(); pss = ref_map_pss[mode]; pss->set_active_element(e); if (e == element) return; element = e; reset_transform(); is_const_jacobian = mode == MODE_TETRAHEDRON; int nvertices = element->get_num_vertices(); // prepare the shapes and coefficients of the reference map Shapeset *shapeset = this->pss->get_shapeset(); int i, k = 0; for (i = 0; i < nvertices; i++) indices[k++] = shapeset->get_vertex_index(i); // straight element for (int iv = 0; iv < nvertices; iv++) vertex[iv] = *mesh->vertices[e->get_vertex(iv)]; coefs = vertex; n_coefs = nvertices; // calculate the order of the reference map switch (mode) { case MODE_TETRAHEDRON: ref_order = Ord3(0); break; case MODE_HEXAHEDRON: ref_order = Ord3(1, 1, 1); break; case MODE_PRISM: EXIT(HERMES_ERR_NOT_IMPLEMENTED); break; } // calculate the order of the inverse reference map switch (mode) { case MODE_TETRAHEDRON: inv_ref_order = Ord3(0); break; case MODE_HEXAHEDRON: inv_ref_order = Ord3(1, 1, 1); break; case MODE_PRISM: EXIT(HERMES_ERR_NOT_IMPLEMENTED); break; } // constant inverse reference map if (this->is_const_jacobian) calc_const_inv_ref_map(); else const_jacobian = 0.0; }
// l2 product double l2_product(RealFunction *fu, RealFunction *fv) { _F_ Quad3D *quad = get_quadrature(MODE); // integrate with maximum order Ord3 o = fu->get_fn_order() + fv->get_fn_order() + Ord3(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; }
int main(int argc, char **args) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; //CTUReader mloader; H3DReader mloader; info("Loading mesh..."); mloader.load("bridge.mesh3d", &mesh); // Create H1 space with default shapeset. H1Space space(&mesh, bc_types, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<Ord, Ord>, HERMES_SYM); wf.add_vector_form(linear_form<double, scalar>, linear_form<Ord, Ord>, HERMES_ANY_INT); // Initialize discrete problem. bool is_linear = true; DiscreteProblem dp(&wf, &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); // Assemble stiffness matrix and load vector. info("Assembling the linear problem (ndof: %d).", Space::get_num_dofs(&space)); dp.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving the linear problem."); Solution sln(&mesh); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); // Output the solution for Paraview. if (solution_output) out_fn_vtk(&sln, "sln"); // Time measurement. cpu_time.tick(); // Print timing information. info("Solutions and mesh with polynomial orders saved. Total running time: %g s", cpu_time.accumulated()); // Clean up. delete matrix; delete rhs; delete solver; return 0; }
int test_order_hex() { info("test_order_hex."); Ord3 a(1, 2, 3), b(3, 4, 2); Ord3 x; Ord3 c = a + b; if (c.x != 4 || c.y != 6 || c.z != 5) return ERR_FAILURE; Ord3 d = a; d += b; if (d.x != 4 || d.y != 6 || c.z != 5) return ERR_FAILURE; Ord3 e = b * 6; if (e.x != 18 || e.y != 24 || e.z != 12) return ERR_FAILURE; Ord3 f = b * Ord3(2, 3, 4); if (f.x != 6 || f.y != 12 || f.z != 8) return ERR_FAILURE; Ord3 m = max(b, e); if (m.x != e.x || m.y != e.y || m.z != e.z) return ERR_FAILURE; Ord3 z(2, 1, 4); x = a + b + z; if (x.x != 6 || x.y != 7 || x.z != 9) return ERR_FAILURE; if (c == Ord3(4, 6, 5)) ; else return ERR_FAILURE; if (c != Ord3(4, 6, 5)) return ERR_FAILURE; Ord1 edge_ref_order[] = { 3, 4, 3, 4, 2, 2, 2, 2, 3, 4, 3, 4 }; for (int iedge = 0; iedge < Hex::NUM_EDGES; iedge++) { if (b.get_edge_order(iedge) != edge_ref_order[iedge]) return ERR_FAILURE; } Ord2 face_ref_order[] = { Ord2(4, 2), Ord2(4, 2), Ord2(3, 2), Ord2(3, 2), Ord2(3, 4), Ord2(3, 4) }; for (int iface = 0; iface < Hex::NUM_FACES; iface++) { if (b.get_face_order(iface) != face_ref_order[iface]) return ERR_FAILURE; } return ERR_SUCCESS; }
Space *H1Space::dup(Mesh *mesh_ext) const { _F_ // FIXME; this only works for hexahedra. H1Space *space = new H1Space(mesh_ext, NULL, NULL, Ord3(1, 1, 1), this->shapeset); space->copy_callbacks(this); // enumerate basis functions space->assign_dofs(); return space; }
void Filter::set_active_element(Element *e) { _F_ MeshFunction::set_active_element(e); if (!unimesh) { for (int i = 0; i < num; i++) sln[i]->set_active_element(e); memset(sln_sub, 0, sizeof(sln_sub)); } else { for (int i = 0; i < num; i++) { sln[i]->set_active_element(unidata[i][e->id].e); sln[i]->set_transform(unidata[i][e->id].idx); sln_sub[i] = sln[i]->get_transform(); } } switch (mode) { case MODE_TETRAHEDRON: order = Ord3(H3D_MAX_QUAD_ORDER_TETRA); break; case MODE_HEXAHEDRON: order = Ord3(H3D_MAX_QUAD_ORDER, H3D_MAX_QUAD_ORDER, H3D_MAX_QUAD_ORDER); break; default: EXIT(HERMES_ERR_NOT_IMPLEMENTED); break; } }
// l2 product double l2_product(ShapeFunction *fu, ShapeFunction *fv) { _F_ Quad3D *quad = get_quadrature(MODE_HEXAHEDRON); Ord3 o = fu->get_fn_order() + fv->get_fn_order() + Ord3(1, 1, 1); QuadPt3D *pt = quad->get_points(o); int np = quad->get_num_points(o); fu->precalculate(np, pt, FN_VAL); fv->precalculate(np, pt, FN_VAL); double *uval = fu->get_fn_values(); double *vval = fv->get_fn_values(); // 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 * (uval[i] * vval[i]); return result; }
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 **args) { // Load the mesh. Mesh mesh; H3DReader mesh_loader; mesh_loader.load("fichera-corner.mesh3d", &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 an H1 space with default shapeset. H1Space space(&mesh, bc_types, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(bilinear_form<double, double>, bilinear_form<Ord, Ord>, HERMES_SYM, HERMES_ANY); wf.add_vector_form(linear_form<double, double>, linear_form<Ord, Ord>, HERMES_ANY); // Set exact solution. ExactSolution exact(&mesh, fndd); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est, graph_dof_exact, graph_cpu_exact; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Initialize the solver in the case of SOLVER_PETSC or SOLVER_MUMPS. initialize_solution_environment(matrix_solver, argc, args); // Adaptivity loop. int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = construct_refined_space(&space,1 , H3D_H3D_H3D_REFT_HEX_XYZ); // Initialize discrete problem. bool is_linear = true; DiscreteProblem dp(&wf, ref_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 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 the reference problem. info("Assembling on reference mesh (ndof: %d).", Space::get_num_dofs(ref_space)); dp.assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system on reference mesh. If successful, obtain the solution. info("Solving on reference mesh."); Solution ref_sln(ref_space->get_mesh()); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), ref_space, &ref_sln); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Project the reference solution on the coarse mesh. Solution sln(space.get_mesh()); info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Time measurement. cpu_time.tick(); // Output solution and mesh with polynomial orders. if (solution_output) { out_fn_vtk(&sln, "sln", as); out_orders_vtk(&space, "order", as); } // Skip the visualization time. cpu_time.tick(HERMES_SKIP); // Calculate element errors and total error estimate. info("Calculating error estimate and exact error."); Adapt *adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = true; double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln, solutions_for_adapt) * 100; // Calculate exact error. solutions_for_adapt = false; double err_exact_rel = adaptivity->calc_err_exact(&sln, &exact, solutions_for_adapt) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d.", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space)); info("err_est_rel: %g%%, err_exact_rel: %g%%.", err_est_rel, err_exact_rel); // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space::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"); graph_dof_exact.add_values(Space::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_rel is too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); adaptivity->adapt(THRESHOLD); } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete ref_space->get_mesh(); delete ref_space; delete matrix; delete rhs; delete solver; delete adaptivity; // Increase the counter of performed adaptivity steps. as++; } while (!done); // Properly terminate the solver in the case of SOLVER_PETSC or SOLVER_MUMPS. finalize_solution_environment(matrix_solver); return 1; }
int main(int argc, char **args) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H3DReader mloader; mloader.load("lshape_hex.mesh3d", &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 an Hcurl space with default shapeset. HcurlSpace space(&mesh, bc_types, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(biform<double, scalar>, biform<Ord, Ord>, HERMES_SYM); wf.add_matrix_form_surf(biform_surf, biform_surf_ord); wf.add_vector_form_surf(liform_surf, liform_surf_ord); // Initialize discrete problem. bool is_linear = true; DiscreteProblem dp(&wf, &space, is_linear); // Initialize the solver in the case of SOLVER_PETSC or SOLVER_MUMPS. initialize_solution_environment(matrix_solver, argc, args); // 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(&space)); dp.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving the linear problem."); Solution sln(space.get_mesh()); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); // Output solution and mesh with polynomial orders. if (solution_output) { out_fn_vtk(&sln, "sln"); out_orders_vtk(&space, "order"); } // Time measurement. cpu_time.tick(); // Print timing information. info("Solution and mesh with polynomial orders saved. Total running time: %g s", cpu_time.accumulated()); // Clean up. delete matrix; delete rhs; delete solver; // Properly terminate the solver in the case of SOLVER_PETSC or SOLVER_MUMPS. finalize_solution_environment(matrix_solver); return 0; }
int main(int argc, char **args) { // Test variable. int success_test = 1; // Check the number of command-line parameters. if (argc < 2) { info("Use x, y, z, xy, xz, yz, or xyz as a command-line parameter."); error("Not enough command-line parameters."); } // Determine anisotropy type from the command-line parameter. ANISO_TYPE = parse_aniso_type(args[1]); // Load the mesh. Mesh mesh; H3DReader mesh_loader; mesh_loader.load("hex-0-1.mesh3d", &mesh); // Assign the lowest possible directional polynomial degrees so that the problem's NDOF >= 1. assign_poly_degrees(); // Create an H1 space with default shapeset. info("Setting directional polynomial degrees %d, %d, %d.", P_INIT_X, P_INIT_Y, P_INIT_Z); H1Space space(&mesh, bc_types, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<Ord, Ord>, HERMES_SYM, HERMES_ANY); wf.add_vector_form(linear_form<double, scalar>, linear_form<Ord, Ord>, HERMES_ANY); // Set exact solution. ExactSolution exact(&mesh, fndd); // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Adaptivity loop. int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = construct_refined_space(&space, 1); // Initialize discrete problem. bool is_linear = true; DiscreteProblem dp(&wf, ref_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 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 the reference problem. info("Assembling on reference mesh (ndof: %d).", Space::get_num_dofs(ref_space)); dp.assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system on reference mesh. If successful, obtain the solution. info("Solving on reference mesh."); Solution ref_sln(ref_space->get_mesh()); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), ref_space, &ref_sln); else { error ("Matrix solver failed.\n"); success_test = 0; } // Time measurement. cpu_time.tick(); // Project the reference solution on the coarse mesh. Solution sln(space.get_mesh()); info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Time measurement. cpu_time.tick(); // Output solution and mesh with polynomial orders. if (solution_output) { out_fn_vtk(&sln, "sln", as); out_orders_vtk(&space, "order", as); } // Skip the visualization time. cpu_time.tick(HERMES_SKIP); // Calculate element errors and total error estimate. info("Calculating error estimate and exact error."); Adapt *adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = true; double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln, solutions_for_adapt) * 100; // Calculate exact error. solutions_for_adapt = false; double err_exact_rel = adaptivity->calc_err_exact(&sln, &exact, solutions_for_adapt) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d.", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space)); info("err_est_rel: %g%%, err_exact_rel: %g%%.", err_est_rel, err_exact_rel); // If err_est_rel is too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); adaptivity->adapt(THRESHOLD); } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete ref_space->get_mesh(); delete ref_space; delete matrix; delete rhs; delete solver; delete adaptivity; // Increase the counter of performed adaptivity steps. as++; } while (!done); // This is the actual test. #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 int ndof_allowed; switch (ANISO_TYPE) { case ANISO_X: ndof_allowed = 28; break; case ANISO_Y: ndof_allowed = 28; break; case ANISO_Z: ndof_allowed = 28; break; case ANISO_X | ANISO_Y: ndof_allowed = 98; break; case ANISO_X | ANISO_Z: ndof_allowed = 98; break; case ANISO_Y | ANISO_Z: ndof_allowed = 98; break; case ANISO_X | ANISO_Y | ANISO_Z: ndof_allowed = 343; break; default: error("Admissible command-line options are x, y, x, xy, xz, yz, xyz."); } int ndof = Space::get_num_dofs(&space); info("ndof_actual = %d", ndof); info("ndof_allowed = %d", ndof_allowed); if (ndof > ndof_allowed) success_test = 0; if (success_test) { info("Success!"); return ERR_SUCCESS; } else { info("Failure!"); return ERR_FAILURE; } }
int main (int argc, char* argv[]) { // Load the mesh. Mesh basemesh; ExodusIIReader mesh_loader; if (!mesh_loader.load("coarse_mesh_full.e", &basemesh)) error("Loading mesh file '%s' failed.\n", "coarse_mesh_full.e"); Mesh C_mesh, phi_mesh; C_mesh.copy(basemesh); phi_mesh.copy(basemesh); H1Space C_space(&C_mesh, bc_types_C, essential_bc_values_C, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); H1Space phi_space(MULTIMESH ? &phi_mesh : &C_mesh, bc_types_phi, essential_bc_values_phi, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); Solution C_prev_time(&C_mesh); C_prev_time.set_const(C0); Solution phi_prev_time(MULTIMESH ? &phi_mesh : &C_mesh); phi_prev_time.set_const(0.0); WeakForm wf(2); // Add the bilinear and linear forms. if (TIME_DISCR == 1) { // Implicit Euler. wf.add_matrix_form(0, 0, callback(J_euler_DFcDYc), HERMES_NONSYM); wf.add_matrix_form(0, 1, callback(J_euler_DFcDYphi), HERMES_NONSYM); wf.add_matrix_form(1, 0, callback(J_euler_DFphiDYc), HERMES_NONSYM); wf.add_matrix_form(1, 1, callback(J_euler_DFphiDYphi), HERMES_NONSYM); wf.add_vector_form(0, callback(Fc_euler), HERMES_ANY_INT, Hermes::vector<MeshFunction*>(&C_prev_time, &phi_prev_time)); wf.add_vector_form(1, callback(Fphi_euler), HERMES_ANY, Hermes::vector<MeshFunction*>(&C_prev_time, &phi_prev_time)); } else { wf.add_matrix_form(0, 0, callback(J_cranic_DFcDYc), HERMES_NONSYM); wf.add_matrix_form(0, 1, callback(J_cranic_DFcDYphi), HERMES_NONSYM); wf.add_matrix_form(1, 0, callback(J_cranic_DFphiDYc), HERMES_NONSYM); wf.add_matrix_form(1, 1, callback(J_cranic_DFphiDYphi), HERMES_NONSYM); wf.add_vector_form(0, callback(Fc_cranic), HERMES_ANY, Hermes::vector<MeshFunction*>(&C_prev_time, &phi_prev_time)); wf.add_vector_form(1, callback(Fphi_cranic), HERMES_ANY); } int ndof = Space::get_num_dofs(Hermes::vector<Space*>(&C_space, &phi_space)); Solution C_sln(C_space.get_mesh()); Solution phi_sln(phi_space.get_mesh()); info("Projecting initial condition to obtain initial vector for the Newton's method."); scalar* coeff_vec_coarse = new scalar[ndof]; OGProjection::project_global(Hermes::vector<Space *>(&C_space, &phi_space), Hermes::vector<MeshFunction *>(&C_prev_time, &phi_prev_time), coeff_vec_coarse, matrix_solver); bool is_linear = false; DiscreteProblem dp_coarse(&wf, Hermes::vector<Space *>(&C_space, &phi_space), is_linear); //Solution::vector_to_solutions(coeff_vec_coarse, dp_coarse.get_spaces(), Hermes::vector<Solution *>(&C_sln, &phi_sln), NULL); // Set up the solver, matrix, and rhs for the coarse mesh according to the solver selection. SparseMatrix* matrix_coarse = create_matrix(matrix_solver); Vector* rhs_coarse = create_vector(matrix_solver); Solver* solver_coarse = create_linear_solver(matrix_solver, matrix_coarse, rhs_coarse); info("Solving on coarse mesh:"); bool verbose = true; if (!solve_newton(coeff_vec_coarse, &dp_coarse, solver_coarse, matrix_coarse, rhs_coarse, NEWTON_TOL_COARSE, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); info("Solved!"); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solutions(coeff_vec_coarse, Hermes::vector<Space *>(&C_space, &phi_space), Hermes::vector<Solution *>(&C_sln, &phi_sln)); out_fn_vtk(&C_sln,"C_init_sln"); out_fn_vtk(&phi_sln,"phi_init_sln"); //out_fn_vtk(&sln, "sln", ts); Solution *C_ref_sln, *phi_ref_sln; PidTimestepController pid(T_FINAL, false, INIT_TAU); TAU = pid.timestep; info("Starting time iteration with the step %g", *TAU); do { pid.begin_step(); if (pid.get_timestep_number() > 1 && pid.get_timestep_number() % UNREF_FREQ == 0) { info("Global mesh derefinement."); C_mesh.copy(basemesh); if (MULTIMESH) { phi_mesh.copy(basemesh); } C_space.set_uniform_order(Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); phi_space.set_uniform_order(Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); } bool done = false; int as = 1; double err_est; do { info("Time step %d, adaptivity step %d:", pid.get_timestep_number(), as); // Construct globally refined reference mesh // and setup reference space. int order_increase = 1; Hermes::vector<Space *>* ref_spaces = construct_refined_spaces(Hermes::vector<Space *>(&C_space, &phi_space), order_increase); scalar* coeff_vec = new scalar[Space::get_num_dofs(*ref_spaces)]; DiscreteProblem* dp = new DiscreteProblem(&wf, *ref_spaces, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); if (as == 1 && pid.get_timestep_number() == 1) { info("Projecting coarse mesh solution to obtain coefficient vector on new fine mesh."); OGProjection::project_global(*ref_spaces, Hermes::vector<MeshFunction *>(&C_sln, &phi_sln), coeff_vec, matrix_solver); } else { info("Projecting previous fine mesh solution to obtain coefficient vector on new fine mesh."); OGProjection::project_global(*ref_spaces, Hermes::vector<MeshFunction *>(C_ref_sln, phi_ref_sln), coeff_vec, matrix_solver); } if (as > 1) { // Now deallocate the previous mesh info("Deallocating the previous mesh"); //delete C_ref_sln->get_mesh(); //delete phi_ref_sln->get_mesh(); //delete C_ref_sln; //delete phi_ref_sln; } /*TODO TEMP */ if (pid.get_timestep_number() > 1) { delete C_ref_sln; delete phi_ref_sln; } info("Solving on fine mesh:"); if (!solve_newton(coeff_vec, dp, solver, matrix, rhs, NEWTON_TOL_FINE, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Store the result in ref_sln. C_ref_sln = new Solution(ref_spaces->at(0)->get_mesh()); phi_ref_sln = new Solution(ref_spaces->at(1)->get_mesh()); Solution::vector_to_solutions(coeff_vec, *ref_spaces, Hermes::vector<Solution *>(C_ref_sln, phi_ref_sln)); // Projecting reference solution onto the coarse mesh info("Projecting fine mesh solution on coarse mesh."); OGProjection::project_global(Hermes::vector<Space *>(&C_space, &phi_space), Hermes::vector<Solution *>(C_ref_sln, phi_ref_sln), Hermes::vector<Solution *>(&C_sln, &phi_sln), matrix_solver); info("Calculating error estimate."); Adapt* adaptivity = new Adapt(Hermes::vector<Space *>(&C_space, &phi_space), Hermes::vector<ProjNormType> (HERMES_H1_NORM, HERMES_H1_NORM)); Hermes::vector<double> err_est_rel; bool solutions_for_adapt = true; double err_est_rel_total = adaptivity->calc_err_est(Hermes::vector<Solution *>(&C_sln, &phi_sln), Hermes::vector<Solution *>(C_ref_sln, phi_ref_sln), solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_ABS, &err_est_rel) * 100; // Report results. info("ndof_coarse[0]: %d, ndof_fine[0]: %d", C_space.get_num_dofs(), (*ref_spaces)[0]->get_num_dofs()); info("err_est_rel[0]: %g%%", err_est_rel[0]*100); info("ndof_coarse[1]: %d, ndof_fine[1]: %d", phi_space.get_num_dofs(), (*ref_spaces)[1]->get_num_dofs()); info("err_est_rel[1]: %g%%", err_est_rel[1]*100); // Report results. info("ndof_coarse_total: %d, ndof_fine_total: %d, err_est_rel: %g%%", Space::get_num_dofs(Hermes::vector<Space *>(&C_space, &phi_space)), Space::get_num_dofs(*ref_spaces), err_est_rel_total); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) done = true; else { info("Adapting the coarse mesh."); adaptivity->adapt(THRESHOLD); info("Adapted..."); if (Space::get_num_dofs(Hermes::vector<Space *>(&C_space, &phi_space)) >= NDOF_STOP) done = true; else // Increase the counter of performed adaptivity steps. as++; } //as++; delete solver; delete matrix; delete rhs; delete ref_spaces; delete dp; delete[] coeff_vec; done = true; } while (!done); out_fn_vtk(C_ref_sln,"C_sln", pid.get_timestep_number()); out_fn_vtk(phi_ref_sln,"phi_sln", pid.get_timestep_number()); pid.end_step(Hermes::vector<Solution*> (C_ref_sln, phi_ref_sln), Hermes::vector<Solution*> (&C_prev_time, &phi_prev_time)); // Copy last reference solution into sln_prev_time. C_prev_time.copy(C_ref_sln); phi_prev_time.copy(phi_ref_sln); } while (pid.has_next()); //View::wait(); return 0; }
int main(int argc, char **args) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; ExodusIIReader mesh_loader; if (!mesh_loader.load("cylinder2.e", &mesh)) error("Loading mesh file '%s' failed.\n", "cylinder2.e"); // 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. H1Space space(&mesh, bc_types, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); info("Number of DOF: %d.", Space::get_num_dofs(&space)); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form1), HERMES_SYM, 1); wf.add_matrix_form(callback(bilinear_form2), HERMES_SYM, 2); wf.add_vector_form(callback(linear_form), HERMES_ANY); // Initialize discrete problem. bool is_linear = true; DiscreteProblem dp(&wf, &space, is_linear); // Initialize the solver in the case of SOLVER_PETSC or SOLVER_MUMPS. initialize_solution_environment(matrix_solver, argc, args); // 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 amtrix and load vector. info("Assembling the linear problem (ndof: %d).", Space::get_num_dofs(&space)); dp.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving the linear problem."); Solution sln(space.get_mesh()); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); // Output solution and the boundary condition. if (solution_output) { out_fn_vtk(&sln, "sln"); out_bc_vtk(&mesh, "bc"); } // Time measurement. cpu_time.tick(); // Print timing information. info("Solution and the boundary condition saved. Total running time: %g s", cpu_time.accumulated()); // Clean up. delete matrix; delete rhs; delete solver; // Properly terminate the solver in the case of SOLVER_PETSC or SOLVER_MUMPS. finalize_solution_environment(matrix_solver); return 0; }
int main(int argc, char **args) { // Test variable. int success_test = 1; // Load the initial mesh. Mesh mesh; H3DReader mesh_loader; mesh_loader.load("../hexahedron.mesh3d", &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. H1Space space(&mesh, bc_types, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); // Construct initial solution and set it to zero. Solution sln_prev(&mesh); sln_prev.set_zero(); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<Ord, Ord>, HERMES_SYM); wf.add_vector_form(linear_form<double, scalar>, linear_form<Ord, Ord>, HERMES_ANY_INT, &sln_prev); // Initialize discrete problem. bool is_linear = true; DiscreteProblem dp(&wf, &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 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). } // Exact error for testing purposes. double err_exact; // Time stepping. int nsteps = (int) (FINAL_TIME/TAU + 0.5); for (int ts = 0; ts < nsteps; ts++) { info("---- Time step %d, time %3.5f.", ts, TIME); // Assemble the linear problem. info("Assembling the linear problem (ndof: %d).", Space::get_num_dofs(&space)); if (ts == 0) dp.assemble(matrix, rhs); else dp.assemble(NULL, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving the linear problem."); Solution sln(space.get_mesh()); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); // Output solution. if (solution_output) out_fn_vtk(&sln, "sln", ts); // Calculate exact error. ExactSolution esln(&mesh, fndd); info("Calculating exact error."); Adapt *adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = false; err_exact = adaptivity->calc_err_exact(&sln, &esln, solutions_for_adapt, HERMES_TOTAL_ERROR_ABS) * 100; info("Err. exact: %g%%.", err_exact); // Next time step. sln_prev = sln; TIME += TAU; // Cleanup. delete adaptivity; } if(err_exact > 3.00) success_test = 0; // Clean up. delete matrix; delete rhs; delete solver; if (success_test) { info("Success!"); return ERR_SUCCESS; } else { info("Failure!"); return ERR_FAILURE; } }
Space *HcurlSpace::dup(Mesh *mesh) const { _F_ HcurlSpace *space = new HcurlSpace(mesh, NULL, NULL, Ord3(-1,-1,-1), shapeset); space->copy_callbacks(this); return space; }
int main(int argc, char* argv[]) { info("Desired number of eigenvalues: %d.", NUMBER_OF_EIGENVALUES); // Load the mesh. info("Loading and refining mesh..."); Mesh mesh; H3DReader mloader; mloader.load("hexahedron.mesh3d", &mesh); // Perform initial mesh refinements (optional). for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ); // Create an H1 space with default shapeset. H1Space space(&mesh, bc_types, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); int ndof = Space::get_num_dofs(&space); info("ndof: %d.", ndof); // Initialize the weak formulation for the left hand side, i.e., H. info("Initializing weak form..."); WeakForm wf_left, wf_right; wf_left.add_matrix_form(bilinear_form_left, bilinear_form_left_ord, HERMES_SYM, HERMES_ANY ); wf_right.add_matrix_form(callback(bilinear_form_right), HERMES_SYM, HERMES_ANY ); // Initialize matrices and matrix solver. SparseMatrix* matrix_left = create_matrix(matrix_solver); SparseMatrix* matrix_right = create_matrix(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix_left); // Assemble the matrices. info("Assembling matrices..."); bool is_linear = true; DiscreteProblem dp_left(&wf_left, &space, is_linear); dp_left.assemble(matrix_left); DiscreteProblem dp_right(&wf_right, &space, is_linear); dp_right.assemble(matrix_right); // Write matrix_left in MatrixMarket format. write_matrix_mm("mat_left.mtx", matrix_left); // Write matrix_right in MatrixMarket format. write_matrix_mm("mat_right.mtx", matrix_right); // Calling Python eigensolver. Solution will be written to "eivecs.dat". info("Using eigensolver..."); char call_cmd[255]; sprintf(call_cmd, "python solveGenEigenFromMtx.py mat_left.mtx mat_right.mtx %g %d %g %d", TARGET_VALUE, NUMBER_OF_EIGENVALUES, TOL, MAX_ITER); system(call_cmd); // Initializing solution vector, solution and ScalarView. info("Initializing solution vector..."); double* coeff_vec = new double[ndof]; Solution sln(space.get_mesh()); // Reading solution vectors from file and visualizing. info("Reading solution vectors from file and saving as solutions in paraview format..."); FILE *file = fopen("eivecs.dat", "r"); char line [64]; // Maximum line size. fgets(line, sizeof line, file); // ndof int n = atoi(line); if (n != ndof) error("Mismatched ndof in the eigensolver output file."); fgets(line, sizeof line, file); // Number of eigenvectors in the file. int neig = atoi(line); if (neig != NUMBER_OF_EIGENVALUES) error("Mismatched number of eigenvectors in the eigensolver output file."); for (int ieig = 0; ieig < neig; ieig++) { // Get next eigenvector from the file. for (int i = 0; i < ndof; i++) { fgets(line, sizeof line, file); coeff_vec[i] = atof(line); } // Convert coefficient vector into a Solution. Solution::vector_to_solution(coeff_vec, &space, &sln); out_fn_vtk(&sln, "sln", ieig ); } fclose(file); delete [] coeff_vec; return 0; };
int main(int argc, char **args) { if (argc < 3) error("Not enough parameters."); char *type = args[1]; Mesh mesh; H3DReader 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) { Ord3 order; if (mesh.elements[1]->get_mode() == HERMES_MODE_HEX) order = Ord3(2, 3, 4); else if (mesh.elements[1]->get_mode() == HERMES_MODE_TET) order = Ord3(3); else error(HERMES_ERR_NOT_IMPLEMENTED); H1Space space(&mesh, bc_types, essential_bc_values, order); #if defined GMSH output.out_orders_gmsh(&space, "orders_gmsh"); #elif defined VTK output.out_orders_vtk(&space, "orders_vtk"); #endif } else if (strcmp(type, "bc") == 0) { #if defined GMSH output.out_bc_gmsh(&mesh); #elif defined VTK output.out_bc_vtk(&mesh); #endif } 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; }
bool test_lin_indep(Shapeset *shapeset) { _F_ printf("I. linear independency\n"); UMFPackMatrix mat; UMFPackVector rhs; UMFPackLinearSolver solver(&mat, &rhs); ShapeFunction fu(shapeset), fv(shapeset); int n = Hex::NUM_VERTICES * 1 + // 1 vertex fn 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(Ord3(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; // vertex fns for (int i = 0; i < Hex::NUM_VERTICES; i++, m++) fn_idx[m] = shapeset->get_vertex_index(i); // 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 Ord3 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++) { fu.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++) { fv.set_active_shape(fn_idx[j]); double value = l2_product(&fu, &fv); 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; }