int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(1, INIT_BDY_REF_NUM); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_function(BDY_DIRICHLET, essential_bc_values); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); // Initialize the weak formulation WeakForm wf; wf.add_matrix_form(callback(jac), HERMES_UNSYM, HERMES_ANY); wf.add_vector_form(callback(res), HERMES_ANY); // Initialize the FE problem. bool is_linear = false; 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 solution. Solution sln; // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. info("Projecting to obtain initial vector for the Newton's method."); scalar* coeff_vec = new scalar[Space::get_num_dofs(&space)] ; Solution* init_sln = new Solution(&mesh, init_cond); OGProjection::project_global(&space, init_sln, coeff_vec, matrix_solver); delete init_sln; // Perform Newton's iteration. int it = 1; bool success = false; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(&space); // Assemble the Jacobian matrix and residual vector. dp.assemble(coeff_vec, matrix, rhs, false); // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for (int i = 0; i < ndof; i++) rhs->set(i, -rhs->get(i)); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(&space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, or the maximum number // of iteration has been reached, then quit. if (res_l2_norm < NEWTON_TOL || it > NEWTON_MAX_ITER) break; // Solve the linear system. if(!(success = solver->solve())) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); it++; } // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solution(coeff_vec, &space, &sln); // Cleanup. delete []coeff_vec; delete matrix; delete rhs; delete solver; if (success) { // should pass with NEWTON_MAX_ITER = 8 and fail with NEWTON_MAX_ITER = 7 printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; ExodusIIReader mloader; if (!mloader.load("iron-water.e", &mesh)) error("ExodusII mesh load failed."); // Perform initial uniform mesh refinement. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Create an H1 space with default shapeset. H1Space space(&mesh, bc_types, essential_bc_values, P_INIT); // Initialize the weak formulation WeakForm wf; wf.add_matrix_form(bilinear_form_water, bilinear_form_ord, HERMES_SYM, WATER_1); wf.add_matrix_form(bilinear_form_water, bilinear_form_ord, HERMES_SYM, WATER_2); wf.add_matrix_form(bilinear_form_iron, bilinear_form_ord, HERMES_SYM, IRON); wf.add_vector_form(linear_form_source, linear_form_ord, WATER_1); // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. ScalarView sview("Solution", new WinGeom(0, 0, 440, 350)); sview.fix_scale_width(50); sview.show_mesh(false); OrderView oview("Polynomial orders", new WinGeom(450, 0, 400, 350)); // DOF and CPU convergence graphs initialization. SimpleGraph graph_dof, graph_cpu; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Adaptivity loop: Solution ref_sln; 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); // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. // If successful, obtain the solution. if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), ref_space, &ref_sln); else error ("Matrix solver failed.\n"); // Project the fine mesh solution onto the coarse mesh. Solution sln; info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Time measurement. cpu_time.tick(); // View the coarse mesh solution and polynomial orders. sview.show(&sln); oview.show(&space); // Skip visualization time. cpu_time.tick(HERMES_SKIP); // Calculate element errors and total error estimate. info("Calculating error estimate."); 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, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space), err_est_rel); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof.save("conv_dof_est.dat"); graph_cpu.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu.save("conv_cpu_est.dat"); // If err_est too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if (done == false) as++; } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; delete dp; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); // Show the reference solution - the final result. sview.set_title("Fine mesh solution"); sview.show_mesh(false); sview.show(&ref_sln); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh, basemesh; H2DReader mloader; mloader.load("square.mesh", &basemesh); // Initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) basemesh.refine_all_elements(); mesh.copy(&basemesh); // Create an H1 space with default shapeset. H1Space space(&mesh, bc_types, essential_bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Initialize coarse and reference mesh solution. Solution sln, ref_sln; Solution sln_prev_time(&mesh, init_cond); // Initialize the weak formulation. WeakForm wf; if(TIME_DISCR == 1) { wf.add_matrix_form(callback(J_euler), HERMES_UNSYM, HERMES_ANY); wf.add_vector_form(callback(F_euler), HERMES_ANY, &sln_prev_time); } else { wf.add_matrix_form(callback(J_cranic), HERMES_UNSYM, HERMES_ANY); wf.add_vector_form(callback(F_cranic), HERMES_ANY, &sln_prev_time); } // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp_coarse(&wf, &space, is_linear); // 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); // Create a selector which will select optimal candidate. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. info("Projecting initial condition to obtain initial vector for the Newton's method."); scalar* coeff_vec_coarse = new scalar[ndof]; OGProjection::project_global(&space, &sln_prev_time, coeff_vec_coarse, matrix_solver); // Show the projection of the initial condition. char title[100]; ScalarView magview("Projection of initial condition", new WinGeom(0, 0, 440, 350)); magview.fix_scale_width(60); Solution init_proj; // init_proj->set_coeff_vector(space, coeff_vec_coarse); Solution::vector_to_solution(coeff_vec_coarse, &space, &init_proj); AbsFilter mag(&init_proj); magview.show(&mag); // delete init_proj; OrderView ordview("Initial mesh", new WinGeom(450, 0, 400, 350)); ordview.show(&space); // Newton's loop on the coarse mesh. info("Solving on coarse mesh:"); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(&space); // Assemble the Jacobian matrix and residual vector. dp_coarse.assemble(coeff_vec_coarse, matrix_coarse, rhs_coarse, false); // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for (int i = 0; i < ndof; i++) rhs_coarse->set(i, -rhs_coarse->get(i)); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs_coarse); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(&space), res_l2_norm); // If l2 norm of the residual vector is in tolerance, or the maximum number // of iteration has been hit, then quit. if (res_l2_norm < NEWTON_TOL_COARSE || it > NEWTON_MAX_ITER) break; // Solve the linear system and if successful, obtain the solution. if(!solver_coarse->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec_coarse[i] += solver_coarse->get_solution()[i]; if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); it++; } // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solution(coeff_vec_coarse, &space, &sln); // Cleanup after the Newton loop on the coarse mesh. delete matrix_coarse; delete rhs_coarse; delete solver_coarse; delete [] coeff_vec_coarse; // Time stepping loop. int num_time_steps = (int)(T_FINAL/TAU + 0.5); for(int ts = 1; ts <= num_time_steps; ts++) { // Periodic global derefinements. if (ts > 1 && ts % UNREF_FREQ == 0) { info("Global mesh derefinement."); mesh.copy(&basemesh); space.set_uniform_order(P_INIT); // Project on globally derefined mesh. info("Projecting previous fine mesh solution on derefined mesh."); OGProjection::project_global(&space, &ref_sln, &sln); } // Adaptivity loop: bool done = false; int as = 1; double err_est; do { info("Time step %d, adaptivity step %d:", ts, as); // Construct globally refined reference mesh // and setup reference space. Space* ref_space = construct_refined_space(&space); scalar* coeff_vec = new scalar[Space::get_num_dofs(ref_space)]; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Calculate initial coefficient vector for Newton on the fine mesh. if (as == 1) { info("Projecting coarse mesh solution to obtain coefficient vector on new fine mesh."); OGProjection::project_global(ref_space, &sln, coeff_vec); } else { info("Projecting previous fine mesh solution to obtain coefficient vector on new fine mesh."); OGProjection::project_global(ref_space, &ref_sln, coeff_vec); } // Newton's loop on the fine mesh. info("Solving on fine mesh:"); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(ref_space); // Assemble the Jacobian matrix and residual vector. dp->assemble(coeff_vec, matrix, rhs, false); // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for (int i = 0; i < ndof; i++) rhs->set(i, -rhs->get(i)); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(ref_space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, or the maximum number // of iteration has been reached, then quit. if (res_l2_norm < NEWTON_TOL_FINE || it > NEWTON_MAX_ITER) break; // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); it++; } // Store the result in ref_sln. Solution::vector_to_solution(coeff_vec, ref_space, &ref_sln); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Calculate element errors and total error estimate. info("Calculating error estimate."); Adapt* adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = true; double err_est_rel_total = adaptivity->calc_err_est(&sln, &ref_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100.; // Report results. info("ndof: %d, ref_ndof: %d, err_est_rel: %g%%", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space), 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."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; else // Increase the counter of performed adaptivity steps. as++; } info("Projecting fine mesh solution on new coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln); // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; delete ref_space->get_mesh(); delete ref_space; delete dp; // Visualize the solution and mesh. char title[100]; sprintf(title, "Solution, time level %d", ts); magview.set_title(title); magview.show(&sln); sprintf(title, "Mesh, time level %d", ts); ordview.set_title(title); ordview.show(&space); } while (done == false); // Copy last reference solution into sln_prev_time. sln_prev_time.copy(&ref_sln); } // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char **args) { int res = ERR_SUCCESS; #ifdef WITH_PETSC PetscInitialize(NULL, NULL, (char *) PETSC_NULL, PETSC_NULL); #endif set_verbose(false); TRACE_START("trace.txt"); DEBUG_OUTPUT_ON; SET_VERBOSE_LEVEL(0); try { for (int i = 0; i < 48; i++) { for (int j = 0; j < 48; j++) { // int i = 5; { // int j = 0; { printf("Config: %d, %d ", i, j); Mesh mesh; for (Word_t k = 0; k < countof(vtcs); k++) mesh.add_vertex(vtcs[k].x, vtcs[k].y, vtcs[k].z); Word_t h1[] = { hexs[0][i][0] + 1, hexs[0][i][1] + 1, hexs[0][i][2] + 1, hexs[0][i][3] + 1, hexs[0][i][4] + 1, hexs[0][i][5] + 1, hexs[0][i][6] + 1, hexs[0][i][7] + 1 }; mesh.add_hex(h1); Word_t h2[] = { hexs[1][j][0] + 1, hexs[1][j][1] + 1, hexs[1][j][2] + 1, hexs[1][j][3] + 1, hexs[1][j][4] + 1, hexs[1][j][5] + 1, hexs[1][j][6] + 1, hexs[1][j][7] + 1 }; mesh.add_hex(h2); // bc for (Word_t k = 0; k < countof(bnd); k++) { Word_t facet_idxs[Quad::NUM_VERTICES] = { bnd[k][0] + 1, bnd[k][1] + 1, bnd[k][2] + 1, bnd[k][3] + 1 }; mesh.add_quad_boundary(facet_idxs, bnd[k][4]); } mesh.ugh(); // mesh.dump(); // Element *hx[] = { mesh.elements[1], mesh.elements[2] }; // printf("[%d, %d]\n", hx[0]->get_face_orientation(1), hx[1]->get_face_orientation(2)); // Word_t fidx[4]; // hx[1]->get_face_vertices(2, fidx); // printf("FI: %d, %d, %d, %d\n", fidx[0], fidx[1], fidx[2], fidx[3]); printf("\n"); #ifdef OUTPUT_DIR BEGIN_BLOCK // output the mesh const char *of_name = OUTPUT_DIR "/ref.msh"; FILE *ofile = fopen(of_name, "w"); if (ofile != NULL) { GmshOutputEngine output(ofile); output.out(&mesh); fclose(ofile); } else { warning("Can not open '%s' for writing.", of_name); } END_BLOCK #endif H1ShapesetLobattoHex shapeset; // printf("* Setting the space up\n"); H1Space space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_essential_bc_values(essential_bc_values); #ifdef XM_YN_ZO order3_t ord(4, 4, 4); #elif defined XM_YN_ZO_2 order3_t ord(4, 4, 4); #elif defined X2_Y2_Z2 order3_t ord(2, 2, 2); #endif // printf(" - Setting uniform order to (%d, %d, %d)\n", dir_x, dir_y, dir_z); space.set_uniform_order(ord); space.assign_dofs(); // printf("* Calculating a solution\n"); #if defined WITH_UMFPACK UMFPackMatrix mat; UMFPackVector rhs; UMFPackLinearSolver solver(&mat, &rhs); #elif defined WITH_PARDISO PardisoLinearSolver solver; #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 WeakForm wf; #ifdef DIRICHLET wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<ord_t, ord_t>, SYM); wf.add_vector_form(linear_form<double, scalar>, linear_form<ord_t, ord_t>); #elif defined NEWTON wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<ord_t, ord_t>, SYM); wf.add_matrix_form_surf(bilinear_form_surf<double, scalar>, bilinear_form_surf<ord_t, ord_t>); wf.add_vector_form(linear_form<double, scalar>, linear_form<ord_t, ord_t>); wf.add_vector_form_surf(linear_form_surf<double, scalar>, linear_form_surf<ord_t, ord_t>); #endif LinProblem lp(&wf); lp.set_space(&space); // assemble stiffness matrix lp.assemble(&mat, &rhs); // solve the stiffness matrix bool solved = solver.solve(); if (!solved) throw ERR_FAILURE; // { // char file_name[1024]; // sprintf(file_name, "%s/matrix-%d-%d", OUTPUT_DIR, i, j); // FILE *file = fopen(file_name, "w"); // if (file != NULL) { // solver.dump_matrix(file, "A"); // solver.dump_rhs(file, "b"); // // fclose(file); // } // } Solution sln(&mesh); sln.set_fe_solution(&space, solver.get_solution()); ExactSolution exsln(&mesh, exact_solution); // norm double h1_sln_norm = h1_norm(&sln); double h1_err_norm = h1_error(&sln, &exsln); printf(" - H1 solution norm: % le\n", h1_sln_norm); printf(" - H1 error norm: % le\n", h1_err_norm); double l2_sln_norm = l2_norm(&sln); double l2_err_norm = l2_error(&sln, &exsln); printf(" - L2 solution norm: % le\n", l2_sln_norm); printf(" - L2 error norm: % le\n", l2_err_norm); assert(h1_sln_norm > 0 && h1_err_norm > 0); assert(l2_sln_norm > 0 && l2_err_norm > 0); // // out fn // char fname[4096]; // sprintf(fname, "%s/cfg-%d-%d.pos", OUTPUT_DIR, i, j); // FILE *fnf = fopen(fname, "w"); // assert(fnf != NULL); // GmshOutputEngine out(fnf); // char var[64]; // sprintf(var, "%d_%d", i, j); // out.out(&sln, var); // fclose(fnf); // // char mfname[4096]; // sprintf(mfname, "%s/mesh-%d-%d.ref", OUTPUT_DIR, i, j); // FILE *mfnf = fopen(mfname, "w"); // assert(mfnf != NULL); // GmshOutputEngine outm(mfnf); // outm.out(&mesh); // fclose(mfnf); if (h1_err_norm > EPS || l2_err_norm > EPS) { // calculated solution is not enough precise printf("Solution is not precise enough.\n"); throw ERR_FAILURE; } printf("Passed\n"); } } } catch (int e) { res = e; printf("Failed\n"); } #ifdef WITH_PETSC PetscFinalize(); #endif TRACE_END; return res; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinements. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(1, INIT_REF_NUM_BDY); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_zero(BDY_DIRICHLET); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form), HERMES_SYM); wf.add_vector_form(callback(linear_form)); // Initialize coarse and reference mesh solution. Solution sln, ref_sln; // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // DOF and CPU convergence graphs initialization. SimpleGraph graph_dof, graph_cpu; // 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); // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. // If successful, obtain the solution. if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), ref_space, &ref_sln); else error ("Matrix solver failed.\n"); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Calculate element errors and total error estimate. info("Calculating error estimate."); 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, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space), err_est_rel); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof.save("conv_dof_est.dat"); graph_cpu.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu.save("conv_cpu_est.dat"); // If err_est too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if (done == false) as++; } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; delete dp; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); int ndof = Space::get_num_dofs(&space); int n_dof_allowed = 750; printf("n_dof_actual = %d\n", ndof); printf("n_dof_allowed = %d\n", n_dof_allowed);// ndofs was 729 at the time this test was created if (ndof <= n_dof_allowed) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements. for(int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(Hermes::Tuple<int>(BDY_BOTTOM, BDY_OUTER, BDY_LEFT, BDY_INNER)); // Enter Dirichlet boudnary values. BCValues bc_values; bc_values.add_function(Hermes::Tuple<int>(BDY_BOTTOM, BDY_OUTER, BDY_LEFT, BDY_INNER), essential_bc_values); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d", ndof); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form)); wf.add_vector_form(callback(linear_form)); // Initialize the FE 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 solution. Solution 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 and solution. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); // Visualize the solution. ScalarView view("Solution", new WinGeom(0, 0, 440, 350)); view.show(&sln); // Wait for the view to be closed. View::wait(); // Clean up. delete solver; delete matrix; delete rhs; return 0; }
int main() { // Three macroelements are defined above via the interfaces[] array. // poly_orders[]... initial poly degrees of macroelements. // material_markers[]... material markers of macroelements. // subdivisions[]... equidistant subdivision of macroelements. int poly_orders[N_MAT] = {P_init_inner, P_init_outer, P_init_reflector }; int material_markers[N_MAT] = {Marker_inner, Marker_outer, Marker_reflector }; int subdivisions[N_MAT] = {N_subdiv_inner, N_subdiv_outer, N_subdiv_reflector }; // Create space. Space* space = new Space(N_MAT, interfaces, poly_orders, material_markers, subdivisions, N_GRP, N_SLN); // Enumerate basis functions, info for user. info("N_dof = %d", Space::get_num_dofs(space)); // Initial approximation: u = 1. double K_EFF_old; double init_val = 1.0; set_vertex_dofs_constant(space, init_val, 0); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(jacobian_vol_inner, NULL, Marker_inner); wf.add_matrix_form(jacobian_vol_outer, NULL, Marker_outer); wf.add_matrix_form(jacobian_vol_reflector, NULL, Marker_reflector); wf.add_vector_form(residual_vol_inner, NULL, Marker_inner); wf.add_vector_form(residual_vol_outer, NULL, Marker_outer); wf.add_vector_form(residual_vol_reflector, NULL, Marker_reflector); wf.add_vector_form_surf(residual_surf_left, BOUNDARY_LEFT); wf.add_matrix_form_surf(jacobian_surf_right, BOUNDARY_RIGHT); wf.add_vector_form_surf(residual_surf_right, BOUNDARY_RIGHT); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear); // Source iteration (power method). for (int i = 0; i < Max_SI; i++) { // Obtain fission source. int current_solution = 0, previous_solution = 1; copy_dofs(current_solution, previous_solution, space); // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(space)]; get_coeff_vector(space, coeff_vec); // 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); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp->assemble(matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec, space); it++; } // Cleanup. delete matrix; delete rhs; delete solver; delete [] coeff_vec; // Update the eigenvalue. K_EFF_old = K_EFF; K_EFF = calc_fission_yield(space); info("K_EFF_%d = %f", i, K_EFF); if (fabs(K_EFF - K_EFF_old)/K_EFF < TOL_SI) break; } // Plot the critical (i.e. steady-state) neutron flux. Linearizer l(space); l.plot_solution("solution.gp"); // Normalize so that the absolute neutron flux generates 320 Watts of energy // (note that, using the symmetry condition at the origin, we've solved for // flux only in the right half of the reactor). normalize_to_power(space, 320/2.); // Plot the solution and space. l.plot_solution("solution_320W.gp"); space->plot("space.gp"); info("K_EFF = %f", K_EFF); info("Done."); return 0; }
int main() { // Create space, set Dirichlet BC, enumerate basis functions. Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ); info("N_dof = %d.", Space::get_num_dofs(space)); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(jacobian); wf.add_vector_form(residual); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear); // Newton's loop. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(space)]; solution_to_vector(space, coeff_vec); // 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); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp->assemble(matrix, rhs); // Calculate the l2-norm of residual vector. double res_norm = 0; for(int i=0; i<ndof; i++) res_norm += rhs->get(i)*rhs->get(i); res_norm = sqrt(res_norm); // Info for user. info("---- Newton iter %d, residual norm: %.15f", it, res_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_norm < NEWTON_TOL && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. vector_to_solution(coeff_vec, space); it++; } // Plot the solution. Linearizer l(space); l.plot_solution("solution.gp"); // Plot the resulting space. space->plot("space.gp"); info("Done."); return 1; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("cathedral.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(BDY_AIR, INIT_REF_NUM_BDY); mesh.refine_towards_boundary(BDY_GROUND, INIT_REF_NUM_BDY); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(Hermes::vector<std::string>(BDY_GROUND)); bc_types.add_bc_newton(BDY_AIR); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_const(BDY_GROUND, TEMP_INIT); // Initialize an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Previous time level solution (initialized by the external temperature). Solution tsln(&mesh, TEMP_INIT); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form)); wf.add_matrix_form_surf(callback(bilinear_form_surf), BDY_AIR); wf.add_vector_form(callback(linear_form), HERMES_ANY, &tsln); wf.add_vector_form_surf(callback(linear_form_surf), BDY_AIR); // Initialize the FE 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); solver->set_factorization_scheme(HERMES_REUSE_FACTORIZATION_COMPLETELY); // Initialize views. ScalarView Tview("Temperature", new WinGeom(0, 0, 450, 600)); Tview.set_min_max_range(0,20); Tview.fix_scale_width(30); // Time stepping: int ts = 1; bool rhs_only = false; do { info("---- Time step %d, time %3.5f s, ext_temp %g C", ts, current_time, temp_ext(current_time)); // First time assemble both the stiffness matrix and right-hand side vector, // then just the right-hand side vector. if (rhs_only == false) info("Assembling the stiffness matrix and right-hand side vector."); else info("Assembling the right-hand side vector (only)."); dp.assemble(matrix, rhs, rhs_only); rhs_only = true; // Solve the linear system and if successful, obtain the solution. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &tsln); else error ("Matrix solver failed.\n"); // Visualize the solution. char title[100]; sprintf(title, "Time %3.2f s, exterior temperature %3.5f C", current_time, temp_ext(current_time)); Tview.set_title(title); Tview.show(&tsln); // Increase current time and time step counter. current_time += time_step; ts++; } while (current_time < T_FINAL); // Wait for the view to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh, basemesh; H2DReader mloader; mloader.load("square.mesh", &basemesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) basemesh.refine_all_elements(); mesh.copy(&basemesh); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(Hermes::Tuple<int>(BDY_BOTTOM, BDY_RIGHT, BDY_TOP, BDY_LEFT)); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_zero(Hermes::Tuple<int>(BDY_BOTTOM, BDY_RIGHT, BDY_TOP, BDY_LEFT)); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); // Initialize coarse and reference mesh solution. Solution sln, ref_sln; // Convert initial condition into a Solution. Solution sln_prev_time; sln_prev_time.set_exact(&mesh, init_cond); // Initialize the weak formulation. WeakForm wf; if(TIME_DISCR == 1) { wf.add_matrix_form(callback(J_euler), HERMES_UNSYM, HERMES_ANY); wf.add_vector_form(callback(F_euler), HERMES_ANY, &sln_prev_time); } else { wf.add_matrix_form(callback(J_cranic), HERMES_UNSYM, HERMES_ANY); wf.add_vector_form(callback(F_cranic), HERMES_ANY, &sln_prev_time); } // Initialize the discrete problem. bool is_linear = false; DiscreteProblem dp_coarse(&wf, &space, is_linear); // Create a refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Visualize initial condition. char title[100]; ScalarView view("Initial condition", new WinGeom(0, 0, 450, 350)); view.fix_scale_width(70); view.show(&sln_prev_time); OrderView ordview("Initial mesh", new WinGeom(455, 0, 410, 350)); ordview.fix_scale_width(10); ordview.show(&space); // Time stepping loop. int num_time_steps = (int)(T_FINAL/TAU + 0.5); for(int ts = 1; ts <= num_time_steps; ts++) { // Periodic global derefinement. if (ts > 1 && ts % UNREF_FREQ == 0) { info("Global mesh derefinement."); mesh.copy(&basemesh); space.set_uniform_order(P_INIT); ndof = Space::get_num_dofs(&space); } // The following is done only in the first time step, // when the nonlinear problem was never solved before. if (ts == 1) { // 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); scalar* coeff_vec_coarse = new scalar[ndof]; // Calculate initial coefficient vector for Newton on the coarse mesh. info("Projecting initial condition to obtain coefficient vector on coarse mesh."); OGProjection::project_global(&space, &sln_prev_time, coeff_vec_coarse, matrix_solver); // Newton's loop on the coarse mesh. 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."); Solution::vector_to_solution(coeff_vec_coarse, &space, &sln); // Cleanup after the Newton loop on the coarse mesh. delete matrix_coarse; delete rhs_coarse; delete solver_coarse; delete [] coeff_vec_coarse; } // Adaptivity loop: bool done = false; int as = 1; double err_est; do { info("Time step %d, adaptivity step %d:", ts, as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = construct_refined_space(&space); // Initialize matrix solver. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); scalar* coeff_vec = new scalar[Space::get_num_dofs(ref_space)]; // Initialize discrete problem on reference mesh. DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); // Calculate initial coefficient vector for Newton on the fine mesh. if (ts == 1 && as == 1) { info("Projecting coarse mesh solution to obtain coefficient vector on fine mesh."); OGProjection::project_global(ref_space, &sln, coeff_vec, matrix_solver); } else { info("Projecting last fine mesh solution to obtain coefficient vector on new fine mesh."); OGProjection::project_global(ref_space, &ref_sln, coeff_vec, matrix_solver); } // Now we can deallocate the previous fine mesh. if(as > 1) delete ref_sln.get_mesh(); // Newton's loop on the fine mesh. info("Solving on fine mesh:"); bool verbose = true; 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. Solution::vector_to_solution(coeff_vec, ref_space, &ref_sln); // Project the fine mesh solution onto the coarse mesh. info("Projecting fine mesh solution on coarse mesh for error estimation."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Calculate element errors and total error estimate. info("Calculating error estimate."); Adapt* adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = true; double err_est_rel_total = adaptivity->calc_err_est(&sln, &ref_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100; // Report results. info("ndof: %d, ref_ndof: %d, err_est_rel: %g%%", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space), 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."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; else // Increase the counter of performed adaptivity steps. as++; } // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; delete ref_space; delete dp; delete [] coeff_vec; } while (done == false); // Visualize the solution and mesh. char title[100]; sprintf(title, "Solution, time %g", ts*TAU); view.set_title(title); view.show_mesh(false); view.show(&sln); sprintf(title, "Mesh, time %g", ts*TAU); ordview.set_title(title); ordview.show(&space); // Copy last reference solution into sln_prev_time. sln_prev_time.copy(&ref_sln); } // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(1,INIT_BDY_REF_NUM); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_zero(BDY_DIRICHLET); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(jac), HERMES_NONSYM, HERMES_ANY); wf.add_vector_form(callback(res), HERMES_ANY); // Initialize the FE problem. bool is_linear = false; 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 solution. Solution sln; // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. info("Projecting to obtain initial vector for the Newton's method."); scalar* coeff_vec = new scalar[Space::get_num_dofs(&space)]; Solution* init_sln = new Solution(); init_sln->set_const(&mesh, INIT_COND_CONST); OGProjection::project_global(&space, init_sln, coeff_vec, matrix_solver); delete init_sln; // Perform Newton's iteration. bool verbose = true; if (!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solution(coeff_vec, &space, &sln); // Cleanup. delete [] coeff_vec; delete matrix; delete rhs; delete solver; info("ndof = %d", ndof); info("Coordinate (1, 0) value = %lf", sln.get_pt_value(1.0, 0.0)); info("Coordinate (3, 0) value = %lf", sln.get_pt_value(3.0, 0.0)); info("Coordinate (5, 0) value = %lf", sln.get_pt_value(5.0, 0.0)); info("Coordinate (7, 0) value = %lf", sln.get_pt_value(7.0, 0.0)); double coor_x[4] = {1.0, 3.0, 5.0, 7.0}; double coor_y = 0.0; double t_value[4] = {2.658510, 2.617692, 2.522083, 2.329342}; bool success = true; for (int i = 0; i < 4; i++) { if (abs(t_value[i] - sln.get_pt_value(coor_x[i], coor_y)) > 1E-6) success = false; } if (success) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements. mesh.refine_towards_vertex(3, CORNER_REF_LEVEL); // Create an H1 space. H1Space space(&mesh, bc_types, essential_bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form)); wf.add_vector_form(callback(linear_form)); wf.add_vector_form_surf(callback(linear_form_surf)); // Testing n_dof and correctness of solution vector // for p_init = 1, 2, ..., 10 int success = 1; Solution sln; for (int p_init = 1; p_init <= 10; p_init++) { printf("********* p_init = %d *********\n", p_init); space.set_uniform_order(p_init); // Initialize the FE 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 solution. Solution sln; // Assemble the stiffness matrix and right-hand side vector. info("Assembling the stiffness matrix and right-hand side vector."); bool rhsonly = false; dp.assemble(matrix, rhs, rhsonly); // Solve the linear system and if successful, obtain the solution. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); int ndof = Space::get_num_dofs(&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 - 6.86366) > 1e-3) success = 0; if (p_init == 2 && fabs(sum - 7.6971) > 1e-3) success = 0; if (p_init == 3 && fabs(sum - 7.56655) > 1e-3) success = 0; if (p_init == 4 && fabs(sum - 7.61343) > 1e-3) success = 0; if (p_init == 5 && fabs(sum - 7.58787) > 1e-3) success = 0; if (p_init == 6 && fabs(sum - 7.59164) > 1e-3) success = 0; if (p_init == 7 && fabs(sum - 7.5961) > 1e-3) success = 0; if (p_init == 8 && fabs(sum - 7.58042) > 1e-3) success = 0; if (p_init == 9 && fabs(sum - 7.60115) > 1e-3) success = 0; if (p_init == 10 && fabs(sum - 7.57284) > 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 mesh; H2DReader mloader; mloader.load("../square.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(BDY_DIRICHLET, INIT_BDY_REF_NUM); // Initialize boundary conditions. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_function(BDY_DIRICHLET, essential_bc_values); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Solution for the previous time level. Solution u_prev_time; // Initialize the weak formulation. WeakForm wf; if (TIME_INTEGRATION == 1) { wf.add_matrix_form(jac_euler, jac_ord, HERMES_NONSYM, HERMES_ANY, &u_prev_time); wf.add_vector_form(res_euler, res_ord, HERMES_ANY, &u_prev_time); } else { wf.add_matrix_form(jac_cranic, jac_ord, HERMES_NONSYM, HERMES_ANY, &u_prev_time); wf.add_vector_form(res_cranic, res_ord, HERMES_ANY, &u_prev_time); } // Project the function init_cond() on the FE space // to obtain initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[Space::get_num_dofs(&space)]; info("Projecting initial condition to obtain initial vector for the Newton's method."); OGProjection::project_global(&space, init_cond, coeff_vec, matrix_solver); Solution::vector_to_solution(coeff_vec, &space, &u_prev_time); // Time stepping loop: double current_time = 0.0; int t_step = 1; do { info("---- Time step %d, t = %g s.", t_step, current_time); t_step++; // Initialize the FE problem. bool is_linear = false; 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); // Perform Newton's iteration. bool verbose = true; if (!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solution(coeff_vec, &space, &u_prev_time); // Cleanup. delete matrix; delete rhs; delete solver; // Update time. current_time += TAU; } while (current_time < T_FINAL); delete [] coeff_vec; info("Coordinate ( 0, 0) value = %lf", u_prev_time.get_pt_value(0.0, 0.0)); info("Coordinate ( 25, 25) value = %lf", u_prev_time.get_pt_value(25.0, 25.0)); info("Coordinate ( 50, 50) value = %lf", u_prev_time.get_pt_value(50.0, 50.0)); info("Coordinate ( 75, 75) value = %lf", u_prev_time.get_pt_value(75.0, 75.0)); info("Coordinate (100, 100) value = %lf", u_prev_time.get_pt_value(100.0, 100.0)); double coor_x_y[5] = {0.0, 25.0, 50.0, 75.0, 100.0}; double value[5] = {-1000.000000, -969.316013, -836.504249, -651.433710, -1000.000000}; bool success = true; for (int i = 0; i < 5; i++) { if (abs(value[i] - u_prev_time.get_pt_value(coor_x_y[i], coor_x_y[i])) > 1E-6) success = false; } if (success) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); mesh.refine_all_elements(); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(Hermes::Tuple<int>(BDY_BOTTOM, BDY_OUTER, BDY_LEFT, BDY_INNER)); // Enter Dirichlet boudnary values. BCValues bc_values; bc_values.add_function(Hermes::Tuple<int>(BDY_BOTTOM, BDY_OUTER, BDY_LEFT, BDY_INNER), essential_bc_values); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d", ndof); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form)); wf.add_vector_form(callback(linear_form)); // Testing n_dof and correctness of solution vector // for p_init = 1, 2, ..., 10 int success = 1; Solution sln; for (int p_init = 1; p_init <= 10; p_init++) { printf("********* p_init = %d *********\n", p_init); space.set_uniform_order(p_init); // Initialize the FE 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 solution. Solution sln; // Assemble the stiffness matrix and right-hand side vector. info("Assembling the stiffness matrix and right-hand side vector."); bool rhsonly = false; dp.assemble(matrix, rhs, rhsonly); // Solve the linear system and if successful, obtain the solution. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); int ndof = Space::get_num_dofs(&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 - 1.7251) > 1e-3) success = 0; if (p_init == 2 && fabs(sum - 3.79195) > 1e-3) success = 0; if (p_init == 3 && fabs(sum - 3.80206) > 1e-3) success = 0; if (p_init == 4 && fabs(sum - 3.80156) > 1e-3) success = 0; if (p_init == 5 && fabs(sum - 3.80155) > 1e-3) success = 0; if (p_init == 6 && fabs(sum - 3.80154) > 1e-3) success = 0; if (p_init == 7 && fabs(sum - 3.80154) > 1e-3) success = 0; if (p_init == 8 && fabs(sum - 3.80153) > 1e-3) success = 0; if (p_init == 9 && fabs(sum - 3.80152) > 1e-3) success = 0; if (p_init == 10 && fabs(sum - 3.80152) > 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[]) { // Choose a Butcher's table or define your own. ButcherTable bt(butcher_table_type); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("cathedral.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(BDY_AIR, INIT_REF_NUM_BDY); mesh.refine_towards_boundary(BDY_GROUND, INIT_REF_NUM_BDY); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(Hermes::vector<std::string>(BDY_GROUND)); bc_types.add_bc_newton(BDY_AIR); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_const(BDY_GROUND, TEMP_INIT); // Initialize an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Previous time level solution (initialized by the external temperature). Solution u_prev_time(&mesh, TEMP_INIT); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(callback(stac_jacobian)); wf.add_vector_form(callback(stac_residual)); wf.add_matrix_form_surf(callback(bilinear_form_surf), BDY_AIR); wf.add_vector_form_surf(callback(linear_form_surf), BDY_AIR); // Project the initial condition on the FE space to obtain initial solution coefficient vector. info("Projecting initial condition to translate initial condition into a vector."); scalar* coeff_vec = new scalar[ndof]; OGProjection::project_global(&space, &u_prev_time, coeff_vec, matrix_solver); // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp(&wf, &space, is_linear); // Time stepping loop: double current_time = 0.0; int ts = 1; do { // Perform one Runge-Kutta time step according to the selected Butcher's table. info("Runge-Kutta time step (t = %g, tau = %g, stages: %d).", current_time, time_step, bt.get_size()); bool verbose = true; if (!rk_time_step(current_time, time_step, &bt, coeff_vec, &dp, matrix_solver, verbose, NEWTON_TOL, NEWTON_MAX_ITER)) { error("Runge-Kutta time step failed, try to decrease time step size."); } // Convert coeff_vec into a new time level solution. Solution::vector_to_solution(coeff_vec, &space, &u_prev_time); // Update time. current_time += time_step; // Increase counter of time steps. ts++; } while (current_time < time_step*5); double sum = 0; for (int i = 0; i < ndof; i++) sum += coeff_vec[i]; printf("sum = %g\n", sum); int success = 1; if (fabs(sum - 3617.55) > 1e-1) success = 0; // Cleanup. delete [] coeff_vec; if (success == 1) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char *argv[]) { _F_ int ret = ERROR_SUCCESS; if (argc < 3) { fprintf(stderr, "ERROR: not enough parameters\n"); return ERR_FAILURE; } if (strcmp(argv[1], "h1") != 0 && strcmp(argv[1], "h1-ipol")) { fprintf(stderr, "ERROR: unknown type of the projection\n"); return ERR_FAILURE; } #ifdef WITH_PETSC PetscInitialize(NULL, NULL, (char *) PETSC_NULL, PETSC_NULL); #endif set_verbose(false); H1ShapesetLobattoHex shapeset; Mesh mesh; Mesh3DReader mloader; if (!mloader.load(argv[2], &mesh)) { fprintf(stderr, "ERROR: loading mesh file '%s'\n", argv[2]); return ERR_FAILURE; } #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 Word_t ne = mesh.elements.count(); // make the mesh for the ref. solution mesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ); H1Space space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_essential_bc_values(essential_bc_values); #if defined X2_Y2_Z2 order3_t o(2, 2, 2); #elif defined X3_Y3_Z3 order3_t o(3, 3, 3); #elif defined XN_YM_ZO order3_t o(2, 3, 4); #endif space.set_uniform_order(o); WeakForm wf; wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<ord_t, ord_t>, SYM, ANY); wf.add_vector_form(linear_form<double, scalar>, linear_form<ord_t, ord_t>, ANY); LinearProblem lp(&wf, &space); space.assign_dofs(); // assemble the stiffness matrix lp.assemble(&mat, &rhs); // solve the stiffness matrix solver.solve(); Solution sln(&mesh); sln.set_coeff_vector(&space, solver.get_solution()); for (Word_t idx = mesh.elements.first(); idx <= ne; idx = mesh.elements.next(idx)) { Element *e = mesh.elements[idx]; order3_t order(4, 4, 4); double error; Projection *proj; if (strcmp(argv[1], "h1") == 0) proj = new H1Projection(&sln, e, &shapeset); else if (strcmp(argv[1], "h1-ipol") == 0) proj = new H1ProjectionIpol(&sln, e, &shapeset); else return ERR_FAILURE; // error = 0.0; error += proj->get_error(H3D_REFT_HEX_NONE, -1, order); error = sqrt(error); CHECK_ERROR; // error = 0.0; error += proj->get_error(H3D_REFT_HEX_X, 20, order); error += proj->get_error(H3D_REFT_HEX_X, 21, order); error = sqrt(error); CHECK_ERROR; // error = 0.0; error += proj->get_error(H3D_REFT_HEX_Y, 22, order); error += proj->get_error(H3D_REFT_HEX_Y, 23, order); error = sqrt(error); CHECK_ERROR; // error = 0.0; error += proj->get_error(H3D_REFT_HEX_Z, 24, order); error += proj->get_error(H3D_REFT_HEX_Z, 25, order); error = sqrt(error); CHECK_ERROR; // error = 0.0; error += proj->get_error(H3D_H3D_REFT_HEX_XY, 8, order); error += proj->get_error(H3D_H3D_REFT_HEX_XY, 9, order); error += proj->get_error(H3D_H3D_REFT_HEX_XY, 10, order); error += proj->get_error(H3D_H3D_REFT_HEX_XY, 11, order); error = sqrt(error); CHECK_ERROR; // error = 0.0; error += proj->get_error(H3D_H3D_REFT_HEX_XZ, 12, order); error += proj->get_error(H3D_H3D_REFT_HEX_XZ, 13, order); error += proj->get_error(H3D_H3D_REFT_HEX_XZ, 14, order); error += proj->get_error(H3D_H3D_REFT_HEX_XZ, 15, order); error = sqrt(error); CHECK_ERROR; // error = 0.0; error += proj->get_error(H3D_H3D_REFT_HEX_YZ, 16, order); error += proj->get_error(H3D_H3D_REFT_HEX_YZ, 17, order); error += proj->get_error(H3D_H3D_REFT_HEX_YZ, 18, order); error += proj->get_error(H3D_H3D_REFT_HEX_YZ, 19, order); error = sqrt(error); CHECK_ERROR; // error = 0.0; for (int j = 0; j < 8; j++) error += proj->get_error(H3D_H3D_H3D_REFT_HEX_XYZ, j, order); error = sqrt(error); CHECK_ERROR; delete proj; } #ifdef WITH_PETSC PetscFinalize(); #endif return ret; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("cathedral.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(2, 5); // Initialize an H1 space with default shepeset. H1Space space(&mesh, bc_types, essential_bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Initialize the solution. Solution tsln; // Set the initial condition. tsln.set_const(&mesh, T_INIT); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(bilinear_form<double, double>, bilinear_form<Ord, Ord>); wf.add_matrix_form_surf(bilinear_form_surf<double, double>, bilinear_form_surf<Ord, Ord>, bdy_air); wf.add_vector_form(linear_form<double, double>, linear_form<Ord, Ord>, HERMES_ANY, &tsln); wf.add_vector_form_surf(linear_form_surf<double, double>, linear_form_surf<Ord, Ord>, bdy_air); // Initialize the FE 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); // Time stepping: int nsteps = (int)(FINAL_TIME/TAU + 0.5); bool rhs_only = false; for(int ts = 1; ts <= nsteps; ts++) { info("---- Time step %d, time %3.5f, ext_temp %g", ts, TIME, temp_ext(TIME)); // First time assemble both the stiffness matrix and right-hand side vector, // then just the right-hand side vector. if (rhs_only == false) info("Assembling the stiffness matrix and right-hand side vector."); else info("Assembling the right-hand side vector (only)."); dp.assemble(matrix, rhs, rhs_only); rhs_only = true; // Solve the linear system and if successful, obtain the solution. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &tsln); else error ("Matrix solver failed.\n"); // Update the time variable. TIME += TAU; } double sum = 0; for (int i=0; i < ndof; i++) sum += solver->get_solution()[i]; printf("coefficient sum = %g\n", sum); // Actual test. The value of 'sum' depend on the // current shapeset. If you change the shapeset, // you need to correct this number. int success = 1; if (fabs(sum - 4737.73) > 1e-1) 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[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // This is a hack I used to run the code a dozen of times when plotting convergence graphs. if (argc > 1) { if (argv[1][0] == 'e') method = IE; else if (argv[1][0] == 's') method = SDIRK; else error("what are you doing?"); } if (argc > 2) { TAU = std::atof(argv[2]); } // This is important to make sure we compare solution at exact same point in time when studying convergence. int N_STEP = std::ceil(T_FINAL / TAU); if (fabs(T_FINAL - N_STEP * TAU) > 1e-10) { error("bad choice of TAU"); } info("t_final = %g, tau = %g, n = %i", T_FINAL, TAU, N_STEP); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("../square.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(BDY_DIRICHLET, INIT_BDY_REF_NUM); // Initialize boundary conditions. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); // Enter Dirichlet boudnary values. BCValues bc_values; bc_values.add_zero(BDY_DIRICHLET); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Previous time level solution (initialized by the initial condition). Solution u_prev_time(&mesh, exact_solution); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. info("Projecting initial condition to obtain initial vector for the Newton's method."); scalar* coeff_vec = new scalar[ndof]; OGProjection::project_global(&space, &u_prev_time, coeff_vec, matrix_solver); // 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); if (method == IE) { info("IMPLICIT EULER METHOD"); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(jac), HERMES_NONSYM, HERMES_ANY); wf.add_vector_form(callback(res), HERMES_ANY, &u_prev_time); // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp(&wf, &space, is_linear); // Time stepping loop: int ts = 0; do { info("---- Time step %d, t = %g s.", ++ts, TIME); info("We are computing solution at next time step TIME+TAU = %g s.", TIME+TAU); // Perform Newton's iteration. info("Solving nonlinear problem:"); bool verbose = true; if (!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Update previous time level solution. Solution::vector_to_solution(coeff_vec, &space, &u_prev_time); // Update time. TIME = TIME + TAU; // Compute exact error. Solution exact_sln(&mesh, exact_solution); double exact_h1_error = hermes2d.calc_abs_error(&u_prev_time, &exact_sln, HERMES_H1_NORM); info("TIME: %g s.", TIME); info("Exact error in l2-norm: %g.", exact_h1_error); } while (ts < N_STEP); // Cleanup. delete [] coeff_vec; delete matrix; delete rhs; delete solver; // Hack to extract error at final time for convergence graph. Solution citrouille(&mesh, exact_solution); info("IE: tau %g, abs_error %g.", TAU, calc_abs_error(&u_prev_time, &citrouille, HERMES_H1_NORM)); } else if (method == SDIRK) { info("SDIRK22"); Solution Y1(&mesh, init_cond); Solution Y2(&mesh, init_cond); scalar* coeff_vec1 = new scalar[ndof]; OGProjection::project_global(&space, &u_prev_time, coeff_vec1, matrix_solver); scalar* coeff_vec2 = new scalar[ndof]; OGProjection::project_global(&space, &u_prev_time, coeff_vec2, matrix_solver); WeakForm wf1; wf1.add_matrix_form(callback(jac_Y), HERMES_NONSYM, HERMES_ANY); wf1.add_vector_form(callback(res_Y1), HERMES_ANY, Hermes::vector<MeshFunction*>(&u_prev_time)); WeakForm wf2; wf2.add_matrix_form(callback(jac_Y), HERMES_NONSYM, HERMES_ANY); wf2.add_vector_form(callback(res_Y2), HERMES_ANY, Hermes::vector<MeshFunction*>(&u_prev_time, &Y1)); // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp1(&wf1, &space, is_linear); DiscreteProblem dp2(&wf2, &space, is_linear); double current_time = 0.0; int ts = 0; do { info("---- Time step %d, t = %g s.", ++ts, current_time); // Compute Y1. info("Compute Y1 at t = %g s.", TIME+GAMMA*TAU); // Perform Newton's iteration for Y1. int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(&space); // Assemble the Jacobian matrix and residual vector. dp1.assemble(coeff_vec1, matrix, rhs, false); // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). rhs->change_sign(); // Calculate the l2-norm of residual vector. double res_l2_norm = hermes2d.get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(&space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, or the maximum number // of iteration has been reached, then quit. if (res_l2_norm < NEWTON_TOL || it > NEWTON_MAX_ITER) break; // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec1[i] += solver->get_solution()[i]; if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); it++; } // Store Y1. Solution::vector_to_solution(coeff_vec1, &space, &Y1); // Compute Y2. info("Compute Y2 at t = %g s.", TIME+TAU); // Perform Newton's iteration. while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(&space); // Assemble the Jacobian matrix and residual vector. dp2.assemble(coeff_vec2, matrix, rhs, false); // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). rhs->change_sign(); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(&space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, or the maximum number // of iteration has been reached, then quit. if (res_l2_norm < NEWTON_TOL || it > NEWTON_MAX_ITER) break; // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec2[i] += solver->get_solution()[i]; if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); it++; } // Store Y2. Solution::vector_to_solution(coeff_vec2, &space, &Y2); // Update previous time level solution. u_prev_time = Y2; // Update time. TIME = TIME + TAU; // Compute exact error. Solution exact_sln(&mesh, exact_solution); double exact_h1_error = hermes2d.calc_abs_error(&u_prev_time, &exact_sln, HERMES_H1_NORM); info("TIME: %g s.", TIME); info("Exact error in H1-norm: %g.", exact_h1_error); } while (ts < N_STEP); // Hack to extract error at final time for convergence graph. Solution citrouille(&mesh, exact_solution); info("SDIRK: tau %g, abs_error %g.", TAU, hermes2d.calc_abs_error(&u_prev_time, &citrouille, HERMES_H1_NORM)); } info("Coordinate ( 0.0, 0.0) u_prev_time value = %lf", u_prev_time.get_pt_value(0.0, 0.0)); info("Coordinate ( 0.3, 0.0) u_prev_time value = %lf", u_prev_time.get_pt_value(0.3, 0.0)); info("Coordinate ( 0.5, 0.0) u_prev_time value = %lf", u_prev_time.get_pt_value(0.5, 0.0)); info("Coordinate ( 0.7, 0.0) u_prev_time value = %lf", u_prev_time.get_pt_value(0.7, 0.0)); info("Coordinate ( 0.9, 0.0) u_prev_time value = %lf", u_prev_time.get_pt_value(0.9, 0.0)); double values[5]; if (method == IE) { values[0] = 2.730284; values[1] = 2.484559; values[2] = 2.047713; values[3] = 1.392445; values[4] = 0.518754; } else { values[0] = 2.717647; values[1] = 2.473058; values[2] = 2.038235; values[3] = 1.386000; values[4] = 0.516353; } int success = 1; double eps = 1e-5; if (fabs(u_prev_time.get_pt_value(0.0, 0.0) - (values[0])) > eps) { printf("Coordinate ( 0.0, 0.0) u_prev_time value = %lf\n", u_prev_time.get_pt_value(0.0, 0.0)); success = 0; } if (fabs(u_prev_time.get_pt_value(0.3, 0.0) - (values[1])) > eps) { printf("Coordinate ( 0.3, 0.0) u_prev_time value = %lf\n", u_prev_time.get_pt_value(0.3, 0.0)); success = 0; } if (fabs(u_prev_time.get_pt_value(0.5, 0.0) - (values[2])) > eps) { printf("Coordinate ( 0.5, 0.0) u_prev_time value = %lf\n", u_prev_time.get_pt_value(0.5, 0.0)); success = 0; } if (fabs(u_prev_time.get_pt_value(0.7, 0.0) - (values[3])) > eps) { printf("Coordinate ( 0.7, 0.0) u_prev_time value = %lf\n", u_prev_time.get_pt_value(0.7, 0.0)); success = 0; } if (fabs(u_prev_time.get_pt_value(0.9, 0.0) - (values[4])) > eps) { printf("Coordinate ( 0.9, 0.0) u_prev_time value = %lf\n", u_prev_time.get_pt_value(0.9, 0.0)); 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 mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_HORIZONTAL); bc_types.add_bc_neumann(BDY_VERTICAL); BCValues bc_values; bc_values.add_function(BDY_HORIZONTAL, essential_bc_values); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d", ndof); // Initialize the weak formulation. bool matrix_free = false; WeakForm wf; wf.add_matrix_form(bilinear_form, bilinear_form_ord, HERMES_SYM); wf.add_vector_form(linear_form, linear_form_ord); wf.add_vector_form_surf(linear_form_surf, linear_form_surf_ord, BDY_VERTICAL); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, &space, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); if (matrix_solver == SOLVER_AZTECOO) { ((AztecOOSolver*) solver)->set_solver(iterative_method); ((AztecOOSolver*) solver)->set_precond(preconditioner); // Using default iteration parameters (see solver/aztecoo.h). } // Initialize the solution. Solution 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 solution. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Clean up. delete solver; delete matrix; delete rhs; // View the solution and mesh. ScalarView sview("Solution", new WinGeom(0, 0, 440, 350)); sview.show(&sln); OrderView oview("Polynomial orders", new WinGeom(450, 0, 400, 350)); oview.show(&space); // Skip visualization time. cpu_time.tick(HERMES_SKIP); // Print timing information. verbose("Total running time: %g s", cpu_time.accumulated()); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(BDY_DIRICHLET, INIT_BDY_REF_NUM); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_function(BDY_DIRICHLET, essential_bc_values); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Solution for the previous time level. Solution u_prev_time; // Initialize the weak formulation. WeakForm wf; if (TIME_INTEGRATION == 1) { wf.add_matrix_form(jac_euler, jac_ord, HERMES_NONSYM, HERMES_ANY, &u_prev_time); wf.add_vector_form(res_euler, res_ord, HERMES_ANY, &u_prev_time); } else { wf.add_matrix_form(jac_cranic, jac_ord, HERMES_NONSYM, HERMES_ANY, &u_prev_time); wf.add_vector_form(res_cranic, res_ord, HERMES_ANY, &u_prev_time); } // Project the function init_cond() on the FE space // to obtain initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[Space::get_num_dofs(&space)]; info("Projecting initial condition to obtain initial vector for the Newton's method."); OGProjection::project_global(&space, init_cond, coeff_vec, matrix_solver); Solution::vector_to_solution(coeff_vec, &space, &u_prev_time); // Initialize views. ScalarView sview("Solution", new WinGeom(0, 0, 500, 400)); OrderView oview("Mesh", new WinGeom(520, 0, 450, 400)); oview.show(&space); sview.show(&u_prev_time); // Time stepping loop: double current_time = 0.0; int t_step = 1; do { info("---- Time step %d, t = %g s.", t_step, current_time); t_step++; // Initialize the FE problem. bool is_linear = false; 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); // Perform Newton's iteration. bool verbose = true; if (!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solution(coeff_vec, &space, &u_prev_time); // Cleanup. delete matrix; delete rhs; delete solver; // Update time. current_time += TAU; // Show the new time level solution. char title[100]; sprintf(title, "Solution, t = %g", current_time); sview.set_title(title); sview.show(&u_prev_time); } while (current_time < T_FINAL); delete [] coeff_vec; // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char **args) { int res = ERR_SUCCESS; #ifdef WITH_PETSC PetscInitialize(&argc, &args, (char *) PETSC_NULL, PETSC_NULL); #endif set_verbose(false); if (argc < 3) error("Not enough parameters"); HcurlShapesetLobattoHex shapeset; printf("* Loading mesh '%s'\n", args[1]); Mesh mesh; Mesh3DReader mesh_loader; if (!mesh_loader.load(args[1], &mesh)) error("Loading mesh file '%s'\n", args[1]); printf("* Setting the space up\n"); HcurlSpace space(&mesh, &shapeset); space.set_bc_types(bc_types); int o; sscanf(args[2], "%d", &o); order3_t order(o, o, o); printf(" - Setting uniform order to (%d, %d, %d)\n", o, o, o); space.set_uniform_order(order); int ndofs = space.assign_dofs(); printf(" - Number of DOFs: %d\n", ndofs); printf("* Calculating a solution\n"); #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 WeakForm wf; wf.add_matrix_form(FORM_CB(bilinear_form), SYM); wf.add_vector_form(FORM_CB(linear_form)); LinearProblem lp(&wf, &space); // assemble stiffness matrix Timer assemble_timer("Assembling stiffness matrix"); assemble_timer.start(); lp.assemble(&mat, &rhs); assemble_timer.stop(); // solve the stiffness matrix Timer solve_timer("Solving stiffness matrix"); solve_timer.start(); bool solved = solver.solve(); solve_timer.stop(); // mat.dump(stdout, "a"); // rhs.dump(stdout, "b"); if (solved) { Solution sln(&mesh); sln.set_coeff_vector(&space, solver.get_solution()); printf("* Solution:\n"); // scalar *s = sln.get_solution_vector(); // for (int i = 1; i <= ndofs; i++) { // printf(" x[% 3d] = " SCALAR_FMT "\n", i, SCALAR(s[i])); // } // output the measured values printf("%s: %s (%lf secs)\n", assemble_timer.get_name(), assemble_timer.get_human_time(), assemble_timer.get_seconds()); printf("%s: %s (%lf secs)\n", solve_timer.get_name(), solve_timer.get_human_time(), solve_timer.get_seconds()); ExactSolution ex_sln(&mesh, exact_solution); double hcurl_sln_norm = hcurl_norm(&sln); double hcurl_err_norm = hcurl_error(&sln, &ex_sln); printf(" - Hcurl solution norm: % le\n", hcurl_sln_norm); printf(" - Hcurl error norm: % le\n", hcurl_err_norm); double l2_sln_norm = l2_norm_hcurl(&sln); double l2_err_norm = l2_error_hcurl(&sln, &ex_sln); printf(" - L2 solution norm: % le\n", l2_sln_norm); printf(" - L2 error norm: % le\n", l2_err_norm); if (hcurl_err_norm > EPS || l2_err_norm > EPS) { // calculated solution is not enough precise res = ERR_FAILURE; } #if defined OUTPUT_DIR // output printf("starting output\n"); const char *of_name = OUTPUT_DIR "/solution.vtk"; FILE *ofile = fopen(of_name, "w"); if (ofile != NULL) { ExactSolution ex_sln(&mesh, exact_solution); DiffFilter eh(&sln, &ex_sln); DiffFilter eh_dx(&sln, &ex_sln, FN_DX, FN_DX); // DiffFilter eh_dy(mesh, &sln, &ex_sln, FN_DY, FN_DY); // DiffFilter eh_dz(mesh, &sln, &ex_sln, FN_DZ, FN_DZ); // GmshOutputEngine output(ofile); VtkOutputEngine output(ofile); output.out(&sln, "Uh", FN_VAL); // output.out(&sln, "Uh_0", FN_VAL_0); // output.out(&sln, "Uh_1", FN_VAL_1); // output.out(&sln, "Uh_2", FN_VAL_2); // output.vector_out(&sln, "Uh_dx", FN_DX); // output.vector_out(&sln, "Uh_dy", FN_DY); // output.vector_out(&sln, "Uh_dz", FN_DZ); // output.scalar_out(&sln, "Uh_dx_0", FN_DX_0); // output.scalar_out(&sln, "Uh_dx_1", FN_DX_1); // output.scalar_out(&sln, "Uh_dx_2", FN_DX_2); // output.out(&sln, "Uh dy", FN_DY_0); // output.out(&sln, "Uh dz", FN_DZ_0); // output.vector_out(&sln, "Uh_dx", FN_DX); // output.vector_out(&sln, "Uh_dy", FN_DY); // output.vector_out(&sln, "Uh_dz", FN_DZ); // output.scalar_out(&sln, "Uh_dx_0", FN_DX_0); // output.scalar_out(&sln, "Uh_dx_1", FN_DX_1); // output.scalar_out(&sln, "Uh_dx_2", FN_DX_2); // output.out(&sln, "Uh_dy", FN_DY_0); // output.out(&sln, "Uh_dz", FN_DZ_0); // output.out(&eh, "Eh", FN_VAL); // output.out(&eh_dx, "Eh_dx", FN_VAL); // output.out(&eh_dy, "Eh_dy"); // output.out(&eh_dz, "Eh_dz"); // output.out(&ex_sln, "U", FN_VAL); // output.out(&ex_sln, "U_dx", FN_DX); // output.out(&ex_sln, "U_dy", FN_DY); // output.out(&ex_sln, "U_dz", FN_DZ); // output.scalar_out(&ex_sln, "U_0", FN_VAL_0); // output.scalar_out(&ex_sln, "U_1", FN_VAL_1); // output.scalar_out(&ex_sln, "U_2", FN_VAL_2); // output.out(&ex_sln, "U_dy", FN_DY_0); // output.out(&ex_sln, "U_dz", FN_DZ_0); fclose(ofile); } else { warning("Can not open '%s' for writing.", of_name); } #endif } #ifdef WITH_PETSC mat.free(); rhs.free(); PetscFinalize(); #endif return res; }
int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh, basemesh; H2DReader mloader; mloader.load("square.mesh", &basemesh); // Perform initial mesh refinements. mesh.copy(&basemesh); for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(2, INIT_REF_NUM_BDY); // Create an H1 space with default shapeset. H1Space* space = new H1Space(&mesh, bc_types, essential_bc_values, P_INIT); int ndof = get_num_dofs(space); info("ndof = %d.", ndof); // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Solutions for the time stepping and the Newton's method. Solution u_prev_time; // Adapt mesh to represent initial condition with given accuracy. bool verbose = true; // Report results. double err_stop_temp = 6.0; adapt_to_exact_function(space, H2D_H1_NORM, init_cond, &selector, THRESHOLD, STRATEGY, MESH_REGULARITY, err_stop_temp, NDOF_STOP, verbose, &u_prev_time); // Initialize the weak formulation. WeakForm wf; if (TIME_INTEGRATION == 1) { wf.add_matrix_form(jac_euler, jac_ord, H2D_UNSYM, H2D_ANY, &u_prev_time); wf.add_vector_form(res_euler, res_ord, H2D_ANY, &u_prev_time); } else { wf.add_matrix_form(jac_cranic, jac_ord, H2D_UNSYM, H2D_ANY, &u_prev_time); wf.add_vector_form(res_cranic, res_ord, H2D_ANY, &u_prev_time); } // Initialize matrix solver. Matrix* mat; Vector* coeff_vec; CommonSolver* solver; init_matrix_solver(matrix_solver, ndof, mat, coeff_vec, solver); // Error estimate and discrete problem size as a function of physical time. SimpleGraph graph_time_err_est, graph_time_err_exact, graph_time_dof, graph_time_cpu; // Project the initial condition on the FE space // to obtain initial coefficient vector for the Newton's method. info("Projecting initial condition to obtain initial vector for the Newton's method."); Solution* sln_tmp = new Solution(&mesh, init_cond); // The NULL means that we do not want the result as a Solution. project_global(space, H2D_H1_NORM, sln_tmp, NULL, coeff_vec); delete sln_tmp; // Initialize views. ScalarView view("Projection of initial condition", 0, 0, 410, 300); OrderView ordview("Initial mesh", 420, 0, 350, 300); view.fix_scale_width(80); // Newton's loop on the coarse mesh. info("Solving on coarse mesh."); if (!solve_newton(space, &wf, coeff_vec, matrix_solver, NEWTON_TOL_COARSE, NEWTON_MAX_ITER, verbose)) error("Newton's method did not converge."); // Store the result in sln. Solution sln, ref_sln; sln.set_coeff_vector(space, coeff_vec); // Time stepping loop. int num_time_steps = (int)(T_FINAL/TAU + 0.5); for(int ts = 1; ts <= num_time_steps; ts++) { // Time measurement. cpu_time.tick(); // Updating current time. TIME = ts*TAU; // Periodic global derefinements. if (ts > 1 && ts % UNREF_FREQ == 0) { info("Global mesh derefinement."); mesh.copy(&basemesh); space->set_uniform_order(P_INIT); // Project fine mesh solution on the globally derefined mesh. info("---- Time step %d:", ts); info("Projecting fine mesh solution on globally derefined mesh."); // The NULL means that we do not want the coefficient vector. project_global(space, H2D_H1_NORM, &ref_sln, &sln, NULL); } // Adaptivity loop (in space): bool done = false; double space_err_est_rel, space_err_exact_rel; int as = 1; do { info("---- Time step %d, adaptivity step %d:", ts, as); // Construct globally refined reference mesh // and setup reference space. Mesh *ref_mesh = new Mesh(); ref_mesh->copy(space->get_mesh()); ref_mesh->refine_all_elements(); Space* ref_space = space->dup(ref_mesh); int order_increase = 1; ref_space->copy_orders(space, order_increase); // Calculate initial coefficient vector for Newton on the fine mesh. if (as == 1 && ts == 1) { info("Projecting coarse mesh solution to obtain initial vector on new fine mesh."); // The NULL means that we do not want the result as a Solution. project_global(ref_space, H2D_H1_NORM, &sln, NULL, coeff_vec); } else { info("Projecting previous fine mesh solution to obtain initial vector on new fine mesh."); // The NULL means that we do not want the result as a Solution. project_global(ref_space, H2D_H1_NORM, &ref_sln, NULL, coeff_vec); } // Newton's method on fine mesh info("Solving on fine mesh."); if (!solve_newton(ref_space, &wf, coeff_vec, matrix_solver, NEWTON_TOL_FINE, NEWTON_MAX_ITER, verbose)) error("Newton's method did not converge."); // Store the result in ref_sln. ref_sln.set_coeff_vector(ref_space, coeff_vec); // Calculate error estimate wrt. fine mesh solution. info("Calculating error (est)."); Adapt hp(space, H2D_H1_NORM); hp.set_solutions(&sln, &ref_sln); double space_err_est_rel = hp.calc_elem_errors(H2D_TOTAL_ERROR_REL | H2D_ELEMENT_ERROR_REL) * 100; // Calculate error wrt. exact solution. info("Calculating error (exact)."); ExactSolution exact(&mesh, exact_sol); double err_exact_abs = calc_abs_error(&sln, &exact, H2D_H1_NORM); double norm_exact = calc_norm(&exact, H2D_H1_NORM); space_err_exact_rel = err_exact_abs / norm_exact * 100; info("ndof_coarse: %d, ndof_fine: %d, space_err_est_rel: %g%%, space_err_exact_rel: %g%%", get_num_dofs(space), get_num_dofs(ref_space), space_err_est_rel, space_err_exact_rel); // If space_err_est too large, adapt the mesh. if (space_err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = hp.adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); if (get_num_dofs(space) >= NDOF_STOP) { done = true; break; } // Project the fine mesh solution on the new coarse mesh. info("Projecting fine mesh solution on coarse mesh for error calculation."); // The NULL means that we do not want the coefficient vector. project_global(space, H2D_H1_NORM, &ref_sln, &sln, NULL); as++; } } while (!done); // Visualize the solution and mesh. char title[100]; sprintf(title, "Solution, time level %d", ts); view.set_title(title); view.show(&sln); sprintf(title, "Mesh, time level %d", ts); ordview.set_title(title); ordview.show(space); // Add entries to convergence graphs. graph_time_err_est.add_values(ts*TAU, space_err_est_rel); graph_time_err_est.save("time_error_est.dat"); graph_time_err_exact.add_values(ts*TAU, space_err_exact_rel); graph_time_err_exact.save("time_error_exact.dat"); graph_time_dof.add_values(ts*TAU, get_num_dofs(space)); graph_time_dof.save("time_dof.dat"); graph_time_cpu.add_values(ts*TAU, cpu_time.accumulated()); graph_time_cpu.save("time_cpu.dat"); // Copy new time level solution into u_prev_time. u_prev_time.copy(&ref_sln); } // Wait for all views to be closed. View::wait(); return 0; }
int main() { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Create space, set Dirichlet BC, enumerate basis functions. Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ); int ndof = Space::get_num_dofs(space); info("ndof: %d", ndof); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(jacobian); wf.add_vector_form(residual); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear); // Set zero initial condition. double *coeff_vec = new double[ndof]; set_zero(coeff_vec, ndof); // 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); int it = 1; bool success = false; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp->assemble(coeff_vec, matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!(success = solver->solve())) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); it++; } info("Total running time: %g s", cpu_time.accumulated()); // Test variable. info("ndof = %d.", Space::get_num_dofs(space)); if (success) { info("Success!"); return ERROR_SUCCESS; } else { info("Failure!"); return ERROR_FAILURE; } }
int main(int argc, char **args) { // Test variable. int success_test = 1; if (argc < 3) error("Not enough parameters."); // Load the mesh. Mesh mesh; H3DReader mloader; if (!mloader.load(args[1], &mesh)) error("Loading mesh file '%s'.", args[1]); // Initialize the space according to the // command-line parameters passed. int o; sscanf(args[2], "%d", &o); Ord3 order(o, o, o); HcurlSpace space(&mesh, bc_types, NULL, order); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<Ord, Ord>, HERMES_UNSYM); wf.add_matrix_form_surf(bilinear_form_surf<double, scalar>, bilinear_form_surf<Ord, Ord>); wf.add_vector_form(linear_form<double, scalar>, linear_form<Ord, Ord>); wf.add_vector_form_surf(linear_form_surf<double, scalar>, linear_form_surf<Ord, Ord>); // Initialize the FE 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 the linear problem. info("Assembling (ndof: %d).", Space::get_num_dofs(&space)); dp.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving."); Solution sln(&mesh); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); ExactSolution ex_sln(&mesh, exact_solution); // Calculate exact error. info("Calculating exact error."); Adapt *adaptivity = new Adapt(&space, HERMES_HCURL_NORM); bool solutions_for_adapt = false; double err_exact = adaptivity->calc_err_exact(&sln, &ex_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_ABS); printf("err_exact = %lf", err_exact); if (err_exact > EPS) // Calculated solution is not precise enough. success_test = 0; // Clean up. delete matrix; delete rhs; delete solver; delete adaptivity; // Properly terminate the solver in the case of SOLVER_PETSC or SOLVER_MUMPS. finalize_solution_environment(matrix_solver); if (success_test) { info("Success!"); return ERR_SUCCESS; } else { info("Failure!"); return ERR_FAILURE; } }
/*********************************************************************************** * 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; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(Hermes::Tuple<int>(BDY_DIRICHLET_1, BDY_DIRICHLET_2, BDY_DIRICHLET_3, BDY_DIRICHLET_4)); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_zero(Hermes::Tuple<int>(BDY_DIRICHLET_1, BDY_DIRICHLET_2, BDY_DIRICHLET_3, BDY_DIRICHLET_4)); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Previous time level solution. Solution psi_prev_time(&mesh, init_cond); // Initialize the weak formulation. WeakForm wf; if(TIME_DISCR == 1) { wf.add_matrix_form(callback(J_euler), HERMES_NONSYM, HERMES_ANY); wf.add_vector_form(callback(F_euler), HERMES_ANY, &psi_prev_time); } else { wf.add_matrix_form(callback(J_cranic), HERMES_NONSYM, HERMES_ANY); wf.add_vector_form(callback(F_cranic), HERMES_ANY, &psi_prev_time); } // Initialize the FE problem. bool is_linear = false; 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); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. info("Projecting initial condition to obtain initial vector for the Newton's method."); scalar* coeff_vec = new scalar[ndof]; OGProjection::project_global(&space, &psi_prev_time, coeff_vec, matrix_solver); // Time stepping loop: int nstep = (int)(T_FINAL/TAU + 0.5); for(int ts = 1; ts <= nstep; ts++) { info("Time step %d:", ts); // Perform Newton's iteration. info("Solving nonlinear problem:"); bool verbose = true; if (!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Update previous time level solution. Solution::vector_to_solution(coeff_vec, &space, &psi_prev_time); } delete coeff_vec; delete matrix; delete rhs; delete solver; AbsFilter mag2(&psi_prev_time); int success = 1; double eps = 1e-5; double val = std::abs(mag2.get_pt_value(0.1, 0.1)); info("Coordinate ( 0.1, 0.1) psi value = %lf", val); if (fabs(val - (0.804900)) > eps) { printf("Coordinate ( 0.1, 0.1) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(0.1, -0.1)); info("Coordinate ( 0.1, -0.1) psi value = %lf", val); if (fabs(val - (0.804900)) > eps) { printf("Coordinate ( 0.1, -0.1) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(0.2, 0.1)); info("Coordinate ( 0.2, 0.1) psi value = %lf", val); if (fabs(val - (0.602930)) > eps) { printf("Coordinate ( 0.2, 0.1) psi value = %lf\n", val); success = 0; } if (success == 1) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main() { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Create coarse mesh, set Dirichlet BC, enumerate basis functions. Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ, NEQ); // Enumerate basis functions, info for user. int ndof = Space::get_num_dofs(space); info("ndof: %d", ndof); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(jacobian); wf.add_vector_form(residual); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp_coarse = new DiscreteProblem(&wf, space, is_linear); // Newton's loop on coarse mesh. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec_coarse = new double[Space::get_num_dofs(space)]; get_coeff_vector(space, coeff_vec_coarse); // Set up the solver, matrix, and rhs 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); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof_coarse = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp_coarse->assemble(coeff_vec_coarse, matrix_coarse, rhs_coarse); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs_coarse); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL_COARSE && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof_coarse; i++) rhs_coarse->set(i, -rhs_coarse->get(i)); // Solve the linear system. if(!solver_coarse->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof_coarse; i++) coeff_vec_coarse[i] += solver_coarse->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec_coarse, space); it++; } // Cleanup. delete matrix_coarse; delete rhs_coarse; delete solver_coarse; delete [] coeff_vec_coarse; delete dp_coarse; // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est; SimpleGraph graph_dof_exact, graph_cpu_exact; // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = construct_refined_space(space); // Initialize the FE problem. bool is_linear = false; DiscreteProblem* dp = new DiscreteProblem(&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); // Newton's loop on the fine mesh. info("Solving on fine mesh:"); // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(ref_space)]; get_coeff_vector(ref_space, coeff_vec); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(ref_space); // Assemble the Jacobian matrix and residual vector. dp->assemble(coeff_vec, matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(ref_space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL_REF && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec, ref_space); it++; } // Starting with second adaptivity step, obtain new coarse // mesh solution via projecting the fine mesh solution. if(as > 1) { info("Projecting the fine mesh solution onto the coarse mesh."); // Project the fine mesh solution (defined on space_ref) onto the coarse mesh (defined on space). OGProjection::project_global(space, ref_space, matrix_solver); } // Calculate element errors and total error estimate. info("Calculating error estimate."); double err_est_array[MAX_ELEM_NUM]; double err_est_rel = calc_err_est(NORM, space, ref_space, err_est_array) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space::get_num_dofs(space), Space::get_num_dofs(ref_space), err_est_rel); // Time measurement. cpu_time.tick(); // If exact solution available, also calculate exact error. if (EXACT_SOL_PROVIDED) { // Calculate element errors wrt. exact solution. double err_exact_rel = calc_err_exact(NORM, space, exact_sol, NEQ, A, B) * 100; // Info for user. info("Relative error (exact) = %g %%", err_exact_rel); // Add entry to DOF and CPU convergence graphs. graph_dof_exact.add_values(Space::get_num_dofs(space), err_exact_rel); graph_cpu_exact.add_values(cpu_time.accumulated(), 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_cpu_est.add_values(cpu_time.accumulated(), err_est_rel); // Decide whether the relative error is sufficiently small. if(err_est_rel < TOL_ERR_REL) break; // Returns updated coarse and fine meshes, with the last // coarse and fine mesh solutions on them, respectively. // The coefficient vectors and numbers of degrees of freedom // on both meshes are also updated. adapt(NORM, ADAPT_TYPE, THRESHOLD, err_est_array, space, ref_space); as++; // Plot meshes, results, and errors. adapt_plotting(space, ref_space, NORM, EXACT_SOL_PROVIDED, exact_sol); // Cleanup. delete solver; delete matrix; delete rhs; delete ref_space; delete dp; delete [] coeff_vec; } while (done == false); info("Total running time: %g s", cpu_time.accumulated()); // Save convergence graphs. graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.save("conv_cpu_est.dat"); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.save("conv_cpu_exact.dat"); // Test variable. int success_test = 1; info("N_dof = %d.", Space::get_num_dofs(space)); if (Space::get_num_dofs(space) > 40) success_test = 0; if (success_test) { info("Success!"); return ERROR_SUCCESS; } else { info("Failure!"); return ERROR_FAILURE; } }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square_quad.mesh", &mesh); // quadrilaterals // mloader.load("square_tri.mesh", &mesh); // triangles // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); // Enter Dirichlet boudnary values. BCValues bc_values; bc_values.add_function(BDY_DIRICHLET, essential_bc_values); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form), HERMES_SYM); wf.add_vector_form(callback(linear_form)); // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Set exact solution. ExactSolution exact(&mesh, fndd); // Initialize views. ScalarView sview("Solution", new WinGeom(0, 0, 440, 350)); sview.show_mesh(false); sview.fix_scale_width(50); OrderView oview("Polynomial orders", new WinGeom(450, 0, 420, 350)); // DOF and CPU convergence graphs. SimpleGraph graph_dof, graph_cpu, graph_dof_exact, graph_cpu_exact; // 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); // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. If successful, obtain the solution. Solution ref_sln; 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 fine mesh solution onto the coarse mesh. Solution sln; info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // View the coarse mesh solution and polynomial orders. sview.show(&sln); oview.show(&space); // 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, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100; // Calculate exact error. solutions_for_adapt = false; double err_exact_rel = adaptivity->calc_err_exact(&sln, &exact, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 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); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof.save("conv_dof_est.dat"); graph_cpu.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu.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 too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if (done == false) as++; } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; delete dp; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(1,INIT_BDY_REF_NUM); // Create an H1 space with default shapeset. H1Space space(&mesh, bc_types, essential_bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(jac), HERMES_UNSYM, HERMES_ANY); wf.add_vector_form(callback(res), HERMES_ANY); // Initialize the FE problem. bool is_linear = false; 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 solution. Solution sln; // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. info("Projecting to obtain initial vector for the Newton's method."); scalar* coeff_vec = new scalar[Space::get_num_dofs(&space)] ; Solution* init_sln = new Solution(); init_sln->set_const(&mesh, INIT_COND_CONST); OGProjection::project_global(&space, init_sln, coeff_vec, matrix_solver); delete init_sln; // Perform Newton's iteration. int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(&space); // Assemble the Jacobian matrix and residual vector. dp.assemble(coeff_vec, matrix, rhs, false); // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for (int i = 0; i < ndof; i++) rhs->set(i, -rhs->get(i)); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(&space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, or the maximum number // of iteration has been reached, then quit. if (res_l2_norm < NEWTON_TOL || it > NEWTON_MAX_ITER) break; // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); it++; } // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solution(coeff_vec, &space, &sln); // Cleanup. delete [] coeff_vec; delete matrix; delete rhs; delete solver; // Visualise the solution and mesh. ScalarView s_view("Solution", new WinGeom(0, 0, 440, 350)); s_view.show_mesh(false); s_view.show(&sln); OrderView o_view("Mesh", new WinGeom(450, 0, 400, 350)); o_view.show(&space); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); //mloader.load("square-tri.mesh", &mesh); // Perform initial mesh refinements. for (int i=0; i<INIT_REF; i++) mesh.refine_all_elements(); // Create an L2 space with default shapeset. L2Space space(&mesh, bc_types, NULL, Ord2(P_H, P_V)); int ndof = Space::get_num_dofs(&space); info("ndof = %d", ndof); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form)); wf.add_vector_form(callback(linear_form)); wf.add_matrix_form_surf(callback(bilinear_form_boundary), H2D_DG_BOUNDARY_EDGE); wf.add_vector_form_surf(callback(linear_form_boundary), H2D_DG_BOUNDARY_EDGE); wf.add_matrix_form_surf(callback(bilinear_form_interface), H2D_DG_INNER_EDGE); // Initialize the FE 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). } // Initialize the solution. Solution 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 solution. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Clean up. delete solver; delete matrix; delete rhs; // Visualize the solution. ScalarView view1("Solution", new WinGeom(860, 0, 400, 350)); view1.show(&sln); // Wait for all views to be closed. View::wait(); return 0; }