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; } }
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(); mesh.refine_towards_vertex(3, CORNER_REF_LEVEL); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_LEFT); bc_types.add_bc_neumann(Hermes::vector<int>(BDY_OUTER, BDY_INNER)); bc_types.add_bc_newton(BDY_BOTTOM); // Enter Dirichlet boudnary values. BCValues bc_values; bc_values.add_const(BDY_LEFT, T1); // 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_1), HERMES_SYM, MATERIAL_1); wf.add_matrix_form(callback(bilinear_form_2), HERMES_SYM, MATERIAL_2); wf.add_matrix_form_surf(callback(bilinear_form_surf_bottom), BDY_BOTTOM); wf.add_vector_form_surf(callback(linear_form_surf_bottom), BDY_BOTTOM); wf.add_vector_form_surf(callback(linear_form_surf_outer), BDY_OUTER); // Initialize coarse and reference mesh solution. Solution sln; // 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(); // Initialize matrix solver. 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; do { info("---- Adaptivity step %d:", as); // Assemble reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, &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(), &space, &sln); else error ("Matrix solver failed.\n"); // 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."); KellyTypeAdapt* adaptivity = new KellyTypeAdapt(&space); adaptivity->add_error_estimator_surf(callback(kelly_interface_estimator)); adaptivity->add_error_estimator_surf(callback(kelly_newton_boundary_estimator), BDY_BOTTOM); adaptivity->add_error_estimator_surf(callback(kelly_neumann_boundary_estimator), BDY_OUTER); adaptivity->add_error_estimator_surf(callback(kelly_zero_neumann_boundary_estimator), BDY_INNER); double err_est_rel = adaptivity->calc_err_est(&sln, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100; // Report results. info("ndof: %d, err_est_rel: %g%%", Space::get_num_dofs(&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(THRESHOLD, STRATEGY, MESH_REGULARITY); } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Increase the counter of performed adaptivity steps. if (done == false) as++; // Clean up. delete adaptivity; delete dp; } while (done == false); // Clean up. delete solver; delete matrix; delete rhs; 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("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[]) { // 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; }
int main(int argc, char* argv[]) { // Load the mesh file. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements. for(int i=0; i<UNIFORM_REF_LEVEL; i++) mesh.refine_all_elements(); mesh.refine_towards_vertex(3, CORNER_REF_LEVEL); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_LEFT); bc_types.add_bc_neumann(Hermes::Tuple<int>(BDY_OUTER, BDY_INNER)); bc_types.add_bc_newton(BDY_BOTTOM); // Enter Dirichlet boudnary values. BCValues bc_values; bc_values.add_const(BDY_LEFT, T1); // 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_matrix_form_surf(callback(bilinear_form_surf), BDY_BOTTOM); wf.add_vector_form_surf(callback(linear_form_surf), BDY_BOTTOM); // 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 - 1146.15) > 1e-1) success = 0; if (p_init == 2 && fabs(sum - 1145.97) > 1e-1) success = 0; if (p_init == 3 && fabs(sum - 1145.97) > 1e-1) success = 0; if (p_init == 4 && fabs(sum - 1145.96) > 1e-1) success = 0; if (p_init == 5 && fabs(sum - 1145.96) > 1e-1) success = 0; if (p_init == 6 && fabs(sum - 1145.96) > 1e-1) success = 0; if (p_init == 7 && fabs(sum - 1145.96) > 1e-1) success = 0; if (p_init == 8 && fabs(sum - 1145.96) > 1e-1) success = 0; if (p_init == 9 && fabs(sum - 1145.96) > 1e-1) success = 0; if (p_init == 10 && fabs(sum - 1145.96) > 1e-1) 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); // 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 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; bool is_linear = true; if (!rk_time_step(current_time, time_step, &bt, coeff_vec, &dp, matrix_solver, verbose, is_linear)) { 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; // Show the new time level solution. char title[100]; sprintf(title, "Time %3.2f, exterior temperature %3.5f", current_time, temp_ext(current_time)); Tview.set_title(title); Tview.show(&u_prev_time); // Increase counter of time steps. ts++; } while (current_time < T_FINAL); // Cleanup. delete [] coeff_vec; // Wait for the view 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()) info("Using a %d-stage explicit R-K method.", bt.get_size()); if (bt.is_diagonally_implicit()) info("Using a %d-stage diagonally implicit R-K method.", bt.get_size()); if (bt.is_fully_implicit()) info("Using a %d-stage fully implicit R-K method.", bt.get_size()); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("wall.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(BDY_BOTTOM, INIT_REF_NUM_BDY); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_neumann(Hermes::vector<int>(BDY_RIGHT, BDY_LEFT)); bc_types.add_bc_newton(Hermes::vector<int>(BDY_BOTTOM, BDY_TOP)); // Initialize an H1 space with default shapeset. H1Space space(&mesh, &bc_types, NULL, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Previous and next time level solutions. Solution* sln_time_prev = new Solution(&mesh, TEMP_INIT); Solution* sln_time_new = new Solution(&mesh); Solution* time_error_fn = new Solution(&mesh, 0.0); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(stac_jacobian_vol, stac_jacobian_vol_ord, HERMES_NONSYM, HERMES_ANY, sln_time_prev); wf.add_vector_form(stac_residual_vol, stac_residual_vol_ord, HERMES_ANY, sln_time_prev); wf.add_matrix_form_surf(stac_jacobian_bottom, stac_jacobian_bottom_ord, BDY_BOTTOM, sln_time_prev); wf.add_vector_form_surf(stac_residual_bottom, stac_residual_bottom_ord, BDY_BOTTOM, sln_time_prev); wf.add_matrix_form_surf(stac_jacobian_top, stac_jacobian_top_ord, BDY_TOP, sln_time_prev); wf.add_vector_form_surf(stac_residual_top, stac_residual_top_ord, BDY_TOP, sln_time_prev); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, &space, is_linear); // Initialize views. ScalarView Tview("Temperature", new WinGeom(0, 0, 1500, 400)); Tview.fix_scale_width(40); ScalarView eview("Temporal error", new WinGeom(0, 450, 1500, 400)); eview.fix_scale_width(40); // Graph for time step history. SimpleGraph time_step_graph; info("Time step history will be saved to file time_step_history.dat."); // Time stepping loop: double current_time = 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 s, tau = %g s, stages: %d).", current_time, time_step, bt.get_size()); bool verbose = true; bool is_linear = true; if (!rk_time_step(current_time, time_step, &bt, sln_time_prev, sln_time_new, time_error_fn, &dp, matrix_solver, verbose, is_linear)) { error("Runge-Kutta time step failed, try to decrease time step size."); } // Plot error function. char title[100]; sprintf(title, "Temporal error, t = %g", current_time); eview.set_title(title); AbsFilter abs_tef(time_error_fn); eview.show(&abs_tef, HERMES_EPS_VERYHIGH); // Calculate relative time stepping error and decide whether the // time step can be accepted. If not, then the time step size is // reduced and the entire time step repeated. If yes, then another // check is run, and if the relative error is very low, time step // is increased. double rel_err_time = calc_norm(time_error_fn, HERMES_H1_NORM) / calc_norm(sln_time_new, HERMES_H1_NORM) * 100; info("rel_err_time = %g%%", rel_err_time); if (rel_err_time > TIME_TOL_UPPER) { info("rel_err_time above upper limit %g%% -> decreasing time step from %g to %g and restarting time step.", TIME_TOL_UPPER, time_step, time_step * TIME_STEP_DEC_RATIO); time_step *= TIME_STEP_DEC_RATIO; continue; } if (rel_err_time < TIME_TOL_LOWER) { info("rel_err_time = below lower limit %g%% -> increasing time step from %g to %g", TIME_TOL_UPPER, time_step, time_step * TIME_STEP_INC_RATIO); time_step *= TIME_STEP_INC_RATIO; } // Add entry to the timestep graph. time_step_graph.add_values(current_time, time_step); time_step_graph.save("time_step_history.dat"); // Update time. current_time += time_step; // Show the new time level solution. sprintf(title, "Time %3.2f s", current_time); Tview.set_title(title); Tview.show(sln_time_new); // Copy solution for the new time step. sln_time_prev->copy(sln_time_new); // Increase counter of time steps. ts++; } while (current_time < T_FINAL); // Cleanup. delete sln_time_prev; delete sln_time_new; delete time_error_fn; // Wait for the view 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, basemesh; H2DReader mloader; mloader.load("domain.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(3, INIT_REF_NUM_BDY); // 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); // Create a selector which will select optimal candidate. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Solutions for the time stepping and the Newton's method. Solution sln, ref_sln, sln_prev_time; // Adapt mesh to represent initial condition with given accuracy. info("Mesh adaptivity to an exact function:"); int as = 1; bool done = false; do { // Setup space for the reference solution. Space *rspace = construct_refined_space(&space); // Assign the function f() to the fine mesh. ref_sln.set_exact(rspace->get_mesh(), init_cond); // Project the function f() on the coarse mesh. OGProjection::project_global(&space, &ref_sln, &sln_prev_time, matrix_solver); // Calculate element errors and total error estimate. Adapt adaptivity(&space, HERMES_H1_NORM); bool solutions_for_adapt = true; double err_est_rel = adaptivity.calc_err_est(&sln_prev_time, &ref_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100; info("Step %d, ndof %d, proj_error %g%%", as, Space::get_num_dofs(&space), err_est_rel); // If err_est_rel too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { double to_be_processed = 0; done = adaptivity.adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY, to_be_processed); if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; } as++; } while (done == false); // 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); OGProjection::project_global(&space, &sln_prev_time, &sln, matrix_solver); // Initialize the weak formulation. WeakForm wf; if (TIME_INTEGRATION == 1) { wf.add_matrix_form(jac_form_vol_euler, jac_form_vol_ord, HERMES_UNSYM, HERMES_ANY, &sln_prev_time); wf.add_matrix_form_surf(jac_form_surf_1_euler, jac_form_surf_1_ord, BDY_1); wf.add_matrix_form_surf(jac_form_surf_4_euler, jac_form_surf_4_ord, BDY_4); wf.add_matrix_form_surf(jac_form_surf_6_euler, jac_form_surf_6_ord, BDY_6); wf.add_vector_form(res_form_vol_euler, res_form_vol_ord, HERMES_ANY, &sln_prev_time); wf.add_vector_form_surf(res_form_surf_1_euler, res_form_surf_1_ord, BDY_1); wf.add_vector_form_surf(res_form_surf_4_euler, res_form_surf_4_ord, BDY_4); wf.add_vector_form_surf(res_form_surf_6_euler, res_form_surf_6_ord, BDY_6); } else { wf.add_matrix_form(jac_form_vol_cranic, jac_form_vol_ord, HERMES_UNSYM, HERMES_ANY, &sln_prev_time); wf.add_matrix_form_surf(jac_form_surf_1_cranic, jac_form_surf_1_ord, BDY_1); wf.add_matrix_form_surf(jac_form_surf_4_cranic, jac_form_surf_4_ord, BDY_4); wf.add_matrix_form_surf(jac_form_surf_6_cranic, jac_form_surf_6_ord, BDY_6); wf.add_vector_form(res_form_vol_cranic, res_form_vol_ord, HERMES_ANY, &sln_prev_time); wf.add_vector_form_surf(res_form_surf_1_cranic, res_form_surf_1_ord, BDY_1, &sln_prev_time); wf.add_vector_form_surf(res_form_surf_4_cranic, res_form_surf_4_ord, BDY_4, &sln_prev_time); wf.add_vector_form_surf(res_form_surf_6_cranic, res_form_surf_6_ord, BDY_6, &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; // 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; info("---- Time step %d:", 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 fine mesh solution on the globally derefined mesh. info("Projecting fine mesh solution on globally derefined mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); } // Adaptivity loop (in space): 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 = 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); } // 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. 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++; } // 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."); Adapt* adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = true; // Calculate error estimate wrt. fine mesh solution. double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_ABS) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, space_err_est_rel: %g%%", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space), err_est_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_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; break; } as++; } // Cleanup. delete [] coeff_vec; delete solver; delete matrix; delete rhs; delete adaptivity; delete ref_space->get_mesh(); delete ref_space; } while (!done); // Copy new time level solution into sln_prev_time. sln_prev_time.copy(&ref_sln); } info("Coordinate ( 2, -2.0) value = %lf", sln_prev_time.get_pt_value( 2, -2.0)); info("Coordinate ( 2, -4.0) value = %lf", sln_prev_time.get_pt_value( 2, -4.0)); info("Coordinate ( 6, -2.0) value = %lf", sln_prev_time.get_pt_value( 6, -2.0)); info("Coordinate ( 6, -4.0) value = %lf", sln_prev_time.get_pt_value( 6, -4.0)); info("Coordinate ( 4, -3.0) value = %lf", sln_prev_time.get_pt_value( 4, -3.0)); #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 double coor_x[5] = {2.0, 2.0, 6.0, 6.0, 4.0}; double coor_y[5] = {-2.0, -4.0, -2.0, -4.0, -3.0}; double value[5] = {-4.821844, -2.462673, -4.000754, -1.705534, -3.257146}; for (int i = 0; i < 5; i++) { if ((value[i] - sln_prev_time.get_pt_value(coor_x[i], coor_y[i])) < 1E-6) { } else { printf("Failure!\n"); return ERROR_FAILURE; } } printf("Success!\n"); return ERROR_SUCCESS; }
int main(int argc, char* argv[]) { // Time measurement TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("lshape3q.mesh", &mesh); // quadrilaterals //mloader.load("lshape3t.mesh", &mesh); // triangles // Perform initial mesh refinemets. 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::vector<int>(BDY_1, BDY_6)); bc_types.add_bc_newton(Hermes::vector<int>(BDY_2, BDY_3, BDY_4, BDY_5)); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_zero(Hermes::vector<int>(BDY_1, BDY_6)); // Create an Hcurl space with default shapeset. HcurlSpace 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_matrix_form_surf(callback(bilinear_form_surf)); wf.add_vector_form_surf(linear_form_surf, linear_form_surf_ord); // Initialize coarse and reference mesh solutions. Solution sln, ref_sln; // Initialize exact solution. ExactSolution sln_exact(&mesh, exact); // Initialize refinement selector. HcurlProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. VectorView v_view("Solution (magnitude)", new WinGeom(0, 0, 460, 350)); v_view.set_min_max_range(0, 1.5); OrderView o_view("Polynomial orders", new WinGeom(470, 0, 400, 350)); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est, 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 matrix solver. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Assemble the 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. v_view.show(&sln); o_view.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, bool solutions_for_adapt = false; double err_exact_rel = adaptivity->calc_err_exact(&sln, &sln_exact, solutions_for_adapt) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space)); info("err_est_rel: %g%%, err_exact_rel: %g%%", err_est_rel, err_exact_rel); // 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"); graph_dof_exact.add_values(Space::get_num_dofs(&space), err_exact_rel); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel); graph_cpu_exact.save("conv_cpu_exact.dat"); // If err_est_rel 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. v_view.set_title("Fine mesh solution (magnitude)"); v_view.show(&ref_sln); // Wait for all views to be closed. View::wait(); return 0; }
int main() { // Create space, set Dirichlet BC, enumerate basis functions. Space* space = new Space(A, B, NELEM, P_INIT, NEQ); info("N_dof = %d", Space::get_num_dofs(space)); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(jacobian_vol); wf.add_vector_form(residual_vol); wf.add_matrix_form_surf(jacobian_surf_left, BOUNDARY_LEFT); 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); // Newton's loop. // 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++; } // Plot the solution. Linearizer l(space); l.plot_solution("solution.gp"); // Plot the resulting space. space->plot("space.gp"); info("Done."); 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("lshape3q.mesh", &mesh); // quadrilaterals //mloader.load("lshape3t.mesh", &mesh); // triangles // Perform initial mesh refinemets. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Create an Hcurl space with default shapeset. HcurlSpace space(&mesh, bc_types, essential_bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form), H2D_SYM); wf.add_matrix_form_surf(callback(bilinear_form_surf)); wf.add_vector_form_surf(linear_form_surf, linear_form_surf_ord); // Initialize views. OrderView ordview("Coarse mesh", 600, 0, 600, 500); VectorView vecview("Electric Field - VectorView", 0, 0, 600, 500); /* // View the basis functions. VectorBaseView bview; vbview.show(&space); View::wait(H2DV_WAIT_KEYPRESS); */ // DOF and CPU convergence graphs SimpleGraph graph_dof_est, graph_dof_exact, graph_cpu_est, graph_cpu_exact; // Initialize refinement selector. HcurlProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize the coarse mesh problem. LinSystem ls(&wf, &space); // Adaptivity loop: int as = 1; bool done = false; Solution sln_coarse, sln_fine; do { info("---- Adaptivity step %d:", as); // Assemble and solve the fine mesh problem. info("Solving on fine mesh."); RefSystem rs(&ls); rs.assemble(); rs.solve(&sln_fine); // Either solve on coarse mesh or project the fine mesh solution // on the coarse mesh. if (SOLVE_ON_COARSE_MESH) { info("Solving on coarse mesh."); ls.assemble(); ls.solve(&sln_coarse); } else { info("Projecting fine mesh solution on coarse mesh."); int proj_type = 2; // Hcurl projection. ls.project_global(&sln_fine, &sln_coarse, proj_type); } // Time measurement. cpu_time.tick(); // Calculate error wrt. exact solution. info("Calculating error (exact)."); ExactSolution ex(&mesh, exact); double err_exact = hcurl_error(&sln_coarse, &ex) * 100; // Show real part of the solution and mesh. ordview.show(&space); RealFilter real(&sln_coarse); vecview.set_min_max_range(0, 1); vecview.show(&real, H2D_EPS_HIGH); // Skip exact error calculation and visualization time. cpu_time.tick(HERMES_SKIP); // Calculate error estimate wrt. fine mesh solution. info("Calculating error (est)."); HcurlAdapt hp(&ls); hp.set_solutions(&sln_coarse, &sln_fine); double err_est_adapt = hp.calc_error() * 100; double err_est_hcurl = hcurl_error(&sln_coarse, &sln_fine) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, err_est: %g%%, err_exact: %g%%", ls.get_num_dofs(), rs.get_num_dofs(), err_est_hcurl, err_exact); // Add entries to DOF convergence graphs. graph_dof_exact.add_values(ls.get_num_dofs(), err_exact); graph_dof_exact.save("conv_dof_exact.dat"); graph_dof_est.add_values(ls.get_num_dofs(), err_est_hcurl); graph_dof_est.save("conv_dof_est.dat"); // Add entries to CPU convergence graphs. graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact); graph_cpu_exact.save("conv_cpu_exact.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_hcurl); graph_cpu_est.save("conv_cpu_est.dat"); // If err_est_adapt too large, adapt the mesh. if (err_est_adapt < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = hp.adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); if (ls.get_num_dofs() >= NDOF_STOP) done = true; } as++; } while (!done); verbose("Total running time: %g s", cpu_time.accumulated()); // Show the fine mesh solution - the final result vecview.set_title("Final solution"); vecview.show(&sln_fine); // 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("lshape3q.mesh", &mesh); // quadrilaterals //mloader.load("lshape3t.mesh", &mesh); // triangles // Perform initial mesh refinemets. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Create an Hcurl space with default shapeset. HcurlSpace space(&mesh, bc_types, essential_bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form), HERMES_SYM); wf.add_matrix_form_surf(callback(bilinear_form_surf)); wf.add_vector_form_surf(linear_form_surf, linear_form_surf_ord); // Initialize coarse and reference mesh solutions. Solution sln, ref_sln; // Initialize exact solution. ExactSolution sln_exact(&mesh, exact); // Initialize refinement selector. HcurlProjBasedSelector 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; // 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"); // 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, HERMES_HCURL_NORM); // Calculate element errors and total error estimate. info("Calculating error estimate and exact error."); Adapt* adaptivity = new Adapt(&space, HERMES_HCURL_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, &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_est.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu_est.save("conv_cpu_est.dat"); graph_dof_exact.add_values(Space::get_num_dofs(&space), err_exact_rel); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel); graph_cpu_exact.save("conv_cpu_exact.dat"); // If err_est_rel 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); printf("ndof allowed = %d\n", 1400); printf("ndof actual = %d\n", ndof); if (ndof < 1400) { // ndofs was 1384 atthe time this test was created printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
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 < 5) error("Not enough parameters"); sscanf(args[2], "%d", &m); sscanf(args[3], "%d", &n); sscanf(args[4], "%d", &o); printf("* Loading mesh '%s'\n", args[1]); Mesh mesh; H3DReader mesh_loader; if (!mesh_loader.load(args[1], &mesh)) error("Loading mesh file '%s'\n", args[1]); H1ShapesetLobattoHex shapeset; printf("* Setting the space up\n"); int mx = maxn(4, m, n, o, 4); Ord3 order(mx, mx, mx); // Ord3 order(1, 1, 1); printf(" - Setting uniform order to (%d, %d, %d)\n", mx, mx, mx); H1Space space(&mesh, bc_types, NULL, 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(bilinear_form<double, scalar>, bilinear_form<Ord, Ord>, SYM); 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>); DiscreteProblem dp(&wf, &space, true); // assemble stiffness matrix printf(" - assembling... "); fflush(stdout); Timer assemble_timer; assemble_timer.start(); dp.assemble(&mat, &rhs); assemble_timer.stop(); printf("%s (%lf secs)\n", assemble_timer.get_human_time(), assemble_timer.get_seconds()); // solve the stiffness matrix printf(" - solving... "); fflush(stdout); Timer solve_timer; solve_timer.start(); bool solved = solver.solve(); solve_timer.stop(); printf("%s (%lf secs)\n", solve_timer.get_human_time(), solve_timer.get_seconds()); // mat.dump(stdout, "a"); // rhs.dump(stdout, "b"); if (solved) { Solution sln(&mesh); sln.set_coeff_vector(&space, solver.get_solution()); printf("* Solution:\n"); // double *s = solver.get_solution(); // for (int i = 1; i <= ndofs; i++) { // printf(" x[% 3d] = % lf\n", i, s[i]); // } // norm ExactSolution ex_sln(&mesh, exact_solution); double h1_sln_norm = h1_norm(&sln); double h1_err_norm = h1_error(&sln, &ex_sln); 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, &ex_sln); printf(" - L2 solution norm: % le\n", l2_sln_norm); printf(" - L2 error norm: % le\n", l2_err_norm); if (h1_err_norm > EPS || l2_err_norm > EPS) { // calculated solution is not enough precise res = ERR_FAILURE; } #ifdef OUTPUT_DIR printf("* Output\n"); // output const char *of_name = OUTPUT_DIR "/solution.pos"; FILE *ofile = fopen(of_name, "w"); if (ofile != NULL) { ExactSolution ex_sln(&mesh, exact_solution); // DiffFilter eh(&sln, &ex_sln); // DiffFilter eh_dx(mesh, &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); output.out(&sln, "Uh"); // output.out(&sln, "Uh dx", FN_DX_0); // output.out(&sln, "Uh dy", FN_DY_0); // output.out(&sln, "Uh dz", FN_DZ_0); // output.out(&eh, "Eh"); // output.out(&eh_dx, "Eh dx"); // output.out(&eh_dy, "Eh dy"); // output.out(&eh_dz, "Eh dz"); output.out(&ex_sln, "U"); // output.out(&ex_sln, "U dx", FN_DX_0); // 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 } else res = ERR_FAILURE; #ifdef WITH_PETSC mat.free(); rhs.free(); PetscFinalize(); #endif return res; }
int main(int argc, char **args) { // Test variable. int success_test = 1; // Initialize the solver in the case of SOLVER_PETSC or SOLVER_MUMPS. initialize_solution_environment(matrix_solver, argc, args); for (int i = 0; i < 48; i++) { for (int j = 0; j < 48; j++) { info("Config: %d, %d ", i, j); Mesh mesh; for (unsigned int k = 0; k < countof(vtcs); k++) mesh.add_vertex(vtcs[k].x, vtcs[k].y, vtcs[k].z); unsigned int 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); unsigned int 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 (unsigned int k = 0; k < countof(bnd); k++) { unsigned int 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(); // Initialize the space. H1Space space(&mesh, bc_types, essential_bc_values); #ifdef XM_YN_ZO Ord3 ord(4, 4, 4); #elif defined XM_YN_ZO_2 Ord3 ord(4, 4, 4); #elif defined X2_Y2_Z2 Ord3 ord(2, 2, 2); #endif space.set_uniform_order(ord); // Initialize the weak formulation. WeakForm wf; #ifdef DIRICHLET wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<Ord, Ord>, HERMES_SYM); wf.add_vector_form(linear_form<double, scalar>, linear_form<Ord, Ord>); #elif defined NEWTON wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<Ord, Ord>, HERMES_SYM); 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>); #endif // 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). } // 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(space.get_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_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; info("failed, error:%g", err_exact); } else info("passed"); // 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; } }
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[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square.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; info("ndof = %d", ndof); info("Coordinate ( 0.1, 0.1) value = %lf", sln.get_pt_value(0.1, 0.1)); info("Coordinate ( 0.3, 0.3) value = %lf", sln.get_pt_value(0.3, 0.3)); info("Coordinate ( 0.5, 0.5) value = %lf", sln.get_pt_value(0.5, 0.5)); info("Coordinate ( 0.7, 0.7) value = %lf", sln.get_pt_value(0.7, 0.7)); double coor_xy[4] = {0.1, 0.3, 0.5, 0.7}; double value[4] = {0.999885, 0.844340, 0.000000, 0.000000}; for (int i = 0; i < 4; i++) { if ((value[i] - sln.get_pt_value(coor_xy[i], coor_xy[i])) < 1E-6) { printf("Success!\n"); } else { printf("Failure!\n"); return ERR_FAILURE; } } return ERR_SUCCESS; }
int main(int argc, char **args) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H3DReader mloader; mloader.load("lshape_hex.mesh3d", &mesh); // Perform initial mesh refinement. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ); // Create an Hcurl space with default shapeset. HcurlSpace space(&mesh, bc_types, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(biform<double, scalar>, biform<Ord, Ord>, HERMES_SYM); wf.add_matrix_form_surf(biform_surf, biform_surf_ord); wf.add_vector_form_surf(liform_surf, liform_surf_ord); // Set exact solution. ExactSolution exact_sol(&mesh, exact); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est, 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, 1); // Initialize discrete problem. bool is_linear = true; DiscreteProblem dp(&wf, ref_space, is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the preconditioner in the case of SOLVER_AZTECOO. if (matrix_solver == SOLVER_AZTECOO) { ((AztecOOSolver*) solver)->set_solver(iterative_method); ((AztecOOSolver*) solver)->set_precond(preconditioner); // Using default iteration parameters (see solver/aztecoo.h). } // Assemble the reference problem. info("Assembling on reference mesh (ndof: %d).", Space::get_num_dofs(ref_space)); dp.assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system on reference mesh. If successful, obtain the solution. info("Solving on reference mesh."); Solution ref_sln(ref_space->get_mesh()); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), ref_space, &ref_sln); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Project the reference solution on the coarse mesh. Solution sln(space.get_mesh()); info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver, HERMES_HCURL_NORM); // Time measurement. cpu_time.tick(); // Output solution and mesh with polynomial orders. if (solution_output) { out_fn_vtk(&sln, "sln", as); out_orders_vtk(&space, "order", as); } // Skip the visualization time. cpu_time.tick(HERMES_SKIP); // Calculate element errors and total error estimate. info("Calculating error estimate and exact error."); Adapt *adaptivity = new Adapt(&space, HERMES_HCURL_NORM); bool solutions_for_adapt = true; double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln, solutions_for_adapt) * 100; // Calculate exact error. solutions_for_adapt = false; double err_exact_rel = adaptivity->calc_err_exact(&sln, &exact_sol, solutions_for_adapt) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d.", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space)); info("err_est_rel: %g%%, err_exact_rel: %g%%.", err_est_rel, err_exact_rel); // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu_est.save("conv_cpu_est.dat"); graph_dof_exact.add_values(Space::get_num_dofs(&space), err_exact_rel); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel); graph_cpu_exact.save("conv_cpu_exact.dat"); // If err_est_rel is too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); adaptivity->adapt(THRESHOLD); } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete ref_space->get_mesh(); delete ref_space; delete matrix; delete rhs; delete solver; delete adaptivity; // Increase the counter of performed adaptivity steps. as++; } while (!done); return 0; }
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); // Initialize an H1 space with default shepeset. H1Space space(&mesh, bc_types, essential_bc_values, P_INIT); int ndof = get_num_dofs(&space); info("ndof = %d.", ndof); // Set initial condition. Solution tsln; 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>, H2D_ANY, &tsln); wf.add_vector_form_surf(linear_form_surf<double, double>, linear_form_surf<Ord, Ord>, bdy_air); // Initialize the linear problem. LinearProblem lp(&wf, &space); // Initialize matrix solver. Matrix* mat; Vector* rhs; CommonSolver* solver; init_matrix_solver(matrix_solver, ndof, mat, rhs, solver); // Time stepping: int nsteps = (int)(FINAL_TIME/TAU + 0.5); bool rhsonly = false; for(int ts = 1; ts <= nsteps; ts++) { info("---- Time step %d, time %3.5f, ext_temp %g", ts, TIME, temp_ext(TIME)); // Assemble stiffness matrix and rhs. lp.assemble(mat, rhs, rhsonly); rhsonly = true; // Solve the matrix problem. if (!solver->solve(mat, rhs)) error ("Matrix solver failed.\n"); // Update tsln. tsln.set_fe_solution(&space, rhs); if (ts % OUTPUT_FREQUENCY == 0) { Linearizer lin; int item = H2D_FN_VAL_0; double eps = H2D_EPS_NORMAL; double max_abs = -1.0; MeshFunction* xdisp = NULL; MeshFunction* ydisp = NULL; double dmult = 1.0; lin.process_solution(&tsln, item, eps, max_abs, xdisp, ydisp, dmult); char* filename = new char[100]; sprintf(filename, "tsln_%d.lin", ts); // Save Linearizer data. lin.save_data(filename); info("Linearizer data saved to file %s.", filename); // Save complete Solution. sprintf(filename, "tsln_%d.dat", ts); bool compress = false; // Gzip compression not used as it only works on Linux. tsln.save(filename, compress); info("Complete Solution saved to file %s.", filename); } // Update the time variable. TIME += TAU; } info("Let's assume that the remote computation has finished and you fetched the *.lin files."); info("Visualizing Linearizer data from file tsln_40.lin."); // First use ScalarView to read and show the Linearizer data. WinGeom* win_geom_1 = new WinGeom(0, 0, 450, 600); ScalarView sview_1("Saved Linearizer data", win_geom_1); sview_1.lin.load_data("tsln_40.lin"); sview_1.set_min_max_range(0,20); sview_1.fix_scale_width(3); sview_1.show_linearizer_data(); info("Visualizing Solution from file tsln_60.dat."); Solution sln_from_file; sln_from_file.load("tsln_60.dat"); WinGeom* win_geom_2 = new WinGeom(460, 0, 450, 600); ScalarView sview_2("Saved Solution data", win_geom_2); sview_2.set_min_max_range(0,20); sview_2.fix_scale_width(3); sview_2.show(&sln_from_file); info("Visualizing Mesh and Orders extracted from the Solution."); int p_init = 1; // The NULLs are for bc_types() and essential_bc_values(). H1Space space_from_file(sln_from_file.get_mesh(), NULL, NULL, p_init); space_from_file.set_element_orders(sln_from_file.get_element_orders()); WinGeom* win_geom_3 = new WinGeom(920, 0, 450, 600); OrderView oview("Saved Solution -> Space", win_geom_3); oview.show(&space_from_file); // Wait for the view to be closed. View::wait(); return 0; }