int main(int argc, char* argv[]) { // Choose a Butcher's table or define your own. ButcherTable bt(butcher_table_type); // Initialize the time. double current_time = 0; // mesh-> MeshSharedPtr mesh(new Mesh); // Init mesh-> MeshReaderH2D 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("Boundary_air", INIT_REF_NUM_BDY); mesh->refine_towards_boundary("Boundary_ground", INIT_REF_NUM_BDY); // Initialize boundary conditions. Hermes::Hermes2D::DefaultEssentialBCConst<double> bc_essential("Boundary_ground", TEMP_INIT); Hermes::Hermes2D::EssentialBCs<double> bcs(&bc_essential); // space-> SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); // Solution pointer. MeshFunctionSharedPtr<double> sln_time_prev(new ConstantSolution<double>(mesh, TEMP_INIT)); MeshFunctionSharedPtr<double> sln_time_new(new Solution<double>(mesh)); WeakFormSharedPtr<double> wf(new CustomWeakFormHeatRK("Boundary_air", ALPHA, LAMBDA, HEATCAP, RHO, ¤t_time, TEMP_INIT, T_FINAL)); // Initialize views. Hermes::Hermes2D::Views::ScalarView Tview("Temperature", new Hermes::Hermes2D::Views::WinGeom(0, 0, 450, 600)); Tview.set_min_max_range(0, 20); Tview.fix_scale_width(30); // Initialize Runge-Kutta time stepping. RungeKutta<double> runge_kutta(wf, space, &bt); runge_kutta.set_tolerance(NEWTON_TOL); runge_kutta.set_verbose_output(true); runge_kutta.set_time_step(time_step); // Iteration number. int iteration = 0; // Time stepping loop: do { // Perform one Runge-Kutta time step according to the selected Butcher's table. try { runge_kutta.set_time(current_time); runge_kutta.rk_time_step_newton(sln_time_prev, sln_time_new); } catch (Exceptions::Exception& e) { e.print_msg(); } // Show the new_ time level solution. char title[100]; 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 current time and time step counter. current_time += time_step; iteration++; } while (current_time < T_FINAL); // Wait for the view to be closed. Hermes::Hermes2D::Views::View::wait(); return 0; }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("cathedral.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary("Boundary air", INIT_REF_NUM_BDY); mesh.refine_towards_boundary("Boundary ground", INIT_REF_NUM_BDY); // Previous time level solution (initialized by the external temperature). Solution tsln(&mesh, TEMP_INIT); // Initialize the weak formulation. double current_time = 0; CustomWeakFormHeatRK1 wf("Boundary air", ALPHA, LAMBDA, HEATCAP, RHO, time_step, ¤t_time, TEMP_INIT, T_FINAL, &tsln); // Initialize boundary conditions. DefaultEssentialBCConst bc_essential("Boundary ground", TEMP_INIT); EssentialBCs bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space space(&mesh, &bcs, P_INIT); int ndof = space.get_num_dofs(); info("ndof = %d", ndof); // Initialize the FE problem. DiscreteProblem dp(&wf, &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); solver->set_factorization_scheme(HERMES_REUSE_FACTORIZATION_COMPLETELY); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof]; memset(coeff_vec, 0, ndof*sizeof(scalar)); // 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 jacobian_changed = true; do { info("---- Time step %d, time %3.5f s", ts, current_time); // Perform Newton's iteration. if (!hermes2d.solve_newton(coeff_vec, &dp, solver, matrix, rhs, jacobian_changed)) error("Newton's iteration failed."); jacobian_changed = false; // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solution(coeff_vec, &space, &tsln); // Visualize the solution. char title[100]; sprintf(title, "Time %3.2f s", 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[]) { // 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("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_vol)); wf.add_vector_form(callback(stac_residual_vol)); wf.add_matrix_form_surf(callback(stac_jacobian_surf), BDY_AIR); wf.add_vector_form_surf(callback(stac_residual_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[]) { // 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); // Initialize views. ScalarView Tview("Temperature", new WinGeom(0, 0, 450, 600)); char title[100]; sprintf(title, "Time %3.5f, exterior temperature %3.5f", TIME, temp_ext(TIME)); Tview.set_min_max_range(0,20); Tview.set_title(title); Tview.fix_scale_width(3); // 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); // Update the time variable. TIME += TAU; // Visualize the solution. sprintf(title, "Time %3.2f, exterior temperature %3.5f", TIME, temp_ext(TIME)); Tview.set_title(title); Tview.show(&tsln); } // Wait for the view to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // load and refine mesh Mesh mesh; mesh.load("cathedral.mesh"); for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(2, 5); // set up shapeset H1Shapeset shapeset; PrecalcShapeset pss(&shapeset); // set up spaces H1Space space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_bc_values(bc_values); space.set_uniform_order(P_INIT); // enumerate basis functions space.assign_dofs(); // set initial condition Solution tsln; tsln.set_const(&mesh, T_INIT); // weak formulation WeakForm wf(1); wf.add_biform(0, 0, bilinear_form<double, double>, bilinear_form<Ord, Ord>); wf.add_biform_surf(0, 0, bilinear_form_surf<double, double>, bilinear_form_surf<Ord, Ord>, marker_air); wf.add_liform(0, linear_form<double, double>, linear_form<Ord, Ord>, ANY, 1, &tsln); wf.add_liform_surf(0, linear_form_surf<double, double>, linear_form_surf<Ord, Ord>, marker_air); // matrix solver UmfpackSolver umfpack; // linear system LinSystem ls(&wf, &umfpack); ls.set_spaces(1, &space); ls.set_pss(1, &pss); // visualisation ScalarView Tview("Temperature", 0, 0, 450, 600); char title[100]; sprintf(title, "Time %3.5f, exterior temperature %3.5f", TIME, temp_ext(TIME)); Tview.set_min_max_range(0,20); Tview.set_title(title); Tview.fix_scale_width(3); // time stepping int nsteps = (int)(FINAL_TIME/TAU + 0.5); bool rhsonly = false; for(int n = 1; n <= nsteps; n++) { info("\n---- Time %3.5f, time step %d, ext_temp %g ----------", TIME, n, temp_ext(TIME)); // assemble and solve ls.assemble(rhsonly); rhsonly = true; ls.solve(1, &tsln); // shifting the time variable TIME += TAU; // visualization of solution sprintf(title, "Time %3.2f, exterior temperature %3.5f", TIME, temp_ext(TIME)); Tview.set_title(title); Tview.show(&tsln); //Tview.wait_for_keypress(); } // Note: a separate example shows how to create videos // wait for keyboard or mouse input View::wait("Waiting for keyboard or mouse input."); 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[]) { #ifdef WITH_PARALUTION HermesCommonApi.set_integral_param_value(matrixSolverType, SOLVER_PARALUTION_AMG); // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D 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_boundary("Boundary air", INIT_REF_NUM_BDY); mesh->refine_towards_boundary("Boundary ground", INIT_REF_NUM_BDY); // Previous time level solution (initialized by the external temperature). MeshFunctionSharedPtr<double> tsln(new ConstantSolution<double> (mesh, TEMP_INIT)); // Initialize the weak formulation. double current_time = 0; CustomWeakFormHeatRK1 wf("Boundary air", ALPHA, LAMBDA, HEATCAP, RHO, time_step, ¤t_time, TEMP_INIT, T_FINAL, tsln); // Initialize boundary conditions. DefaultEssentialBCConst<double> bc_essential("Boundary ground", TEMP_INIT); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); int ndof = space->get_num_dofs(); Hermes::Mixins::Loggable::Static::info("ndof = %d", ndof); // Initialize Newton solver. NewtonSolver<double> newton(&wf, space); #ifdef SHOW_OUTPUT newton.set_verbose_output(true); #else newton.set_verbose_output(false); #endif newton.set_jacobian_constant(); newton.get_linear_matrix_solver()->as_AMGSolver()->set_smoother(Solvers::GMRES, Preconditioners::ILU); newton.get_linear_matrix_solver()->as_LoopSolver()->set_tolerance(1e-1, RelativeTolerance); #ifdef SHOW_OUTPUT // Initialize views. ScalarView Tview("Temperature", new WinGeom(0, 0, 450, 600)); Tview.set_min_max_range(0,20); Tview.fix_scale_width(30); #endif // Time stepping: int ts = 1; do { Hermes::Mixins::Loggable::Static::info("---- Time step %d, time %3.5f s", ts, current_time); newton.solve(); // Translate the resulting coefficient vector into the Solution sln. Solution<double>::vector_to_solution(newton.get_sln_vector(), space, tsln); #ifdef SHOW_OUTPUT // Visualize the solution. char title[100]; sprintf(title, "Time %3.2f s", current_time); Tview.set_title(title); Tview.show(tsln); #endif // Increase current time and time step counter. current_time += time_step; ts++; } while (current_time < T_FINAL); // Wait for the view to be closed. #ifdef SHOW_OUTPUT View::wait(); #endif return 0; #endif 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); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_GROUND); bc_types.add_bc_newton(BDY_AIR); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_const(BDY_GROUND, T_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); // Initialize the solution. Solution tsln; // Set the initial condition. 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>, HERMES_ANY, &tsln); wf.add_vector_form_surf(linear_form_surf<double, double>, linear_form_surf<Ord, Ord>, 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); // Initialize views. ScalarView Tview("Temperature", new WinGeom(0, 0, 450, 600)); char title[100]; sprintf(title, "Time %3.5f, exterior temperature %3.5f", TIME, temp_ext(TIME)); Tview.set_min_max_range(0,20); Tview.set_title(title); Tview.fix_scale_width(3); // Time stepping: int nsteps = (int)(FINAL_TIME/TAU + 0.5); bool rhs_only = false; for(int ts = 1; ts <= nsteps; ts++) { info("---- Time step %d, time %3.5f, ext_temp %g", ts, TIME, temp_ext(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"); // Update the time variable. TIME += TAU; // Visualize the solution. sprintf(title, "Time %3.2f, exterior temperature %3.5f", TIME, temp_ext(TIME)); Tview.set_title(title); Tview.show(&tsln); } // Wait for the view to be closed. View::wait(); // Clean up. delete solver; delete matrix; delete rhs; 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[]) { // 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 = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Initialize the solution. Solution tsln; // Set the initial condition. 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>, HERMES_ANY, &tsln); wf.add_vector_form_surf(linear_form_surf<double, double>, linear_form_surf<Ord, Ord>, 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); // Initialize views. ScalarView Tview("Temperature", new WinGeom(0, 0, 450, 600)); char title[100]; sprintf(title, "Time %3.5f, exterior temperature %3.5f", TIME, temp_ext(TIME)); Tview.set_min_max_range(0,20); Tview.set_title(title); Tview.fix_scale_width(3); // Time stepping: int nsteps = (int)(FINAL_TIME/TAU + 0.5); bool rhs_only = false; for(int ts = 1; ts <= nsteps; ts++) { info("---- Time step %d, time %3.5f, ext_temp %g", ts, TIME, temp_ext(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"); if (ts % OUTPUT_FREQUENCY == 0) { Linearizer lin; int item = H2D_FN_VAL_0; double eps = HERMES_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); // Clean up. delete solver; delete matrix; delete rhs; // 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; MeshReaderH2D 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_RIGHT, 2); mesh.refine_towards_boundary(BDY_FIRE, INIT_REF_NUM_BDY); // Initialize essential boundary conditions (none). EssentialBCs<double> bcs; // Initialize an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); int ndof = Space<double>::get_num_dofs(&space); info("ndof = %d.", ndof); // Previous and next time level solutions. ConstantSolution<double> sln_time_prev(&mesh, TEMP_INIT); ZeroSolution sln_time_new(&mesh); ConstantSolution<double> time_error_fn(&mesh, 0.0); // Initialize the weak formulation. double current_time = 0; CustomWeakFormHeatRK wf(BDY_FIRE, BDY_AIR, ALPHA_FIRE, ALPHA_AIR, RHO, HEATCAP, TEMP_EXT_AIR, TEMP_INIT, ¤t_time); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, &space); // 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."); // Initialize Runge-Kutta time stepping. RungeKutta<double> runge_kutta(&dp, &bt, matrix_solver_type); // Time stepping loop: 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 jacobian_changed = false; bool verbose = true; try { runge_kutta.rk_time_step_newton(current_time, time_step, &sln_time_prev, &sln_time_new, &time_error_fn, !jacobian_changed, false, verbose); } catch(Exceptions::Exception& e) { e.printMsg(); error("Runge-Kutta time step failed"); } // 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 = Global<double>::calc_norm(&time_error_fn, HERMES_H1_NORM) / Global<double>::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); // Wait for the view to be closed. View::wait(); return 0; }