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

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

  // Create an L2 space with default shapeset.
  SpaceSharedPtr<double> space(new L2Space<double>(mesh, P_INIT));

  // View basis functions.
  BaseView<double> bview("BaseView", new WinGeom(0, 0, 600, 500));
  bview.show(space);
  // View::wait(H2DV_WAIT_KEYPRESS);

  // Initialize the exact and projected solution.
  MeshFunctionSharedPtr<double> sln(new Solution<double>);
  MeshFunctionSharedPtr<double> sln_exact(new CustomExactSolution(mesh));

  // Project the exact function on the FE space.
  OGProjection<double> ogProjection;
  ogProjection.project_global(space, sln_exact, sln);

  // Visualize the projection.
  ScalarView view1("Projection", new WinGeom(610, 0, 600, 500));
  view1.show(sln);

  // Wait for all views to be closed.
  View::wait();
  return 0;
}
예제 #2
0
int main(int argc, char* argv[])
{
  // Time measurement.
  Hermes::Mixins::TimeMeasurable cpu_time;
  cpu_time.tick();

  // 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 boundary conditions.
  DefaultEssentialBCConst<double> left_t("Left", 1.0);
  EssentialBCs<double> bcs_t(&left_t);

  DefaultEssentialBCConst<double> left_c("Left", 0.0);
  EssentialBCs<double> bcs_c(&left_c);

  // Create H1 spaces with default shapesets.
  H1Space<double>* t_space = new H1Space<double>(&mesh, &bcs_t, P_INIT);
  H1Space<double>* c_space = new H1Space<double>(&mesh, &bcs_c, P_INIT);
  int ndof = Space<double>::get_num_dofs(Hermes::vector<const Space<double>*>(t_space, c_space));
  Hermes::Mixins::Loggable::Static::info("ndof = %d.", ndof);

  // Define initial conditions.
  InitialSolutionTemperature t_prev_time_1(&mesh, x1);
  InitialSolutionConcentration c_prev_time_1(&mesh, x1, Le);
  InitialSolutionTemperature t_prev_time_2(&mesh, x1);
  InitialSolutionConcentration c_prev_time_2(&mesh, x1, Le);
  Solution<double> t_prev_newton;
  Solution<double> c_prev_newton;

  // Filters for the reaction rate omega and its derivatives.
  CustomFilter omega(Hermes::vector<Solution<double>*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU);
  CustomFilterDt omega_dt(Hermes::vector<Solution<double>*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU);
  CustomFilterDc omega_dc(Hermes::vector<Solution<double>*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU);

  // Initialize visualization.
  ScalarView rview("Reaction rate", new WinGeom(0, 0, 800, 230));

  // Initialize weak formulation.
  CustomWeakForm wf(Le, alpha, beta, kappa, x1, TAU, TRILINOS_JFNK, PRECOND, &omega, &omega_dt, 
                    &omega_dc, &t_prev_time_1, &c_prev_time_1, &t_prev_time_2, &c_prev_time_2);

  // Project the functions "t_prev_time_1" and "c_prev_time_1" on the FE space 
  // in order to obtain initial vector for NOX. 
  Hermes::Mixins::Loggable::Static::info("Projecting initial solutions on the FE meshes.");
  double* coeff_vec = new double[ndof];
  OGProjection<double> ogProjection; ogProjection.project_global(Hermes::vector<const Space<double> *>(t_space, c_space), 
                                       Hermes::vector<MeshFunction<double>*>(&t_prev_time_1, &c_prev_time_1),
                                       coeff_vec);

  // Measure the projection time.
  double proj_time = cpu_time.tick().last();

  // Initialize finite element problem.
  DiscreteProblem<double> dp(&wf, Hermes::vector<const Space<double>*>(t_space, c_space));

  // Initialize NOX solver and preconditioner.
  NewtonSolverNOX<double> solver(&dp);
  MlPrecond<double> pc("sa");
  if (PRECOND)
  {
    if (TRILINOS_JFNK) 
      solver.set_precond(pc);
    else 
      solver.set_precond("New Ifpack");
  }
  if (TRILINOS_OUTPUT)
    solver.set_output_flags(NOX::Utils::Error | NOX::Utils::OuterIteration |
                            NOX::Utils::OuterIterationStatusTest |
                            NOX::Utils::LinearSolverDetails);

  // Time stepping loop:
  double total_time = 0.0;
  cpu_time.tick_reset();
  for (int ts = 1; total_time <= T_FINAL; ts++)
  {
    Hermes::Mixins::Loggable::Static::info("---- Time step %d, t = %g s", ts, total_time + TAU);

    cpu_time.tick();
    try
    {
      solver.solve(coeff_vec);
    }
    catch(std::exception& e)
    {
      std::cout << e.what();
      
    }

    Solution<double>::vector_to_solutions(solver.get_sln_vector(), Hermes::vector<const Space<double> *>(t_space, c_space), 
              Hermes::vector<Solution<double> *>(&t_prev_newton, &c_prev_newton));

    cpu_time.tick();
    Hermes::Mixins::Loggable::Static::info("Number of nonlin iterations: %d (norm of residual: %g)",
        solver.get_num_iters(), solver.get_residual());
    Hermes::Mixins::Loggable::Static::info("Total number of iterations in linsolver: %d (achieved tolerance in the last step: %g)",
        solver.get_num_lin_iters(), solver.get_achieved_tol());

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

    // Update global time.
    total_time += TAU;

    // Saving solutions for the next time step.
    if(ts > 1)
    {
      t_prev_time_2.copy(&t_prev_time_1);
      c_prev_time_2.copy(&c_prev_time_1);
    }

    t_prev_time_1.copy(&t_prev_newton);
    c_prev_time_1.copy(&c_prev_newton);
      
    // Visualization.
    rview.set_min_max_range(0.0,2.0);
    rview.show(&omega);
    cpu_time.tick();

    Hermes::Mixins::Loggable::Static::info("Total running time for time level %d: %g s.", ts, cpu_time.tick().last());
  }

  // Wait for all views to be closed.
  View::wait();
  return 0;
}
예제 #3
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  MeshSharedPtr mesh(new Mesh);
  MeshReaderH2D mloader;
  mloader.load("domain.mesh", mesh);

  // Initial mesh refinements.
  mesh->refine_towards_boundary(BDY_OBSTACLE, 2, false);
  mesh->refine_towards_boundary(BDY_TOP, 2, true);     // '4' is the number of levels,
  mesh->refine_towards_boundary(BDY_BOTTOM, 2, true);  // 'true' stands for anisotropic refinements.
  mesh->refine_all_elements();

  // Initialize boundary conditions.
  EssentialBCNonConst bc_left_vel_x(BDY_LEFT, VEL_INLET, H, STARTUP_TIME);
  Hermes::Hermes2D::DefaultEssentialBCConst<double> bc_other_vel_x(Hermes::vector<std::string>(BDY_BOTTOM, BDY_TOP, BDY_OBSTACLE), 0.0);
  Hermes::Hermes2D::EssentialBCs<double> bcs_vel_x(Hermes::vector<EssentialBoundaryCondition<double> *>(&bc_left_vel_x, &bc_other_vel_x));
  Hermes::Hermes2D::DefaultEssentialBCConst<double> bc_vel_y(Hermes::vector<std::string>(BDY_LEFT, BDY_BOTTOM, BDY_TOP, BDY_OBSTACLE), 0.0);
  Hermes::Hermes2D::EssentialBCs<double> bcs_vel_y(&bc_vel_y);
  Hermes::Hermes2D::EssentialBCs<double> bcs_pressure;

  // Spaces for velocity components and pressure.
  SpaceSharedPtr<double> xvel_space(new H1Space<double>(mesh, &bcs_vel_x, P_INIT_VEL));
  SpaceSharedPtr<double> yvel_space(new H1Space<double>(mesh, &bcs_vel_y, P_INIT_VEL));
#ifdef PRESSURE_IN_L2
  SpaceSharedPtr<double> p_space(new L2Space<double> (mesh, P_INIT_PRESSURE));
#else
  SpaceSharedPtr<double> p_space(new H1Space<double> (mesh, &bcs_pressure, P_INIT_PRESSURE));
#endif

  // Calculate and report the number of degrees of freedom.
  int ndof = Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(xvel_space, yvel_space, p_space));

  // Define projection norms.
  NormType vel_proj_norm = HERMES_H1_NORM;
#ifdef PRESSURE_IN_L2
  NormType p_proj_norm = HERMES_L2_NORM;
#else
  NormType p_proj_norm = HERMES_H1_NORM;
#endif

  // Solutions for the Newton's iteration and time stepping.
  MeshFunctionSharedPtr<double> xvel_prev_time(new ConstantSolution<double> (mesh, 0.0));
  MeshFunctionSharedPtr<double> yvel_prev_time(new ConstantSolution<double> (mesh, 0.0));
  MeshFunctionSharedPtr<double> p_prev_time(new ConstantSolution<double> (mesh, 0.0));

  // Initialize weak formulation.
  WeakFormNSNewton wf(STOKES, RE, TAU, xvel_prev_time, yvel_prev_time);
  UExtFunctionSharedPtr<double> fn_0(new CustomUExtFunction(0));
  UExtFunctionSharedPtr<double> fn_1(new CustomUExtFunction(1));
  wf.set_ext(Hermes::vector<MeshFunctionSharedPtr<double> >(xvel_prev_time, yvel_prev_time));
  wf.set_u_ext_fn(Hermes::vector<UExtFunctionSharedPtr<double> >(fn_0, fn_1));

  // Initialize the Newton solver.
  Hermes::Hermes2D::NewtonSolver<double> newton;
  newton.set_weak_formulation(&wf);
  Hermes::vector<SpaceSharedPtr<double> > spaces(xvel_space, yvel_space, p_space);
  newton.set_spaces(spaces);

  // Initialize views.
  Views::VectorView vview("velocity[m/s]", new Views::WinGeom(0, 0, 750, 240));
  Views::ScalarView pview("pressure[Pa]", new Views::WinGeom(0, 290, 750, 240));
  vview.set_min_max_range(0, 1.6);
  vview.fix_scale_width(80);
  //pview.set_min_max_range(-0.9, 1.0);
  pview.fix_scale_width(80);
  if(HERMES_VISUALIZATION)
    pview.show_mesh(true);

  // Project the initial condition on the FE space to obtain initial
  // coefficient vector for the Newton's method.
  double* coeff_vec = new double[Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(xvel_space, yvel_space, p_space))];
  OGProjection<double> ogProjection;

  ogProjection.project_global(Hermes::vector<SpaceSharedPtr<double> >(xvel_space, yvel_space, p_space),
    Hermes::vector<MeshFunctionSharedPtr<double> >(xvel_prev_time, yvel_prev_time, p_prev_time),
    coeff_vec, Hermes::vector<NormType>(vel_proj_norm, vel_proj_norm, p_proj_norm));

  newton.set_max_allowed_iterations(max_allowed_iterations);
  newton.set_tolerance(NEWTON_TOL, Hermes::Solvers::ResidualNormAbsolute);
  newton.set_sufficient_improvement_factor_jacobian(1e-2);
  //newton.set_jacobian_constant();

  // Time-stepping loop:
  char title[100];
  int num_time_steps = T_FINAL / TAU;
  for (int ts = 1; ts <= num_time_steps; ts++)
  {
    current_time += TAU;
    Hermes::Mixins::Loggable::Static::info("Time step %i, time %f.", ts, current_time);

    // Update time-dependent essential BCs.
    newton.set_time(current_time);

    // Perform Newton's iteration and translate the resulting coefficient vector into previous time level solutions.
    try
    {
      newton.solve(coeff_vec);
    }
    catch(Hermes::Exceptions::Exception& e)
    {
      e.print_msg();
    }
    Hermes::vector<MeshFunctionSharedPtr<double> > tmp(xvel_prev_time, yvel_prev_time, p_prev_time);
    Hermes::Hermes2D::Solution<double>::vector_to_solutions(newton.get_sln_vector(), 
      Hermes::vector<SpaceSharedPtr<double> >(xvel_space, yvel_space, p_space), tmp);

    // Show the solution at the end of time step.
    if(HERMES_VISUALIZATION)
    {
      sprintf(title, "Velocity, time %g", current_time);
      vview.set_title(title);
      vview.show(xvel_prev_time, yvel_prev_time);
      sprintf(title, "Pressure, time %g", current_time);
      pview.set_title(title);
      pview.show(p_prev_time);
    }
  }

  delete [] coeff_vec;

  return 0;
}
예제 #4
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  mloader.load("square.mesh", &mesh);     // quadrilaterals

  // Perform initial mesh refinements.
  for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements();
  
  // Define exact solution.
  CustomExactSolution exact(&mesh, slope);

  // Define right-hand side.
  CustomFunction f(slope);

  // Initialize the weak formulation.
  WeakFormsH1::DefaultWeakFormPoisson<double> wf(HERMES_ANY, new Hermes1DFunction<double>(1.0), &f);
  
  // Initialize boundary conditions
  DefaultEssentialBCNonConst<double> bc_essential("Bdy", &exact);
  EssentialBCs<double> bcs(&bc_essential);

  // Create an H1 space with default shapeset.
  H1Space<double> space(&mesh, &bcs, P_INIT);
  
  // Initialize refinement selector.
  H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER);

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

  // DOF and CPU convergence graphs.
  SimpleGraph graph_dof, graph_cpu, 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
  {
    Hermes::Mixins::Loggable::Static::info("---- Adaptivity step %d:", as);

    // Construct globally refined reference mesh and setup reference space.
    Space<double>* ref_space = Space<double>::construct_refined_space(&space);
    int ndof_ref = Space<double>::get_num_dofs(ref_space);

    // Initialize reference problem.
    Hermes::Mixins::Loggable::Static::info("Solving on reference mesh.");
    DiscreteProblem<double> dp(&wf, ref_space);

    // Time measurement.
    cpu_time.tick();

    // Initial coefficient vector for the Newton's method.  
    double* coeff_vec = new double[ndof_ref];
    memset(coeff_vec, 0, ndof_ref * sizeof(double));

    // Initialize NOX solver.
    NewtonSolverNOX<double> solver(&dp);
    solver.set_output_flags(message_type);

    solver.set_ls_tolerance(ls_tolerance);

    solver.set_conv_iters(max_iters);
    if (flag_absresid)
      solver.set_conv_abs_resid(abs_resid);
    if (flag_relresid)
      solver.set_conv_rel_resid(rel_resid);

    // Select preconditioner.
    MlPrecond<double> pc("sa");
    if (PRECOND)
    {
      if (TRILINOS_JFNK) solver.set_precond(pc);
      else solver.set_precond("ML");
    }

    // Time measurement.
    cpu_time.tick();

    Solution<double> sln, ref_sln;

    Hermes::Mixins::Loggable::Static::info("Assembling by DiscreteProblem, solving by NOX.");
    try
    {
      solver.solve(coeff_vec);
    }
    catch(std::exception& e)
    {
      std::cout << e.what();
      
    }

    Solution<double>::vector_to_solution(solver.get_sln_vector(), ref_space, &ref_sln);
    Hermes::Mixins::Loggable::Static::info("Number of nonlin iterations: %d (norm of residual: %g)", 
      solver.get_num_iters(), solver.get_residual());
    Hermes::Mixins::Loggable::Static::info("Total number of iterations in linsolver: %d (achieved tolerance in the last step: %g)", 
      solver.get_num_lin_iters(), solver.get_achieved_tol());

    Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh.");
    OGProjection<double> ogProjection; ogProjection.project_global(&space, &ref_sln, &sln);

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

    // Calculate element errors and total error estimate.
    Hermes::Mixins::Loggable::Static::info("Calculating error estimate and exact error.");
    Adapt<double>* adaptivity = new Adapt<double>(&space);
    double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100;

    // Calculate exact error.
    //Solution<double>* exact = new Solution(&mesh, &exact);
    bool solutions_for_adapt = false;
    double err_exact_rel = adaptivity->calc_err_exact(&sln, &exact, solutions_for_adapt) * 100;

    // Report results.
    Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d",
      Space<double>::get_num_dofs(&space), Space<double>::get_num_dofs(ref_space));
    Hermes::Mixins::Loggable::Static::info("err_est_rel: %g%%, err_exact_rel: %g%%", err_est_rel, err_exact_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");
    graph_dof_exact.add_values(Space<double>::get_num_dofs(&space), err_exact_rel);
    graph_dof_exact.save("conv_dof_exact.dat");
    graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel);
    graph_cpu_exact.save("conv_cpu_exact.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, THRESHOLD, STRATEGY, MESH_REGULARITY);

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

    // Clean up.
    delete [] coeff_vec;
    delete adaptivity;
    if(done == false) delete ref_space->get_mesh();
    delete ref_space;
  }
  while (done == false);

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

  // Wait for all views to be closed.
  View::wait();
  return 0;
}
예제 #5
0
파일: main.cpp 프로젝트: fauzisd/hermes
int main(int argc, char* argv[])
{
  Hermes::Mixins::TimeMeasurable m;
  m.tick();

  // Load the mesh.
  Mesh 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<std::complex<double> > bc_essential("Dirichlet", std::complex<double>(0.0, 0.0));
  EssentialBCs<std::complex<double> > bcs(&bc_essential);

  // Create an H1 space with default shapeset.
  H1Space<std::complex<double> > space(&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, std::complex<double>(J_EXT, 0.0), OMEGA);

  // Initialize coarse and reference mesh solution.
  Solution<std::complex<double> > sln, ref_sln;

  // Initialize refinement selector.
  H1ProjBasedSelector<std::complex<double> > selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER);

  // Initialize views.
  Views::VectorView sview("Solution", new Views::WinGeom(0, 0, 600, 350));
  Views::OrderView oview("Polynomial orders", new Views::WinGeom(610, 0, 520, 350));

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

  DiscreteProblem<std::complex<double> > dp(&wf, &space);

  // Perform Newton's iteration and translate the resulting coefficient vector into a Solution.
  Hermes::Hermes2D::NewtonSolver<std::complex<double> > newton(&dp);
    
  Views::MeshView m1, m2;
  Views::OrderView o1, o2;
  // Adaptivity loop:
  int as = 1; bool done = false;
  do
  {
    // Construct globally refined reference mesh and setup reference space.
    Space<std::complex<double> >::ReferenceSpaceCreator ref_space_creator(&space, &mesh);
    Space<std::complex<double> >* 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.
    std::complex<double>* coeff_vec = new std::complex<double>[ndof_ref];
    memset(coeff_vec, 0, ndof_ref * sizeof(std::complex<double>));

    // Perform Newton's iteration and translate the resulting coefficient vector into a Solution.
    // For iterative solver.
    if(matrix_solver_type == SOLVER_AZTECOO)
    {
      newton.set_iterative_method(iterative_method);
      newton.set_preconditioner(preconditioner);
    }
    try
    {
      newton.solve_keep_jacobian(coeff_vec);
    }
    catch(Hermes::Exceptions::Exception& e)
    {
      e.print_msg();
    }

    Hermes::Hermes2D::Solution<std::complex<double> >::vector_to_solution(newton.get_sln_vector(), ref_space, &ref_sln);

    // Project the fine mesh solution onto the coarse mesh.
    OGProjection<std::complex<double> > ogProjection;
    ogProjection.project_global(&space, &ref_sln, &sln);

    // View the coarse mesh solution and polynomial orders.
    RealFilter real_filter(&sln);
    sview.show(&real_filter, &real_filter);

    oview.show(&space);

    // Calculate element errors and total error estimate.
    Adapt<std::complex<double> >* adaptivity = new Adapt<std::complex<double> >(&space);
    double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100;
    std::cout << (std::string)"Relative error: " << err_est_rel << std::endl;

    // Add entry to DOF and CPU convergence graphs.
    graph_dof.add_values(space.get_num_dofs(), err_est_rel);
    graph_dof.save("conv_dof_est.dat");

    // If err_est too large, adapt the mesh.
    if(err_est_rel < ERR_STOP) done = true;
    else
    {
      std::cout << (std::string)"Adapting..." << std::endl << std::endl;
      done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY);
    }
    if(space.get_num_dofs() >= NDOF_STOP) done = true;

    // Clean up.
    delete [] coeff_vec;
    delete adaptivity;

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

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

  RealFilter real_filter(&ref_sln);
  sview.show(&real_filter, &real_filter);

  m.tick();
  std::cout << m.accumulated();

  // Wait for all views to be closed.
  Views::View::wait();
  return 0;
}
예제 #6
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  MeshSharedPtr u_mesh(new Mesh), v_mesh(new Mesh);
  MeshReaderH2D mloader;
  mloader.load("elasticity.mesh", u_mesh);

  // Create initial mesh (master mesh).
  v_mesh->copy(u_mesh);

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

  // Set exact solution for each displacement component.
  MeshFunctionSharedPtr<double> exact_u(new CustomExactSolutionU(u_mesh, E, nu, lambda, Q));
  MeshFunctionSharedPtr<double> exact_v(new CustomExactSolutionV(v_mesh, E, nu, lambda, Q));

  // Initialize the weak formulation.
  // NOTE: We pass all four parameters (temporarily) 
  // since in Mitchell's paper (NIST benchmarks) they 
  // are mutually inconsistent.
  CustomWeakFormElasticityNIST wf(E, nu, mu, lambda);

  // Initialize boundary conditions.
  DefaultEssentialBCNonConst<double> bc_u("Bdy", exact_u);
  EssentialBCs<double> bcs_u(&bc_u);
  DefaultEssentialBCNonConst<double> bc_v("Bdy", exact_v);
  EssentialBCs<double> bcs_v(&bc_v);

  // Create H1 spaces with default shapeset for both displacement components.
  SpaceSharedPtr<double> u_space(new H1Space<double>(u_mesh, &bcs_u, P_INIT_U));
  SpaceSharedPtr<double> v_space(new H1Space<double>(v_mesh, &bcs_v, P_INIT_V));
  Hermes::vector<SpaceSharedPtr<double> >spaces(u_space, v_space);

  // Initialize approximate solution.
  MeshFunctionSharedPtr<double> u_sln(new Solution<double>());
  MeshFunctionSharedPtr<double> u_ref_sln(new Solution<double>());
  MeshFunctionSharedPtr<double> v_sln(new Solution<double>());
  MeshFunctionSharedPtr<double> v_ref_sln(new Solution<double>());
  Hermes::vector<MeshFunctionSharedPtr<double> >slns(u_sln, v_sln);
  Hermes::vector<MeshFunctionSharedPtr<double> >ref_slns(u_ref_sln, v_ref_sln);
  Hermes::vector<MeshFunctionSharedPtr<double> >exact_slns(exact_u, exact_v);

  // Initialize refinement selector.
  MySelector selector(CAND_LIST);

  // Initialize views.
  Views::ScalarView s_view_u("Solution for u", new WinGeom(0, 0, 440, 350));
  s_view_u.show_mesh(false);
  Views::OrderView  o_view_u("Mesh for u", new WinGeom(450, 0, 420, 350));
  Views::ScalarView s_view_v("Solution for v", new WinGeom(0, 405, 440, 350));
  s_view_v.show_mesh(false);
  Views::OrderView  o_view_v("Mesh for v", new WinGeom(450, 405, 420, 350));
  Views::ScalarView mises_view("Von Mises stress [Pa]", new WinGeom(880, 0, 440, 350));
  mises_view.fix_scale_width(50);

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

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

    // Construct globally refined reference mesh and setup reference space->
    Mesh::ReferenceMeshCreator refMeshCreatorU(u_mesh);
    MeshSharedPtr ref_u_mesh = refMeshCreatorU.create_ref_mesh();

    Space<double>::ReferenceSpaceCreator refSpaceCreatorU(u_space, ref_u_mesh);
    SpaceSharedPtr<double> ref_u_space = refSpaceCreatorU.create_ref_space();

    Mesh::ReferenceMeshCreator refMeshCreatorV(u_mesh);
    MeshSharedPtr ref_v_mesh = refMeshCreatorV.create_ref_mesh();

    Space<double>::ReferenceSpaceCreator refSpaceCreatorV(v_space, ref_v_mesh);
    SpaceSharedPtr<double> ref_v_space = refSpaceCreatorV.create_ref_space();

    Hermes::vector<SpaceSharedPtr<double> > ref_spaces(ref_u_space, ref_v_space);

    int ndof_ref = Space<double>::get_num_dofs(ref_spaces);

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

    NewtonSolver<double> newton(&dp);
    
    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_solutions(newton.get_sln_vector(), ref_spaces, ref_slns);

    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(spaces, ref_slns, slns);

    // Calculate element errors and total error estimate.
    DefaultErrorCalculator<double, HERMES_H1_NORM> error_calculator(errorType, 2);
    error_calculator.calculate_errors(slns, exact_slns);
    double err_exact_rel_total = error_calculator.get_total_error_squared() * 100.0;
    error_calculator.calculate_errors(slns, ref_slns);
    double err_est_rel_total = error_calculator.get_total_error_squared() * 100.0;

    Adapt<double> adaptivity(spaces, &error_calculator);
    adaptivity.set_strategy(&stoppingCriterion);

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

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

    // View the coarse mesh solution and polynomial orders.
    s_view_u.show(u_sln); 
    o_view_u.show(u_space);
    s_view_v.show(v_sln); 
    o_view_v.show(v_space);
    MeshFunctionSharedPtr<double> stress(new VonMisesFilter(Hermes::vector<MeshFunctionSharedPtr<double> >(u_sln, v_sln), lambda, mu));
    mises_view.show(stress, H2D_FN_VAL_0, u_sln, v_sln, 0.03);

    // Add entry to DOF and CPU convergence graphs.
    graph_dof_est.add_values(Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space)), err_est_rel_total);
    graph_dof_est.save("conv_dof_est.dat");
    graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel_total);
    graph_cpu_est.save("conv_cpu_est.dat");
    graph_dof_exact.add_values(Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space)), err_exact_rel_total);
    graph_dof_exact.save("conv_dof_exact.dat");
    graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel_total);
    graph_cpu_exact.save("conv_cpu_exact.dat");

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

    // If err_est too large, adapt the mesh.
    if (err_est_rel_total < ERR_STOP) 
      done = true;
    else 
    {
      Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh.");
      done = adaptivity.adapt(Hermes::vector<RefinementSelectors::Selector<double> *>(&selector, &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();
  return 0;
}
예제 #7
0
파일: main.cpp 프로젝트: HPeX/hermes
int main(int argc, char* argv[])
{
  // Time measurement.
  Hermes::Mixins::TimeMeasurable cpu_time;
  cpu_time.tick();

  // Load the mesh.
  MeshSharedPtr u_mesh(new Mesh), v_mesh(new Mesh);
  MeshReaderH2D mloader;
  mloader.load("domain.mesh", u_mesh);
  if (MULTI == false)
    u_mesh->refine_towards_boundary("Bdy", INIT_REF_BDY);

  // Create initial mesh (master mesh).
  v_mesh->copy(u_mesh);

  // Initial mesh refinements in the v_mesh towards the boundary.
  if (MULTI == true)
    v_mesh->refine_towards_boundary("Bdy", INIT_REF_BDY);

  // Set exact solutions.
  MeshFunctionSharedPtr<double> exact_u(new ExactSolutionFitzHughNagumo1(u_mesh));
  MeshFunctionSharedPtr<double> exact_v(new ExactSolutionFitzHughNagumo2(MULTI ? v_mesh : u_mesh, K));

  // Define right-hand sides.
  CustomRightHandSide1 g1(K, D_u, SIGMA);
  CustomRightHandSide2 g2(K, D_v);

  // Initialize the weak formulation.
  CustomWeakForm wf(&g1, &g2);

  // Initialize boundary conditions
  DefaultEssentialBCConst<double> bc_u("Bdy", 0.0);
  EssentialBCs<double> bcs_u(&bc_u);
  DefaultEssentialBCConst<double> bc_v("Bdy", 0.0);
  EssentialBCs<double> bcs_v(&bc_v);

  // Create H1 spaces with default shapeset for both displacement components.
  SpaceSharedPtr<double> u_space(new H1Space<double>(u_mesh, &bcs_u, P_INIT_U));
  SpaceSharedPtr<double> v_space(new H1Space<double>(MULTI ? v_mesh : u_mesh, &bcs_v, P_INIT_V));

  // Initialize coarse and reference mesh solutions.
  MeshFunctionSharedPtr<double> u_sln(new Solution<double>()), v_sln(new Solution<double>()), u_ref_sln(new Solution<double>()), v_ref_sln(new Solution<double>());
  Hermes::vector<MeshFunctionSharedPtr<double> > slns(u_sln, v_sln);
  Hermes::vector<MeshFunctionSharedPtr<double> > ref_slns(u_ref_sln, v_ref_sln);
  Hermes::vector<MeshFunctionSharedPtr<double> > exact_slns(exact_u, exact_v);

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

  // Initialize views.
  Views::ScalarView s_view_0("Solution[0]", new Views::WinGeom(0, 0, 440, 350));
  s_view_0.show_mesh(false);
  Views::OrderView  o_view_0("Mesh[0]", new Views::WinGeom(450, 0, 420, 350));
  Views::ScalarView s_view_1("Solution[1]", new Views::WinGeom(880, 0, 440, 350));
  s_view_1.show_mesh(false);
  Views::OrderView o_view_1("Mesh[1]", new Views::WinGeom(1330, 0, 420, 350));

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

  NewtonSolver<double> newton;
  newton.set_weak_formulation(&wf);

  // 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 u_ref_mesh_creator(u_mesh);
    MeshSharedPtr u_ref_mesh = u_ref_mesh_creator.create_ref_mesh();
    Mesh::ReferenceMeshCreator v_ref_mesh_creator(v_mesh);
    MeshSharedPtr v_ref_mesh = v_ref_mesh_creator.create_ref_mesh();
    Space<double>::ReferenceSpaceCreator u_ref_space_creator(u_space, u_ref_mesh);
    SpaceSharedPtr<double> u_ref_space = u_ref_space_creator.create_ref_space();
    Space<double>::ReferenceSpaceCreator v_ref_space_creator(v_space, MULTI ? v_ref_mesh : u_ref_mesh);
    SpaceSharedPtr<double> v_ref_space = v_ref_space_creator.create_ref_space();

    Hermes::vector<SpaceSharedPtr<double> > ref_spaces_const(u_ref_space, v_ref_space);

    newton.set_spaces(ref_spaces_const);

    int ndof_ref = Space<double>::get_num_dofs(ref_spaces_const);

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

    // Time measurement.
    cpu_time.tick();

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

    // Translate the resulting coefficient vector into the instance of Solution.
    Solution<double>::vector_to_solutions(newton.get_sln_vector(), ref_spaces_const, Hermes::vector<MeshFunctionSharedPtr<double> >(u_ref_sln, v_ref_sln));

    // Project the fine mesh solution onto the coarse mesh.
    Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh.");
    OGProjection<double> ogProjection; ogProjection.project_global(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space), ref_slns, slns);

    cpu_time.tick();

    // View the coarse mesh solution and polynomial orders.
    s_view_0.show(u_sln);
    o_view_0.show(u_space);
    s_view_1.show(v_sln);
    o_view_1.show(v_space);

    // Calculate element errors.
    Hermes::Mixins::Loggable::Static::info("Calculating error estimate and exact error.");
    errorCalculator.calculate_errors(slns, exact_slns, false);
    double err_exact_rel_total = errorCalculator.get_total_error_squared() * 100;
    Hermes::vector<double> err_exact_rel;
    err_exact_rel.push_back(errorCalculator.get_error_squared(0) * 100);
    err_exact_rel.push_back(errorCalculator.get_error_squared(1) * 100);

    errorCalculator.calculate_errors(slns, ref_slns, true);
    double err_est_rel_total = errorCalculator.get_total_error_squared() * 100;
    Hermes::vector<double> err_est_rel;
    err_est_rel.push_back(errorCalculator.get_error_squared(0) * 100);
    err_est_rel.push_back(errorCalculator.get_error_squared(1) * 100);

    adaptivity.set_spaces(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space));

    // Time measurement.
    cpu_time.tick();

    // Report results.
    Hermes::Mixins::Loggable::Static::info("ndof_coarse[0]: %d, ndof_fine[0]: %d",
      u_space->get_num_dofs(), u_ref_space->get_num_dofs());
    Hermes::Mixins::Loggable::Static::info("err_est_rel[0]: %g%%, err_exact_rel[0]: %g%%", err_est_rel[0], err_exact_rel[0]);
    Hermes::Mixins::Loggable::Static::info("ndof_coarse[1]: %d, ndof_fine[1]: %d",
      v_space->get_num_dofs(), v_ref_space->get_num_dofs());
    Hermes::Mixins::Loggable::Static::info("err_est_rel[1]: %g%%, err_exact_rel[1]: %g%%", err_est_rel[1], err_exact_rel[1]);
    Hermes::Mixins::Loggable::Static::info("ndof_coarse_total: %d, ndof_fine_total: %d",
      Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space)),
      Space<double>::get_num_dofs(ref_spaces_const));
    Hermes::Mixins::Loggable::Static::info("err_est_rel_total: %g%%, err_est_exact_total: %g%%", err_est_rel_total, err_exact_rel_total);

    // Add entry to DOF and CPU convergence graphs.
    graph_dof_est.add_values(Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space)),
      err_est_rel_total);
    graph_dof_est.save("conv_dof_est.dat");
    graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel_total);
    graph_cpu_est.save("conv_cpu_est.dat");

    graph_dof_exact.add_values(Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space)),
      err_exact_rel_total);
    graph_dof_exact.save("conv_dof_exact.dat");
    graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel_total);
    graph_cpu_exact.save("conv_cpu_exact.dat");

    // If err_est too large, adapt the mesh->
    if (err_est_rel_total < ERR_STOP)
      done = true;
    else
    {
      Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh.");
      Hermes::vector<RefinementSelectors::Selector<double> *> selectors(&selector, &selector);
      done = adaptivity.adapt(selectors);
    }

    // Increase counter.
    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();
  return 0;
}
예제 #8
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;
}
예제 #9
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;
  }
예제 #10
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;
}
예제 #11
0
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));
    Hermes::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));
    Hermes::vector<MeshFunctionSharedPtr<double> > slns_time_new(E_time_new, H_time_new, P_time_new);

    // Initialize the weak formulation.
    CustomWeakFormMD wf(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));

    Hermes::vector<SpaceSharedPtr<double> > spaces = Hermes::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_max_allowed_iterations(NEWTON_MAX_ITER);
    runge_kutta.set_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();
        Hermes::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> ogProjection; ogProjection.project_global(Hermes::vector<SpaceSharedPtr<double> >(E_space, H_space,
          P_space), Hermes::vector<MeshFunctionSharedPtr<double> >(E_time_new, H_time_new, P_time_new), Hermes::vector<MeshFunctionSharedPtr<double> >(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(Hermes::vector<SpaceSharedPtr<double> >(E_space, H_space, P_space));
        errorCalculator.calculate_errors(Hermes::vector<MeshFunctionSharedPtr<double> >(E_time_new_coarse, H_time_new_coarse, P_time_new_coarse),
          Hermes::vector<MeshFunctionSharedPtr<double> >(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(Hermes::vector<RefinementSelectors::Selector<double> *>(&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;
}
예제 #12
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;
}
예제 #13
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  if (ALIGN_MESH) 
    mloader.load("oven_load_circle.mesh", &mesh);
  else 
    mloader.load("oven_load_square.mesh", &mesh);

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

  // Initialize boundary conditions
  DefaultEssentialBCConst<std::complex<double> > bc_essential(BDY_PERFECT_CONDUCTOR, std::complex<double>(0.0, 0.0));

  EssentialBCs<std::complex<double> > bcs(&bc_essential);

  // Create an Hcurl space with default shapeset.
  HcurlSpace<std::complex<double> > space(&mesh, &bcs, P_INIT);
  int ndof = space.get_num_dofs();
  Hermes::Mixins::Loggable::Static::info("ndof = %d", ndof);

  // Initialize the weak formulation.
  CustomWeakForm wf(e_0, mu_0, mu_r, kappa, omega, J, ALIGN_MESH, &mesh, BDY_CURRENT);

  // Initialize coarse and reference mesh solution.
  Solution<std::complex<double> > sln, ref_sln;

  // Initialize refinements selector.
  HcurlProjBasedSelector<std::complex<double> > selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER);

  // Initialize views.
  ScalarView eview("Electric field", new WinGeom(0, 0, 580, 400));
  OrderView  oview("Polynomial orders", new WinGeom(590, 0, 550, 400));
  
  // 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);
    Mesh* ref_mesh = refMeshCreator.create_ref_mesh();

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

    // Initialize reference problem.
    Hermes::Mixins::Loggable::Static::info("Solving on reference mesh.");
    DiscreteProblem<std::complex<double> > dp(&wf, ref_space);

    // Time measurement.
    cpu_time.tick();

    // Perform Newton's iteration.
    Hermes::Hermes2D::NewtonSolver<std::complex<double> > newton(&dp);
    try
    {
      newton.set_newton_max_iter(NEWTON_MAX_ITER);
      newton.set_newton_tol(NEWTON_TOL);
      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<std::complex<double> > sln.
    Hermes::Hermes2D::Solution<std::complex<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 reference solution on coarse mesh.");
    OGProjection<std::complex<double> > ogProjection; ogProjection.project_global(&space, &ref_sln, &sln); 
   
    // View the coarse mesh solution and polynomial orders.
    RealFilter real(&sln);
    MagFilter<double> magn(&real);
    ValFilter limited_magn(&magn, 0.0, 4e3);
    char title[100];
    sprintf(title, "Electric field, adaptivity step %d", as);
    eview.set_title(title);
    //eview.set_min_max_range(0.0, 4e3);
    eview.show(&limited_magn);
    sprintf(title, "Polynomial orders, adaptivity step %d", as);
    oview.set_title(title);
    oview.show(&space);

    // Calculate element errors and total error estimate.
    Hermes::Mixins::Loggable::Static::info("Calculating error estimate."); 
    Adapt<std::complex<double> >* adaptivity = new Adapt<std::complex<double> >(&space);

    // Set custom error form and calculate error estimate.
    CustomErrorForm cef(kappa);
    adaptivity->set_error_form(0, 0, &cef);
    double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100;

    // Report results.
    Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", 
      Space<std::complex<double> >::get_num_dofs(&space), 
      Space<std::complex<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<std::complex<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, THRESHOLD, STRATEGY, MESH_REGULARITY);
    }
    if (space.get_num_dofs() >= NDOF_STOP) done = true;

    delete adaptivity;
    if(!done)
    {
      delete ref_space->get_mesh();
      delete ref_space;
    }
    
    // Increase counter.
    as++;
  }
  while (done == false);
  
  Hermes::Mixins::Loggable::Static::info("Total running time: %g s", cpu_time.accumulated());

  RealFilter ref_real(&sln);
  MagFilter<double> ref_magn(&ref_real);
  ValFilter ref_limited_magn(&ref_magn, 0.0, 4e3);
  eview.set_title("Fine mesh solution - magnitude");
  eview.show(&ref_limited_magn);

  // Output solution in VTK format.
  Linearizer lin;
  bool mode_3D = true;
  lin.save_solution_vtk(&ref_limited_magn, "sln.vtk", "Magnitude of E", mode_3D);
  Hermes::Mixins::Loggable::Static::info("Solution in VTK format saved to file %s.", "sln.vtk");

  // Wait for all views to be closed.
  View::wait();
  return 0;
}
예제 #14
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh 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.
  H1Space<double> space(&mesh, &bcs, P_INIT);

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

  // Initialize refinement selector.
  H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, 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);
    Mesh* ref_mesh = ref_mesh_creator.create_ref_mesh();
    Space<double>::ReferenceSpaceCreator ref_space_creator(&space, ref_mesh);
    Space<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> ogProjection; ogProjection.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(&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.");
    Adapt<double> adaptivity(&space);
    bool solutions_for_adapt = true;
    // In the following function, the Boolean parameter "solutions_for_adapt" determines whether
    // the calculated errors are intended for use with adaptivity (this may not be the case, for example,
    // when error wrt. an exact solution is calculated). The default value is solutions_for_adapt = true,
    // The last parameter "error_flags" determine whether the total and element errors are treated as
    // absolute or relative. Its default value is error_flags = HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL.
    // In subsequent examples and benchmarks, these two parameters will be often used with
    // their default values, and thus they will not be present in the code explicitly.
    double err_est_rel = adaptivity.calc_err_est(&sln, &ref_sln, solutions_for_adapt,
                         HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 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, THRESHOLD, STRATEGY, MESH_REGULARITY);

      // Increase the counter of performed adaptivity steps.
      if (done == false)  
        as++;
    }
    if (space.get_num_dofs() >= NDOF_STOP) 
      done = true;

    // Keep the mesh from final step to allow further work with the final fine mesh solution.
    if(done == false) 
      delete ref_space->get_mesh(); 
    delete ref_space;
  }
  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;
}
예제 #15
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  mloader.load("domain.mesh", &mesh);
  
  // Perform initial uniform mesh refinement.
  for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements();

  // Set essential boundary conditions.
  DefaultEssentialBCConst<double> bc_essential(Hermes::vector<std::string>("right", "top"), 0.0);
  EssentialBCs<double> bcs(&bc_essential);
  
  // Create an H1 space with default shapeset.
  H1Space<double> space(&mesh, &bcs, P_INIT);

  // Associate element markers (corresponding to physical regions) 
  // with material properties (diffusion coefficient, absorption 
  // cross-section, external sources).
  Hermes::vector<std::string> regions("e1", "e2", "e3", "e4", "e5");
  Hermes::vector<double> D_map(D_1, D_2, D_3, D_4, D_5);
  Hermes::vector<double> Sigma_a_map(SIGMA_A_1, SIGMA_A_2, SIGMA_A_3, SIGMA_A_4, SIGMA_A_5);
  Hermes::vector<double> Sources_map(Q_EXT_1, 0.0, Q_EXT_3, 0.0, 0.0);
  
  // Initialize the weak formulation.
  WeakFormsNeutronics::Monoenergetic::Diffusion::DefaultWeakFormFixedSource<double>
    wf(regions, D_map, Sigma_a_map, Sources_map);

  // Initialize coarse and reference mesh solution.
  Solution<double> sln, ref_sln;
  
  // Initialize refinement selector.
  H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER);

  // 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);
    
    // Time measurement.
    cpu_time.tick();

    // Construct globally refined mesh and setup fine mesh space.
    Space<double>* ref_space = Space<double>::construct_refined_space(&space);
    int ndof_ref = ref_space->get_num_dofs();

    // Initialize fine mesh problem.
    Hermes::Mixins::Loggable::Static::info("Solving on fine mesh.");
    DiscreteProblem<double> dp(&wf, ref_space);
    
    NewtonSolver<double> newton(&dp);
    newton.set_verbose_output(false);

    // Perform Newton's iteration.
    try
    {
      newton.solve();
    }
    catch(Hermes::Exceptions::Exception e)
    {
      e.printMsg();
      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);
    
    // Project the fine mesh solution onto the coarse mesh.
    Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh.");
    OGProjection<double> ogProjection; ogProjection.project_global(&space, &ref_sln, &sln);

    // Time measurement.
    cpu_time.tick();

    // Visualize the solution and mesh.
    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.");
    Adapt<double> adaptivity(&space);
    bool solutions_for_adapt = true;
    double err_est_rel = adaptivity.calc_err_est(&sln, &ref_sln, solutions_for_adapt,
                         HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 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(Hermes::Mixins::TimeMeasurable::HERMES_SKIP);

    // 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, THRESHOLD, STRATEGY, MESH_REGULARITY);

      // Increase the counter of performed adaptivity steps.
      if (done == false)  
        as++;
    }
    if (space.get_num_dofs() >= NDOF_STOP) 
      done = true;

    // Keep the mesh from final step to allow further work with the final fine mesh solution.
    if(done == false)
    {
      delete ref_space->get_mesh(); 
      delete ref_space;
    }
  }
  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;
}
예제 #16
0
파일: main.cpp 프로젝트: fauzisd/hermes
int main(int argc, char* argv[])
{  
  // Load the mesh.
  Mesh mesh, basemesh;
  MeshReaderH2D mloader;
  mloader.load("domain.mesh", &basemesh);
  /*  MeshView meshview("mesh", new WinGeom(0, 0, 500, 400));
  meshview.show(&basemesh);
  View::wait();*/

  // Perform initial mesh refinements (optional).
  for (int i=0; i < INIT_REF_NUM; i++) basemesh.refine_all_elements();
  mesh.copy(&basemesh);


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

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

  // Initialize solution of lower & higher order
  Solution<double>  low_sln, ref_sln, high_sln, sln;
  PrevSolution u_prev_time;

  // Previous time level solution (initialized by the initial condition).
  CustomInitialCondition initial_condition(&mesh);  

  // Initialize the weak formulation.
  CustomWeakFormMassmatrix  massmatrix(time_step);
  CustomWeakFormConvection  convection;

  // Initialize views.
  ScalarView sview("Solution", new WinGeom(0, 500, 500, 400));
  OrderView mview("mesh", new WinGeom(0, 0, 500, 400));
  OrderView ref_mview("ref_mesh", new WinGeom(500, 0, 500, 400));
  char title[100];

  // Output solution in VTK format.
  Linearizer lin;
  Orderizer ord;
  bool mode_3D = true;

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

  //Initialize
  UMFPackMatrix<double> * mass_matrix = new UMFPackMatrix<double> ;   //M_c/tau
  UMFPackMatrix<double> * conv_matrix = new UMFPackMatrix<double> ;   //K
  double* u_L = NULL; 
  double* u_H =NULL;
  double* ref_sln_double =NULL;


  int ref_ndof, ndof; double err_est_rel_total;
  Adapt<double> adaptivity(&space, HERMES_L2_NORM);

  OGProjection<double> ogProjection;	
  Lumped_Projection lumpedProjection;	
  Low_Order lowOrder(theta);
  High_Order highOrd(theta);
  Flux_Correction fluxCorrection(theta);
  Regularity_Estimator regEst(EPS_smooth);

  DiscreteProblem<double> dp_mass(&massmatrix, &space);
  DiscreteProblem<double> dp_convection(&convection, &space); 

  // Time stepping loop:
  double current_time = 0.0; 
  int ts = 1;

  do
  { 
    Hermes::Mixins::Loggable::Static::info("Time step %d, time %3.5f", ts, current_time);
    Hermes::Hermes2D::Hermes2DApi.set_integral_param_value(Hermes::Hermes2D::numThreads,1);  


    // Periodic global derefinement. 
    if ((ts > 1 && ts % UNREF_FREQ == 0)||(space.get_num_dofs() >= NDOF_STOP)) 
    { 
      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: Exceptions::Exception("Wrong global derefinement method.");
      }      
    }

    bool done = false; int as = 1;	

    do 
    {
      Hermes::Mixins::Loggable::Static::info("Time step %i, adap_step %i", ts, as);			
      ndof = space.get_num_dofs(); 

      //Unrefinement step
      /*	if(as==1)
      {
      double* coeff_vec_smooth = new double[ndof];	
      if(ts==1)		
      ogProjection.project_global(&space,&initial_condition, coeff_vec_smooth,  HERMES_L2_NORM);	
      else		
      ogProjection.project_global(&space,&u_prev_time, coeff_vec_smooth,  HERMES_L2_NORM);										  
      Solution<double>::vector_to_solution(coeff_vec_smooth, &space, &low_sln);
      // Calculate element errors and total error estimate.
      if(ts==1)
      err_est_rel_total = adaptivity.calc_err_est(&low_sln, &initial_condition) * 100; 
      else 
      err_est_rel_total = adaptivity.calc_err_est(&low_sln, &u_prev_time) * 100;  
      adaptivity.unrefine(THRESHOLD_UNREF);		
      delete [] coeff_vec_smooth; 
      // Visualize the solution.
      if(HERMES_VISUALIZATION)
      {
      sprintf(title, "unrefined Mesh: Time %3.2f,timestep %i", current_time,ts);
      mview.set_title(title); 
      mview.show(&space);
      }
      }	*/

      ndof = space.get_num_dofs();  	    		
      double* coeff_vec_smooth = new double[ndof];
      int* smooth_elem_ref;	

      //smoothness-check for projected data		
      Hermes::Mixins::Loggable::Static::info("Projecting...");
      if(ts==1)
        ogProjection.project_global(&space,&initial_condition, coeff_vec_smooth, HERMES_L2_NORM);		
      else
        ogProjection.project_global(&space,&u_prev_time, coeff_vec_smooth, HERMES_L2_NORM);			

      Hermes::Mixins::Loggable::Static::info("Calling get_smooth_elems()...");
      smooth_elem_ref = regEst.get_smooth_elems(&space,coeff_vec_smooth);
      // Construct reference mesh and setup reference space.
      Mesh* ref_mesh = new Mesh;
      ref_mesh->copy(space.get_mesh());
      Space<double>::ReferenceSpaceCreator ref_space_creator(&space, ref_mesh, 0);
      Space<double>* ref_space = ref_space_creator.create_ref_space();

      HPAdapt * adapting = new HPAdapt(ref_space, HERMES_L2_NORM);	

      // increase p in smooth regions, h refine in non-smooth regions 
      Hermes::Mixins::Loggable::Static::info("Calling adapt_smooth()...");
      if(adapting->adapt_smooth(smooth_elem_ref, P_MAX)==false) 
        throw Exceptions::Exception("reference space couldn't be constructed");							

      delete adapting;
      delete [] coeff_vec_smooth; 	 


      ref_ndof = ref_space->get_num_dofs();

      Hermes::Mixins::Loggable::Static::info("Visualization...");
      if(HERMES_VISUALIZATION) 
      {
        sprintf(title, "Ref_Mesh: Time %3.2f,timestep %i,as=%i,", current_time,ts,as);
        ref_mview.set_title(title);
        ref_mview.show(ref_space);
      }


      dp_mass.set_space(ref_space);
      dp_convection.set_space(ref_space);
      fluxCorrection.init(ref_space);	

      double* coeff_vec = new double[ref_ndof];
      double* coeff_vec_2 = new double[ref_ndof];
      double* limited_flux = new double[ref_ndof];	


      dp_mass.assemble(mass_matrix); 										//M_c/tau
      dp_convection.assemble(conv_matrix, NULL,true);		//K

      //----------------------MassLumping  & Artificial Diffusion --------------------------------------------------------------------	
      UMFPackMatrix<double>* lumped_matrix = fluxCorrection.massLumping(mass_matrix); // M_L/tau
      UMFPackMatrix<double>* diffusion = fluxCorrection.artificialDiffusion(conv_matrix);	

      //-----------------Assembling of matrices ---------------------------------------------------------------------	
      lowOrder.assemble_Low_Order(conv_matrix,diffusion,lumped_matrix);	
      highOrd.assemble_High_Order(conv_matrix,mass_matrix);

      mass_matrix->multiply_with_Scalar(time_step);  // massmatrix = M_C
      lumped_matrix->multiply_with_Scalar(time_step);  // M_L


      //--------- Project the previous timestep solution on the FE space (FCT is applied )----------------			
      // coeff_vec : FCT -Projection, coeff_vec_2: L2 Projection (ogProjection)	
      if(ts==1)
        fluxCorrection.project_FCT(&initial_condition, coeff_vec, coeff_vec_2,mass_matrix,lumped_matrix,time_step,&ogProjection,&lumpedProjection, &regEst);	
      else		
        fluxCorrection.project_FCT(&u_prev_time, coeff_vec, coeff_vec_2,mass_matrix,lumped_matrix,time_step,&ogProjection,&lumpedProjection, &regEst);			
      //------------------------- lower order solution------------					
      u_L = lowOrder.solve_Low_Order(lumped_matrix, coeff_vec,time_step);								
      //-------------high order solution (standard galerkin) ------				
      u_H = highOrd.solve_High_Order(coeff_vec);		
      //------------------------------Assemble antidiffusive fluxes and limit these-----------------------------------	
      fluxCorrection.antidiffusiveFlux(mass_matrix,lumped_matrix,conv_matrix,diffusion,u_H, u_L,coeff_vec, limited_flux,time_step,&regEst);
      //-------------Compute final solution ---------------			
      ref_sln_double = lowOrder.explicit_Correction(limited_flux);
      Solution<double> ::vector_to_solution(ref_sln_double, ref_space, &ref_sln);	

      // Project the fine mesh solution onto the coarse mesh.
      ogProjection.project_global(&space, &ref_sln, &sln, HERMES_L2_NORM); 
      // Calculate element errors and total error estimate.
      err_est_rel_total = adaptivity.calc_err_est(&sln, &ref_sln) * 100;
      // Report results.
      Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", ndof,ref_ndof, err_est_rel_total);				
      // If err_est_rel too large, adapt the mesh.
      if((err_est_rel_total < ERR_STOP)||(as>=ADAPSTEP_MAX)) done = true;
      else
      {
        done = adaptivity.adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY);
        // Increase the counter of performed adaptivity steps.
        if(done == false)  as++;
      }
      if(space.get_num_dofs() >= NDOF_STOP)
        done = true;

      if(done) 
      {  
        u_prev_time.copy(&ref_sln);
        u_prev_time.set_own_mesh(ref_mesh); //ref_mesh can be deleted
      }

      // Visualize the solution and mesh.
      if(HERMES_VISUALIZATION)
      {
        sprintf(title, "Ref-Loesung: Time %3.2f,timestep %i,as=%i,", current_time,ts,as);
        sview.set_title(title);
        sview.show(&ref_sln);
        sprintf(title, "Mesh: Time %3.2f,timestep %i,as=%i,", current_time,ts,as);
        mview.set_title(title);
        mview.show(&space);
      }

      if((VTK_VISUALIZATION) &&((done==true)&&(ts  % VTK_FREQ == 0)))
      {
        // Output solution in VTK format.
        char filename[40];
        sprintf(filename, "solution-%i.vtk", ts );
        lin.save_solution_vtk(&u_prev_time, filename, "solution", mode_3D);  
        sprintf(filename, "ref_space_order-%i.vtk", ts);
        ord.save_orders_vtk(ref_space, filename);
        sprintf(filename, "ref_mesh-%i.vtk", ts );
        ord.save_mesh_vtk(ref_space, filename);       
      } 

      // Clean up.
      delete lumped_matrix; 
      delete diffusion;
      delete [] coeff_vec_2;
      delete [] coeff_vec; 
      delete [] limited_flux; 
      delete ref_mesh; 
      delete ref_space; 
    }
    while (done == false);

    // Update global time.
    current_time += time_step;
    // Increase time step counter
    ts++;
  }
  while (current_time < T_FINAL); 

  // Visualize the solution.
  if(VTK_VISUALIZATION) {
    lin.save_solution_vtk(&u_prev_time, "end_solution.vtk", "solution", mode_3D);
    ord.save_mesh_vtk(&space, "end_mesh");
    ord.save_orders_vtk(&space, "end_order.vtk");
  }

  delete mass_matrix;  
  delete conv_matrix;

  // Wait for the view to be closed.
  View::wait();
  return 0;
}
예제 #17
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.
  Mesh mesh, basemesh;
  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(Hermes::vector<std::string>("Left", "Right"), 0);
  EssentialBCs<double> bcs(&bc_essential);

  // Create an H1 space with default shapeset.
  H1Space<double> space(&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);
  CustomWeakFormPoisson wf(new Hermes::Hermes1DFunction<double>(-1.0), &f);

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

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

  // 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);
      Mesh* ref_mesh = refMeshCreator.create_ref_mesh();

      Space<double>::ReferenceSpaceCreator refSpaceCreator(&space, ref_mesh);
      Space<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_time_step(time_step);
        runge_kutta.set_newton_max_iter(NEWTON_MAX_ITER);
        runge_kutta.set_newton_tol(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.
      Solution<double> sln_coarse;
      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.");
      Adapt<double>* adaptivity = new Adapt<double>(&space);
      double err_est_rel_total = adaptivity->calc_err_est(&sln_coarse, &sln_time_new) * 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, THRESHOLD, STRATEGY, MESH_REGULARITY);

        if (space.get_num_dofs() >= NDOF_STOP) 
          done = true;
        else
          // Increase the counter of performed adaptivity steps.
          as++;
      }
 
      // Clean up.
      delete adaptivity;
      if(!done)
      {
        delete sln_time_new.get_mesh();
        delete ref_space;
      }
    }
    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;
}
예제 #18
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;
  }
예제 #19
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;
    }
}
예제 #20
0
int main(int argc, char* args[])
{
  // Load the mesh->
  HermesSharedPtr 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->
  L2Space<double> space(mesh, P_INIT);

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

  // Disable weighting of refinement candidates.
  selector.set_error_weights(1, 1, 1);

  Solution<double> sln;
  Solution<double> ref_sln;

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

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

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

  int as = 1; bool done = false;
  do
  {
    // Construct globally refined reference mesh
    // and setup reference space->
    Mesh::ReferenceMeshCreator ref_mesh_creator(mesh);
    Mesh* ref_mesh = ref_mesh_creator.create_ref_mesh();
    Space<double>::ReferenceSpaceCreator ref_space_creator(space, ref_mesh);
    Space<double>* ref_space = ref_space_creator.create_ref_space();

    dp.set_space(ref_space);

    // Solve the linear system. If successful, obtain the solution.
    try
    {
      linear_solver.solve();
      Solution<double>::vector_to_solution(linear_solver.get_sln_vector(), ref_space, &ref_sln);
    }
    catch(std::exception& e)
    {
      std::cout << e.what();
    }
    // Project the fine mesh solution onto the coarse mesh->
    OGProjection<double> ogProjection;
    ogProjection.project_global(space, &ref_sln, &sln, HERMES_L2_NORM);

    // Calculate element errors and total error estimate.
    Adapt<double>* adaptivity = new Adapt<double>(space);
    double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100;

    // If err_est_rel too large, adapt the mesh->
    if(err_est_rel < ERR_STOP) done = true;
    else
    {
      done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY);

      if(Space<double>::get_num_dofs(space) >= NDOF_STOP)
      {
        done = true;
        break;
      }
    }

    // Clean up.
    delete adaptivity;
    if(done == false)
      delete ref_space->get_mesh();
    delete ref_space;

    as++;
  }
  while (done == false);

  if(done)
  {
    printf("Success!\n");
    return 0;
  }
  else
  {
    printf("Failure!\n");
    return -1;
  }
}
예제 #21
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;
}
예제 #22
0
int main(int argc, char* argv[])
{
  // Initialize refinement selector.
  MySelector selector(hORpSelectionBasedOnDOFs);

  HermesCommonApi.set_integral_param_value(Hermes::showInternalWarnings, false);

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

  // Load the mesh.
  MeshSharedPtr mesh(new Mesh);
  MeshReaderH2D mloader;
  mloader.load("domain.mesh", mesh);

  // Error calculation & adaptivity.
  DefaultErrorCalculator<complex, HERMES_H1_NORM> errorCalculator(RelativeErrorToGlobalNorm, 1);
  // Stopping criterion for an adaptivity step.
  AdaptStoppingCriterionSingleElement<complex> stoppingCriterion(THRESHOLD);
  // Adaptivity processor class.
  Adapt<complex> adaptivity(&errorCalculator, &stoppingCriterion);

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

  // Initialize boundary conditions.
  DefaultEssentialBCConst<complex> bc_essential("Source", P_SOURCE);
  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<complex>::get_num_dofs(space);
  //Hermes::Mixins::Loggable::Static::info("ndof = %d", ndof);

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

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

  // Initialize views.
  ScalarView sview("Acoustic pressure", new WinGeom(600, 0, 600, 350));
  sview.show_contours(.2);
  ScalarView eview("Error", new WinGeom(600, 377, 600, 350));
  sview.show_mesh(false);
  sview.fix_scale_width(50);
  OrderView  oview("Polynomial orders", new WinGeom(1208, 0, 600, 350));
  ScalarView ref_view("Refined elements", new WinGeom(1208, 377, 600, 350));
  ref_view.show_scale(false);
  ref_view.set_min_max_range(0, 2);

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

  //Hermes::Mixins::Loggable::Static::info("Solving on reference mesh.");
  // Time measurement.
  cpu_time.tick();

  // Perform Newton's iteration.
  Hermes::Hermes2D::NewtonSolver<complex> newton(&wf, space);
  newton.set_verbose_output(false);

  // Adaptivity loop:
  int as = 1;
  adaptivity.set_space(space);
  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<complex>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh);
    SpaceSharedPtr<complex> ref_space = refSpaceCreator.create_ref_space();

    int ndof_ref = Space<complex>::get_num_dofs(ref_space);
    wf.set_verbose_output(false);
    newton.set_space(ref_space);

    // Assemble the reference problem.
    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 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.
    //Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh.");
    OGProjection<complex> ogProjection; ogProjection.project_global(space, ref_sln, sln);

    // Time measurement.
    cpu_time.tick();

    // View the coarse mesh solution and polynomial orders.
    MeshFunctionSharedPtr<double> acoustic_pressure(new RealFilter(sln));
    sview.show(acoustic_pressure);
    oview.show(space);

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

    eview.show(errorCalculator.get_errorMeshFunction());

    // Report results.
    //Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space<complex>::get_num_dofs(space), Space<complex>::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<complex>::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);
      ref_view.show(adaptivity.get_refinementInfoMeshFunction());
      cpu_time.tick();
      std::cout << "Adaptivity step: " << as << ", running CPU time: " << cpu_time.accumulated_str() << std::endl;
    }

    // Increase counter.
    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 magnitude");

  MeshFunctionSharedPtr<double>  ref_mag(new RealFilter(ref_sln));
  sview.show(ref_mag);

  // Output solution in VTK format.
  Linearizer lin(FileExport);
  bool mode_3D = true;
  lin.save_solution_vtk(ref_mag, "sln.vtk", "Acoustic pressure", mode_3D);
  //Hermes::Mixins::Loggable::Static::info("Solution in VTK format saved to file %s.", "sln.vtk");

  // Wait for all views to be closed.
  View::wait();
  return 0;
}
예제 #23
0
int main(int argc, char* argv[])
{

  // Define nonlinear thermal conductivity lambda(u) via a cubic spline.
  // Step 1: Fill the x values and use lambda_macro(u) = 1 + u^4 for the y values.
  #define lambda_macro(x) (1 + std::pow(x, 4))
  Hermes::vector<double> lambda_pts(-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0);
  Hermes::vector<double> lambda_val;
  for (unsigned int i = 0; i < lambda_pts.size(); i++) lambda_val.push_back(lambda_macro(lambda_pts[i]));
  // Step 2: Create the cubic spline (and plot it for visual control). 
  double bc_left = 0.0;
  double bc_right = 0.0;
  bool first_der_left = false;
  bool first_der_right = false;
  bool extrapolate_der_left = true;
  bool extrapolate_der_right = true;
  CubicSpline lambda(lambda_pts, lambda_val, bc_left, bc_right, first_der_left, first_der_right,
                     extrapolate_der_left, extrapolate_der_right);
  Hermes::Mixins::Loggable::Static::info("Saving cubic spline into a Pylab file spline.dat.");
  // The interval of definition of the spline will be 
  // extended by "interval_extension" on both sides.
  double interval_extension = 3.0; 
  lambda.plot("spline.dat", interval_extension);

  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  mloader.load("square.mesh", &mesh);

  // Perform initial mesh refinements.
  for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements();
  mesh.refine_towards_boundary("Bdy", INIT_BDY_REF_NUM);

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

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

  // Initialize the weak formulation
  Hermes2DFunction<double> f(-heat_src);
  WeakFormsH1::DefaultWeakFormPoisson<double> wf(HERMES_ANY, &lambda, &f);

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

  // Create a selector which will select optimal candidate.
  H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER);

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

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

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

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

  // Project the initial condition on the FE space to obtain initial
  // coefficient vector for the Newton's method.
  Hermes::Mixins::Loggable::Static::info("Projecting initial condition to obtain initial vector on the coarse mesh.");
  double* coeff_vec_coarse = new double[space.get_num_dofs()];
  InitialSolutionHeatTransfer init_sln(&mesh);
  OGProjection<double> ogProjection; ogProjection.project_global(&space, &init_sln, coeff_vec_coarse);

  // Initialize Newton solver on coarse mesh.
  Hermes::Mixins::Loggable::Static::info("Solving on coarse mesh:");
  NewtonSolver<double> newton_coarse(&dp_coarse);
  newton_coarse.set_verbose_output(Hermes::Mixins::Loggable::Static::info);

  // Perform initial Newton's iteration on coarse mesh, to obtain 
  // good initial guess for the Newton's method on the fine mesh.
  try
  {
    newton_coarse.solve(coeff_vec_coarse);
  }
  catch(std::exception& e)
  {
    std::cout << e.what();
    
  }

  // Translate the resulting coefficient vector into the Solution<double> sln.
  Solution<double>::vector_to_solution(newton_coarse.get_sln_vector(), &space, &sln);

  // Cleanup after the Newton loop on the coarse mesh.
  DiscreteProblem<double> dp(&wf, &space);
  delete [] coeff_vec_coarse;
  NewtonSolver<double> newton(&dp);
  newton.set_verbose_output(Hermes::Mixins::Loggable::Static::info);

    
  // 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.
    Space<double>* ref_space = Space<double>::construct_refined_space(&space);

    // Initialize discrete problem on the reference mesh.

    // Calculate initial coefficient vector on the reference mesh.
    double* coeff_vec = new double[ref_space->get_num_dofs()];
    if (as == 1)
    {
      // In the first step, project the coarse mesh solution.
      Hermes::Mixins::Loggable::Static::info("Projecting coarse mesh solution to obtain initial vector on new fine mesh.");
      OGProjection<double> ogProjection; ogProjection.project_global(ref_space, &sln, coeff_vec);
    }
    else
    {
      // In all other steps, project the previous fine mesh solution.
      Hermes::Mixins::Loggable::Static::info("Projecting previous fine mesh solution to obtain initial vector on new fine mesh.");
      OGProjection<double> ogProjection; ogProjection.project_global(ref_space, &ref_sln, coeff_vec);
    }

    // Initialize Newton solver on fine mesh.
    Hermes::Mixins::Loggable::Static::info("Solving on fine mesh:");
    // Perform Newton's iteration.
    newton.set_space(ref_space);
    try
    {
      newton.solve(coeff_vec);
    }
    catch(std::exception& e)
    {
      std::cout << e.what();
      
    }

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

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

    // Calculate element errors and total error estimate.
    Hermes::Mixins::Loggable::Static::info("Calculating error estimate.");
    Adapt<double>* adaptivity = new Adapt<double>(&space);
    double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 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_est.add_values(Space<double>::get_num_dofs(&space), err_est_rel);
    graph_dof_est.save("conv_dof_est.dat");
    graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel);
    graph_cpu_est.save("conv_cpu_est.dat");

    // View the coarse mesh solution.
    sview.show(&sln);
    oview.show(&space);

    // If err_est_rel 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, THRESHOLD, STRATEGY, MESH_REGULARITY);

      if (Space<double>::get_num_dofs(&space) >= NDOF_STOP)
      {
        done = true;
        break;
      }
    }

    // Clean up.
    delete [] coeff_vec;
    delete adaptivity;

    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 keyboard or mouse input.
  View::wait();
  return 0;
}
예제 #24
0
int main(int argc, char* argv[])
{
  // Time measurement.
  Hermes::Mixins::TimeMeasurable cpu_time;
  cpu_time.tick();

  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  mloader.load("square.mesh", &mesh);
  
  // Create an H1 space with default shapeset.
  H1Space<double> space(&mesh, P_INIT);

  // Initialize the weak formulation.
  WeakForm<double> wf_dummy;

  // Initialize coarse and reference mesh solution.
  Solution<double> sln;
  ExactSolutionCustom* ref_sln = NULL;

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

  // Initialize views.
  ScalarView sview("Scalar potential Phi", new WinGeom(0, 0, 610, 300));
  sview.fix_scale_width(40);
  sview.show_mesh(false);
  OrderView  oview("Mesh", new WinGeom(620, 0, 600, 300));

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

  // 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.
    Space<double>* ref_space = Space<double>::construct_refined_space(&space);

    // Assign the function f() to the fine mesh.
    Hermes::Mixins::Loggable::Static::info("Assigning f() to the fine mesh.");
    if(ref_sln != NULL) delete ref_sln;
    ref_sln = new ExactSolutionCustom(ref_space->get_mesh());

    // Time measurement.
    cpu_time.tick();
    
    // Project the fine mesh solution onto the coarse mesh.
    Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh.");
    OGProjection<double> ogProjection; ogProjection.project_global(&space, ref_sln, &sln); 
   
    // View the coarse mesh solution and polynomial orders.
    sview.show(&sln);
    oview.show(&space);

    // Calculate element errors and total error estimate.
    Hermes::Mixins::Loggable::Static::info("Calculating exact error."); 
    Adapt<double>* adaptivity = new Adapt<double>(&space);
    // Note: the error estimate is now equal to the exact error.
    double err_exact_rel = adaptivity->calc_err_est(&sln, ref_sln) * 100;

    // Report results.
    Hermes::Mixins::Loggable::Static::info("ndof_coarse: %d, ndof_fine: %d, err_exact_rel: %g%%", 
      Space<double>::get_num_dofs(&space), Space<double>::get_num_dofs(ref_space), err_exact_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_exact_rel);
    graph_dof.save("conv_dof.dat");
    graph_cpu.add_values(cpu_time.accumulated(), err_exact_rel);
    graph_cpu.save("conv_cpu.dat");

    // If err_exact_rel too large, adapt the mesh.
    if (err_exact_rel < ERR_STOP) done = true;
    else 
    {
      Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh.");
      done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY);
      
      // Increase the counter of performed adaptivity steps.
      if (done == false)  as++;
    }
    if (Space<double>::get_num_dofs(&space) >= NDOF_STOP) done = true;

    // Clean up.
    delete adaptivity;
    if (done == false)
      delete ref_space->get_mesh();
    delete ref_space;
  }
  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(ref_sln);

  // Wait for all views to be closed.
  View::wait();
  return 0;
}
예제 #25
0
파일: main.cpp 프로젝트: LeiDai/hermes
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;
}
예제 #26
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  mloader.load("square.mesh", &mesh);

  // Perform initial mesh refinements.
  for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements();
  mesh.refine_towards_boundary("Bdy", INIT_BDY_REF_NUM);

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

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

  // Initialize the weak formulation
  CustomNonlinearity lambda(alpha);
  Hermes2DFunction<double> src(-heat_src);
  DefaultWeakFormPoisson<double> wf(HERMES_ANY, &lambda, &src);

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

  // 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];
  CustomInitialCondition init_sln(&mesh);
  OGProjection<double> ogProjection; ogProjection.project_global(&space, &init_sln, coeff_vec); 

  // Initialize Newton solver.
  NewtonSolver<double> newton(&dp);

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

  // Translate the resulting coefficient vector into a Solution.
  Solution<double> sln;
  Solution<double>::vector_to_solution(newton.get_sln_vector(), &space, &sln);

  // Get info about time spent during assembling in its respective parts.
  //dp.get_all_profiling_output(std::cout);

  // Clean up.
  delete [] coeff_vec;

  // Visualise the solution and mesh.
  ScalarView s_view("Solution", new WinGeom(0, 0, 440, 350));
  s_view.show_mesh(false);
  s_view.show(&sln);
  OrderView o_view("Mesh", new WinGeom(450, 0, 400, 350));
  o_view.show(&space);

  // Wait for all views to be closed.
  View::wait();
  return 0;
}
예제 #27
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  mloader.load("square.mesh", &mesh);

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

  // Define exact solution.
  CustomExactSolution exact_sln(&mesh, K);

  // Define right side vector.
  CustomFunction f(K);

  // Initialize the weak formulation.
  CustomWeakForm wf(&f);
  
  // Initialize boundary conditions.
  DefaultEssentialBCConst<double> bc_essential("Bdy", 0.0);
  EssentialBCs<double> bcs(&bc_essential);

  // Create an H1 space with default shapeset.
  H1Space<double> space(&mesh, &bcs, P_INIT);
  
  // Initialize approximate solution.
  Solution<double> sln;

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

  // Initialize views.
  Views::ScalarView sview("Solution", new Views::WinGeom(0, 0, 440, 350));
  sview.show_mesh(false);
  Views::OrderView oview("Polynomial orders", new Views::WinGeom(450, 0, 400, 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);
    Mesh* ref_mesh = refMeshCreator.create_ref_mesh();

    Space<double>::ReferenceSpaceCreator refSpaceCreator(&space, ref_mesh);
    Space<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);
    
    Solution<double> ref_sln;
    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.
    Adapt<double> adaptivity(&space);
    double err_est_rel = adaptivity.calc_err_est(&sln, &ref_sln) * 100;

    // Calculate exact error.
    double err_exact_rel = Global<double>::calc_rel_error(&sln, &exact_sln, HERMES_H1_NORM) * 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 || space.get_num_dofs() >= NDOF_STOP) 
      done = true;
    else
      done = adaptivity.adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY);
   
    cpu_time.tick();
    Hermes::Mixins::Loggable::Static::info("Adaptation: %g s", cpu_time.last());
    
    // Increase the counter of adaptivity steps.
    if (done == false) as++;
  
    if(done == false) 
      delete ref_space->get_mesh();
    delete ref_space;
  }
  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();
  return 0;
}
예제 #28
0
int main(int argc, char* argv[])
{
  // Define problem parameters: (x_loc, y_loc) is the center of the circular wave front, R_ZERO is the distance from the 
  // wave front to the center of the circle, and alpha gives the steepness of the wave front.
  double alpha, x_loc, y_loc, r_zero;
  switch(PARAM) 
  {
  case 0:
    alpha = 20;
    x_loc = -0.05;
    y_loc = -0.05;
    r_zero = 0.7;
    break;
  case 1:
    alpha = 1000;
    x_loc = -0.05;
    y_loc = -0.05;
    r_zero = 0.7;
    break;
  case 2:
    alpha = 1000;
    x_loc = 1.5;
    y_loc = 0.25;
    r_zero = 0.92;
    break;
  case 3:
    alpha = 50;
    x_loc = 0.5;
    y_loc = 0.5;
    r_zero = 0.25;
    break;
  default:   
    // The same as 0.
    alpha = 20;
    x_loc = -0.05;
    y_loc = -0.05;
    r_zero = 0.7;
    break;
  }

  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  // Quadrilaterals.
  mloader.load("square_quad.mesh", &mesh);     
  // Triangles.
  // mloader.load("square_tri.mesh", &mesh);   

  // Perform initial mesh refinement.
  for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements();
  
  // Set exact solution.
  CustomExactSolution exact_sln(&mesh, alpha, x_loc, y_loc, r_zero);

  // Define right-hand side.
  CustomRightHandSide rhs(alpha, x_loc, y_loc, r_zero);

  // Initialize the weak formulation.
  CustomWeakForm wf(&rhs);
  // Equivalent, but slower:
  // WeakFormsH1::DefaultWeakFormPoisson wf(HERMES_ANY, HERMES_ONE, &rhs);

  // Initialize boundary conditions.
  DefaultEssentialBCNonConst<double> bc("Bdy", &exact_sln);
  EssentialBCs<double> bcs(&bc);
  
  // Create an H1 space with default shapeset.
  H1Space<double> space(&mesh, &bcs, P_INIT);
   
  // Initialize approximate solution.
  Solution<double> sln;
 
  // Initialize refinement selector.
  H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER);
  
  // 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;
  
  // Adaptivity loop:
  int as = 1; bool done = false;
  do
  {
    cpu_time.tick();

    // Construct globally refined reference mesh and setup reference space.
    Space<double>* ref_space = Space<double>::construct_refined_space(&space, 1);
    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);
    
    Solution<double> ref_sln;
    try
    {
      newton.solve();
    }
    catch(Hermes::Exceptions::Exception e)
    {
      e.printMsg();
      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.
    Adapt<double> adaptivity(&space);
    double err_est_rel = adaptivity.calc_err_est(&sln, &ref_sln) * 100;

    // Calculate exact error.
    double err_exact_rel = Global<double>::calc_rel_error(&sln, &exact_sln, HERMES_H1_NORM) * 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 || space.get_num_dofs() >= NDOF_STOP) 
      done = true;
    else
      done = adaptivity.adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY);
   
    cpu_time.tick();
    Hermes::Mixins::Loggable::Static::info("Adaptation: %g s", cpu_time.last());
    
    // Increase the counter of adaptivity steps.
    if (done == false)  
      as++;
    
    delete ref_space->get_mesh();
    delete ref_space;
  }
  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();
  return 0;
}
예제 #29
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();
}
예제 #30
0
int main(int argc, char* argv[])
{
  // Time measurement.
  Hermes::Mixins::TimeMeasurable cpu_time;
  cpu_time.tick();

  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  mloader.load("square.mesh", &mesh);

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

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

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

  Hermes::Mixins::Loggable::Static::info("Assembling by DiscreteProblem, solving by Umfpack:");

  // Time measurement.
  cpu_time.tick();

  // Initialize weak formulation,
  CustomWeakForm wf1;

  // Initialize the discrete problem.
  DiscreteProblem<double> dp1(&wf1, &space);

  // Initialize the Newton solver.
  Hermes::Hermes2D::NewtonSolver<double> newton(&dp1);

  // Perform Newton's iteration and translate the resulting coefficient vector into a Solution.
  Hermes::Hermes2D::Solution<double> sln1;
  try
  {
    newton.solve();
  }
  catch(std::exception& e)
  {
    std::cout << e.what();
    
  }

  // Translate the solution vector into a Solution.
  Hermes::Hermes2D::Solution<double>::vector_to_solution(newton.get_sln_vector(), &space, &sln1);

  // CPU time needed by UMFpack
  double time1 = cpu_time.tick().last();

  // Time measurement.
  cpu_time.tick();
 
  // Show UMFPACK solution.
  ScalarView view1("Solution 1", new WinGeom(0, 0, 500, 400));
  view1.show(&sln1);

  // Calculate error.
  CustomExactSolution ex(&mesh);
  double rel_err_1 = Global<double>::calc_rel_error(&sln1, &ex, HERMES_H1_NORM) * 100;
  Hermes::Mixins::Loggable::Static::info("Solution 1 :  exact H1 error: %g%% (time %g s)", rel_err_1, time1);

  // TRILINOS PART:

  // Project the initial condition to obtain the initial
  // coefficient vector.
  Hermes::Mixins::Loggable::Static::info("Projecting to obtain initial vector for the Newton's method.");
  double* coeff_vec = new double[ndof];
  ZeroSolution<double> sln_tmp(&mesh);
  OGProjection<double> ogProjection; ogProjection.project_global(&space, &sln_tmp, coeff_vec);

  // Measure the projection time.
  double proj_time = cpu_time.tick().last();

  // Initialize the weak formulation for Trilinos.
  CustomWeakForm wf2(TRILINOS_JFNK, PRECOND == 1, PRECOND == 2);

  // Initialize DiscreteProblem.
  DiscreteProblem<double> dp2(&wf2, &space);

  // Initialize the NOX solver with the vector "coeff_vec".
  Hermes::Mixins::Loggable::Static::info("Initializing NOX.");
  NewtonSolverNOX<double> solver_nox(&dp2);
  solver_nox.set_output_flags(message_type);

  solver_nox.set_ls_tolerance(ls_tolerance);

  solver_nox.set_conv_iters(max_iters);
  if (flag_absresid)
    solver_nox.set_conv_abs_resid(abs_resid);
  if (flag_relresid)
    solver_nox.set_conv_rel_resid(rel_resid);

  // Choose preconditioning.
  MlPrecond<double> pc("sa");
  if (PRECOND)
  {
    if (TRILINOS_JFNK) solver_nox.set_precond(pc);
    else solver_nox.set_precond("ML");
  }

  // Solve the nonlinear problem using NOX.
  Hermes::Mixins::Loggable::Static::info("Assembling by DiscreteProblem, solving by NOX.");
  Solution<double> sln2;
  try
  {
    solver_nox.solve(coeff_vec);
  }
  catch(std::exception& e)
  {
    std::cout << e.what();
    
  }

  Solution<double>::vector_to_solution(solver_nox.get_sln_vector(), &space, &sln2);
  Hermes::Mixins::Loggable::Static::info("Number of nonlin iterations: %d (norm of residual: %g)", 
        solver_nox.get_num_iters(), solver_nox.get_residual());
  Hermes::Mixins::Loggable::Static::info("Total number of iterations in linsolver: %d (achieved tolerance in the last step: %g)", 
        solver_nox.get_num_lin_iters(), solver_nox.get_achieved_tol());

  // CPU time needed by NOX.
  double time2 = cpu_time.tick().last();

  // Calculate error.
  double rel_err_2 = Global<double>::calc_rel_error(&sln2, &ex, HERMES_H1_NORM) * 100;
  Hermes::Mixins::Loggable::Static::info("Solution 2 (NOX): exact H1 error: %g%% (time %g + %g = %g [s])", rel_err_2, proj_time, time2, proj_time+time2);

  // Show NOX solution.
  ScalarView view2("Solution 2", new WinGeom(510, 0, 500, 400));
  view2.show(&sln2);

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