int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(BDY_DIRICHLET, INIT_BDY_REF_NUM); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_function(BDY_DIRICHLET, essential_bc_values); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Solution for the previous time level. Solution u_prev_time; // Initialize the weak formulation. WeakForm wf; if (TIME_INTEGRATION == 1) { wf.add_matrix_form(jac_euler, jac_ord, HERMES_NONSYM, HERMES_ANY, &u_prev_time); wf.add_vector_form(res_euler, res_ord, HERMES_ANY, &u_prev_time); } else { wf.add_matrix_form(jac_cranic, jac_ord, HERMES_NONSYM, HERMES_ANY, &u_prev_time); wf.add_vector_form(res_cranic, res_ord, HERMES_ANY, &u_prev_time); } // Project the function init_cond() on the FE space // to obtain initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[Space::get_num_dofs(&space)]; info("Projecting initial condition to obtain initial vector for the Newton's method."); OGProjection::project_global(&space, init_cond, coeff_vec, matrix_solver); Solution::vector_to_solution(coeff_vec, &space, &u_prev_time); // Time stepping loop: double current_time = 0.0; int t_step = 1; do { info("---- Time step %d, t = %g s.", t_step, current_time); t_step++; // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp(&wf, &space, is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Perform Newton's iteration. bool verbose = true; if (!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solution(coeff_vec, &space, &u_prev_time); // Cleanup. delete matrix; delete rhs; delete solver; // Update time. current_time += TAU; } while (current_time < T_FINAL); delete [] coeff_vec; info("Coordinate ( 0, 0) value = %lf", u_prev_time.get_pt_value(0.0, 0.0)); info("Coordinate ( 25, 25) value = %lf", u_prev_time.get_pt_value(25.0, 25.0)); info("Coordinate ( 50, 50) value = %lf", u_prev_time.get_pt_value(50.0, 50.0)); info("Coordinate ( 75, 75) value = %lf", u_prev_time.get_pt_value(75.0, 75.0)); info("Coordinate (100, 100) value = %lf", u_prev_time.get_pt_value(100.0, 100.0)); double coor_x_y[5] = {0.0, 25.0, 50.0, 75.0, 100.0}; double value[5] = {-1000.000000, -969.316013, -836.504249, -651.433710, -1000.000000}; bool success = true; for (int i = 0; i < 5; i++) { if (abs(value[i] - u_prev_time.get_pt_value(coor_x_y[i], coor_x_y[i])) > 1E-6) success = false; } if (success) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main (int argc, char* argv[]) { // Load the mesh. Mesh basemesh; ExodusIIReader mesh_loader; if (!mesh_loader.load("coarse_mesh_full.e", &basemesh)) error("Loading mesh file '%s' failed.\n", "coarse_mesh_full.e"); Mesh C_mesh, phi_mesh; C_mesh.copy(basemesh); phi_mesh.copy(basemesh); H1Space C_space(&C_mesh, bc_types_C, essential_bc_values_C, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); H1Space phi_space(MULTIMESH ? &phi_mesh : &C_mesh, bc_types_phi, essential_bc_values_phi, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); Solution C_prev_time(&C_mesh); C_prev_time.set_const(C0); Solution phi_prev_time(MULTIMESH ? &phi_mesh : &C_mesh); phi_prev_time.set_const(0.0); WeakForm wf(2); // Add the bilinear and linear forms. if (TIME_DISCR == 1) { // Implicit Euler. wf.add_matrix_form(0, 0, callback(J_euler_DFcDYc), HERMES_NONSYM); wf.add_matrix_form(0, 1, callback(J_euler_DFcDYphi), HERMES_NONSYM); wf.add_matrix_form(1, 0, callback(J_euler_DFphiDYc), HERMES_NONSYM); wf.add_matrix_form(1, 1, callback(J_euler_DFphiDYphi), HERMES_NONSYM); wf.add_vector_form(0, callback(Fc_euler), HERMES_ANY_INT, Hermes::vector<MeshFunction*>(&C_prev_time, &phi_prev_time)); wf.add_vector_form(1, callback(Fphi_euler), HERMES_ANY, Hermes::vector<MeshFunction*>(&C_prev_time, &phi_prev_time)); } else { wf.add_matrix_form(0, 0, callback(J_cranic_DFcDYc), HERMES_NONSYM); wf.add_matrix_form(0, 1, callback(J_cranic_DFcDYphi), HERMES_NONSYM); wf.add_matrix_form(1, 0, callback(J_cranic_DFphiDYc), HERMES_NONSYM); wf.add_matrix_form(1, 1, callback(J_cranic_DFphiDYphi), HERMES_NONSYM); wf.add_vector_form(0, callback(Fc_cranic), HERMES_ANY, Hermes::vector<MeshFunction*>(&C_prev_time, &phi_prev_time)); wf.add_vector_form(1, callback(Fphi_cranic), HERMES_ANY); } int ndof = Space::get_num_dofs(Hermes::vector<Space*>(&C_space, &phi_space)); Solution C_sln(C_space.get_mesh()); Solution phi_sln(phi_space.get_mesh()); info("Projecting initial condition to obtain initial vector for the Newton's method."); scalar* coeff_vec_coarse = new scalar[ndof]; OGProjection::project_global(Hermes::vector<Space *>(&C_space, &phi_space), Hermes::vector<MeshFunction *>(&C_prev_time, &phi_prev_time), coeff_vec_coarse, matrix_solver); bool is_linear = false; DiscreteProblem dp_coarse(&wf, Hermes::vector<Space *>(&C_space, &phi_space), is_linear); //Solution::vector_to_solutions(coeff_vec_coarse, dp_coarse.get_spaces(), Hermes::vector<Solution *>(&C_sln, &phi_sln), NULL); // Set up the solver, matrix, and rhs for the coarse mesh according to the solver selection. SparseMatrix* matrix_coarse = create_matrix(matrix_solver); Vector* rhs_coarse = create_vector(matrix_solver); Solver* solver_coarse = create_linear_solver(matrix_solver, matrix_coarse, rhs_coarse); info("Solving on coarse mesh:"); bool verbose = true; if (!solve_newton(coeff_vec_coarse, &dp_coarse, solver_coarse, matrix_coarse, rhs_coarse, NEWTON_TOL_COARSE, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); info("Solved!"); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solutions(coeff_vec_coarse, Hermes::vector<Space *>(&C_space, &phi_space), Hermes::vector<Solution *>(&C_sln, &phi_sln)); out_fn_vtk(&C_sln,"C_init_sln"); out_fn_vtk(&phi_sln,"phi_init_sln"); //out_fn_vtk(&sln, "sln", ts); Solution *C_ref_sln, *phi_ref_sln; PidTimestepController pid(T_FINAL, false, INIT_TAU); TAU = pid.timestep; info("Starting time iteration with the step %g", *TAU); do { pid.begin_step(); if (pid.get_timestep_number() > 1 && pid.get_timestep_number() % UNREF_FREQ == 0) { info("Global mesh derefinement."); C_mesh.copy(basemesh); if (MULTIMESH) { phi_mesh.copy(basemesh); } C_space.set_uniform_order(Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); phi_space.set_uniform_order(Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); } bool done = false; int as = 1; double err_est; do { info("Time step %d, adaptivity step %d:", pid.get_timestep_number(), as); // Construct globally refined reference mesh // and setup reference space. int order_increase = 1; Hermes::vector<Space *>* ref_spaces = construct_refined_spaces(Hermes::vector<Space *>(&C_space, &phi_space), order_increase); scalar* coeff_vec = new scalar[Space::get_num_dofs(*ref_spaces)]; DiscreteProblem* dp = new DiscreteProblem(&wf, *ref_spaces, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); if (as == 1 && pid.get_timestep_number() == 1) { info("Projecting coarse mesh solution to obtain coefficient vector on new fine mesh."); OGProjection::project_global(*ref_spaces, Hermes::vector<MeshFunction *>(&C_sln, &phi_sln), coeff_vec, matrix_solver); } else { info("Projecting previous fine mesh solution to obtain coefficient vector on new fine mesh."); OGProjection::project_global(*ref_spaces, Hermes::vector<MeshFunction *>(C_ref_sln, phi_ref_sln), coeff_vec, matrix_solver); } if (as > 1) { // Now deallocate the previous mesh info("Deallocating the previous mesh"); //delete C_ref_sln->get_mesh(); //delete phi_ref_sln->get_mesh(); //delete C_ref_sln; //delete phi_ref_sln; } /*TODO TEMP */ if (pid.get_timestep_number() > 1) { delete C_ref_sln; delete phi_ref_sln; } info("Solving on fine mesh:"); if (!solve_newton(coeff_vec, dp, solver, matrix, rhs, NEWTON_TOL_FINE, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Store the result in ref_sln. C_ref_sln = new Solution(ref_spaces->at(0)->get_mesh()); phi_ref_sln = new Solution(ref_spaces->at(1)->get_mesh()); Solution::vector_to_solutions(coeff_vec, *ref_spaces, Hermes::vector<Solution *>(C_ref_sln, phi_ref_sln)); // Projecting reference solution onto the coarse mesh info("Projecting fine mesh solution on coarse mesh."); OGProjection::project_global(Hermes::vector<Space *>(&C_space, &phi_space), Hermes::vector<Solution *>(C_ref_sln, phi_ref_sln), Hermes::vector<Solution *>(&C_sln, &phi_sln), matrix_solver); info("Calculating error estimate."); Adapt* adaptivity = new Adapt(Hermes::vector<Space *>(&C_space, &phi_space), Hermes::vector<ProjNormType> (HERMES_H1_NORM, HERMES_H1_NORM)); Hermes::vector<double> err_est_rel; bool solutions_for_adapt = true; double err_est_rel_total = adaptivity->calc_err_est(Hermes::vector<Solution *>(&C_sln, &phi_sln), Hermes::vector<Solution *>(C_ref_sln, phi_ref_sln), solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_ABS, &err_est_rel) * 100; // Report results. info("ndof_coarse[0]: %d, ndof_fine[0]: %d", C_space.get_num_dofs(), (*ref_spaces)[0]->get_num_dofs()); info("err_est_rel[0]: %g%%", err_est_rel[0]*100); info("ndof_coarse[1]: %d, ndof_fine[1]: %d", phi_space.get_num_dofs(), (*ref_spaces)[1]->get_num_dofs()); info("err_est_rel[1]: %g%%", err_est_rel[1]*100); // Report results. info("ndof_coarse_total: %d, ndof_fine_total: %d, err_est_rel: %g%%", Space::get_num_dofs(Hermes::vector<Space *>(&C_space, &phi_space)), Space::get_num_dofs(*ref_spaces), err_est_rel_total); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) done = true; else { info("Adapting the coarse mesh."); adaptivity->adapt(THRESHOLD); info("Adapted..."); if (Space::get_num_dofs(Hermes::vector<Space *>(&C_space, &phi_space)) >= NDOF_STOP) done = true; else // Increase the counter of performed adaptivity steps. as++; } //as++; delete solver; delete matrix; delete rhs; delete ref_spaces; delete dp; delete[] coeff_vec; done = true; } while (!done); out_fn_vtk(C_ref_sln,"C_sln", pid.get_timestep_number()); out_fn_vtk(phi_ref_sln,"phi_sln", pid.get_timestep_number()); pid.end_step(Hermes::vector<Solution*> (C_ref_sln, phi_ref_sln), Hermes::vector<Solution*> (&C_prev_time, &phi_prev_time)); // Copy last reference solution into sln_prev_time. C_prev_time.copy(C_ref_sln); phi_prev_time.copy(phi_ref_sln); } while (pid.has_next()); //View::wait(); return 0; }
int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); info("TIME_MAX_ITER = %d", TIME_MAX_ITER); // Load the mesh file. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements. for (int i=0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(1, INIT_BDY_REF_NUM); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); // Enter Dirichlet boudnary values. BCValues bc_values; bc_values.add_zero(BDY_DIRICHLET); // Create H1 spaces with default shapesets. H1Space space_T(&mesh, &bc_types, &bc_values, P_INIT); H1Space space_phi(&mesh, &bc_types, &bc_values, P_INIT); Hermes::Tuple<Space*> spaces(&space_T, &space_phi); // Exact solutions for error evaluation. ExactSolution T_exact_solution(&mesh, T_exact), phi_exact_solution(&mesh, phi_exact); // Initialize solution views (their titles will be2 updated in each time step). ScalarView sview_T("", new WinGeom(0, 0, 500, 400)); sview_T.fix_scale_width(50); ScalarView sview_phi("", new WinGeom(0, 500, 500, 400)); sview_phi.fix_scale_width(50); ScalarView sview_T_exact("", new WinGeom(550, 0, 500, 400)); sview_T_exact.fix_scale_width(50); ScalarView sview_phi_exact("", new WinGeom(550, 500, 500, 400)); sview_phi_exact.fix_scale_width(50); char title[100]; // Character array to store the title for an actual view and time step. // Solutions in the previous time step. Solution T_prev_time, phi_prev_time; Hermes::Tuple<MeshFunction*> time_iterates(&T_prev_time, &phi_prev_time); // Solutions in the previous Newton's iteration. Solution T_prev_newton, phi_prev_newton; Hermes::Tuple<Solution*> newton_iterates(&T_prev_newton, &phi_prev_newton); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, jac_TT, jac_TT_ord); wf.add_matrix_form(0, 1, jac_Tphi, jac_Tphi_ord); wf.add_vector_form(0, res_T, res_T_ord, HERMES_ANY, &T_prev_time); wf.add_matrix_form(1, 0, jac_phiT, jac_phiT_ord); wf.add_matrix_form(1, 1, jac_phiphi, jac_phiphi_ord); wf.add_vector_form(1, res_phi, res_phi_ord, HERMES_ANY, &phi_prev_time); // Set initial conditions. T_prev_time.set_exact(&mesh, T_exact); phi_prev_time.set_exact(&mesh, phi_exact); // 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_MATRIX_REORDERING); // Time stepping. int t_step = 1; do { TIME += TAU; info("---- Time step %d, t = %g s:", t_step, TIME); t_step++; info("Projecting to obtain initial vector for the Newton's method."); scalar* coeff_vec = new scalar[Space::get_num_dofs(spaces)]; OGProjection::project_global(spaces, time_iterates, coeff_vec, matrix_solver); Solution::vector_to_solutions(coeff_vec, Hermes::Tuple<Space*>(&space_T, &space_phi), Hermes::Tuple<Solution*>(&T_prev_newton, &phi_prev_newton)); // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp(&wf, spaces, is_linear); // Perform Newton's iteration. info("Newton's iteration..."); bool verbose = true; if(!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solutions(coeff_vec, spaces, newton_iterates); delete [] coeff_vec; // Show the new time level solution. sprintf(title, "Approx. solution for T, t = %g s", TIME); sview_T.set_title(title); sview_T.show(&T_prev_newton); sprintf(title, "Approx. solution for phi, t = %g s", TIME); sview_phi.set_title(title); sview_phi.show(&phi_prev_newton); // Exact solution for comparison with computational results. T_exact_solution.update(&mesh, T_exact); phi_exact_solution.update(&mesh, phi_exact); // Show exact solution. sview_T_exact.show(&T_exact_solution); sprintf(title, "Exact solution for T, t = %g s", TIME); sview_T_exact.set_title(title); sview_phi_exact.show(&phi_exact_solution); sprintf(title, "Exact solution for phi, t = %g s", TIME); sview_phi_exact.set_title(title); // Calculate exact error. info("Calculating error (exact)."); Hermes::Tuple<double> exact_errors; Adapt adaptivity_exact(spaces, Hermes::Tuple<ProjNormType>(HERMES_H1_NORM, HERMES_H1_NORM)); bool solutions_for_adapt = false; adaptivity_exact.calc_err_exact(Hermes::Tuple<Solution *>(&T_prev_newton, &phi_prev_newton), Hermes::Tuple<Solution *>(&T_exact_solution, &phi_exact_solution), solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL, &exact_errors); double maxerr = std::max(exact_errors[0], exact_errors[1])*100; info("Exact solution error for T (H1 norm): %g %%", exact_errors[0]*100); info("Exact solution error for phi (H1 norm): %g %%", exact_errors[1]*100); info("Exact solution error (maximum): %g %%", maxerr); // Prepare previous time level solution for the next time step. T_prev_time.copy(&T_prev_newton); phi_prev_time.copy(&phi_prev_newton); } while (t_step <= TIME_MAX_ITER); // Cleanup. delete matrix; delete rhs; delete solver; // 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(); info("TIME_MAX_ITER = %d", TIME_MAX_ITER); // Load the mesh file. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements. for (int i=0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(1, INIT_BDY_REF_NUM); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); // Enter Dirichlet boudnary values. BCValues bc_values; bc_values.add_zero(BDY_DIRICHLET); // Create H1 spaces with default shapesets. H1Space space_T(&mesh, &bc_types, &bc_values, P_INIT); H1Space space_phi(&mesh, &bc_types, &bc_values, P_INIT); Hermes::vector<Space*> spaces(&space_T, &space_phi); // Exact solutions for error evaluation. ExactSolution T_exact_solution(&mesh, T_exact), phi_exact_solution(&mesh, phi_exact); // Solutions in the previous time step. Solution T_prev_time, phi_prev_time; Hermes::vector<MeshFunction*> time_iterates(&T_prev_time, &phi_prev_time); // Solutions in the previous Newton's iteration. Solution T_prev_newton, phi_prev_newton; Hermes::vector<Solution*> newton_iterates(&T_prev_newton, &phi_prev_newton); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, jac_TT, jac_TT_ord); wf.add_matrix_form(0, 1, jac_Tphi, jac_Tphi_ord); wf.add_vector_form(0, res_T, res_T_ord, HERMES_ANY, &T_prev_time); wf.add_matrix_form(1, 0, jac_phiT, jac_phiT_ord); wf.add_matrix_form(1, 1, jac_phiphi, jac_phiphi_ord); wf.add_vector_form(1, res_phi, res_phi_ord, HERMES_ANY, &phi_prev_time); // Set initial conditions. T_prev_time.set_exact(&mesh, T_exact); phi_prev_time.set_exact(&mesh, phi_exact); // 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_MATRIX_REORDERING); // Time stepping. int t_step = 1; do { TIME += TAU; info("---- Time step %d, t = %g s:", t_step, TIME); t_step++; info("Projecting to obtain initial vector for the Newton's method."); scalar* coeff_vec = new scalar[Space::get_num_dofs(spaces)]; OGProjection::project_global(spaces, time_iterates, coeff_vec, matrix_solver); Solution::vector_to_solutions(coeff_vec, Hermes::vector<Space*>(&space_T, &space_phi), Hermes::vector<Solution*>(&T_prev_newton, &phi_prev_newton)); // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp(&wf, spaces, is_linear); // Perform Newton's iteration. info("Newton's iteration..."); bool verbose = false; if(!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solutions(coeff_vec, spaces, newton_iterates); delete [] coeff_vec; // Exact solution for comparison with computational results. T_exact_solution.update(&mesh, T_exact); phi_exact_solution.update(&mesh, phi_exact); // Calculate exact error. info("Calculating error (exact)."); Hermes::vector<double> exact_errors; Adapt adaptivity_exact(spaces); bool solutions_for_adapt = false; adaptivity_exact.calc_err_exact(Hermes::vector<Solution *>(&T_prev_newton, &phi_prev_newton), Hermes::vector<Solution *>(&T_exact_solution, &phi_exact_solution), &exact_errors, solutions_for_adapt); double maxerr = std::max(exact_errors[0], exact_errors[1])*100; info("Exact solution error for T (H1 norm): %g %%", exact_errors[0]*100); info("Exact solution error for phi (H1 norm): %g %%", exact_errors[1]*100); info("Exact solution error (maximum): %g %%", maxerr); // Prepare previous time level solution for the next time step. T_prev_time.copy(&T_prev_newton); phi_prev_time.copy(&phi_prev_newton); } while (t_step <= TIME_MAX_ITER); // Cleanup. delete matrix; delete rhs; delete solver; info("Coordinate ( 0, 0) T value = %lf", T_prev_time.get_pt_value(0.0, 0.0)); info("Coordinate ( 25, 25) T value = %lf", T_prev_time.get_pt_value(25.0, 25.0)); info("Coordinate ( 75, 25) T value = %lf", T_prev_time.get_pt_value(75.0, 25.0)); info("Coordinate ( 25, 75) T value = %lf", T_prev_time.get_pt_value(25.0, 75.0)); info("Coordinate ( 75, 75) T value = %lf", T_prev_time.get_pt_value(75.0, 75.0)); info("Coordinate ( 0, 0) phi value = %lf", phi_prev_time.get_pt_value(0.0, 0.0)); info("Coordinate ( 25, 25) phi value = %lf", phi_prev_time.get_pt_value(25.0, 25.0)); info("Coordinate ( 75, 25) phi value = %lf", phi_prev_time.get_pt_value(75.0, 25.0)); info("Coordinate ( 25, 75) phi value = %lf", phi_prev_time.get_pt_value(25.0, 75.0)); info("Coordinate ( 75, 75) phi value = %lf", phi_prev_time.get_pt_value(75.0, 75.0)); int success = 1; double eps = 1e-5; if (fabs(T_prev_time.get_pt_value(0.0, 0.0) - 0.000000) > eps) { printf("Coordinate ( 0, 0) T value = %lf\n", T_prev_time.get_pt_value(0.0, 0.0)); success = 0; } if (fabs(T_prev_time.get_pt_value(25.0, 25.0) - 0.915885) > eps) { printf("Coordinate ( 25, 25) T value = %lf\n", T_prev_time.get_pt_value(25.0, 25.0)); success = 0; } if (fabs(T_prev_time.get_pt_value(75.0, 25.0) - 0.915885) > eps) { printf("Coordinate ( 75, 25) T value = %lf\n", T_prev_time.get_pt_value(75.0, 25.0)); success = 0; } if (fabs(T_prev_time.get_pt_value(25.0, 75.0) - 0.915885) > eps) { printf("Coordinate ( 25, 75) T value = %lf\n", T_prev_time.get_pt_value(25.0, 75.0)); success = 0; } if (fabs(T_prev_time.get_pt_value(75.0, 75.0) - 0.915885) > eps) { printf("Coordinate ( 75, 75) T value = %lf\n", T_prev_time.get_pt_value(75.0, 75.0)); success = 0; } if (fabs(phi_prev_time.get_pt_value(0.0, 0.0) - 0.000000) > eps) { printf("Coordinate ( 0, 0) phi value = %lf\n", phi_prev_time.get_pt_value(0.0, 0.0)); success = 0; } if (fabs(phi_prev_time.get_pt_value(25.0, 25.0) - 0.071349) > eps) { printf("Coordinate ( 25, 25) phi value = %lf\n", phi_prev_time.get_pt_value(25.0, 25.0)); success = 0; } if (fabs(phi_prev_time.get_pt_value(75.0, 25.0) - 0.214063) > eps) { printf("Coordinate ( 75, 25) phi value = %lf\n", phi_prev_time.get_pt_value(75.0, 25.0)); success = 0; } if (fabs(phi_prev_time.get_pt_value(25.0, 75.0) - 0.214063) > eps) { printf("Coordinate ( 25, 75) phi value = %lf\n", phi_prev_time.get_pt_value(25.0, 75.0)); success = 0; } if (fabs(phi_prev_time.get_pt_value(75.0, 75.0) - 0.642226) > eps) { printf("Coordinate ( 75, 75) phi value = %lf\n", phi_prev_time.get_pt_value(75.0, 75.0)); success = 0; } if (success == 1) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(BDY_DIRICHLET, INIT_BDY_REF_NUM); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_function(BDY_DIRICHLET, essential_bc_values); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Solution for the previous time level. Solution u_prev_time; // Initialize the weak formulation. WeakForm wf; if (TIME_INTEGRATION == 1) { wf.add_matrix_form(jac_euler, jac_ord, HERMES_NONSYM, HERMES_ANY, &u_prev_time); wf.add_vector_form(res_euler, res_ord, HERMES_ANY, &u_prev_time); } else { wf.add_matrix_form(jac_cranic, jac_ord, HERMES_NONSYM, HERMES_ANY, &u_prev_time); wf.add_vector_form(res_cranic, res_ord, HERMES_ANY, &u_prev_time); } // Project the function init_cond() on the FE space // to obtain initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[Space::get_num_dofs(&space)]; info("Projecting initial condition to obtain initial vector for the Newton's method."); OGProjection::project_global(&space, init_cond, coeff_vec, matrix_solver); Solution::vector_to_solution(coeff_vec, &space, &u_prev_time); // Initialize views. ScalarView sview("Solution", new WinGeom(0, 0, 500, 400)); OrderView oview("Mesh", new WinGeom(520, 0, 450, 400)); oview.show(&space); sview.show(&u_prev_time); // Time stepping loop: double current_time = 0.0; int t_step = 1; do { info("---- Time step %d, t = %g s.", t_step, current_time); t_step++; // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp(&wf, &space, is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Perform Newton's iteration. bool verbose = true; if (!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solution(coeff_vec, &space, &u_prev_time); // Cleanup. delete matrix; delete rhs; delete solver; // Update time. current_time += TAU; // Show the new time level solution. char title[100]; sprintf(title, "Solution, t = %g", current_time); sview.set_title(title); sview.show(&u_prev_time); } while (current_time < T_FINAL); delete [] coeff_vec; // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain-excentric.mesh", &mesh); //mloader.load("domain-concentric.mesh", &mesh); // Initial mesh refinements. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(BDY_INNER, INIT_BDY_REF_NUM_INNER, false); // true for anisotropic refinements mesh.refine_towards_boundary(BDY_OUTER, INIT_BDY_REF_NUM_OUTER, false); // false for isotropic refinements // Enter boundary markers for x-velocity and y-velocity. BCTypes bc_types; bc_types.add_bc_dirichlet(Hermes::Tuple<int>(BDY_INNER, BDY_OUTER)); BCTypes bc_types_p; bc_types_p.add_bc_none(Hermes::Tuple<int>(BDY_INNER, BDY_OUTER)); // Enter Dirichlet boundary values. BCValues bc_values_xvel(&TIME); bc_values_xvel.add_timedep_function(BDY_INNER, essential_bc_values_xvel); bc_values_xvel.add_zero(BDY_OUTER); BCValues bc_values_yvel(&TIME); bc_values_yvel.add_timedep_function(BDY_INNER, essential_bc_values_yvel); bc_values_yvel.add_zero(BDY_OUTER); // Create spaces with default shapesets. H1Space xvel_space(&mesh, &bc_types, &bc_values_xvel, P_INIT_VEL); H1Space yvel_space(&mesh, &bc_types, &bc_values_yvel, P_INIT_VEL); #ifdef PRESSURE_IN_L2 L2Space p_space(&mesh, P_INIT_PRESSURE); #else H1Space p_space(&mesh, &bc_types_p, P_INIT_PRESSURE); #endif // Calculate and report the number of degrees of freedom. int ndof = Space::get_num_dofs(Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space)); info("ndof = %d.", ndof); // Define projection norms. ProjNormType vel_proj_norm = HERMES_H1_NORM; #ifdef PRESSURE_IN_L2 ProjNormType p_proj_norm = HERMES_L2_NORM; #else ProjNormType p_proj_norm = HERMES_H1_NORM; #endif // Solutions for the Newton's iteration and time stepping. info("Setting initial conditions."); Solution xvel_prev_time, yvel_prev_time, p_prev_time; xvel_prev_time.set_zero(&mesh); yvel_prev_time.set_zero(&mesh); p_prev_time.set_zero(&mesh); // Initialize weak formulation. WeakForm wf(3); if (NEWTON) { wf.add_matrix_form(0, 0, callback(bilinear_form_sym_0_0_1_1), HERMES_SYM); wf.add_matrix_form(0, 0, callback(newton_bilinear_form_unsym_0_0), HERMES_NONSYM, HERMES_ANY); wf.add_matrix_form(0, 1, callback(newton_bilinear_form_unsym_0_1), HERMES_NONSYM, HERMES_ANY); wf.add_matrix_form(0, 2, callback(bilinear_form_unsym_0_2), HERMES_ANTISYM); wf.add_matrix_form(1, 0, callback(newton_bilinear_form_unsym_1_0), HERMES_NONSYM, HERMES_ANY); wf.add_matrix_form(1, 1, callback(bilinear_form_sym_0_0_1_1), HERMES_SYM); wf.add_matrix_form(1, 1, callback(newton_bilinear_form_unsym_1_1), HERMES_NONSYM, HERMES_ANY); wf.add_matrix_form(1, 2, callback(bilinear_form_unsym_1_2), HERMES_ANTISYM); wf.add_vector_form(0, callback(newton_F_0), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&xvel_prev_time, &yvel_prev_time)); wf.add_vector_form(1, callback(newton_F_1), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&xvel_prev_time, &yvel_prev_time)); wf.add_vector_form(2, callback(newton_F_2), HERMES_ANY); } else { wf.add_matrix_form(0, 0, callback(bilinear_form_sym_0_0_1_1), HERMES_SYM); wf.add_matrix_form(0, 0, callback(simple_bilinear_form_unsym_0_0_1_1), HERMES_NONSYM, HERMES_ANY, Hermes::Tuple<MeshFunction*>(&xvel_prev_time, &yvel_prev_time)); wf.add_matrix_form(1, 1, callback(bilinear_form_sym_0_0_1_1), HERMES_SYM); wf.add_matrix_form(1, 1, callback(simple_bilinear_form_unsym_0_0_1_1), HERMES_NONSYM, HERMES_ANY, Hermes::Tuple<MeshFunction*>(&xvel_prev_time, &yvel_prev_time)); wf.add_matrix_form(0, 2, callback(bilinear_form_unsym_0_2), HERMES_ANTISYM); wf.add_matrix_form(1, 2, callback(bilinear_form_unsym_1_2), HERMES_ANTISYM); wf.add_vector_form(0, callback(simple_linear_form), HERMES_ANY, &xvel_prev_time); wf.add_vector_form(1, callback(simple_linear_form), HERMES_ANY, &yvel_prev_time); } // Project initial conditions on FE spaces to obtain initial coefficient // vector for the Newton's method. scalar* coeff_vec = new scalar[Space::get_num_dofs(Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space))]; if (NEWTON) { info("Projecting initial conditions to obtain initial vector for the Newton's method."); OGProjection::project_global(Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space), Hermes::Tuple<MeshFunction*>(&xvel_prev_time, &yvel_prev_time, &p_prev_time), coeff_vec, matrix_solver, Hermes::Tuple<ProjNormType>(vel_proj_norm, vel_proj_norm, p_proj_norm)); } // Time-stepping loop: char title[100]; int num_time_steps = T_FINAL / TAU; for (int ts = 1; ts <= num_time_steps; ts++) { TIME += TAU; info("---- Time step %d, time = %g:", ts, TIME); // Update time-dependent essential BC are used. if (TIME <= STARTUP_TIME) { info("Updating time-dependent essential BC."); update_essential_bc_values(Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space)); } if (NEWTON) { info("Performing Newton's method."); // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp(&wf, Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_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 nonlinear problem:"); bool verbose = true; if (!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the actual solutions. Solution::vector_to_solutions(coeff_vec, Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space), Hermes::Tuple<Solution *>(&xvel_prev_time, &yvel_prev_time, &p_prev_time)); // Cleanup. delete matrix; delete rhs; delete solver; } else { // Linear solve. info("Assembling and solving linear problem."); bool is_linear = true; DiscreteProblem dp(&wf, Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_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); 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_solutions(solver->get_solution(), Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space), Hermes::Tuple<Solution *>(&xvel_prev_time, &yvel_prev_time, &p_prev_time)); else error ("Matrix solver failed.\n"); } } // Clean up. delete [] coeff_vec; info("Coordinate ( 0.1, 0.0) xvel value = %lf", xvel_prev_time.get_pt_value(0.1, 0.0)); info("Coordinate ( 0.5, 0.0) xvel value = %lf", xvel_prev_time.get_pt_value(0.5, 0.0)); info("Coordinate ( 0.9, 0.0) xvel value = %lf", xvel_prev_time.get_pt_value(0.9, 0.0)); info("Coordinate ( 1.3, 0.0) xvel value = %lf", xvel_prev_time.get_pt_value(1.3, 0.0)); info("Coordinate ( 1.7, 0.0) xvel value = %lf", xvel_prev_time.get_pt_value(1.7, 0.0)); info("Coordinate ( 0.1, 0.0) yvel value = %lf", yvel_prev_time.get_pt_value(0.1, 0.0)); info("Coordinate ( 0.5, 0.0) yvel value = %lf", yvel_prev_time.get_pt_value(0.5, 0.0)); info("Coordinate ( 0.9, 0.0) yvel value = %lf", yvel_prev_time.get_pt_value(0.9, 0.0)); info("Coordinate ( 1.3, 0.0) yvel value = %lf", yvel_prev_time.get_pt_value(1.3, 0.0)); info("Coordinate ( 1.7, 0.0) yvel value = %lf", yvel_prev_time.get_pt_value(1.7, 0.0)); int success = 1; double eps = 1e-5; if (fabs(xvel_prev_time.get_pt_value(0.1, 0.0) - (0.000000)) > eps) { printf("Coordinate ( 0.1, 0.0) xvel value = %lf\n", xvel_prev_time.get_pt_value(0.1, 0.0)); success = 0; } if (fabs(xvel_prev_time.get_pt_value(0.5, 0.0) - (-0.000347)) > eps) { printf("Coordinate ( 0.5, 0.0) xvel value = %lf\n", xvel_prev_time.get_pt_value(0.5, 0.0)); success = 0; } if (fabs(xvel_prev_time.get_pt_value(0.9, 0.0) - (-0.000047)) > eps) { printf("Coordinate ( 0.9, 0.0) xvel value = %lf\n", xvel_prev_time.get_pt_value(0.9, 0.0)); success = 0; } if (fabs(xvel_prev_time.get_pt_value(1.3, 0.0) - (-0.000004)) > eps) { printf("Coordinate ( 1.3, 0.0) xvel value = %lf\n", xvel_prev_time.get_pt_value(1.3, 0.0)); success = 0; } if (fabs(xvel_prev_time.get_pt_value(1.7, 0.0) - (-0.000001)) > eps) { printf("Coordinate ( 1.7, 0.0) xvel value = %lf\n", xvel_prev_time.get_pt_value(1.7, 0.0)); success = 0; } if (fabs(yvel_prev_time.get_pt_value(0.1, 0.0) - (-0.100000)) > eps) { printf("Coordinate ( 0.1, 0.0) yvel value = %lf\n", yvel_prev_time.get_pt_value(0.1, 0.0)); success = 0; } if (fabs(yvel_prev_time.get_pt_value(0.5, 0.0) - (0.001477)) > eps) { printf("Coordinate ( 0.5, 0.0) yvel value = %lf\n", yvel_prev_time.get_pt_value(0.5, 0.0)); success = 0; } if (fabs(yvel_prev_time.get_pt_value(0.9, 0.0) - (0.000572)) > eps) { printf("Coordinate ( 0.9, 0.0) yvel value = %lf\n", yvel_prev_time.get_pt_value(0.9, 0.0)); success = 0; } if (fabs(yvel_prev_time.get_pt_value(1.3, 0.0) - (0.000296)) > eps) { printf("Coordinate ( 1.3, 0.0) yvel value = %lf\n", yvel_prev_time.get_pt_value(1.3, 0.0)); success = 0; } if (fabs(yvel_prev_time.get_pt_value(1.7, 0.0) - (0.000169)) > eps) { printf("Coordinate ( 1.7, 0.0) yvel value = %lf\n", yvel_prev_time.get_pt_value(1.7, 0.0)); success = 0; } if (success == 1) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }