Exemplo n.º 1
0
/* given two profiles (layers that have been reduced to just their levels),
 * take the union, i.e. combine them, taking the finer layers */
static void
p6est_profile_union (sc_array_t * a, sc_array_t * b, sc_array_t * c)
{
  size_t              az, bz, na;
  P4EST_ASSERT (SC_ARRAY_IS_OWNER (c));
  P4EST_ASSERT (a->elem_size == sizeof (int8_t));
  P4EST_ASSERT (b->elem_size == sizeof (int8_t));
  P4EST_ASSERT (c->elem_size == sizeof (int8_t));
  int8_t              al, bl, finel, *cc;
  p4est_qcoord_t      finesize, coarsesize;
  sc_array_t         *finer;
  size_t             *fineincr;

  sc_array_truncate (c);
  az = 0;
  bz = 0;
  na = a->elem_count;
  while (az < na) {
    P4EST_ASSERT (bz < b->elem_count);

    cc = (int8_t *) sc_array_push (c);

    al = *((int8_t *) sc_array_index (a, az++));
    bl = *((int8_t *) sc_array_index (b, bz++));
    if (al == bl) {
      *cc = al;
      continue;
    }
    else if (al > bl) {
      finer = a;
      finesize = P4EST_QUADRANT_LEN (al);
      fineincr = &az;
      finel = al;
      coarsesize = P4EST_QUADRANT_LEN (bl);
    }
    else {
      finer = b;
      finesize = P4EST_QUADRANT_LEN (bl);
      fineincr = &bz;
      finel = bl;
      coarsesize = P4EST_QUADRANT_LEN (al);
    }

    P4EST_ASSERT (finesize < coarsesize);

    do {
      *cc = finel;
      cc = (int8_t *) sc_array_push (c);
      finel = *((int8_t *) sc_array_index (finer, (*fineincr)++));
      finesize += P4EST_QUADRANT_LEN (finel);
    } while (finesize < coarsesize);
    P4EST_ASSERT (finesize == coarsesize);
    *cc = finel;
  }
}
Exemplo n.º 2
0
static              p4est_locidx_t
mesh_corner_allocate (p4est_mesh_t * mesh, p4est_locidx_t clen,
                      p4est_locidx_t ** pcquad, int8_t ** pccorner)
{
  p4est_locidx_t      cornerid, cstart, cend;

  P4EST_ASSERT (clen > 0);
  P4EST_ASSERT (mesh->corner_offset->elem_count ==
                (size_t) (mesh->local_num_corners + 1));

  cornerid = mesh->local_num_corners++;
  cstart = *(p4est_locidx_t *) sc_array_index (mesh->corner_offset, cornerid);
  cend = cstart + clen;
  *(p4est_locidx_t *) sc_array_push (mesh->corner_offset) = cend;

  P4EST_ASSERT (mesh->corner_offset->elem_count ==
                (size_t) (mesh->local_num_corners + 1));

  P4EST_ASSERT (mesh->corner_quad->elem_count == (size_t) cstart);
  *pcquad = (p4est_locidx_t *) sc_array_push_count (mesh->corner_quad, clen);
  P4EST_ASSERT (mesh->corner_quad->elem_count == (size_t) cend);

  P4EST_ASSERT (mesh->corner_corner->elem_count == (size_t) cstart);
  *pccorner = (int8_t *) sc_array_push_count (mesh->corner_corner, clen);
  P4EST_ASSERT (mesh->corner_corner->elem_count == (size_t) cend);

  return cornerid;
}
Exemplo n.º 3
0
static void
p6est_profile_balance_self_one_pass (sc_array_t * read, sc_array_t * write)
{
  int                 stackcount;
  int8_t              n, newn, p, l;
  int8_t             *wc;
  size_t              count = read->elem_count;
  size_t              zy;

  P4EST_ASSERT (SC_ARRAY_IS_OWNER (write));
  P4EST_ASSERT (read->elem_size == sizeof (int8_t));
  P4EST_ASSERT (write->elem_size == sizeof (int8_t));

  sc_array_truncate (write);
  wc = (int8_t *) sc_array_push (write);
  n = *((int8_t *) sc_array_index (read, count - 1));
  *wc = l = n;
  for (zy = 1; zy < count; zy++) {
    n = *((int8_t *) sc_array_index (read, count - 1 - zy));
    p = l - 1;
    newn = SC_MAX (p, n);
    stackcount = newn - n;
    wc = (int8_t *) sc_array_push_count (write, 1 + stackcount);
    *wc = l = newn;
    while (stackcount--) {
      *(++wc) = l = newn--;
    }
  }
}
Exemplo n.º 4
0
static void
mesh_iter_volume (p4est_iter_volume_info_t * info, void *user_data)
{
  p4est_mesh_t       *mesh = (p4est_mesh_t *) user_data;
  p4est_tree_t       *tree;
  p4est_locidx_t     *quadid;
  int                 level = info->quad->level;

  /* We could use a static quadrant counter, but that gets uglier */
  tree = p4est_tree_array_index (info->p4est->trees, info->treeid);
  P4EST_ASSERT (0 <= info->quadid &&
                info->quadid < (p4est_locidx_t) tree->quadrants.elem_count);

  if (mesh->quad_to_tree != NULL) {
    mesh->quad_to_tree[tree->quadrants_offset + info->quadid] = info->treeid;
  }

  if (mesh->quad_level != NULL) {
    quadid = (p4est_locidx_t *) sc_array_push (mesh->quad_level + level);
    *quadid = tree->quadrants_offset + info->quadid;
  }
}
Exemplo n.º 5
0
int
check_balance_seeds (p4est_quadrant_t * q, p4est_quadrant_t * p,
                     p4est_connect_type_t b, sc_array_t * seeds)
{
  int                 ib;
  int                 level = q->level;
  p4est_quadrant_t   *s, *t;
  sc_array_t         *thislevel = sc_array_new (sizeof (p4est_quadrant_t));
  sc_array_t         *nextlevel = sc_array_new (sizeof (p4est_quadrant_t));
  sc_array_t         *temparray;
  p4est_quadrant_t    temp1, temp2;
  int                 f, c;
#ifdef P4_TO_P8
  int                 e;
#endif
  int                 stop = 0;

  sc_array_resize (seeds, 0);

  s = (p4est_quadrant_t *) sc_array_push (thislevel);
  p4est_quadrant_sibling (q, s, 0);

#ifndef P4_TO_P8
  if (b == P4EST_CONNECT_FACE) {
    ib = 0;
  }
  else {
    ib = 1;
  }
#else
  if (b == P8EST_CONNECT_FACE) {
    ib = 0;
  }
  else if (b == P8EST_CONNECT_EDGE) {
    ib = 1;
  }
  else {
    ib = 2;
  }
#endif

  while (level > p->level + 1) {
    size_t              nlast = thislevel->elem_count;
    size_t              zz;

    stop = 0;

    for (zz = 0; zz < nlast; zz++) {
      s = p4est_quadrant_array_index (thislevel, zz);
      P4EST_ASSERT (p4est_quadrant_child_id (s) == 0);
      p4est_quadrant_parent (s, &temp1);
      for (f = 0; f < P4EST_FACES; f++) {
        p4est_quadrant_face_neighbor (&temp1, f, &temp2);
        if (is_farther (&temp1, p, &temp2)) {
          continue;
        }
        if (p4est_quadrant_is_ancestor (p, &temp2)) {
          stop = 1;
          sc_array_resize (seeds, seeds->elem_count + 1);
          t = p4est_quadrant_array_index (seeds, seeds->elem_count - 1);
          p4est_quadrant_sibling (&temp2, t, 0);
        }
        else if (p4est_quadrant_is_inside_root (&temp2)) {
          t = (p4est_quadrant_t *) sc_array_push (nextlevel);
          p4est_quadrant_sibling (&temp2, t, 0);
        }
      }

      if (ib == 0) {
        continue;
      }

#ifdef P4_TO_P8
      for (e = 0; e < P8EST_EDGES; e++) {
        p8est_quadrant_edge_neighbor (&temp1, e, &temp2);
        if (is_farther (&temp1, p, &temp2)) {
          continue;
        }
        if (p4est_quadrant_is_ancestor (p, &temp2)) {
          stop = 1;
          sc_array_resize (seeds, seeds->elem_count + 1);
          t = p4est_quadrant_array_index (seeds, seeds->elem_count - 1);
          p4est_quadrant_sibling (&temp2, t, 0);
        }
        else if (p4est_quadrant_is_inside_root (&temp2)) {
          t = (p4est_quadrant_t *) sc_array_push (nextlevel);
          p4est_quadrant_sibling (&temp2, t, 0);
        }
      }

      if (ib == 1) {
        continue;
      }
#endif

      for (c = 0; c < P4EST_CHILDREN; c++) {
        p4est_quadrant_corner_neighbor (&temp1, c, &temp2);
        if (is_farther (&temp1, p, &temp2)) {
          continue;
        }
        if (p4est_quadrant_is_ancestor (p, &temp2)) {
          stop = 1;
          sc_array_resize (seeds, seeds->elem_count + 1);
          t = p4est_quadrant_array_index (seeds, seeds->elem_count - 1);
          p4est_quadrant_sibling (&temp2, t, 0);
        }
        else if (p4est_quadrant_is_inside_root (&temp2)) {
          t = (p4est_quadrant_t *) sc_array_push (nextlevel);
          p4est_quadrant_sibling (&temp2, t, 0);
        }
      }
    }

    if (stop) {
      sc_array_sort (seeds, p4est_quadrant_compare);
      sc_array_uniq (seeds, p4est_quadrant_compare);

#ifdef P4_TO_P8
      if (!ib && seeds->elem_count == 1) {
        sc_array_sort (nextlevel, p4est_quadrant_compare);
        sc_array_uniq (nextlevel, p4est_quadrant_compare);
        temparray = thislevel;
        thislevel = nextlevel;
        nextlevel = temparray;
        sc_array_reset (nextlevel);
        level--;

        nlast = thislevel->elem_count;
        for (zz = 0; zz < nlast; zz++) {
          s = p4est_quadrant_array_index (thislevel, zz);
          P4EST_ASSERT (p4est_quadrant_child_id (s) == 0);
          p4est_quadrant_parent (s, &temp1);
          for (f = 0; f < P4EST_FACES; f++) {
            p4est_quadrant_face_neighbor (&temp1, f, &temp2);
            if (p4est_quadrant_is_ancestor (p, &temp2)) {
              int                 f2;
              p4est_quadrant_t    a;
              p4est_quadrant_t    u;

              t = p4est_quadrant_array_index (seeds, 0);

              p8est_quadrant_parent (t, &a);

              for (f2 = 0; f2 < P8EST_FACES; f2++) {
                if (f2 / 2 == f / 2) {
                  continue;
                }
                p8est_quadrant_face_neighbor (&a, f2, &u);

                if (p8est_quadrant_is_equal (&temp2, &u) ||
                    p8est_quadrant_is_sibling (&temp2, &u)) {
                  break;
                }
              }

              if (f2 == P8EST_FACES) {
                sc_array_resize (seeds, seeds->elem_count + 1);
                t = p4est_quadrant_array_index (seeds, seeds->elem_count - 1);
                p4est_quadrant_sibling (&temp2, t, 0);
              }
            }
          }
        }
      }
#endif
      sc_array_sort (seeds, p4est_quadrant_compare);
      sc_array_uniq (seeds, p4est_quadrant_compare);

      break;
    }
    sc_array_sort (nextlevel, p4est_quadrant_compare);
    sc_array_uniq (nextlevel, p4est_quadrant_compare);
    temparray = thislevel;
    thislevel = nextlevel;
    nextlevel = temparray;
    sc_array_reset (nextlevel);
    level--;
  }

  sc_array_destroy (thislevel);
  sc_array_destroy (nextlevel);

  return stop;
}
Exemplo n.º 6
0
void
p8est_quadrant_edge_neighbor_extra (const p4est_quadrant_t * q, p4est_topidx_t
                                    t, int edge, sc_array_t * quads,
                                    sc_array_t * treeids,
                                    p4est_connectivity_t * conn)
{
  p4est_quadrant_t    temp;
  p4est_quadrant_t   *qp;
  p4est_topidx_t     *tp;
  int                 face;
  p8est_edge_info_t   ei;
  p8est_edge_transform_t *et;
  sc_array_t         *eta;
  size_t              etree;

  eta = &ei.edge_transforms;

  P4EST_ASSERT (SC_ARRAY_IS_OWNER (quads));
  P4EST_ASSERT (quads->elem_count == 0);
  P4EST_ASSERT (quads->elem_size == sizeof (p4est_quadrant_t));
  P4EST_ASSERT (SC_ARRAY_IS_OWNER (treeids));
  P4EST_ASSERT (treeids->elem_count == 0);
  P4EST_ASSERT (treeids->elem_size == sizeof (p4est_topidx_t));

  p8est_quadrant_edge_neighbor (q, edge, &temp);
  if (p4est_quadrant_is_inside_root (&temp)) {
    qp = p4est_quadrant_array_push (quads);
    *qp = temp;
    tp = (p4est_topidx_t *) sc_array_push (treeids);
    *tp = t;
    return;
  }

  if (!p8est_quadrant_is_outside_edge (&temp)) {
    qp = p4est_quadrant_array_push (quads);
    tp = (p4est_topidx_t *) sc_array_push (treeids);

    face = p8est_edge_faces[edge][0];
    p4est_quadrant_face_neighbor (q, face, &temp);
    if (p4est_quadrant_is_inside_root (&temp)) {
      face = p8est_edge_faces[edge][1];
      *tp = p8est_quadrant_face_neighbor_extra (&temp, t, face, qp, conn);
      if (*tp == -1) {
        qp = (p4est_quadrant_t *) sc_array_pop (quads);
        tp = (p4est_topidx_t *) sc_array_pop (treeids);
      }
      return;
    }
    face = p8est_edge_faces[edge][1];
    p4est_quadrant_face_neighbor (q, face, &temp);
    P4EST_ASSERT (p4est_quadrant_is_inside_root (&temp));
    face = p8est_edge_faces[edge][0];
    *tp = p8est_quadrant_face_neighbor_extra (&temp, t, face, qp, conn);
    if (*tp == -1) {
      qp = (p4est_quadrant_t *) sc_array_pop (quads);
      tp = (p4est_topidx_t *) sc_array_pop (treeids);
    }
    return;
  }
  sc_array_init (eta, sizeof (p8est_edge_transform_t));
  p8est_find_edge_transform (conn, t, edge, &ei);
  sc_array_resize (quads, eta->elem_count);
  sc_array_resize (treeids, eta->elem_count);
  for (etree = 0; etree < eta->elem_count; etree++) {
    qp = p4est_quadrant_array_index (quads, etree);
    tp = (p4est_topidx_t *) sc_array_index (treeids, etree);
    et = p8est_edge_array_index (eta, etree);
    p8est_quadrant_transform_edge (&temp, qp, &ei, et, 1);
    *tp = et->ntree;
  }
  sc_array_reset (eta);
}
Exemplo n.º 7
0
int
main (int argc, char **argv)
{
  int                 i, i1, i2, i3, i3last, i4, i4last, temp, count;
  size_t              s, swaps1, swaps2, swaps3, total1, total2, total3;
  ssize_t             searched;
  int                *pi;
  sc_array_t         *a1, *a2, *a3, *a4;
  int                 mpiret;
  double              start, elapsed_pqueue, elapsed_qsort;

  mpiret = sc_MPI_Init (&argc, &argv);
  SC_CHECK_MPI (mpiret);

  sc_init (sc_MPI_COMM_WORLD, 1, 1, NULL, SC_LP_DEFAULT);

  a1 = sc_array_new (sizeof (int));
  a2 = sc_array_new (sizeof (int));
  a3 = sc_array_new (sizeof (int));
  a4 = sc_array_new (sizeof (int));

#ifdef THEBIGTEST
  count = 325323;
#else
  count = 3251;
#endif
  SC_INFOF ("Test pqueue with count %d\n", count);

  start = -sc_MPI_Wtime ();

  swaps1 = swaps2 = swaps3 = 0;
  total1 = total2 = total3 = 0;
  for (i = 0; i < count; ++i) {
    *(int *) sc_array_push (a1) = i;
    s = sc_array_pqueue_add (a1, &temp, compar);
    swaps1 += ((s > 0) ? 1 : 0);
    total1 += s;

    *(int *) sc_array_push (a2) = count - i - 1;
    s = sc_array_pqueue_add (a2, &temp, compar);
    swaps2 += ((s > 0) ? 1 : 0);
    total2 += s;

    *(int *) sc_array_push (a3) = (15 * i) % 172;
    s = sc_array_pqueue_add (a3, &temp, compar);
    swaps3 += ((s > 0) ? 1 : 0);
    total3 += s;
  }
  SC_CHECK_ABORT (swaps1 == 0 && total1 == 0, "pqueue_add");
  SC_VERBOSEF ("   Swaps %lld %lld %lld Total %lld %lld %lld\n",
               (long long) swaps1, (long long) swaps2, (long long) swaps3,
               (long long) total1, (long long) total2, (long long) total3);

  temp = 52;
  searched = sc_array_bsearch (a1, &temp, compar);
  SC_CHECK_ABORT (searched != -1, "array_bsearch_index");
  pi = (int *) sc_array_index_ssize_t (a1, searched);
  SC_CHECK_ABORT (*pi == temp, "array_bsearch");

  i3last = -1;
  swaps1 = swaps2 = swaps3 = 0;
  total1 = total2 = total3 = 0;
  for (i = 0; i < count; ++i) {
    s = sc_array_pqueue_pop (a1, &i1, compar);
    swaps1 += ((s > 0) ? 1 : 0);
    total1 += s;

    s = sc_array_pqueue_pop (a2, &i2, compar);
    swaps2 += ((s > 0) ? 1 : 0);
    total2 += s;

    s = sc_array_pqueue_pop (a3, &i3, compar);
    swaps3 += ((s > 0) ? 1 : 0);
    total3 += s;

    SC_CHECK_ABORT (i == i1 && i == i2, "pqueue_pop");
    SC_CHECK_ABORT (i3 >= i3last, "pqueue_pop");
    i3last = i3;
  }
  SC_VERBOSEF ("   Swaps %lld %lld %lld Total %lld %lld %lld\n",
               (long long) swaps1, (long long) swaps2, (long long) swaps3,
               (long long) total1, (long long) total2, (long long) total3);

  elapsed_pqueue = start + sc_MPI_Wtime ();

  sc_array_destroy (a1);
  sc_array_destroy (a2);
  sc_array_destroy (a3);

  SC_INFOF ("Test array sort with count %d\n", count);

  start = -sc_MPI_Wtime ();

  /* the resize is done to be comparable with the above procedure */
  for (i = 0; i < count; ++i) {
    *(int *) sc_array_push (a4) = (15 * i) % 172;
  }
  sc_array_sort (a4, compar);

  i4last = -1;
  for (i = 0; i < count; ++i) {
    i4 = *(int *) sc_array_index_int (a4, i);

    SC_CHECK_ABORT (i4 >= i4last, "array_sort");
    i4last = i4;
  }
  sc_array_resize (a4, 0);

  elapsed_qsort = start + sc_MPI_Wtime ();
  SC_STATISTICSF ("Test timings pqueue %g qsort %g\n",
                  elapsed_pqueue, 3. * elapsed_qsort);

  sc_array_destroy (a4);
  sc_finalize ();

  mpiret = sc_MPI_Finalize ();
  SC_CHECK_MPI (mpiret);

  return 0;
}
Exemplo n.º 8
0
p4est_mesh_t       *
p4est_mesh_new_ext (p4est_t * p4est, p4est_ghost_t * ghost,
                    int compute_tree_index, int compute_level_lists,
                    p4est_connect_type_t btype)
{
  int                 do_corner = 0;
  int                 do_volume = 0;
  int                 rank;
  p4est_locidx_t      lq, ng;
  p4est_locidx_t      jl;
  p4est_mesh_t       *mesh;

  P4EST_ASSERT (p4est_is_balanced (p4est, btype));

  mesh = P4EST_ALLOC_ZERO (p4est_mesh_t, 1);

  lq = mesh->local_num_quadrants = p4est->local_num_quadrants;
  ng = mesh->ghost_num_quadrants = (p4est_locidx_t) ghost->ghosts.elem_count;

  if (btype == P4EST_CONNECT_FULL) {
    do_corner = 1;
  }
  do_volume = (compute_tree_index || compute_level_lists ? 1 : 0);

  /* Optional map of tree index for each quadrant */
  if (compute_tree_index) {
    mesh->quad_to_tree = P4EST_ALLOC (p4est_topidx_t, lq);
  }

  mesh->ghost_to_proc = P4EST_ALLOC (int, ng);
  mesh->quad_to_quad = P4EST_ALLOC (p4est_locidx_t, P4EST_FACES * lq);
  mesh->quad_to_face = P4EST_ALLOC (int8_t, P4EST_FACES * lq);
  mesh->quad_to_half = sc_array_new (P4EST_HALF * sizeof (p4est_locidx_t));

  /* Optional per-level lists of quadrants */
  if (compute_level_lists) {
    mesh->quad_level = P4EST_ALLOC (sc_array_t, P4EST_QMAXLEVEL + 1);

    for (jl = 0; jl <= P4EST_QMAXLEVEL; ++jl) {
      sc_array_init (mesh->quad_level + jl, sizeof (p4est_locidx_t));
    }
  }

  /* Populate ghost information */
  rank = 0;
  for (jl = 0; jl < ng; ++jl) {
    while (ghost->proc_offsets[rank + 1] <= jl) {
      ++rank;
      P4EST_ASSERT (rank < p4est->mpisize);
    }
    mesh->ghost_to_proc[jl] = rank;
  }

  /* Fill face arrays with default values */
  memset (mesh->quad_to_quad, -1, P4EST_FACES * lq * sizeof (p4est_locidx_t));
  memset (mesh->quad_to_face, -25, P4EST_FACES * lq * sizeof (int8_t));

  if (do_corner) {
    /* Initialize corner information to a consistent state */
    mesh->quad_to_corner = P4EST_ALLOC (p4est_locidx_t, P4EST_CHILDREN * lq);
    memset (mesh->quad_to_corner, -1, P4EST_CHILDREN * lq *
            sizeof (p4est_locidx_t));

    mesh->corner_offset = sc_array_new (sizeof (p4est_locidx_t));
    *(p4est_locidx_t *) sc_array_push (mesh->corner_offset) = 0;

    mesh->corner_quad = sc_array_new (sizeof (p4est_locidx_t));
    mesh->corner_corner = sc_array_new (sizeof (int8_t));
  }

  /* Call the forest iterator to collect face connectivity */
  p4est_iterate (p4est, ghost, mesh,
                 (do_volume ? mesh_iter_volume : NULL), mesh_iter_face,
#ifdef P4_TO_P8
                 NULL,
#endif
                 do_corner ? mesh_iter_corner : NULL);

  return mesh;
}
Exemplo n.º 9
0
static void
mesh_iter_face (p4est_iter_face_info_t * info, void *user_data)
{
  int                 h;
  int                 swapsides;
  p4est_mesh_t       *mesh = (p4est_mesh_t *) user_data;
  p4est_locidx_t      jl, jl2, jls[P4EST_HALF];
  p4est_locidx_t      in_qtoq, halfindex;
  p4est_locidx_t     *halfentries;
  p4est_tree_t       *tree;
  p4est_iter_face_side_t *side, *side2, *tempside;

  if (info->sides.elem_count == 1) {
    /* this face is on an outside boundary of the forest */
    P4EST_ASSERT (info->orientation == 0);
    P4EST_ASSERT (info->tree_boundary);
    side = (p4est_iter_face_side_t *) sc_array_index (&info->sides, 0);
    P4EST_ASSERT (0 <= side->treeid &&
                  side->treeid < info->p4est->connectivity->num_trees);
    P4EST_ASSERT (0 <= side->face && side->face < P4EST_FACES);
    P4EST_ASSERT (!side->is_hanging && !side->is.full.is_ghost);
    tree = p4est_tree_array_index (info->p4est->trees, side->treeid);
    jl = side->is.full.quadid + tree->quadrants_offset;
    P4EST_ASSERT (0 <= jl && jl < mesh->local_num_quadrants);
    in_qtoq = P4EST_FACES * jl + side->face;
    mesh->quad_to_quad[in_qtoq] = jl;   /* put in myself and my own face */
    mesh->quad_to_face[in_qtoq] = side->face;
  }
  else {
    /* this face is between two quadrants */
    P4EST_ASSERT (info->orientation == 0 || info->tree_boundary);
    P4EST_ASSERT (info->sides.elem_count == 2);
    side = (p4est_iter_face_side_t *) sc_array_index (&info->sides, 0);
    side2 = (p4est_iter_face_side_t *) sc_array_index (&info->sides, 1);
    P4EST_ASSERT (info->tree_boundary || side->treeid == side2->treeid);
    P4EST_ASSERT (!side->is_hanging || !side2->is_hanging);
    if (!side->is_hanging && !side2->is_hanging) {
      /* same-size face neighbors */
      P4EST_ASSERT (!side->is.full.is_ghost || !side2->is.full.is_ghost);

      /* determine both quadrant numbers */
      if (!side->is.full.is_ghost) {
        tree = p4est_tree_array_index (info->p4est->trees, side->treeid);
        jl = side->is.full.quadid + tree->quadrants_offset;
        P4EST_ASSERT (0 <= jl && jl < mesh->local_num_quadrants);
      }
      else {
        P4EST_ASSERT (side->is.full.quad != NULL);
        P4EST_ASSERT (side->is.full.quadid >= 0);
        jl = mesh->local_num_quadrants + side->is.full.quadid;
      }
      if (!side2->is.full.is_ghost) {
        tree = p4est_tree_array_index (info->p4est->trees, side2->treeid);
        jl2 = side2->is.full.quadid + tree->quadrants_offset;
        P4EST_ASSERT (0 <= jl2 && jl2 < mesh->local_num_quadrants);
      }
      else {
        P4EST_ASSERT (side2->is.full.quad != NULL);
        P4EST_ASSERT (side2->is.full.quadid >= 0);
        jl2 = mesh->local_num_quadrants + side2->is.full.quadid;
      }

      /* encode quadrant neighborhood */
      if (!side->is.full.is_ghost) {
        in_qtoq = P4EST_FACES * jl + side->face;
        P4EST_ASSERT (mesh->quad_to_quad[in_qtoq] == -1);
        P4EST_ASSERT (mesh->quad_to_face[in_qtoq] == -25);
        mesh->quad_to_quad[in_qtoq] = jl2;
        mesh->quad_to_face[in_qtoq] =
          P4EST_FACES * info->orientation + side2->face;
      }
      if (!side2->is.full.is_ghost) {
        in_qtoq = P4EST_FACES * jl2 + side2->face;
        P4EST_ASSERT (mesh->quad_to_quad[in_qtoq] == -1);
        P4EST_ASSERT (mesh->quad_to_face[in_qtoq] == -25);
        mesh->quad_to_quad[in_qtoq] = jl;
        mesh->quad_to_face[in_qtoq] =
          P4EST_FACES * info->orientation + side->face;
      }
    }
    else {
      /* one of the faces is hanging, rename so it's always side2 */
      swapsides = side->is_hanging;
      if (swapsides) {
        tempside = side;
        side = side2;
        side2 = tempside;
      }
      P4EST_ASSERT (!side->is_hanging && side2->is_hanging);

      /* determine quadrant number for non-hanging large face */
      if (!side->is.full.is_ghost) {
        tree = p4est_tree_array_index (info->p4est->trees, side->treeid);
        jl = side->is.full.quadid + tree->quadrants_offset;
        P4EST_ASSERT (0 <= jl && jl < mesh->local_num_quadrants);
      }
      else {
        P4EST_ASSERT (side->is.full.quad != NULL);
        P4EST_ASSERT (side->is.full.quadid >= 0);
        jl = mesh->local_num_quadrants + side->is.full.quadid;
      }

      /* determine quadrant numbers for all hanging faces */
      for (h = 0; h < P4EST_HALF; ++h) {
        if (!side2->is.hanging.is_ghost[h]) {
          tree = p4est_tree_array_index (info->p4est->trees, side2->treeid);
          jls[h] = side2->is.hanging.quadid[h] + tree->quadrants_offset;
          P4EST_ASSERT (0 <= jls[h] && jls[h] < mesh->local_num_quadrants);
        }
        else {
          P4EST_ASSERT (side2->is.hanging.quad[h] != NULL);
          P4EST_ASSERT (side2->is.hanging.quadid[h] >= 0);
          jls[h] = mesh->local_num_quadrants + side2->is.hanging.quadid[h];
        }
      }

      /* encode quadrant neighborhood */
      if (!side->is.full.is_ghost) {
        in_qtoq = P4EST_FACES * jl + side->face;
        P4EST_ASSERT (mesh->quad_to_quad[in_qtoq] == -1);
        P4EST_ASSERT (mesh->quad_to_face[in_qtoq] == -25);
        halfindex = (p4est_locidx_t) mesh->quad_to_half->elem_count;
        mesh->quad_to_quad[in_qtoq] = halfindex;
        mesh->quad_to_face[in_qtoq] =
          P4EST_FACES * (info->orientation - P4EST_HALF) + side2->face;
        halfentries = (p4est_locidx_t *) sc_array_push (mesh->quad_to_half);
        for (h = 0; h < P4EST_HALF; ++h) {
          halfentries[h] = jls[h];
        }
      }
      for (h = 0; h < P4EST_HALF; ++h) {
        if (!side2->is.hanging.is_ghost[h]) {
          in_qtoq = P4EST_FACES * jls[h] + side2->face;
          P4EST_ASSERT (mesh->quad_to_quad[in_qtoq] == -1);
          P4EST_ASSERT (mesh->quad_to_face[in_qtoq] == -25);
          mesh->quad_to_quad[in_qtoq] = jl;
          mesh->quad_to_face[in_qtoq] =
            P4EST_FACES * (info->orientation + (h + 1) * P4EST_HALF) +
            side->face;
        }
      }
    }
  }
}
Exemplo n.º 10
0
static int
p8est_find_edge_transform_internal (p4est_connectivity_t * conn,
                                    p4est_topidx_t itree, int iedge,
                                    p8est_edge_info_t * ei,
                                    const p4est_topidx_t * ett,
                                    const int8_t * ete,
                                    p4est_topidx_t edge_trees)
{
  int                 i, j;
  int                 redge, nedge, iflip, nflip;
  int                 pref, pset, fc[2], nc[2];
  int                 face, nface, orient, eorient;
  p4est_topidx_t      etree, ietree, ntree;
  p8est_edge_transform_t *et;
  sc_array_t         *ta = &ei->edge_transforms;
  const int          *fcorners;
  int                 distinct = 1;
  int                 edges[3], edgeorients[3];
  p4est_topidx_t      etrees[3];

  P4EST_ASSERT (0 <= itree && itree < conn->num_trees);
  P4EST_ASSERT (0 <= iedge && iedge < P8EST_EDGES);
  P4EST_ASSERT (ta->elem_size == sizeof (p8est_edge_transform_t));

  etrees[0] = itree;
  edges[0] = iedge;
  edgeorients[0] = 0;

  /* identify touching faces */
  for (i = 0; i < 2; ++i) {
    face = p8est_edge_faces[iedge][i];
    ntree = conn->tree_to_tree[P4EST_FACES * itree + face];
    nface = (int) conn->tree_to_face[P4EST_FACES * itree + face];
    if (ntree != itree || nface != face) {      /* not domain boundary */
      orient = nface / P4EST_FACES;
      nface %= P4EST_FACES;
      fcorners = &(p8est_edge_face_corners[iedge][face][0]);
      P4EST_ASSERT (fcorners[0] >= 0 && fcorners[1] >= 0);
      pref = p8est_face_permutation_refs[face][nface];
      pset = p8est_face_permutation_sets[pref][orient];
      fc[0] = p8est_face_permutations[pset][fcorners[0]];
      fc[1] = p8est_face_permutations[pset][fcorners[1]];

      /* if this is a new edge, add it */
      nc[0] = p8est_face_corners[nface][fc[0]];
      nc[1] = p8est_face_corners[nface][fc[1]];
      nedge = p8est_child_corner_edges[nc[0]][nc[1]];
      P4EST_ASSERT (nedge >= 0);
      eorient = (p8est_edge_corners[nedge][1] == nc[0]);
      for (j = 0; j < distinct; j++) {
        if (ntree == etrees[j] &&
            nedge == edges[j] && eorient == edgeorients[j]) {
          break;
        }
      }
      if (j == distinct) {
        etrees[j] = ntree;
        edges[j] = nedge;
        edgeorients[j] = eorient;
        distinct++;
      }
    }
  }

  /* find orientation of this edge */
  ietree = -1;
  iflip = -1;
  for (etree = 0; etree < edge_trees; ++etree) {
    ntree = ett[etree];
    P4EST_ASSERT (0 <= ntree && ntree < conn->num_trees);
    redge = (int) ete[etree];
    P4EST_ASSERT (redge >= 0 && redge < 2 * P8EST_EDGES);
    nedge = redge % P8EST_EDGES;
    if (nedge == iedge && ntree == itree) {
      iflip = redge / P8EST_EDGES;
      ietree = etree;
      break;
    }
  }
  P4EST_ASSERT (ietree >= 0 && iflip >= 0);

  /* loop through all trees connected through this edge */
  for (etree = 0; etree < edge_trees; ++etree) {
    if (etree == ietree) {
      continue;
    }
    ntree = ett[etree];
    P4EST_ASSERT (0 <= ntree && ntree < conn->num_trees);
    redge = (int) ete[etree];
    P4EST_ASSERT (redge >= 0 && redge < 2 * P8EST_EDGES);
    nedge = redge % P8EST_EDGES;
    nflip = (redge / P8EST_EDGES) ^ iflip;

    for (j = 0; j < distinct; j++) {
      if (ntree == etrees[j] && nedge == edges[j] && nflip == edgeorients[j]) {
        break;
      }
    }
    if (j < distinct) {
      /* already found from self or faces */
      continue;
    }
#if 0
    nows[0] = nows[1] = 0;
    for (i = 0; i < 2; ++i) {
      if (ntree == ntrees[i]) {
        /* check if the edge touches this neighbor contact face */
        P4EST_ASSERT (fcorners[i][0] >= 0);
        nfcorners = p8est_edge_face_corners[nedge][nfaces[i]];
        if (nfcorners[0] >= 0) {
          pref = p8est_face_permutation_refs[faces[i]][nfaces[i]];
          pset = p8est_face_permutation_sets[pref][orients[i]];
          fc[0] = p8est_face_permutations[pset][fcorners[i][0]];
          fc[1] = p8est_face_permutations[pset][fcorners[i][1]];

          if (fc[0] == nfcorners[nflip] && fc[1] == nfcorners[!nflip]) {
            P4EST_ASSERT (!founds[i] && !nows[!i]);
#ifdef P4EST_ENABLE_DEBUG
            founds[i] = 1;
#endif
            nows[i] = 1;
          }
          else if (fc[0] == nfcorners[!nflip] && fc[1] == nfcorners[nflip]) {
            ++flipped;
          }
        }
      }
    }
    if (nows[0] || nows[1]) {
      continue;
    }
#endif

    /* else we have a diagonal edge with ntree */
    et = (p8est_edge_transform_t *) sc_array_push (ta);
    et->ntree = ntree;
    et->nedge = (int8_t) nedge;
    et->naxis[0] = (int8_t) (nedge / 4);
    et->naxis[1] = (int8_t) (nedge < 4 ? 1 : 0);
    et->naxis[2] = (int8_t) (nedge < 8 ? 2 : 1);
    et->nflip = (int8_t) nflip;
    et->corners = (int8_t) (nedge % 4);
  }

  return distinct;
}