Beispiel #1
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  H2DReader mloader;
  mloader.load("square.mesh", &mesh);

  // Initial mesh refinements.
  for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements();
  mesh.refine_towards_boundary(BDY_DIRICHLET, INIT_BDY_REF_NUM);

  // Enter boundary markers.
  BCTypes bc_types;
  bc_types.add_bc_dirichlet(BDY_DIRICHLET);

  // Enter Dirichlet boundary values.
  BCValues bc_values;
  bc_values.add_function(BDY_DIRICHLET, essential_bc_values);

  // Create an H1 space with default shapeset.
  H1Space space(&mesh, &bc_types, &bc_values, P_INIT);
  int ndof = Space::get_num_dofs(&space);
  info("ndof = %d.", ndof);

  // Solution for the previous time level.
  Solution u_prev_time;

  // Initialize the weak formulation.
  WeakForm wf;
  if (TIME_INTEGRATION == 1) {
    wf.add_matrix_form(jac_euler, jac_ord, HERMES_NONSYM, HERMES_ANY, &u_prev_time);
    wf.add_vector_form(res_euler, res_ord, HERMES_ANY, &u_prev_time);
  }
  else {
    wf.add_matrix_form(jac_cranic, jac_ord, HERMES_NONSYM, HERMES_ANY, &u_prev_time);
    wf.add_vector_form(res_cranic, res_ord, HERMES_ANY, &u_prev_time);
  }

  // Project the function init_cond() on the FE space
  // to obtain initial coefficient vector for the Newton's method.
  scalar* coeff_vec = new scalar[Space::get_num_dofs(&space)];
  info("Projecting initial condition to obtain initial vector for the Newton's method.");
  OGProjection::project_global(&space, init_cond, coeff_vec, matrix_solver);
  Solution::vector_to_solution(coeff_vec, &space, &u_prev_time);
  
  // Time stepping loop:
  double current_time = 0.0;
  int t_step = 1;
  do {
    info("---- Time step %d, t = %g s.", t_step, current_time); t_step++;

    // Initialize the FE problem.
    bool is_linear = false;
    DiscreteProblem dp(&wf, &space, is_linear);

    // Set up the solver, matrix, and rhs according to the solver selection.
    SparseMatrix* matrix = create_matrix(matrix_solver);
    Vector* rhs = create_vector(matrix_solver);
    Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);

    // Perform Newton's iteration.
    bool verbose = true;
    if (!solve_newton(coeff_vec, &dp, solver, matrix, rhs, 
        NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); 

    // Translate the resulting coefficient vector into the Solution sln.
    Solution::vector_to_solution(coeff_vec, &space, &u_prev_time);

    // Cleanup.
    delete matrix;
    delete rhs;
    delete solver;

    // Update time.
    current_time += TAU;

  } while (current_time < T_FINAL);
  
  delete [] coeff_vec;

  info("Coordinate (  0,   0) value = %lf", u_prev_time.get_pt_value(0.0, 0.0));
  info("Coordinate ( 25,  25) value = %lf", u_prev_time.get_pt_value(25.0, 25.0));
  info("Coordinate ( 50,  50) value = %lf", u_prev_time.get_pt_value(50.0, 50.0));
  info("Coordinate ( 75,  75) value = %lf", u_prev_time.get_pt_value(75.0, 75.0));
  info("Coordinate (100, 100) value = %lf", u_prev_time.get_pt_value(100.0, 100.0));

  double coor_x_y[5] = {0.0, 25.0, 50.0, 75.0, 100.0};
  double value[5] = {-1000.000000, -969.316013, -836.504249, -651.433710, -1000.000000};
  bool success = true;
  for (int i = 0; i < 5; i++)
  {
    if (abs(value[i] - u_prev_time.get_pt_value(coor_x_y[i], coor_x_y[i])) > 1E-6) 
      success = false;
  }

  if (success) {
    printf("Success!\n");
    return ERR_SUCCESS;
  }
  else {
    printf("Failure!\n");
    return ERR_FAILURE;
  }
}
Beispiel #2
0
int main (int argc, char* argv[]) {
  
  // Load the mesh. 
  Mesh basemesh;
  ExodusIIReader mesh_loader;
  if (!mesh_loader.load("coarse_mesh_full.e", &basemesh))
    error("Loading mesh file '%s' failed.\n", "coarse_mesh_full.e");

  Mesh C_mesh, phi_mesh;
  C_mesh.copy(basemesh);

  phi_mesh.copy(basemesh);

  H1Space C_space(&C_mesh, bc_types_C, essential_bc_values_C, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z));
  H1Space phi_space(MULTIMESH ? &phi_mesh : &C_mesh, bc_types_phi, essential_bc_values_phi, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z));

  Solution C_prev_time(&C_mesh);
  C_prev_time.set_const(C0);
  Solution phi_prev_time(MULTIMESH ? &phi_mesh : &C_mesh);
  phi_prev_time.set_const(0.0);


  WeakForm wf(2);
  // Add the bilinear and linear forms.
  if (TIME_DISCR == 1) {  // Implicit Euler.
  wf.add_matrix_form(0, 0, callback(J_euler_DFcDYc), HERMES_NONSYM);
  wf.add_matrix_form(0, 1, callback(J_euler_DFcDYphi), HERMES_NONSYM);
  wf.add_matrix_form(1, 0, callback(J_euler_DFphiDYc), HERMES_NONSYM);
  wf.add_matrix_form(1, 1, callback(J_euler_DFphiDYphi), HERMES_NONSYM);
  wf.add_vector_form(0, callback(Fc_euler), HERMES_ANY_INT,
                     Hermes::vector<MeshFunction*>(&C_prev_time, &phi_prev_time));
  wf.add_vector_form(1, callback(Fphi_euler), HERMES_ANY,
                     Hermes::vector<MeshFunction*>(&C_prev_time, &phi_prev_time));
  } else {
    wf.add_matrix_form(0, 0, callback(J_cranic_DFcDYc), HERMES_NONSYM);
    wf.add_matrix_form(0, 1, callback(J_cranic_DFcDYphi), HERMES_NONSYM);
    wf.add_matrix_form(1, 0, callback(J_cranic_DFphiDYc), HERMES_NONSYM);
    wf.add_matrix_form(1, 1, callback(J_cranic_DFphiDYphi), HERMES_NONSYM);
    wf.add_vector_form(0, callback(Fc_cranic), HERMES_ANY,
                       Hermes::vector<MeshFunction*>(&C_prev_time, &phi_prev_time));
    wf.add_vector_form(1, callback(Fphi_cranic), HERMES_ANY);
  }

  int ndof = Space::get_num_dofs(Hermes::vector<Space*>(&C_space, &phi_space));

  Solution C_sln(C_space.get_mesh());
  Solution phi_sln(phi_space.get_mesh());

  info("Projecting initial condition to obtain initial vector for the Newton's method.");
  scalar* coeff_vec_coarse = new scalar[ndof];
  OGProjection::project_global(Hermes::vector<Space *>(&C_space, &phi_space),
                               Hermes::vector<MeshFunction *>(&C_prev_time, &phi_prev_time),
                               coeff_vec_coarse, matrix_solver);



  bool is_linear = false;
  DiscreteProblem dp_coarse(&wf, Hermes::vector<Space *>(&C_space, &phi_space), is_linear);

  //Solution::vector_to_solutions(coeff_vec_coarse, dp_coarse.get_spaces(), Hermes::vector<Solution *>(&C_sln, &phi_sln), NULL);


  // Set up the solver, matrix, and rhs for the coarse mesh according to the solver selection.
  SparseMatrix* matrix_coarse = create_matrix(matrix_solver);
  Vector* rhs_coarse = create_vector(matrix_solver);
  Solver* solver_coarse = create_linear_solver(matrix_solver, matrix_coarse, rhs_coarse);

  info("Solving on coarse mesh:");
  bool verbose = true;
  if (!solve_newton(coeff_vec_coarse, &dp_coarse, solver_coarse, matrix_coarse, rhs_coarse,
      NEWTON_TOL_COARSE, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed.");

  info("Solved!");
  // Translate the resulting coefficient vector into the Solution sln.
  Solution::vector_to_solutions(coeff_vec_coarse, Hermes::vector<Space *>(&C_space, &phi_space),
                                Hermes::vector<Solution *>(&C_sln, &phi_sln));

  out_fn_vtk(&C_sln,"C_init_sln");
  out_fn_vtk(&phi_sln,"phi_init_sln");
  //out_fn_vtk(&sln, "sln", ts);

  Solution *C_ref_sln, *phi_ref_sln;

  PidTimestepController pid(T_FINAL, false, INIT_TAU);
  TAU = pid.timestep;
  info("Starting time iteration with the step %g", *TAU);
  do {
    pid.begin_step();

    if (pid.get_timestep_number() > 1 && pid.get_timestep_number() % UNREF_FREQ == 0)
    {
      info("Global mesh derefinement.");
      C_mesh.copy(basemesh);
      if (MULTIMESH)
      {
        phi_mesh.copy(basemesh);
      }
      C_space.set_uniform_order(Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z));
      phi_space.set_uniform_order(Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z));


      }
      bool done = false; int as = 1;
      double err_est;
      do {
        info("Time step %d, adaptivity step %d:", pid.get_timestep_number(), as);

        // Construct globally refined reference mesh
        // and setup reference space.
        int order_increase = 1;
        Hermes::vector<Space *>* ref_spaces = construct_refined_spaces(Hermes::vector<Space *>(&C_space, &phi_space), 
                                                                       order_increase);
        scalar* coeff_vec = new scalar[Space::get_num_dofs(*ref_spaces)];
        DiscreteProblem* dp = new DiscreteProblem(&wf, *ref_spaces, is_linear);
        SparseMatrix* matrix = create_matrix(matrix_solver);
        Vector* rhs = create_vector(matrix_solver);
        Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);


        if (as == 1 && pid.get_timestep_number() == 1) {
          info("Projecting coarse mesh solution to obtain coefficient vector on new fine mesh.");
          OGProjection::project_global(*ref_spaces, Hermes::vector<MeshFunction *>(&C_sln, &phi_sln),
                                       coeff_vec, matrix_solver);
        }
        else {
          info("Projecting previous fine mesh solution to obtain coefficient vector on new fine mesh.");
          OGProjection::project_global(*ref_spaces, Hermes::vector<MeshFunction *>(C_ref_sln, phi_ref_sln),
                                       coeff_vec, matrix_solver);
        }
        if (as > 1) {
          // Now deallocate the previous mesh
          info("Deallocating the previous mesh");
          //delete C_ref_sln->get_mesh();
          //delete phi_ref_sln->get_mesh();
          //delete C_ref_sln;
          //delete phi_ref_sln;
        }
        /*TODO TEMP */
        if (pid.get_timestep_number() > 1) {

        delete C_ref_sln;
        delete phi_ref_sln;
        }

        info("Solving on fine mesh:");
        if (!solve_newton(coeff_vec, dp, solver, matrix, rhs,
              NEWTON_TOL_FINE, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed.");


        // Store the result in ref_sln.
        C_ref_sln = new Solution(ref_spaces->at(0)->get_mesh());
        phi_ref_sln = new Solution(ref_spaces->at(1)->get_mesh());

        Solution::vector_to_solutions(coeff_vec, *ref_spaces,
                                      Hermes::vector<Solution *>(C_ref_sln, phi_ref_sln));
        // Projecting reference solution onto the coarse mesh
        info("Projecting fine mesh solution on coarse mesh.");
        OGProjection::project_global(Hermes::vector<Space *>(&C_space, &phi_space),
                                     Hermes::vector<Solution *>(C_ref_sln, phi_ref_sln),
                                     Hermes::vector<Solution *>(&C_sln, &phi_sln),
                                     matrix_solver);


        info("Calculating error estimate.");
        Adapt* adaptivity = new Adapt(Hermes::vector<Space *>(&C_space, &phi_space),
            Hermes::vector<ProjNormType> (HERMES_H1_NORM, HERMES_H1_NORM));
        Hermes::vector<double> err_est_rel;
        bool solutions_for_adapt = true;

        double err_est_rel_total = adaptivity->calc_err_est(Hermes::vector<Solution *>(&C_sln, &phi_sln),
            Hermes::vector<Solution *>(C_ref_sln, phi_ref_sln), solutions_for_adapt,
            HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_ABS, &err_est_rel) * 100;

        // Report results.
        info("ndof_coarse[0]: %d, ndof_fine[0]: %d",
             C_space.get_num_dofs(), (*ref_spaces)[0]->get_num_dofs());
        info("err_est_rel[0]: %g%%", err_est_rel[0]*100);
        info("ndof_coarse[1]: %d, ndof_fine[1]: %d",
             phi_space.get_num_dofs(), (*ref_spaces)[1]->get_num_dofs());
        info("err_est_rel[1]: %g%%", err_est_rel[1]*100);
        // Report results.
        info("ndof_coarse_total: %d, ndof_fine_total: %d, err_est_rel: %g%%",
             Space::get_num_dofs(Hermes::vector<Space *>(&C_space, &phi_space)),
                                 Space::get_num_dofs(*ref_spaces), err_est_rel_total);

        // If err_est too large, adapt the mesh.
        if (err_est_rel_total < ERR_STOP) done = true;
        else
        {
          info("Adapting the coarse mesh.");
          adaptivity->adapt(THRESHOLD);

          info("Adapted...");

          if (Space::get_num_dofs(Hermes::vector<Space *>(&C_space, &phi_space)) >= NDOF_STOP)
            done = true;
          else
            // Increase the counter of performed adaptivity steps.
            as++;
        }



        //as++;
        delete solver;
        delete matrix;
        delete rhs;
        delete ref_spaces;
        delete dp;
        delete[] coeff_vec;
        done = true;
      } while (!done);
      out_fn_vtk(C_ref_sln,"C_sln", pid.get_timestep_number());
      out_fn_vtk(phi_ref_sln,"phi_sln", pid.get_timestep_number());

      pid.end_step(Hermes::vector<Solution*> (C_ref_sln, phi_ref_sln), Hermes::vector<Solution*> (&C_prev_time, &phi_prev_time));

      // Copy last reference solution into sln_prev_time.
      C_prev_time.copy(C_ref_sln);
      phi_prev_time.copy(phi_ref_sln);
  } while (pid.has_next());


  //View::wait();
  return 0;
}
Beispiel #3
0
int main(int argc, char* argv[])
{
  // Time measurement.
  TimePeriod cpu_time;
  cpu_time.tick();

  info("TIME_MAX_ITER = %d", TIME_MAX_ITER);

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

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

  // Enter boundary markers.
  BCTypes bc_types;
  bc_types.add_bc_dirichlet(BDY_DIRICHLET);

  // Enter Dirichlet boudnary values.
  BCValues bc_values;
  bc_values.add_zero(BDY_DIRICHLET);

  // Create H1 spaces with default shapesets.
  H1Space space_T(&mesh, &bc_types, &bc_values, P_INIT);
  H1Space space_phi(&mesh, &bc_types, &bc_values, P_INIT);
  Hermes::Tuple<Space*> spaces(&space_T, &space_phi);

  // Exact solutions for error evaluation.
  ExactSolution T_exact_solution(&mesh, T_exact),
                phi_exact_solution(&mesh, phi_exact);

  // Initialize solution views (their titles will be2 updated in each time step).
  ScalarView sview_T("", new WinGeom(0, 0, 500, 400));
  sview_T.fix_scale_width(50);
  ScalarView sview_phi("", new WinGeom(0, 500, 500, 400));
  sview_phi.fix_scale_width(50);
  ScalarView sview_T_exact("", new WinGeom(550, 0, 500, 400));
  sview_T_exact.fix_scale_width(50);
  ScalarView sview_phi_exact("", new WinGeom(550, 500, 500, 400));
  sview_phi_exact.fix_scale_width(50);
  char title[100]; // Character array to store the title for an actual view and time step.

  // Solutions in the previous time step.
  Solution T_prev_time, phi_prev_time;
  Hermes::Tuple<MeshFunction*> time_iterates(&T_prev_time, &phi_prev_time);
  
  // Solutions in the previous Newton's iteration.
  Solution T_prev_newton, phi_prev_newton;
  Hermes::Tuple<Solution*> newton_iterates(&T_prev_newton, &phi_prev_newton);

  // Initialize the weak formulation.
  WeakForm wf(2);
  wf.add_matrix_form(0, 0, jac_TT, jac_TT_ord);
  wf.add_matrix_form(0, 1, jac_Tphi, jac_Tphi_ord);
  wf.add_vector_form(0, res_T, res_T_ord, HERMES_ANY, &T_prev_time);
  wf.add_matrix_form(1, 0, jac_phiT, jac_phiT_ord);
  wf.add_matrix_form(1, 1, jac_phiphi, jac_phiphi_ord);
  wf.add_vector_form(1, res_phi, res_phi_ord, HERMES_ANY, &phi_prev_time);
  
  // Set initial conditions.
  T_prev_time.set_exact(&mesh, T_exact);
  phi_prev_time.set_exact(&mesh, phi_exact);
  
  // Set up the solver, matrix, and rhs according to the solver selection.
  SparseMatrix* matrix = create_matrix(matrix_solver);
  Vector* rhs = create_vector(matrix_solver);
  Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);
  solver->set_factorization_scheme(HERMES_REUSE_MATRIX_REORDERING);

  // Time stepping.
  int t_step = 1;
  do {
    TIME += TAU;

    info("---- Time step %d, t = %g s:", t_step, TIME); t_step++;
    info("Projecting to obtain initial vector for the Newton's method.");

    scalar* coeff_vec = new scalar[Space::get_num_dofs(spaces)];
    OGProjection::project_global(spaces, time_iterates, coeff_vec, matrix_solver);
    Solution::vector_to_solutions(coeff_vec, Hermes::Tuple<Space*>(&space_T, &space_phi), 
                                  Hermes::Tuple<Solution*>(&T_prev_newton, &phi_prev_newton));
    
    // Initialize the FE problem.
    bool is_linear = false;
    DiscreteProblem dp(&wf, spaces, is_linear);

    // Perform Newton's iteration.
    info("Newton's iteration...");
    bool verbose = true;
    if(!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose))
      error("Newton's iteration failed.");
        
    // Translate the resulting coefficient vector into the Solution sln.
    Solution::vector_to_solutions(coeff_vec, spaces, newton_iterates);
    delete [] coeff_vec;
    
    // Show the new time level solution.
    sprintf(title, "Approx. solution for T, t = %g s", TIME);
    sview_T.set_title(title); 
    sview_T.show(&T_prev_newton);
    
    sprintf(title, "Approx. solution for phi, t = %g s", TIME);
    sview_phi.set_title(title);
    sview_phi.show(&phi_prev_newton);

    // Exact solution for comparison with computational results.
    T_exact_solution.update(&mesh, T_exact);
    phi_exact_solution.update(&mesh, phi_exact);

    // Show exact solution.
    sview_T_exact.show(&T_exact_solution);
    sprintf(title, "Exact solution for T, t = %g s", TIME);
    sview_T_exact.set_title(title);
    
    sview_phi_exact.show(&phi_exact_solution);
    sprintf(title, "Exact solution for phi, t = %g s", TIME);
    sview_phi_exact.set_title(title);
    
    // Calculate exact error.
    info("Calculating error (exact).");
    Hermes::Tuple<double> exact_errors;
    Adapt adaptivity_exact(spaces, Hermes::Tuple<ProjNormType>(HERMES_H1_NORM, HERMES_H1_NORM));
    bool solutions_for_adapt = false;
    adaptivity_exact.calc_err_exact(Hermes::Tuple<Solution *>(&T_prev_newton, &phi_prev_newton), Hermes::Tuple<Solution *>(&T_exact_solution, &phi_exact_solution), solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL, &exact_errors);
    
    double maxerr = std::max(exact_errors[0], exact_errors[1])*100;
    info("Exact solution error for T (H1 norm): %g %%", exact_errors[0]*100);
    info("Exact solution error for phi (H1 norm): %g %%", exact_errors[1]*100);
    info("Exact solution error (maximum): %g %%", maxerr);
    
    // Prepare previous time level solution for the next time step.
    T_prev_time.copy(&T_prev_newton);
    phi_prev_time.copy(&phi_prev_newton);
  }
  while (t_step <= TIME_MAX_ITER);

  // Cleanup.
  delete matrix;
  delete rhs;
  delete solver;
  
  // Wait for all views to be closed.
  View::wait();

  return 0;
}
Beispiel #4
0
int main(int argc, char* argv[])
{
    // Time measurement.
    TimePeriod cpu_time;
    cpu_time.tick();

    info("TIME_MAX_ITER = %d", TIME_MAX_ITER);

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

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

    // Enter boundary markers.
    BCTypes bc_types;
    bc_types.add_bc_dirichlet(BDY_DIRICHLET);

    // Enter Dirichlet boudnary values.
    BCValues bc_values;
    bc_values.add_zero(BDY_DIRICHLET);

    // Create H1 spaces with default shapesets.
    H1Space space_T(&mesh, &bc_types, &bc_values, P_INIT);
    H1Space space_phi(&mesh, &bc_types, &bc_values, P_INIT);
    Hermes::vector<Space*> spaces(&space_T, &space_phi);

    // Exact solutions for error evaluation.
    ExactSolution T_exact_solution(&mesh, T_exact),
                  phi_exact_solution(&mesh, phi_exact);

    // Solutions in the previous time step.
    Solution T_prev_time, phi_prev_time;
    Hermes::vector<MeshFunction*> time_iterates(&T_prev_time, &phi_prev_time);

    // Solutions in the previous Newton's iteration.
    Solution T_prev_newton, phi_prev_newton;
    Hermes::vector<Solution*> newton_iterates(&T_prev_newton, &phi_prev_newton);

    // Initialize the weak formulation.
    WeakForm wf(2);
    wf.add_matrix_form(0, 0, jac_TT, jac_TT_ord);
    wf.add_matrix_form(0, 1, jac_Tphi, jac_Tphi_ord);
    wf.add_vector_form(0, res_T, res_T_ord, HERMES_ANY, &T_prev_time);
    wf.add_matrix_form(1, 0, jac_phiT, jac_phiT_ord);
    wf.add_matrix_form(1, 1, jac_phiphi, jac_phiphi_ord);
    wf.add_vector_form(1, res_phi, res_phi_ord, HERMES_ANY, &phi_prev_time);

    // Set initial conditions.
    T_prev_time.set_exact(&mesh, T_exact);
    phi_prev_time.set_exact(&mesh, phi_exact);

    // Set up the solver, matrix, and rhs according to the solver selection.
    SparseMatrix* matrix = create_matrix(matrix_solver);
    Vector* rhs = create_vector(matrix_solver);
    Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);
    solver->set_factorization_scheme(HERMES_REUSE_MATRIX_REORDERING);

    // Time stepping.
    int t_step = 1;
    do {
        TIME += TAU;

        info("---- Time step %d, t = %g s:", t_step, TIME);
        t_step++;
        info("Projecting to obtain initial vector for the Newton's method.");

        scalar* coeff_vec = new scalar[Space::get_num_dofs(spaces)];
        OGProjection::project_global(spaces, time_iterates, coeff_vec, matrix_solver);
        Solution::vector_to_solutions(coeff_vec, Hermes::vector<Space*>(&space_T, &space_phi),
                                      Hermes::vector<Solution*>(&T_prev_newton, &phi_prev_newton));

        // Initialize the FE problem.
        bool is_linear = false;
        DiscreteProblem dp(&wf, spaces, is_linear);

        // Perform Newton's iteration.
        info("Newton's iteration...");
        bool verbose = false;
        if(!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose))
            error("Newton's iteration failed.");

        // Translate the resulting coefficient vector into the Solution sln.
        Solution::vector_to_solutions(coeff_vec, spaces, newton_iterates);
        delete [] coeff_vec;

        // Exact solution for comparison with computational results.
        T_exact_solution.update(&mesh, T_exact);
        phi_exact_solution.update(&mesh, phi_exact);

        // Calculate exact error.
        info("Calculating error (exact).");
        Hermes::vector<double> exact_errors;
        Adapt adaptivity_exact(spaces);
        bool solutions_for_adapt = false;
        adaptivity_exact.calc_err_exact(Hermes::vector<Solution *>(&T_prev_newton, &phi_prev_newton), Hermes::vector<Solution *>(&T_exact_solution, &phi_exact_solution), &exact_errors, solutions_for_adapt);

        double maxerr = std::max(exact_errors[0], exact_errors[1])*100;
        info("Exact solution error for T (H1 norm): %g %%", exact_errors[0]*100);
        info("Exact solution error for phi (H1 norm): %g %%", exact_errors[1]*100);
        info("Exact solution error (maximum): %g %%", maxerr);

        // Prepare previous time level solution for the next time step.
        T_prev_time.copy(&T_prev_newton);
        phi_prev_time.copy(&phi_prev_newton);
    }
    while (t_step <= TIME_MAX_ITER);

    // Cleanup.
    delete matrix;
    delete rhs;
    delete solver;

    info("Coordinate (  0,  0) T value = %lf", T_prev_time.get_pt_value(0.0, 0.0));
    info("Coordinate ( 25, 25) T value = %lf", T_prev_time.get_pt_value(25.0, 25.0));
    info("Coordinate ( 75, 25) T value = %lf", T_prev_time.get_pt_value(75.0, 25.0));
    info("Coordinate ( 25, 75) T value = %lf", T_prev_time.get_pt_value(25.0, 75.0));
    info("Coordinate ( 75, 75) T value = %lf", T_prev_time.get_pt_value(75.0, 75.0));

    info("Coordinate (  0,  0) phi value = %lf", phi_prev_time.get_pt_value(0.0, 0.0));
    info("Coordinate ( 25, 25) phi value = %lf", phi_prev_time.get_pt_value(25.0, 25.0));
    info("Coordinate ( 75, 25) phi value = %lf", phi_prev_time.get_pt_value(75.0, 25.0));
    info("Coordinate ( 25, 75) phi value = %lf", phi_prev_time.get_pt_value(25.0, 75.0));
    info("Coordinate ( 75, 75) phi value = %lf", phi_prev_time.get_pt_value(75.0, 75.0));

    int success = 1;
    double eps = 1e-5;
    if (fabs(T_prev_time.get_pt_value(0.0, 0.0) - 0.000000) > eps) {
        printf("Coordinate (  0,  0) T value = %lf\n", T_prev_time.get_pt_value(0.0, 0.0));
        success = 0;
    }

    if (fabs(T_prev_time.get_pt_value(25.0, 25.0) - 0.915885) > eps) {
        printf("Coordinate ( 25, 25) T value = %lf\n", T_prev_time.get_pt_value(25.0, 25.0));
        success = 0;
    }

    if (fabs(T_prev_time.get_pt_value(75.0, 25.0) - 0.915885) > eps) {
        printf("Coordinate ( 75, 25) T value = %lf\n", T_prev_time.get_pt_value(75.0, 25.0));
        success = 0;
    }

    if (fabs(T_prev_time.get_pt_value(25.0, 75.0) - 0.915885) > eps) {
        printf("Coordinate ( 25, 75) T value = %lf\n", T_prev_time.get_pt_value(25.0, 75.0));
        success = 0;
    }

    if (fabs(T_prev_time.get_pt_value(75.0, 75.0) - 0.915885) > eps) {
        printf("Coordinate ( 75, 75) T value = %lf\n", T_prev_time.get_pt_value(75.0, 75.0));
        success = 0;
    }

    if (fabs(phi_prev_time.get_pt_value(0.0, 0.0) - 0.000000) > eps) {
        printf("Coordinate (  0,  0) phi value = %lf\n", phi_prev_time.get_pt_value(0.0, 0.0));
        success = 0;
    }

    if (fabs(phi_prev_time.get_pt_value(25.0, 25.0) - 0.071349) > eps) {
        printf("Coordinate ( 25, 25) phi value = %lf\n", phi_prev_time.get_pt_value(25.0, 25.0));
        success = 0;
    }

    if (fabs(phi_prev_time.get_pt_value(75.0, 25.0) - 0.214063) > eps) {
        printf("Coordinate ( 75, 25) phi value = %lf\n", phi_prev_time.get_pt_value(75.0, 25.0));
        success = 0;
    }

    if (fabs(phi_prev_time.get_pt_value(25.0, 75.0) - 0.214063) > eps) {
        printf("Coordinate ( 25, 75) phi value = %lf\n", phi_prev_time.get_pt_value(25.0, 75.0));
        success = 0;
    }

    if (fabs(phi_prev_time.get_pt_value(75.0, 75.0) - 0.642226) > eps) {
        printf("Coordinate ( 75, 75) phi value = %lf\n", phi_prev_time.get_pt_value(75.0, 75.0));
        success = 0;
    }

    if (success == 1) {
        printf("Success!\n");
        return ERR_SUCCESS;
    }
    else {
        printf("Failure!\n");
        return ERR_FAILURE;
    }
}
Beispiel #5
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  H2DReader mloader;
  mloader.load("square.mesh", &mesh);

  // Initial mesh refinements.
  for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements();
  mesh.refine_towards_boundary(BDY_DIRICHLET, INIT_BDY_REF_NUM);

  // Enter boundary markers.
  BCTypes bc_types;
  bc_types.add_bc_dirichlet(BDY_DIRICHLET);

  // Enter Dirichlet boundary values.
  BCValues bc_values;
  bc_values.add_function(BDY_DIRICHLET, essential_bc_values);

  // Create an H1 space with default shapeset.
  H1Space space(&mesh, &bc_types, &bc_values, P_INIT);
  int ndof = Space::get_num_dofs(&space);
  info("ndof = %d.", ndof);

  // Solution for the previous time level.
  Solution u_prev_time;

  // Initialize the weak formulation.
  WeakForm wf;
  if (TIME_INTEGRATION == 1) {
    wf.add_matrix_form(jac_euler, jac_ord, HERMES_NONSYM, HERMES_ANY, &u_prev_time);
    wf.add_vector_form(res_euler, res_ord, HERMES_ANY, &u_prev_time);
  }
  else {
    wf.add_matrix_form(jac_cranic, jac_ord, HERMES_NONSYM, HERMES_ANY, &u_prev_time);
    wf.add_vector_form(res_cranic, res_ord, HERMES_ANY, &u_prev_time);
  }

  // Project the function init_cond() on the FE space
  // to obtain initial coefficient vector for the Newton's method.
  scalar* coeff_vec = new scalar[Space::get_num_dofs(&space)];
  info("Projecting initial condition to obtain initial vector for the Newton's method.");
  OGProjection::project_global(&space, init_cond, coeff_vec, matrix_solver);
  Solution::vector_to_solution(coeff_vec, &space, &u_prev_time);

  // Initialize views.
  ScalarView sview("Solution", new WinGeom(0, 0, 500, 400));
  OrderView oview("Mesh", new WinGeom(520, 0, 450, 400));
  oview.show(&space);
  sview.show(&u_prev_time);
  
  // Time stepping loop:
  double current_time = 0.0;
  int t_step = 1;
  do {
    info("---- Time step %d, t = %g s.", t_step, current_time); t_step++;

    // Initialize the FE problem.
    bool is_linear = false;
    DiscreteProblem dp(&wf, &space, is_linear);

    // Set up the solver, matrix, and rhs according to the solver selection.
    SparseMatrix* matrix = create_matrix(matrix_solver);
    Vector* rhs = create_vector(matrix_solver);
    Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);

    // Perform Newton's iteration.
    bool verbose = true;
    if (!solve_newton(coeff_vec, &dp, solver, matrix, rhs, 
        NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed.");

    // Translate the resulting coefficient vector into the Solution sln.
    Solution::vector_to_solution(coeff_vec, &space, &u_prev_time);

    // Cleanup.
    delete matrix;
    delete rhs;
    delete solver;

    // Update time.
    current_time += TAU;

    // Show the new time level solution.
    char title[100];
    sprintf(title, "Solution, t = %g", current_time);
    sview.set_title(title);
    sview.show(&u_prev_time);
  } while (current_time < T_FINAL);
  
  delete [] coeff_vec;

  // Wait for all views to be closed.
  View::wait();
  return 0;
}
Beispiel #6
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  H2DReader mloader;
  mloader.load("domain-excentric.mesh", &mesh);
  //mloader.load("domain-concentric.mesh", &mesh);

  // Initial mesh refinements.
  for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements();
  mesh.refine_towards_boundary(BDY_INNER, INIT_BDY_REF_NUM_INNER, false);  // true for anisotropic refinements
  mesh.refine_towards_boundary(BDY_OUTER, INIT_BDY_REF_NUM_OUTER, false);  // false for isotropic refinements

  // Enter boundary markers for x-velocity and y-velocity.
  BCTypes bc_types;
  bc_types.add_bc_dirichlet(Hermes::Tuple<int>(BDY_INNER, BDY_OUTER));

  BCTypes bc_types_p;
  bc_types_p.add_bc_none(Hermes::Tuple<int>(BDY_INNER, BDY_OUTER));

  // Enter Dirichlet boundary values.
  BCValues bc_values_xvel(&TIME);
  bc_values_xvel.add_timedep_function(BDY_INNER, essential_bc_values_xvel);
  bc_values_xvel.add_zero(BDY_OUTER);

  BCValues bc_values_yvel(&TIME);
  bc_values_yvel.add_timedep_function(BDY_INNER, essential_bc_values_yvel);
  bc_values_yvel.add_zero(BDY_OUTER);

  // Create spaces with default shapesets. 
  H1Space xvel_space(&mesh, &bc_types, &bc_values_xvel, P_INIT_VEL);
  H1Space yvel_space(&mesh, &bc_types, &bc_values_yvel, P_INIT_VEL);
#ifdef PRESSURE_IN_L2
  L2Space p_space(&mesh, P_INIT_PRESSURE);
#else
  H1Space p_space(&mesh, &bc_types_p, P_INIT_PRESSURE);
#endif

  // Calculate and report the number of degrees of freedom.
  int ndof = Space::get_num_dofs(Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space));
  info("ndof = %d.", ndof);

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

  // Solutions for the Newton's iteration and time stepping.
  info("Setting initial conditions.");
  Solution xvel_prev_time, yvel_prev_time, p_prev_time;
  xvel_prev_time.set_zero(&mesh);
  yvel_prev_time.set_zero(&mesh);
  p_prev_time.set_zero(&mesh);

  // Initialize weak formulation.
  WeakForm wf(3);
  if (NEWTON) {
    wf.add_matrix_form(0, 0, callback(bilinear_form_sym_0_0_1_1), HERMES_SYM);
    wf.add_matrix_form(0, 0, callback(newton_bilinear_form_unsym_0_0), HERMES_NONSYM, HERMES_ANY);
    wf.add_matrix_form(0, 1, callback(newton_bilinear_form_unsym_0_1), HERMES_NONSYM, HERMES_ANY);
    wf.add_matrix_form(0, 2, callback(bilinear_form_unsym_0_2), HERMES_ANTISYM);
    wf.add_matrix_form(1, 0, callback(newton_bilinear_form_unsym_1_0), HERMES_NONSYM, HERMES_ANY);
    wf.add_matrix_form(1, 1, callback(bilinear_form_sym_0_0_1_1), HERMES_SYM);
    wf.add_matrix_form(1, 1, callback(newton_bilinear_form_unsym_1_1), HERMES_NONSYM, HERMES_ANY);
    wf.add_matrix_form(1, 2, callback(bilinear_form_unsym_1_2), HERMES_ANTISYM);
    wf.add_vector_form(0, callback(newton_F_0), HERMES_ANY, 
                       Hermes::Tuple<MeshFunction*>(&xvel_prev_time, &yvel_prev_time));
    wf.add_vector_form(1, callback(newton_F_1), HERMES_ANY, 
                       Hermes::Tuple<MeshFunction*>(&xvel_prev_time, &yvel_prev_time));
    wf.add_vector_form(2, callback(newton_F_2), HERMES_ANY);
  }
  else {
    wf.add_matrix_form(0, 0, callback(bilinear_form_sym_0_0_1_1), HERMES_SYM);
    wf.add_matrix_form(0, 0, callback(simple_bilinear_form_unsym_0_0_1_1), 
                  HERMES_NONSYM, HERMES_ANY, Hermes::Tuple<MeshFunction*>(&xvel_prev_time, &yvel_prev_time));
    wf.add_matrix_form(1, 1, callback(bilinear_form_sym_0_0_1_1), HERMES_SYM);
    wf.add_matrix_form(1, 1, callback(simple_bilinear_form_unsym_0_0_1_1), 
                  HERMES_NONSYM, HERMES_ANY, Hermes::Tuple<MeshFunction*>(&xvel_prev_time, &yvel_prev_time));
    wf.add_matrix_form(0, 2, callback(bilinear_form_unsym_0_2), HERMES_ANTISYM);
    wf.add_matrix_form(1, 2, callback(bilinear_form_unsym_1_2), HERMES_ANTISYM);
    wf.add_vector_form(0, callback(simple_linear_form), HERMES_ANY, &xvel_prev_time);
    wf.add_vector_form(1, callback(simple_linear_form), HERMES_ANY, &yvel_prev_time);
  }

  // Project initial conditions on FE spaces to obtain initial coefficient 
  // vector for the Newton's method.
  scalar* coeff_vec = new scalar[Space::get_num_dofs(Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space))];
  if (NEWTON) {
    info("Projecting initial conditions to obtain initial vector for the Newton's method.");
    OGProjection::project_global(Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space),
                   Hermes::Tuple<MeshFunction*>(&xvel_prev_time, &yvel_prev_time, &p_prev_time),
                   coeff_vec, matrix_solver, Hermes::Tuple<ProjNormType>(vel_proj_norm, vel_proj_norm, p_proj_norm));
  }

  // Time-stepping loop:
  char title[100];
  int num_time_steps = T_FINAL / TAU;
  for (int ts = 1; ts <= num_time_steps; ts++)
  {
    TIME += TAU;
    info("---- Time step %d, time = %g:", ts, TIME);

    // Update time-dependent essential BC are used.
    if (TIME <= STARTUP_TIME) {
      info("Updating time-dependent essential BC.");
      update_essential_bc_values(Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space));
    }

    if (NEWTON) 
    {
      info("Performing Newton's method.");
      // Initialize the FE problem.
      bool is_linear = false;
      DiscreteProblem dp(&wf, Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space), is_linear);

      // Set up the solver, matrix, and rhs according to the solver selection.
      SparseMatrix* matrix = create_matrix(matrix_solver);
      Vector* rhs = create_vector(matrix_solver);
      Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);

      // Perform Newton's iteration.
      info("Solving nonlinear problem:");
      bool verbose = true;
      if (!solve_newton(coeff_vec, &dp, solver, matrix, rhs, 
          NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed.");
      
      // Translate the resulting coefficient vector into the actual solutions. 
      Solution::vector_to_solutions(coeff_vec, Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space), 
                                    Hermes::Tuple<Solution *>(&xvel_prev_time, &yvel_prev_time, &p_prev_time));

      // Cleanup.
      delete matrix;
      delete rhs;
      delete solver;
    }
    else {
      // Linear solve.  
      info("Assembling and solving linear problem.");
      bool is_linear = true;
      DiscreteProblem dp(&wf, Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space), is_linear);

      // Set up the solver, matrix, and rhs according to the solver selection.
      SparseMatrix* matrix = create_matrix(matrix_solver);
      Vector* rhs = create_vector(matrix_solver);
      Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);

      dp.assemble(matrix, rhs);

      // Solve the linear system and if successful, obtain the solution.
      info("Solving the matrix problem.");
      if(solver->solve())
        Solution::vector_to_solutions(solver->get_solution(),  Hermes::Tuple<Space *>(&xvel_space, &yvel_space, &p_space), 
                                      Hermes::Tuple<Solution *>(&xvel_prev_time, &yvel_prev_time, &p_prev_time));
      else
        error ("Matrix solver failed.\n");
    }
  }
  // Clean up.
  delete [] coeff_vec;
  
  info("Coordinate ( 0.1, 0.0) xvel value = %lf", xvel_prev_time.get_pt_value(0.1, 0.0));
  info("Coordinate ( 0.5, 0.0) xvel value = %lf", xvel_prev_time.get_pt_value(0.5, 0.0));
  info("Coordinate ( 0.9, 0.0) xvel value = %lf", xvel_prev_time.get_pt_value(0.9, 0.0));
  info("Coordinate ( 1.3, 0.0) xvel value = %lf", xvel_prev_time.get_pt_value(1.3, 0.0));
  info("Coordinate ( 1.7, 0.0) xvel value = %lf", xvel_prev_time.get_pt_value(1.7, 0.0));

  info("Coordinate ( 0.1, 0.0) yvel value = %lf", yvel_prev_time.get_pt_value(0.1, 0.0));
  info("Coordinate ( 0.5, 0.0) yvel value = %lf", yvel_prev_time.get_pt_value(0.5, 0.0));
  info("Coordinate ( 0.9, 0.0) yvel value = %lf", yvel_prev_time.get_pt_value(0.9, 0.0));
  info("Coordinate ( 1.3, 0.0) yvel value = %lf", yvel_prev_time.get_pt_value(1.3, 0.0));
  info("Coordinate ( 1.7, 0.0) yvel value = %lf", yvel_prev_time.get_pt_value(1.7, 0.0));

  int success = 1;
  double eps = 1e-5;
  if (fabs(xvel_prev_time.get_pt_value(0.1, 0.0) - (0.000000)) > eps) {
    printf("Coordinate ( 0.1, 0.0) xvel value = %lf\n", xvel_prev_time.get_pt_value(0.1, 0.0));
    success = 0;
  }
  if (fabs(xvel_prev_time.get_pt_value(0.5, 0.0) - (-0.000347)) > eps) {
    printf("Coordinate ( 0.5, 0.0) xvel value = %lf\n", xvel_prev_time.get_pt_value(0.5, 0.0));
    success = 0;
  }
  if (fabs(xvel_prev_time.get_pt_value(0.9, 0.0) - (-0.000047)) > eps) {
    printf("Coordinate ( 0.9, 0.0) xvel value = %lf\n", xvel_prev_time.get_pt_value(0.9, 0.0));
    success = 0;
  }
  if (fabs(xvel_prev_time.get_pt_value(1.3, 0.0) - (-0.000004)) > eps) {
    printf("Coordinate ( 1.3, 0.0) xvel value = %lf\n", xvel_prev_time.get_pt_value(1.3, 0.0));
    success = 0;
  }
  if (fabs(xvel_prev_time.get_pt_value(1.7, 0.0) - (-0.000001)) > eps) {
    printf("Coordinate ( 1.7, 0.0) xvel value = %lf\n", xvel_prev_time.get_pt_value(1.7, 0.0));
    success = 0;
  }

  if (fabs(yvel_prev_time.get_pt_value(0.1, 0.0) - (-0.100000)) > eps) {
    printf("Coordinate ( 0.1, 0.0) yvel value = %lf\n", yvel_prev_time.get_pt_value(0.1, 0.0));
    success = 0;
  }
  if (fabs(yvel_prev_time.get_pt_value(0.5, 0.0) - (0.001477)) > eps) {
    printf("Coordinate ( 0.5, 0.0) yvel value = %lf\n", yvel_prev_time.get_pt_value(0.5, 0.0));
    success = 0;
  }
  if (fabs(yvel_prev_time.get_pt_value(0.9, 0.0) - (0.000572)) > eps) {
    printf("Coordinate ( 0.9, 0.0) yvel value = %lf\n", yvel_prev_time.get_pt_value(0.9, 0.0));
    success = 0;
  }
  if (fabs(yvel_prev_time.get_pt_value(1.3, 0.0) - (0.000296)) > eps) {
    printf("Coordinate ( 1.3, 0.0) yvel value = %lf\n", yvel_prev_time.get_pt_value(1.3, 0.0));
    success = 0;
  }
  if (fabs(yvel_prev_time.get_pt_value(1.7, 0.0) - (0.000169)) > eps) {
    printf("Coordinate ( 1.7, 0.0) yvel value = %lf\n", yvel_prev_time.get_pt_value(1.7, 0.0));
    success = 0;
  }

  if (success == 1) {
    printf("Success!\n");
    return ERR_SUCCESS;
  }
  else {
    printf("Failure!\n");
    return ERR_FAILURE;
  }
}