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("domain.mesh", &mesh); // Perform initial mesh refinemets. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize solutions. CustomInitialConditionWave E_sln(&mesh); ZeroSolutionVector F_sln(&mesh); Hermes::vector<Solution<double>*> slns(&E_sln, &F_sln); // Initialize the weak formulation. CustomWeakFormWave wf(C_SQUARED); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_essential("Perfect conductor", 0.0); EssentialBCs<double> bcs(&bc_essential); // Create x- and y- displacement space using the default H1 shapeset. HcurlSpace<double> E_space(&mesh, &bcs, P_INIT); HcurlSpace<double> F_space(&mesh, &bcs, P_INIT); Hermes::vector<Space<double> *> spaces = Hermes::vector<Space<double> *>(&E_space, &F_space); info("ndof = %d.", Space<double>::get_num_dofs(spaces)); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, spaces); // Initialize views. ScalarView E1_view("Solution E1", new WinGeom(0, 0, 400, 350)); E1_view.fix_scale_width(50); ScalarView E2_view("Solution E2", new WinGeom(410, 0, 400, 350)); E2_view.fix_scale_width(50); // Initialize Runge-Kutta time stepping. RungeKutta<double> runge_kutta(&dp, &bt, matrix_solver_type); // 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, time_step = %g s, stages: %d).", current_time, time_step, bt.get_size()); bool verbose = true; bool jacobian_changed = true; try { runge_kutta.rk_time_step_newton(current_time, time_step, slns, slns, jacobian_changed, verbose); } catch(Exceptions::Exception& e) { e.printMsg(); error("Runge-Kutta time step failed"); } // Visualize the solutions. char title[100]; sprintf(title, "E1, t = %g", current_time); E1_view.set_title(title); E1_view.show(&E_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_0); sprintf(title, "E2, t = %g", current_time); E2_view.set_title(title); E2_view.show(&E_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_1); // Update time. current_time += time_step; } while (current_time < T_FINAL); // Wait for the view to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // 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 solutions. CustomInitialConditionWave E_sln(&mesh); ZeroSolutionVector F_sln(&mesh); Hermes::vector<Solution<double>*> slns(&E_sln, &F_sln); // Initialize the weak formulation. CustomWeakFormWave wf(time_step, C_SQUARED, &E_sln, &F_sln); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_essential("Perfect conductor", 0.0); EssentialBCs<double> bcs(&bc_essential); // Create x- and y- displacement space using the default H1 shapeset. HcurlSpace<double> E_space(&mesh, &bcs, P_INIT); HcurlSpace<double> F_space(&mesh, &bcs, P_INIT); Hermes::vector<Space<double> *> spaces = Hermes::vector<Space<double> *>(&E_space, &F_space); info("ndof = %d.", Space<double>::get_num_dofs(spaces)); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, spaces); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type); Vector<double>* rhs = create_vector<double>(matrix_solver_type); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs); solver->set_factorization_scheme(HERMES_REUSE_FACTORIZATION_COMPLETELY); // Initialize views. ScalarView E1_view("Solution E1", new WinGeom(0, 0, 400, 350)); E1_view.fix_scale_width(50); ScalarView E2_view("Solution E2", new WinGeom(410, 0, 400, 350)); E2_view.fix_scale_width(50); // Time stepping loop. double current_time = 0; int ts = 1; do { // Perform one implicit Euler time step. info("Implicit Euler time step (t = %g s, time_step = %g s).", current_time, time_step); // First time assemble both the stiffness matrix and right-hand side vector, // then just the right-hand side vector. if (ts == 1) { info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); static char file_name[1024]; sprintf(file_name, "matrix.m"); FILE *f = fopen(file_name, "w"); matrix->dump(f, "A"); fclose(f); } else { info("Assembling the right-hand side vector (only)."); dp.assemble(rhs); } // Solve the linear system and if successful, obtain the solution. info("Solving the matrix problem."); if(solver->solve()) Solution<double>::vector_to_solutions(solver->get_sln_vector(), spaces, slns); else error ("Matrix solver failed.\n"); // Visualize the solutions. char title[100]; sprintf(title, "E1, t = %g", current_time); E1_view.set_title(title); E1_view.show(&E_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_0); sprintf(title, "E2, t = %g", current_time); E2_view.set_title(title); E2_view.show(&E_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_1); // Update time. current_time += time_step; } 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("../domain.mesh", &mesh); // Perform initial mesh refinemets. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize solutions. CustomInitialConditionWave E_sln(&mesh); Solution F_sln(&mesh, 0.0, 0.0); Hermes::vector<Solution*> slns(&E_sln, &F_sln); // Initialize the weak formulation. CustomWeakFormWave wf(C_SQUARED); // Initialize boundary conditions DefaultEssentialBCConst bc_essential(BDY, 0.0); EssentialBCs bcs(&bc_essential); // Create x- and y- displacement space using the default H1 shapeset. HcurlSpace E_space(&mesh, &bcs, P_INIT); HcurlSpace F_space(&mesh, &bcs, P_INIT); Hermes::vector<Space *> spaces = Hermes::vector<Space *>(&E_space, &F_space); info("ndof = %d.", Space::get_num_dofs(spaces)); // Initialize the FE problem. DiscreteProblem dp(&wf, spaces); // Initialize Runge-Kutta time stepping. RungeKutta runge_kutta(&dp, &bt, matrix_solver); // 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, time_step = %g s, stages: %d).", current_time, time_step, bt.get_size()); bool verbose = true; bool jacobian_changed = true; if (!runge_kutta.rk_time_step(current_time, time_step, slns, slns, jacobian_changed, verbose)) error("Runge-Kutta time step failed, try to decrease time step size."); // Update time. current_time += time_step; } while (current_time < T_FINAL); double coord_x[4] = {0.3, 0.6, 0.9, 1.4}; double coord_y[4] = {0, 0.3, 0.5, 0.7}; info("Coordinate (0.3, 0.0) value = %lf", F_sln.get_pt_value(coord_x[0], coord_y[0])); info("Coordinate (0.6, 0.3) value = %lf", F_sln.get_pt_value(coord_x[1], coord_y[1])); info("Coordinate (0.9, 0.5) value = %lf", F_sln.get_pt_value(coord_x[2], coord_y[2])); info("Coordinate (1.4, 0.7) value = %lf", F_sln.get_pt_value(coord_x[3], coord_y[3])); double t_value[4] = {-0.144673, -0.264077, -0.336536, -0.368983}; bool success = true; for (int i = 0; i < 4; i++) { if (fabs(t_value[i] - F_sln.get_pt_value(coord_x[i], coord_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. MeshSharedPtr mesh(new 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 solutions. MeshFunctionSharedPtr<double> E_sln(new CustomInitialConditionWave(mesh)); MeshFunctionSharedPtr<double> F_sln(new ZeroSolutionVector<double>(mesh)); Hermes::vector<MeshFunctionSharedPtr<double> > slns(E_sln, F_sln); // Initialize the weak formulation. CustomWeakFormWaveIE wf(time_step, C_SQUARED, E_sln, F_sln); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_essential("Perfect conductor", 0.0); EssentialBCs<double> bcs(&bc_essential); SpaceSharedPtr<double> E_space(new HcurlSpace<double>(mesh, &bcs, P_INIT)); SpaceSharedPtr<double> F_space(new HcurlSpace<double>(mesh, &bcs, P_INIT)); Hermes::vector<SpaceSharedPtr<double> > spaces = Hermes::vector<SpaceSharedPtr<double> >(E_space, F_space); int ndof = HcurlSpace<double>::get_num_dofs(spaces); Hermes::Mixins::Loggable::Static::info("ndof = %d.", ndof); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, spaces); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. // NOTE: If you want to start from the zero vector, just define // coeff_vec to be a vector of ndof zeros (no projection is needed). Hermes::Mixins::Loggable::Static::info("Projecting to obtain initial vector for the Newton's method."); double* coeff_vec = new double[ndof]; OGProjection<double> ogProjection; ogProjection.project_global(spaces, slns, coeff_vec); // Initialize Newton solver. NewtonSolver<double> newton(&dp); // Initialize views. ScalarView E1_view("Solution E1", new WinGeom(0, 0, 400, 350)); E1_view.fix_scale_width(50); ScalarView E2_view("Solution E2", new WinGeom(410, 0, 400, 350)); E2_view.fix_scale_width(50); ScalarView F1_view("Solution F1", new WinGeom(0, 410, 400, 350)); F1_view.fix_scale_width(50); ScalarView F2_view("Solution F2", new WinGeom(410, 410, 400, 350)); F2_view.fix_scale_width(50); // Time stepping loop. double current_time = 0; int ts = 1; do { // Perform one implicit Euler time step. Hermes::Mixins::Loggable::Static::info("Implicit Euler time step (t = %g s, time_step = %g s).", current_time, time_step); // Perform Newton's iteration. try { newton.set_max_allowed_iterations(NEWTON_MAX_ITER); newton.set_tolerance(NEWTON_TOL, Hermes::Solvers::ResidualNormAbsolute); newton.solve(coeff_vec); } catch(Hermes::Exceptions::Exception e) { e.print_msg(); throw Hermes::Exceptions::Exception("Newton's iteration failed."); } // Translate the resulting coefficient vector into Solutions. Solution<double>::vector_to_solutions(newton.get_sln_vector(), spaces, slns); // Visualize the solutions. char title[100]; sprintf(title, "E1, t = %g", current_time + time_step); E1_view.set_title(title); E1_view.show(E_sln, H2D_FN_VAL_0); sprintf(title, "E2, t = %g", current_time + time_step); E2_view.set_title(title); E2_view.show(E_sln, H2D_FN_VAL_1); sprintf(title, "F1, t = %g", current_time + time_step); F1_view.set_title(title); F1_view.show(F_sln, H2D_FN_VAL_0); sprintf(title, "F2, t = %g", current_time + time_step); F2_view.set_title(title); F2_view.show(F_sln, H2D_FN_VAL_1); //View::wait(); // Update time. current_time += time_step; } while (current_time < T_FINAL); // Wait for the view to be closed. View::wait(); return 0; }