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[]) { // 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; }