Exemplo n.º 1
0
  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;
  }
Exemplo n.º 2
0
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;
}