int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinemets. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Create H1 spaces with default shapesets. H1Space* t_space = new H1Space(&mesh, bc_types, essential_bc_values_t, P_INIT); H1Space* c_space = new H1Space(&mesh, bc_types, essential_bc_values_c, P_INIT); int ndof = get_num_dofs(Tuple<Space *>(t_space, c_space)); info("ndof = %d.", ndof); // Define initial conditions. Solution t_prev_time_1, c_prev_time_1, t_prev_time_2, c_prev_time_2, t_iter, c_iter, t_prev_newton, c_prev_newton; t_prev_time_1.set_exact(&mesh, temp_ic); c_prev_time_1.set_exact(&mesh, conc_ic); t_prev_time_2.set_exact(&mesh, temp_ic); c_prev_time_2.set_exact(&mesh, conc_ic); t_iter.set_exact(&mesh, temp_ic); c_iter.set_exact(&mesh, conc_ic); // Filters for the reaction rate omega and its derivatives. DXDYFilter omega(omega_fn, Tuple<MeshFunction*>(&t_prev_time_1, &c_prev_time_1)); DXDYFilter omega_dt(omega_dt_fn, Tuple<MeshFunction*>(&t_prev_time_1, &c_prev_time_1)); DXDYFilter omega_dc(omega_dc_fn, Tuple<MeshFunction*>(&t_prev_time_1, &c_prev_time_1)); // Initialize visualization. ScalarView rview("Reaction rate", new WinGeom(0, 0, 800, 230)); // Initialize weak formulation. WeakForm wf(2, JFNK ? true : false); if (!JFNK || (JFNK && PRECOND == 1)) { wf.add_matrix_form(callback(newton_bilinear_form_0_0), H2D_UNSYM, H2D_ANY, &omega_dt); wf.add_matrix_form_surf(0, 0, callback(newton_bilinear_form_0_0_surf), 3); wf.add_matrix_form(1, 1, callback(newton_bilinear_form_1_1), H2D_UNSYM, H2D_ANY, &omega_dc); wf.add_matrix_form(0, 1, callback(newton_bilinear_form_0_1), H2D_UNSYM, H2D_ANY, &omega_dc); wf.add_matrix_form(1, 0, callback(newton_bilinear_form_1_0), H2D_UNSYM, H2D_ANY, &omega_dt); } else if (PRECOND == 2) { wf.add_matrix_form(0, 0, callback(precond_0_0)); wf.add_matrix_form(1, 1, callback(precond_1_1)); } wf.add_vector_form(0, callback(newton_linear_form_0), H2D_ANY, Tuple<MeshFunction*>(&t_prev_time_1, &t_prev_time_2, &omega)); wf.add_vector_form_surf(0, callback(newton_linear_form_0_surf), 3); wf.add_vector_form(1, callback(newton_linear_form_1), H2D_ANY, Tuple<MeshFunction*>(&c_prev_time_1, &c_prev_time_2, &omega)); // Project the functions "t_iter" and "c_iter" on the FE space // in order to obtain initial vector for NOX. info("Projecting initial solutions on the FE meshes."); Vector* coeff_vec = new AVector(ndof); project_global(Tuple<Space *>(t_space, c_space), Tuple<int>(H2D_H1_NORM, H2D_H1_NORM), Tuple<MeshFunction*>(&t_prev_time_1, &c_prev_time_1), Tuple<Solution*>(&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. FeProblem fep(&wf, Tuple<Space*>(t_space, c_space)); // Initialize NOX solver and preconditioner. NoxSolver solver(&fep); MlPrecond pc("sa"); if (PRECOND) { if (JFNK) solver.set_precond(&pc); else solver.set_precond("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 <= 60.0; ts++) { info("---- Time step %d, t = %g s", ts, total_time + TAU); cpu_time.tick(HERMES_SKIP); solver.set_init_sln(coeff_vec->get_c_array()); bool solved = solver.solve(); if (solved) { double* s = solver.get_solution_vector(); AVector *tmp_vector = new AVector(ndof); tmp_vector->set_c_array(s, ndof); t_prev_newton.set_fe_solution(t_space, tmp_vector); c_prev_newton.set_fe_solution(c_space, tmp_vector); delete tmp_vector; cpu_time.tick(); info("Number of nonlin iterations: %d (norm of residual: %g)", solver.get_num_iters(), solver.get_residual()); 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(HERMES_SKIP); // Visualization. DXDYFilter omega_view(omega_fn, Tuple<MeshFunction*>(&t_prev_newton, &c_prev_newton)); rview.set_min_max_range(0.0,2.0); cpu_time.tick(HERMES_SKIP); // Skip visualization time. cpu_time.tick(HERMES_SKIP); // Update global time. total_time += TAU; // Saving solutions for the next time step. t_prev_time_2.copy(&t_prev_time_1); c_prev_time_2.copy(&c_prev_time_1); t_prev_time_1 = t_prev_newton; c_prev_time_1 = c_prev_newton; } else error("NOX failed."); 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; }
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; }