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); // 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_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); // Initialize coarse and reference mesh solution. Solution sln, ref_sln; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est; // 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 on the coarse mesh."); scalar* coeff_vec_coarse = new scalar[Space::get_num_dofs(&space)] ; Solution* init_sln = new Solution(&mesh, init_cond); OGProjection::project_global(&space, init_sln, coeff_vec_coarse, matrix_solver); delete init_sln; // Newton's loop on the coarse mesh. This is needed to obtain a good // starting point for the Newton's method on the reference 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."); // 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; // 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 discrete problem on the reference mesh. DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); // Initialize matrix solver. 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 on the reference mesh. scalar* coeff_vec = new scalar[Space::get_num_dofs(ref_space)]; if (as == 1) { // In the first step, project the coarse mesh solution. info("Projecting coarse mesh solution to obtain initial vector on new fine mesh."); OGProjection::project_global(ref_space, &sln, coeff_vec, matrix_solver); } else { // In all other steps, project the previous fine mesh solution. info("Projecting previous fine mesh solution to obtain initial 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:"); if (!solve_newton(coeff_vec, dp, solver, matrix, rhs, NEWTON_TOL_FINE, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution ref_sln. Solution::vector_to_solution(coeff_vec, ref_space, &ref_sln); // Project the fine mesh solution on the coarse mesh. if (as > 1) { info("Projecting reference solution on new coarse mesh for error calculation."); 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_est.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu_est.save("conv_cpu_est.dat"); // If err_est_rel too large, adapt the mesh. if (err_est_rel < 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; break; } // Project last fine mesh solution on the new coarse mesh // to obtain new coars emesh solution. info("Projecting reference solution on new coarse mesh for error calculation."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); } // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; delete ref_space; delete dp; delete [] coeff_vec; as++; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); int ndof = Space::get_num_dofs(&space); printf("ndof allowed = %d\n", 400); printf("ndof actual = %d\n", ndof); if (ndof < 400) { // ndofs was 389 at the time this test was created. 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("lshape.mesh", &mesh); // quadrilaterals // Perform initial mesh refinement. 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); // 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); // 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 for each solution component. 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()); int ndof = Space::get_num_dofs(&space); int n_dof_allowed = 660; printf("n_dof_actual = %d\n", ndof); printf("n_dof_allowed = %d\n", n_dof_allowed); if (ndof <= n_dof_allowed) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinement. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); //mesh.refine_towards_vertex(3, 5); // Define exact solution. CustomExactSolution exact_sln(&mesh); // Initialize the weak formulation. DefaultWeakFormLaplace wf; // Initialize boundary conditions DefaultEssentialBCNonConst bc_essential("Bdy", &exact_sln); EssentialBCs bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space space(&mesh, &bcs, P_INIT); // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. ScalarView sview("Solution", new WinGeom(0, 0, 440, 350)); sview.show_mesh(false); OrderView oview("Polynomial orders", new WinGeom(450, 0, 410, 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 = Space::construct_refined_space(&space); int ndof_ref = Space::get_num_dofs(ref_space); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize reference problem. info("Solving on reference mesh."); DiscreteProblem dp(&wf, ref_space); // Time measurement. cpu_time.tick(); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof_ref]; memset(coeff_vec, 0, ndof_ref * sizeof(scalar)); // Perform Newton's iteration. if (!hermes2d.solve_newton(coeff_vec, &dp, solver, matrix, rhs)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution ref_sln; Solution::vector_to_solution(coeff_vec, ref_space, &ref_sln); // 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); double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100; // Calculate exact error. double err_exact_rel = hermes2d.calc_rel_error(&sln, &exact_sln, HERMES_H1_NORM) * 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 [] coeff_vec; delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; } 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[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements. mesh.refine_all_elements(); // Initialize boundary conditions. CustomEssentialBCNonConst bc_essential(BDY_HORIZONTAL); EssentialBCs bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space space(&mesh, &bcs, P_INIT); int ndof = space.get_num_dofs(); info("ndof = %d", ndof); // Initialize the weak formulation. CustomWeakFormGeneral wf; // Initialize coarse and reference mesh solution. Solution sln, ref_sln; // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. ScalarView sview("Solution", new WinGeom(0, 0, 440, 350)); 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; // 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 = 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); // Assemble reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); 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"); // Time measurement. cpu_time.tick(); // 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); // 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."); Adapt* adaptivity = new Adapt(&space); double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 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_rel 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); } 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; // Increase counter. as++; } 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(&ref_sln); // 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; MeshReaderH2D mloader; mloader.load("square.mesh", &mesh); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, P_INIT); // Initialize the weak formulation. WeakForm<double> wf_dummy; // Initialize coarse and reference mesh solution. Solution<double> sln; ExactSolutionCustom* ref_sln = NULL; // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. ScalarView sview("Scalar potential Phi", new WinGeom(0, 0, 610, 300)); sview.fix_scale_width(40); sview.show_mesh(false); OrderView oview("Mesh", new WinGeom(620, 0, 600, 300)); // DOF and CPU convergence graphs. SimpleGraph graph_dof, graph_cpu; // Adapt<double>ivity loop: int as = 1; bool done = false; do { info("---- Adapt<double>ivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space<double>* ref_space = Space<double>::construct_refined_space(&space); // Assign the function f() to the fine mesh. info("Assigning f() to the fine mesh."); if(ref_sln != NULL) delete ref_sln; ref_sln = new ExactSolutionCustom(ref_space->get_mesh()); // Time measurement. cpu_time.tick(); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection<double>::project_global(&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 exact error."); Adapt<double>* adaptivity = new Adapt<double>(&space); // Note: the error estimate is now equal to the exact error. double err_exact_rel = adaptivity->calc_err_est(&sln, ref_sln) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, err_exact_rel: %g%%", Space<double>::get_num_dofs(&space), Space<double>::get_num_dofs(ref_space), err_exact_rel); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(Space<double>::get_num_dofs(&space), err_exact_rel); graph_dof.save("conv_dof.dat"); graph_cpu.add_values(cpu_time.accumulated(), err_exact_rel); graph_cpu.save("conv_cpu.dat"); // If err_exact_rel too large, adapt the mesh. if (err_exact_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<double>::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete adaptivity; if (done == false) delete ref_space->get_mesh(); delete ref_space; } 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(ref_sln); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { GalerkinMethod method; CandList CAND_LIST; int P_INIT; int ORDER_INCREASE; int n_dof_allowed; int iter_allowed; std::string arg = (argc == 1) ? "CG" : argv[1]; if (arg == "CG") { method = CG; CAND_LIST = H2D_HP_ANISO; P_INIT = 1; ORDER_INCREASE = 1; n_dof_allowed = 7; iter_allowed = 3; } else if (arg == "SUPG") { method = CG_STAB_SUPG; CAND_LIST = H2D_H_ANISO; P_INIT = 1; ORDER_INCREASE = 0; n_dof_allowed = 190; iter_allowed = 11; } else if (arg == "GLS_1") { method = CG_STAB_GLS_1; CAND_LIST = H2D_H_ANISO; P_INIT = 1; ORDER_INCREASE = 0; n_dof_allowed = 195; iter_allowed = 12; } else if (arg == "GLS_2") { method = CG_STAB_GLS_2; CAND_LIST = H2D_H_ANISO; P_INIT = 2; ORDER_INCREASE = 0; n_dof_allowed = 80; iter_allowed = 4; } else if (arg == "SGS") { method = CG_STAB_SGS; CAND_LIST = H2D_H_ANISO; P_INIT = 1; ORDER_INCREASE = 0; n_dof_allowed = 430; iter_allowed = 14; } else if (arg == "SGS_ALT") { method = CG_STAB_SGS_ALT; CAND_LIST = H2D_H_ANISO; P_INIT = 1; ORDER_INCREASE = 0; n_dof_allowed = 190; iter_allowed = 11; } else if (arg == "DG") { method = DG; CAND_LIST = H2D_HP_ANISO; P_INIT = 0; ORDER_INCREASE = 1; n_dof_allowed = 0;//TODO iter_allowed = 0;//TODO error("DG option not yet supported."); } else { error("Invalid discretization method."); } // Instantiate a class with global functions. Hermes2D hermes2d; info("Discretization method: %s", method_names[method].c_str()); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("../square_quad.mesh", &mesh); // Perform initial mesh refinement. for (int i=0; i<INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary("outflow", INIT_BDY_REF_NUM); //mesh.refine_towards_boundary(NONZERO_DIRICHLET, INIT_BDY_REF_NUM/2); // Create a space and refinement selector appropriate for the selected discretization method. Space *space; ProjBasedSelector *selector; ProjNormType norm; WeaklyImposableBC bc_fn(Hermes::vector<std::string>("nonzero_Dirichlet"), new NonzeroBoundaryValues(&mesh)); WeaklyImposableBC bc_zero(Hermes::vector<std::string>("zero_Dirichlet", "outflow"), 0.0); EssentialBCs bcs(Hermes::vector<EssentialBoundaryCondition*>(&bc_fn, &bc_zero)); // Initialize the weak formulation. WeakForm *wf; if (method != DG) { space = new H1Space(&mesh, &bcs, P_INIT); selector = new L2ProjBasedSelector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); norm = HERMES_L2_NORM; // WARNING: In order to compare the errors with DG, L2 norm should be here. wf = new CustomWeakFormContinuousGalerkin(method, EPSILON); } else { space = new L2Space(&mesh, P_INIT); selector = new L2ProjBasedSelector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); norm = HERMES_L2_NORM; // Disable weighting of refinement candidates. selector->set_error_weights(1, 1, 1); wf = new CustomWeakFormDiscontinuousGalerkin(bcs, EPSILON); } // Initialize coarse and reference mesh solution. Solution sln, ref_sln; // Set exact solution. CustomExactSolution exact(&mesh, EPSILON); // DOF and CPU convergence graphs initialization. SimpleGraph graph_dof, graph_cpu, graph_dof_exact, graph_cpu_exact; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Setup data structures for solving the discrete algebraic problem. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Adaptivity loop: int as = 1; bool done = false; Space* actual_sln_space; do { info("---- Adaptivity step %d:", as); if (STRATEGY == -1) actual_sln_space = space; else // Construct globally refined reference mesh and setup reference space. actual_sln_space = Space::construct_refined_space(space, ORDER_INCREASE); int ndof_fine = Space::get_num_dofs(actual_sln_space); int ndof_coarse = Space::get_num_dofs(space); // Solve the linear system. If successful, obtain the solution. info("Solving on the refined mesh (%d NDOF).", ndof_fine); DiscreteProblem dp(wf, actual_sln_space); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof_fine]; memset(coeff_vec, 0, ndof_fine * sizeof(scalar)); // Perform Newton's iteration. if (!hermes2d.solve_newton(coeff_vec, &dp, solver, matrix, rhs)) error("Newton's iteration failed."); Solution::vector_to_solution(solver->get_solution(), actual_sln_space, &ref_sln); // Calculate exact error. double err_exact_rel = hermes2d.calc_rel_error(&ref_sln, &exact, norm) * 100; info("ndof_fine: %d, err_exact_rel: %g%%", ndof_fine, err_exact_rel); if (STRATEGY == -1) done = true; // Do not adapt. else { Adapt* adaptivity = new Adapt(space, norm); // 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, norm); // Calculate element errors and total error estimate. info("Calculating error estimate."); bool solutions_for_adapt = true; double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln, solutions_for_adapt) * 100; // Report results. info("ndof_coarse: %d, err_est_rel: %g%%", ndof_coarse, err_est_rel); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(ndof_coarse, 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(ndof_coarse, 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"); // Skip graphing time. cpu_time.tick(HERMES_SKIP); // If err_est too large, adapt the mesh. if (err_exact_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. if(done == false) { delete actual_sln_space->get_mesh(); delete actual_sln_space; } delete adaptivity; } } while (done == false); int ndof = Space::get_num_dofs(space); if (space != actual_sln_space) { delete space; delete actual_sln_space->get_mesh(); } delete actual_sln_space; delete solver; delete matrix; delete rhs; delete selector; verbose("Total running time: %g s", cpu_time.accumulated()); // Test number of DOF. printf("n_dof_actual = %d\n", ndof); printf("n_dof_allowed = %d\n", n_dof_allowed); if (ndof <= n_dof_allowed) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } // Test number of iterations. printf("iterations = %d\n", as); printf("iterations allowed = %d\n", iter_allowed); if (as <= iter_allowed) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char **args) { // Test variable. int success_test = 1; if (argc < 2) 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. #if defined NONLIN1 Ord3 order(1, 1, 1); #else Ord3 order(2, 2, 2); #endif H1Space space(&mesh, bc_types, essential_bc_values, order); #if defined NONLIN2 // Do L2 projection of zero function. WeakForm proj_wf; proj_wf.add_matrix_form(biproj_form<double, scalar>, biproj_form<Ord, Ord>, HERMES_SYM); proj_wf.add_vector_form(liproj_form<double, scalar>, liproj_form<Ord, Ord>); bool is_linear = true; DiscreteProblem lp(&proj_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_proj = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the preconditioner in the case of SOLVER_AZTECOO. if (matrix_solver == SOLVER_AZTECOO) { ((AztecOOSolver*) solver_proj)->set_solver(iterative_method); ((AztecOOSolver*) solver_proj)->set_precond(preconditioner); // Using default iteration parameters (see solver/aztecoo.h). } // Assemble the linear problem. info("Assembling (ndof: %d).", Space::get_num_dofs(&space)); lp.assemble(matrix, rhs); // Solve the linear system. info("Solving."); if(!solver_proj->solve()) error ("Matrix solver failed.\n"); delete matrix; delete rhs; #endif // Initialize the weak formulation. WeakForm wf(1); wf.add_matrix_form(0, 0, jacobi_form<double, scalar>, jacobi_form<Ord, Ord>, HERMES_NONSYM); wf.add_vector_form(0, resid_form<double, scalar>, resid_form<Ord, Ord>); // Initialize the FE problem. #if defined NONLIN2 is_linear = false; #else bool is_linear = false; #endif DiscreteProblem dp(&wf, &space, is_linear); NoxSolver solver(&dp); #if defined NONLIN2 solver.set_init_sln(solver_proj->get_solution()); delete solver_proj; #endif solver.set_conv_iters(10); info("Solving."); Solution sln(&mesh); if(solver.solve()) Solution::vector_to_solution(solver.get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); Solution ex_sln(&mesh); #ifdef NONLIN1 ex_sln.set_const(100.0); #else ex_sln.set_exact(exact_solution); #endif // Calculate exact error. info("Calculating exact error."); Adapt *adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = false; double err_exact = adaptivity->calc_err_exact(&sln, &ex_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_ABS); if (err_exact > EPS) // Calculated solution is not precise enough. success_test = 0; if (success_test) { info("Success!"); return ERR_SUCCESS; } else { info("Failure!"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh u_mesh, v_mesh; H2DReader mloader; mloader.load("../square.mesh", &u_mesh); if (MULTI == false) u_mesh.refine_towards_boundary("Outer", INIT_REF_BDY); // Create initial mesh (master mesh). v_mesh.copy(&u_mesh); // Initial mesh refinements in the v_mesh towards the boundary. if (MULTI == true) v_mesh.refine_towards_boundary("Outer", INIT_REF_BDY); // Set exact solutions. ExactSolutionFitzHughNagumo1 exact_u(&u_mesh); ExactSolutionFitzHughNagumo2 exact_v(&v_mesh, K); // Define right-hand sides. CustomRightHandSide1 rhs_1(K, D_u, SIGMA); CustomRightHandSide2 rhs_2(K, D_v); // Initialize the weak formulation. WeakFormFitzHughNagumo wf(&rhs_1, &rhs_2); // Initialize boundary conditions DefaultEssentialBCConst bc_u("Outer", 0.0); EssentialBCs bcs_u(&bc_u); DefaultEssentialBCConst bc_v("Outer", 0.0); EssentialBCs bcs_v(&bc_v); // Create H1 spaces with default shapeset for both displacement components. H1Space u_space(&u_mesh, &bcs_u, P_INIT_U); H1Space v_space(MULTI ? &v_mesh : &u_mesh, &bcs_v, P_INIT_V); // Initialize coarse and reference mesh solutions. Solution u_sln, v_sln, u_ref_sln, v_ref_sln; // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est, graph_dof_exact, graph_cpu_exact; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Hermes::vector<Space *>* ref_spaces = Space::construct_refined_spaces(Hermes::vector<Space *>(&u_space, &v_space)); int ndof_ref = Space::get_num_dofs(Hermes::vector<Space *>(&u_space, &v_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); // Initialize reference problem. info("Solving on reference mesh."); DiscreteProblem* dp = new DiscreteProblem(&wf, *ref_spaces); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof_ref]; memset(coeff_vec, 0, ndof_ref * sizeof(scalar)); // Perform Newton's iteration. if (!hermes2d.solve_newton(coeff_vec, dp, solver, matrix, rhs)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solutions(coeff_vec, *ref_spaces, Hermes::vector<Solution *>(&u_ref_sln, &v_ref_sln)); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection::project_global(Hermes::vector<Space *>(&u_space, &v_space), Hermes::vector<Solution *>(&u_ref_sln, &v_ref_sln), Hermes::vector<Solution *>(&u_sln, &v_sln), matrix_solver); // Calculate element errors. info("Calculating error estimate and exact error."); Adapt* adaptivity = new Adapt(Hermes::vector<Space *>(&u_space, &v_space)); // Calculate error estimate for each solution component and the total error estimate. Hermes::vector<double> err_est_rel; double err_est_rel_total = adaptivity->calc_err_est(Hermes::vector<Solution *>(&u_sln, &v_sln), Hermes::vector<Solution *>(&u_ref_sln, &v_ref_sln), &err_est_rel) * 100; // Calculate exact error for each solution component and the total exact error. Hermes::vector<double> err_exact_rel; bool solutions_for_adapt = false; double err_exact_rel_total = adaptivity->calc_err_exact(Hermes::vector<Solution *>(&u_sln, &v_sln), Hermes::vector<Solution *>(&exact_u, &exact_v), &err_exact_rel, solutions_for_adapt) * 100; // Time measurement. cpu_time.tick(); // Report results. info("ndof_coarse[0]: %d, ndof_fine[0]: %d", u_space.Space::get_num_dofs(), (*ref_spaces)[0]->Space::get_num_dofs()); info("err_est_rel[0]: %g%%, err_exact_rel[0]: %g%%", err_est_rel[0]*100, err_exact_rel[0]*100); info("ndof_coarse[1]: %d, ndof_fine[1]: %d", v_space.Space::get_num_dofs(), (*ref_spaces)[1]->Space::get_num_dofs()); info("err_est_rel[1]: %g%%, err_exact_rel[1]: %g%%", err_est_rel[1]*100, err_exact_rel[1]*100); info("ndof_coarse_total: %d, ndof_fine_total: %d", Space::get_num_dofs(Hermes::vector<Space *>(&u_space, &v_space)), Space::get_num_dofs(*ref_spaces)); info("err_est_rel_total: %g%%, err_est_exact_total: %g%%", err_est_rel_total, err_exact_rel_total); // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space::get_num_dofs(Hermes::vector<Space *>(&u_space, &v_space)), err_est_rel_total); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel_total); graph_cpu_est.save("conv_cpu_est.dat"); graph_dof_exact.add_values(Space::get_num_dofs(Hermes::vector<Space *>(&u_space, &v_space)), err_exact_rel_total); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel_total); graph_cpu_exact.save("conv_cpu_exact.dat"); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(Hermes::vector<RefinementSelectors::Selector *>(&selector, &selector), THRESHOLD, STRATEGY, MESH_REGULARITY); } if (Space::get_num_dofs(Hermes::vector<Space *>(&u_space, &v_space)) >= NDOF_STOP) done = true; // Clean up. delete [] coeff_vec; delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) for(unsigned int i = 0; i < ref_spaces->size(); i++) delete (*ref_spaces)[i]->get_mesh(); delete ref_spaces; delete dp; // Increase counter. as++; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); int ndof = Space::get_num_dofs(Hermes::vector<Space *>(&u_space, &v_space)); printf("ndof allowed = %d\n", 580); printf("ndof actual = %d\n", ndof); if (ndof < 580) { // ndofs was 574 at the time this test was created printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char* args[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("square.mesh", mesh); // Perform initial mesh refinement. for (int i = 0; i < INIT_REF; i++) mesh->refine_all_elements(); // Create an L2 space. SpaceSharedPtr<double> fine_space(new L2Space<double>(mesh, USE_TAYLOR_SHAPESET ? std::max(P_INIT, 2) : P_INIT, (USE_TAYLOR_SHAPESET ? (Shapeset*)(new L2ShapesetTaylor) : (Shapeset*)(new L2ShapesetLegendre)))); // Initialize refinement selector. L2ProjBasedSelector<double> selector(CAND_LIST); selector.set_error_weights(1., 1., 1.); MeshFunctionSharedPtr<double> sln(new Solution<double>); MeshFunctionSharedPtr<double> refsln(new Solution<double>); // Initialize the weak formulation. WeakFormSharedPtr<double> wf(new CustomWeakForm("Bdy_bottom_left", mesh)); ScalarView view1("Solution", new WinGeom(900, 0, 450, 350)); view1.fix_scale_width(60); // Initialize linear solver. Hermes::Hermes2D::LinearSolver<double> linear_solver; linear_solver.set_weak_formulation(wf); adaptivity.set_space(fine_space); int as = 1; bool done = false; do { // Construct globally refined reference mesh // and setup reference space-> Mesh::ReferenceMeshCreator ref_mesh_creator(mesh); MeshSharedPtr ref_mesh = ref_mesh_creator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refspace_creator(fine_space, ref_mesh, 0); SpaceSharedPtr<double> refspace = refspace_creator.create_ref_space(); try { linear_solver.set_space(refspace); linear_solver.solve(); if (USE_TAYLOR_SHAPESET) { PostProcessing::VertexBasedLimiter limiter(refspace, linear_solver.get_sln_vector(), P_INIT); refsln = limiter.get_solution(); } else { Solution<double>::vector_to_solution(linear_solver.get_sln_vector(), refspace, refsln); } view1.show(refsln); OGProjection<double>::project_global(fine_space, refsln, sln, HERMES_L2_NORM); } catch (Exceptions::Exception& e) { std::cout << e.info(); } catch (std::exception& e) { std::cout << e.what(); } // Calculate element errors and total error estimate. errorCalculator.calculate_errors(sln, refsln); double err_est_rel = errorCalculator.get_total_error_squared() * 100; std::cout << "Error: " << err_est_rel << "%." << std::endl; // If err_est_rel too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else done = adaptivity.adapt(&selector); as++; } while (done == false); // Wait for keyboard or mouse input. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh u_mesh, v_mesh; H2DReader mloader; mloader.load("square.mesh", &u_mesh); if (MULTI == false) u_mesh.refine_towards_boundary(1, INIT_REF_BDY); // Create initial mesh (master mesh). v_mesh.copy(&u_mesh); // Initial mesh refinements in the v_mesh towards the boundary. if (MULTI == true) v_mesh.refine_towards_boundary(1, INIT_REF_BDY); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(OUTER_BDY); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_zero(OUTER_BDY); // Create H1 spaces with default shapeset for both displacement components. H1Space u_space(&u_mesh, &bc_types, &bc_values, P_INIT_U); H1Space v_space(MULTI ? &v_mesh : &u_mesh, &bc_types, &bc_values, P_INIT_V); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, callback(bilinear_form_0_0)); wf.add_matrix_form(0, 1, callback(bilinear_form_0_1)); wf.add_matrix_form(1, 0, callback(bilinear_form_1_0)); wf.add_matrix_form(1, 1, callback(bilinear_form_1_1)); wf.add_vector_form(0, linear_form_0, linear_form_0_ord); wf.add_vector_form(1, linear_form_1, linear_form_1_ord); // Initialize coarse and reference mesh solutions. Solution u_sln, v_sln, u_ref_sln, v_ref_sln; // Initialize exact solutions. ExactSolution u_exact(&u_mesh, uexact); ExactSolution v_exact(&v_mesh, vexact); // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est, graph_dof_exact, graph_cpu_exact; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Hermes::Tuple<Space *>* ref_spaces = construct_refined_spaces(Hermes::Tuple<Space *>(&u_space, &v_space)); // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, *ref_spaces, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. If successful, obtain the solutions. if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), *ref_spaces, Hermes::Tuple<Solution *>(&u_ref_sln, &v_ref_sln)); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection::project_global(Hermes::Tuple<Space *>(&u_space, &v_space), Hermes::Tuple<Solution *>(&u_ref_sln, &v_ref_sln), Hermes::Tuple<Solution *>(&u_sln, &v_sln), matrix_solver); // Calculate element errors. info("Calculating error estimate and exact error."); Adapt* adaptivity = new Adapt(Hermes::Tuple<Space *>(&u_space, &v_space), Hermes::Tuple<ProjNormType>(HERMES_H1_NORM, HERMES_H1_NORM)); // Calculate error estimate for each solution component and the total error estimate. Hermes::Tuple<double> err_est_rel; bool solutions_for_adapt = true; double err_est_rel_total = adaptivity->calc_err_est(Hermes::Tuple<Solution *>(&u_sln, &v_sln), Hermes::Tuple<Solution *>(&u_ref_sln, &v_ref_sln), solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_ABS, &err_est_rel) * 100; // Calculate exact error for each solution component and the total exact error. Hermes::Tuple<double> err_exact_rel; solutions_for_adapt = false; double err_exact_rel_total = adaptivity->calc_err_exact(Hermes::Tuple<Solution *>(&u_sln, &v_sln), Hermes::Tuple<Solution *>(&u_exact, &v_exact), solutions_for_adapt, HERMES_TOTAL_ERROR_REL, &err_exact_rel) * 100; // Time measurement. cpu_time.tick(); // Report results. info("ndof_coarse[0]: %d, ndof_fine[0]: %d", u_space.Space::get_num_dofs(), (*ref_spaces)[0]->Space::get_num_dofs()); info("err_est_rel[0]: %g%%, err_exact_rel[0]: %g%%", err_est_rel[0]*100, err_exact_rel[0]*100); info("ndof_coarse[1]: %d, ndof_fine[1]: %d", v_space.Space::get_num_dofs(), (*ref_spaces)[1]->Space::get_num_dofs()); info("err_est_rel[1]: %g%%, err_exact_rel[1]: %g%%", err_est_rel[1]*100, err_exact_rel[1]*100); info("ndof_coarse_total: %d, ndof_fine_total: %d", Space::get_num_dofs(Hermes::Tuple<Space *>(&u_space, &v_space)), Space::get_num_dofs(*ref_spaces)); info("err_est_rel_total: %g%%, err_est_exact_total: %g%%", err_est_rel_total, err_exact_rel_total); // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space::get_num_dofs(Hermes::Tuple<Space *>(&u_space, &v_space)), err_est_rel_total); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel_total); graph_cpu_est.save("conv_cpu_est.dat"); graph_dof_exact.add_values(Space::get_num_dofs(Hermes::Tuple<Space *>(&u_space, &v_space)), err_exact_rel_total); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel_total); graph_cpu_exact.save("conv_cpu_exact.dat"); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(Hermes::Tuple<RefinementSelectors::Selector *>(&selector, &selector), THRESHOLD, STRATEGY, MESH_REGULARITY); } if (Space::get_num_dofs(Hermes::Tuple<Space *>(&u_space, &v_space)) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) for(unsigned int i = 0; i < ref_spaces->size(); i++) delete (*ref_spaces)[i]->get_mesh(); delete ref_spaces; delete dp; // Increase counter. as++; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); int ndof = Space::get_num_dofs(Hermes::Tuple<Space *>(&u_space, &v_space)); printf("ndof allowed = %d\n", 1040); printf("ndof actual = %d\n", ndof); if (ndof < 1040) { // ndofs was 1030 at the time this test was created 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, 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(BDY_TOP, INIT_REF_NUM_BDY); basemesh.copy(&mesh); // Initialize boundary conditions. BCTypes bc_types; bc_types.add_bc_dirichlet(Hermes::vector<int>(BDY_TOP, BDY_REST)); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_function(Hermes::vector<int>(BDY_TOP, BDY_REST), 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); // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Solutions for the time stepping and adaptivity. Solution sln_prev_time, sln, ref_sln; // Initialize sln_prev_time. // Note: only if adaptivity to initial condition is not done. sln_prev_time.set_exact(&mesh, init_cond); // Initialize the weak formulation. WeakForm wf; if (TIME_INTEGRATION == 1) { wf.add_matrix_form(jac_euler, jac_ord, HERMES_NONSYM, HERMES_ANY, &sln_prev_time); wf.add_vector_form(res_euler, res_ord, HERMES_ANY, &sln_prev_time); } else { wf.add_matrix_form(jac_cranic, jac_ord, HERMES_NONSYM, HERMES_ANY, &sln_prev_time); wf.add_vector_form(res_cranic, res_ord, HERMES_ANY, &sln_prev_time); } // 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 coefficient vector for Newton on coarse mesh."); scalar* coeff_vec_coarse = new scalar[Space::get_num_dofs(&space)]; OGProjection::project_global(&space, init_cond, coeff_vec_coarse, matrix_solver); // Newton's loop on the coarse mesh. info("Solving on coarse mesh."); // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp_coarse(&wf, &space, is_linear); // Set up the solver_coarse, matrix_coarse, and rhs_coarse according to the solver_coarse 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); // Perform Newton's iteration. 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."); // Translate the resulting coefficient vector into the actual solution. Solution::vector_to_solution(coeff_vec_coarse, &space, &sln); // Clean up. delete [] coeff_vec_coarse; delete rhs_coarse; delete matrix_coarse; delete solver_coarse; // 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); } // Spatial adaptivity loop. Note; sln_prev_time must not be changed during // spatial adaptivity. bool done = false; int as = 1; do { info("---- Time step %d, adaptivity step %d:", ts, as); // Construct globally refined reference mesh // and setup reference space. Space* ref_space = Space::construct_refined_space(&space); scalar* coeff_vec = new scalar[Space::get_num_dofs(ref_space)]; // 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."); OGProjection::project_global(ref_space, &sln, coeff_vec, matrix_solver); } else { info("Projecting previous fine mesh solution to obtain initial vector on new fine mesh."); OGProjection::project_global(ref_space, &ref_sln, coeff_vec, matrix_solver); delete ref_sln.get_mesh(); } // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp(&wf, ref_space, is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Perform Newton's iteration. info("Solving on fine mesh."); if (!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL_FINE, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the actual solutions. Solution::vector_to_solutions(coeff_vec, ref_space, &ref_sln); // Project the fine mesh solution on the coarse mesh. info("Projecting fine mesh solution on coarse mesh for error calculation."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Calculate element errors. info("Calculating error estimate and exact error."); Adapt* adaptivity = new Adapt(&space); // Calculate error estimate wrt. fine mesh solution. double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100; // Calculate error wrt. exact solution. ExactSolution exact(&mesh, exact_sol); bool solutions_for_adapt = false; double err_exact_rel = adaptivity->calc_err_exact(&sln, &exact, solutions_for_adapt) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space)); info("space_err_est_rel: %g%%, space_err_exact_rel: %g%%", err_est_rel, err_exact_rel); // Add entries to convergence graphs. graph_time_err_est.add_values(ts*TAU, err_est_rel); graph_time_err_est.save("time_error_est.dat"); graph_time_err_exact.add_values(ts*TAU, err_exact_rel); graph_time_err_exact.save("time_error_exact.dat"); graph_time_dof.add_values(ts*TAU, Space::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"); // If space_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); if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; else as++; } // Cleanup. delete [] coeff_vec; delete solver; delete matrix; delete rhs; delete adaptivity; delete ref_space; } while (!done); // Copy new time level solution into sln_prev_time. sln_prev_time.copy(&ref_sln); } delete ref_sln.get_mesh(); int ndof_allowed = 35; printf("ndof actual = %d\n", ndof); printf("ndof allowed = %d\n", ndof_allowed); if (ndof <= ndof_allowed) { // ndofs was 33 at the time this test was created 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); if (bt.is_explicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage explicit R-K method.", bt.get_size()); if (bt.is_diagonally_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage diagonally implicit R-K method.", bt.get_size()); if (bt.is_fully_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage fully implicit R-K method.", bt.get_size()); // Load the mesh. Mesh mesh, basemesh; MeshReaderH2D mloader; mloader.load("square.mesh", &basemesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) basemesh.refine_all_elements(0, true); mesh.copy(&basemesh); // Initialize boundary conditions. EssentialBCNonConst bc_essential("Bdy"); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); int ndof_coarse = space.get_num_dofs(); // Previous time level solution (initialized by initial condition). CustomInitialCondition sln_time_prev(&mesh); // Initialize the weak formulation CustomNonlinearity lambda(alpha); Hermes2DFunction<double> f(heat_src); WeakFormsH1::DefaultWeakFormPoisson<double> wf(HERMES_ANY, &lambda, &f); // Next time level solution. Solution<double> sln_time_new(&mesh); // Create a refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Visualize initial condition. char title[100]; ScalarView view("Initial condition", new WinGeom(0, 0, 440, 350)); OrderView ordview("Initial mesh", new WinGeom(445, 0, 410, 350)); view.show(&sln_time_prev); ordview.show(&space); // Initialize Runge-Kutta time stepping. RungeKutta<double> runge_kutta(&wf, &space, &bt); // Time stepping loop. double current_time = 0; int ts = 1; do { // Periodic global derefinement. if (ts > 1 && ts % UNREF_FREQ == 0) { Hermes::Mixins::Loggable::Static::info("Global mesh derefinement."); switch (UNREF_METHOD) { case 1: mesh.copy(&basemesh); space.set_uniform_order(P_INIT); break; case 2: mesh.unrefine_all_elements(); space.set_uniform_order(P_INIT); break; case 3: mesh.unrefine_all_elements(); space.adjust_element_order(-1, -1, P_INIT, P_INIT); break; } ndof_coarse = Space<double>::get_num_dofs(&space); } // Spatial adaptivity loop. Note: sln_time_prev must not be changed // during spatial adaptivity. bool done = false; int as = 1; double err_est; do { Hermes::Mixins::Loggable::Static::info("Time step %d, adaptivity step %d:", ts, as); // Construct globally refined reference mesh and setup reference space. Space<double>* ref_space = Space<double>::construct_refined_space(&space); int ndof_ref = Space<double>::get_num_dofs(ref_space); // Perform one Runge-Kutta time step according to the selected Butcher's table. try { runge_kutta.set_space(ref_space); runge_kutta.set_verbose_output(true); runge_kutta.setTime(current_time); runge_kutta.setTimeStep(time_step); runge_kutta.rk_time_step_newton(&sln_time_prev, &sln_time_new); } catch(Exceptions::Exception& e) { std::cout << e.what(); } // Project the fine mesh solution onto the coarse mesh. Solution<double> sln_coarse; Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh for error estimation."); OGProjection<double> ogProjection; ogProjection.project_global(&space, &sln_time_new, &sln_coarse); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); Adapt<double>* adaptivity = new Adapt<double>(&space); double err_est_rel_total = adaptivity->calc_err_est(&sln_coarse, &sln_time_new) * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_ref: %d, err_est_rel: %g%%", Space<double>::get_num_dofs(&space), Space<double>::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 { Hermes::Mixins::Loggable::Static::info("Adapting the coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); if (Space<double>::get_num_dofs(&space) >= NDOF_STOP) done = true; else // Increase the counter of performed adaptivity steps. as++; } // Visualize the solution and mesh. char title[100]; sprintf(title, "Solution<double>, time %g", current_time); view.set_title(title); view.show_mesh(false); view.show(&sln_time_new); sprintf(title, "Mesh, time %g", current_time); ordview.set_title(title); ordview.show(&space); // Clean up. delete adaptivity; if(!done) { delete ref_space; delete sln_time_new.get_mesh(); } } while (done == false); sln_time_prev.copy(&sln_time_new); // Increase current time and counter of time steps. current_time += time_step; ts++; } while (current_time < T_FINAL); // 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); // 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_NONSYM, HERMES_ANY); wf.add_vector_form(callback(F_euler), HERMES_ANY, &sln_prev_time); } else { wf.add_matrix_form(callback(J_cranic), HERMES_NONSYM, 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. Note: sln_prev_time must not be changed during spatial adaptivity. 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); double err_est_rel_total = adaptivity->calc_err_est(&sln, &ref_sln) * 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. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("square_quad.mesh", mesh); // mloader.load("square_tri.mesh", mesh); // Perform initial mesh refinement. for (int i = 0; i < INIT_REF_NUM; i++) mesh->refine_all_elements(); mesh->refine_towards_boundary("Layer", INIT_REF_NUM_BDY); // Initialize the weak formulation. WeakFormSharedPtr<double> wf(new WeakFormLinearAdvectionDiffusion(STABILIZATION_ON, SHOCK_CAPTURING_ON, B1, B2, EPSILON)); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_rest("Rest", 1.0); EssentialBCNonConst bc_layer("Layer"); EssentialBCs<double> bcs({ &bc_rest, &bc_layer }); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); WinGeom* sln_win_geom = new WinGeom(0, 0, 440, 350); WinGeom* mesh_win_geom = new WinGeom(450, 0, 400, 350); // Initialize coarse and reference mesh solution. MeshFunctionSharedPtr<double> sln(new Solution<double>), ref_sln(new Solution<double>); // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST); // 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. Hermes::Mixins::TimeMeasurable cpu_time; cpu_time.tick(); // Adaptivity loop: int as = 1; bool done = false; do { Hermes::Mixins::Loggable::Static::info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Mesh::ReferenceMeshCreator refMeshCreator(mesh); MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh); SpaceSharedPtr<double> ref_space = refSpaceCreator.create_ref_space(); // Assemble the reference problem. Hermes::Mixins::Loggable::Static::info("Solving on reference mesh."); LinearSolver<double> solver(wf, ref_space); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. // If successful, obtain the solution. solver.solve(); Solution<double>::vector_to_solution(solver.get_sln_vector(), ref_space, ref_sln); // Project the fine mesh solution onto the coarse mesh. Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh."); OGProjection<double>::project_global(space, ref_sln, sln); // 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::Mixins::TimeMeasurable::HERMES_SKIP); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); adaptivity.set_space(space); errorCalculator.calculate_errors(sln, ref_sln); double err_est_rel = errorCalculator.get_total_error_squared() * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space<double>::get_num_dofs(space), Space<double>::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<double>::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 { Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh."); done = adaptivity.adapt(&selector); // Increase the counter of performed adaptivity steps. if (done == false) as++; } } while (done == false); Hermes::Mixins::Loggable::Static::info("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[]) { // Choose a Butcher's table or define your own. ButcherTable bt(butcher_table_type); if (bt.is_explicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage explicit R-K method.", bt.get_size()); if (bt.is_diagonally_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage diagonally implicit R-K method.", bt.get_size()); if (bt.is_fully_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage fully implicit R-K method.", bt.get_size()); // Turn off adaptive time stepping if R-K method is not embedded. if (bt.is_embedded() == false && ADAPTIVE_TIME_STEP_ON == true) { throw Hermes::Exceptions::Exception("R-K method not embedded, turning off adaptive time stepping."); ADAPTIVE_TIME_STEP_ON = false; } // Load the mesh. Mesh mesh, basemesh; MeshReaderH2D mloader; mloader.load("square.mesh", &basemesh); mesh.copy(&basemesh); // Initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary("Bdy", INIT_BDY_REF_NUM); // Initialize boundary conditions. EssentialBCNonConst bc_essential("Bdy"); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); int ndof = space.get_num_dofs(); // Convert initial condition into a Solution. CustomInitialCondition sln_time_prev(&mesh); // Initialize the weak formulation CustomNonlinearity lambda(alpha); Hermes2DFunction<double> f(heat_src); WeakFormsH1::DefaultWeakFormPoisson<double> wf(HERMES_ANY, &lambda, &f); // Initialize the discrete problem. DiscreteProblem<double> dp(&wf, &space); // Create a refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Visualize initial condition. char title[100]; ScalarView sln_view("Initial condition", new WinGeom(0, 0, 440, 350)); sln_view.show_mesh(false); OrderView ordview("Initial mesh", new WinGeom(445, 0, 440, 350)); ScalarView time_error_view("Temporal error", new WinGeom(0, 400, 440, 350)); time_error_view.fix_scale_width(60); ScalarView space_error_view("Spatial error", new WinGeom(445, 400, 440, 350)); space_error_view.fix_scale_width(60); sln_view.show(&sln_time_prev); ordview.show(&space); // Graph for time step history. SimpleGraph time_step_graph; if (ADAPTIVE_TIME_STEP_ON) Hermes::Mixins::Loggable::Static::info("Time step history will be saved to file time_step_history.dat."); // Time stepping loop. double current_time = 0.0; int ts = 1; do { Hermes::Mixins::Loggable::Static::info("Begin time step %d.", ts); // Periodic global derefinement. if (ts > 1 && ts % UNREF_FREQ == 0) { Hermes::Mixins::Loggable::Static::info("Global mesh derefinement."); switch (UNREF_METHOD) { case 1: mesh.copy(&basemesh); space.set_uniform_order(P_INIT); break; case 2: mesh.unrefine_all_elements(); space.set_uniform_order(P_INIT); break; case 3: mesh.unrefine_all_elements(); space.adjust_element_order(-1, -1, P_INIT, P_INIT); break; } ndof = Space<double>::get_num_dofs(&space); } Hermes::Mixins::Loggable::Static::info("ndof: %d", ndof); // Spatial adaptivity loop. Note: sln_time_prev must not be // changed during spatial adaptivity. Solution<double> ref_sln; Solution<double>* time_error_fn; if (bt.is_embedded() == true) time_error_fn = new Solution<double>(&mesh); else time_error_fn = NULL; bool done = false; int as = 1; double err_est; do { // Construct globally refined reference mesh and setup reference space. Space<double>* ref_space = Space<double>::construct_refined_space(&space); RungeKutta<double> runge_kutta(&wf, ref_space, &bt); // Runge-Kutta step on the fine mesh. Hermes::Mixins::Loggable::Static::info("Runge-Kutta time step on fine mesh (t = %g s, tau = %g s, stages: %d).", current_time, time_step, bt.get_size()); try { runge_kutta.setTime(current_time); runge_kutta.setTimeStep(time_step); runge_kutta.set_newton_max_iter(NEWTON_MAX_ITER); runge_kutta.set_newton_tol(NEWTON_TOL_FINE); runge_kutta.rk_time_step_newton(&sln_time_prev, &ref_sln, time_error_fn); } catch(Exceptions::Exception& e) { std::cout << e.what(); } /* If ADAPTIVE_TIME_STEP_ON == true, estimate temporal error. If too large or too small, then adjust it and restart the time step. */ double rel_err_time = 0; if (bt.is_embedded() == true) { Hermes::Mixins::Loggable::Static::info("Calculating temporal error estimate."); // Show temporal error. char title[100]; sprintf(title, "Temporal error est, spatial adaptivity step %d", as); time_error_view.set_title(title); time_error_view.show_mesh(false); AbsFilter abs_tef(time_error_fn); time_error_view.show(&abs_tef); rel_err_time = Global<double>::calc_norm(time_error_fn, HERMES_H1_NORM) / Global<double>::calc_norm(&ref_sln, HERMES_H1_NORM) * 100; if (ADAPTIVE_TIME_STEP_ON == false) Hermes::Mixins::Loggable::Static::info("rel_err_time: %g%%", rel_err_time); } if (ADAPTIVE_TIME_STEP_ON) { if (rel_err_time > TIME_ERR_TOL_UPPER) { Hermes::Mixins::Loggable::Static::info("rel_err_time %g%% is above upper limit %g%%", rel_err_time, TIME_ERR_TOL_UPPER); Hermes::Mixins::Loggable::Static::info("Decreasing tau from %g to %g s and restarting time step.", time_step, time_step * TIME_STEP_DEC_RATIO); time_step *= TIME_STEP_DEC_RATIO; delete ref_space->get_mesh(); delete ref_space; continue; } else if (rel_err_time < TIME_ERR_TOL_LOWER) { Hermes::Mixins::Loggable::Static::info("rel_err_time = %g%% is below lower limit %g%%", rel_err_time, TIME_ERR_TOL_LOWER); Hermes::Mixins::Loggable::Static::info("Increasing tau from %g to %g s.", time_step, time_step * TIME_STEP_INC_RATIO); time_step *= TIME_STEP_INC_RATIO; delete ref_space->get_mesh(); delete ref_space; continue; } else { Hermes::Mixins::Loggable::Static::info("rel_err_time = %g%% is in acceptable interval (%g%%, %g%%)", rel_err_time, TIME_ERR_TOL_LOWER, TIME_ERR_TOL_UPPER); } // Add entry to time step history graph. time_step_graph.add_values(current_time, time_step); time_step_graph.save("time_step_history.dat"); } /* Estimate spatial errors and perform mesh refinement */ Hermes::Mixins::Loggable::Static::info("Spatial adaptivity step %d.", as); // Project the fine mesh solution onto the coarse mesh. Solution<double> sln; Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh for error estimation."); OGProjection<double> ogProjection; ogProjection.project_global(&space, &ref_sln, &sln); // Show spatial error. sprintf(title, "Spatial error est, spatial adaptivity step %d", as); DiffFilter<double>* space_error_fn = new DiffFilter<double>(Hermes::vector<MeshFunction<double>*>(&ref_sln, &sln)); space_error_view.set_title(title); space_error_view.show_mesh(false); AbsFilter abs_sef(space_error_fn); space_error_view.show(&abs_sef); // Calculate element errors and spatial error estimate. Hermes::Mixins::Loggable::Static::info("Calculating spatial error estimate."); Adapt<double>* adaptivity = new Adapt<double>(&space); double err_rel_space = adaptivity->calc_err_est(&sln, &ref_sln) * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof: %d, ref_ndof: %d, err_rel_space: %g%%", Space<double>::get_num_dofs(&space), Space<double>::get_num_dofs(ref_space), err_rel_space); // If err_est too large, adapt the mesh. if (err_rel_space < SPACE_ERR_TOL) done = true; else { Hermes::Mixins::Loggable::Static::info("Adapting the coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); if (Space<double>::get_num_dofs(&space) >= NDOF_STOP) done = true; else // Increase the counter of performed adaptivity steps. as++; } // Clean up. delete adaptivity; if(!done) { delete ref_space->get_mesh(); delete ref_space; } delete space_error_fn; } while (done == false); // Clean up. if (time_error_fn != NULL) delete time_error_fn; // Visualize the solution and mesh. char title[100]; sprintf(title, "Solution<double>, time %g s", current_time); sln_view.set_title(title); sln_view.show_mesh(false); sln_view.show(&ref_sln); sprintf(title, "Mesh, time %g s", current_time); ordview.set_title(title); ordview.show(&space); // Copy last reference solution into sln_time_prev. sln_time_prev.copy(&ref_sln); // Increase current time and counter of time steps. current_time += time_step; ts++; } while (current_time < T_FINAL); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char **args) { // Test variable. int success_test = 1; if (argc < 2) 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. int mx = 2; Ord3 order(mx, mx, mx); H1Space space(&mesh, bc_types, NULL, order); #if defined LIN_DIRICHLET || defined NLN_DIRICHLET space.set_essential_bc_values(essential_bc_values); #endif // Initialize the weak formulation. WeakForm wf; wf.add_vector_form(form_0<double, scalar>, form_0<Ord, Ord>); #if defined LIN_NEUMANN || defined LIN_NEWTON wf.add_vector_form_surf(form_0_surf<double, scalar>, form_0_surf<Ord, Ord>); #endif #if defined LIN_DIRICHLET || defined NLN_DIRICHLET // preconditioner wf.add_matrix_form(precond_0_0<double, scalar>, precond_0_0<Ord, Ord>, HERMES_SYM); #endif // Initialize the FE problem. DiscreteProblem fep(&wf, &space); #if defined LIN_DIRICHLET || defined NLN_DIRICHLET // use ML preconditioner to speed-up things MlPrecond pc("sa"); pc.set_param("max levels", 6); pc.set_param("increasing or decreasing", "decreasing"); pc.set_param("aggregation: type", "MIS"); pc.set_param("coarse: type", "Amesos-KLU"); #endif NoxSolver solver(&fep); #if defined LIN_DIRICHLET || defined NLN_DIRICHLET // solver.set_precond(&pc); #endif info("Solving."); Solution sln(&mesh); if(solver.solve()) Solution::vector_to_solution(solver.get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); Solution ex_sln(&mesh); ex_sln.set_exact(exact_solution); // Calculate exact error. info("Calculating exact error."); Adapt *adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = false; double err_exact = adaptivity->calc_err_exact(&sln, &ex_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_ABS); if (err_exact > EPS) // Calculated solution is not precise enough. success_test = 0; if (success_test) { info("Success!"); return ERR_SUCCESS; } else { info("Failure!"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial uniform mesh refinement. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Set essential boundary conditions. DefaultEssentialBCConst bc_essential(Hermes::vector<std::string>("right", "top"), 0.0); EssentialBCs bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space space(&mesh, &bcs, P_INIT); // Associate element markers (corresponding to physical regions) // with material properties (diffusion coefficient, absorption // cross-section, external sources). Hermes::vector<std::string> regions("e1", "e2", "e3", "e4", "e5"); Hermes::vector<double> D_map(D_1, D_2, D_3, D_4, D_5); Hermes::vector<double> Sigma_a_map(SIGMA_A_1, SIGMA_A_2, SIGMA_A_3, SIGMA_A_4, SIGMA_A_5); Hermes::vector<double> Sources_map(Q_EXT_1, 0.0, Q_EXT_3, 0.0, 0.0); // Initialize the weak formulation. WeakFormsNeutronics::Monoenergetic::Diffusion::DefaultWeakFormFixedSource wf(regions, D_map, Sigma_a_map, Sources_map); // Initialize coarse and reference mesh solution. Solution sln, ref_sln; // 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: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = Space::construct_refined_space(&space); int ndof_ref = Space::get_num_dofs(ref_space); // Initialize the FE problem. DiscreteProblem dp(&wf, ref_space); // Initialize the FE problem. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof_ref]; memset(coeff_vec, 0, ndof_ref*sizeof(scalar)); // Perform Newton's iteration on reference emesh. info("Solving on reference mesh."); if (!hermes2d.solve_newton(coeff_vec, &dp, solver, matrix, rhs)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solution(coeff_vec, ref_space, &ref_sln); // 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); double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 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 [] coeff_vec; delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; } 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[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("motor.mesh", &mesh); // Initialize the weak formulation. CustomWeakFormPoisson wf("Motor", EPS_MOTOR, "Air", EPS_AIR); // Initialize boundary conditions DefaultEssentialBCConst bc_essential_out("Outer", 0.0); DefaultEssentialBCConst bc_essential_stator("Stator", VOLTAGE); EssentialBCs bcs(Hermes::vector<EssentialBoundaryCondition *>(&bc_essential_out, &bc_essential_stator)); // Create an H1 space with default shapeset. H1Space space(&mesh, &bcs, P_INIT); // Initialize coarse and reference mesh solution. Solution sln, ref_sln; // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. ScalarView sview("Solution", new WinGeom(0, 0, 410, 600)); sview.fix_scale_width(50); sview.show_mesh(false); OrderView oview("Polynomial orders", new WinGeom(420, 0, 400, 600)); // 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 = Space::construct_refined_space(&space); int ndof_ref = Space::get_num_dofs(ref_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); // Initialize reference problem. info("Solving on reference mesh."); DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space); // Time measurement. cpu_time.tick(); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof_ref]; memset(coeff_vec, 0, ndof_ref * sizeof(scalar)); // Perform Newton's iteration. if (!hermes2d.solve_newton(coeff_vec, dp, solver, matrix, rhs)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution 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); // Time measurement. cpu_time.tick(); // VTK output. if (VTK_VISUALIZATION) { // Output solution in VTK format. Linearizer lin; char* title = new char[100]; sprintf(title, "sln-%d.vtk", as); lin.save_solution_vtk(&sln, title, "Potential", false); info("Solution in VTK format saved to file %s.", title); // Output mesh and element orders in VTK format. Orderizer ord; sprintf(title, "ord-%d.vtk", as); ord.save_orders_vtk(&space, title); info("Element orders in VTK format saved to file %s.", title); } // View the coarse mesh solution and polynomial orders. if (HERMES_VISUALIZATION) { 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); bool solutions_for_adapt = true; // In the following function, the Boolean parameter "solutions_for_adapt" determines whether // the calculated errors are intended for use with adaptivity (this may not be the case, for example, // when error wrt. an exact solution is calculated). The default value is solutions_for_adapt = true, // The last parameter "error_flags" determine whether the total and element errors are treated as // absolute or relative. Its default value is error_flags = HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL. // In subsequent examples and benchmarks, these two parameters will be often used with // their default values, and thus they will not be present in the code explicitly. 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 [] coeff_vec; 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; }