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 B_sln(&mesh, 0.0); Hermes::vector<Solution*> slns(&E_sln, &B_sln); // Initialize the weak formulation. CustomWeakFormWave wf(C_SQUARED); // Initialize boundary conditions DefaultEssentialBCConst bc_essential(BDY, 0.0); EssentialBCs bcs_E(&bc_essential); EssentialBCs bcs_B; // Create x- and y- displacement space using the default H1 shapeset. HcurlSpace E_space(&mesh, &bcs_E, P_INIT); H1Space B_space(&mesh, &bcs_B, P_INIT); //L2Space B_space(&mesh, P_INIT); Hermes::vector<Space *> spaces = Hermes::vector<Space *>(&E_space, &B_space); info("ndof = %d.", Space::get_num_dofs(spaces)); // Initialize the FE problem. DiscreteProblem 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); // ScalarView B_view("Solution B", new WinGeom(0, 405, 400, 350)); // B_view.fix_scale_width(50); // Initialize Runge-Kutta time stepping. RungeKutta runge_kutta(&dp, &bt, matrix_solver); // Time stepping loop. double current_time = time_step; 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 jacobian_changed = false; bool verbose = 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."); /* // 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); sprintf(title, "B, t = %g", current_time); B_view.set_title(title); B_view.show(&B_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_0); */ // 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", B_sln.get_pt_value(coord_x[0], coord_y[0])); info("Coordinate (0.6, 0.3) value = %lf", B_sln.get_pt_value(coord_x[1], coord_y[1])); info("Coordinate (0.9, 0.5) value = %lf", B_sln.get_pt_value(coord_x[2], coord_y[2])); info("Coordinate (1.4, 0.7) value = %lf", B_sln.get_pt_value(coord_x[3], coord_y[3])); double t_value[4] = {0.0, -0.065100, -0.146515, -0.247677}; bool success = true; for (int i = 0; i < 4; i++) { if (fabs(t_value[i] - B_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[]) { try { // Sanity check for omega. double K_squared = Hermes::sqr(OMEGA / M_PI) * (OMEGA - 2) / (1 - OMEGA); if (K_squared <= 0) throw Hermes::Exceptions::Exception("Wrong choice of omega, K_squared < 0!"); double K_norm_coeff = std::sqrt(K_squared) / std::sqrt(Hermes::sqr(K_x) + Hermes::sqr(K_y)); Hermes::Mixins::Loggable::Static::info("Wave number K = %g", std::sqrt(K_squared)); K_x *= K_norm_coeff; K_y *= K_norm_coeff; // Wave number. double K = std::sqrt(Hermes::sqr(K_x) + Hermes::sqr(K_y)); // Choose a Butcher's table or define your own. ButcherTable bt(butcher_table); if (bt.is_explicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage explicit R-K method.", bt.get_size()); if (bt.is_diagonally_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage diagonally implicit R-K method.", bt.get_size()); if (bt.is_fully_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage fully implicit R-K method.", bt.get_size()); // Load the mesh. MeshSharedPtr E_mesh(new Mesh), H_mesh(new Mesh), P_mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", E_mesh); mloader.load("domain.mesh", H_mesh); mloader.load("domain.mesh", P_mesh); // Perform initial mesh refinemets. for (int i = 0; i < INIT_REF_NUM; i++) { E_mesh->refine_all_elements(); H_mesh->refine_all_elements(); P_mesh->refine_all_elements(); } // Initialize solutions. double current_time = 0; MeshFunctionSharedPtr<double> E_time_prev(new CustomInitialConditionE(E_mesh, current_time, OMEGA, K_x, K_y)); MeshFunctionSharedPtr<double> H_time_prev(new CustomInitialConditionH(H_mesh, current_time, OMEGA, K_x, K_y)); MeshFunctionSharedPtr<double> P_time_prev(new CustomInitialConditionP(P_mesh, current_time, OMEGA, K_x, K_y)); std::vector<MeshFunctionSharedPtr<double> > slns_time_prev({ E_time_prev, H_time_prev, P_time_prev }); MeshFunctionSharedPtr<double> E_time_new(new Solution<double>(E_mesh)), H_time_new(new Solution<double>(H_mesh)), P_time_new(new Solution<double>(P_mesh)); MeshFunctionSharedPtr<double> E_time_new_coarse(new Solution<double>(E_mesh)), H_time_new_coarse(new Solution<double>(H_mesh)), P_time_new_coarse(new Solution<double>(P_mesh)); std::vector<MeshFunctionSharedPtr<double> > slns_time_new({ E_time_new, H_time_new, P_time_new }); // Initialize the weak formulation. WeakFormSharedPtr<double> wf(new CustomWeakFormMD(OMEGA, K_x, K_y, MU_0, EPS_0, EPS_INF, EPS_Q, TAU)); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_essential("Bdy", 0.0); EssentialBCs<double> bcs(&bc_essential); SpaceSharedPtr<double> E_space(new HcurlSpace<double>(E_mesh, &bcs, P_INIT)); SpaceSharedPtr<double> H_space(new H1Space<double>(H_mesh, NULL, P_INIT)); //L2Space<double> H_space(mesh, P_INIT)); SpaceSharedPtr<double> P_space(new HcurlSpace<double>(P_mesh, &bcs, P_INIT)); std::vector<SpaceSharedPtr<double> > spaces = std::vector<SpaceSharedPtr<double> >({ E_space, H_space, P_space }); // 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 H_view("Solution H", new WinGeom(0, 410, 400, 350)); H_view.fix_scale_width(50); ScalarView P1_view("Solution P1", new WinGeom(410, 410, 400, 350)); P1_view.fix_scale_width(50); ScalarView P2_view("Solution P2", new WinGeom(820, 410, 400, 350)); P2_view.fix_scale_width(50); // Visualize initial conditions. char title[100]; sprintf(title, "E1 - Initial Condition"); E1_view.set_title(title); E1_view.show(E_time_prev, H2D_FN_VAL_0); sprintf(title, "E2 - Initial Condition"); E2_view.set_title(title); E2_view.show(E_time_prev, H2D_FN_VAL_1); sprintf(title, "H - Initial Condition"); H_view.set_title(title); H_view.show(H_time_prev); sprintf(title, "P1 - Initial Condition"); P1_view.set_title(title); P1_view.show(P_time_prev, H2D_FN_VAL_0); sprintf(title, "P2 - Initial Condition"); P2_view.set_title(title); P2_view.show(P_time_prev, H2D_FN_VAL_1); // Initialize Runge-Kutta time stepping. RungeKutta<double> runge_kutta(wf, spaces, &bt); runge_kutta.set_newton_max_allowed_iterations(NEWTON_MAX_ITER); runge_kutta.set_newton_tolerance(NEWTON_TOL); runge_kutta.set_verbose_output(true); // Initialize refinement selector. H1ProjBasedSelector<double> H1selector(CAND_LIST); HcurlProjBasedSelector<double> HcurlSelector(CAND_LIST); // Time stepping loop. int ts = 1; do { // Perform one Runge-Kutta time step according to the selected Butcher's table. Hermes::Mixins::Loggable::Static::info("\nRunge-Kutta time step (t = %g s, time_step = %g s, stages: %d).", current_time, time_step, bt.get_size()); // Periodic global derefinements. if (ts > 1 && ts % UNREF_FREQ == 0 && REFINEMENT_COUNT > 0) { Hermes::Mixins::Loggable::Static::info("Global mesh derefinement."); REFINEMENT_COUNT = 0; E_space->unrefine_all_mesh_elements(true); H_space->unrefine_all_mesh_elements(true); P_space->unrefine_all_mesh_elements(true); E_space->adjust_element_order(-1, P_INIT); H_space->adjust_element_order(-1, P_INIT); P_space->adjust_element_order(-1, P_INIT); E_space->assign_dofs(); H_space->assign_dofs(); P_space->assign_dofs(); } // Adaptivity loop: int as = 1; bool done = false; do { Hermes::Mixins::Loggable::Static::info("Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. int order_increase = 1; Mesh::ReferenceMeshCreator refMeshCreatorE(E_mesh); Mesh::ReferenceMeshCreator refMeshCreatorH(H_mesh); Mesh::ReferenceMeshCreator refMeshCreatorP(P_mesh); MeshSharedPtr ref_mesh_E = refMeshCreatorE.create_ref_mesh(); MeshSharedPtr ref_mesh_H = refMeshCreatorH.create_ref_mesh(); MeshSharedPtr ref_mesh_P = refMeshCreatorP.create_ref_mesh(); Space<double>::ReferenceSpaceCreator refSpaceCreatorE(E_space, ref_mesh_E, order_increase); SpaceSharedPtr<double> ref_space_E = refSpaceCreatorE.create_ref_space(); Space<double>::ReferenceSpaceCreator refSpaceCreatorH(H_space, ref_mesh_H, order_increase); SpaceSharedPtr<double> ref_space_H = refSpaceCreatorH.create_ref_space(); Space<double>::ReferenceSpaceCreator refSpaceCreatorP(P_space, ref_mesh_P, order_increase); SpaceSharedPtr<double> ref_space_P = refSpaceCreatorP.create_ref_space(); std::vector<SpaceSharedPtr<double> > ref_spaces({ ref_space_E, ref_space_H, ref_space_P }); int ndof = Space<double>::get_num_dofs(ref_spaces); Hermes::Mixins::Loggable::Static::info("ndof = %d.", ndof); try { runge_kutta.set_spaces(ref_spaces); runge_kutta.set_time(current_time); runge_kutta.set_time_step(time_step); runge_kutta.rk_time_step_newton(slns_time_prev, slns_time_new); } catch (Exceptions::Exception& e) { e.print_msg(); throw Hermes::Exceptions::Exception("Runge-Kutta time step failed"); } // Visualize the solutions. char title[100]; sprintf(title, "E1, t = %g", current_time + time_step); E1_view.set_title(title); E1_view.show(E_time_new, H2D_FN_VAL_0); sprintf(title, "E2, t = %g", current_time + time_step); E2_view.set_title(title); E2_view.show(E_time_new, H2D_FN_VAL_1); sprintf(title, "H, t = %g", current_time + time_step); H_view.set_title(title); H_view.show(H_time_new); sprintf(title, "P1, t = %g", current_time + time_step); P1_view.set_title(title); P1_view.show(P_time_new, H2D_FN_VAL_0); sprintf(title, "P2, t = %g", current_time + time_step); P2_view.set_title(title); P2_view.show(P_time_new, H2D_FN_VAL_1); // Project the fine mesh solution onto the coarse mesh. Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh."); OGProjection<double>::project_global({ E_space, H_space, P_space }, { E_time_new, H_time_new, P_time_new }, { E_time_new_coarse, H_time_new_coarse, P_time_new_coarse }); // Calculate element errors and total error estimate. Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); adaptivity.set_spaces({ E_space, H_space, P_space }); errorCalculator.calculate_errors({ E_time_new_coarse, H_time_new_coarse, P_time_new_coarse }, { E_time_new, H_time_new, P_time_new }); double err_est_rel_total = errorCalculator.get_total_error_squared() * 100.; // Report results. Hermes::Mixins::Loggable::Static::info("Error estimate: %g%%", err_est_rel_total); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) { Hermes::Mixins::Loggable::Static::info("Error estimate under the specified threshold -> moving to next time step."); done = true; } else { Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh."); REFINEMENT_COUNT++; done = adaptivity.adapt({ &HcurlSelector, &H1selector, &HcurlSelector }); if (!done) as++; } } while (!done); //View::wait(); E_time_prev->copy(E_time_new); H_time_prev->copy(H_time_new); P_time_prev->copy(P_time_new); // Update time. current_time += time_step; ts++; } while (current_time < T_FINAL); // Wait for the view to be closed. View::wait(); } catch (std::exception& e) { std::cout << e.what(); } 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("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); ZeroSolution B_sln(&mesh); Hermes::vector<Solution<double>*> slns(&E_sln, &B_sln); // Initialize the weak formulation. CustomWeakFormWave wf(C_SQUARED); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_essential("Perfect conductor", 0.0); EssentialBCs<double> bcs_E(&bc_essential); EssentialBCs<double> bcs_B; // Create x- and y- displacement space using the default H1 shapeset. HcurlSpace<double> E_space(&mesh, &bcs_E, P_INIT); H1Space<double> B_space(&mesh, &bcs_B, P_INIT); //L2Space<double> B_space(&mesh, P_INIT); Hermes::vector<Space<double> *> spaces = Hermes::vector<Space<double> *>(&E_space, &B_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); ScalarView B_view("Solution B", new WinGeom(0, 405, 400, 350)); B_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 = time_step; 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 jacobian_changed = false; bool verbose = 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); sprintf(title, "B, t = %g", current_time); B_view.set_title(title); B_view.show(&B_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_0); // 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. 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[]) { // 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; }