Example #1
0
/* This is the kernel for 3d balance with face balancing only */
static inline int
p8est_balance_kernel_3d_face (p4est_qcoord_t dx, p4est_qcoord_t dy,
                              p4est_qcoord_t dz, int level)
{
  int                 shift = P4EST_MAXLEVEL - level;
  int                 maxbit;
  int                 yzbit, zxbit, xybit;
  p4est_qcoord_t      dyz, dzx, dxy, bitwor;
  int                 ret;

  P4EST_ASSERT (dx >= 0);
  P4EST_ASSERT (!(dx & (~(((p4est_qcoord_t) - 1) << shift))));
  P4EST_ASSERT (dy >= 0);
  P4EST_ASSERT (!(dy & (~(((p4est_qcoord_t) - 1) << shift))));
  P4EST_ASSERT (dz >= 0);
  P4EST_ASSERT (!(dz & (~(((p4est_qcoord_t) - 1) << shift))));

  if (!dx && !dy && !dz) {
    return level;
  }

  dx >>= shift;
  /* get the smallest even number greater than or equal to dx */
  dx = (dx + 1) & (~((p4est_qcoord_t) 0x1));

  dy >>= shift;
  /* get the smallest even number greater than or equal to dy */
  dy = (dy + 1) & (~((p4est_qcoord_t) 0x1));

  dz >>= shift;
  /* get the smallest even number greater than or equal to dz */
  dz = (dz + 1) & (~((p4est_qcoord_t) 0x1));

  /* this problem is dual to dual to kernel 3d edge */
  dyz = dy + dz;
  dzx = dz + dx;
  dxy = dx + dy;

  yzbit = SC_LOG2_32 (dyz);
  maxbit = yzbit;
  zxbit = SC_LOG2_32 (dzx);
  maxbit = SC_MAX (maxbit, zxbit);
  xybit = SC_LOG2_32 (dxy);
  maxbit = SC_MAX (maxbit, xybit);
  P4EST_ASSERT (maxbit >= 1);

  /* we want to carry a 1 when there are three 1 bits, so we find places
   * where there is at least one 1 bit and subtract one 1 bit: then if we
   * sum, the binary carry rule will give the correct result */
  bitwor = (dyz | dzx | dxy);
  ret = SC_LOG2_32 (dyz + dzx + dxy - bitwor);
  /* we have to guard against the case when the leading position has one 1
   * bit. */
  ret = SC_MAX (maxbit, ret);
  return SC_MAX (0, level - ret);
}
Example #2
0
static void
p6est_profile_balance_full_one_pass (sc_array_t * read, sc_array_t * write,
                                     p4est_qcoord_t readh)
{
  int8_t             *wc;
  size_t              count;
  int                 stackcount;
  int8_t              n, nn, newn, p, l, prevl, nextl;
  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));

  count = read->elem_count;

  sc_array_truncate (write);
  l = 0;
  zy = 0;
  while (zy < count) {
    n = *((int8_t *) sc_array_index (read, count - 1 - zy++));
    if (n && !(readh & P4EST_QUADRANT_LEN (n))) {
      P4EST_ASSERT (zy < count);
      nn = *((int8_t *) sc_array_index (read, count - 1 - zy));
      if (n == nn) {
        if (zy > 1) {
          prevl = *((int8_t *) sc_array_index (read, count - 1 - (zy - 2)));
        }
        else {
          prevl = -1;
        }
        if (zy < count - 1) {
          nextl = *((int8_t *) sc_array_index (read, count - 1 - (zy + 1)));
        }
        else {
          nextl = -1;
        }
        if (n >= SC_MAX (nextl, prevl) - 1) {
          zy++;
          n--;
        }
      }
    }
    readh += P4EST_QUADRANT_LEN (n);
    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--;
    }
  }
}
Example #3
0
void
sc_log_indent_pop_count (int package, int count)
{
  /* TODO: figure out a version that makes sense with threads */
#ifndef SC_ENABLE_PTHREAD
  int                 new_indent;

  SC_ASSERT (package < sc_num_packages);

  if (package >= 0) {
    new_indent = sc_packages[package].log_indent - SC_MAX (0, count);
    sc_packages[package].log_indent = SC_MAX (0, new_indent);
  }
#endif
}
Example #4
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--;
    }
  }
}
Example #5
0
/* This is the kernel for 2D balance with face-only balancing */
static inline int
p4est_balance_kernel_2d (p4est_qcoord_t dx, p4est_qcoord_t dy, int level)
{
  int                 shift = P4EST_MAXLEVEL - level;
  p4est_qcoord_t      distance;

  P4EST_ASSERT (0 <= level && level <= P4EST_QMAXLEVEL);
  /* the distance only makes sense if it is an integer number of \a level
   * distances */
  P4EST_ASSERT (dx >= 0);
  P4EST_ASSERT (!(dx & (~(((p4est_qcoord_t) - 1) << shift))));
  P4EST_ASSERT (dy >= 0);
  P4EST_ASSERT (!(dy & (~(((p4est_qcoord_t) - 1) << shift))));

  dx >>= shift;
  /* get the smallest even number greater than or equal to dx */
  dx = (dx + 1) & (~((p4est_qcoord_t) 0x1));

  dy >>= shift;
  /* get the smallest even number greater than or equal to dy */
  dy = (dy + 1) & (~((p4est_qcoord_t) 0x1));

  /* the + 1 guarantees the correct answer even for (0, 0) */
  distance = dx + dy + 1;

  return SC_MAX (0, level - SC_LOG2_32 (distance));
}
Example #6
0
/** Compute the maximum state value.
 *
 * This function updates the maximum value from the value of a single cell.
 *
 * This function matches the p4est_iter_volume_t prototype used by
 * p4est_iterate().
 *
 * \param [in] info              the information about this quadrant that has been
 *                               populated by p4est_iterate()
 * \param [in,out] user_data     the user_data given to p4est_iterate(): in this case,
 *                               it points to the maximum value that will be updated
 */
static void
step3_compute_max (p4est_iter_volume_info_t * info, void *user_data)
{
  p4est_quadrant_t   *q = info->quad;
  step3_data_t       *data = (step3_data_t *) q->p.user_data;
  double              umax = *((double *) user_data);

  umax = SC_MAX (data->u, umax);

  *((double *) user_data) = umax;
}
Example #7
0
/* We have a location, and a \a level quadrant that must be shifted by
 * \a distance (>= 0) to be at the location.  This returns the largest quadrant
 * that can exist at \a location and be in balance with the \a level quadrant.
 */
static inline int
p4est_balance_kernel_1d (p4est_qcoord_t distance, int level)
{
  int                 shift = P4EST_MAXLEVEL - level;
  P4EST_ASSERT (0 <= level && level <= P4EST_QMAXLEVEL);
  /* the distance only makes sense if it is an integer number of \a level
   * distances */
  P4EST_ASSERT (distance >= 0);
  P4EST_ASSERT (!(distance & (~(((p4est_qcoord_t) - 1) << shift))));
  distance >>= shift;
  /* The theory says we should use ((distance + 1)&(~1) + 1), but
   * using distance + 1 is equivalent for all distance >= 0 */
  distance++;

  return SC_MAX (0, level - SC_LOG2_32 (distance));
}
Example #8
0
/** Compute the timestep.
 *
 * Find the smallest quadrant and scale the timestep based on that length and
 * the advection velocity.
 *
 * \param [in] p4est the forest
 * \return the timestep.
 */
static double
step3_get_timestep (p4est_t * p4est)
{
  step3_ctx_t        *ctx = (step3_ctx_t *) p4est->user_pointer;
  p4est_topidx_t      t, flt, llt;
  p4est_tree_t       *tree;
  int                 max_level, global_max_level;
  int                 mpiret, i;
  double              min_h, vnorm;
  double              dt;

  /* compute the timestep by finding the smallest quadrant */
  flt = p4est->first_local_tree;
  llt = p4est->last_local_tree;

  max_level = 0;
  for (t = flt; t <= llt; t++) {
    tree = p4est_tree_array_index (p4est->trees, t);
    max_level = SC_MAX (max_level, tree->maxlevel);

  }
  mpiret =
    sc_MPI_Allreduce (&max_level, &global_max_level, 1, sc_MPI_INT,
                      sc_MPI_MAX, p4est->mpicomm);
  SC_CHECK_MPI (mpiret);

  min_h =
    (double) P4EST_QUADRANT_LEN (global_max_level) / (double) P4EST_ROOT_LEN;

  vnorm = 0;
  for (i = 0; i < P4EST_DIM; i++) {
    vnorm += ctx->v[i] * ctx->v[i];
  }
  vnorm = sqrt (vnorm);

  dt = min_h / 2. / vnorm;

  return dt;
}
Example #9
0
int
main (int argc, char **argv)
{
  sc_MPI_Comm         mpicomm;
  int                 mpiret;
  int                 mpisize, mpirank;
  unsigned            crc;
#ifndef P4_TO_P8
  size_t              kz;
  int8_t              l;
  p4est_quadrant_t   *q;
  p4est_tree_t        stree, *tree = &stree;
#endif
  p4est_t            *p4est;
  p4est_connectivity_t *connectivity;

  /* initialize MPI */
  mpiret = sc_MPI_Init (&argc, &argv);
  SC_CHECK_MPI (mpiret);
  mpicomm = sc_MPI_COMM_WORLD;
  mpiret = sc_MPI_Comm_size (mpicomm, &mpisize);
  SC_CHECK_MPI (mpiret);
  mpiret = sc_MPI_Comm_rank (mpicomm, &mpirank);
  SC_CHECK_MPI (mpiret);

  sc_init (mpicomm, 1, 1, NULL, SC_LP_DEFAULT);
  p4est_init (NULL, SC_LP_DEFAULT);

#ifndef P4_TO_P8
  connectivity = p4est_connectivity_new_star ();
#else
  connectivity = p8est_connectivity_new_rotcubes ();
#endif
  p4est = p4est_new_ext (mpicomm, connectivity, 0, 0, 0, 4, NULL, NULL);

#ifndef P4_TO_P8
  /* build empty tree */
  sc_array_init (&tree->quadrants, sizeof (p4est_quadrant_t));
  for (l = 0; l <= P4EST_MAXLEVEL; ++l) {
    tree->quadrants_per_level[l] = 0;
  }
  tree->maxlevel = 0;

  /* insert two quadrants */
  sc_array_resize (&tree->quadrants, 4);
  q = p4est_quadrant_array_index (&tree->quadrants, 0);
  p4est_quadrant_set_morton (q, 3, 13);
  q = p4est_quadrant_array_index (&tree->quadrants, 1);
  p4est_quadrant_set_morton (q, 1, 1);
  q = p4est_quadrant_array_index (&tree->quadrants, 2);
  p4est_quadrant_set_morton (q, 1, 2);
  q = p4est_quadrant_array_index (&tree->quadrants, 3);
  p4est_quadrant_set_morton (q, 1, 3);
  for (kz = 0; kz < tree->quadrants.elem_count; ++kz) {
    q = p4est_quadrant_array_index (&tree->quadrants, kz);
    q->p.user_data = sc_mempool_alloc (p4est->user_data_pool);
    ++tree->quadrants_per_level[q->level];
    tree->maxlevel = (int8_t) SC_MAX (tree->maxlevel, q->level);
  }

  /* balance the tree, print and destroy */
#if 0
  p4est_balance_subtree (p4est, P4EST_CONNECT_FULL, 0, NULL);
  p4est_tree_print (SC_LP_INFO, tree);
#endif
  for (kz = 0; kz < tree->quadrants.elem_count; ++kz) {
    q = p4est_quadrant_array_index (&tree->quadrants, kz);
    sc_mempool_free (p4est->user_data_pool, q->p.user_data);
  }
  sc_array_reset (&tree->quadrants);
#endif /* !P4_TO_P8 */

  /* check reset data function */
  p4est_reset_data (p4est, 0, init_fn, NULL);
  p4est_reset_data (p4est, 0, NULL, NULL);

  /* refine and balance the forest */
  SC_CHECK_ABORT (p4est_is_balanced (p4est, P4EST_CONNECT_FULL), "Balance 1");
  p4est_refine (p4est, 1, refine_fn, NULL);
  SC_CHECK_ABORT (!p4est_is_balanced (p4est, P4EST_CONNECT_FULL),
                  "Balance 2");
  p4est_balance (p4est, P4EST_CONNECT_FULL, NULL);
  SC_CHECK_ABORT (p4est_is_balanced (p4est, P4EST_CONNECT_FULL), "Balance 3");

  /* check reset data function */
  p4est_reset_data (p4est, 17, NULL, NULL);
  p4est_reset_data (p4est, 8, init_fn, NULL);

  /* checksum and partition */
  crc = p4est_checksum (p4est);
  p4est_partition (p4est, 0, NULL);
  SC_CHECK_ABORT (p4est_checksum (p4est) == crc, "Partition");
  SC_CHECK_ABORT (p4est_is_balanced (p4est, P4EST_CONNECT_FULL), "Balance 4");

  /* check reset data function */
  p4est_reset_data (p4est, 3, NULL, NULL);
  p4est_reset_data (p4est, 3, NULL, NULL);

  /* checksum and rebalance */
  crc = p4est_checksum (p4est);
  p4est_balance (p4est, P4EST_CONNECT_FULL, NULL);
  SC_CHECK_ABORT (p4est_checksum (p4est) == crc, "Rebalance");

  /* clean up and exit */
  P4EST_ASSERT (p4est->user_data_pool->elem_count ==
                (size_t) p4est->local_num_quadrants);
  p4est_destroy (p4est);
  p4est_connectivity_destroy (connectivity);

  sc_finalize ();

  mpiret = sc_MPI_Finalize ();
  SC_CHECK_MPI (mpiret);

  return 0;
}
Example #10
0
int
main (int argc, char **argv)
{
  const p4est_qcoord_t qone = 1;
  int                 mpiret;
  int                 k;
  int                 level, mid, cid;
  int                 id0, id1, id2, id3;
  int64_t             index1, index2;
  size_t              iz, jz, incount;
  p4est_qcoord_t      mh = P4EST_QUADRANT_LEN (P4EST_QMAXLEVEL);
  p4est_connectivity_t *connectivity;
  p4est_t            *p4est1;
  p4est_t            *p4est2;
  p4est_tree_t       *t1, *t2, tree;
  p4est_quadrant_t   *p, *q1, *q2;
  p4est_quadrant_t    r, s;
  p4est_quadrant_t    c0, c1, c2, c3;
  p4est_quadrant_t    cv[P4EST_CHILDREN], *cp[P4EST_CHILDREN];
  p4est_quadrant_t    A, B, C, D, E, F, G, H, I, P, Q;
  p4est_quadrant_t    a, f, g, h;
  uint64_t            Aid, Fid;

  /* initialize MPI */
  mpiret = sc_MPI_Init (&argc, &argv);
  SC_CHECK_MPI (mpiret);

  /* create connectivity and forest structures */
  connectivity = p4est_connectivity_new_unitsquare ();
  p4est1 = p4est_new_ext (sc_MPI_COMM_SELF, connectivity, 15, 0, 0,
                          0, NULL, NULL);
  p4est2 = p4est_new_ext (sc_MPI_COMM_SELF, connectivity, 15, 0, 0,
                          8, NULL, NULL);

  /* refine the second tree to a uniform level */
  p4est_refine (p4est1, 1, refine_none, NULL);
  p4est_refine (p4est2, 1, refine_some, NULL);
  t1 = p4est_tree_array_index (p4est1->trees, 0);
  t2 = p4est_tree_array_index (p4est2->trees, 0);
  SC_CHECK_ABORT (p4est_tree_is_sorted (t1), "is_sorted");
  SC_CHECK_ABORT (p4est_tree_is_sorted (t2), "is_sorted");

  /* run a bunch of cross-tests */
  p = NULL;
  for (iz = 0; iz < t1->quadrants.elem_count; ++iz) {
    q1 = p4est_quadrant_array_index (&t1->quadrants, iz);

    /* test the index conversion */
    index1 = p4est_quadrant_linear_id (q1, (int) q1->level);
    p4est_quadrant_set_morton (&r, (int) q1->level, index1);
    index2 = p4est_quadrant_linear_id (&r, (int) r.level);
    SC_CHECK_ABORT (index1 == index2, "index conversion");
    level = (int) q1->level - 1;
    if (level >= 0) {
      index1 = p4est_quadrant_linear_id (q1, level);
      p4est_quadrant_set_morton (&r, level, index1);
      index2 = p4est_quadrant_linear_id (&r, level);
      SC_CHECK_ABORT (index1 == index2, "index conversion");
    }

    /* test the is_next function */
    if (p != NULL) {
      SC_CHECK_ABORT (p4est_quadrant_is_next (p, q1), "is_next");
    }
    p = q1;

    /* test the is_family function */
    p4est_quadrant_children (q1, &c0, &c1, &c2, &c3);
    SC_CHECK_ABORT (p4est_quadrant_is_family (&c0, &c1, &c2, &c3),
                    "is_family");
    SC_CHECK_ABORT (!p4est_quadrant_is_family (&c1, &c0, &c2, &c3),
                    "is_family");
    SC_CHECK_ABORT (!p4est_quadrant_is_family (&c0, &c0, &c1, &c2),
                    "is_family");
    p4est_quadrant_childrenv (q1, cv);
    SC_CHECK_ABORT (p4est_quadrant_is_equal (&c0, &cv[0]), "is_family");
    SC_CHECK_ABORT (p4est_quadrant_is_equal (&c1, &cv[1]), "is_family");
    SC_CHECK_ABORT (p4est_quadrant_is_equal (&c2, &cv[2]), "is_family");
    SC_CHECK_ABORT (p4est_quadrant_is_equal (&c3, &cv[3]), "is_family");
    SC_CHECK_ABORT (p4est_quadrant_is_family (&cv[0], &cv[1], &cv[2], &cv[3]),
                    "is_family");
    cp[0] = &cv[0];
    cp[1] = &cv[1];
    cp[2] = &cv[2];
    cp[3] = &cv[3];
    SC_CHECK_ABORT (p4est_quadrant_is_familypv (cp), "is_family");
    cv[1] = cv[0];
    SC_CHECK_ABORT (!p4est_quadrant_is_familyv (cv), "is_family");
    cp[1] = &c1;
    SC_CHECK_ABORT (p4est_quadrant_is_familypv (cp), "is_family");
    cp[2] = &c3;
    SC_CHECK_ABORT (!p4est_quadrant_is_familypv (cp), "is_family");

    /* test the sibling function */
    mid = p4est_quadrant_child_id (q1);
    for (cid = 0; cid < 4; ++cid) {
      p4est_quadrant_sibling (q1, &r, cid);
      if (cid != mid) {
        SC_CHECK_ABORT (p4est_quadrant_is_sibling (q1, &r), "sibling");
      }
      else {
        SC_CHECK_ABORT (p4est_quadrant_is_equal (q1, &r), "sibling");
      }
    }

    /* test t1 against itself */
    for (jz = 0; jz < t1->quadrants.elem_count; ++jz) {
      q2 = p4est_quadrant_array_index (&t1->quadrants, jz);

      /* test the comparison function */
      SC_CHECK_ABORT (p4est_quadrant_compare (q1, q2) ==
                      -p4est_quadrant_compare (q2, q1), "compare");
      SC_CHECK_ABORT ((p4est_quadrant_compare (q1, q2) == 0) ==
                      p4est_quadrant_is_equal (q1, q2), "is_equal");

      /* test the descriptive versions of functions */
      SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (q1, q2) ==
                      p4est_quadrant_is_sibling (q1, q2), "is_sibling");
      SC_CHECK_ABORT (p4est_quadrant_is_parent_D (q1, q2) ==
                      p4est_quadrant_is_parent (q1, q2), "is_parent");
      SC_CHECK_ABORT (p4est_quadrant_is_parent_D (q2, q1) ==
                      p4est_quadrant_is_parent (q2, q1), "is_parent");
      SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (q1, q2) ==
                      p4est_quadrant_is_ancestor (q1, q2), "is_ancestor");
      SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (q2, q1) ==
                      p4est_quadrant_is_ancestor (q2, q1), "is_ancestor");
      SC_CHECK_ABORT (p4est_quadrant_is_next_D (q1, q2) ==
                      p4est_quadrant_is_next (q1, q2), "is_next");
      SC_CHECK_ABORT (p4est_quadrant_is_next_D (q2, q1) ==
                      p4est_quadrant_is_next (q2, q1), "is_next");
      p4est_nearest_common_ancestor_D (q1, q2, &r);
      p4est_nearest_common_ancestor (q1, q2, &s);
      SC_CHECK_ABORT (p4est_quadrant_is_equal (&r, &s), "common_ancestor");
      p4est_nearest_common_ancestor_D (q2, q1, &r);
      p4est_nearest_common_ancestor (q2, q1, &s);
      SC_CHECK_ABORT (p4est_quadrant_is_equal (&r, &s), "common_ancestor");
    }

    /* test t1 against t2 */
    for (jz = 0; jz < t2->quadrants.elem_count; ++jz) {
      q2 = p4est_quadrant_array_index (&t2->quadrants, jz);

      /* test the comparison function */
      SC_CHECK_ABORT (p4est_quadrant_compare (q1, q2) ==
                      -p4est_quadrant_compare (q2, q1), "compare");
      SC_CHECK_ABORT ((p4est_quadrant_compare (q1, q2) == 0) ==
                      p4est_quadrant_is_equal (q1, q2), "is_equal");

      /* test the descriptive versions of functions */
      SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (q1, q2) ==
                      p4est_quadrant_is_sibling (q1, q2), "is_sibling");
      SC_CHECK_ABORT (p4est_quadrant_is_parent_D (q1, q2) ==
                      p4est_quadrant_is_parent (q1, q2), "is_parent");
      SC_CHECK_ABORT (p4est_quadrant_is_parent_D (q2, q1) ==
                      p4est_quadrant_is_parent (q2, q1), "is_parent");
      SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (q1, q2) ==
                      p4est_quadrant_is_ancestor (q1, q2), "is_ancestor");
      SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (q2, q1) ==
                      p4est_quadrant_is_ancestor (q2, q1), "is_ancestor");
      SC_CHECK_ABORT (p4est_quadrant_is_next_D (q1, q2) ==
                      p4est_quadrant_is_next (q1, q2), "is_next");
      SC_CHECK_ABORT (p4est_quadrant_is_next_D (q2, q1) ==
                      p4est_quadrant_is_next (q2, q1), "is_next");
      p4est_nearest_common_ancestor_D (q1, q2, &r);
      p4est_nearest_common_ancestor (q1, q2, &s);
      SC_CHECK_ABORT (p4est_quadrant_is_equal (&r, &s), "common_ancestor");
      p4est_nearest_common_ancestor_D (q2, q1, &r);
      p4est_nearest_common_ancestor (q2, q1, &s);
      SC_CHECK_ABORT (p4est_quadrant_is_equal (&r, &s), "common_ancestor");
    }
  }

  p = NULL;
  for (iz = 0; iz < t2->quadrants.elem_count; ++iz) {
    q1 = p4est_quadrant_array_index (&t2->quadrants, iz);

    /* test the is_next function */
    if (p != NULL) {
      SC_CHECK_ABORT (p4est_quadrant_is_next (p, q1), "is_next");
    }
    p = q1;
  }

  /* test the coarsen function */
  p4est_coarsen (p4est1, 1, coarsen_none, NULL);
  p4est_coarsen (p4est1, 1, coarsen_all, NULL);
  p4est_coarsen (p4est2, 1, coarsen_some, NULL);

  /* test the linearize algorithm */
  incount = t2->quadrants.elem_count;
  (void) p4est_linearize_tree (p4est2, t2);
  SC_CHECK_ABORT (incount == t2->quadrants.elem_count, "linearize");

  /* this is user_data neutral only when p4est1->data_size == 0 */
  sc_array_init (&tree.quadrants, sizeof (p4est_quadrant_t));
  sc_array_resize (&tree.quadrants, 18);
  q1 = p4est_quadrant_array_index (&tree.quadrants, 0);
  q2 = p4est_quadrant_array_index (&t2->quadrants, 0);
  *q1 = *q2;
  q2 = p4est_quadrant_array_index (&t2->quadrants, 1);
  for (k = 0; k < 3; ++k) {
    q1 = p4est_quadrant_array_index (&tree.quadrants, (size_t) (k + 1));
    *q1 = *q2;
    q1->level = (int8_t) (q1->level + k);
  }
  for (k = 0; k < 10; ++k) {
    q1 = p4est_quadrant_array_index (&tree.quadrants, (size_t) (k + 4));
    q2 = p4est_quadrant_array_index (&t2->quadrants, (size_t) (k + 3));
    *q1 = *q2;
    q1->level = (int8_t) (q1->level + k);
  }
  for (k = 0; k < 4; ++k) {
    q1 = p4est_quadrant_array_index (&tree.quadrants, (size_t) (k + 14));
    q2 = p4est_quadrant_array_index (&t2->quadrants, (size_t) (k + 12));
    *q1 = *q2;
    q1->level = (int8_t) (q1->level + 10 + k);
  }
  tree.maxlevel = 0;
  for (k = 0; k <= P4EST_QMAXLEVEL; ++k) {
    tree.quadrants_per_level[k] = 0;
  }
  for (; k <= P4EST_MAXLEVEL; ++k) {
    tree.quadrants_per_level[k] = -1;
  }
  incount = tree.quadrants.elem_count;
  for (iz = 0; iz < incount; ++iz) {
    q1 = p4est_quadrant_array_index (&tree.quadrants, iz);
    ++tree.quadrants_per_level[q1->level];
    tree.maxlevel = (int8_t) SC_MAX (tree.maxlevel, q1->level);
  }
  SC_CHECK_ABORT (!p4est_tree_is_linear (&tree), "is_linear");
  (void) p4est_linearize_tree (p4est1, &tree);
  SC_CHECK_ABORT (incount - 3 == tree.quadrants.elem_count, "linearize");
  sc_array_reset (&tree.quadrants);

  /* create a partial tree and check overlap */
  sc_array_resize (&tree.quadrants, 3);
  q1 = p4est_quadrant_array_index (&tree.quadrants, 0);
  p4est_quadrant_set_morton (q1, 1, 1);
  q1 = p4est_quadrant_array_index (&tree.quadrants, 1);
  p4est_quadrant_set_morton (q1, 2, 8);
  q1 = p4est_quadrant_array_index (&tree.quadrants, 2);
  p4est_quadrant_set_morton (q1, 2, 9);
  for (k = 0; k <= P4EST_QMAXLEVEL; ++k) {
    tree.quadrants_per_level[k] = 0;
  }
  for (; k <= P4EST_MAXLEVEL; ++k) {
    tree.quadrants_per_level[k] = -1;
  }
  tree.quadrants_per_level[1] = 1;
  tree.quadrants_per_level[2] = 2;
  tree.maxlevel = 2;
  p4est_quadrant_first_descendant (p4est_quadrant_array_index
                                   (&tree.quadrants, 0), &tree.first_desc,
                                   P4EST_QMAXLEVEL);
  p4est_quadrant_last_descendant (p4est_quadrant_array_index
                                  (&tree.quadrants,
                                   tree.quadrants.elem_count - 1),
                                  &tree.last_desc, P4EST_QMAXLEVEL);
  SC_CHECK_ABORT (p4est_tree_is_complete (&tree), "is_complete");

  p4est_quadrant_set_morton (&D, 0, 0);
  SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &D), "overlaps 0");

  p4est_quadrant_set_morton (&A, 1, 0);
  SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &A), "overlaps 1");
  p4est_quadrant_set_morton (&A, 1, 1);
  SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &A), "overlaps 2");
  p4est_quadrant_set_morton (&A, 1, 2);
  SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &A), "overlaps 3");
  p4est_quadrant_set_morton (&A, 1, 3);
  SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &A), "overlaps 4");

  p4est_quadrant_set_morton (&B, 3, 13);
  SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &B), "overlaps 5");
  p4est_quadrant_set_morton (&B, 3, 25);
  SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &B), "overlaps 6");
  p4est_quadrant_set_morton (&B, 3, 39);
  SC_CHECK_ABORT (p4est_quadrant_overlaps_tree (&tree, &B), "overlaps 7");
  p4est_quadrant_set_morton (&B, 3, 40);
  SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &B), "overlaps 8");

  p4est_quadrant_set_morton (&C, 4, 219);
  SC_CHECK_ABORT (!p4est_quadrant_overlaps_tree (&tree, &C), "overlaps 9");

  sc_array_reset (&tree.quadrants);

  /* destroy the p4est and its connectivity structure */
  p4est_destroy (p4est1);
  p4est_destroy (p4est2);
  p4est_connectivity_destroy (connectivity);

  /* This will test the ability to address negative quadrants */
  P4EST_QUADRANT_INIT (&A);
  P4EST_QUADRANT_INIT (&B);
  P4EST_QUADRANT_INIT (&C);
  P4EST_QUADRANT_INIT (&D);
  P4EST_QUADRANT_INIT (&E);
  P4EST_QUADRANT_INIT (&F);
  P4EST_QUADRANT_INIT (&G);
  P4EST_QUADRANT_INIT (&H);
  P4EST_QUADRANT_INIT (&I);
  P4EST_QUADRANT_INIT (&P);
  P4EST_QUADRANT_INIT (&Q);

  A.x = -qone << P4EST_MAXLEVEL;
  A.y = -qone << P4EST_MAXLEVEL;
  A.level = 0;

  B.x = qone << P4EST_MAXLEVEL;
  B.y = -qone << P4EST_MAXLEVEL;
  B.level = 0;

  C.x = -qone << P4EST_MAXLEVEL;
  C.y = qone << P4EST_MAXLEVEL;
  C.level = 0;

  D.x = qone << P4EST_MAXLEVEL;
  D.y = qone << P4EST_MAXLEVEL;
  D.level = 0;

  /* this one is outside the 3x3 box */
  E.x = -qone << (P4EST_MAXLEVEL + 1);
  E.y = -qone;
  E.level = 0;

  F.x = P4EST_ROOT_LEN + (P4EST_ROOT_LEN - mh);
  F.y = P4EST_ROOT_LEN + (P4EST_ROOT_LEN - mh);
  F.level = P4EST_QMAXLEVEL;

  G.x = -mh;
  G.y = -mh;
  G.level = P4EST_QMAXLEVEL;

  H.x = -qone << (P4EST_MAXLEVEL - 1);
  H.y = -qone << (P4EST_MAXLEVEL - 1);
  H.level = 1;

  I.x = -qone << P4EST_MAXLEVEL;
  I.y = -qone << (P4EST_MAXLEVEL - 1);
  I.level = 1;

  check_linear_id (&A, &A);
  check_linear_id (&A, &B);
  check_linear_id (&A, &C);
  check_linear_id (&A, &D);
  /* check_linear_id (&A, &E); */
  check_linear_id (&A, &F);
  check_linear_id (&A, &G);
  check_linear_id (&A, &H);
  check_linear_id (&A, &I);

  check_linear_id (&B, &A);
  check_linear_id (&B, &B);
  check_linear_id (&B, &C);
  check_linear_id (&B, &D);
  /* check_linear_id (&B, &E); */
  check_linear_id (&B, &F);
  check_linear_id (&B, &G);
  check_linear_id (&B, &H);
  check_linear_id (&B, &I);

  check_linear_id (&D, &A);
  check_linear_id (&D, &B);
  check_linear_id (&D, &C);
  check_linear_id (&D, &D);
  /* check_linear_id (&D, &E); */
  check_linear_id (&D, &F);
  check_linear_id (&D, &G);
  check_linear_id (&D, &H);
  check_linear_id (&D, &I);

  check_linear_id (&G, &A);
  check_linear_id (&G, &B);
  check_linear_id (&G, &C);
  check_linear_id (&G, &D);
  /* check_linear_id (&G, &E); */
  check_linear_id (&G, &F);
  check_linear_id (&G, &G);
  check_linear_id (&G, &H);
  check_linear_id (&G, &I);

  check_linear_id (&I, &A);
  check_linear_id (&I, &B);
  check_linear_id (&I, &C);
  check_linear_id (&I, &D);
  /* check_linear_id (&I, &E); */
  check_linear_id (&I, &F);
  check_linear_id (&I, &G);
  check_linear_id (&I, &H);
  check_linear_id (&I, &I);

  SC_CHECK_ABORT (p4est_quadrant_is_extended (&A) == 1, "is_extended A");
  SC_CHECK_ABORT (p4est_quadrant_is_extended (&B) == 1, "is_extended B");
  SC_CHECK_ABORT (p4est_quadrant_is_extended (&C) == 1, "is_extended C");
  SC_CHECK_ABORT (p4est_quadrant_is_extended (&D) == 1, "is_extended D");
  SC_CHECK_ABORT (!p4est_quadrant_is_extended (&E) == 1, "!is_extended E");
  SC_CHECK_ABORT (p4est_quadrant_is_extended (&F) == 1, "is_extended F");
  SC_CHECK_ABORT (p4est_quadrant_is_extended (&G) == 1, "is_extended G");

  SC_CHECK_ABORT (p4est_quadrant_compare (&A, &A) == 0, "compare");
  SC_CHECK_ABORT (p4est_quadrant_compare (&A, &B) > 0, "compare");
  SC_CHECK_ABORT (p4est_quadrant_compare (&B, &A) < 0, "compare");

  SC_CHECK_ABORT (p4est_quadrant_compare (&F, &F) == 0, "compare");
  SC_CHECK_ABORT (p4est_quadrant_compare (&G, &F) > 0, "compare");
  SC_CHECK_ABORT (p4est_quadrant_compare (&F, &G) < 0, "compare");

  A.p.which_tree = 0;
  B.p.piggy1.which_tree = 0;
  SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&A, &A) == 0,
                  "compare_piggy");
  SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&A, &B) > 0, "compare_piggy");
  SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&B, &A) < 0, "compare_piggy");

  F.p.piggy2.which_tree = 0;
  G.p.which_tree = 0;
  SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&F, &F) == 0,
                  "compare_piggy");
  SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&G, &F) > 0, "compare_piggy");
  SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&F, &G) < 0, "compare_piggy");

  F.p.piggy1.which_tree = (p4est_topidx_t) P4EST_TOPIDX_MAX - 3;
  G.p.piggy2.which_tree = (p4est_topidx_t) P4EST_TOPIDX_MAX / 2;
  SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&F, &F) == 0,
                  "compare_piggy");
  SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&G, &F) < 0, "compare_piggy");
  SC_CHECK_ABORT (p4est_quadrant_compare_piggy (&F, &G) > 0, "compare_piggy");

  SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &A) == 1, "is_equal");
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&F, &F) == 1, "is_equal");
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&G, &G) == 1, "is_equal");

  /* Not sure if these make sense because D, O and A are all level 0 */
#if 0
  SC_CHECK_ABORT (p4est_quadrant_is_sibling (&D, &O) == 1, "is_sibling");
  SC_CHECK_ABORT (p4est_quadrant_is_sibling (&D, &A) == 0, "is_sibling");
  SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (&D, &O) == 1, "is_sibling_D");
  SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (&D, &A) == 0, "is_sibling_D");
#endif

  SC_CHECK_ABORT (p4est_quadrant_is_sibling (&I, &H) == 1, "is_sibling");
  SC_CHECK_ABORT (p4est_quadrant_is_sibling (&I, &G) == 0, "is_sibling");
  SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (&I, &H) == 1, "is_sibling_D");
  SC_CHECK_ABORT (p4est_quadrant_is_sibling_D (&I, &G) == 0, "is_sibling_D");

  SC_CHECK_ABORT (p4est_quadrant_is_parent (&A, &H) == 1, "is_parent");
  SC_CHECK_ABORT (p4est_quadrant_is_parent (&H, &A) == 0, "is_parent");
  SC_CHECK_ABORT (p4est_quadrant_is_parent (&A, &D) == 0, "is_parent");
  SC_CHECK_ABORT (p4est_quadrant_is_parent_D (&A, &H) == 1, "is_parent_D");

  SC_CHECK_ABORT (p4est_quadrant_is_ancestor (&A, &G) == 1, "is_ancestor");
  SC_CHECK_ABORT (p4est_quadrant_is_ancestor (&G, &A) == 0, "is_ancestor");

  SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (&A, &G) == 1,
                  "is_ancestor_D");
  SC_CHECK_ABORT (p4est_quadrant_is_ancestor_D (&G, &A) == 0,
                  "is_ancestor_D");

  /* SC_CHECK_ABORT (p4est_quadrant_is_next (&F, &E) == 1, "is_next"); */
  SC_CHECK_ABORT (p4est_quadrant_is_next (&A, &H) == 0, "is_next");
  /* SC_CHECK_ABORT (p4est_quadrant_is_next_D (&F, &E) == 1, "is_next_D"); */
  SC_CHECK_ABORT (p4est_quadrant_is_next_D (&A, &H) == 0, "is_next_D");

  p4est_quadrant_parent (&H, &a);
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &a) == 1, "parent");

  p4est_quadrant_sibling (&I, &h, 3);
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&H, &h) == 1, "sibling");

  p4est_quadrant_children (&A, &c0, &c1, &c2, &c3);
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&c2, &I) == 1, "children");
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&c3, &H) == 1, "children");
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&c3, &G) == 0, "children");

  SC_CHECK_ABORT (p4est_quadrant_is_family (&c0, &c1, &c2, &c3) == 1,
                  "is_family");
  id0 = p4est_quadrant_child_id (&c0);
  id1 = p4est_quadrant_child_id (&c1);
  id2 = p4est_quadrant_child_id (&c2);
  id3 = p4est_quadrant_child_id (&c3);
  SC_CHECK_ABORT (id0 == 0 && id1 == 1 && id2 == 2 && id3 == 3, "child_id");
  SC_CHECK_ABORT (p4est_quadrant_child_id (&G) == 3, "child_id");

  p4est_quadrant_first_descendant (&A, &c1, 1);
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&c0, &c1) == 1,
                  "first_descendant");

  p4est_quadrant_last_descendant (&A, &g, P4EST_QMAXLEVEL);
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&G, &g) == 1, "last_descendant");

  Fid = p4est_quadrant_linear_id (&F, P4EST_QMAXLEVEL);
  p4est_quadrant_set_morton (&f, P4EST_QMAXLEVEL, Fid);
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&F, &f) == 1,
                  "set_morton/linear_id");

  Aid = p4est_quadrant_linear_id (&A, 0);
  p4est_quadrant_set_morton (&a, 0, Aid);
  SC_CHECK_ABORT (Aid == 15, "linear_id");
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &a) == 1,
                  "set_morton/linear_id");

  p4est_nearest_common_ancestor (&I, &H, &a);
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &a) == 1, "ancestor");

  p4est_nearest_common_ancestor_D (&I, &H, &a);
  SC_CHECK_ABORT (p4est_quadrant_is_equal (&A, &a) == 1, "ancestor_D");

  for (k = 0; k < 16; ++k) {
    if (k != 4 && k != 6 && k != 8 && k != 9 && k != 12 && k != 13 && k != 14) {
      p4est_quadrant_set_morton (&E, 0, (uint64_t) k);
    }
  }
  p4est_quadrant_set_morton (&P, 0, 10);
  p4est_quadrant_set_morton (&Q, 0, 11);
  SC_CHECK_ABORT (p4est_quadrant_is_next (&P, &Q), "is_next");
  SC_CHECK_ABORT (!p4est_quadrant_is_next (&A, &Q), "is_next");

  sc_finalize ();

  mpiret = sc_MPI_Finalize ();
  SC_CHECK_MPI (mpiret);

  return 0;
}
Example #11
0
static void
test_tree (p8est_geometry_t * geom, p4est_topidx_t which_tree,
           const double bounds[6], int N)
{
    const double        epsilon = 1e-8;
    int                 i, j, k, l, m;
    double              h[3];
    double              xyz[4][3], XYZ[4][3];
    double              Jgeom[3][3], Jdisc[3][3];
    double              detD, detJ, fd, fg;
    double              diffD, diffJ, maxJ;

    for (l = 0; l < 3; ++l) {
        h[l] = bounds[2 * l + 1] - bounds[2 * l];
    }

    for (i = 0; i < N; ++i) {
        xyz[3][2] = ((N - (i + .5)) * bounds[4] + (i + .5) * bounds[5]) / N;
        for (j = 0; j < N; ++j) {
            xyz[3][1] = ((N - (j + .5)) * bounds[2] + (j + .5) * bounds[3]) / N;
            for (k = 0; k < N; ++k) {
                xyz[3][0] = ((N - (k + .5)) * bounds[0] + (k + .5) * bounds[1]) / N;

                /* compute transformed point */
                geom->X (geom, which_tree, xyz[3], XYZ[3]);

                /* offset point three times in the coordinate directions */
                for (l = 0; l < 3; ++l) {       /* l runs in domain */
                    memcpy (xyz[l], xyz[3], 3 * sizeof (double));
                    xyz[l][l] += epsilon * h[l];
                    geom->X (geom, which_tree, xyz[l], XYZ[l]);

                    for (m = 0; m < 3; ++m) {     /* m runs in image domain */
                        Jdisc[m][l] = (XYZ[l][m] - XYZ[3][m]) / (epsilon * h[l]);
                    }
                }
                detJ = geom->J (geom, which_tree, xyz[3], Jgeom);
                detD = geom->D (geom, which_tree, xyz[3]);

                /* compare results */
                diffD = fabs (detD - detJ) / SC_MAX (detD, detJ);
                SC_CHECK_ABORTF (diffD < 1e-8, "Determinant mismatch %lld %g %g %g",
                                 (long long) which_tree, xyz[3][0], xyz[3][1],
                                 xyz[3][2]);

                diffJ = maxJ = 0.;
                for (l = 0; l < 3; ++l) {
                    for (m = 0; m < 3; ++m) {
                        fd = fabs (Jdisc[m][l]);
                        fg = fabs (Jgeom[m][l]);
                        maxJ = SC_MAX (maxJ, fd);
                        maxJ = SC_MAX (maxJ, fg);
                        diffJ += fabs (Jdisc[m][l] - Jgeom[m][l]);
                    }
                }
                diffJ /= 3 * 3 * maxJ;
                SC_CHECK_ABORTF (diffJ < 100. * epsilon,
                                 "Jacobian mismatch %lld %g %g %g",
                                 (long long) which_tree, xyz[3][0], xyz[3][1],
                                 xyz[3][2]);
            }
        }
    }
}
Example #12
0
/**
 * Runs all tests.
 */
int
main (int argc, char **argv)
{
  const char         *this_fn_name = P4EST_STRING "_test_subcomm";
  /* options */
  const p4est_locidx_t min_quadrants = 15;
  const int           min_level = 4;
  const int           fill_uniform = 0;
  /* parallel environment */
  sc_MPI_Comm         mpicomm = sc_MPI_COMM_WORLD;
  int                 mpisize, submpisize;
  int                 mpiret;
#ifdef P4EST_ENABLE_DEBUG
  int                 rank;
#endif
  /* p4est */
  p4est_connectivity_t *connectivity;
  p4est_t            *p4est;
  p4est_locidx_t     *partition;

  /* initialize MPI */
  mpiret = sc_MPI_Init (&argc, &argv);
  SC_CHECK_MPI (mpiret);

  /* exit if MPI communicator cannot be reduced */
  mpiret = sc_MPI_Comm_size (mpicomm, &mpisize);
  SC_CHECK_MPI (mpiret);
  if (mpisize == 1) {
    mpiret = sc_MPI_Finalize ();
    SC_CHECK_MPI (mpiret);
    return 0;
  }

  /* initialize p4est */
  sc_init (mpicomm, 1, 1, NULL, SC_LP_DEFAULT);
  p4est_init (NULL, SC_LP_DEFAULT);

  /* create connectivity */
#ifdef P4_TO_P8
  connectivity = p8est_connectivity_new_unitcube ();
#else
  connectivity = p4est_connectivity_new_unitsquare ();
#endif

  /* create p4est object */
  p4est = p4est_new_ext (mpicomm, connectivity,
                         min_quadrants, min_level, fill_uniform,
                         0, NULL, NULL);

  /* write vtk: new */
  p4est_vtk_write_file (p4est, NULL, P4EST_STRING "_subcomm_new");

  /* set variables pertaining to the parallel environment */
#ifdef P4EST_ENABLE_DEBUG
  rank = p4est->mpirank;
#endif
  submpisize = mpisize / 2;
  P4EST_ASSERT (submpisize <= p4est->global_num_quadrants);

  /* construct partitioning with empty ranks */
  {
    p4est_locidx_t      n_quads_per_proc, n_quads_leftover;
    int                 p;

    partition = P4EST_ALLOC (p4est_locidx_t, mpisize);
    n_quads_per_proc = p4est->global_num_quadrants / submpisize;
    n_quads_leftover = p4est->global_num_quadrants -
      (n_quads_per_proc * submpisize);
    for (p = 0; p < mpisize; p++) {
      if (p % 2) {              /* if this rank will get quadrants */
        partition[p] = n_quads_per_proc;
      }
      else {                    /* if this rank will be empty */
        partition[p] = 0;
      }
    }
    partition[1] += n_quads_leftover;

    /* check partitioning */
#ifdef P4EST_ENABLE_DEBUG
    {
      p4est_gloidx_t      sum = 0;

      for (p = 0; p < mpisize; p++) {
        sum += (p4est_gloidx_t) partition[p];
      }
      P4EST_ASSERT (sum == p4est->global_num_quadrants);
    }
#endif
  }

  /*
   * Test 1: Reduce MPI communicator to non-empty ranks
   */

  P4EST_GLOBAL_INFOF ("%s: Into test 1\n", this_fn_name);
  {
    p4est_t            *p4est_subcomm;
    int                 is_nonempty;

    /* create p4est copy and re-partition */
    p4est_subcomm = p4est_copy_ext (p4est, 1, 1);
    (void) p4est_partition_given (p4est_subcomm, partition);

    /* write vtk: partitioned */
    p4est_vtk_write_file (p4est_subcomm, NULL, P4EST_STRING "_subcomm_part");

    /* reduce MPI communicator to non-empty ranks */
    is_nonempty = p4est_comm_parallel_env_reduce (&p4est_subcomm);
    P4EST_ASSERT ((is_nonempty && 0 < partition[rank]) ||
                  (!is_nonempty && 0 == partition[rank]));

    if (is_nonempty) {
      /* write vtk: reduced communicator */
      p4est_vtk_write_file (p4est_subcomm, NULL,
                            P4EST_STRING "_subcomm_sub1");

      /* destroy the p4est that has a reduced MPI communicator */
      p4est_destroy (p4est_subcomm);
    }
  }
  mpiret = sc_MPI_Barrier (mpicomm);
  SC_CHECK_MPI (mpiret);
  P4EST_GLOBAL_INFOF ("%s: Done test 1\n", this_fn_name);

  /*
   * Test 2: Reduce MPI communicator to non-empty ranks, but now the MPI
   * communicator is not owned
   */

  P4EST_GLOBAL_INFOF ("%s: Into test 2\n", this_fn_name);
  {
    p4est_t            *p4est_subcomm;
    int                 is_nonempty;

    /* create p4est copy and re-partition */
    p4est_subcomm = p4est_copy_ext (p4est, 1, 0 /* don't dup. comm. */ );
    (void) p4est_partition_given (p4est_subcomm, partition);

    /* reduce MPI communicator to non-empty ranks */
    is_nonempty = p4est_comm_parallel_env_reduce (&p4est_subcomm);
    P4EST_ASSERT ((is_nonempty && 0 < partition[rank]) ||
                  (!is_nonempty && 0 == partition[rank]));

    if (is_nonempty) {
      /* destroy the p4est that has a reduced MPI communicator */
      p4est_destroy (p4est_subcomm);
    }
  }
  mpiret = sc_MPI_Barrier (mpicomm);
  SC_CHECK_MPI (mpiret);
  P4EST_GLOBAL_INFOF ("%s: Done test 2\n", this_fn_name);

  /*
   * Test 3: Reduce MPI communicator to non-empty ranks, but keep rank 0
   */

  P4EST_GLOBAL_INFOF ("%s: Into test 3\n", this_fn_name);
  {
    p4est_t            *p4est_subcomm;
    int                 sub_exists;
    sc_MPI_Group        group, group_reserve;
    int                 reserve_range[1][3];

    /* create group of full MPI communicator */
    mpiret = sc_MPI_Comm_group (mpicomm, &group);
    SC_CHECK_MPI (mpiret);

    /* create sub-group containing only rank 0 */
    reserve_range[0][0] = 0;
    reserve_range[0][1] = 0;
    reserve_range[0][2] = 1;
    mpiret =
      sc_MPI_Group_range_incl (group, 1, reserve_range, &group_reserve);
    SC_CHECK_MPI (mpiret);

    /* create p4est copy and re-partition */
    p4est_subcomm = p4est_copy_ext (p4est, 1, 1);
    (void) p4est_partition_given (p4est_subcomm, partition);

    /* reduce MPI communicator to non-empty ranks, but keep rank 0 */
    sub_exists = p4est_comm_parallel_env_reduce_ext (&p4est_subcomm,
                                                     group_reserve, 1, NULL);
    P4EST_ASSERT ((sub_exists && (0 < partition[rank] || rank == 0)) ||
                  (!sub_exists && 0 == partition[rank]));

    if (sub_exists) {
      /* write vtk: reduced communicator */
      p4est_vtk_write_file (p4est_subcomm, NULL,
                            P4EST_STRING "_subcomm_sub3");

      /* destroy the p4est that has a reduced MPI communicator */
      p4est_destroy (p4est_subcomm);
    }
  }
  mpiret = sc_MPI_Barrier (mpicomm);
  SC_CHECK_MPI (mpiret);
  P4EST_GLOBAL_INFOF ("%s: Done test 3\n", this_fn_name);

  /*
   * Test 4: Reduce MPI communicator to non-empty ranks, but keep last 2 ranks
   */

  P4EST_GLOBAL_INFOF ("%s: Into test 4\n", this_fn_name);
  {
    p4est_t            *p4est_subcomm;
    int                 sub_exists;
    sc_MPI_Group        group, group_reserve;
    int                 reserve_range[1][3];

    /* create group of full MPI communicator */
    mpiret = sc_MPI_Comm_group (mpicomm, &group);
    SC_CHECK_MPI (mpiret);

    /* create sub-group containing only last 2 ranks */
    reserve_range[0][0] = SC_MAX (0, mpisize - 2);
    reserve_range[0][1] = mpisize - 1;
    reserve_range[0][2] = 1;
    mpiret =
      sc_MPI_Group_range_incl (group, 1, reserve_range, &group_reserve);
    SC_CHECK_MPI (mpiret);

    /* create p4est copy and re-partition */
    p4est_subcomm = p4est_copy_ext (p4est, 1, 1);
    (void) p4est_partition_given (p4est_subcomm, partition);

    /* reduce MPI communicator to non-empty ranks, but keep last 2 ranks */
    sub_exists = p4est_comm_parallel_env_reduce_ext (&p4est_subcomm,
                                                     group_reserve, 0, NULL);
    P4EST_ASSERT ((sub_exists && (0 < partition[rank] || mpisize - 2 <= rank))
                  || (!sub_exists && 0 == partition[rank]));

    if (sub_exists) {
      /* write vtk: reduced communicator */
      p4est_vtk_write_file (p4est_subcomm, NULL,
                            P4EST_STRING "_subcomm_sub4");

      /* destroy the p4est that has a reduced MPI communicator */
      p4est_destroy (p4est_subcomm);
    }
  }
  mpiret = sc_MPI_Barrier (mpicomm);
  SC_CHECK_MPI (mpiret);
  P4EST_GLOBAL_INFOF ("%s: Done test 4\n", this_fn_name);

  /* destroy */
  P4EST_FREE (partition);
  p4est_destroy (p4est);
  p4est_connectivity_destroy (connectivity);

  /* finalize */
  sc_finalize ();
  mpiret = sc_MPI_Finalize ();
  SC_CHECK_MPI (mpiret);

  return 0;
}
Example #13
0
static int
sc_bspline_find_interval (sc_bspline_t * bs, double t)
{
  int                 i, iguess;
  double              t0, t1;
  const double       *knotse = bs->knots->e[0];

  t0 = knotse[bs->n];
  t1 = knotse[bs->n + bs->l];
  SC_ASSERT (t >= t0 && t <= t1);
  SC_ASSERT (bs->cacheknot >= bs->n && bs->cacheknot < bs->n + bs->l);

  if (t >= t1) {
    iguess = bs->cacheknot = bs->n + bs->l - 1;
  }
  else if (knotse[bs->cacheknot] <= t && t < knotse[bs->cacheknot + 1]) {
    iguess = bs->cacheknot;
  }
  else {
    const int           nshift = 1;
    int                 ileft, iright;
    double              tleft, tright;

    ileft = bs->n;
    iright = bs->n + bs->l - 1;
    iguess = bs->n + (int) floor ((t - t0) / (t1 - t0) * bs->l);
    iguess = SC_MAX (iguess, ileft);
    iguess = SC_MIN (iguess, iright);

    for (i = 0;; ++i) {
      tleft = knotse[iguess];
      tright = knotse[iguess + 1];
      if (t < tleft) {
        iright = iguess - 1;
        if (i < nshift) {
          iguess = iright;
        }
        else {
          iguess = (ileft + iright + 1) / 2;
        }
      }
      else if (t >= tright) {
        ileft = iguess + 1;
        if (i < nshift) {
          iguess = ileft;
        }
        else {
          iguess = (ileft + iright) / 2;
        }
      }
      else {
        if (i > 0) {
          SC_LDEBUGF ("For %g needed %d search steps\n", t, i);
        }
        break;
      }
    }
    bs->cacheknot = iguess;
  }
  SC_ASSERT (iguess >= bs->n && iguess < bs->n + bs->l);
  SC_CHECK_ABORT ((knotse[iguess] <= t && t < knotse[iguess + 1]) ||
                  (t >= t1 && iguess == bs->n + bs->l - 1),
                  "Bug in sc_bspline_find_interval");

  return iguess;
}
Example #14
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 #15
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));
}