Пример #1
0
    void OGProjectionNOX<Scalar>::project_global(SpaceSharedPtr<Scalar> space,
      MeshFunctionSharedPtr<Scalar> source_sln, MeshFunctionSharedPtr<Scalar> target_sln,
      NormType proj_norm,
      double newton_tol, int newton_max_iter)
    {
      if(proj_norm == HERMES_UNSET_NORM)
      {
        SpaceType space_type = space->get_type();
        switch (space_type)
        {
        case HERMES_H1_SPACE: proj_norm = HERMES_H1_NORM; break;
        case HERMES_HCURL_SPACE: proj_norm = HERMES_HCURL_NORM; break;
        case HERMES_HDIV_SPACE: proj_norm = HERMES_HDIV_NORM; break;
        case HERMES_L2_SPACE: proj_norm = HERMES_L2_NORM; break;
        case HERMES_L2_MARKERWISE_CONST_SPACE: proj_norm = HERMES_L2_NORM; break;
        default: throw Hermes::Exceptions::Exception("Unknown space type in OGProjectionNOX<Scalar>::project_global().");
        }
      }

      // Calculate the coefficient vector.
      int ndof = space->get_num_dofs();
      Scalar* target_vec = new Scalar[ndof];
      project_global(space, source_sln, target_vec, proj_norm, newton_tol, newton_max_iter);

      // Translate coefficient vector into a Solution.
      Solution<Scalar>::vector_to_solution(target_vec, space, target_sln);

      // Clean up.
      delete [] target_vec;
    }
Пример #2
0
 void OGProjectionNOX<Scalar>::project_global(SpaceSharedPtr<Scalar> space,
   MeshFunctionSharedPtr<Scalar> source_meshfn, Scalar* target_vec,
   NormType proj_norm,
   double newton_tol, int newton_max_iter)
 {
   project_global(space, source_meshfn.get(), target_vec, proj_norm, newton_tol, newton_max_iter);
 }
Пример #3
0
 void OGProjection<Scalar>::project_global(Hermes::vector<Space<Scalar>*> spaces, Hermes::vector<Solution<Scalar>*> source_sols,
   Scalar* target_vec, Hermes::MatrixSolverType matrix_solver_type, Hermes::vector<ProjNormType> proj_norms)
 {
   Hermes::vector<MeshFunction<Scalar>*> mesh_fns;
   for(unsigned int i = 0; i < source_sols.size(); i++)
     mesh_fns.push_back(source_sols[i]);
   project_global(spaces, mesh_fns, target_vec, matrix_solver_type, proj_norms);
 }
Пример #4
0
    void OGProjection<Scalar>::project_global(Hermes::vector<SpaceSharedPtr<Scalar> > spaces, Hermes::vector<MeshFunctionSharedPtr<Scalar> > source_slns,
      Hermes::Algebra::Vector<Scalar>* target_vec, Hermes::vector<NormType> proj_norms)
    {
      if(target_vec->get_size() != Space<Scalar>::get_num_dofs(spaces))
        throw Exceptions::ValueException("target_vec->size", target_vec->get_size(), Space<Scalar>::get_num_dofs(spaces));

      Scalar* vec = new Scalar[target_vec->get_size()];
      project_global(spaces, source_slns, vec, proj_norms);
      target_vec->set_vector(vec);
      delete [] vec;
    }
Пример #5
0
    void OGProjectionNOX<Scalar>::project_global(Hermes::vector<SpaceSharedPtr<Scalar> > spaces, Hermes::vector<MeshFunctionSharedPtr<Scalar> > source_slns,
      Scalar* target_vec, Hermes::vector<NormType> proj_norms,
      double newton_tol, int newton_max_iter)
    {
      int n = spaces.size();

      // Sanity checks.
      if(n != source_slns.size()) throw Exceptions::LengthException(1, 2, n, source_slns.size());
      if(target_vec == nullptr) throw Exceptions::NullException(3);
      if(!proj_norms.empty() && n != proj_norms.size()) throw Exceptions::LengthException(1, 5, n, proj_norms.size());

      int start_index = 0;
      for (int i = 0; i < n; i++)
      {
        if(proj_norms.empty())
          project_global(spaces[i], source_slns[i], target_vec + start_index, HERMES_UNSET_NORM, newton_tol, newton_max_iter);
        else
          project_global(spaces[i], source_slns[i], target_vec + start_index, proj_norms[i], newton_tol, newton_max_iter);
        start_index += spaces[i]->get_num_dofs();
      }
    }
Пример #6
0
    void OGProjection<Scalar>::project_global(SpaceSharedPtr<Scalar> space,
      MeshFunctionSharedPtr<Scalar> source_meshfn, Hermes::Algebra::Vector<Scalar>* target_vec,
      NormType proj_norm)
    {
      if(target_vec->get_size() != space->get_num_dofs())
        throw Exceptions::ValueException("target_vec->size", target_vec->get_size(), space->get_num_dofs());

      Scalar* vec = new Scalar[target_vec->get_size()];
      project_global(space, source_meshfn, vec, proj_norm);
      target_vec->set_vector(vec);
      delete [] vec;
    }
Пример #7
0
 void OGProjection<Scalar>::project_global(Space<Scalar>* space, MeshFunction<Scalar>* source_meshfn,
   Scalar* target_vec, Hermes::MatrixSolverType matrix_solver_type,
   ProjNormType proj_norm)
 {
   Hermes::vector<Space<Scalar>*> spaces;
   spaces.push_back(space);
   Hermes::vector<MeshFunction<Scalar>*> source_meshfns;
   source_meshfns.push_back(source_meshfn);
   Hermes::vector<ProjNormType> proj_norms;
   proj_norms.push_back(proj_norm);
   project_global(spaces, source_meshfns, target_vec, matrix_solver_type, proj_norms);
 }
Пример #8
0
    void OGProjection<Scalar>::project_global(Hermes::vector<SpaceSharedPtr<Scalar> > spaces, Hermes::vector<MeshFunctionSharedPtr<Scalar> > source_slns,
      Hermes::vector<MeshFunctionSharedPtr<Scalar> > target_slns, Hermes::vector<NormType> proj_norms, bool delete_old_meshes)
    {
      int n = spaces.size();

      // Sanity checks.
      if(n != source_slns.size()) 
        throw Exceptions::LengthException(1, 2, n, source_slns.size());
      if(n != target_slns.size()) 
        throw Exceptions::LengthException(1, 2, n, target_slns.size());
      if(!proj_norms.empty() && n != proj_norms.size()) 
        throw Exceptions::LengthException(1, 5, n, proj_norms.size());

      int start_index = 0;
      for (int i = 0; i < n; i++)
      {
        if(proj_norms.empty())
          project_global(spaces[i], source_slns[i], target_slns[i], HERMES_UNSET_NORM);
        else
          project_global(spaces[i], source_slns[i], target_slns[i], proj_norms[i]);
        start_index += spaces[i]->get_num_dofs();
      }
    }
Пример #9
0
    void OGProjection<Scalar>::project_global(SpaceSharedPtr<Scalar> space,
      MatrixFormVol<Scalar>* custom_projection_jacobian,
      VectorFormVol<Scalar>* custom_projection_residual,
      MeshFunctionSharedPtr<Scalar> target_sln)
    {
      // Calculate the coefficient vector.
      Scalar* target_vec = new Scalar[space->get_num_dofs()];

      project_global(space, custom_projection_jacobian, custom_projection_residual, target_vec);

      // Translate coefficient vector into a Solution.
      Solution<Scalar>::vector_to_solution(target_vec, space, target_sln);

      // Clean up.
      delete [] target_vec;
    }
Пример #10
0
    void OGProjection<Scalar>::project_global(const Hermes::vector<SpaceSharedPtr<Scalar> >& spaces,
      const Hermes::vector<MatrixFormVol<Scalar>*>& custom_projection_jacobians,
      const Hermes::vector<VectorFormVol<Scalar>*>& custom_projection_residuals,
      const Hermes::vector<MeshFunctionSharedPtr<Scalar> >& target_slns)
    {
      int n = spaces.size();

      // Sanity checks.
      if (n != target_slns.size()) throw Exceptions::LengthException(1, 2, n, target_slns.size());
      if (n != custom_projection_jacobians.size()) throw Exceptions::LengthException(1, 2, n, custom_projection_residuals.size());
      if (n != custom_projection_residuals.size()) throw Exceptions::LengthException(1, 2, n, custom_projection_residuals.size());

      for (int i = 0; i < n; i++) 
      {
        project_global(spaces[i], custom_projection_jacobians[i], custom_projection_residuals[i], target_slns[i]);
      }
    }
Пример #11
0
    void OGProjection<Scalar>::project_global(Space<Scalar>* space,
      Solution<Scalar>* sol_src, Solution<Scalar>* sol_dest,
      Hermes::MatrixSolverType matrix_solver_type,
      ProjNormType proj_norm)
    {
      Hermes::vector<Space<Scalar>*> spaces;
      spaces.push_back(space);
      Hermes::vector<Solution<Scalar>*> sols_src;
      sols_src.push_back(sol_src);
      Hermes::vector<Solution<Scalar>*> sols_dest;
      sols_dest.push_back(sol_dest);
      Hermes::vector<ProjNormType> proj_norms;
      if(proj_norm != HERMES_UNSET_NORM)
        proj_norms.push_back(proj_norm);

      project_global(spaces, sols_src, sols_dest, matrix_solver_type, proj_norms);
    }
Пример #12
0
    void OGProjection<Scalar>::project_global(const Hermes::vector<SpaceSharedPtr<Scalar> >& spaces,
      const Hermes::vector<MatrixFormVol<Scalar>*>& custom_projection_jacobians,
      const Hermes::vector<VectorFormVol<Scalar>*>& custom_projection_residuals,
      Scalar* target_vec)
    {
      int n = spaces.size();

      // Sanity checks.
      if(target_vec == nullptr) throw Exceptions::NullException(3);
      if (n != custom_projection_jacobians.size()) throw Exceptions::LengthException(1, 2, n, custom_projection_residuals.size());
      if (n != custom_projection_residuals.size()) throw Exceptions::LengthException(1, 2, n, custom_projection_residuals.size());

      int start_index = 0;
      for (int i = 0; i < n; i++) 
      {

        project_global(spaces[i], custom_projection_jacobians[i], custom_projection_residuals[i], target_vec + start_index);

        start_index += spaces[i]->get_num_dofs();                       
      }
    }
Пример #13
0
void OGProjection::project_global(Space *space, ExactFunction2 source_fn, scalar* target_vec, 
                                  MatrixSolverType matrix_solver)
{
  _F_
  ProjNormType norm;
  ESpaceType space_type = space->get_type();
  switch (space_type) {
    case HERMES_H1_SPACE: norm = HERMES_H1_NORM; break;
    case HERMES_HCURL_SPACE: norm = HERMES_HCURL_NORM; break;
    case HERMES_HDIV_SPACE: norm = HERMES_HDIV_NORM; break;
    case HERMES_L2_SPACE: norm = HERMES_L2_NORM; break;
    default: error("Unknown space type in OGProjection::project_global().");
  }
  // Since the projected function is vector-valued, H1 and L2 spaces are not admissible.
  if (space_type == HERMES_H1_SPACE) error("Mismatched space and projection norm in OGProjection::project_global().");
  if (space_type == HERMES_L2_SPACE) error("Mismatched space and projection norm in OGProjection::project_global().");
  Mesh *mesh = space->get_mesh();
  if (mesh == NULL) error("Mesh is NULL in project_global().");
  Solution source_sln;
  source_sln.set_exact(mesh, source_fn);
  project_global(space, (MeshFunction*)&source_sln, target_vec, matrix_solver, norm);
};
Пример #14
0
int main(int argc, char* argv[])
{
  // Read the command-line arguments.
  if (argc != 10) error("You must provide 5 real numbers (mesh vertices) and 4 integers (poly degrees).");
  double x0 = atof(argv[1]);
  double x1 = atof(argv[2]);
  double x2 = atof(argv[3]);
  double x3 = atof(argv[4]);
  double x4 = atof(argv[5]);
  int o0 = atoi(argv[6]);
  int o1 = atoi(argv[7]);
  int o2 = atoi(argv[8]);
  int o3 = atoi(argv[9]);

  // Prepare mesh geometry.
  int nv = 10;
  double2 verts[10];
  verts[0][0] = x0; verts[0][1] = 0;
  verts[1][0] = x1; verts[1][1] = 0;
  verts[2][0] = x2; verts[2][1] = 0;
  verts[3][0] = x3; verts[3][1] = 0;
  verts[4][0] = x4; verts[4][1] = 0;
  verts[5][0] = x0; verts[5][1] = 1;
  verts[6][0] = x1; verts[6][1] = 1;
  verts[7][0] = x2; verts[7][1] = 1;
  verts[8][0] = x3; verts[8][1] = 1;
  verts[9][0] = x4; verts[9][1] = 1;
  int nt = 0;
  int4* tris = NULL;
  int nq = 4;
  int5 quads[4];
  quads[0][0] = 0; quads[0][1] = 1; quads[0][2] = 6; quads[0][3] = 5; quads[0][4] = 0;
  quads[1][0] = 1; quads[1][1] = 2; quads[1][2] = 7; quads[1][3] = 6; quads[1][4] = 0;
  quads[2][0] = 2; quads[2][1] = 3; quads[2][2] = 8; quads[2][3] = 7; quads[2][4] = 0;
  quads[3][0] = 3; quads[3][1] = 4; quads[3][2] = 9; quads[3][3] = 8; quads[3][4] = 0;
  int nm = 10;
  int3 mark[10];
  mark[0][0] = 0; mark[0][1] = 1; mark[0][2] = 1;
  mark[1][0] = 1; mark[1][1] = 2; mark[1][2] = 1;
  mark[2][0] = 2; mark[2][1] = 3; mark[2][2] = 1;
  mark[3][0] = 3; mark[3][1] = 4; mark[3][2] = 1;
  mark[4][0] = 4; mark[4][1] = 9; mark[4][2] = 1;
  mark[5][0] = 9; mark[5][1] = 8; mark[5][2] = 1;
  mark[6][0] = 8; mark[6][1] = 7; mark[6][2] = 1;
  mark[7][0] = 7; mark[7][1] = 6; mark[7][2] = 1;
  mark[8][0] = 6; mark[8][1] = 5; mark[8][2] = 1;
  mark[9][0] = 5; mark[9][1] = 0; mark[9][2] = 1;

  // Create a mesh with 10 vertices, 4 elements and 10 boundary 
  // edges from the above data.
  Mesh mesh;
  mesh.create(nv, verts, nt, tris, nq, quads, nm, mark);

  // Create an H1 space with default shapeset.
  H1Space space(&mesh, NULL, NULL, P_INIT);

  // Set element poly orders.
  space.set_element_order(0, H2D_MAKE_QUAD_ORDER(o0, 1));
  space.set_element_order(1, H2D_MAKE_QUAD_ORDER(o1, 1));
  space.set_element_order(2, H2D_MAKE_QUAD_ORDER(o2, 1));
  space.set_element_order(3, H2D_MAKE_QUAD_ORDER(o3, 1));

  // Perform orthogonal projection in the H1 norm.
  Solution sln_approx;
  ExactSolution sln_exact(&mesh, init_cond);
  project_global(&space, H2D_H1_NORM, &sln_exact, &sln_approx);

  // Calculate the error.
  double err = calc_abs_error(&sln_approx, &sln_exact, H2D_H1_NORM);
  printf("\nMesh: %g, %g, %g, %g, %g\n", x0, x1, x2, x3, x4);
  printf("Poly degrees: %d, %d, %d, %d\n", o0, o1, o2, o3);
  printf("err = %g, err_squared = %g\n\n", err, err*err);

  /*
  // Visualise the solution and mesh.
  WinGeom* sln_win_geom = new WinGeom(0, 0, 440, 350);
  ScalarView sview("Solution", sln_win_geom);
  sview.show(&sln_approx);
  WinGeom* mesh_win_geom = new WinGeom(450, 0, 400, 350);
  OrderView oview("Mesh", mesh_win_geom);
  oview.show(&space);

  // Wait for all views to be closed.
  View::wait();
  return 0;
  */
}
Пример #15
0
int main(int argc, char* argv[])
{
  // Time measurement.
  TimePeriod cpu_time;
  cpu_time.tick();

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

  // Create H1 spaces with default shapesets.
  H1Space* t_space = new H1Space(&mesh, bc_types, essential_bc_values_t, P_INIT);
  H1Space* c_space = new H1Space(&mesh, bc_types, essential_bc_values_c, P_INIT);
  int ndof = get_num_dofs(Tuple<Space *>(t_space, c_space));
  info("ndof = %d.", ndof);

  // Define initial conditions.
  Solution t_prev_time_1, c_prev_time_1, t_prev_time_2, 
           c_prev_time_2, t_iter, c_iter, t_prev_newton, c_prev_newton;
  t_prev_time_1.set_exact(&mesh, temp_ic);  
  c_prev_time_1.set_exact(&mesh, conc_ic);
  t_prev_time_2.set_exact(&mesh, temp_ic);  
  c_prev_time_2.set_exact(&mesh, conc_ic);
  t_iter.set_exact(&mesh, temp_ic);   
  c_iter.set_exact(&mesh, conc_ic);

  // Filters for the reaction rate omega and its derivatives.
  DXDYFilter omega(omega_fn, Tuple<MeshFunction*>(&t_prev_time_1, &c_prev_time_1));
  DXDYFilter omega_dt(omega_dt_fn, Tuple<MeshFunction*>(&t_prev_time_1, &c_prev_time_1));
  DXDYFilter omega_dc(omega_dc_fn, Tuple<MeshFunction*>(&t_prev_time_1, &c_prev_time_1));

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

  // Initialize weak formulation.
  WeakForm wf(2, JFNK ? true : false);
  if (!JFNK || (JFNK && PRECOND == 1))
  {
    wf.add_matrix_form(callback(newton_bilinear_form_0_0), H2D_UNSYM, H2D_ANY, &omega_dt);
    wf.add_matrix_form_surf(0, 0, callback(newton_bilinear_form_0_0_surf), 3);
    wf.add_matrix_form(1, 1, callback(newton_bilinear_form_1_1), H2D_UNSYM, H2D_ANY, &omega_dc);
    wf.add_matrix_form(0, 1, callback(newton_bilinear_form_0_1), H2D_UNSYM, H2D_ANY, &omega_dc);
    wf.add_matrix_form(1, 0, callback(newton_bilinear_form_1_0), H2D_UNSYM, H2D_ANY, &omega_dt);
  }
  else if (PRECOND == 2)
  {
    wf.add_matrix_form(0, 0, callback(precond_0_0));
    wf.add_matrix_form(1, 1, callback(precond_1_1));
  }
  wf.add_vector_form(0, callback(newton_linear_form_0), H2D_ANY, 
                     Tuple<MeshFunction*>(&t_prev_time_1, &t_prev_time_2, &omega));
  wf.add_vector_form_surf(0, callback(newton_linear_form_0_surf), 3);
  wf.add_vector_form(1, callback(newton_linear_form_1), H2D_ANY, 
                     Tuple<MeshFunction*>(&c_prev_time_1, &c_prev_time_2, &omega));

  // Project the functions "t_iter" and "c_iter" on the FE space 
  // in order to obtain initial vector for NOX. 
  info("Projecting initial solutions on the FE meshes.");
  Vector* coeff_vec = new AVector(ndof);
  project_global(Tuple<Space *>(t_space, c_space), Tuple<int>(H2D_H1_NORM, H2D_H1_NORM), 
                 Tuple<MeshFunction*>(&t_prev_time_1, &c_prev_time_1), Tuple<Solution*>(&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.
  FeProblem fep(&wf, Tuple<Space*>(t_space, c_space));

  // Initialize NOX solver and preconditioner.
  NoxSolver solver(&fep);
  MlPrecond pc("sa");
  if (PRECOND)
  {
    if (JFNK) solver.set_precond(&pc);
    else solver.set_precond("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 <= 60.0; ts++)
  {
    info("---- Time step %d, t = %g s", ts, total_time + TAU);

    cpu_time.tick(HERMES_SKIP);
    solver.set_init_sln(coeff_vec->get_c_array());
    bool solved = solver.solve();
    if (solved)
    {
      double* s = solver.get_solution_vector();
      AVector *tmp_vector = new AVector(ndof);
      tmp_vector->set_c_array(s, ndof);
      t_prev_newton.set_fe_solution(t_space, tmp_vector);
      c_prev_newton.set_fe_solution(c_space, tmp_vector);
      delete tmp_vector;

      cpu_time.tick();
      info("Number of nonlin iterations: %d (norm of residual: %g)",
          solver.get_num_iters(), solver.get_residual());
      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(HERMES_SKIP);

      // Visualization.
      DXDYFilter omega_view(omega_fn, Tuple<MeshFunction*>(&t_prev_newton, &c_prev_newton));
      rview.set_min_max_range(0.0,2.0);
      cpu_time.tick(HERMES_SKIP);
			
      // Skip visualization time.
      cpu_time.tick(HERMES_SKIP);

      // Update global time.
      total_time += TAU;

      // Saving solutions for the next time step.
      t_prev_time_2.copy(&t_prev_time_1);
      c_prev_time_2.copy(&c_prev_time_1);
      t_prev_time_1 = t_prev_newton;
      c_prev_time_1 = c_prev_newton;
    }
    else
      error("NOX failed.");

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