Beispiel #1
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  MeshSharedPtr mesh(new Mesh);
  MeshReaderH2D mloader;
  mloader.load("domain.mesh", mesh);

  // Define exact solution.
  MeshFunctionSharedPtr<double> exact_sln(new CustomExactSolution(mesh));

  // Initialize the weak formulation.
  CustomWeakForm wf("Right");

  // Initialize boundary conditions.
  DefaultEssentialBCConst<double> bc_essential("Left", 0.0);
  EssentialBCs<double> bcs(&bc_essential);

  // Create an H1 space with default shapeset.
  SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT));

  // Set the space to adaptivity.
  adaptivity.set_space(space);

  // Initialize approximate solution.
  MeshFunctionSharedPtr<double> sln(new Solution<double>());

  // Initialize refinement selector.
  H1ProjBasedSelector<double> selector(CAND_LIST);

  // Initialize views.
  Views::ScalarView sview("Solution", new Views::WinGeom(0, 0, 440, 350));
  sview.show_mesh(false);
  sview.fix_scale_width(50);
  Views::OrderView oview("Polynomial orders", new Views::WinGeom(450, 0, 420, 350));

  // DOF and CPU convergence graphs.
  SimpleGraph graph_dof_est, graph_cpu_est, graph_dof_exact, graph_cpu_exact;

  // Time measurement.
  Hermes::Mixins::TimeMeasurable cpu_time;
  cpu_time.tick();

  // Adaptivity loop:
  int as = 1; bool done = false;
  do
  {
    cpu_time.tick();

    // Construct globally refined reference mesh and setup reference space.
    Mesh::ReferenceMeshCreator refMeshCreator(mesh);
    MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh();

    Space<double>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh);
    SpaceSharedPtr<double> ref_space = refSpaceCreator.create_ref_space();
    int ndof_ref = ref_space->get_num_dofs();

    Hermes::Mixins::Loggable::Static::info("---- Adaptivity step %d (%d DOF):", as, ndof_ref);
    cpu_time.tick();

    Hermes::Mixins::Loggable::Static::info("Solving on reference mesh.");

    // Assemble the discrete problem.
    DiscreteProblem<double> dp(&wf, ref_space);

    NewtonSolver<double> newton(&dp);
    //newton.set_verbose_output(false);

    MeshFunctionSharedPtr<double> ref_sln(new Solution<double>());
    try
    {
      newton.solve();
    }
    catch(Hermes::Exceptions::Exception e)
    {
      e.print_msg();
      throw Hermes::Exceptions::Exception("Newton's iteration failed.");
    };
    // Translate the resulting coefficient vector into the instance of Solution.
    Solution<double>::vector_to_solution(newton.get_sln_vector(), ref_space, ref_sln);

    cpu_time.tick();
    Hermes::Mixins::Loggable::Static::info("Solution: %g s", cpu_time.last());

    // Project the fine mesh solution onto the coarse mesh.
    Hermes::Mixins::Loggable::Static::info("Calculating error estimate and exact error.");
    OGProjection<double> ogProjection; ogProjection.project_global(space, ref_sln, sln);

    // Calculate element errors and total error estimate.
    errorCalculator.calculate_errors(sln, exact_sln, false);
    double err_exact_rel = errorCalculator.get_total_error_squared() * 100;

    errorCalculator.calculate_errors(sln, ref_sln, true);
    double err_est_rel = errorCalculator.get_total_error_squared() * 100;

    cpu_time.tick();
    Hermes::Mixins::Loggable::Static::info("Error calculation: %g s", cpu_time.last());

    // Report results.
    Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d", space->get_num_dofs(), ref_space->get_num_dofs());
    Hermes::Mixins::Loggable::Static::info("err_est_rel: %g%%, err_exact_rel: %g%%", err_est_rel, err_exact_rel);

    // Time measurement.
    cpu_time.tick();
    double accum_time = cpu_time.accumulated();

    // View the coarse mesh solution and polynomial orders.
    sview.show(sln);
    oview.show(space);

    // Add entry to DOF and CPU convergence graphs.
    graph_dof_est.add_values(space->get_num_dofs(), err_est_rel);
    graph_dof_est.save("conv_dof_est.dat");
    graph_cpu_est.add_values(accum_time, err_est_rel);
    graph_cpu_est.save("conv_cpu_est.dat");
    graph_dof_exact.add_values(space->get_num_dofs(), err_exact_rel);
    graph_dof_exact.save("conv_dof_exact.dat");
    graph_cpu_exact.add_values(accum_time, err_exact_rel);
    graph_cpu_exact.save("conv_cpu_exact.dat");

    cpu_time.tick(Hermes::Mixins::TimeMeasurable::HERMES_SKIP);

    // If err_est too large, adapt the mesh. The NDOF test must be here, so that the solution may be visualized
    // after ending due to this criterion.
    if (err_exact_rel < ERR_STOP) 
      done = true;
    else
      done = adaptivity.adapt(&selector);

    cpu_time.tick();
    Hermes::Mixins::Loggable::Static::info("Adaptation: %g s", cpu_time.last());

    // Increase the counter of adaptivity steps.
    if (done == false)  
      as++;
  }
  while (done == false);

  Hermes::Mixins::Loggable::Static::info("Total running time: %g s", cpu_time.accumulated());

  // Wait for all views to be closed.
  Views::View::wait();
}
Beispiel #2
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()) 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 mesh(new Mesh), basemesh(new Mesh);
  MeshReaderH2D mloader;
  mloader.load("square.mesh", basemesh);
  mesh->copy(basemesh);

  // Initial mesh refinements.
  for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh->refine_all_elements();
  mesh->refine_towards_boundary("Top", INIT_REF_NUM_BDY);

  // Initialize boundary conditions.
  CustomEssentialBCNonConst bc_essential(Hermes::vector<std::string>("Bottom", "Right", "Top", "Left"));
  EssentialBCs<double> bcs(&bc_essential);

  // Create an H1 space with default shapeset.
  SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT));
  int ndof_coarse = Space<double>::get_num_dofs(space);
  adaptivity.set_space(space);
  Hermes::Mixins::Loggable::Static::info("ndof_coarse = %d.", ndof_coarse);

  // Zero initial solution. This is why we use H_OFFSET.
  MeshFunctionSharedPtr<double> h_time_prev(new ZeroSolution<double>(mesh)), h_time_new(new ZeroSolution<double>(mesh));

  // Initialize the constitutive relations.
  ConstitutiveRelations* constitutive_relations;
  if(constitutive_relations_type == CONSTITUTIVE_GENUCHTEN)
    constitutive_relations = new ConstitutiveRelationsGenuchten(ALPHA, M, N, THETA_S, THETA_R, K_S, STORATIVITY);
  else
    constitutive_relations = new ConstitutiveRelationsGardner(ALPHA, THETA_S, THETA_R, K_S);

  // Initialize the weak formulation.
  CustomWeakFormRichardsRK wf(constitutive_relations);

  // Initialize the FE problem.
  DiscreteProblem<double> dp(&wf, space);

  // Create a refinement selector.
  H1ProjBasedSelector<double> selector(CAND_LIST);

  // Visualize initial condition.
  char title[100];
  ScalarView view("Initial condition", new WinGeom(0, 0, 440, 350));
  OrderView ordview("Initial mesh", new WinGeom(445, 0, 440, 350));
  view.show(h_time_prev);
  ordview.show(space);

  // DOF and CPU convergence graphs initialization.
  SimpleGraph graph_dof, graph_cpu;
  
  // Time measurement.
  Hermes::Mixins::TimeMeasurable cpu_time;
  cpu_time.tick();
  
  // Time stepping loop.
  double current_time = 0; int ts = 1;
  do 
  {
    // Periodic global derefinement.
    if (ts > 1 && ts % UNREF_FREQ == 0) 
    {
      Hermes::Mixins::Loggable::Static::info("Global mesh derefinement.");
      switch (UNREF_METHOD) {
        case 1: mesh->copy(basemesh);
                space->set_uniform_order(P_INIT);
                break;
        case 2: mesh->unrefine_all_elements();
                space->set_uniform_order(P_INIT);
                break;
        case 3: space->unrefine_all_mesh_elements();
                space->adjust_element_order(-1, -1, P_INIT, P_INIT);
                break;
        default: throw Hermes::Exceptions::Exception("Wrong global derefinement method.");
      }

      space->assign_dofs();
      ndof_coarse = Space<double>::get_num_dofs(space);
    }

    // Spatial adaptivity loop. Note: h_time_prev must not be changed 
    // during spatial adaptivity. 
    bool done = false; int as = 1;
    double err_est;
    do {
      Hermes::Mixins::Loggable::Static::info("Time step %d, adaptivity step %d:", ts, as);

      // Construct globally refined reference mesh and setup reference space.
      Mesh::ReferenceMeshCreator refMeshCreator(mesh);
      MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh();

      Space<double>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh);
      SpaceSharedPtr<double> ref_space = refSpaceCreator.create_ref_space();
      int ndof_ref = Space<double>::get_num_dofs(ref_space);

      // Time measurement.
      cpu_time.tick();

      // Initialize Runge-Kutta time stepping.
      RungeKutta<double> runge_kutta(&wf, ref_space, &bt);

      // Perform one Runge-Kutta time step according to the selected Butcher's table.
      Hermes::Mixins::Loggable::Static::info("Runge-Kutta time step (t = %g s, tau = %g s, stages: %d).",
           current_time, time_step, bt.get_size());
      try
      {
        runge_kutta.set_time(current_time);
        runge_kutta.set_time_step(time_step);
        runge_kutta.set_max_allowed_iterations(NEWTON_MAX_ITER);
        runge_kutta.set_tolerance(NEWTON_TOL);
        runge_kutta.rk_time_step_newton(h_time_prev, h_time_new);
      }
      catch(Exceptions::Exception& e)
      {
        e.print_msg();
        throw Hermes::Exceptions::Exception("Runge-Kutta time step failed");
      }

      // Project the fine mesh solution onto the coarse mesh.
      MeshFunctionSharedPtr<double> sln_coarse(new Solution<double>);
      Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh for error estimation.");
      OGProjection<double> ogProjection; ogProjection.project_global(space, h_time_new, sln_coarse); 

      // Calculate element errors and total error estimate.
      Hermes::Mixins::Loggable::Static::info("Calculating error estimate.");
      errorCalculator.calculate_errors(sln_coarse, h_time_new, true);
      double err_est_rel_total = errorCalculator.get_total_error_squared() * 100;

      // Report results.
      Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_ref: %d, err_est_rel: %g%%", 
           Space<double>::get_num_dofs(space), Space<double>::get_num_dofs(ref_space), err_est_rel_total);

      // Time measurement.
      cpu_time.tick();

      // If err_est too large, adapt the mesh.
      if (err_est_rel_total < ERR_STOP) done = true;
      else 
      {
        Hermes::Mixins::Loggable::Static::info("Adapting the coarse mesh.");
        done = adaptivity.adapt(&selector);

        // Increase the counter of performed adaptivity steps.
        as++;
      }
    }
    while (done == false);

    // Add entry to DOF and CPU convergence graphs.
    graph_dof.add_values(current_time, Space<double>::get_num_dofs(space));
    graph_dof.save("conv_dof_est.dat");
    graph_cpu.add_values(current_time, cpu_time.accumulated());
    graph_cpu.save("conv_cpu_est.dat");

    // Visualize the solution and mesh->
    char title[100];
    sprintf(title, "Solution, time %g", current_time);
    view.set_title(title);
    view.show_mesh(false);
    view.show(h_time_new);
    sprintf(title, "Mesh, time %g", current_time);
    ordview.set_title(title);
    ordview.show(space);

    // Copy last reference solution into h_time_prev.
    h_time_prev->copy(h_time_new);

    // Increase current time and counter of time steps.
    current_time += time_step;
    ts++;
  }
  while (current_time < T_FINAL);

  // Wait for all views to be closed.
  View::wait();
  return 0;
}
Beispiel #3
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()) 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 mesh(new Mesh), basemesh(new Mesh);
  MeshReaderH2D mloader;
  mloader.load("square.mesh", basemesh);

  // Perform initial mesh refinements.
  for (int i = 0; i < INIT_REF_NUM; i++)
    basemesh->refine_all_elements(0, true);
  mesh->copy(basemesh);

  // Initialize boundary conditions.
  EssentialBCNonConst bc_essential("Bdy");
  EssentialBCs<double> bcs(&bc_essential);

  // Create an H1 space with default shapeset.
  SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT));
  adaptivity.set_space(space);
  int ndof_coarse = space->get_num_dofs();

  // Previous time level solution (initialized by initial condition).
  MeshFunctionSharedPtr<double> sln_time_prev(new CustomInitialCondition(mesh));

  // Initialize the weak formulation
  CustomNonlinearity lambda(alpha);
  Hermes2DFunction<double> f(heat_src);
  WeakFormSharedPtr<double> wf(new CustomWeakFormPoisson(&lambda, &f));

  // Next time level solution.
  MeshFunctionSharedPtr<double> sln_time_new(new Solution<double>(mesh));

  // Create a refinement selector.
  H1ProjBasedSelector<double> selector(CAND_LIST);

  // Visualize initial condition.
  ScalarView view("Initial condition", new WinGeom(0, 0, 440, 350));
  OrderView ordview("Initial mesh", new WinGeom(445, 0, 410, 350));
  if (HERMES_VISUALIZATION)
  {
    view.show(sln_time_prev);
    ordview.show(space);
  }

  // Initialize Runge-Kutta time stepping.
  RungeKutta<double> runge_kutta(wf, space, &bt);

  // Time stepping loop.
  double current_time = 0; int ts = 1;
  do
  {
    // Periodic global derefinement.
    if (ts > 1 && ts % UNREF_FREQ == 0)
    {
      Hermes::Mixins::Loggable::Static::info("Global mesh derefinement.");
      switch (UNREF_METHOD)
      {
      case 1: mesh->copy(basemesh);
        space->set_uniform_order(P_INIT);
        break;
      case 2: mesh->unrefine_all_elements();
        space->set_uniform_order(P_INIT);
        break;
      case 3: mesh->unrefine_all_elements();
        space->adjust_element_order(-1, -1, P_INIT, P_INIT);
        break;
      }

      space->assign_dofs();
      ndof_coarse = Space<double>::get_num_dofs(space);
    }

    // Spatial adaptivity loop. Note: sln_time_prev must not be changed
    // during spatial adaptivity.
    bool done = false; int as = 1;
    do {
      Hermes::Mixins::Loggable::Static::info("Time step %d, adaptivity step %d:", ts, as);

      // 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<double>::ReferenceSpaceCreator ref_space_creator(space, ref_mesh);
      SpaceSharedPtr<double> ref_space = ref_space_creator.create_ref_space();
      int ndof_ref = Space<double>::get_num_dofs(ref_space);

      // Perform one Runge-Kutta time step according to the selected Butcher's table.
      try
      {
        runge_kutta.set_space(ref_space);
        runge_kutta.set_verbose_output(true);
        runge_kutta.set_time(current_time);
        runge_kutta.set_time_step(time_step);
        runge_kutta.set_tolerance(NEWTON_TOL);
        runge_kutta.rk_time_step_newton(sln_time_prev, sln_time_new);
      }
      catch (Exceptions::Exception& e)
      {
        std::cout << e.info();
      }
      catch (std::exception& e)
      {
        std::cout << e.what();
      }

      // Project the fine mesh solution onto the coarse mesh.
      MeshFunctionSharedPtr<double> sln_coarse(new Solution<double>());
      Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh for error estimation.");
      OGProjection<double> ogProjection; ogProjection.project_global(space, sln_time_new, sln_coarse);

      // Calculate element errors and total error estimate.
      Hermes::Mixins::Loggable::Static::info("Calculating error estimate.");
      errorCalculator.calculate_errors(sln_coarse, sln_time_new);
      double err_est_rel = errorCalculator.get_total_error_squared() * 100;

      // Report results.
      Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_ref: %d, err_est_rel: %g%%",
        Space<double>::get_num_dofs(space), Space<double>::get_num_dofs(ref_space), err_est_rel);

      // If err_est too large, adapt the mesh->
      if (err_est_rel < ERR_STOP) done = true;
      else
      {
        Hermes::Mixins::Loggable::Static::info("Adapting the coarse mesh.");
        done = adaptivity.adapt(&selector);
        as++;
      }

      if (HERMES_VISUALIZATION)
      {
        // Visualize the solution and mesh->
        char title[100];
        sprintf(title, "Solution<double>, time %g", current_time);
        view.set_title(title);
        view.show_mesh(false);
        view.show(sln_time_new);
        sprintf(title, "Mesh, time %g", current_time);
        ordview.set_title(title);
        ordview.show(space);
      }
    } while (done == false);

    sln_time_prev->copy(sln_time_new);

    // Increase current time and counter of time steps.
    current_time += time_step;
    ts++;
  } while (current_time < T_FINAL);

  // Wait for all views to be closed.
  if (HERMES_VISUALIZATION)
    View::wait();
  return 0;
}
Beispiel #4
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()) 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());

  // Turn off adaptive time stepping if R-K method is not embedded.
  if (bt.is_embedded() == false && ADAPTIVE_TIME_STEP_ON == true) {
    Hermes::Mixins::Loggable::Static::warn("R-K method not embedded, turning off adaptive time stepping.");
    ADAPTIVE_TIME_STEP_ON = false;
  }

  // Load the mesh.
  MeshSharedPtr mesh(new Mesh), basemesh(new Mesh);
  MeshReaderH2D mloader;
  mloader.load("wall.mesh", basemesh);
  mesh->copy(basemesh);

  // 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.
  SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT));
  int ndof = Space<double>::get_num_dofs(space);
  Hermes::Mixins::Loggable::Static::info("ndof = %d.", ndof);

  // Convert initial condition into a Solution.
  MeshFunctionSharedPtr<double> sln_prev_time(new ConstantSolution<double> (mesh, TEMP_INIT));

  // 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, &current_time);

  // Initialize the FE problem.
  DiscreteProblem<double> dp(&wf, space);

  // Create a refinement selector.
  H1ProjBasedSelector<double> selector(CAND_LIST);

  // Visualize initial condition.
  char title[100];
  ScalarView sln_view("Initial condition", new WinGeom(0, 0, 1500, 360));
  OrderView ordview("Initial mesh", new WinGeom(0, 410, 1500, 360));
  ScalarView time_error_view("Temporal error", new WinGeom(0, 800, 1500, 360));
  time_error_view.fix_scale_width(40);
  ScalarView space_error_view("Spatial error", new WinGeom(0, 1220, 1500, 360));
  space_error_view.fix_scale_width(40);
  sln_view.show(sln_prev_time);
  ordview.show(space);

  // Graph for time step history.
  SimpleGraph time_step_graph;
  if (ADAPTIVE_TIME_STEP_ON) Hermes::Mixins::Loggable::Static::info("Time step history will be saved to file time_step_history.dat.");

  // Class for projections.
  OGProjection<double> ogProjection;

  // Time stepping loop:
  int ts = 1;
  do 
  {
    Hermes::Mixins::Loggable::Static::info("Begin time step %d.", ts);
    // Periodic global derefinement.
    if (ts > 1 && ts % UNREF_FREQ == 0) 
    {
      Hermes::Mixins::Loggable::Static::info("Global mesh derefinement.");
      switch (UNREF_METHOD) {
      case 1: mesh->copy(basemesh);
        space->set_uniform_order(P_INIT);
        break;
      case 2: space->unrefine_all_mesh_elements();
        space->set_uniform_order(P_INIT);
        break;
      case 3: space->unrefine_all_mesh_elements();
        //space->adjust_element_order(-1, P_INIT);
        space->adjust_element_order(-1, -1, P_INIT, P_INIT);
        break;
      default: throw Hermes::Exceptions::Exception("Wrong global derefinement method.");
      }

      space->assign_dofs();
      ndof = Space<double>::get_num_dofs(space);
    }

    // Spatial adaptivity loop. Note: sln_prev_time must not be 
    // changed during spatial adaptivity. 
    MeshFunctionSharedPtr<double> ref_sln(new Solution<double>());
    MeshFunctionSharedPtr<double> time_error_fn(new Solution<double>(mesh));
    bool done = false; int as = 1;
    double err_est;
    do {
      // Construct globally refined reference mesh and setup reference space.
      Mesh::ReferenceMeshCreator refMeshCreator(mesh);
      MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh();

      Space<double>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh);
      SpaceSharedPtr<double> ref_space = refSpaceCreator.create_ref_space();

      // Initialize Runge-Kutta time stepping on the reference mesh.
      RungeKutta<double> runge_kutta(&wf, ref_space, &bt);

      try
      {
        ogProjection.project_global(ref_space, sln_prev_time, 
          sln_prev_time);
      }
      catch(Exceptions::Exception& e)
      {
        std::cout << e.what() << std::endl;
        Hermes::Mixins::Loggable::Static::error("Projection failed.");

        return -1;
      }

      // Runge-Kutta step on the fine mesh->
      Hermes::Mixins::Loggable::Static::info("Runge-Kutta time step on fine mesh (t = %g s, tau = %g s, stages: %d).", 
        current_time, time_step, bt.get_size());
      bool verbose = true;
      bool jacobian_changed = false;

      try
      {
        runge_kutta.set_time(current_time);
        runge_kutta.set_time_step(time_step);
        runge_kutta.set_max_allowed_iterations(NEWTON_MAX_ITER);
        runge_kutta.set_tolerance(NEWTON_TOL_FINE);
        runge_kutta.rk_time_step_newton(sln_prev_time, ref_sln, bt.is_embedded() ? time_error_fn : NULL);
      }
      catch(Exceptions::Exception& e)
      {
        std::cout << e.what() << std::endl;
        Hermes::Mixins::Loggable::Static::error("Runge-Kutta time step failed");

        return -1;
      }

      /* If ADAPTIVE_TIME_STEP_ON == true, estimate temporal error. 
      If too large or too small, then adjust it and restart the time step. */

      double rel_err_time = 0;
      if (bt.is_embedded() == true) 
      {
        Hermes::Mixins::Loggable::Static::info("Calculating temporal error estimate.");

        // Show temporal error.
        char title[100];
        sprintf(title, "Temporal error est, spatial adaptivity step %d", as);     
        time_error_view.set_title(title);
        //time_error_view.show_mesh(false);
        time_error_view.show(time_error_fn);

        rel_err_time = Global<double>::calc_norm(time_error_fn.get(), HERMES_H1_NORM) 
          / Global<double>::calc_norm(ref_sln.get(), HERMES_H1_NORM) * 100;
        if (ADAPTIVE_TIME_STEP_ON == false) Hermes::Mixins::Loggable::Static::info("rel_err_time: %g%%", rel_err_time);
      }

      if (ADAPTIVE_TIME_STEP_ON) 
      {
        if (rel_err_time > TIME_ERR_TOL_UPPER) 
        {
          Hermes::Mixins::Loggable::Static::info("rel_err_time %g%% is above upper limit %g%%", rel_err_time, TIME_ERR_TOL_UPPER);
          Hermes::Mixins::Loggable::Static::info("Decreasing tau from %g to %g s and restarting time step.", 
            time_step, time_step * TIME_STEP_DEC_RATIO);
          time_step *= TIME_STEP_DEC_RATIO;
          continue;
        }
        else if (rel_err_time < TIME_ERR_TOL_LOWER) 
        {
          Hermes::Mixins::Loggable::Static::info("rel_err_time = %g%% is below lower limit %g%%", rel_err_time, TIME_ERR_TOL_LOWER);
          Hermes::Mixins::Loggable::Static::info("Increasing tau from %g to %g s.", time_step, time_step * TIME_STEP_INC_RATIO);
          time_step *= TIME_STEP_INC_RATIO;
        }
        else 
        {
          Hermes::Mixins::Loggable::Static::info("rel_err_time = %g%% is in acceptable interval (%g%%, %g%%)", 
            rel_err_time, TIME_ERR_TOL_LOWER, TIME_ERR_TOL_UPPER);
        }

        // Add entry to time step history graph.
        time_step_graph.add_values(current_time, time_step);
        time_step_graph.save("time_step_history.dat");
      }

      /* Estimate spatial errors and perform mesh refinement */

      Hermes::Mixins::Loggable::Static::info("Spatial adaptivity step %d.", as);

      // Project the fine mesh solution onto the coarse mesh.
      MeshFunctionSharedPtr<double> sln(new Solution<double>());
      Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh for error estimation.");
      ogProjection.project_global(space, ref_sln, sln); 

      // Show spatial error.
      sprintf(title, "Spatial error est, spatial adaptivity step %d", as);  
      MeshFunctionSharedPtr<double> space_error_fn(new DiffFilter<double>(Hermes::vector<MeshFunctionSharedPtr<double> >(ref_sln, sln)));
      space_error_view.set_title(title);
      //space_error_view.show_mesh(false);
      MeshFunctionSharedPtr<double> abs_sef(new AbsFilter(space_error_fn));

      space_error_view.show(abs_sef);

      // Calculate element errors and spatial error estimate.
      Hermes::Mixins::Loggable::Static::info("Calculating spatial error estimate.");
      adaptivity.set_space(space);
      double err_rel_space = errorCalculator.get_total_error_squared() * 100;

      // Report results.
      Hermes::Mixins::Loggable::Static::info("ndof: %d, ref_ndof: %d, err_rel_space: %g%%", 
        Space<double>::get_num_dofs(space), Space<double>::get_num_dofs(ref_space), err_rel_space);

      // If err_est too large, adapt the mesh.
      if (err_rel_space < SPACE_ERR_TOL) done = true;
      else 
      {
        Hermes::Mixins::Loggable::Static::info("Adapting the coarse mesh.");
        done = adaptivity.adapt(&selector);

        if (Space<double>::get_num_dofs(space) >= NDOF_STOP) 
          done = true;
        else
          // Increase the counter of performed adaptivity steps.
          as++;
      }

      // Clean up.
      if(!done)

        
    }
    while (done == false);

    // Visualize the solution and mesh->
    char title[100];
    sprintf(title, "Solution, time %g s", current_time);
    sln_view.set_title(title);
    //sln_view.show_mesh(false);
    sln_view.show(ref_sln);
    sprintf(title, "Mesh, time %g s", current_time);
    ordview.set_title(title);
    ordview.show(space);

    // Copy last reference solution into sln_prev_time
    sln_prev_time->copy(ref_sln);

    // Increase current time and counter of time steps.
    current_time += time_step;
    ts++;
  }
  while (current_time < T_FINAL);

  // Wait for all views to be closed.
  View::wait();
  return 0;
}
Beispiel #5
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));

    // 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);

    // DOF and CPU convergence graphs initialization.
    SimpleGraph graph_dof, graph_cpu;

    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);

        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.
        try
        {
            newton.solve(coeff_vec);
        }
        catch(Hermes::Exceptions::Exception& e)
        {
            e.print_msg();
        }

        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;
        ogProjection.project_global(space, ref_sln, sln);

        // Calculate element errors and total error estimate.
        errorCalculator.calculate_errors(sln, ref_sln);

        // If err_est too large, adapt the mesh->
        if(errorCalculator.get_total_error_squared()  * 100. < ERR_STOP)
            done = true;
        else
        {
            adaptivity.adapt(&selector);
        }

        // Clean up.
        delete [] coeff_vec;

        // Increase counter.
        as++;
    }
    while (done == false);

    complex sum = 0;
    for (int i = 0; i < space->get_num_dofs(); i++)
        sum += newton.get_sln_vector()[i];
    printf("coefficient sum = %f\n", sum);

    complex expected_sum;
    expected_sum.real(1.4685364e-005);
    expected_sum.imag(-5.45632171e-007);

    bool success = true;
    if(std::abs(sum - expected_sum) > 1e-6)
        success = false;

    int ndof = space->get_num_dofs();
    if(ndof != 82) // Tested value as of May 2013.
        success = false;

    if(success)
    {
        printf("Success!\n");
        return 0;
    }
    else
    {
        printf("Failure!\n");
        return -1;
    }
}
Beispiel #6
0
  int main(int argc, char* args[])
  {
    // Load the mesh.
    MeshSharedPtr mesh(new Mesh);
    MeshReaderH2D mloader;
    mloader.load("square.mesh", mesh);

    // Perform initial mesh refinement.
    for (int i=0; i<INIT_REF; i++)
      mesh->refine_all_elements();

    // Create an L2 space->
    SpaceSharedPtr<double> space(new L2Space<double>(mesh, P_INIT));

    // Initialize refinement selector.
    L2ProjBasedSelector<double> selector(CAND_LIST);

    // Display the mesh.
#ifdef SHOW_OUTPUT
    OrderView oview("Coarse mesh", new WinGeom(0, 0, 440, 350));
    oview.show(space);
#endif

    MeshFunctionSharedPtr<double> sln(new Solution<double>);
    MeshFunctionSharedPtr<double> ref_sln(new Solution<double>);

    // Initialize the weak formulation.
    CustomWeakForm wf("Bdy_bottom_left", mesh);

#ifdef SHOW_OUTPUT
    ScalarView view1("Solution", new WinGeom(900, 0, 450, 350));
    view1.fix_scale_width(60);
#endif

    // Initialize linear solver.
    Hermes::Hermes2D::LinearSolver<double> linear_solver(&wf, space);

    int as = 1; bool done = false;
    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<double>::ReferenceSpaceCreator ref_space_creator(space, ref_mesh);
      SpaceSharedPtr<double> ref_space = ref_space_creator.create_ref_space();

      ref_space->save("space-real.xml");
      ref_space->free();
      ref_space->load("space-real.xml");
#ifdef WITH_BSON
      ref_space->save_bson("space-real.bson");
      ref_space->free();
      ref_space->load_bson("space-real.bson");
#endif

      linear_solver.set_space(ref_space);

      // Solve the linear system. If successful, obtain the solution.
      linear_solver.solve();
      Solution<double>::vector_to_solution(linear_solver.get_sln_vector(), ref_space, ref_sln);
      
      // Project the fine mesh solution onto the coarse mesh.
      OGProjection<double> ogProjection;
      ogProjection.project_global(space, ref_sln, sln, HERMES_L2_NORM);

#ifdef SHOW_OUTPUT
      MeshFunctionSharedPtr<double> val_filter(new ValFilter(ref_sln, 0.0, 1.0));

      // View the coarse mesh solution.
      view1.show(val_filter);
      oview.show(space);
#endif

      // Calculate element errors and total error estimate.
      errorCalculator.calculate_errors(sln, ref_sln);
      double err_est_rel = errorCalculator.get_total_error_squared() * 100;

      adaptivity.set_space(space);
#ifdef SHOW_OUTPUT
      std::cout << "Error: " << err_est_rel << "%." << std::endl;
#endif
      // If err_est_rel too large, adapt the mesh->
      if(err_est_rel < ERR_STOP)
        done = true;
      else
        done = adaptivity.adapt(&selector);
      as++;
    }
    while (done == false);

    // Wait for keyboard or mouse input.
#ifdef SHOW_OUTPUT
    View::wait();
#endif
    return as;
  }
Beispiel #7
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()) 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 mesh(new Mesh), basemesh(new Mesh);
  MeshReaderH1DXML mloader;
  try
  {
    mloader.load("domain.xml", basemesh);
  }
  catch (Hermes::Exceptions::MeshLoadFailureException& e)
  {
    e.print_msg();
    return -1;
  }

  // Perform initial mesh refinements.
  int refinement_type = 2;                        // Split elements vertically.
  for (int i = 0; i < INIT_REF_NUM; i++) basemesh->refine_all_elements(refinement_type, true);
  mesh->copy(basemesh);

  // Exact solution.
  CustomExactSolution exact_sln(mesh, x_0, x_1, y_0, y_1, &current_time, s, c);

  // Initialize boundary conditions.
  DefaultEssentialBCConst<double> bc_essential(std::vector<std::string>({ "Left", "Right" }), 0);
  EssentialBCs<double> bcs(&bc_essential);

  // Create an H1 space with default shapeset.
  SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT));
  int ndof_coarse = space->get_num_dofs();

  // Initialize the weak formulation
  CustomFunction f(x_0, x_1, y_0, y_1, s, c);
  WeakFormSharedPtr<double> wf(new CustomWeakFormPoisson(new Hermes::Hermes1DFunction<double>(-1.0), &f));

  // Previous and next time level solution.
  MeshFunctionSharedPtr<double>  sln_time_prev(new ZeroSolution<double>(mesh));
  MeshFunctionSharedPtr<double> sln_time_new(new Solution<double>(mesh));

  // Create a refinement selector.
  H1ProjBasedSelector<double> selector(CAND_LIST);

  // Visualize initial condition.
  char title[100];
  Views::ScalarView sview("Initial condition", new Views::WinGeom(0, 0, 1200, 200));
  Views::OrderView oview("Initial mesh", new Views::WinGeom(0, 260, 1200, 200));
  sview.show(sln_time_prev);
  oview.show(space);

  // Graph for dof history.
  SimpleGraph dof_history_graph;

  // Time stepping loop.
  int ts = 1;
  do
  {
    // Periodic global derefinement.
    if (ts > 1 && ts % UNREF_FREQ == 0)
    {
      Hermes::Mixins::Loggable::Static::info("Global mesh derefinement.");
      switch (UNREF_METHOD) {
      case 1: mesh->copy(basemesh);
        space->set_uniform_order(P_INIT);
        break;
      case 2: mesh->unrefine_all_elements();
        space->set_uniform_order(P_INIT);
        break;
      case 3: mesh->unrefine_all_elements();
        space->adjust_element_order(-1, -1, P_INIT, P_INIT);
        break;
      default: throw Hermes::Exceptions::Exception("Wrong global derefinement method.");
      }

      space->assign_dofs();
      ndof_coarse = space->get_num_dofs();
    }

    // Spatial adaptivity loop. Note: sln_time_prev must not be changed
    // during spatial adaptivity.
    bool done = false; int as = 1;
    double err_est;
    do {
      Hermes::Mixins::Loggable::Static::info("Time step %d, adaptivity step %d:", ts, as);

      // Construct globally refined reference mesh and setup reference space.
      // FIXME: This should be increase in the x-direction only.
      int order_increase = 1;
      // FIXME: This should be '2' but that leads to a segfault.
      int refinement_type = 0;
      Mesh::ReferenceMeshCreator refMeshCreator(mesh);
      MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh();

      Space<double>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh);
      SpaceSharedPtr<double> ref_space = refSpaceCreator.create_ref_space();
      int ndof_ref = ref_space->get_num_dofs();

      // Initialize Runge-Kutta time stepping.
      RungeKutta<double> runge_kutta(wf, ref_space, &bt);

      // Perform one Runge-Kutta time step according to the selected Butcher's table.
      Hermes::Mixins::Loggable::Static::info("Runge-Kutta time step (t = %g s, tau = %g s, stages: %d).",
        current_time, time_step, bt.get_size());
      bool freeze_jacobian = true;
      bool block_diagonal_jacobian = false;
      bool verbose = true;

      try
      {
        runge_kutta.set_time(current_time);
        runge_kutta.set_verbose_output(true);
        runge_kutta.set_time_step(time_step);
        runge_kutta.set_newton_max_allowed_iterations(NEWTON_MAX_ITER);
        runge_kutta.set_newton_tolerance(NEWTON_TOL);
        runge_kutta.rk_time_step_newton(sln_time_prev, sln_time_new);
      }
      catch (Exceptions::Exception& e)
      {
        e.print_msg();
        throw Hermes::Exceptions::Exception("Runge-Kutta time step failed");
      }

      // Project the fine mesh solution onto the coarse mesh.
      MeshFunctionSharedPtr<double> sln_coarse(new Solution<double>);
      Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh for error estimation.");
      OGProjection<double>::project_global(space, sln_time_new, sln_coarse);

      // Calculate element errors and total error estimate.
      Hermes::Mixins::Loggable::Static::info("Calculating error estimate.");
      adaptivity.set_space(space);
      errorCalculator.calculate_errors(sln_coarse, sln_time_new);
      double err_est_rel_total = errorCalculator.get_total_error_squared() * 100;

      // Report results.
      Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_ref: %d, err_est_rel: %g%%",
        space->get_num_dofs(), ref_space->get_num_dofs(), err_est_rel_total);

      // If err_est too large, adapt the mesh.
      if (err_est_rel_total < ERR_STOP) done = true;
      else
      {
        Hermes::Mixins::Loggable::Static::info("Adapting the coarse mesh.");
        done = adaptivity.adapt(&selector);

        // Increase the counter of performed adaptivity steps.
        as++;
      }
    } while (done == false);

    // Visualize the solution and mesh.
    char title[100];
    sprintf(title, "Solution, time %g", current_time);
    sview.set_title(title);
    sview.show_mesh(false);
    sview.show(sln_time_new);
    sprintf(title, "Mesh, time %g", current_time);
    oview.set_title(title);
    oview.show(space);

    // Copy last reference solution into sln_time_prev->
    sln_time_prev->copy(sln_time_new);

    dof_history_graph.add_values(current_time, space->get_num_dofs());
    dof_history_graph.save("dof_history.dat");

    // Increase current time and counter of time steps.
    current_time += time_step;
    ts++;
  } while (current_time < T_FINAL);

  // Wait for all views to be closed.
  Views::View::wait();
  return 0;
}
Beispiel #8
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;
  }
Beispiel #9
0
int main(int argc, char* argv[])
{
#ifdef THREAD_TESTING
  HermesCommonApi.set_integral_param_value(numThreads, 8);
#endif
  // Load the mesh.
  MeshSharedPtr mesh(new Mesh);
  Hermes::vector<MeshSharedPtr> meshes;
  meshes.push_back(mesh);
  MeshReaderH2DXML mloader;
  mloader.load("agrosMesh.msh", meshes);

  // Perform initial mesh refinements.
  for (int i = 0; i < INIT_REF_NUM; i++)
    mesh->refine_all_elements();

  // Initialize boundary conditions.
  DefaultEssentialBCConst<complex> bc_essential("4", P_SOURCE);
  EssentialBCs<complex> bcs(&bc_essential);

  // Create an H1 space with default shapeset.
  SpaceSharedPtr<complex> space(new H1Space<complex> (mesh, &bcs, P_INIT));
  adaptivity.set_space(space);

  // Initialize the weak formulation.
  CustomWeakFormAcoustics wf("0", RHO, SOUND_SPEED, OMEGA);

  // Initialize coarse and reference mesh solution.
  MeshFunctionSharedPtr<complex>  sln(new Solution<complex>), ref_sln(new Solution<complex>);

  // Initialize refinement selector.
  H1ProjBasedSelector<complex> selector(CAND_LIST);

  Hermes::Hermes2D::NewtonSolver<complex> newton;
  newton.set_weak_formulation(&wf);

  // 2 Adaptivity steps:
  int as = 1;
  bool done = false;
  do
  {
    // Construct globally refined reference mesh and setup reference space.
    Mesh::ReferenceMeshCreator refMeshCreator(mesh);
    MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh();

    Space<complex>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh);
    SpaceSharedPtr<complex> ref_space = refSpaceCreator.create_ref_space();

    // Perform Newton's iteration.
    try
    {
      newton.set_space(ref_space);
      newton.solve();
    }
    catch(Hermes::Exceptions::Exception& e)
    {
      e.print_msg();
      throw Hermes::Exceptions::Exception("Newton's iteration failed.");
    };

    // Translate the resulting coefficient vector into the Solution<complex> sln->
    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; ogProjection.project_global(space, ref_sln, sln);
    
    // Calculate element errors and total error estimate.
    errorCalculator.calculate_errors(sln, ref_sln);
    adaptivity.adapt(&selector);
  }
  while (as++ < 2);
  return 0;
}
Beispiel #10
0
int main(int argc, char* argv[])
{
    // Load the mesh.
    MeshSharedPtr mesh(new Mesh);
    MeshReaderH2D mloader;
    mloader.load("domain.mesh", mesh);

    // Initialize the weak formulation.
    CustomWeakFormPoisson wf("Motor", EPS_MOTOR, "Air", EPS_AIR);

    // Initialize boundary conditions
    DefaultEssentialBCConst<double> bc_essential_out("Outer", 0.0);
    DefaultEssentialBCConst<double> bc_essential_stator("Stator", VOLTAGE);
    EssentialBCs<double> bcs(Hermes::vector<EssentialBoundaryCondition<double> *>(&bc_essential_out, &bc_essential_stator));

    // Create an H1 space with default shapeset.
    SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT));

    // Set the space to adaptivity.
    adaptivity.set_space(space);

    // Initialize coarse and fine mesh solution.
    MeshFunctionSharedPtr<double> sln(new Solution<double>), ref_sln(new Solution<double>);

    // Initialize refinement selector.
    H1ProjBasedSelector<double> selector(CAND_LIST, H2DRS_DEFAULT_ORDER);

    // Initialize views.
    Views::ScalarView sview("Solution", new Views::WinGeom(0, 0, 410, 600));
    sview.fix_scale_width(50);
    sview.show_mesh(false);
    Views::OrderView  oview("Polynomial orders", new Views::WinGeom(420, 0, 400, 600));

    // DOF and CPU convergence graphs initialization.
    SimpleGraph graph_dof, graph_cpu;

    // Time measurement.
    Hermes::Mixins::TimeMeasurable cpu_time;

    DiscreteProblem<double> dp(&wf, space);
    NewtonSolver<double> newton(&dp);
    newton.set_verbose_output(true);

    // Adaptivity loop:
    int as = 1;
    bool done = false;
    do
    {
        Hermes::Mixins::Loggable::Static::info("---- Adaptivity step %d:", as);

        // Time measurement.
        cpu_time.tick();

        // Construct globally refined mesh and setup fine mesh space.
        Mesh::ReferenceMeshCreator ref_mesh_creator(mesh);
        MeshSharedPtr ref_mesh = ref_mesh_creator.create_ref_mesh();
        Space<double>::ReferenceSpaceCreator ref_space_creator(space, ref_mesh);
        SpaceSharedPtr<double> ref_space = ref_space_creator.create_ref_space();
        int ndof_ref = ref_space->get_num_dofs();

        // Initialize fine mesh problem.
        Hermes::Mixins::Loggable::Static::info("Solving on fine mesh.");

        newton.set_space(ref_space);

        // Perform Newton's iteration.
        try
        {
            newton.solve();
        }
        catch(std::exception& e)
        {
            std::cout << e.what();
        }

        // Translate the resulting coefficient vector into the instance of Solution.
        Solution<double>::vector_to_solution(newton.get_sln_vector(), ref_space, ref_sln);

        // Project the fine mesh solution onto the coarse mesh.
        Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh.");
        OGProjection<double>::project_global(space, ref_sln, sln);

        // Time measurement.
        cpu_time.tick();

        // VTK output.
        if (VTK_VISUALIZATION)
        {
            // Output solution in VTK format.
            Views::Linearizer lin;
            char* title = new char[100];
            sprintf(title, "sln-%d.vtk", as);
            lin.save_solution_vtk(ref_sln, title, "Potential", false);
            Hermes::Mixins::Loggable::Static::info("Solution in VTK format saved to file %s.", title);

            // Output mesh and element orders in VTK format.
            Views::Orderizer ord;
            sprintf(title, "ord-%d.vtk", as);
            ord.save_orders_vtk(space, title);
            Hermes::Mixins::Loggable::Static::info("Element orders in VTK format saved to file %s.", title);
        }

        // View the coarse mesh solution and polynomial orders.
        if (HERMES_VISUALIZATION)
        {
            sview.show(sln);
            oview.show(space);
        }

        // Skip visualization time.
        cpu_time.tick();

        // Calculate element errors and total error estimate.
        Hermes::Mixins::Loggable::Static::info("Calculating error estimate.");
        errorCalculator.calculate_errors(sln, ref_sln);
        double err_est_rel = errorCalculator.get_total_error_squared() * 100;

        // Report results.
        Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%",
                                               space->get_num_dofs(), ref_space->get_num_dofs(), err_est_rel);

        // Add entry to DOF and CPU convergence graphs.
        cpu_time.tick();
        graph_cpu.add_values(cpu_time.accumulated(), err_est_rel);
        graph_cpu.save("conv_cpu_est.dat");
        graph_dof.add_values(space->get_num_dofs(), err_est_rel);
        graph_dof.save("conv_dof_est.dat");

        // Skip the time spent to save the convergence graphs.
        cpu_time.tick();

        // If err_est too large, adapt the mesh.
        if (err_est_rel < ERR_STOP)
            done = true;
        else
        {
            Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh.");
            done = adaptivity.adapt(&selector);

            // Increase the counter of performed adaptivity steps.
            if (done == false)
                as++;
        }
    }
    while (done == false);

    Hermes::Mixins::Loggable::Static::info("Total running time: %g s", cpu_time.accumulated());

    // Show the fine mesh solution - final result.
    sview.set_title("Fine mesh solution");
    sview.show_mesh(false);
    sview.show(ref_sln);

    // Wait for all views to be closed.
    Views::View::wait();

    return 0;
}
Beispiel #11
0
int main(int argc, char* args[])
{
  // Load the mesh.
  MeshSharedPtr mesh(new Mesh);
  MeshReaderH2D mloader;
  mloader.load("square.mesh", mesh);

  // Perform initial mesh refinement.
  for (int i = 0; i < INIT_REF; i++)
    mesh->refine_all_elements();

  // Create an L2 space.
  SpaceSharedPtr<double> fine_space(new L2Space<double>(mesh, USE_TAYLOR_SHAPESET ? std::max(P_INIT, 2) : P_INIT, (USE_TAYLOR_SHAPESET ? (Shapeset*)(new L2ShapesetTaylor) : (Shapeset*)(new L2ShapesetLegendre))));

  // Initialize refinement selector.
  L2ProjBasedSelector<double> selector(CAND_LIST);
  selector.set_error_weights(1., 1., 1.);

  MeshFunctionSharedPtr<double> sln(new Solution<double>);
  MeshFunctionSharedPtr<double> refsln(new Solution<double>);

  // Initialize the weak formulation.
  WeakFormSharedPtr<double> wf(new CustomWeakForm("Bdy_bottom_left", mesh));
  ScalarView view1("Solution", new WinGeom(900, 0, 450, 350));
  view1.fix_scale_width(60);

  // Initialize linear solver.
  Hermes::Hermes2D::LinearSolver<double> linear_solver;
  linear_solver.set_weak_formulation(wf);

  adaptivity.set_space(fine_space);

  int as = 1; bool done = false;
  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<double>::ReferenceSpaceCreator refspace_creator(fine_space, ref_mesh, 0);
    SpaceSharedPtr<double> refspace = refspace_creator.create_ref_space();

    try
    {
      linear_solver.set_space(refspace);
      linear_solver.solve();

      if (USE_TAYLOR_SHAPESET)
      {
        PostProcessing::VertexBasedLimiter limiter(refspace, linear_solver.get_sln_vector(), P_INIT);
        refsln = limiter.get_solution();
      }
      else
      {
        Solution<double>::vector_to_solution(linear_solver.get_sln_vector(), refspace, refsln);
      }

      view1.show(refsln);
      OGProjection<double>::project_global(fine_space, refsln, sln, HERMES_L2_NORM);
    }
    catch (Exceptions::Exception& e)
    {
      std::cout << e.info();
    }
    catch (std::exception& e)
    {
      std::cout << e.what();
    }

    // Calculate element errors and total error estimate.
    errorCalculator.calculate_errors(sln, refsln);
    double err_est_rel = errorCalculator.get_total_error_squared() * 100;

    std::cout << "Error: " << err_est_rel << "%." << std::endl;

    // If err_est_rel too large, adapt the mesh.
    if (err_est_rel < ERR_STOP)
      done = true;
    else
      done = adaptivity.adapt(&selector);
    as++;
  } while (done == false);

  // Wait for keyboard or mouse input.
  View::wait();
  return 0;
}
Beispiel #12
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  MeshSharedPtr mesh(new Mesh);
  MeshReaderH2D mloader;
  mloader.load("square_quad.mesh", mesh);
  // mloader.load("square_tri.mesh", mesh);

  // Perform initial mesh refinement.
  for (int i = 0; i < INIT_REF_NUM; i++) mesh->refine_all_elements();
  mesh->refine_towards_boundary("Layer", INIT_REF_NUM_BDY);

  // Initialize the weak formulation.
  WeakFormSharedPtr<double> wf(new WeakFormLinearAdvectionDiffusion(STABILIZATION_ON, SHOCK_CAPTURING_ON, B1, B2, EPSILON));

  // Initialize boundary conditions
  DefaultEssentialBCConst<double> bc_rest("Rest", 1.0);
  EssentialBCNonConst bc_layer("Layer");

  EssentialBCs<double> bcs({ &bc_rest, &bc_layer });

  // Create an H1 space with default shapeset.
  SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT));

  WinGeom* sln_win_geom = new WinGeom(0, 0, 440, 350);
  WinGeom* mesh_win_geom = new WinGeom(450, 0, 400, 350);

  // Initialize coarse and reference mesh solution.
  MeshFunctionSharedPtr<double> sln(new Solution<double>), ref_sln(new Solution<double>);

  // Initialize refinement selector.
  H1ProjBasedSelector<double> selector(CAND_LIST);

  // Initialize views.
  ScalarView sview("Solution", new WinGeom(0, 0, 440, 350));
  sview.fix_scale_width(50);
  sview.show_mesh(false);
  OrderView  oview("Polynomial orders", new WinGeom(450, 0, 400, 350));

  // DOF and CPU convergence graphs initialization.
  SimpleGraph graph_dof, graph_cpu;

  // Time measurement.
  Hermes::Mixins::TimeMeasurable cpu_time;
  cpu_time.tick();

  // 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.
    Mesh::ReferenceMeshCreator refMeshCreator(mesh);
    MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh();

    Space<double>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh);
    SpaceSharedPtr<double> ref_space = refSpaceCreator.create_ref_space();

    // Assemble the reference problem.
    Hermes::Mixins::Loggable::Static::info("Solving on reference mesh.");
    LinearSolver<double> solver(wf, ref_space);

    // Time measurement.
    cpu_time.tick();

    // Solve the linear system of the reference problem.
    // If successful, obtain the solution.
    solver.solve();
    Solution<double>::vector_to_solution(solver.get_sln_vector(), ref_space, ref_sln);

    // Project the fine mesh solution onto the coarse mesh.
    Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh.");
    OGProjection<double>::project_global(space, ref_sln, sln);

    // Time measurement.
    cpu_time.tick();

    // View the coarse mesh solution and polynomial orders.
    sview.show(sln);
    oview.show(space);

    // Skip visualization time.
    cpu_time.tick(Hermes::Mixins::TimeMeasurable::HERMES_SKIP);

    // Calculate element errors and total error estimate.
    Hermes::Mixins::Loggable::Static::info("Calculating error estimate.");
    adaptivity.set_space(space);
    errorCalculator.calculate_errors(sln, ref_sln);
    double err_est_rel = errorCalculator.get_total_error_squared() * 100;

    // Report results.
    Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%",
      Space<double>::get_num_dofs(space), Space<double>::get_num_dofs(ref_space), err_est_rel);

    // Time measurement.
    cpu_time.tick();

    // Add entry to DOF and CPU convergence graphs.
    graph_dof.add_values(Space<double>::get_num_dofs(space), err_est_rel);
    graph_dof.save("conv_dof_est.dat");
    graph_cpu.add_values(cpu_time.accumulated(), err_est_rel);
    graph_cpu.save("conv_cpu_est.dat");

    // If err_est too large, adapt the mesh.
    if (err_est_rel < ERR_STOP) done = true;
    else
    {
      Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh.");
      done = adaptivity.adapt(&selector);

      // Increase the counter of performed adaptivity steps.
      if (done == false)  as++;
    }
  } while (done == false);

  Hermes::Mixins::Loggable::Static::info("Total running time: %g s", cpu_time.accumulated());

  // Show the reference solution - the final result.
  sview.set_title("Fine mesh solution");
  sview.show_mesh(false);
  sview.show(ref_sln);

  // Wait for all views to be closed.
  View::wait();
  return 0;
}