Esempio n. 1
0
      bool OrderPermutator::next()
      {
        if(iso_p)
        {
          if(order_h >= end_order_h || order_v >= end_order_v)
            return false;

          order_h++;
          order_v++;
        }
        else
        {
          if(order_h >= end_order_h && order_v >= end_order_v)
            return false;

          order_h++;
          if(order_h > end_order_h)
          {
            order_h = start_order_h;
            order_v++;
          }
        }

        if(tgt_quad_order != NULL)
          *tgt_quad_order = H2D_MAKE_QUAD_ORDER(order_h, order_v);
        return true;
      }
Esempio n. 2
0
 void OrderPermutator::reset()
 {
   order_h = start_order_h;
   order_v = start_order_v;
   if(tgt_quad_order != NULL)
     *tgt_quad_order = H2D_MAKE_QUAD_ORDER(order_h, order_v);
 }
Esempio n. 3
0
void RefMap::set_active_element(Element* e)
{
  if (e != element) free();

  ref_map_pss.set_active_element(e);
  quad_2d->set_mode(e->get_mode());
  num_tables = quad_2d->get_num_tables();
  assert(num_tables <= H2D_MAX_TABLES);

  if (e == element) return;
  element = e;

  reset_transform();
  update_cur_node();

  is_const = !element->is_curved() &&
             (element->is_triangle() || is_parallelogram());

  // prepare the shapes and coefficients of the reference map
  int j, k = 0;
  for (unsigned int i = 0; i < e->nvert; i++)
    indices[k++] = ref_map_shapeset.get_vertex_index(i);

  // straight-edged element
  if (e->cm == NULL)
  {
    for (unsigned int i = 0; i < e->nvert; i++)
    {
      lin_coeffs[i][0] = e->vn[i]->x;
      lin_coeffs[i][1] = e->vn[i]->y;
    }
    coeffs = lin_coeffs;
    nc = e->nvert;
  }
  else // curvilinear element - edge and bubble shapes
  {
    int o = e->cm->order;
    for (unsigned int i = 0; i < e->nvert; i++)
      for (j = 2; j <= o; j++)
        indices[k++] = ref_map_shapeset.get_edge_index(i, 0, j);

    if (e->is_quad()) o = H2D_MAKE_QUAD_ORDER(o, o);
    memcpy(indices + k, ref_map_shapeset.get_bubble_indices(o),
           ref_map_shapeset.get_num_bubbles(o) * sizeof(int));

    coeffs = e->cm->coeffs;
    nc = e->cm->nc;
  }

  // calculate the order of the inverse reference map
  if (element->iro_cache == -1 && quad_2d->get_max_order() > 1)
  {
    element->iro_cache = is_const ? 0 : calc_inv_ref_order();
  }
  inv_ref_order = element->iro_cache;

  // constant inverse reference map
  if (is_const) calc_const_inv_ref_map(); else const_jacobian = 0.0;
}
Esempio n. 4
0
    void Space<Scalar>::set_element_order_internal(int id, int order)
    {
      if(id < 0 || id >= mesh->get_max_element_id())
        throw Hermes::Exceptions::Exception("Space<Scalar>::set_element_order_internal: Invalid element id.");

      resize_tables();

      if(mesh->get_element(id)->is_quad() && get_type() != HERMES_L2_SPACE && H2D_GET_V_ORDER(order) == 0)
        order = H2D_MAKE_QUAD_ORDER(order, order);

      edata[id].order = order;
      seq = g_space_seq++;
    }
Esempio n. 5
0
// just sets the element order without enumerating dof
void Space::set_element_order_internal(int id, int order)
{
  //NOTE: We need to take into account that L2 and Hcurl may use zero orders. The latter has its own version of this method, however.
  assert_msg(mesh->get_element(id)->is_triangle() || get_type() == 3 || H2D_GET_V_ORDER(order) != 0, "Element #%d is quad but given vertical order is zero", id);
  assert_msg(mesh->get_element(id)->is_quad() || H2D_GET_V_ORDER(order) == 0, "Element #%d is triangle but vertical is not zero", id);
  if (id < 0 || id >= mesh->get_max_element_id())
    error("Invalid element id.");
  H2D_CHECK_ORDER(order);

  resize_tables();
  if (mesh->get_element(id)->is_quad() && get_type() != 3 && H2D_GET_V_ORDER(order) == 0) 
     order = H2D_MAKE_QUAD_ORDER(order, order);
  edata[id].order = order;
  seq++;
}
Esempio n. 6
0
void Space::set_element_orders(int* elem_orders_)
{
  resize_tables();
  
  Element* e;
  int counter = 0;
  for_all_elements(e, mesh)
  {
    H2D_CHECK_ORDER(elem_orders_[counter]);
    ElementData* ed = &edata[e->id];
    if (e->is_triangle())
      ed->order = elem_orders_[counter];
    else
      ed->order = H2D_MAKE_QUAD_ORDER(elem_orders_[counter], elem_orders_[counter]);
    counter++;
  }
Esempio n. 7
0
    void Space<Scalar>::set_element_orders(int* elem_orders_)
    {
      resize_tables();

      Element* e;
      int counter = 0;
      for_all_elements(e, mesh)
      {
        assert(elem_orders_[counter] >= 0 && elem_orders_[counter] <= shapeset->get_max_order());
        ElementData* ed = &edata[e->id];
        if(e->is_triangle())
          ed->order = elem_orders_[counter];
        else
          ed->order = H2D_MAKE_QUAD_ORDER(elem_orders_[counter], elem_orders_[counter]);
        counter++;
      }
Esempio n. 8
0
  Hermes::vector<Cand> create_candidates(Element* e, int quad_order)
  {
    Hermes::vector<Cand> candidates;

    // Get the current order range.
    int current_min_order, current_max_order;
    this->get_current_order_range(e, current_min_order, current_max_order);

    int order_h = H2D_GET_H_ORDER(quad_order), order_v = H2D_GET_V_ORDER(quad_order);

    if(current_max_order < std::max(order_h, order_v))
      current_max_order = std::max(order_h, order_v);

    int last_order_h = std::min(current_max_order, order_h + 1), last_order_v = std::min(current_max_order, order_v + 1);
    int last_order = H2D_MAKE_QUAD_ORDER(last_order_h, last_order_v);

    switch(strategy)
    {
    case(hORpSelectionBasedOnDOFs):
      {
        candidates.push_back(Cand(H2D_REFINEMENT_P, quad_order));
      }
    case(hXORpSelectionBasedOnError):
      {
        candidates.push_back(Cand(H2D_REFINEMENT_P, last_order));
        candidates.push_back(Cand(H2D_REFINEMENT_H, quad_order, quad_order, quad_order, quad_order));
        return candidates;
      }
      break;
    case(isoHPSelectionBasedOnDOFs):
      {
        this->cand_list = H2D_HP_ISO;
        return H1ProjBasedSelector<complex>::create_candidates(e, quad_order);
      }
      break;
    case(anisoHPSelectionBasedOnDOFs):
      {
        this->cand_list = H2D_HP_ANISO;
        return H1ProjBasedSelector<complex>::create_candidates(e, quad_order);
      }
      break;
    }
  }
Esempio n. 9
0
    void Space<Scalar>::set_uniform_order_internal(int order, int marker)
    {
      resize_tables();
      int quad_order = H2D_MAKE_QUAD_ORDER(order, order);

      Element* e;
      for_all_active_elements(e, mesh)
      {
        if(marker == HERMES_ANY_INT || e->marker == marker)
        {
          ElementData* ed = &edata[e->id];
          if(e->is_triangle())
            ed->order = order;
          else
            ed->order = quad_order;
        }
      }
      seq = g_space_seq++;
    }
Esempio n. 10
0
    void Adapt<Scalar>::homogenize_shared_mesh_orders(Mesh** meshes) 
    {
      Element* e;
      for (int i = 0; i < this->num; i++) 
      {
        for_all_active_elements(e, meshes[i]) 
        {
          int current_quad_order = this->spaces[i]->get_element_order(e->id);
          int current_order_h = H2D_GET_H_ORDER(current_quad_order), current_order_v = H2D_GET_V_ORDER(current_quad_order);

          for (int j = 0; j < this->num; j++)
            if ((j != i) && (meshes[j] == meshes[i])) // components share the mesh
            {
              int quad_order = this->spaces[j]->get_element_order(e->id);
              current_order_h = std::max(current_order_h, H2D_GET_H_ORDER(quad_order));
              current_order_v = std::max(current_order_v, H2D_GET_V_ORDER(quad_order));
            }

            this->spaces[i]->set_element_order_internal(e->id, H2D_MAKE_QUAD_ORDER(current_order_h, current_order_v));
        }
      }
Esempio n. 11
0
      bool POnlySelector<Scalar>::select_refinement(Element* element, int quad_order, Solution<Scalar>* rsln, ElementToRefine& refinement)
      {
        refinement.split = H2D_REFINEMENT_P;

        //determin max. order
        int max_allowed_order = this->max_order;
        if (this->max_order == H2DRS_DEFAULT_ORDER)
          max_allowed_order = H2DRS_MAX_ORDER;

        //calculate new order
        int order_h = H2D_GET_H_ORDER(quad_order), order_v = H2D_GET_V_ORDER(quad_order);
        int new_order_h = std::min(max_allowed_order, order_h + order_h_inc);
        int new_order_v = std::min(max_allowed_order, order_v + order_v_inc);
        if (element->is_triangle())
          refinement.p[0] = refinement.q[0] = new_order_h;
        else
          refinement.p[0] = refinement.q[0] = H2D_MAKE_QUAD_ORDER(new_order_h, new_order_v);

        //decide if successful
        if (new_order_h > order_h || new_order_v > order_v)
          return true;
        else
          return false;
      }
Esempio n. 12
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  H2DReader mloader;
  // We load the mesh on a (-1, 1)^2 domain.
  mloader.load("ref_square.mesh", &mesh);            

  // Enter boundary markers 
  // (If no markers are entered, default is a natural BC).
  BCTypes bc_types;

  // Create an H1 space with default shapeset,
  // natural BC, and linear elements.
  H1Space space(&mesh, &bc_types, P_INIT);
  // The type of element, mesh_mode = 4 means a rectangle element.
  int mesh_mode = 4;
  int ndof = Space::get_num_dofs(&space);
  printf("ndof = %d\n", ndof);
  if(ndof > FNS_NUM) error("Max number of shape functions exceeded.");

  int *fn_idx = new int [FNS_NUM];
  int m = 0;
  int order = P_INIT;

  // Get the vertex fns index.
  info("Get the vertex fns index.");
  for (int i = 0; i < mesh_mode; i++, m++)
  {
    fn_idx[m] = space.get_shapeset()->get_vertex_index(i);
    printf("m = %d, get_vertex_index(m) = %d\n",
          m, space.get_shapeset()->get_vertex_index(m));
  }
  // Get the edge fns index.
  info("Get the edge fns index.");
  for (int edge_order = 2; edge_order <= order; edge_order++)
  {
    for (int j = 0; j < mesh_mode; j++, m++)
    {
      fn_idx[m] = space.get_shapeset()->get_edge_index(j, 0, edge_order);
      printf("m = %d, get_edge_index(m) = %d\n", m, fn_idx[m]);
    }
  }
  // Get the bubble fns index.
  info("Get the bubble fns index.");
  int number_bubble = space.get_shapeset()->get_num_bubbles(H2D_MAKE_QUAD_ORDER(order, order));
  int *bubble_idx = space.get_shapeset()->get_bubble_indices(H2D_MAKE_QUAD_ORDER(order, order));
  for (int i = 0; i < number_bubble; i++, m++ )
  {
    fn_idx[m] = bubble_idx[i];
    printf("m = %d, get_bubble_index(m) = %d\n", m, fn_idx[m]);
  }
  
  // Initialize the matrix solver.
  SparseMatrix* mat = create_matrix(matrix_solver);
  Vector* rhs = create_vector(matrix_solver);
  Solver* solver = create_linear_solver(matrix_solver, mat, rhs);

  // precalc structure
  mat->prealloc(ndof);
  for (int i = 0; i < ndof; i++)
    for (int j = 0; j < ndof; j++)
      mat->pre_add_ij(i, j);
        
  mat->alloc();
  rhs->alloc(ndof);

  info("Assembling matrix ...");
  for (int i = 0; i < ndof; i++)
  {
    for (int j = 0; j < order; j++)
    {
      double x1 = -1 + (2.0/order)*j;
      double y1 = -1;
      double value = space.get_shapeset()->get_fn_value(fn_idx[i], x1, y1, 0);
      mat->add(i, j, value);
      printf("get fn[%d] value = %f  ", i, value); 
      printf("x1 = %f, y1 = %f\n", x1, y1);
    }
    for (int j = 0; j < order; j++)
    {
      double y2 = -1 + (2.0/order)*j;;
      double x2 = 1;
      double value = space.get_shapeset()->get_fn_value(fn_idx[i], x2, y2, 0);
      mat->add(i, j+order, value);
      printf("get fn[%d] value = %f  ", i, value); 
      printf("x2 = %f, y2 = %f\n", x2, y2);
    }
    for (int j = 0; j < order; j++)
    {
      double x3 = 1 + (-1.0)*(2.0/order)*j;
      double y3 = 1;
      double value = space.get_shapeset()->get_fn_value(fn_idx[i], x3, y3, 0);
      mat->add(i, j+2*order, value);
      printf("get fn[%d] value = %f  ", i, value); 
      printf("x3 = %f, y3 = %f\n", x3, y3);
    }
    for (int j = 0; j < order; j++)
    {
      double x4 = -1;
      double y4 = 1 + (-1.0)*(2.0/order)*j;
      double value = space.get_shapeset()->get_fn_value(fn_idx[i], x4, y4, 0);
      mat->add(i, j+3*order, value);
      printf("get fn[%d] value = %f  ", i, value); 
      printf("x4 = %f, y4 = %f\n", x4, y4);
    }
  }

  int bubble = 0;
  for (int i = order*4; i < ndof; i++)
  {
      double x = 0.0 + (1.0/number_bubble)*bubble;
      double y = 0.0 + (1.0/number_bubble)*bubble;
      double value = space.get_shapeset()->get_fn_value(fn_idx[i], x, y, 0);
      mat->add(i, i, value);
      printf("get fn[%d] value = %f  ", i, value); 
      printf("x = %f, y = %f\n", x, y);
      bubble++;
  }

  printf("Adding the rhs\n");
  for (int i = 0; i < ndof; i++)
  {
    rhs->add(i, 0.0);
  }

  // Initialize the solution.
  Solution sln;
   
  info("Solution ...");
  if(solver->solve())
    Solution::vector_to_solution(solver->get_solution(), &space, &sln);
  else
    error ("Matrix solver failed.\n");

  for (int i = 0; i < ndof; i++)
  {
    // Get the value of the matrix solution by calling Vector::get().
    if (rhs->get(i) >= EPS)
    {
      printf("Shape functions are not linearly independent\n");
      return ERR_FAILURE; 
    }
  }
  printf("Success!\n");
 
  // Clean up.
  delete solver;
  delete mat;
  delete rhs;
  delete [] fn_idx;
  return ERR_SUCCESS;
}
Esempio n. 13
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;
  */
}
Esempio n. 14
0
 int OrderPermutator::get_end_quad_order() const
 {
   return H2D_MAKE_QUAD_ORDER(end_order_h, end_order_v);
 }
Esempio n. 15
0
 int OrderPermutator::get_start_quad_order() const
 {
   return H2D_MAKE_QUAD_ORDER(start_order_h, start_order_v);
 }
Esempio n. 16
0
void L2OrthoHP::calc_ortho_base()
{
  int i, j, k, l, m, ii, nb, np, o, r;
  int n, idx[121];

  H1Shapeset shapeset;

  // allocate the orthonormal base tables - these are simply the values of the
  // orthonormal functions in integration points; we store the basic functions
  // plus four son cut-outs of them (i.e. 5 times)
  for (i = 0; i < 9; i++)
  {
    if ((i < 4) || (i >= 8))
      obase[0][i] = new_matrix<double3>(66, 79); // tri
    obase[1][i] = new_matrix<double3>(121, 121); // quad
  }

  // repeat for triangles and quads
  for (m = 0; m <= 1; m++)
  {
    shapeset.set_mode(m);

    // obtain a list of all shape functions up to the order 10, from lowest to highest order
    n = 0;
    int nv = m ? 4 : 3;
    int num_sons = m ? 8 : 4;
    for (i = 0; i < nv; i++)
      idx[n++] = shapeset.get_vertex_index(i);
    basecnt[m][0] = 0;
    basecnt[m][1] = n;

    for (i = 2; i <= 10; i++)
    {
      for (j = 0; j < nv; j++)
        idx[n++] = shapeset.get_edge_index(j, 0, i);

      ii = m ? H2D_MAKE_QUAD_ORDER(i, i) : i;
      nb = shapeset.get_num_bubbles(ii);
      int* bub = shapeset.get_bubble_indices(ii);
      for (j = 0; j < nb; j++)
      {
        o = shapeset.get_order(bub[j]);
        if (H2D_GET_H_ORDER(o) == i || H2D_GET_V_ORDER(o) == i)
          idx[n++] = bub[j];
      }
      basecnt[m][i] = n;
    }

    // obtain their values for integration rule 20
    g_quad_2d_std.set_mode(m);
    np = g_quad_2d_std.get_num_points(20);
    double3* pt = g_quad_2d_std.get_points(20);

    for (i = 0; i < n; i++)
      for (j = 0; j < np; j++)
        for (k = 0; k < 3; k++)
          obase[m][8][i][j][k] = shapeset.get_value(k, idx[i], pt[j][0], pt[j][1], 0);

    for (l = 0; l < num_sons; l++)
    {
      Trf* tr = (m ? quad_trf : tri_trf) + l;
      for (i = 0; i < n; i++)
        for (j = 0; j < np; j++)
        {
          double x = tr->m[0]*pt[j][0] + tr->t[0],
                 y = tr->m[1]*pt[j][1] + tr->t[1];
          for (k = 0; k < 3; k++)
            obase[m][l][i][j][k] = shapeset.get_value(k, idx[i], x, y, 0);
        }
    }

    // orthonormalize the basis functions
    for (i = 0; i < n; i++)
    {
      for (j = 0; j < i; j++)
      {
        double prod = 0.0;
        for (k = 0; k < np; k++) {
          double sum = 0.0;
          for (r = 0; r < 1; r++)
            sum += obase[m][8][i][k][r] * obase[m][8][j][k][r];
          prod += pt[k][2] * sum;
        }

        for (l = 0; l < 9; l++)
          if (m || l < 4 || l >= 8)
            for (k = 0; k < np; k++)
              for (r = 0; r < 1; r++)
                obase[m][l][i][k][r] -= prod * obase[m][l][j][k][r];
      }

      double norm = 0.0;
      for (k = 0; k < np; k++) {
        double sum = 0.0;
        for (r = 0; r < 1; r++)
          sum += sqr(obase[m][8][i][k][r]);
        norm += pt[k][2] * sum;
      }
      norm = sqrt(norm);

      for (l = 0; l < 9; l++)
        if (m || l < 4 || l >= 8)
          for (k = 0; k < np; k++)
            for (r = 0; r < 1; r++)
              obase[m][l][i][k][r] /= norm;
    }

    // check the orthonormal base
/*    if (m) {
    for (i = 0; i < n; i++)
      for (j = 0; j < n; j++)
      {
        double check = 0.0;
        for(int son = 4; son < 6; son++ )
          for (k = 0; k < np; k++)
            check += pt[k][2] * (obase[m][son][i][k][0] * obase[m][son][j][k][0] +
                                 obase[m][son][i][k][1] * obase[m][son][j][k][1] +
                                 obase[m][son][i][k][2] * obase[m][son][j][k][2]);
        check *= 0.5;
        if ((i == j && fabs(check - 1.0) > 1e-8) || (i != j && fabs(check) > 1e-8))
          warn("Not orthonormal: base %d times base %d = %g", i, j , check);
      }
    }*/
  }
  obase_ready = true;
}
Esempio n. 17
0
int main(int argc, char* argv[])
{
  // Initialize the library's global functions.
  Hermes2D hermes2D;

  // 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, 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;
  CustomExactSolution sln_exact(&mesh, K);
  OGProjection::project_global(&space, &sln_exact, &sln_approx);

  // Calculate the error.
  double err = hermes2D.calc_abs_error(&sln_approx, &sln_exact, HERMES_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);

  // Mesh: 0, 1, 2, 3, 4
  // Poly degrees: 10, 10, 10, 10
  if ((err - 0.04381394) < 1E-6) {
    printf("Success!\n");
    return ERR_SUCCESS;
  }
  else {
    printf("Failure!\n");
    return ERR_FAILURE;
  }
}
Esempio n. 18
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);

    // Enter boundary markers.
    BCTypes bc_types;
    bc_types.add_bc_neumann(Hermes::Tuple<int>(BDY_LEFT_RIGHT, BDY_TOP_BOTTOM));

    // Create an H1 space with default shapeset.
    H1Space space(&mesh, &bc_types, 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);
    OGProjection::project_global(&space, &sln_exact, &sln_approx);

    // Calculate the error.
    double err = calc_abs_error(&sln_approx, &sln_exact, HERMES_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);

    // Mesh: 0, 1, 2, 3, 4
    // Poly degrees: 10, 10, 10, 10
    // err = 2.11454e-09, err_squared = 4.47128e-18
    if ((err - 2.11454e-09) < 1E-6) {      // err was 2.11454e-09 at the time this test was created
        printf("Success!\n");
        return ERR_SUCCESS;
    }
    else {
        printf("Failure!\n");
        return ERR_FAILURE;
    }
}
Esempio n. 19
0
void RefSystem::global_refinement()
{
    // after this, meshes and spaces are NULL
    this->free_spaces();

    // create new meshes and spaces
    this->meshes = new Mesh*[this->wf->neq];
    this->spaces = new Space*[this->wf->neq];
    this->sp_seq = new int[this->wf->neq];

    int i, j;
    // copy meshes from the coarse problem and refine them
    for (i = 0; i < this->wf->neq; i++)
    {
        Mesh* mesh = base->spaces[i]->get_mesh();

        // check if we already have the same mesh
        for (j = 0; j < i; j++)
            if (mesh->get_seq() == base->spaces[j]->get_mesh()->get_seq())
                break;

        if (j < i) // yes
        {
            meshes[i] = meshes[j];
        }
        else // no, copy and refine the coarse one
        {
            Mesh* rmesh = new Mesh;
            rmesh->copy(mesh);
            if (refinement ==  1) rmesh->refine_all_elements();
            if (refinement == -1) rmesh->unrefine_all_elements();
            this->meshes[i] = rmesh;
        }
    }

    // duplicate spaces from the coarse problem, assign reference orders and dofs
    int ndof = 0;
    for (i = 0; i < this->wf->neq; i++)
    {
        this->spaces[i] = this->base->spaces[i]->dup(this->meshes[i]);

        if (refinement == -1)
        {
            Element* re;
            for_all_active_elements(re, meshes[i])
            {
                Mesh* mesh = this->base->spaces[i]->get_mesh();
                Element* e = mesh->get_element(re->id);
                int max_order_h = 0, max_order_v = 0;
                if (e->active) {
                    int quad_order = base->spaces[i]->get_element_order(e->id);
                    max_order_h = H2D_GET_H_ORDER(quad_order);
                    max_order_v = H2D_GET_V_ORDER(quad_order);
                }
                else
                {   //find maximum order of sons
                    for (int son = 0; son < 4; son++)
                    {
                        if (e->sons[son] != NULL)
                        {
                            int quad_order = base->spaces[i]->get_element_order(e->sons[son]->id);
                            max_order_h = std::max(max_order_h, H2D_GET_H_ORDER(quad_order));
                            max_order_v = std::max(max_order_v, H2D_GET_V_ORDER(quad_order));
                        }
                    }
                }

                //increase order and set it to element
                max_order_h = std::max(1, max_order_h + order_increase);
                if (re->is_triangle())
                    max_order_v = 0;
                else
                    max_order_v = std::max(1, max_order_v + order_increase);
                spaces[i]->set_element_order_internal(re->id, H2D_MAKE_QUAD_ORDER(max_order_h, max_order_v));
            }
        }
Esempio n. 20
0
  bool select_refinement(Element* element, int order, MeshFunction<complex>* rsln, ElementToRefine& refinement)
  {
    switch(strategy)
    {
    case(noSelectionH):
      {
        refinement.split = H2D_REFINEMENT_H;
        refinement.best_refinement_polynomial_order_type[H2D_REFINEMENT_H][0] = 
          refinement.best_refinement_polynomial_order_type[H2D_REFINEMENT_H][1] = 
          refinement.best_refinement_polynomial_order_type[H2D_REFINEMENT_H][2] = 
          refinement.best_refinement_polynomial_order_type[H2D_REFINEMENT_H][3] = 
          order;
        ElementToRefine::copy_orders(refinement.refinement_polynomial_order, refinement.best_refinement_polynomial_order_type[H2D_REFINEMENT_H]);
        return true;
      }
      break;
    case(noSelectionHP):
      {
        int max_allowed_order = this->max_order;
        if(this->max_order == H2DRS_DEFAULT_ORDER)
          max_allowed_order = H2DRS_MAX_ORDER;
        int order_h = H2D_GET_H_ORDER(order), order_v = H2D_GET_V_ORDER(order);
        int increased_order_h = std::min(max_allowed_order, order_h + 1), increased_order_v = std::min(max_allowed_order, order_v + 1);
        int increased_order;
        if(element->is_triangle())
          increased_order = refinement.best_refinement_polynomial_order_type[H2D_REFINEMENT_H][0] = H2D_MAKE_QUAD_ORDER(increased_order_h, increased_order_h);
        else
          increased_order = refinement.best_refinement_polynomial_order_type[H2D_REFINEMENT_H][0] = H2D_MAKE_QUAD_ORDER(increased_order_h, increased_order_v);

        refinement.split = H2D_REFINEMENT_H;
        refinement.best_refinement_polynomial_order_type[H2D_REFINEMENT_H][0] = 
          refinement.best_refinement_polynomial_order_type[H2D_REFINEMENT_H][1] = 
          refinement.best_refinement_polynomial_order_type[H2D_REFINEMENT_H][2] = 
          refinement.best_refinement_polynomial_order_type[H2D_REFINEMENT_H][3] = 
          increased_order;
        ElementToRefine::copy_orders(refinement.refinement_polynomial_order, refinement.best_refinement_polynomial_order_type[H2D_REFINEMENT_H]);
        return true;
      }
      case(hXORpSelectionBasedOnError):
      {
        //make an uniform order in a case of a triangle
        int order_h = H2D_GET_H_ORDER(order), order_v = H2D_GET_V_ORDER(order);

        int current_min_order, current_max_order;
        this->get_current_order_range(element, current_min_order, current_max_order);

        if(current_max_order < std::max(order_h, order_v))
          current_max_order = std::max(order_h, order_v);

        int last_order_h = std::min(current_max_order, order_h + 1), last_order_v = std::min(current_max_order, order_v + 1);
        int last_order = H2D_MAKE_QUAD_ORDER(last_order_h, last_order_v);

        //build candidates.
        Hermes::vector<Cand> candidates;
        candidates.push_back(Cand(H2D_REFINEMENT_P, last_order));
        candidates.push_back(Cand(H2D_REFINEMENT_H, order, order, order, order));
        
        this->evaluate_cands_error(candidates, element, rsln);
        
        Cand* best_candidate = (candidates[0].error < candidates[1].error) ? &candidates[0] : &candidates[1];
        Cand* best_candidates_specific_type[4];
        best_candidates_specific_type[H2D_REFINEMENT_P] = &candidates[0];
        best_candidates_specific_type[H2D_REFINEMENT_H] = &candidates[1];
        best_candidates_specific_type[2] = NULL;
        best_candidates_specific_type[3] = NULL;

        //copy result to output
        refinement.split = best_candidate->split;
        ElementToRefine::copy_orders(refinement.refinement_polynomial_order, best_candidate->p);
        for(int i = 0; i < 4; i++)
          if(best_candidates_specific_type[i] != NULL)
            ElementToRefine::copy_orders(refinement.best_refinement_polynomial_order_type[i], best_candidates_specific_type[i]->p);

        ElementToRefine::copy_errors(refinement.errors, best_candidate->errors);

        //modify orders in a case of a triangle such that order_v is zero
        if(element->is_triangle())
          for(int i = 0; i < H2D_MAX_ELEMENT_SONS; i++)
            refinement.refinement_polynomial_order[i] = H2D_MAKE_QUAD_ORDER(H2D_GET_H_ORDER(refinement.refinement_polynomial_order[i]), 0);

        return true;
      }
    default:
      H1ProjBasedSelector<complex>::select_refinement(element, order, rsln, refinement);
      return true;
      break;
    }
  }
      void L2ProjBasedSelector<Scalar>::create_candidates(Element* e, int quad_order, int max_ha_quad_order, int max_p_quad_order) 
      {
        int order_h = H2D_GET_H_ORDER(quad_order), order_v = H2D_GET_V_ORDER(quad_order);
        int max_p_order_h = H2D_GET_H_ORDER(max_p_quad_order), max_p_order_v = H2D_GET_V_ORDER(max_p_quad_order);
        int max_ha_order_h = H2D_GET_H_ORDER(max_ha_quad_order), max_ha_order_v = H2D_GET_V_ORDER(max_ha_quad_order);
        bool tri = e->is_triangle();

        //clear list of candidates
        this->candidates.clear();
        if (this->candidates.capacity() < H2DRS_ASSUMED_MAX_CANDS)
          this->candidates.reserve(H2DRS_ASSUMED_MAX_CANDS);

        //generate all P-candidates (start from intention of generating all possible candidates
        //and restrict it according to the given adapt-type)
        bool iso_p = false;
        int start_quad_order = quad_order;
        int last_quad_order = H2D_MAKE_QUAD_ORDER(std::min(max_p_order_h, order_h+H2DRS_MAX_ORDER_INC), std::min(max_p_order_v, order_v+H2DRS_MAX_ORDER_INC));
        switch(this->cand_list) 
        {
        case H2D_H_ISO:
        case H2D_H_ANISO: last_quad_order = start_quad_order; break; //no P-candidates except the original candidate
        case H2D_P_ISO:
        case H2D_HP_ISO:
        case H2D_HP_ANISO_H: iso_p = true; break; //iso change of orders
        }
        this->append_candidates_split(quad_order, last_quad_order, H2D_REFINEMENT_P, tri || iso_p);

        //generate all H-candidates
        iso_p = false;
        int start_order_h = std::max(this->current_min_order, (order_h+1) / 2), start_order_v = std::max(this->current_min_order, (order_v+1) / 2);
        start_quad_order = H2D_MAKE_QUAD_ORDER(start_order_h, start_order_v);
        last_quad_order = H2D_MAKE_QUAD_ORDER(std::min(max_ha_order_h, start_order_h + H2DRS_MAX_ORDER_INC), std::min(max_ha_order_v, start_order_v + H2DRS_MAX_ORDER_INC));
        switch(this->cand_list) 
        {
        case H2D_H_ISO:
        case H2D_H_ANISO:
          last_quad_order = start_quad_order = quad_order; break; //no only one candidate will be created
        case H2D_P_ISO:
        case H2D_P_ANISO: last_quad_order = -1; break; //no H-candidate will be generated
        case H2D_HP_ISO:
        case H2D_HP_ANISO_H: iso_p = true; break; //iso change of orders
        }
        this->append_candidates_split(start_quad_order, last_quad_order, H2D_REFINEMENT_H, tri || iso_p);

        //generate all ANISO-candidates
        if (!tri && e->iro_cache < 8 /** \todo Find and why is iro_cache compared with the number 8. What does the number 8 mean? */
          && (this->cand_list == H2D_H_ANISO || this->cand_list == H2D_HP_ANISO_H || this->cand_list == H2D_HP_ANISO)) 
        {
          iso_p = false;
          int start_quad_order_hz = H2D_MAKE_QUAD_ORDER(order_h, std::max(this->current_min_order, (order_v+1) / 2));
          int last_quad_order_hz = H2D_MAKE_QUAD_ORDER(std::min(max_ha_order_h, order_h+H2DRS_MAX_ORDER_INC), std::min(order_v, H2D_GET_V_ORDER(start_quad_order)+H2DRS_MAX_ORDER_INC));
          int start_quad_order_vt = H2D_MAKE_QUAD_ORDER(std::max(this->current_min_order, (order_h+1) / 2), order_v);
          int last_quad_order_vt = H2D_MAKE_QUAD_ORDER(std::min(order_h, H2D_GET_H_ORDER(start_quad_order)+H2DRS_MAX_ORDER_INC), std::min(max_ha_order_v, order_v+H2DRS_MAX_ORDER_INC));
          switch(this->cand_list) 
          {
          case H2D_H_ANISO:
            last_quad_order_hz = start_quad_order_hz = quad_order;
            last_quad_order_vt = start_quad_order_vt = quad_order;
            break; //only one candidate will be created
          case H2D_HP_ANISO_H: iso_p = true; break; //iso change of orders
          }
          if (iso_p) { //make orders uniform: take mininmum order since nonuniformity is caused by different handling of orders along directions
            int order = std::min(H2D_GET_H_ORDER(start_quad_order_hz), H2D_GET_V_ORDER(start_quad_order_hz));
            start_quad_order_hz = H2D_MAKE_QUAD_ORDER(order, order);
            order = std::min(H2D_GET_H_ORDER(start_quad_order_vt), H2D_GET_V_ORDER(start_quad_order_vt));
            start_quad_order_vt = H2D_MAKE_QUAD_ORDER(order, order);

            order = std::min(H2D_GET_H_ORDER(last_quad_order_hz), H2D_GET_V_ORDER(last_quad_order_hz));
            last_quad_order_hz = H2D_MAKE_QUAD_ORDER(order, order);
            order = std::min(H2D_GET_H_ORDER(last_quad_order_vt), H2D_GET_V_ORDER(last_quad_order_vt));
            last_quad_order_vt = H2D_MAKE_QUAD_ORDER(order, order);
          }
          this->append_candidates_split(start_quad_order_hz, last_quad_order_hz, H2D_REFINEMENT_ANISO_H, iso_p);
          this->append_candidates_split(start_quad_order_vt, last_quad_order_vt, H2D_REFINEMENT_ANISO_V, iso_p);
        }
      }
Esempio n. 22
0
 unsigned short OrderPermutator::get_quad_order() const
 {
   return H2D_MAKE_QUAD_ORDER(order_h, order_v);
 }