int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes_2D; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst left_t("Left", 1.0); EssentialBCs bcs_t(&left_t); DefaultEssentialBCConst left_c("Left", 0.0); EssentialBCs bcs_c(&left_c); // Create H1 spaces with default shapesets. H1Space* t_space = new H1Space(&mesh, &bcs_t, P_INIT); H1Space* c_space = new H1Space(&mesh, &bcs_c, P_INIT); int ndof = Space::get_num_dofs(Hermes::vector<Space*>(t_space, c_space)); info("ndof = %d.", ndof); // Define initial conditions. InitialSolutionTemperature t_prev_time_1(&mesh, x1); InitialSolutionConcentration c_prev_time_1(&mesh, x1, Le); InitialSolutionTemperature t_prev_time_2(&mesh, x1); InitialSolutionConcentration c_prev_time_2(&mesh, x1, Le); Solution t_prev_newton; Solution c_prev_newton; // Filters for the reaction rate omega and its derivatives. CustomFilter omega(Hermes::vector<MeshFunction*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); CustomFilterDt omega_dt(Hermes::vector<MeshFunction*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); CustomFilterDc omega_dc(Hermes::vector<MeshFunction*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); // Initialize visualization. ScalarView rview("Reaction rate", new WinGeom(0, 0, 800, 230)); scalar* coeff_vec = new scalar[Space::get_num_dofs(Hermes::vector<Space*>(t_space, c_space))]; memset(coeff_vec, 0, ndof * sizeof(double)); Solution::vector_to_solutions(coeff_vec, Hermes::vector<Space*>(t_space, c_space), Hermes::vector<Solution *>(&t_prev_time_1, &c_prev_time_1)); // Initialize the weak formulation. double current_time = 0; CustomWeakForm wf(Le, alpha, beta, kappa, x1, TAU, false, PRECOND, &omega, &omega_dt, &omega_dc, &t_prev_time_1, &c_prev_time_1, &t_prev_time_2, &c_prev_time_2); // Initialize the FE problem. DiscreteProblem dp(&wf, Hermes::vector<Space*>(t_space, c_space)); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Time stepping: int ts = 1; bool jacobian_changed = true; do { info("---- Time step %d, time %3.5f s", ts, current_time); if (NEWTON) { // Perform Newton's iteration. info("Solving nonlinear problem:"); bool verbose = true; bool jacobian_changed = true; if (!hermes_2D.solve_newton(coeff_vec, &dp, solver, matrix, rhs, jacobian_changed, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); Solution::vector_to_solutions(coeff_vec, Hermes::vector<Space*>(t_space, c_space), Hermes::vector<Solution*>(&t_prev_newton, &c_prev_newton)); // Saving solutions for the next time step. if(ts > 1) { t_prev_time_2.copy(&t_prev_time_1); c_prev_time_2.copy(&c_prev_time_1); } t_prev_time_1.copy(&t_prev_newton); c_prev_time_1.copy(&c_prev_newton); } // Visualization. rview.set_min_max_range(0.0,2.0); rview.show(&omega); // Increase current time and time step counter. current_time += TAU; ts++; } while (current_time < T_FINAL); // Clean up. delete [] coeff_vec; 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. Hermes::Mixins::TimeMeasurable cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinemets. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst<double> left_t("Left", 1.0); EssentialBCs<double> bcs_t(&left_t); DefaultEssentialBCConst<double> left_c("Left", 0.0); EssentialBCs<double> bcs_c(&left_c); // Create H1 spaces with default shapesets. H1Space<double>* t_space = new H1Space<double>(&mesh, &bcs_t, P_INIT); H1Space<double>* c_space = new H1Space<double>(&mesh, &bcs_c, P_INIT); int ndof = Space<double>::get_num_dofs(Hermes::vector<const Space<double>*>(t_space, c_space)); Hermes::Mixins::Loggable::Static::info("ndof = %d.", ndof); // Define initial conditions. InitialSolutionTemperature t_prev_time_1(&mesh, x1); InitialSolutionConcentration c_prev_time_1(&mesh, x1, Le); InitialSolutionTemperature t_prev_time_2(&mesh, x1); InitialSolutionConcentration c_prev_time_2(&mesh, x1, Le); Solution<double> t_prev_newton; Solution<double> c_prev_newton; // Filters for the reaction rate omega and its derivatives. CustomFilter omega(Hermes::vector<Solution<double>*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); CustomFilterDt omega_dt(Hermes::vector<Solution<double>*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); CustomFilterDc omega_dc(Hermes::vector<Solution<double>*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); // Initialize visualization. ScalarView rview("Reaction rate", new WinGeom(0, 0, 800, 230)); // Initialize weak formulation. CustomWeakForm wf(Le, alpha, beta, kappa, x1, TAU, TRILINOS_JFNK, PRECOND, &omega, &omega_dt, &omega_dc, &t_prev_time_1, &c_prev_time_1, &t_prev_time_2, &c_prev_time_2); // Project the functions "t_prev_time_1" and "c_prev_time_1" on the FE space // in order to obtain initial vector for NOX. Hermes::Mixins::Loggable::Static::info("Projecting initial solutions on the FE meshes."); double* coeff_vec = new double[ndof]; OGProjection<double> ogProjection; ogProjection.project_global(Hermes::vector<const Space<double> *>(t_space, c_space), Hermes::vector<MeshFunction<double>*>(&t_prev_time_1, &c_prev_time_1), coeff_vec); // Measure the projection time. double proj_time = cpu_time.tick().last(); // Initialize finite element problem. DiscreteProblem<double> dp(&wf, Hermes::vector<const Space<double>*>(t_space, c_space)); // Initialize NOX solver and preconditioner. NewtonSolverNOX<double> solver(&dp); MlPrecond<double> pc("sa"); if (PRECOND) { if (TRILINOS_JFNK) solver.set_precond(pc); else solver.set_precond("New Ifpack"); } if (TRILINOS_OUTPUT) solver.set_output_flags(NOX::Utils::Error | NOX::Utils::OuterIteration | NOX::Utils::OuterIterationStatusTest | NOX::Utils::LinearSolverDetails); // Time stepping loop: double total_time = 0.0; cpu_time.tick_reset(); for (int ts = 1; total_time <= T_FINAL; ts++) { Hermes::Mixins::Loggable::Static::info("---- Time step %d, t = %g s", ts, total_time + TAU); cpu_time.tick(); try { solver.solve(coeff_vec); } catch(std::exception& e) { std::cout << e.what(); } Solution<double>::vector_to_solutions(solver.get_sln_vector(), Hermes::vector<const Space<double> *>(t_space, c_space), Hermes::vector<Solution<double> *>(&t_prev_newton, &c_prev_newton)); cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Number of nonlin iterations: %d (norm of residual: %g)", solver.get_num_iters(), solver.get_residual()); Hermes::Mixins::Loggable::Static::info("Total number of iterations in linsolver: %d (achieved tolerance in the last step: %g)", solver.get_num_lin_iters(), solver.get_achieved_tol()); // Time measurement. cpu_time.tick(); // Skip visualization time. cpu_time.tick(); // Update global time. total_time += TAU; // Saving solutions for the next time step. if(ts > 1) { t_prev_time_2.copy(&t_prev_time_1); c_prev_time_2.copy(&c_prev_time_1); } t_prev_time_1.copy(&t_prev_newton); c_prev_time_1.copy(&c_prev_newton); // Visualization. rview.set_min_max_range(0.0,2.0); rview.show(&omega); cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Total running time for time level %d: %g s.", ts, cpu_time.tick().last()); } // Wait for all views to be closed. View::wait(); return 0; }