Example #1
0
void
p8est_quadrant_edge_neighbor (const p4est_quadrant_t * q,
                              int edge, p4est_quadrant_t * r)
{
  const p4est_qcoord_t qh = P4EST_QUADRANT_LEN (q->level);

  P4EST_ASSERT (0 <= edge && edge < 12);
  P4EST_ASSERT (p4est_quadrant_is_valid (q));

  switch (edge / 4) {
  case 0:
    r->x = q->x;
    r->y = q->y + (2 * (edge & 0x01) - 1) * qh;
    r->z = q->z + ((edge & 0x02) - 1) * qh;
    break;
  case 1:
    r->x = q->x + (2 * (edge & 0x01) - 1) * qh;
    r->y = q->y;
    r->z = q->z + ((edge & 0x02) - 1) * qh;
    break;
  case 2:
    r->x = q->x + (2 * (edge & 0x01) - 1) * qh;
    r->y = q->y + ((edge & 0x02) - 1) * qh;
    r->z = q->z;
    break;
  default:
    SC_ABORT_NOT_REACHED ();
    break;
  }
  r->level = q->level;
  P4EST_ASSERT (p4est_quadrant_is_extended (r));
}
Example #2
0
/** For a quadrant that touches a tree face with a corner inside the face,
 * get the number of the touching face.
 */
static int
tree_face_quadrant_corner_face (const p4est_quadrant_t * q, int corner)
{
  int                 which;
  p4est_qcoord_t      end = P4EST_LAST_OFFSET (q->level);

  P4EST_ASSERT (p4est_quadrant_is_valid (q));
  P4EST_ASSERT (0 <= corner && corner < P4EST_CHILDREN);

  which = corner & 1;
  if (q->x == (which ? end : 0)) {
    return which;
  }
  which = corner & 2;
  if (q->y == (which ? end : 0)) {
    return 2 + (which >> 1);
  }
#ifdef P4_TO_P8
  which = corner & 4;
  if (q->z == (which ? end : 0)) {
    return 4 + (which >> 2);
  }
#endif
  SC_ABORT_NOT_REACHED ();
}
static void 
d4est_geometry_compact_disk_X(p4est_geometry_t * geom,
                       p4est_topidx_t which_tree,
                       const double rst[3], double xyz[3])
{
  double* radii = (double*)geom->user;
  
  double R0 = radii[0];
  double R1 = radii[1];

  double xref = rst[0];
  double yref = rst[1];
  double x,y;
  
  if (which_tree == 0){
    /* bottom */
    d4est_geometry_compact_disk_map_cube_to_slab(yref, xref, 1., 0., -R1, -R0/sqrt(2), &y, &x);
    x *= -1.;
  }
  else if (which_tree == 1){
    /* left */
    d4est_geometry_compact_disk_map_cube_to_slab(xref, yref, 1., 0., -R1, -R0/sqrt(2), &x, &y);
    y *= -1;
  }
  else if (which_tree == 2){
    /* center */
    d4est_geometry_compact_disk_linear_map(xref, 0., 1., -R0/sqrt(2), R0/sqrt(2), &x);
    d4est_geometry_compact_disk_linear_map(yref, 0., 1., -R0/sqrt(2), R0/sqrt(2), &y);
  }
  else if (which_tree == 3){
    /* right */
    d4est_geometry_compact_disk_map_cube_to_slab(xref, yref, 0, 1, R0/sqrt(2), R1, &x, &y);
  }
  else if (which_tree == 4){
    /* top */
    d4est_geometry_compact_disk_map_cube_to_slab(yref, xref, 0, 1, R0/sqrt(2), R1, &y, &x);
  }
  else{
    SC_ABORT_NOT_REACHED();
  }
z
  xyz[0] = x;
  xyz[1] = y;
  xyz[2] = 0.;

  /* compactify */
  if (which_tree != 2){
    double xnc = xyz[0];
    double ync = xyz[1];
    double R = sqrt(xnc*xnc + ync*ync);
    double r = (R1 + (w - R1)*(R - R1)/(R2 - R1))/(1 - (R - R1)*(1 - w/Rinf)/(R2 - R1));
    xyz[0] = r*xnc/R;
    xyz[1] = r*ync/R;
  }
}
Example #4
0
const char         *
p8est_connect_type_string (p8est_connect_type_t btype)
{
  switch (btype) {
  case P8EST_CONNECT_FACE:
    return "FACE";
  case P8EST_CONNECT_EDGE:
    return "EDGE";
  case P8EST_CONNECT_CORNER:
    return "CORNER";
  default:
    SC_ABORT_NOT_REACHED ();
  }
}
Example #5
0
int
p8est_connect_type_int (p8est_connect_type_t btype)
{
  switch (btype) {
  case P8EST_CONNECT_FACE:
    return 1;
  case P8EST_CONNECT_EDGE:
    return 2;
  case P8EST_CONNECT_CORNER:
    return 3;
  default:
    SC_ABORT_NOT_REACHED ();
  }
}
Example #6
0
int
p8est_quadrant_is_outside_edge_extra (const p4est_quadrant_t * q, int *edge)
{
  int                 quad_contact[P4EST_FACES];
  int                 face_axis[P4EST_DIM];

  P4EST_ASSERT (q->level <= P4EST_QMAXLEVEL);

  quad_contact[0] = (int) (q->x < 0);
  quad_contact[1] = (int) (q->x >= P4EST_ROOT_LEN);
  quad_contact[2] = (int) (q->y < 0);
  quad_contact[3] = (int) (q->y >= P4EST_ROOT_LEN);
  quad_contact[4] = (int) (q->z < 0);
  quad_contact[5] = (int) (q->z >= P4EST_ROOT_LEN);
  face_axis[0] = quad_contact[0] || quad_contact[1];
  face_axis[1] = quad_contact[2] || quad_contact[3];
  face_axis[2] = quad_contact[4] || quad_contact[5];

  if (face_axis[0] + face_axis[1] + face_axis[2] != 2) {
    return 0;
  }

  if (edge != NULL) {
    if (!face_axis[0]) {
      *edge = 0 + 2 * quad_contact[5] + quad_contact[3];
    }
    else if (!face_axis[1]) {
      *edge = 4 + 2 * quad_contact[5] + quad_contact[1];
    }
    else if (!face_axis[2]) {
      *edge = 8 + 2 * quad_contact[3] + quad_contact[1];
    }
    else {
      SC_ABORT_NOT_REACHED ();
    }
    P4EST_ASSERT (p8est_quadrant_touches_edge (q, *edge, 0));
  }

  return 1;
}
Example #7
0
static void
p4est_build_verify_4 (p4est_t * p4est)
{
  p4est_topidx_t      jt;
  p4est_locidx_t      il, c1, c2;
  p4est_tree_t       *tree;
  p4est_quadrant_t   *quadrant;
  test_build_t       *tb;

  tb = (test_build_t *) p4est->user_pointer;

  c1 = c2 = 0;
  for (jt = p4est->first_local_tree; jt <= p4est->last_local_tree; ++jt) {
    tree = p4est_tree_array_index (p4est->trees, jt);
    for (il = 0; il < (p4est_locidx_t) tree->quadrants.elem_count; ++il) {
      quadrant = p4est_quadrant_array_index (&tree->quadrants, il);
      switch (*(long *) quadrant->p.user_data) {
      case 11321:
        ++c1;
        break;
      case -748:
        ++c2;
        break;
      default:
        SC_ABORT_NOT_REACHED ();
      }
    }
  }
  SC_CHECK_ABORT (c1 + c2 == p4est->local_num_quadrants,
                  "Test 4 count quadrants");
  SC_CHECK_ABORT (c1 + c2 >= (p4est_locidx_t) tb->count_add,
                  "Test 4 count sum");
  SC_CHECK_ABORT (c1 == (p4est_locidx_t) tb->init_default,
                  "Test 4 count default");
  SC_CHECK_ABORT (c2 == (p4est_locidx_t) tb->init_add, "Test 4 count add");
}
Example #8
0
int
p4est_balance_seeds (p4est_quadrant_t * q, p4est_quadrant_t * p,
                     p4est_connect_type_t balance, sc_array_t * seeds)
{
  int                 outside[P4EST_DIM];
  int                 i;
  int                 type = 0;
  p4est_qcoord_t      diff;
  p4est_qcoord_t      qc, pc;
  p4est_qcoord_t      pdist = P4EST_QUADRANT_LEN (p->level);
  p4est_qcoord_t      qdist = P4EST_QUADRANT_LEN (q->level);
  p4est_quadrant_t   *s;
  int                 f, c;
#ifdef P4_TO_P8
  int                 e;
#endif

  if (seeds != NULL) {
    sc_array_resize (seeds, 0);
  }

  /* basic level comparison */
  if (q->level <= p->level + 1) {
    return 0;
  }

  for (i = 0; i < P4EST_DIM; i++) {
    switch (i) {
    case 0:
      qc = q->x;
      pc = p->x;
      break;
    case 1:
      qc = q->y;
      pc = p->y;
      break;
#ifdef P4_TO_P8
    case 2:
      qc = q->z;
      pc = p->z;
      break;
#endif
    default:
      SC_ABORT_NOT_REACHED ();
      break;
    }
    outside[i] = 0;
    if (qc < pc) {
      diff = pc - qc;
      /* insulation layer comparison */
      if (diff > pdist) {
        return 0;
      }
      outside[i] = -1;
    }
    else {
      diff = (qc + qdist) - (pc + pdist);
      /* insulation layer comparison */
      if (diff > pdist) {
        return 0;
      }
      if (diff > 0) {
        outside[i] = 1;
      }
    }
    type += (outside[i] ? 1 : 0);
  }

  switch (type) {
  case 0:
    /* q is inside p, so it is its own seed */
    sc_array_resize (seeds, seeds->elem_count + 1);
    s = p4est_quadrant_array_index (seeds, seeds->elem_count - 1);
    *s = *q;
    return 1;
  case 1:
    for (i = 0; i < P4EST_DIM; i++) {
      if (outside[i]) {
        f = 2 * i + (outside[i] > 0 ? 1 : 0);
        return p4est_balance_seeds_face (q, p, f, balance, seeds);
      }
    }
    SC_ABORT_NOT_REACHED ();
    return -1;
  case P4EST_DIM:
    c = 0;
    for (i = 0; i < P4EST_DIM; i++) {
      c += (outside[i] > 0 ? (1 << i) : 0);
    }
    return p4est_balance_seeds_corner (q, p, c, balance, seeds);
#ifdef P4_TO_P8
  case 2:
    e = 0;
    c = 0;
    for (i = 2; i >= 0; i--) {
      if (outside[i]) {
        c <<= 1;
        c |= (outside[i] > 0 ? 1 : 0);
      }
      else {
        e |= (i << 2);
      }
    }
    e |= c;
    return p8est_balance_seeds_edge (q, p, e, balance, seeds);
#endif
  default:
    SC_ABORT_NOT_REACHED ();
    return -1;
  }
}
Example #9
0
static void
p8est_bal_edge_con_internal (p4est_quadrant_t const *q,
                             p4est_quadrant_t * p, int edge,
                             int balance, int *consistent,
                             p4est_quadrant_t * add)
{
  int                 plevel = p->level;
  int                 qlevel = q->level;
  int                 blevel;
  int                 child;
  int                 recon;
  p4est_quadrant_t    porig;
  p4est_quadrant_t    temp;
  p4est_quadrant_t    a;
  p4est_qcoord_t      dx, dy;
  p4est_qcoord_t      dist;
  p4est_qcoord_t      qlen, plen, mask;
  p4est_qcoord_t      b1len, pmask;
  int                 i;

  P4EST_ASSERT (p4est_quadrant_is_extended (q));
  P4EST_ASSERT (p4est_quadrant_is_extended (p));

  if (qlevel <= plevel) {
    if (consistent != NULL) {
      *consistent = 1;
    }
    return;
  }

  qlen = P4EST_QUADRANT_LEN (qlevel);
  plen = P4EST_QUADRANT_LEN (plevel);

  switch (edge / 4) {
  case 0:
    dx = (edge & 1) ? (q->y + qlen) - (p->y + plen) : p->y - q->y;
    dy = (edge & 2) ? (q->z + qlen) - (p->z + plen) : p->z - q->z;
    break;
  case 1:
    dx = (edge & 1) ? (q->x + qlen) - (p->x + plen) : p->x - q->x;
    dy = (edge & 2) ? (q->z + qlen) - (p->z + plen) : p->z - q->z;
    break;
  case 2:
    dx = (edge & 1) ? (q->x + qlen) - (p->x + plen) : p->x - q->x;
    dy = (edge & 2) ? (q->y + qlen) - (p->y + plen) : p->y - q->y;
    break;
  default:
    SC_ABORT_NOT_REACHED ();
  }
  P4EST_ASSERT (dx >= 0);
  P4EST_ASSERT (dy >= 0);

  if (balance) {
    dist = SC_MAX (dx, dy);
    blevel = p4est_balance_kernel_1d (dist, qlevel);
  }
  else {
    blevel = p4est_balance_kernel_2d (dx, dy, qlevel);
  }

  if (blevel <= plevel) {
    if (consistent != NULL) {
      *consistent = 1;
    }
    return;
  }

  if (consistent != NULL) {
    *consistent = 0;
  }

  porig = *p;
  *p = *q;

  switch (edge / 4) {
  case 0:
    p->y += (edge & 1) ? -dx : dx;
    p->z += (edge & 2) ? -dy : dy;
    break;
  case 1:
    p->x += (edge & 1) ? -dx : dx;
    p->z += (edge & 2) ? -dy : dy;
    break;
  case 2:
    p->x += (edge & 1) ? -dx : dx;
    p->y += (edge & 2) ? -dy : dy;
    break;
  default:
    SC_ABORT_NOT_REACHED ();
  }
  mask = -1 << (P4EST_MAXLEVEL - blevel);
  p->x &= mask;
  p->y &= mask;
  p->z &= mask;
  p->level = blevel;
  P4EST_ASSERT (p4est_quadrant_is_extended (p));

  if (add != NULL) {
    add[1] = *p;

    /* this is the only quad needed if it is only one level smaller than the
     * original quadrant */
    if (blevel == plevel - 1) {
      return;
    }

    mask = -1 << (P4EST_MAXLEVEL - (blevel - 1));
    pmask = -1 << (P4EST_MAXLEVEL - (plevel));
    a = *p;
    a.x &= mask;
    a.y &= mask;
    a.z &= mask;
    a.level = blevel - 1;

    b1len = P4EST_QUADRANT_LEN (blevel - 1);
    for (i = -1; i <= 1; i += 2) {
      temp = a;
      /* temp is in a family group one family group over from temp */
      switch (edge / 4) {
      case 0:
        temp.x += i * b1len;
        break;
      case 1:
        temp.y += i * b1len;
        break;
      case 2:
        temp.z += i * b1len;
        break;
      default:
        SC_ABORT_NOT_REACHED ();
      }

      if ((temp.x & pmask) != porig.x || (temp.y & pmask) != porig.y ||
          (temp.z & pmask) != porig.z) {
        /* only test other descendents of p */
        continue;
      }

      child = p8est_edge_corners[edge][(1 - i) / 2];

      p4est_bal_corner_con_internal (q, &temp, child, balance, &recon);

      if (!recon) {
        add[1 + i] = temp;
      }
    }
  }
}
Example #10
0
static void
p4est_bal_face_con_internal (p4est_quadrant_t const *q,
                             p4est_quadrant_t * p, int face,
                             int balance, int *consistent,
                             p4est_quadrant_t * add)
{
  int                 qlevel = q->level;
  int                 plevel = p->level;
  int                 blevel;

  int                 child;
#ifdef P4_TO_P8
  int                 edge;
  int                 dual;
  int                 achild = -1;
#endif
  int                 recon;
  p4est_quadrant_t    porig;
  p4est_quadrant_t    temp;
  p4est_quadrant_t    a;
  int                 i;
#ifndef P4_TO_P8
  int                 nconextra = 3;
#else
  int                 nconextra = 9;
  int                 j;
  p4est_qcoord_t      b2mask;
#endif
  p4est_qcoord_t      distance;
  p4est_qcoord_t      qlen, plen, mask, pmask;
  p4est_qcoord_t      b1len;

  P4EST_ASSERT (p4est_quadrant_is_extended (q));
  P4EST_ASSERT (p4est_quadrant_is_extended (p));

  if (qlevel <= plevel) {
    if (consistent != NULL) {
      *consistent = 1;
    }
    return;
  }

  qlen = P4EST_QUADRANT_LEN (qlevel);
  plen = P4EST_QUADRANT_LEN (plevel);

  switch (face) {
  case 0:
    distance = p->x - q->x;
    break;
  case 1:
    distance = (q->x + qlen) - (p->x + plen);
    break;
  case 2:
    distance = p->y - q->y;
    break;
  case 3:
    distance = (q->y + qlen) - (p->y + plen);
    break;
#ifdef P4_TO_P8
  case 4:
    distance = p->z - q->z;
    break;
  case 5:
    distance = (q->z + qlen) - (p->z + plen);
    break;
#endif
  default:
    SC_ABORT_NOT_REACHED ();
  }

  P4EST_ASSERT (distance >= 0);

  blevel = p4est_balance_kernel_1d (distance, q->level);

  if (blevel <= plevel) {
    if (consistent != NULL) {
      *consistent = 1;
    }
    return;
  }

  if (consistent != NULL) {
    *consistent = 0;
  }

  porig = *p;

  *p = *q;

  /* shift a until it is inside p */
  switch (face) {
  case 0:
    p->x += distance;
    break;
  case 1:
    p->x -= distance;
    break;
  case 2:
    p->y += distance;
    break;
  case 3:
    p->y -= distance;
    break;
#ifdef P4_TO_P8
  case 4:
    p->z += distance;
    break;
  case 5:
    p->z -= distance;
    break;
#endif
  default:
    SC_ABORT_NOT_REACHED ();
  }

  mask = -1 << (P4EST_MAXLEVEL - blevel);
  p->x &= mask;
  p->y &= mask;
#ifdef P4_TO_P8
  p->z &= mask;
#endif
  p->level = blevel;
  P4EST_ASSERT (p4est_quadrant_is_extended (p));

  if (add != NULL) {

    add[nconextra / 2] = *p;

    /* this is the only quad needed if it is only one level smaller than the
     * original quadrant */
    if (blevel == plevel - 1) {
      return;
    }

    mask = -1 << (P4EST_MAXLEVEL - (blevel - 1));
    pmask = -1 << (P4EST_MAXLEVEL - (plevel));
    a = *p;
    a.x &= mask;
    a.y &= mask;
#ifdef P4_TO_P8
    a.z &= mask;
#endif
    a.level = blevel - 1;

    b1len = P4EST_QUADRANT_LEN (blevel - 1);
#ifndef P4_TO_P8
    for (i = -1; i <= 1; i += 2) {
      temp = a;
      /* temp is in a family group one family group over from temp */
      if (face / 2 == 0) {
        temp.y += i * b1len;
      }
      else {
        temp.x += i * b1len;
      }

      if ((temp.x & pmask) != porig.x || (temp.y & pmask) != porig.y) {
        /* only test other descendents of p */
        continue;
      }

      child = p4est_face_corners[face][(1 - i) / 2];

      p4est_bal_corner_con_internal (q, &temp, child, balance, &recon);

      if (!recon) {
        add[1 + i] = temp;
      }
    }
#else
    b2mask = -1 << (P4EST_MAXLEVEL - (blevel - 2));
    if (!balance) {
      achild = p8est_quadrant_child_id (&a);
    }
    for (j = -1; j <= 1; j++) {
      for (i = -1; i <= 1; i++) {
        if (!i & !j) {
          continue;
        }
        temp = a;
        switch (face / 2) {
        case 0:
          temp.y += i * b1len;
          temp.z += j * b1len;
          break;
        case 1:
          temp.x += i * b1len;
          temp.z += j * b1len;
          break;
        case 2:
          temp.x += i * b1len;
          temp.y += j * b1len;
          break;
        default:
          SC_ABORT_NOT_REACHED ();
        }

        if ((temp.x & pmask) != porig.x || (temp.y & pmask) != porig.y ||
            (temp.z & pmask) != porig.z) {
          /* only test other descendents of p */
          continue;
        }

        if (i && j) {

          child = p8est_face_corners[face][(1 - j) + (1 - i) / 2];

          /* for face only balance, we need to check a larger neighbor in one
           * instance */
          if (!balance) {
            dual = p8est_face_corners[face][(1 + j) + (1 + i) / 2];

            if (achild == dual) {
              temp.x &= b2mask;
              temp.y &= b2mask;
              temp.z &= b2mask;
              temp.level = blevel - 2;
            }
          }

          p4est_bal_corner_con_internal (q, &temp, child, balance, &recon);

          if (!recon) {
            add[4 + 3 * j + i] = temp;
          }
        }
        else {
          if (!i) {
            edge = p8est_face_edges[face][(1 - j) / 2];
          }
          else {
            edge = p8est_face_edges[face][2 + (1 - i) / 2];
          }

          p8est_bal_edge_con_internal (q, &temp, edge, balance, &recon, NULL);

          if (!recon) {
            add[4 + 3 * j + i] = temp;
          }
        }

      }
    }

    if (!balance) {
      for (j = -1; j <= 1; j += 2) {
        for (i = -1; i <= 1; i += 2) {
          if (add[4 + 3 * j + i].level != -1 &&
              add[4 + 3 * j + i].level < blevel) {
            if (add[4 + 3 * j].level != -1 || add[4 + i].level != -1) {
              memset (&(add[4 + 3 * j + i]), -1, sizeof (p4est_quadrant_t));
            }
          }
        }
      }
    }
#endif
  }
}
Example #11
0
/* \a corner is the corner of \a p closest to \a q: the corner of \a q closest
 * to \a p is the dual of \a corner */
static void
p4est_bal_corner_con_internal (p4est_quadrant_t const *q,
                               p4est_quadrant_t * p,
                               int corner, int balance, int *consistent)
{
  int                 qlevel = q->level;
  int                 plevel = p->level;
  int                 blevel;
  p4est_qcoord_t      qlen, plen, mask;
  p4est_qcoord_t      dx, dy, dist;
#ifdef P4_TO_P8
  p4est_qcoord_t      dz;
#endif

  P4EST_ASSERT (p4est_quadrant_is_extended (q));
  P4EST_ASSERT (p4est_quadrant_is_extended (p));

  if (qlevel <= plevel) {
    if (consistent != NULL) {
      *consistent = 1;
    }
    return;
  }

  qlen = P4EST_QUADRANT_LEN (qlevel);
  plen = P4EST_QUADRANT_LEN (plevel);

  dx = (corner & 1) ? ((q->x + qlen) - (p->x + plen)) : p->x - q->x;
  P4EST_ASSERT (dx >= 0);
  dy = (corner & 2) ? ((q->y + qlen) - (p->y + plen)) : p->y - q->y;
  P4EST_ASSERT (dy >= 0);
#ifdef P4_TO_P8
  dz = (corner & 4) ? ((q->z + qlen) - (p->z + plen)) : p->z - q->z;
  P4EST_ASSERT (dz >= 0);
#endif

#ifndef P4_TO_P8
  if (balance) {
    dist = SC_MAX (dx, dy);
    blevel = p4est_balance_kernel_1d (dist, qlevel);
  }
  else {
    blevel = p4est_balance_kernel_2d (dx, dy, qlevel);
  }
#else
  switch (balance) {
  case 0:
    blevel = p8est_balance_kernel_3d_face (dx, dy, dz, qlevel);
    break;
  case 1:
    blevel = p8est_balance_kernel_3d_edge (dx, dy, dz, qlevel);
    break;
  case 2:
    dist = SC_MAX (dx, dy);
    dist = SC_MAX (dist, dz);
    blevel = p4est_balance_kernel_1d (dist, qlevel);
    break;
  default:
    SC_ABORT_NOT_REACHED ();
  }
#endif

  if (blevel <= plevel) {
    if (consistent != NULL) {
      *consistent = 1;
    }
    return;
  }

  if (consistent != NULL) {
    *consistent = 0;
  }

  mask = -1 << (P4EST_MAXLEVEL - blevel);
  p->x = q->x + ((corner & 1) ? -dx : dx);
  p->x &= mask;
  p->y = q->y + ((corner & 2) ? -dy : dy);
  p->y &= mask;
#ifdef P4_TO_P8
  p->z = q->z + ((corner & 4) ? -dz : dz);
  p->z &= mask;
#endif
  p->level = blevel;
  P4EST_ASSERT (p4est_quadrant_is_extended (p));
}