Exemplo n.º 1
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;
}
Exemplo n.º 2
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  mloader.load("domain.mesh", &mesh);

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

  // Initialize boundary conditions.
  DefaultEssentialBCConst<std::complex<double> > bc(Hermes::vector<std::string>(BDY_BOTTOM, BDY_RIGHT, BDY_TOP, BDY_LEFT), std::complex<double>(0.0, 0.0));

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

  // Create an H1 space.
  H1Space<std::complex<double> >* phi_space = new H1Space<std::complex<double> >(&mesh, &bcs, P_INIT);
  H1Space<std::complex<double> >* psi_space = new H1Space<std::complex<double> >(&mesh, &bcs, P_INIT);

  int ndof = Space<std::complex<double> >::get_num_dofs(Hermes::vector<Space<std::complex<double> > *>(phi_space, psi_space));
  info("ndof = %d.", ndof);

  // Initialize previous time level solutions.
  ConstantSolution<std::complex<double> > phi_prev_time(&mesh, init_cond_phi);
  ConstantSolution<std::complex<double> > psi_prev_time(&mesh, init_cond_psi);

  // Initialize the weak formulation.
  WeakForm<std::complex<double> > wf(2);
  wf.add_matrix_form(0, 0, callback(biform_euler_0_0));
  wf.add_matrix_form(0, 1, callback(biform_euler_0_1));
  wf.add_matrix_form(1, 0, callback(biform_euler_1_0));
  wf.add_matrix_form(1, 1, callback(biform_euler_1_1));
  wf.add_vector_form(0, callback(liform_euler_0), HERMES_ANY, &phi_prev_time);
  wf.add_vector_form(1, callback(liform_euler_1), HERMES_ANY, &psi_prev_time);

  // Initialize views.
  ScalarView view("Psi", new WinGeom(0, 0, 600, 500));
  view.fix_scale_width(80);

  // Time stepping loop:
  int nstep = (int)(T_FINAL/TAU + 0.5);
  for(int ts = 1; ts <= nstep; ts++)
  {

    info("Time step %d:", ts);

    info("Solving linear system.");
    // Initialize the FE problem.
    bool is_linear = true;
    DiscreteProblem<std::complex<double> > dp(&wf, Hermes::vector<Space<double>* *>(phi_space, psi_space), is_linear);
   
    SparseMatrix<std::complex<double> >* matrix = create_matrix<std::complex<double> >(matrix_solver_type);
    Vector<std::complex<double> >* rhs = create_vector<std::complex<double> >(matrix_solver_type);
    LinearSolver<std::complex<double> >* solver = create_linear_solver<std::complex<double> >(matrix_solver_type, matrix, rhs);

    // Assemble the stiffness matrix and right-hand side vector.
    info("Assembling the stiffness matrix and right-hand side vector.");
    dp.assemble(matrix, rhs);

    // Solve the linear system and if successful, obtain the solution.
    info("Solving the matrix problem.");
    if(solver->solve())
      Solution<std::complex<double> >::vector_to_solutions(solver->get_sln_vector(), Hermes::vector<Space<std::complex<double> >*>(phi_space, psi_space), Hermes::vector<Solution<std::complex<double> > *>(&phi_prev_time, &psi_prev_time));
    else
      error ("Matrix solver failed.\n");

    // Show the new time level solution.
    char title[100];
    sprintf(title, "Time step %d", ts);
    view.set_title(title);
    view.show(&psi_prev_time);
  }

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