Esempio n. 1
0
int main(int argc, char* argv[])
{
    // Choose a Butcher's table or define your own.
    ButcherTable bt(butcher_table_type);
    if (bt.is_explicit()) info("Using a %d-stage explicit R-K method.", bt.get_size());
    if (bt.is_diagonally_implicit()) info("Using a %d-stage diagonally implicit R-K method.", bt.get_size());
    if (bt.is_fully_implicit()) info("Using a %d-stage fully implicit R-K method.", bt.get_size());

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

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

    // Initialize solutions.
    CustomInitialConditionWave E_sln(&mesh);
    ZeroSolutionVector F_sln(&mesh);
    Hermes::vector<Solution<double>*> slns(&E_sln, &F_sln);

    // Initialize the weak formulation.
    CustomWeakFormWave wf(C_SQUARED);

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

    // Create x- and y- displacement space using the default H1 shapeset.
    HcurlSpace<double> E_space(&mesh, &bcs, P_INIT);
    HcurlSpace<double> F_space(&mesh, &bcs, P_INIT);
    Hermes::vector<Space<double> *> spaces = Hermes::vector<Space<double> *>(&E_space, &F_space);
    info("ndof = %d.", Space<double>::get_num_dofs(spaces));

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

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

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

    // Time stepping loop.
    double current_time = 0;
    int ts = 1;
    do
    {
        // Perform one Runge-Kutta time step according to the selected Butcher's table.
        info("Runge-Kutta time step (t = %g s, time_step = %g s, stages: %d).",
             current_time, time_step, bt.get_size());
        bool verbose = true;
        bool jacobian_changed = true;

        try
        {
            runge_kutta.rk_time_step_newton(current_time, time_step, slns, slns, jacobian_changed, verbose);
        }
        catch(Exceptions::Exception& e)
        {
            e.printMsg();
            error("Runge-Kutta time step failed");
        }

        // Visualize the solutions.
        char title[100];
        sprintf(title, "E1, t = %g", current_time);
        E1_view.set_title(title);
        E1_view.show(&E_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_0);
        sprintf(title, "E2, t = %g", current_time);
        E2_view.set_title(title);
        E2_view.show(&E_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_1);

        // Update time.
        current_time += time_step;

    } while (current_time < T_FINAL);

    // Wait for the view to be closed.
    View::wait();

    return 0;
}
Esempio n. 2
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  mloader.load("domain.mesh", &mesh);

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

  // Initialize solutions.
  CustomInitialConditionWave E_sln(&mesh);
  ZeroSolutionVector F_sln(&mesh);
  Hermes::vector<Solution<double>*> slns(&E_sln, &F_sln);

  // Initialize the weak formulation.
  CustomWeakFormWave wf(time_step, C_SQUARED, &E_sln, &F_sln);
  
  // Initialize boundary conditions
  DefaultEssentialBCConst<double> bc_essential("Perfect conductor", 0.0);
  EssentialBCs<double> bcs(&bc_essential);

  // Create x- and y- displacement space using the default H1 shapeset.
  HcurlSpace<double> E_space(&mesh, &bcs, P_INIT);
  HcurlSpace<double> F_space(&mesh, &bcs, P_INIT);
  Hermes::vector<Space<double> *> spaces = Hermes::vector<Space<double> *>(&E_space, &F_space);

  info("ndof = %d.", Space<double>::get_num_dofs(spaces));

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

  // Set up the solver, matrix, and rhs according to the solver selection.
  SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type);
  Vector<double>* rhs = create_vector<double>(matrix_solver_type);
  LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs);
  solver->set_factorization_scheme(HERMES_REUSE_FACTORIZATION_COMPLETELY);

  // Initialize views.
  ScalarView E1_view("Solution E1", new WinGeom(0, 0, 400, 350));
  E1_view.fix_scale_width(50);
  ScalarView E2_view("Solution E2", new WinGeom(410, 0, 400, 350));
  E2_view.fix_scale_width(50);

  // Time stepping loop.
  double current_time = 0; int ts = 1;
  do
  {
    // Perform one implicit Euler time step.
    info("Implicit Euler time step (t = %g s, time_step = %g s).", current_time, time_step);

    // First time assemble both the stiffness matrix and right-hand side vector,
    // then just the right-hand side vector.
    if (ts == 1) {
      info("Assembling the stiffness matrix and right-hand side vector.");
      dp.assemble(matrix, rhs);
      static char file_name[1024];
      sprintf(file_name, "matrix.m");
      FILE *f = fopen(file_name, "w");
      matrix->dump(f, "A");
      fclose(f);
    }
    else {
      info("Assembling the right-hand side vector (only).");
      dp.assemble(rhs);
    }

    // Solve the linear system and if successful, obtain the solution.
    info("Solving the matrix problem.");
    if(solver->solve()) Solution<double>::vector_to_solutions(solver->get_sln_vector(), spaces, slns);
    else error ("Matrix solver failed.\n");

    // Visualize the solutions.
    char title[100];
    sprintf(title, "E1, t = %g", current_time);
    E1_view.set_title(title);
    E1_view.show(&E_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_0);
    sprintf(title, "E2, t = %g", current_time);
    E2_view.set_title(title);
    E2_view.show(&E_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_1);

    // Update time.
    current_time += time_step;
  } while (current_time < T_FINAL);

  // Wait for the view to be closed.
  View::wait();

  return 0;
}
Esempio n. 3
0
int main(int argc, char* argv[])
{
  // Choose a Butcher's table or define your own.
  ButcherTable bt(butcher_table_type);
  if (bt.is_explicit()) info("Using a %d-stage explicit R-K method.", bt.get_size());
  if (bt.is_diagonally_implicit()) info("Using a %d-stage diagonally implicit R-K method.", bt.get_size());
  if (bt.is_fully_implicit()) info("Using a %d-stage fully implicit R-K method.", bt.get_size());

  // Load the mesh.
  Mesh mesh;
  H2DReader mloader;
  mloader.load("../domain.mesh", &mesh);

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

  // Initialize solutions.
  CustomInitialConditionWave E_sln(&mesh);
  Solution F_sln(&mesh, 0.0, 0.0);
  Hermes::vector<Solution*> slns(&E_sln, &F_sln);

  // Initialize the weak formulation.
  CustomWeakFormWave wf(C_SQUARED);
  
  // Initialize boundary conditions
  DefaultEssentialBCConst bc_essential(BDY, 0.0);
  EssentialBCs bcs(&bc_essential);

  // Create x- and y- displacement space using the default H1 shapeset.
  HcurlSpace E_space(&mesh, &bcs, P_INIT);
  HcurlSpace F_space(&mesh, &bcs, P_INIT);
  Hermes::vector<Space *> spaces = Hermes::vector<Space *>(&E_space, &F_space);
  info("ndof = %d.", Space::get_num_dofs(spaces));

  // Initialize the FE problem.
  DiscreteProblem dp(&wf, spaces);

  // Initialize Runge-Kutta time stepping.
  RungeKutta runge_kutta(&dp, &bt, matrix_solver);

  // Time stepping loop.
  double current_time = 0; int ts = 1;
  do
  {
    // Perform one Runge-Kutta time step according to the selected Butcher's table.
    info("Runge-Kutta time step (t = %g s, time_step = %g s, stages: %d).", 
         current_time, time_step, bt.get_size());
    bool verbose = true;
    bool jacobian_changed = true;
    if (!runge_kutta.rk_time_step(current_time, time_step, slns, slns, jacobian_changed, verbose))
      error("Runge-Kutta time step failed, try to decrease time step size.");

    // Update time.
    current_time += time_step;
  
  } while (current_time < T_FINAL);

  double coord_x[4] = {0.3, 0.6, 0.9, 1.4};
  double coord_y[4] = {0, 0.3, 0.5, 0.7};

  info("Coordinate (0.3, 0.0) value = %lf", F_sln.get_pt_value(coord_x[0], coord_y[0]));
  info("Coordinate (0.6, 0.3) value = %lf", F_sln.get_pt_value(coord_x[1], coord_y[1]));
  info("Coordinate (0.9, 0.5) value = %lf", F_sln.get_pt_value(coord_x[2], coord_y[2]));
  info("Coordinate (1.4, 0.7) value = %lf", F_sln.get_pt_value(coord_x[3], coord_y[3]));

  double t_value[4] = {-0.144673, -0.264077, -0.336536, -0.368983};
  bool success = true;

  for (int i = 0; i < 4; i++)
  {
    if (fabs(t_value[i] - F_sln.get_pt_value(coord_x[i], coord_y[i])) > 1E-6) success = false;
  }

  if (success) {
    printf("Success!\n");
    return ERR_SUCCESS;
  }
  else {
    printf("Failure!\n");
    return ERR_FAILURE;
  }
}
Esempio n. 4
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;
}