Beispiel #1
0
void
p4est_mesh_destroy (p4est_mesh_t * mesh)
{
  int                 level = 0;

  if (mesh->quad_to_tree != NULL) {
    P4EST_FREE (mesh->quad_to_tree);
  }

  if (mesh->quad_level != NULL) {
    for (level = 0; level <= P4EST_QMAXLEVEL; ++level) {
      sc_array_reset (mesh->quad_level + level);
    }
    P4EST_FREE (mesh->quad_level);
  }

  P4EST_FREE (mesh->ghost_to_proc);
  P4EST_FREE (mesh->quad_to_quad);
  P4EST_FREE (mesh->quad_to_face);
  sc_array_destroy (mesh->quad_to_half);

  if (mesh->quad_to_corner != NULL) {
    P4EST_FREE (mesh->quad_to_corner);
    sc_array_destroy (mesh->corner_offset);
    sc_array_destroy (mesh->corner_quad);
    sc_array_destroy (mesh->corner_corner);
  }

  P4EST_FREE (mesh);
}
Beispiel #2
0
static void
coords_double_to_PetscScalar (sc_array_t * array)
{
  sc_array_t         *newarray;
  size_t              zz, count = array->elem_count;
  P4EST_ASSERT (array->elem_size == 3 * sizeof (double));

  if (sizeof (double) == sizeof (PetscScalar)) {
    return;
  }

  newarray = sc_array_new_size (3 * sizeof (PetscScalar), array->elem_count);
  for (zz = 0; zz < count; zz++) {
    double             *id = (double *) sc_array_index (array, zz);
    PetscScalar        *ip = (PetscScalar *) sc_array_index (newarray, zz);

    ip[0] = (PetscScalar) id[0];
    ip[1] = (PetscScalar) id[1];
    ip[2] = (PetscScalar) id[2];
  }

  sc_array_reset (array);
  sc_array_init_size (array, 3 * sizeof (PetscScalar), count);
  sc_array_copy (array, newarray);
  sc_array_destroy (newarray);
}
Beispiel #3
0
static void
p6est_profile_compress (p6est_profile_t * profile)
{
  p4est_locidx_t      nidx, il, old_off, nln =
    profile->lnodes->num_local_nodes;
  p4est_locidx_t (*lr)[2] = (p4est_locidx_t (*)[2]) profile->lnode_ranges;
  sc_array_t         *lc = profile->lnode_columns;
  size_t              old_count = lc->elem_count;
  size_t              new_count;
  sc_array_t         *perm;
  size_t             *newindex;
  size_t              zz, offset;

  if (!old_count) {
    return;
  }
  perm = sc_array_new_size (sizeof (size_t), old_count);
  newindex = (size_t *) sc_array_index (perm, 0);

  for (zz = 0; zz < old_count; zz++) {
    newindex[zz] = old_count;
  }

  offset = 0;

  for (nidx = 0; nidx < nln; nidx++) {
    old_off = lr[nidx][0];
    if (lr[nidx][1]) {
      lr[nidx][0] = offset;
    }
    else {
      P4EST_ASSERT (!lr[nidx][0]);
    }
    for (il = 0; il < lr[nidx][1]; il++) {
      newindex[il + old_off] = offset++;
    }
  }
  new_count = offset;

  for (zz = 0; zz < old_count; zz++) {
    if (newindex[zz] == old_count) {
      newindex[zz] = offset++;
    }
  }

  sc_array_permute (lc, perm, 0);
  sc_array_destroy (perm);
  sc_array_resize (lc, new_count);
}
Beispiel #4
0
static void
test_deflate (p4est_t * p4est)
{
  p4est_gloidx_t     *pertree;
  p4est_t            *p4est2;
  sc_array_t         *qarr, *darr;

  pertree = P4EST_ALLOC (p4est_gloidx_t, p4est->connectivity->num_trees + 1);
  p4est_comm_count_pertree (p4est, pertree);
  darr = NULL;
  qarr = p4est_deflate_quadrants (p4est, p4est->data_size > 0 ? &darr : NULL);

  /* Data that describes the forest completely
     (a) shared data (identical on all processors):
     p4est->connectivity
     p4est->global_first_quadrant (does not need to be stored away)
     pertree
     (b) per-processor data (partition independent after allgatherv):
     qarr
     darr (if per-quadrant data size is greater 0 and it should be saved)
   */

  /* Create a forest from this information and compare */
  p4est2 = p4est_inflate (p4est->mpicomm, p4est->connectivity,
                          p4est->global_first_quadrant, pertree,
                          qarr, darr, p4est->user_pointer);
  SC_CHECK_ABORT (p4est_is_equal (p4est, p4est2, 1), "de/inflate");
  p4est_destroy (p4est2);

  /* clean up allocated memory */
  P4EST_FREE (pertree);
  sc_array_destroy (qarr);
  if (darr != NULL) {
    sc_array_destroy (darr);
  }
}
Beispiel #5
0
void
p6est_profile_destroy (p6est_profile_t * profile)
{
  p4est_lnodes_destroy (profile->lnodes);
  if (profile->ghost_owned) {
    p4est_ghost_destroy (profile->cghost);
  }
  if (profile->lnode_changed[0]) {
    P4EST_ASSERT (profile->lnode_changed[1]);
    P4EST_FREE (profile->lnode_changed[0]);
    P4EST_FREE (profile->lnode_changed[1]);
    P4EST_ASSERT (profile->enode_counts);
    P4EST_FREE (profile->enode_counts);
  }
  P4EST_FREE (profile->lnode_ranges);
  sc_array_destroy (profile->lnode_columns);
  P4EST_FREE (profile);
}
Beispiel #6
0
static void
locidx_pair_to_PetscSFNode (sc_array_t * array)
{
  sc_array_t         *newarray;
  size_t              zz, count = array->elem_count;
  P4EST_ASSERT (array->elem_size == 2 * sizeof (p4est_locidx_t));

  newarray = sc_array_new_size (sizeof (PetscSFNode), array->elem_count);
  for (zz = 0; zz < count; zz++) {
    p4est_locidx_t     *il = (p4est_locidx_t *) sc_array_index (array, zz);
    PetscSFNode        *ip = (PetscSFNode *) sc_array_index (newarray, zz);

    ip->rank = (PetscInt) il[0];
    ip->index = (PetscInt) il[1];
  }

  sc_array_reset (array);
  sc_array_init_size (array, sizeof (PetscSFNode), count);
  sc_array_copy (array, newarray);
  sc_array_destroy (newarray);
}
Beispiel #7
0
static void
locidx_to_PetscInt (sc_array_t * array)
{
  sc_array_t         *newarray;
  size_t              zz, count = array->elem_count;
  P4EST_ASSERT (array->elem_size == sizeof (p4est_locidx_t));

  if (sizeof (p4est_locidx_t) == sizeof (PetscInt)) {
    return;
  }

  newarray = sc_array_new_size (sizeof (PetscInt), array->elem_count);
  for (zz = 0; zz < count; zz++) {
    p4est_locidx_t      il = *((p4est_locidx_t *) sc_array_index (array, zz));
    PetscInt           *ip = (PetscInt *) sc_array_index (newarray, zz);

    *ip = (PetscInt) il;
  }

  sc_array_reset (array);
  sc_array_init_size (array, sizeof (PetscInt), count);
  sc_array_copy (array, newarray);
  sc_array_destroy (newarray);
}
Beispiel #8
0
int
p6est_profile_sync (p6est_profile_t * profile)
{
  p4est_lnodes_t     *lnodes = profile->lnodes;
  p4est_locidx_t      nln = lnodes->num_local_nodes;
  sc_array_t          lrview;
  p4est_lnodes_buffer_t *countbuf;
  sc_array_t         *sharers;
  size_t              zz, nsharers;
  int                 nleft;
  int8_t             *recv, *send;
  int                *array_of_indices;
  p4est_locidx_t      recv_total;
  p4est_locidx_t     *recv_offsets, recv_offset;
  p4est_locidx_t      send_total;
  p4est_locidx_t     *send_offsets, send_offset;
  p4est_locidx_t (*lr)[2];
  sc_array_t         *lc = profile->lnode_columns;
  sc_MPI_Request     *recv_request, *send_request;
  sc_array_t         *work;
  int                 any_change = 0;
  int                 any_global_change;
  int                 mpiret, mpirank;
  int                 evenodd = profile->evenodd;

  lr = (p4est_locidx_t (*)[2]) profile->lnode_ranges;
  sharers = lnodes->sharers;
  nsharers = sharers->elem_count;

  mpiret = sc_MPI_Comm_rank (lnodes->mpicomm, &mpirank);
  SC_CHECK_MPI (mpiret);

  sc_array_init_data (&lrview, lr, 2 * sizeof (p4est_locidx_t), nln);

  countbuf = p4est_lnodes_share_all_begin (&lrview, lnodes);
  send_offsets = P4EST_ALLOC (p4est_locidx_t, nsharers + 1);
  send_offset = 0;
  for (zz = 0; zz < nsharers; zz++) {
    p4est_lnodes_rank_t *sharer;
    sc_array_t         *send_buf;
    size_t              zy, nnodes;

    send_offsets[zz] = send_offset;
    sharer = p4est_lnodes_rank_array_index (sharers, zz);
    if (sharer->rank == mpirank) {
      continue;
    }
    send_buf = (sc_array_t *) sc_array_index (countbuf->send_buffers, zz);
    nnodes = sharer->shared_nodes.elem_count;

    P4EST_ASSERT (nnodes == send_buf->elem_count);

    P4EST_ASSERT (send_buf->elem_size == 2 * sizeof (p4est_locidx_t));
    for (zy = 0; zy < nnodes; zy++) {
      p4est_locidx_t     *lp =
        (p4est_locidx_t *) sc_array_index (send_buf, zy);
      P4EST_ASSERT (lp[0] >= 0);
      P4EST_ASSERT (lp[1] >= 0);
      send_offset += lp[1];
    }
  }
  send_total = send_offsets[nsharers] = send_offset;

  p4est_lnodes_share_all_end (countbuf);
  recv_offsets = P4EST_ALLOC (p4est_locidx_t, nsharers + 1);
  recv_offset = 0;
  for (zz = 0; zz < nsharers; zz++) {
    p4est_lnodes_rank_t *sharer;
    sc_array_t         *recv_buf;
    size_t              zy, nnodes;

    recv_offsets[zz] = recv_offset;
    sharer = p4est_lnodes_rank_array_index (sharers, zz);
    if (sharer->rank == mpirank) {
      continue;
    }
    recv_buf = (sc_array_t *) sc_array_index (countbuf->recv_buffers, zz);
    nnodes = sharer->shared_nodes.elem_count;

    P4EST_ASSERT (nnodes == recv_buf->elem_count);

    P4EST_ASSERT (recv_buf->elem_size == 2 * sizeof (p4est_locidx_t));
    for (zy = 0; zy < nnodes; zy++) {
      p4est_locidx_t     *lp =
        (p4est_locidx_t *) sc_array_index (recv_buf, zy);
      P4EST_ASSERT (lp[0] >= 0);
      P4EST_ASSERT (lp[1] >= 0);
      recv_offset += lp[1];
    }
  }
  recv_total = recv_offsets[nsharers] = recv_offset;

  recv = P4EST_ALLOC (int8_t, recv_total);
  recv_request = P4EST_ALLOC (sc_MPI_Request, nsharers);
  send = P4EST_ALLOC (int8_t, send_total);
  send_request = P4EST_ALLOC (sc_MPI_Request, nsharers);

  /* post receives */
  nleft = 0;
  for (zz = 0; zz < nsharers; zz++) {
    p4est_lnodes_rank_t *sharer;
    int                 icount = recv_offsets[zz + 1] - recv_offsets[zz];

    sharer = p4est_lnodes_rank_array_index (sharers, zz);
    if (sharer->rank == mpirank) {
      recv_request[zz] = sc_MPI_REQUEST_NULL;
      continue;
    }
    if (icount) {
      mpiret =
        sc_MPI_Irecv (recv + recv_offsets[zz], icount * sizeof (int8_t),
                      sc_MPI_BYTE, sharer->rank, P6EST_COMM_BALANCE,
                      lnodes->mpicomm, recv_request + zz);
      SC_CHECK_MPI (mpiret);
      nleft++;
    }
    else {
      recv_request[zz] = sc_MPI_REQUEST_NULL;
    }
  }

  /* post sends */
  for (zz = 0; zz < nsharers; zz++) {
    p4est_lnodes_rank_t *sharer;
    size_t              zy, nnodes;
    int                 icount;
    sc_array_t         *shared_nodes;

    sharer = p4est_lnodes_rank_array_index (sharers, zz);
    if (sharer->rank == mpirank) {
      send_request[zz] = sc_MPI_REQUEST_NULL;
      continue;
    }
    shared_nodes = &sharer->shared_nodes;
    nnodes = shared_nodes->elem_count;
    icount = 0;
    for (zy = 0; zy < nnodes; zy++) {
      p4est_locidx_t      nidx;
      int8_t             *c;

      nidx = *((p4est_locidx_t *) sc_array_index (shared_nodes, zy));

      if (lr[nidx][1]) {
        c = (int8_t *) sc_array_index (lc, lr[nidx][0]);
        memcpy (send + send_offsets[zz] + icount, c,
                lr[nidx][1] * sizeof (int8_t));
        icount += lr[nidx][1];
      }
      else {
        P4EST_ASSERT (!lr[nidx][0]);
      }
    }
    P4EST_ASSERT (icount == send_offsets[zz + 1] - send_offsets[zz]);
    if (icount) {
      mpiret =
        sc_MPI_Isend (send + send_offsets[zz], icount * sizeof (int8_t),
                      sc_MPI_BYTE, sharer->rank, P6EST_COMM_BALANCE,
                      lnodes->mpicomm, send_request + zz);
      SC_CHECK_MPI (mpiret);
    }
    else {
      send_request[zz] = sc_MPI_REQUEST_NULL;
    }
  }

  work = sc_array_new (sizeof (int8_t));
  array_of_indices = P4EST_ALLOC (int, nsharers);
  while (nleft) {
    int                 outcount;
    int                 i;

    mpiret = sc_MPI_Waitsome (nsharers, recv_request, &outcount,
                              array_of_indices, sc_MPI_STATUSES_IGNORE);
    SC_CHECK_MPI (mpiret);

    for (i = 0; i < outcount; i++) {
      p4est_lnodes_rank_t *sharer;
      size_t              zy, nnode;
      sc_array_t         *shared_nodes;
      sc_array_t         *recv_buf;

      zz = array_of_indices[i];
      sharer = p4est_lnodes_rank_array_index (sharers, zz);
      shared_nodes = &sharer->shared_nodes;
      recv_buf = (sc_array_t *) sc_array_index (countbuf->recv_buffers, zz);
      nnode = shared_nodes->elem_count;
      P4EST_ASSERT (nnode == recv_buf->elem_count);

      recv_offset = recv_offsets[zz];
      for (zy = 0; zy < nnode; zy++) {
        p4est_locidx_t     *lp;
        p4est_locidx_t      nidx;
        sc_array_t          oldview, newview;

        nidx = *((p4est_locidx_t *) sc_array_index (shared_nodes, zy));
        lp = (p4est_locidx_t *) sc_array_index (recv_buf, zy);

        sc_array_init_view (&oldview, lc, lr[nidx][0], lr[nidx][1]);
        sc_array_init_data (&newview, recv + recv_offset, sizeof (int8_t),
                            lp[1]);
        if (profile->ptype == P6EST_PROFILE_UNION) {
          p6est_profile_union (&oldview, &newview, work);

          if (work->elem_count > oldview.elem_count) {
            int8_t             *c;

            any_change = 1;
            lr[nidx][0] = lc->elem_count;
            lr[nidx][1] = work->elem_count;
            profile->lnode_changed[evenodd][nidx] = 1;

            c = (int8_t *) sc_array_push_count (lc, work->elem_count);
            memcpy (c, work->array, work->elem_count * work->elem_size);
          }
        }
        else {
          p6est_profile_intersection (&oldview, &newview, work);
          P4EST_ASSERT (work->elem_count <= oldview.elem_count);
          if (work->elem_count < oldview.elem_count) {
            lr[nidx][1] = work->elem_count;
            memcpy (oldview.array, work->array,
                    work->elem_count * work->elem_size);
          }
        }

        recv_offset += lp[1];
      }
      P4EST_ASSERT (recv_offset == recv_offsets[zz + 1]);
    }

    nleft -= outcount;
    P4EST_ASSERT (nleft >= 0);
  }
  P4EST_FREE (array_of_indices);
  sc_array_destroy (work);

  p6est_profile_compress (profile);
  p4est_lnodes_buffer_destroy (countbuf);

  P4EST_FREE (recv_request);
  P4EST_FREE (recv_offsets);
  P4EST_FREE (recv);

  {
    mpiret = sc_MPI_Waitall (nsharers, send_request, sc_MPI_STATUSES_IGNORE);

    SC_CHECK_MPI (mpiret);
    P4EST_FREE (send_request);
    P4EST_FREE (send_offsets);
    P4EST_FREE (send);

    any_global_change = any_change;
    mpiret = sc_MPI_Allreduce (&any_change, &any_global_change, 1, sc_MPI_INT,
                               sc_MPI_LOR, lnodes->mpicomm);

    SC_CHECK_MPI (mpiret);
  }

  return any_global_change;
}
Beispiel #9
0
void
p6est_profile_balance_local (p6est_profile_t * profile)
{
  p4est_lnodes_t     *lnodes = profile->lnodes;
  p4est_locidx_t      nln, nle;
  p4est_locidx_t     *en, (*lr)[2];
  sc_array_t         *lc;
  int                 i, j;
  p4est_locidx_t      nidx, enidx, eidx;
  p8est_connect_type_t btype = profile->btype;
  p4est_connect_type_t hbtype;
  int8_t             *c;
  sc_array_t         *thisprof;
  sc_array_t         *selfprof;
  sc_array_t         *faceprof;
  sc_array_t         *cornerprof;
  sc_array_t         *work;
  sc_array_t          oldprof;
  sc_array_t          testprof;
  int                 any_prof_change;
  int                 any_local_change;
  int                 evenodd = profile->evenodd;
  p4est_qcoord_t      diff = profile->diff;

  P4EST_ASSERT (profile->lnodes->degree == 2);

  if (btype == P8EST_CONNECT_FACE) {
    hbtype = P4EST_CONNECT_FACE;
  }
  else {
    hbtype = P4EST_CONNECT_FULL;
  }
  en = lnodes->element_nodes;
  nln = lnodes->num_local_nodes;
  nle = lnodes->num_local_elements;
  lr = (p4est_locidx_t (*)[2]) profile->lnode_ranges;
  lc = profile->lnode_columns;
  selfprof = sc_array_new (sizeof (int8_t));
  work = sc_array_new (sizeof (int8_t));
  faceprof = sc_array_new (sizeof (int8_t));
  cornerprof = sc_array_new (sizeof (int8_t));

  do {
    /* We read from evenodd and write to evenodd ^ 1 */
    memset (&(profile->lnode_changed[evenodd ^ 1][0]), 0, sizeof (int) * nln);
    P4EST_GLOBAL_VERBOSE ("p6est_balance local loop\n");

    any_local_change = 0;
    for (eidx = 0, enidx = 0; eidx < nle; eidx++) {
      p4est_locidx_t      start_enidx = enidx;
      nidx = en[start_enidx + P4EST_INSUL / 2];
      P4EST_ASSERT (lr[nidx][1]);
      sc_array_init_view (&oldprof, lc, lr[nidx][0], lr[nidx][1]);
      thisprof = &oldprof;
      any_prof_change = 0;
      for (j = 0; j < 3; j++) {
        for (i = 0; i < 3; i++, enidx++) {
          nidx = en[enidx];
          if (!profile->lnode_changed[evenodd][nidx]) {
            /* if the profile hasn't changed since I wrote to it, there's no
             * need to balance against it */
            continue;
          }
          if (i != 1 && j != 1) {
            if (hbtype == P4EST_CONNECT_FACE) {
              /* skip corners if we don't need to balance them */
              P4EST_ASSERT (!lr[nidx][0]);
              P4EST_ASSERT (!lr[nidx][1]);
              continue;
            }
          }
          if (i == 1 && j == 1) {
            /* no need to further balance against oneself */
            continue;
          }
          P4EST_ASSERT (lr[nidx][1]);
          P4EST_ASSERT (profile->enode_counts[enidx] <= lr[nidx][1]);
          if (profile->enode_counts[enidx] == lr[nidx][1]) {
            /* if the profile hasn't changed since I wrote to it, there's no
             * need to balance against it */
            continue;
          }
          sc_array_init_view (&testprof, lc, lr[nidx][0], lr[nidx][1]);
          p6est_profile_union (thisprof, &testprof, work);
          if (work->elem_count > thisprof->elem_count) {
            P4EST_ASSERT (profile->lnode_changed[evenodd][nidx]);
            any_prof_change = 1;
            sc_array_copy (selfprof, work);
            thisprof = selfprof;
          }
        }
      }

      if (any_prof_change) {
        P4EST_ASSERT (thisprof == selfprof);
        P4EST_ASSERT (selfprof->elem_count > oldprof.elem_count);
        /* update */
        if (btype == P8EST_CONNECT_FACE) {
          p6est_profile_balance_face (selfprof, faceprof, work, diff);
        }
        else {
          p6est_profile_balance_full (selfprof, faceprof, work, diff);
        }
        if (btype == P8EST_CONNECT_EDGE) {
          p6est_profile_balance_face (selfprof, cornerprof, work, diff);
        }
        else if (btype == P8EST_CONNECT_FULL) {
          p6est_profile_balance_full (selfprof, cornerprof, work, diff);
        }
        enidx = start_enidx;
        for (j = 0; j < 3; j++) {
          for (i = 0; i < 3; i++, enidx++) {
            thisprof = NULL;
            nidx = en[enidx];
            if (i != 1 && j != 1) {
              if (hbtype == P4EST_CONNECT_FACE) {
                /* skip corners if we don't need to balance them */
                P4EST_ASSERT (!lr[nidx][0]);
                P4EST_ASSERT (!lr[nidx][1]);
                continue;
              }
              else {
                thisprof = cornerprof;
              }
            }
            else if (i == 1 && j == 1) {
              thisprof = selfprof;
            }
            else {
              thisprof = faceprof;
            }
            P4EST_ASSERT (lr[nidx][1]);
            /* if this node has been initialized, combine the two profiles,
             * taking the finer layers from each */
            sc_array_init_view (&oldprof, lc, lr[nidx][0], lr[nidx][1]);
            if (i == 1 && j == 1) {
              sc_array_copy (work, thisprof);
            }
            else {
              p6est_profile_union (thisprof, &oldprof, work);
            }
            if (work->elem_count > oldprof.elem_count) {
              if (!(i == 1 && j == 1)) {        /* we don't count changing self */
                profile->lnode_changed[evenodd ^ 1][nidx] = 1;
                any_local_change = 1;
              }
              lr[nidx][0] = lc->elem_count;
              lr[nidx][1] = work->elem_count;
              c = (int8_t *) sc_array_push_count (lc, work->elem_count);
              memcpy (c, work->array, work->elem_count * work->elem_size);
            }
            profile->enode_counts[enidx] = lr[nidx][1];
          }
        }
      }
    }
    p6est_profile_compress (profile);
    evenodd ^= 1;
  } while (any_local_change);

  profile->evenodd = evenodd;
  sc_array_destroy (selfprof);
  sc_array_destroy (faceprof);
  sc_array_destroy (cornerprof);
  sc_array_destroy (work);
}
Beispiel #10
0
p6est_profile_t    *
p6est_profile_new_local (p6est_t * p6est,
                         p6est_ghost_t * ghost,
                         p6est_profile_type_t ptype,
                         p8est_connect_type_t btype, int degree)
{
  p6est_profile_t    *profile = P4EST_ALLOC (p6est_profile_t, 1);
  p4est_lnodes_t     *lnodes;
  p4est_locidx_t      nln, nle;
  p4est_topidx_t      jt;
  p4est_t            *columns = p6est->columns;
  p4est_tree_t       *tree;
  sc_array_t         *tquadrants;
  p4est_quadrant_t   *col;
  p4est_qcoord_t      diff = P4EST_ROOT_LEN - p6est->root_len;
  size_t              first, last, count, zz, zy;
  p4est_locidx_t     *en, (*lr)[2];
  sc_array_t         *lc;
  int                 i, j;
  p2est_quadrant_t   *layer;
  sc_array_t         *layers = p6est->layers;
  p4est_locidx_t      nidx, enidx;
  p4est_connect_type_t hbtype;
  int8_t             *c;
  sc_array_t         *thisprof;
  sc_array_t         *selfprof;
  sc_array_t         *faceprof;
  sc_array_t         *cornerprof;
  sc_array_t         *work;
  sc_array_t          oldprof;
  const int           Nrp = degree + 1;

  P4EST_ASSERT (degree > 1);
  profile->ptype = ptype;
  profile->btype = btype;
  profile->lnode_changed[0] = NULL;
  profile->lnode_changed[1] = NULL;
  profile->enode_counts = NULL;
  profile->diff = diff;
  if (btype == P8EST_CONNECT_FACE) {
    hbtype = P4EST_CONNECT_FACE;
  }
  else {
    hbtype = P4EST_CONNECT_FULL;
  }
  if (ghost == NULL) {
    profile->cghost = p4est_ghost_new (p6est->columns, P4EST_CONNECT_FULL);
    profile->ghost_owned = 1;
  }
  else {
    P4EST_ASSERT (ghost->column_ghost->btype == P4EST_CONNECT_FULL);
    profile->cghost = ghost->column_ghost;
    profile->ghost_owned = 0;
  }
  if (ptype == P6EST_PROFILE_UNION) {
    P4EST_ASSERT (degree == 2);
  }
  profile->lnodes = lnodes = p4est_lnodes_new (p6est->columns,
                                               profile->cghost, degree);
  en = lnodes->element_nodes;
  nln = lnodes->num_local_nodes;
  nle = lnodes->num_local_elements;
  profile->lnode_ranges = P4EST_ALLOC_ZERO (p4est_locidx_t, 2 * nln);
  lr = (p4est_locidx_t (*)[2]) profile->lnode_ranges;
  profile->lnode_columns = lc = sc_array_new (sizeof (int8_t));
  selfprof = sc_array_new (sizeof (int8_t));
  work = sc_array_new (sizeof (int8_t));
  faceprof = sc_array_new (sizeof (int8_t));
  cornerprof = sc_array_new (sizeof (int8_t));
  if (ptype == P6EST_PROFILE_UNION) {
    profile->lnode_changed[0] = P4EST_ALLOC (p4est_locidx_t, nln);
    profile->lnode_changed[1] = P4EST_ALLOC (p4est_locidx_t, nln);
    profile->enode_counts = P4EST_ALLOC (p4est_locidx_t, P4EST_INSUL * nle);
    profile->evenodd = 0;
    memset (profile->lnode_changed[0], -1, nln * sizeof (int));
  }

  /* create the profiles for each node: layers are reduced to just their level
   * */
  for (enidx = 0, jt = columns->first_local_tree;
       jt <= columns->last_local_tree; ++jt) {
    tree = p4est_tree_array_index (columns->trees, jt);
    tquadrants = &tree->quadrants;

    for (zz = 0; zz < tquadrants->elem_count; ++zz) {
      col = p4est_quadrant_array_index (tquadrants, zz);
      P6EST_COLUMN_GET_RANGE (col, &first, &last);
      count = last - first;
      sc_array_truncate (selfprof);
      c = (int8_t *) sc_array_push_count (selfprof, count);
      for (zy = first; zy < last; zy++) {
        layer = p2est_quadrant_array_index (layers, zy);
        *(c++) = layer->level;
      }
      if (ptype == P6EST_PROFILE_UNION) {
        p6est_profile_balance_self (selfprof, work);
        if (btype == P8EST_CONNECT_FACE) {
          p6est_profile_balance_face (selfprof, faceprof, work, diff);
        }
        else {
          p6est_profile_balance_full (selfprof, faceprof, work, diff);
        }
        if (btype == P8EST_CONNECT_EDGE) {
          p6est_profile_balance_face (selfprof, cornerprof, work, diff);
        }
        else if (btype == P8EST_CONNECT_FULL) {
          p6est_profile_balance_full (selfprof, cornerprof, work, diff);
        }
      }
      for (j = 0; j < Nrp; j++) {
        for (i = 0; i < Nrp; i++, enidx++) {
          nidx = en[enidx];
          if (ptype == P6EST_PROFILE_UNION) {
            thisprof = NULL;
            if (!(i % degree) && !(j % degree)) {
              if (hbtype == P4EST_CONNECT_FACE) {
                /* skip corners if we don't need to balance them */
                P4EST_ASSERT (!lr[nidx][0]);
                P4EST_ASSERT (!lr[nidx][1]);
                continue;
              }
              else {
                thisprof = cornerprof;
              }
            }
            else if ((i % degree) && (j % degree)) {
              thisprof = selfprof;
            }
            else {
              thisprof = faceprof;
            }
            count = thisprof->elem_count;
            profile->enode_counts[enidx] = count;
            if (!lr[nidx][1]) {
              /* if this node has not yet been initialized, initialize it */
              lr[nidx][0] = lc->elem_count;
              lr[nidx][1] = count;
              c = (int8_t *) sc_array_push_count (lc, count);
              memcpy (c, thisprof->array, count * sizeof (int8_t));
            }
            else {
              /* if this node has been initialized, combine the two profiles,
               * taking the finer layers from each */
              sc_array_init_view (&oldprof, lc, lr[nidx][0], lr[nidx][1]);
              p6est_profile_union (thisprof, &oldprof, work);
              if (work->elem_count > oldprof.elem_count) {
                lr[nidx][0] = lc->elem_count;
                lr[nidx][1] = work->elem_count;
                c = (int8_t *) sc_array_push_count (lc, work->elem_count);
                memcpy (c, work->array, work->elem_count * work->elem_size);
              }
            }
          }
          else {
            count = selfprof->elem_count;
            if (!lr[nidx][1]) {
              /* if this node has not yet been initialized, initialize it */
              lr[nidx][0] = lc->elem_count;
              lr[nidx][1] = count;
              c = (int8_t *) sc_array_push_count (lc, count);
              memcpy (c, selfprof->array, count * sizeof (int8_t));
            }
            else {
              /* if this node has been initialized, combine the two profiles,
               * taking the coarser layers from each */
              sc_array_init_view (&oldprof, lc, lr[nidx][0], lr[nidx][1]);
              p6est_profile_intersection (selfprof, &oldprof, work);
              P4EST_ASSERT (work->elem_count <= oldprof.elem_count);
              if (work->elem_count < oldprof.elem_count) {
                lr[nidx][1] = work->elem_count;
                memcpy (oldprof.array, work->array,
                        work->elem_count * work->elem_size);
              }
            }
          }
        }
      }
    }
  }
  p6est_profile_compress (profile);

  sc_array_destroy (selfprof);
  sc_array_destroy (faceprof);
  sc_array_destroy (cornerprof);
  sc_array_destroy (work);

  return profile;
}
Beispiel #11
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;
}
Beispiel #12
0
void
p6est_refine_to_profile (p6est_t * p6est, p6est_profile_t * profile,
                         p6est_init_t init_fn, p6est_replace_t replace_fn)
{
  size_t              zz, zy, first, last;
  p4est_topidx_t      jt;
  p4est_quadrant_t   *col;
  p4est_tree_t       *tree;
  sc_array_t         *tquadrants;
  p4est_locidx_t      eidx;
  p4est_locidx_t     *en = profile->lnodes->element_nodes;
  p4est_locidx_t (*lr)[2];
  p4est_locidx_t      nidx, pidx, pfirst, plast;
  sc_array_t         *layers = p6est->layers;
  sc_array_t         *lc = profile->lnode_columns;
  sc_array_t         *work;

  P4EST_ASSERT (profile->lnodes->degree == 2);

  lr = (p4est_locidx_t (*)[2]) profile->lnode_ranges;
  work = sc_array_new (sizeof (p2est_quadrant_t));
  for (eidx = 0, jt = p6est->columns->first_local_tree;
       jt <= p6est->columns->last_local_tree; ++jt) {
    tree = p4est_tree_array_index (p6est->columns->trees, jt);
    tquadrants = &tree->quadrants;
    for (zz = 0; zz < tquadrants->elem_count; ++zz, eidx++) {

      col = p4est_quadrant_array_index (tquadrants, zz);
      P6EST_COLUMN_GET_RANGE (col, &first, &last);
      nidx = en[P4EST_INSUL * eidx + P4EST_INSUL / 2];
      P4EST_ASSERT ((size_t) lr[nidx][1] >= last - first);
      pfirst = lr[nidx][0];
      plast = pfirst + lr[nidx][1];
      if ((size_t) lr[nidx][1] > last - first) {
        p2est_quadrant_t    stack[P4EST_QMAXLEVEL];
        p2est_quadrant_t   *q, *r, s, t;
        int                 stackcount;

        sc_array_truncate (work);
        stackcount = 0;
        zy = first;
        for (pidx = pfirst; pidx < plast; pidx++) {
          int8_t              p;

          P4EST_ASSERT (stackcount || zy < last);

          p = *((int8_t *) sc_array_index (lc, pidx));

          if (stackcount) {
            q = &(stack[--stackcount]);
          }
          else {
            q = p2est_quadrant_array_index (layers, zy++);
          }

          P4EST_ASSERT (q->level <= p);
          while (q->level < p) {
            p2est_quadrant_t   *child[2];

            t = *q;
            s = *q;
            s.level++;
            stack[stackcount] = s;
            stack[stackcount].z += P4EST_QUADRANT_LEN (s.level);
            child[0] = &s;
            child[1] = &stack[stackcount++];
            p6est_layer_init_data (p6est, jt, col, child[0], init_fn);
            p6est_layer_init_data (p6est, jt, col, child[1], init_fn);
            q = &t;
            if (replace_fn) {
              replace_fn (p6est, jt, 1, 1, &col, &q, 1, 2, &col, child);
            }
            p6est_layer_free_data (p6est, &t);
            q = &s;
          }
          r = p2est_quadrant_array_push (work);
          *r = *q;
        }
        P4EST_ASSERT (work->elem_count == (size_t) lr[nidx][1]);
        first = layers->elem_count;
        last = first + work->elem_count;
        P6EST_COLUMN_SET_RANGE (col, first, last);
        q = (p2est_quadrant_t *) sc_array_push_count (layers,
                                                      work->elem_count);
        memcpy (q, work->array, work->elem_count * work->elem_size);
      }
    }
  }
  sc_array_destroy (work);
  p6est_compress_columns (p6est);
  p6est_update_offsets (p6est);
}
Beispiel #13
0
int
main (int argc, char **argv)
{
  p4est_quadrant_t    root;
  p4est_quadrant_t    p;
  p4est_quadrant_t    q;
  p4est_quadrant_t    desc;
  int                 face, corner;
#ifndef P4_TO_P8
  int                 maxlevel = 9;
#else
  int                 edge;
  int                 maxlevel = 6;
#endif
  int                 mpiret, mpisize, mpirank;
  sc_MPI_Comm         mpicomm;
  uint64_t            i, ifirst, ilast;
  int                 level;
  sc_array_t         *seeds, *seeds_check;
  int                 testval;
  int                 checkval;
  int                 j, nrand = 1000;

  /* 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);

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

  seeds = sc_array_new (sizeof (p4est_quadrant_t));
  seeds_check = sc_array_new (sizeof (p4est_quadrant_t));

  memset (&root, 0, sizeof (p4est_quadrant_t));
  root.level = 2;
  root.x = P4EST_QUADRANT_LEN (2);
  root.y = P4EST_QUADRANT_LEN (2);
#ifdef P4_TO_P8
  root.z = P4EST_QUADRANT_LEN (2);
#endif
  P4EST_QUADRANT_INIT (&p);
  P4EST_QUADRANT_INIT (&q);

#if 1
  for (face = 0; face < P4EST_FACES; face++) {
    p4est_quadrant_face_neighbor (&root, face ^ 1, &p);
    P4EST_GLOBAL_VERBOSEF ("Testing face %d\n", face);
    for (level = 4; level <= maxlevel; level++) {
      P4EST_GLOBAL_VERBOSEF (" level %d\n", level);
      p4est_quadrant_first_descendant (&root, &desc, level);
      ifirst = p4est_quadrant_linear_id (&desc, level);
      p4est_quadrant_last_descendant (&root, &desc, level);
      ilast = p4est_quadrant_linear_id (&desc, level);
      for (i = ifirst; i <= ilast; i += P4EST_CHILDREN) {
        p4est_quadrant_set_morton (&q, level, i);
#ifndef P4_TO_P8
        testval = p4est_balance_seeds_face (&q, &p, face, P4EST_CONNECT_FACE,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P4EST_CONNECT_FACE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p4est_balance_seeds_face error");
        compare_seeds (seeds, seeds_check);
#else
        testval = p4est_balance_seeds_face (&q, &p, face, P8EST_CONNECT_FACE,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_FACE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_face error");
        compare_seeds (seeds, seeds_check);
        testval = p4est_balance_seeds_face (&q, &p, face, P8EST_CONNECT_EDGE,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_EDGE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_face error");
        compare_seeds (seeds, seeds_check);
#endif
        testval = p4est_balance_seeds_face (&q, &p, face, P4EST_CONNECT_FULL,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P4EST_CONNECT_FULL,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p4est_balance_seeds_face error");
        compare_seeds (seeds, seeds_check);
      }
    }
    if (!face) {
      P4EST_GLOBAL_VERBOSE (" random levels\n");
      for (j = 0; j < (int) nrand; j++) {
        level = ((random ()) % (P4EST_QMAXLEVEL - maxlevel)) + maxlevel + 1;
        p4est_quadrant_first_descendant (&root, &desc, level);
        ifirst = p4est_quadrant_linear_id (&desc, level);
        p4est_quadrant_last_descendant (&root, &desc, level);
        ilast = p4est_quadrant_linear_id (&desc, level);
        i = ((random ()) % (ilast + 1 - ifirst)) + ifirst;
        p4est_quadrant_set_morton (&q, level, i);
#ifndef P4_TO_P8
        testval = p4est_balance_seeds_face (&q, &p, face, P4EST_CONNECT_FACE,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P4EST_CONNECT_FACE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p4est_balance_seeds_face error");
        compare_seeds (seeds, seeds_check);
#else
        testval = p4est_balance_seeds_face (&q, &p, face, P8EST_CONNECT_FACE,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_FACE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_face error");
        compare_seeds (seeds, seeds_check);
        testval = p4est_balance_seeds_face (&q, &p, face, P8EST_CONNECT_EDGE,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_EDGE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_face error");
        compare_seeds (seeds, seeds_check);
#endif
        testval = p4est_balance_seeds_face (&q, &p, face, P4EST_CONNECT_FULL,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P4EST_CONNECT_FULL,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p4est_balance_seeds_face error");
        compare_seeds (seeds, seeds_check);
      }
    }
  }

#ifdef P4_TO_P8
  for (edge = 0; edge < P8EST_EDGES; edge++) {
    p8est_quadrant_edge_neighbor (&root, edge ^ 3, &p);
    P4EST_GLOBAL_VERBOSEF ("Testing edge %d\n", edge);
    for (level = 4; level <= maxlevel; level++) {
      P4EST_GLOBAL_VERBOSEF (" level %d\n", level);
      p4est_quadrant_first_descendant (&root, &desc, level);
      ifirst = p4est_quadrant_linear_id (&desc, level);
      p4est_quadrant_last_descendant (&root, &desc, level);
      ilast = p4est_quadrant_linear_id (&desc, level);
      for (i = ifirst; i <= ilast; i += P4EST_CHILDREN) {
        p4est_quadrant_set_morton (&q, level, i);
        testval = p8est_balance_seeds_edge (&q, &p, edge, P8EST_CONNECT_FACE,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_FACE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_edge error");
        compare_seeds (seeds, seeds_check);
        testval = p8est_balance_seeds_edge (&q, &p, edge, P8EST_CONNECT_EDGE,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_EDGE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_edge error");
        compare_seeds (seeds, seeds_check);
        testval = p8est_balance_seeds_edge (&q, &p, edge, P8EST_CONNECT_FULL,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_FULL,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_edge error");
        compare_seeds (seeds, seeds_check);
      }
    }
    if (!edge) {
      P4EST_GLOBAL_VERBOSE (" random levels\n");
      for (j = 0; j < (int) nrand; j++) {
        level = ((random ()) % (P4EST_QMAXLEVEL - maxlevel)) + maxlevel + 1;
        p4est_quadrant_first_descendant (&root, &desc, level);
        ifirst = p4est_quadrant_linear_id (&desc, level);
        p4est_quadrant_last_descendant (&root, &desc, level);
        ilast = p4est_quadrant_linear_id (&desc, level);
        i = ((random ()) % (ilast + 1 - ifirst)) + ifirst;
        p4est_quadrant_set_morton (&q, level, i);
        testval = p8est_balance_seeds_edge (&q, &p, edge, P8EST_CONNECT_FACE,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_FACE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_edge error");
        compare_seeds (seeds, seeds_check);
        testval = p8est_balance_seeds_edge (&q, &p, edge, P8EST_CONNECT_EDGE,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_EDGE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_edge error");
        compare_seeds (seeds, seeds_check);
        testval = p8est_balance_seeds_edge (&q, &p, edge, P8EST_CONNECT_FULL,
                                            seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_FULL,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_edge error");
        compare_seeds (seeds, seeds_check);
      }
    }
  }
#endif
#endif

  for (corner = 0; corner < P4EST_FACES; corner++) {
    p4est_quadrant_corner_neighbor (&root, corner ^ (P4EST_CHILDREN - 1), &p);
    P4EST_GLOBAL_VERBOSEF ("Testing corner %d\n", corner);
    for (level = 4; level <= maxlevel; level++) {
      P4EST_GLOBAL_VERBOSEF (" level %d\n", level);
      p4est_quadrant_first_descendant (&root, &desc, level);
      ifirst = p4est_quadrant_linear_id (&desc, level);
      p4est_quadrant_last_descendant (&root, &desc, level);
      ilast = p4est_quadrant_linear_id (&desc, level);
      for (i = ifirst; i <= ilast; i += P4EST_CHILDREN) {
        p4est_quadrant_set_morton (&q, level, i);
#ifndef P4_TO_P8
        testval =
          p4est_balance_seeds_corner (&q, &p, corner, P4EST_CONNECT_FACE,
                                      seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P4EST_CONNECT_FACE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p4est_balance_seeds_corner error");
        compare_seeds (seeds, seeds_check);
#else
        testval = p4est_balance_seeds_corner (&q, &p, corner,
                                              P8EST_CONNECT_FACE, seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_FACE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_corner error");
        compare_seeds (seeds, seeds_check);
        testval =
          p4est_balance_seeds_corner (&q, &p, corner, P8EST_CONNECT_EDGE,
                                      seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_EDGE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_corner error");
        compare_seeds (seeds, seeds_check);
#endif
        testval =
          p4est_balance_seeds_corner (&q, &p, corner, P4EST_CONNECT_FULL,
                                      seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P4EST_CONNECT_FULL,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p4est_balance_seeds_corner error");
        compare_seeds (seeds, seeds_check);
      }
    }
    if (!corner) {
      P4EST_GLOBAL_VERBOSE (" random levels\n");
      for (j = 0; j < (int) nrand; j++) {
        level = ((random ()) % (P4EST_QMAXLEVEL - maxlevel)) + maxlevel + 1;
        p4est_quadrant_first_descendant (&root, &desc, level);
        ifirst = p4est_quadrant_linear_id (&desc, level);
        p4est_quadrant_last_descendant (&root, &desc, level);
        ilast = p4est_quadrant_linear_id (&desc, level);
        i = ((random ()) % (ilast + 1 - ifirst)) + ifirst;
        p4est_quadrant_set_morton (&q, level, i);
#ifndef P4_TO_P8
        testval =
          p4est_balance_seeds_corner (&q, &p, corner, P4EST_CONNECT_FACE,
                                      seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P4EST_CONNECT_FACE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p4est_balance_seeds_corner error");
        compare_seeds (seeds, seeds_check);
#else
        testval = p4est_balance_seeds_corner (&q, &p, corner,
                                              P8EST_CONNECT_FACE, seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_FACE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_corner error");
        compare_seeds (seeds, seeds_check);
        testval =
          p4est_balance_seeds_corner (&q, &p, corner, P8EST_CONNECT_EDGE,
                                      seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P8EST_CONNECT_EDGE,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p8est_balance_seeds_corner error");
        compare_seeds (seeds, seeds_check);
#endif
        testval =
          p4est_balance_seeds_corner (&q, &p, corner, P4EST_CONNECT_FULL,
                                      seeds);
        standard_seeds (seeds);
        checkval = check_balance_seeds (&q, &p, P4EST_CONNECT_FULL,
                                        seeds_check);
        SC_CHECK_ABORT (testval == checkval,
                        "p4est_balance_seeds_corner error");
        compare_seeds (seeds, seeds_check);
      }
    }
  }

  sc_array_destroy (seeds);
  sc_array_destroy (seeds_check);

  sc_finalize ();

  mpiret = sc_MPI_Finalize ();
  SC_CHECK_MPI (mpiret);

  return 0;
}
Beispiel #14
0
int
main (int argc, char **argv)
{
  sc_MPI_Comm         mpicomm;
  int                 mpiret;
  int                 mpisize, mpirank;
  p4est_t            *p4est;
  p4est_connectivity_t *connectivity;
  sc_dmatrix_t       *vtkvec;
  p4est_tree_t       *tree;
  sc_array_t         *quadrants;
  size_t              zz, count;
  p4est_quadrant_t   *q;
  int                 i;
#ifndef P4_TO_P8
  char                filename[] = "p4est_balance_face";
#else
  char                filename[] = "p8est_balance_edge";
#endif
  p4est_vtk_context_t *context;
  sc_array_t         *level;
  int                 retval;

  /* 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_unitsquare ();
#else
  connectivity = p8est_connectivity_new_unitcube ();
#endif

  p4est = p4est_new_ext (mpicomm, connectivity, 0, 2, 1,
                         sizeof (balance_seeds_elem_t), init_fn, NULL);

  p4est_refine (p4est, 1, refine_fn, init_fn);

  context = p4est_vtk_context_new (p4est, filename);
  p4est_vtk_context_set_scale (context, 1. - 2. * SC_EPS);
  context = p4est_vtk_write_header (context);
  SC_CHECK_ABORT (context != NULL, P4EST_STRING "_vtk: Error writing header");

  vtkvec = sc_dmatrix_new (p4est->local_num_quadrants, P4EST_CHILDREN);
  tree = p4est_tree_array_index (p4est->trees, 0);
  quadrants = &(tree->quadrants);
  count = quadrants->elem_count;
  for (zz = 0; zz < count; zz++) {
    q = p4est_quadrant_array_index (quadrants, zz);
    for (i = 0; i < P4EST_CHILDREN; i++) {
      vtkvec->e[zz][i] = (double)
        ((balance_seeds_elem_t *) (q->p.user_data))->flag;
    }
  }
  level =
    sc_array_new_data ((void *) vtkvec->e[0], sizeof (double),
                       count * P4EST_CHILDREN);
  context =
    p4est_vtk_write_point_dataf (context, 1, 0, "level", level, context);
  SC_CHECK_ABORT (context != NULL,
                  P4EST_STRING "_vtk: Error writing point data");
  sc_array_destroy (level);

  retval = p4est_vtk_write_footer (context);
  SC_CHECK_ABORT (!retval, P4EST_STRING "_vtk: Error writing footer");

  sc_dmatrix_destroy (vtkvec);
  p4est_destroy (p4est);
  p4est_connectivity_destroy (connectivity);

  sc_finalize ();

  mpiret = sc_MPI_Finalize ();
  SC_CHECK_MPI (mpiret);

  return 0;
}
Beispiel #15
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;
}
Beispiel #16
0
static void
test_build_local (sc_MPI_Comm mpicomm)
{
  sc_array_t         *points;
  p4est_connectivity_t *conn;
  p4est_t            *p4est, *built, *copy;
  test_build_t        stb, *tb = &stb;

  /* 0. prepare data that we will reuse */
  tb->maxlevel = 7 - P4EST_DIM;
  tb->counter = -1;
  tb->wrapper = 3;
  tb->init_default = -1;
  tb->init_add = -1;
  tb->count_add = -1;
  tb->last_tree = -1;
  tb->build = NULL;
#ifndef P4_TO_P8
  conn = p4est_connectivity_new_moebius ();
#else
  conn = p8est_connectivity_new_rotcubes ();
#endif /* P4_TO_P8 */
  p4est = p4est_new_ext (mpicomm, conn, 0, 0, 2, 0, NULL, tb);
  p4est_refine (p4est, 1, test_build_refine, NULL);
  p4est_partition (p4est, 0, NULL);

  /* TODO: enrich tests with quadrant data */

  /* 1. Create a p4est that shall be identical to the old one. */

  tb->build = p4est_build_new (p4est, 0, NULL, NULL);
  p4est_search_local (p4est, 0, test_search_local_1, NULL, NULL);
  built = p4est_build_complete (tb->build);
  SC_CHECK_ABORT (p4est_is_equal (p4est, built, 0), "Mismatch build_local 1");
  p4est_destroy (built);

  /* 2. Create a p4est that is as coarse as possible.
   *    Coarsen recursively, compare. */

  tb->build = p4est_build_new (p4est, 4, NULL, NULL);
  p4est_search_local (p4est, 0, test_search_local_2, NULL, NULL);
  built = p4est_build_complete (tb->build);
  copy = p4est_copy (p4est, 0);
  p4est_coarsen (copy, 1, test_build_coarsen, NULL);
  SC_CHECK_ABORT (p4est_is_equal (copy, built, 0), "Mismatch build_local 2");
  p4est_destroy (copy);
  p4est_destroy (built);

  /* 3. Create a p4est with some random pattern for demonstration */

  tb->init_default = 0;
  tb->init_add = 0;
  tb->count_add = 0;
  tb->build = p4est_build_new (p4est, 0, test_search_init_3, tb);
  p4est_build_init_add (tb->build, test_search_init_add_3);
  p4est_search_local (p4est, 1, test_search_local_3, NULL, NULL);
  built = p4est_build_complete (tb->build);
  p4est_build_verify_3 (built);
  SC_CHECK_ABORT (p4est_is_valid (built), "Invalid build_local 3");
  p4est_destroy (built);

  /* 4. Create a p4est from a search with one quadrant per tree */

  tb->init_default = 0;
  tb->init_add = 0;
  tb->count_add = 0;
  tb->last_tree = -1;
  tb->build = p4est_build_new (p4est, sizeof (long), test_search_init_4, tb);
  p4est_build_init_add (tb->build, test_search_init_add_4);
  p4est_search_local (p4est, 0, test_search_local_4, NULL, NULL);
  built = p4est_build_complete (tb->build);
  p4est_build_verify_4 (built);
  SC_CHECK_ABORT (p4est_is_valid (built), "Invalid build_local 4");
  p4est_destroy (built);

  /* 5. Create a p4est from a multiple-item search */

  points = sc_array_new_size (sizeof (int8_t), 2);
  *(int8_t *) sc_array_index (points, 0) = 0;
  *(int8_t *) sc_array_index (points, 1) = 1;
  tb->wrapper = 5;
  tb->init_default = 0;
  tb->init_add = 0;
  tb->build = p4est_build_new (p4est, 0, NULL, tb);
  p4est_search_local (p4est, 0, NULL, test_search_point_5, points);
  built = p4est_build_complete (tb->build);
#if 0
  p4est_build_verify_5 (built);
#endif
  SC_CHECK_ABORT (p4est_is_valid (built), "Invalid build_local 5");
  p4est_destroy (built);
  sc_array_destroy (points);

  /* clean up */
  p4est_destroy (p4est);
  p4est_connectivity_destroy (conn);
}
Beispiel #17
0
int
main (int argc, char **argv)
{
  sc_MPI_Comm         mpicomm;
  int                 mpiret;
  int                 mpisize, mpirank;
  p4est_t            *p4est;
  p4est_connectivity_t *conn;
  sc_array_t         *points_per_dim, *cone_sizes, *cones,
    *cone_orientations, *coords,
    *children, *parents, *childids, *leaves, *remotes;
  p4est_locidx_t      first_local_quad = -1;

  /* 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
  conn = p4est_connectivity_new_moebius ();
#else
  conn = p8est_connectivity_new_rotcubes ();
#endif
  p4est = p4est_new_ext (mpicomm, conn, 0, 1, 1, 0, NULL, NULL);
  p4est_refine (p4est, 1, refine_fn, NULL);
  p4est_balance (p4est, P4EST_CONNECT_FULL, NULL);
  p4est_partition (p4est, 0, NULL);

  points_per_dim = sc_array_new (sizeof (p4est_locidx_t));
  cone_sizes = sc_array_new (sizeof (p4est_locidx_t));
  cones = sc_array_new (sizeof (p4est_locidx_t));
  cone_orientations = sc_array_new (sizeof (p4est_locidx_t));
  coords = sc_array_new (3 * sizeof (double));
  children = sc_array_new (sizeof (p4est_locidx_t));
  parents = sc_array_new (sizeof (p4est_locidx_t));
  childids = sc_array_new (sizeof (p4est_locidx_t));
  leaves = sc_array_new (sizeof (p4est_locidx_t));
  remotes = sc_array_new (2 * sizeof (p4est_locidx_t));

  p4est_get_plex_data (p4est, P4EST_CONNECT_FULL, (mpisize > 1) ? 2 : 0,
                       &first_local_quad, points_per_dim, cone_sizes, cones,
                       cone_orientations, coords, children, parents, childids,
                       leaves, remotes);

#ifdef P4EST_WITH_PETSC
  {
    PetscErrorCode      ierr;
    DM                  plex, refTree;
    PetscInt            pStart, pEnd;
    PetscSection        parentSection;
    PetscSF             pointSF;
    size_t              zz, count;

    locidx_to_PetscInt (points_per_dim);
    locidx_to_PetscInt (cone_sizes);
    locidx_to_PetscInt (cones);
    locidx_to_PetscInt (cone_orientations);
    coords_double_to_PetscScalar (coords);
    locidx_to_PetscInt (children);
    locidx_to_PetscInt (parents);
    locidx_to_PetscInt (childids);
    locidx_to_PetscInt (leaves);
    locidx_pair_to_PetscSFNode (remotes);

    P4EST_GLOBAL_PRODUCTION ("Begin PETSc routines\n");
    ierr = PetscInitialize (&argc, &argv, 0, help);
    CHKERRQ (ierr);

    ierr = DMPlexCreate (mpicomm, &plex);
    CHKERRQ (ierr);
    ierr = DMSetDimension (plex, P4EST_DIM);
    CHKERRQ (ierr);
    ierr = DMSetCoordinateDim (plex, 3);
    CHKERRQ (ierr);
    ierr = DMPlexCreateFromDAG (plex, P4EST_DIM,
                                (PetscInt *) points_per_dim->array,
                                (PetscInt *) cone_sizes->array,
                                (PetscInt *) cones->array,
                                (PetscInt *) cone_orientations->array,
                                (PetscScalar *) coords->array);
    CHKERRQ (ierr);
    ierr = PetscSFCreate (mpicomm, &pointSF);
    CHKERRQ (ierr);
    ierr =
      DMPlexCreateDefaultReferenceTree (mpicomm, P4EST_DIM, PETSC_FALSE,
                                        &refTree);
    CHKERRQ (ierr);
    ierr = DMPlexSetReferenceTree (plex, refTree);
    CHKERRQ (ierr);
    ierr = DMDestroy (&refTree);
    CHKERRQ (ierr);
    ierr = PetscSectionCreate (mpicomm, &parentSection);
    CHKERRQ (ierr);
    ierr = DMPlexGetChart (plex, &pStart, &pEnd);
    CHKERRQ (ierr);
    ierr = PetscSectionSetChart (parentSection, pStart, pEnd);
    CHKERRQ (ierr);
    count = children->elem_count;
    for (zz = 0; zz < count; zz++) {
      PetscInt            child =
        *((PetscInt *) sc_array_index (children, zz));

      ierr = PetscSectionSetDof (parentSection, child, 1);
      CHKERRQ (ierr);
    }
    ierr = PetscSectionSetUp (parentSection);
    CHKERRQ (ierr);
    ierr =
      DMPlexSetTree (plex, parentSection, (PetscInt *) parents->array,
                     (PetscInt *) childids->array);
    CHKERRQ (ierr);
    ierr = PetscSectionDestroy (&parentSection);
    CHKERRQ (ierr);
    ierr =
      PetscSFSetGraph (pointSF, pEnd - pStart, (PetscInt) leaves->elem_count,
                       (PetscInt *) leaves->array, PETSC_COPY_VALUES,
                       (PetscSFNode *) remotes->array, PETSC_COPY_VALUES);
    CHKERRQ (ierr);
    ierr = DMViewFromOptions (plex, NULL, "-dm_view");
    CHKERRQ (ierr);
    /* TODO: test with rigid body modes as in plex ex3 */
    ierr = DMDestroy (&plex);
    CHKERRQ (ierr);

    ierr = PetscFinalize ();
    P4EST_GLOBAL_PRODUCTION ("End   PETSc routines\n");
  }
#endif

  sc_array_destroy (points_per_dim);
  sc_array_destroy (cone_sizes);
  sc_array_destroy (cones);
  sc_array_destroy (cone_orientations);
  sc_array_destroy (coords);
  sc_array_destroy (children);
  sc_array_destroy (parents);
  sc_array_destroy (childids);
  sc_array_destroy (leaves);
  sc_array_destroy (remotes);

  p4est_destroy (p4est);
  p4est_connectivity_destroy (conn);

  sc_finalize ();

  mpiret = sc_MPI_Finalize ();
  SC_CHECK_MPI (mpiret);

  return 0;
}
Beispiel #18
0
int
main (int argc, char **argv)
{
  sc_MPI_Comm         mpicomm;
  int                 mpiret;
  int                 found_total;
  p4est_locidx_t      jt, Al, Bl;
  p4est_locidx_t      local_count;
  p4est_connectivity_t *conn;
  p4est_quadrant_t   *A, *B;
  p4est_geometry_t   *geom;
  p4est_t            *p4est;
  sc_array_t         *points;
  test_point_t       *p;
  const char         *vtkname;

  /* Initialize MPI */
  mpiret = sc_MPI_Init (&argc, &argv);
  SC_CHECK_MPI (mpiret);
  mpicomm = sc_MPI_COMM_WORLD;

  /* Initialize packages */
  sc_init (mpicomm, 1, 1, NULL, SC_LP_DEFAULT);
  p4est_init (NULL, SC_LP_DEFAULT);

  /* Create forest */
#ifndef P4_TO_P8
  conn = p4est_connectivity_new_star ();
  geom = NULL;
  vtkname = "test_search2";
#else
  conn = p8est_connectivity_new_sphere ();
  geom = p8est_geometry_new_sphere (conn, 1., 0.191728, 0.039856);
  vtkname = "test_search3";
#endif
  p4est = p4est_new_ext (mpicomm, conn, 0, 0, 0, 0, NULL, &local_count);
  p4est_refine (p4est, 1, refine_fn, NULL);
  p4est_partition (p4est, 0, NULL);
  p4est_vtk_write_file (p4est, geom, vtkname);

  /* The following code should really be in a separate function. */

  /* Prepare a point search -- fix size so the memory is not relocated */
  points = sc_array_new_size (sizeof (test_point_t), 2);

  /* A */
  p = (test_point_t *) sc_array_index (points, 0);
  p->name = "A";
  A = &p->quad;
  P4EST_QUADRANT_INIT (A);
  p4est_quadrant_set_morton (A, 3, 23);
  A->p.piggy3.which_tree = 0;
  A->p.piggy3.local_num = -1;
  Al = -1;

  /* B */
  p = (test_point_t *) sc_array_index (points, 1);
  p->name = "B";
  B = &p->quad;
  P4EST_QUADRANT_INIT (B);
  p4est_quadrant_set_morton (B, 2, 13);
  B->p.piggy3.which_tree = conn->num_trees / 2;
  B->p.piggy3.local_num = -1;
  Bl = -1;

  /* Find quadrant numbers if existing */
  for (jt = p4est->first_local_tree; jt <= p4est->last_local_tree; ++jt) {
    size_t              zz;
    p4est_tree_t       *tree = p4est_tree_array_index (p4est->trees, jt);
    p4est_quadrant_t   *quad;
    sc_array_t         *tquadrants = &tree->quadrants;

    for (zz = 0; zz < tquadrants->elem_count; ++zz) {
      quad = p4est_quadrant_array_index (tquadrants, zz);
      if (A->p.piggy3.which_tree == jt && !p4est_quadrant_compare (quad, A)) {
        Al = tree->quadrants_offset + (p4est_locidx_t) zz;
        P4EST_VERBOSEF ("Searching for A at %lld\n", (long long) Al);
      }
      if (B->p.piggy3.which_tree == jt && !p4est_quadrant_compare (quad, B)) {
        Bl = tree->quadrants_offset + (p4est_locidx_t) zz;
        P4EST_VERBOSEF ("Searching for B at %lld\n", (long long) Bl);
      }
    }
  }

  /* Go */
  found_count = 0;
  p4est_search_local (p4est, 0, NULL, search_callback, points);
  mpiret = sc_MPI_Allreduce (&found_count, &found_total,
                             1, sc_MPI_INT, sc_MPI_SUM, mpicomm);
  SC_CHECK_MPI (mpiret);
  SC_CHECK_ABORT (found_total == (int) points->elem_count, "Point search");
  SC_CHECK_ABORT (A->p.piggy3.local_num == Al, "Search A");
  SC_CHECK_ABORT (B->p.piggy3.local_num == Bl, "Search B");

  /* Use another search to count local quadrants */
  local_count = 0;
  p4est_search_local (p4est, 0, count_callback, NULL, NULL);
  SC_CHECK_ABORT (local_count == p4est->local_num_quadrants, "Count search");

  /* Clear memory */
  sc_array_destroy (points);
  p4est_destroy (p4est);
  if (geom != NULL) {
    p4est_geometry_destroy (geom);
  }
  p4est_connectivity_destroy (conn);

  /* Test the build_local function and friends */
  test_build_local (mpicomm);

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

  return 0;
}
Beispiel #19
0
int
main (int argc, char *argv[])
{
  MPI_Comm comm = MPI_COMM_WORLD;
  p4est_t *p4est;
  p4est_connectivity_t *conn;
  p4est_ghost_t *ghost_layer;
  p4est_lnodes_t *lnodes;
  int rank;
  const int degree = 1;

  BFAM_MPI_CHECK(MPI_Init(&argc,&argv));
  BFAM_MPI_CHECK(MPI_Comm_rank(comm, &rank));

  bfam_log_init(rank, stdout, BFAM_LL_DEFAULT);
  bfam_signal_handler_set();

  sc_init(comm, 0, 0, NULL, SC_LP_DEFAULT);
  p4est_init(NULL, SC_LP_DEFAULT);

  conn = p4est_connectivity_new_corner();
  p4est = p4est_new_ext(comm, conn, 0, 0, 0, 0, NULL, NULL);

  refine_level = 1;
  p4est_refine(p4est, 1, refine_fn, NULL);
  p4est_balance(p4est, P4EST_CONNECT_FACE, NULL);
  p4est_partition(p4est, 1, NULL);

  p4est_vtk_write_file(p4est, NULL, "mesh");

  ghost_layer = p4est_ghost_new(p4est, P4EST_CONNECT_FULL);
  lnodes = p4est_lnodes_new(p4est, ghost_layer, degree);


  /*
   * Output the mesh.  It can be read using something like following command:
   *
   * mpirun -np 3 ./bfam_exam_p4est | grep MESH | sort -n -k 2 | sort -n -k 5 | gvim -
   */
  fflush(stdout);
  BFAM_MPI_CHECK(MPI_Barrier(comm));
  BFAM_ROOT_INFO("MESH 0 ------------ Mesh Begin ------------");
  BFAM_ROOT_INFO("MESH 1 degree  = %d", lnodes->degree);
  BFAM_ROOT_INFO("MESH 2 vnodes = %d", lnodes->vnodes);
  BFAM_INFO("MESH 3 num_local_elements  = %jd", (intmax_t)lnodes->num_local_elements);
  BFAM_INFO("MESH 4 num_local_nodes = %jd", (intmax_t)lnodes->num_local_nodes);
  BFAM_INFO("MESH 5 owned_count = %jd", (intmax_t)lnodes->owned_count);
  BFAM_INFO("MESH 6 global_offset = %jd", (intmax_t)lnodes->global_offset);


  sc_array_t *global_nodes = sc_array_new(sizeof (p4est_gloidx_t));
  sc_array_resize(global_nodes, lnodes->num_local_nodes);
  for(size_t zz = 0; zz < global_nodes->elem_count; ++zz)
  {
    *((p4est_gloidx_t *) sc_array_index(global_nodes, zz)) =
      p4est_lnodes_global_index(lnodes, zz);
  }

  p4est_lnodes_share_owned(global_nodes, lnodes);

  for(size_t zz = 0; zz < global_nodes->elem_count; ++zz)
  {
    const p4est_gloidx_t gn =
      *((p4est_gloidx_t *)sc_array_index(global_nodes, zz));
    SC_CHECK_ABORT (gn == p4est_lnodes_global_index(lnodes, zz),
        "Lnodes: bad global index across procesors");
    BFAM_INFO("MESH 7 global_nodes[%zu] = %jd", zz, (intmax_t)gn);
  }

  sc_array_destroy(global_nodes);

  p4est_topidx_t  flt = p4est->first_local_tree;
  p4est_topidx_t  llt = p4est->last_local_tree;

  p4est_locidx_t elid, elnid;
  p4est_topidx_t t;
  const double *v = conn->vertices;
  const p4est_topidx_t *tree_to_vertex = conn->tree_to_vertex;
  for(elid = 0, elnid = 0, t = flt; t <= llt; ++t)
  {
    p4est_tree_t *tree = p4est_tree_array_index(p4est->trees, t);
    const size_t count = tree->quadrants.elem_count;
    p4est_topidx_t vt[P4EST_CHILDREN];

    for (int c = 0; c < P4EST_CHILDREN; ++c)
    {
      vt[c] = tree_to_vertex[t * P4EST_CHILDREN + c];
    }

    for (size_t zz = 0; zz < count; ++zz, ++elid)
    {
      p4est_quadrant_t *q = p4est_quadrant_array_index(&tree->quadrants, zz);

      for(int jind = 0; jind < degree + 1; ++jind)
      {
        for(int iind = 0; iind < degree + 1; ++iind, ++elnid)
        {
          double xyz[3];
          for (int j = 0; j < 3; ++j)
          {

            const p4est_qcoord_t len  = P4EST_QUADRANT_LEN(q->level);
            const double         rlen = (double) P4EST_ROOT_LEN;
            const double         deg  = (double) degree;
            const double         qlen = ((double) len) / rlen;

            const double eta_x =
              ((double) q->x) / rlen + (((double) iind) / deg) * qlen;
            const double eta_y =
              ((double) q->y) / rlen + (((double) jind) / deg) * qlen;

            xyz[j] = ((1. - eta_y) * ((1. - eta_x) * v[3 * vt[0] + j] +
                                            eta_x  * v[3 * vt[1] + j]) +
                            eta_y  * ((1. - eta_x) * v[3 * vt[2] + j] +
                                            eta_x  * v[3 * vt[3] + j]));
          }

          const p4est_locidx_t nid = lnodes->element_nodes[elnid];

          BFAM_INFO(
              "MESH 8 local_node[%03jd] = %03jd ( %25.16e %25.16e %25.16e )",
              (intmax_t)elnid, (intmax_t)nid, xyz[0], xyz[1], xyz[2]);
        }
      }
    }
  }


  BFAM_ROOT_INFO("MESH 9 ------------ Mesh End ------------");




  p4est_lnodes_destroy(lnodes);
  p4est_ghost_destroy(ghost_layer);
  p4est_destroy(p4est);
  p4est_connectivity_destroy(conn);

  sc_finalize();
  BFAM_MPI_CHECK(MPI_Finalize());

  return EXIT_SUCCESS;
}