int main(int argc, char* argv[]) { // 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(); // Initialize boundary conditions. Hermes::Hermes2D::DefaultEssentialBCConst<complex> bc_essential("Dirichlet", complex(0.0, 0.0)); EssentialBCs<complex> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<complex> space(new H1Space<complex>(mesh, &bcs, P_INIT)); int ndof = space->get_num_dofs(); // Initialize the weak formulation. CustomWeakForm wf("Air", MU_0, "Iron", MU_IRON, GAMMA_IRON, "Wire", MU_0, complex(J_EXT, 0.0), OMEGA); // Initialize coarse and reference mesh solution. MeshFunctionSharedPtr<complex> sln(new Hermes::Hermes2D::Solution<complex>()); MeshFunctionSharedPtr<complex> ref_sln(new Hermes::Hermes2D::Solution<complex>()); // Initialize refinement selector. H1ProjBasedSelector<complex> selector(CAND_LIST); // Initialize views. #ifdef SHOW_OUTPUT Views::ScalarView sview("Solution", new Views::WinGeom(0, 0, 600, 350)); Views::ScalarView sview2("Ref. Solution", new Views::WinGeom(0, 0, 600, 350)); Views::OrderView oview("Polynomial orders", new Views::WinGeom(610, 0, 520, 350)); #endif DiscreteProblem<complex> dp(&wf, space); // Perform Newton's iteration and translate the resulting coefficient vector into a Solution. Hermes::Hermes2D::NewtonSolver<complex> newton(&dp); // Adaptivity loop: int as = 1; bool done = false; adaptivity.set_space(space); do { // Construct globally refined reference mesh and setup reference space-> Mesh::ReferenceMeshCreator ref_mesh_creator(mesh); MeshSharedPtr ref_mesh = ref_mesh_creator.create_ref_mesh(); Space<complex>::ReferenceSpaceCreator ref_space_creator(space, ref_mesh); SpaceSharedPtr<complex> ref_space = ref_space_creator.create_ref_space(); newton.set_space(ref_space); ref_space->save("space-complex.xml"); ref_space->free(); ref_space->load("space-complex.xml"); #ifdef WITH_BSON ref_space->save_bson("space-complex.bson"); ref_space->free(); ref_space->load_bson("space-complex.bson"); #endif int ndof_ref = ref_space->get_num_dofs(); // Initialize reference problem. // Initial coefficient vector for the Newton's method. complex* coeff_vec = new complex[ndof_ref]; memset(coeff_vec, 0, ndof_ref * sizeof(complex)); // Perform Newton's iteration and translate the resulting coefficient vector into a Solution. SpaceSharedPtr<complex> space_test = Space<complex>::load("space-complex.xml", ref_mesh, false, &bcs); newton.set_space(space_test); newton.solve(coeff_vec); Hermes::Hermes2D::Solution<complex>::vector_to_solution(newton.get_sln_vector(), ref_space, ref_sln); // Project the fine mesh solution onto the coarse mesh. OGProjection<complex> ogProjection; #ifdef WITH_BSON space->save_bson("space-complex-coarse.bson"); SpaceSharedPtr<complex> space_test2 = Space<complex>::load_bson("space-complex-coarse.bson", mesh, &bcs); ogProjection.project_global(space_test2, ref_sln, sln); #else space->save("space-complex-coarse.xml2"); SpaceSharedPtr<complex> space_test2 = Space<complex>::load("space-complex-coarse.xml2", mesh, false, &bcs); ogProjection.project_global(space_test2, ref_sln, sln); #endif // View the coarse mesh solution and polynomial orders. #ifdef SHOW_OUTPUT MeshFunctionSharedPtr<double> real_filter(new RealFilter(sln)); MeshFunctionSharedPtr<double> rreal_filter(new RealFilter(ref_sln)); sview2.show(rreal_filter); oview.show(space); #endif // Calculate element errors and total error estimate. errorCalculator.calculate_errors(sln, ref_sln); #ifdef SHOW_OUTPUT std::cout << "Relative error: " << errorCalculator.get_total_error_squared() * 100. << '%' << std::endl; #endif // Add entry to DOF and CPU convergence graphs. #ifdef SHOW_OUTPUT sview.show(errorCalculator.get_errorMeshFunction()); #endif // If err_est too large, adapt the mesh-> if(errorCalculator.get_total_error_squared() * 100. < ERR_STOP) done = true; else { std::cout << "Adapting..." << std::endl << std::endl; adaptivity.adapt(&selector); } // Clean up. delete [] coeff_vec; // Increase counter. as++; } while (done == false); #ifdef SHOW_OUTPUT // Show the reference solution - the final result. sview.set_title("Fine mesh solution"); MeshFunctionSharedPtr<double> real_filter(new RealFilter(ref_sln)); sview.show(real_filter); // Wait for all views to be closed. Views::View::wait(); #endif return as; }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; H2DReader mloader; mloader.load("square_quad.mesh", &mesh); // mloader.load("square_tri.mesh", &mesh); for (int i=0; i<INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(2, INIT_REF_NUM_BDY); // initialize the shapeset and the cache H1Shapeset shapeset; PrecalcShapeset pss(&shapeset); // create finite element space 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(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form)); if (STABILIZATION_ON == true) { wf.add_biform(0, 0, bilinear_form_stabilization, bilinear_form_stabilization_order); } if (SHOCK_CAPTURING_ON == true) { wf.add_biform(0, 0, bilinear_form_shock_capturing, bilinear_form_shock_capturing_order); } // visualize solution and mesh OrderView oview("Coarse mesh", 0, 0, 500, 400); ScalarView sview("Coarse mesh solution", 510, 0, 500, 400); ScalarView sview2("Fine mesh solution", 1020, 0, 500, 400); // matrix solver UmfpackSolver solver; // DOF convergence graph SimpleGraph graph_dof_est, graph_cpu_est; // prepare selector RefinementSelectors::H1NonUniformHP selector(ISO_ONLY, ADAPT_TYPE, CONV_EXP, H2DRS_DEFAULT_ORDER, &shapeset); // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem ls(&wf, &solver); ls.set_spaces(1, &space); ls.set_pss(1, &pss); ls.assemble(); ls.solve(1, &sln_coarse); // solve the fine mesh problem int p_increase; if (ADAPT_TYPE == RefinementSelectors::H2DRS_CAND_HP) p_increase = 1; else p_increase = 0; RefSystem rs(&ls, p_increase, 1); // the '1' is for one level of global refinement in space rs.assemble(); rs.solve(1, &sln_fine); // time measurement cpu += end_time(); // show fine mesh solution // view the solution and mesh oview.show(&space); sview.show(&sln_coarse); sview2.show(&sln_fine); //sview.wait_for_keypress(); // time measurement begin_time(); // calculate error estimate wrt. fine mesh solution H1AdaptHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Estimate of error: %g%%", err_est); // add entries to DOF and CPU convergence graphs graph_dof_est.add_values(space.get_num_dofs(), err_est); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu, err_est); graph_cpu_est.save("conv_cpu_est.dat"); // if err_est too large, adapt the mesh if (err_est < ERR_STOP) done = true; else { hp.adapt(THRESHOLD, STRATEGY, &selector, MESH_REGULARITY); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); } while (done == false); verbose("Total running time: %g sec", cpu); // show the fine solution - this is the final result sview.set_title("Final solution"); sview.show(&sln_fine); // wait for keyboard or mouse input View::wait(); return 0; }