示例#1
0
文件: main.cpp 项目: MathPhys/hermes
//------------------------------------------------------------------------------
// Compute marked boundary length 
//
double CalculateBoundaryLength(Mesh* mesh, int bdryMarker)
{
  // Variables declaration.
  Element* e;
  double length = 0;
  RefMap rm;
  rm.set_quad_2d(&g_quad_2d_std);
  Quad2D * quad = rm.get_quad_2d();
  int points_location;
  double3* points;
  int np;
  double3* tangents;

  // Loop through all boundary faces of all active elements.
  for_all_active_elements(e, mesh) {
    for(int edge = 0; edge < e->nvert; ++edge) {
      if ((e->en[edge]->bnd) && (e->en[edge]->marker == bdryMarker)) {
        rm.set_active_element(e);
        points_location = quad->get_edge_points(edge);
        points = quad->get_points(points_location);
        np = quad->get_num_points(points_location);
        tangents = rm.get_tangent(edge, points_location);
        for(int i = 0; i < np; i++) {
          // Weights sum up to two on every edge, therefore the division by two must be present.
          length +=  0.5 * points[i][2] * tangents[i][2];
        }
      }
    }
  }
  return length;
} // end of CalculateBoundaryLength()
示例#2
0
void DiscreteProblem::precalc_equi_coefs()
{
  int i, m;
  memset(equi, 0, sizeof(double) * ndofs);
  verbose("Precalculating equilibration coefficients...");

  RefMap refmap;
  AsmList al;
  Element* e;

  for (m = 0; m < neq; m++)
  {
    PrecalcShapeset* fu = pss[m];
    BiForm* bf = biform[m] + m;
    Mesh* mesh = spaces[m]->get_mesh();

    for_all_active_elements(e, mesh)
    {
      update_limit_table(e->get_mode());
      fu->set_active_element(e);
      refmap.set_active_element(e);

      spaces[m]->get_element_assembly_list(e, &al);
      for (i = 0; i < al.cnt; i++)
      {
        if (al.dof[i] < 0) continue;
        fu->set_active_shape(al.idx[i]);
        scalar sy = 0.0, un = 0.0;
        if (bf->unsym) un = bf->unsym(fu, fu, &refmap, &refmap);
        if (bf->sym)   sy = bf->sym  (fu, fu, &refmap, &refmap);
        #ifndef COMPLEX
        equi[al.dof[i]] += (sy + un) * sqr(al.coef[i]);
        #else
        equi[al.dof[i]] += 0;//std::norm(sy + un) * sqr(al.coef[i]);
        #endif
      }
    }
  }
示例#3
0
文件: orderizer.cpp 项目: HPeX/hermes
      void Orderizer::process_space(SpaceSharedPtr<Scalar> space, bool show_edge_orders)
      {
        // sanity check
        if (space == nullptr)
          throw Hermes::Exceptions::Exception("Space is nullptr in Orderizer:process_space().");

        if (!space->is_up_to_date())
          throw Hermes::Exceptions::Exception("The space is not up to date.");

        MeshSharedPtr mesh = space->get_mesh();

        // Reallocate.
        this->reallocate(mesh);

        RefMap refmap;

        int oo, o[6];

        // make a mesh illustrating the distribution of polynomial orders over the space
        Element* e;
        for_all_active_elements(e, mesh)
        {
          oo = o[4] = o[5] = space->get_element_order(e->id);
          if (show_edge_orders)
          for (unsigned int k = 0; k < e->get_nvert(); k++)
            o[k] = space->get_edge_order(e, k);
          else if (e->is_curved())
          {
            if (e->is_triangle())
            for (unsigned int k = 0; k < e->get_nvert(); k++)
              o[k] = oo;
            else
            for (unsigned int k = 0; k < e->get_nvert(); k++)
              o[k] = H2D_GET_H_ORDER(oo);
          }

          double3* pt;
          int np;
          double* x;
          double* y;
          if (show_edge_orders || e->is_curved())
          {
            refmap.set_quad_2d(&quad_ord);
            refmap.set_active_element(e);
            x = refmap.get_phys_x(1);
            y = refmap.get_phys_y(1);

            pt = quad_ord.get_points(1, e->get_mode());
            np = quad_ord.get_num_points(1, e->get_mode());
          }
          else
          {
            refmap.set_quad_2d(&quad_ord_simple);
            refmap.set_active_element(e);
            x = refmap.get_phys_x(1);
            y = refmap.get_phys_y(1);

            pt = quad_ord_simple.get_points(1, e->get_mode());
            np = quad_ord_simple.get_num_points(1, e->get_mode());
          }

          int id[80];
          assert(np <= 80);

          int mode = e->get_mode();
          if (e->is_quad())
          {
            o[4] = H2D_GET_H_ORDER(oo);
            o[5] = H2D_GET_V_ORDER(oo);
          }
          if (show_edge_orders || e->is_curved())
          {
            make_vert(lvert[label_count], x[0], y[0], o[4]);

            for (int i = 1; i < np; i++)
              make_vert(id[i - 1], x[i], y[i], o[(int)pt[i][2]]);

            for (int i = 0; i < num_elem[mode][1]; i++)
              this->add_triangle(id[ord_elem[mode][1][i][0]], id[ord_elem[mode][1][i][1]], id[ord_elem[mode][1][i][2]], e->marker);

            for (int i = 0; i < num_edge[mode][1]; i++)
            {
              if (e->en[ord_edge[mode][1][i][2]]->bnd || (y[ord_edge[mode][1][i][0] + 1] < y[ord_edge[mode][1][i][1] + 1]) ||
                ((y[ord_edge[mode][1][i][0] + 1] == y[ord_edge[mode][1][i][1] + 1]) &&
                (x[ord_edge[mode][1][i][0] + 1] < x[ord_edge[mode][1][i][1] + 1])))
              {
                add_edge(id[ord_edge[mode][1][i][0]], id[ord_edge[mode][1][i][1]], e->en[ord_edge[mode][1][i][2]]->marker);
              }
            }
          }
          else
          {
            make_vert(lvert[label_count], x[0], y[0], o[4]);

            for (int i = 1; i < np; i++)
              make_vert(id[i - 1], x[i], y[i], o[(int)pt[i][2]]);

            for (int i = 0; i < num_elem_simple[mode][1]; i++)
              this->add_triangle(id[ord_elem_simple[mode][1][i][0]], id[ord_elem_simple[mode][1][i][1]], id[ord_elem_simple[mode][1][i][2]], e->marker);

            for (int i = 0; i < num_edge_simple[mode][1]; i++)
              add_edge(id[ord_edge_simple[mode][1][i][0]], id[ord_edge_simple[mode][1][i][1]], e->en[ord_edge_simple[mode][1][i][2]]->marker);
          }

          double xmin = 1e100, ymin = 1e100, xmax = -1e100, ymax = -1e100;
          for (unsigned int k = 0; k < e->get_nvert(); k++)
          {
            if (e->vn[k]->x < xmin) xmin = e->vn[k]->x;
            if (e->vn[k]->x > xmax) xmax = e->vn[k]->x;
            if (e->vn[k]->y < ymin) ymin = e->vn[k]->y;
            if (e->vn[k]->y > ymax) ymax = e->vn[k]->y;
          }
          lbox[label_count][0] = xmax - xmin;
          lbox[label_count][1] = ymax - ymin;
          ltext[label_count++] = labels[o[4]][o[5]];
        }
示例#4
0
void Orderizer::process_solution(Space* space)
{
  // sanity check
  if (space == NULL) error("Space is NULL in Orderizer:process_solution().");

  if (!space->is_up_to_date())
    error("The space is not up to date.");

  int type = 1;

  nv = nt = ne = nl = 0;
  del_slot = -1;

  // estimate the required number of vertices and triangles
  Mesh* mesh = space->get_mesh();
  if (mesh == NULL) {
    error("Mesh is NULL in Orderizer:process_solution().");
  }
  int nn = mesh->get_num_active_elements();
  int ev = 77 * nn, et = 64 * nn, ee = 16 * nn, el = nn + 10;

  // reuse or allocate vertex, triangle and edge arrays
  lin_init_array(verts, double3, cv, ev);
  lin_init_array(tris, int3, ct, et);
  lin_init_array(edges, int3, ce, ee);
  lin_init_array(lvert, int, cl1, el);
  lin_init_array(ltext, char*, cl2, el);
  lin_init_array(lbox, double2, cl3, el);
  info = NULL;

  int oo, o[6];

  RefMap refmap;
  refmap.set_quad_2d(&quad_ord);

  // make a mesh illustrating the distribution of polynomial orders over the space
  Element* e;
  for_all_active_elements(e, mesh)
  {
    oo = o[4] = o[5] = space->get_element_order(e->id);
    for (unsigned int k = 0; k < e->nvert; k++)
      o[k] = space->get_edge_order(e, k);

    refmap.set_active_element(e);
    double* x = refmap.get_phys_x(type);
    double* y = refmap.get_phys_y(type);

    double3* pt = quad_ord.get_points(type);
    int np = quad_ord.get_num_points(type);
    int id[80];
    assert(np <= 80);

    #define make_vert(index, x, y, val) \
      { (index) = add_vertex(); \
      verts[index][0] = (x); \
      verts[index][1] = (y); \
      verts[index][2] = (val); }

    int mode = e->get_mode();
    if (e->is_quad())
    {
      o[4] = H2D_GET_H_ORDER(oo);
      o[5] = H2D_GET_V_ORDER(oo);
    }
    make_vert(lvert[nl], x[0], y[0], o[4]);

    for (int i = 1; i < np; i++)
      make_vert(id[i-1], x[i], y[i], o[(int) pt[i][2]]);

    for (int i = 0; i < num_elem[mode][type]; i++)
      add_triangle(id[ord_elem[mode][type][i][0]], id[ord_elem[mode][type][i][1]], id[ord_elem[mode][type][i][2]]);

    for (int i = 0; i < num_edge[mode][type]; i++)
    {
      if (e->en[ord_edge[mode][type][i][2]]->bnd || (y[ord_edge[mode][type][i][0] + 1] < y[ord_edge[mode][type][i][1] + 1]) ||
          ((y[ord_edge[mode][type][i][0] + 1] == y[ord_edge[mode][type][i][1] + 1]) &&
           (x[ord_edge[mode][type][i][0] + 1] <  x[ord_edge[mode][type][i][1] + 1])))
      {
        add_edge(id[ord_edge[mode][type][i][0]], id[ord_edge[mode][type][i][1]], 0);
      }
    }

    double xmin = 1e100, ymin = 1e100, xmax = -1e100, ymax = -1e100;
    for (unsigned int k = 0; k < e->nvert; k++)
    {
      if (e->vn[k]->x < xmin) xmin = e->vn[k]->x;
      if (e->vn[k]->x > xmax) xmax = e->vn[k]->x;
      if (e->vn[k]->y < ymin) ymin = e->vn[k]->y;
      if (e->vn[k]->y > ymax) ymax = e->vn[k]->y;
    }
    lbox[nl][0] = xmax - xmin;
    lbox[nl][1] = ymax - ymin;
    ltext[nl++] = labels[o[4]][o[5]];
  }