Exemple #1
0
static void
hack_test (mpi_context_t * mpi, p4est_connectivity_t * connectivity)
{
  int                 i;
  int8_t              cc;
  p4est_topidx_t      tt;
  p4est_locidx_t      lnq, lng, lnc, lnco;
  p4est_locidx_t      li, qtc;
  p4est_locidx_t      co0, co1, coi, cq;
  p4est_t            *p4est;
  p4est_ghost_t      *ghost;
  p4est_mesh_t       *mesh;

  p4est = p4est_new_ext (mpi->mpicomm, connectivity, 0,
                         refine_level, 1, 0, NULL, NULL);
  p4est_vtk_write_file (p4est, NULL, "mesh_hack");

  ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL);
  mesh = p4est_mesh_new_ext (p4est, ghost, 1, 1, P4EST_CONNECT_FULL);

  lnq = mesh->local_num_quadrants;
  lng = mesh->ghost_num_quadrants;
  lnco = lnq + lng;
  lnc = mesh->local_num_corners;
  P4EST_LDEBUGF ("Local quads %lld corners %lld array %lld\n",
                 (long long) lnq, (long long) lnc,
                 (long long) mesh->corner_offset->elem_count);
  for (li = 0; li < lnq; ++li) {
    tt = mesh->quad_to_tree[li];
    if (tt >= 2) {
      /* break; */
    }
    for (i = 0; i < P4EST_CHILDREN; ++i) {
      qtc = mesh->quad_to_corner[P4EST_CHILDREN * li + i];
      if (qtc >= lnco) {
        P4EST_LDEBUGF ("Quad %lld tree %lld Corner %d is %lld\n",
                       (long long) li, (long long) tt, i, (long long) qtc);
        if (qtc >= lnco) {
          qtc -= lnco;
          co0 = *(p4est_locidx_t *) sc_array_index (mesh->corner_offset, qtc);
          co1 =
            *(p4est_locidx_t *) sc_array_index (mesh->corner_offset, qtc + 1);
          for (coi = co0; coi < co1; ++coi) {
            cq = *(p4est_locidx_t *) sc_array_index (mesh->corner_quad, coi);
            cc = *(int8_t *) sc_array_index (mesh->corner_corner, coi);
            P4EST_LDEBUGF ("   Part %d quad %lld corner %d\n",
                           (int) (coi - co0), (long long) cq, (int) cc);
          }
        }
      }
    }
  }

  p4est_mesh_destroy (mesh);
  p4est_ghost_destroy (ghost);
  p4est_destroy (p4est);
}
Exemple #2
0
static void
check_all (sc_MPI_Comm mpicomm, p4est_connectivity_t * conn,
           const char *vtkname, unsigned crc_expected, unsigned gcrc_expected)
{
  int                 mpiret;
  unsigned            crc_computed, gcrc_computed;
  long long           lsize[3], gsize[3];
  size_t              size_conn, size_p4est, size_ghost;
  p4est_t            *p4est;
  p4est_nodes_t      *nodes;
  p4est_ghost_t      *ghost;

  P4EST_GLOBAL_STATISTICSF ("Testing configuration %s\n", vtkname);

  p4est = p4est_new_ext (mpicomm, conn, 0, 0, 0, 0, NULL, NULL);
  p4est_refine (p4est, 1, refine_fn, NULL);
  p4est_coarsen (p4est, 1, coarsen_fn, NULL);
  p4est_balance (p4est, P4EST_CONNECT_FULL, NULL);
  p4est_partition (p4est, 0, NULL);
  p4est_vtk_write_file (p4est, NULL, vtkname);

  crc_computed = p4est_checksum (p4est);
  P4EST_GLOBAL_STATISTICSF ("Forest checksum 0x%08x\n", crc_computed);
  if (p4est->mpisize == 2 && p4est->mpirank == 0) {
    SC_CHECK_ABORT (crc_computed == crc_expected, "Forest checksum mismatch");
  }

  ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL);

  /* compute total size of forest storage */
  size_conn = p4est_connectivity_memory_used (conn);
  size_p4est = p4est_memory_used (p4est);
  size_ghost = p4est_ghost_memory_used (ghost);
  lsize[0] = (long long) size_conn;
  lsize[1] = (long long) size_p4est;
  lsize[2] = (long long) size_ghost;
  mpiret = sc_MPI_Reduce (lsize, gsize, 3, sc_MPI_LONG_LONG_INT, sc_MPI_SUM,
                          0, mpicomm);
  SC_CHECK_MPI (mpiret);
  P4EST_GLOBAL_INFOF ("Global byte sizes: %lld %lld %lld\n",
                      gsize[0], gsize[1], gsize[2]);

  gcrc_computed = p4est_ghost_checksum (p4est, ghost);
  P4EST_GLOBAL_STATISTICSF ("Ghost checksum 0x%08x\n", gcrc_computed);
  if (p4est->mpisize == 2 && p4est->mpirank == 0) {
    SC_CHECK_ABORT (gcrc_computed == gcrc_expected,
                    "Ghost checksum mismatch");
  }

  nodes = p4est_nodes_new (p4est, ghost);
  p4est_nodes_destroy (nodes);
  p4est_ghost_destroy (ghost);

  p4est_destroy (p4est);
  p4est_connectivity_destroy (conn);
}
static void
test_the_p4est (p4est_connectivity_t * conn, int N)
{
  p4est_t            *p4est;
  p4est_ghost_t      *ghost;
  p4est_lnodes_t     *lnodes;

  p4est = p4est_new (sc_MPI_COMM_WORLD, conn, 0, NULL, NULL);
  ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL);
  lnodes = p4est_lnodes_new (p4est, ghost, N);
  p4est_lnodes_destroy (lnodes);
  p4est_ghost_destroy (ghost);
  p4est_destroy (p4est);
}
Exemple #4
0
int
main (int argc, char **argv)
{
  int                 mpiret;
  mpi_context_t       mpi_context, *mpi = &mpi_context;
  p4est_t            *p4est;
  p4est_connectivity_t *connectivity;
  p4est_ghost_t      *ghost;

  /* initialize MPI and p4est internals */
  mpiret = MPI_Init (&argc, &argv);
  SC_CHECK_MPI (mpiret);
  mpi->mpicomm = MPI_COMM_WORLD;        /* your favourite comm here */
  mpiret = MPI_Comm_size (mpi->mpicomm, &mpi->mpisize);
  SC_CHECK_MPI (mpiret);
  mpiret = MPI_Comm_rank (mpi->mpicomm, &mpi->mpirank);
  SC_CHECK_MPI (mpiret);

  /* this should alwaps be MPI_COMM_WORLD (no effect on p4est) */
  sc_init (MPI_COMM_WORLD, 0, 0, NULL, SC_LP_DEFAULT);
  p4est_init (NULL, SC_LP_DEFAULT);

  /* create 2D connectivity and forest structures */
  connectivity = p4est_connectivity_new_unitsquare ();
  p4est = p4est_new_ext (mpi->mpicomm, connectivity, 0, 0, 1, 0, NULL, NULL);

  /* refine and partition */
  p4est_refine (p4est, 1, refine_fn, NULL);
  p4est_partition (p4est, NULL);

  /* write vtk output */
  p4est_vtk_write_file (p4est, NULL, "p4est_ptest2");

  /* create and destroy ghost layer */
  ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL);
  p4est_ghost_destroy (ghost);

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

  /* clean up and exit */
  sc_finalize ();

  mpiret = MPI_Finalize ();
  SC_CHECK_MPI (mpiret);

  return 0;
}
Exemple #5
0
void
p4est_wrap_set_hollow (p4est_wrap_t * pp, int hollow)
{
  /* Verify consistency */
  if (!pp->hollow) {
    P4EST_ASSERT (pp->flags != NULL);
    P4EST_ASSERT (pp->ghost != NULL);
    P4EST_ASSERT (pp->mesh != NULL);
  }
  else {
    P4EST_ASSERT (pp->flags == NULL);
    P4EST_ASSERT (pp->ghost == NULL);
    P4EST_ASSERT (pp->mesh == NULL);
  }

  /* Make sure a full wrap is only set to hollow outside of adaptation cycle */
  P4EST_ASSERT (!pp->match_aux);
  P4EST_ASSERT (pp->temp_flags == NULL);
  P4EST_ASSERT (pp->ghost_aux == NULL);
  P4EST_ASSERT (pp->mesh_aux == NULL);

  /* Do nothing if the status is right */
  if (hollow == pp->hollow) {
    return;
  }

  if (pp->hollow) {
    /* Allocate the ghost, mesh, and flag members */
    pp->flags = P4EST_ALLOC_ZERO (uint8_t, pp->p4est->local_num_quadrants);
    pp->ghost = p4est_ghost_new (pp->p4est, pp->btype);
    pp->mesh = p4est_mesh_new_ext (pp->p4est, pp->ghost, 1, 1, pp->btype);
  }
  else {
    /* Free and nullify the ghost, mesh, and flag members */
    p4est_mesh_destroy (pp->mesh);
    p4est_ghost_destroy (pp->ghost);
    P4EST_FREE (pp->flags);
    pp->ghost = NULL;
    pp->mesh = NULL;
    pp->flags = NULL;
  }
  pp->num_refine_flags = pp->inside_counter = pp->num_replaced = 0;
  pp->hollow = hollow;
}
Exemple #6
0
p4est_wrap_t       *
p4est_wrap_new_p4est (p4est_t * p4est, int hollow, p4est_connect_type_t btype,
                      p4est_replace_t replace_fn, void *user_pointer)
{
  p4est_wrap_t       *pp;

  P4EST_ASSERT (p4est_is_valid (p4est));
  P4EST_ASSERT (p4est->user_pointer == NULL);

  pp = P4EST_ALLOC_ZERO (p4est_wrap_t, 1);

  pp->hollow = hollow;

  sc_refcount_init (&pp->conn_rc, p4est_package_id);
  pp->conn = p4est->connectivity;
  pp->conn_owner = NULL;

  pp->p4est_dim = P4EST_DIM;
  pp->p4est_half = P4EST_HALF;
  pp->p4est_faces = P4EST_FACES;
  pp->p4est_children = P4EST_CHILDREN;
  pp->btype = btype;
  pp->replace_fn = replace_fn;
  pp->p4est = p4est;
  pp->weight_exponent = 0;      /* keep this even though using ALLOC_ZERO */

  if (!pp->hollow) {
    pp->flags = P4EST_ALLOC_ZERO (uint8_t, pp->p4est->local_num_quadrants);
    pp->ghost = p4est_ghost_new (pp->p4est, pp->btype);
    pp->mesh = p4est_mesh_new_ext (pp->p4est, pp->ghost, 1, 1, pp->btype);
  }

  pp->p4est->user_pointer = pp;
  pp->user_pointer = user_pointer;

  return pp;
}
int main(int argc, char *argv[])
{
  int mpiret;
  sc_MPI_Comm mpicomm;
  int proc_size;

  p4est_connectivity_t *conn;
  p4est_geometry_t *geom;
  p4est_t* p4est;
  
  int seed = time(NULL);
  srand(seed);
  
  /* MPI init */
  mpiret = sc_MPI_Init(&argc, &argv);
  SC_CHECK_MPI(mpiret);
  mpicomm = sc_MPI_COMM_WORLD;
  sc_init (mpicomm, 1, 1, NULL, SC_LP_ESSENTIAL);
  mpiret = MPI_Comm_size(mpicomm, &proc_size);
  SC_CHECK_MPI (mpiret);
  /* pXest init */
  p4est_init(NULL, SC_LP_PRODUCTION);


  conn = p4est_connectivity_new_disk();
  /* geom = p4est_geometry_new_connectivity(conn); */
  geom = p4est_geometry_new_disk(conn,1.,2.);

  p4est = p4est_new_ext (mpicomm, conn, -1, 0, 1,
                         sizeof(curved_element_data_t), NULL, NULL);

  int world_rank,world_size;
  sc_MPI_Comm_rank(sc_MPI_COMM_WORLD, &world_rank);
  sc_MPI_Comm_size(sc_MPI_COMM_WORLD, &world_size);
  
  /* start just-in-time dg-math */
  dgmath_jit_dbase_t* dgmath_jit_dbase = dgmath_jit_dbase_init();
  geometric_factors_t* geometric_factors = geometric_factors_init(p4est);
  
  curved_element_data_init(p4est, geometric_factors, dgmath_jit_dbase, geom, 4);
  /* int local_nodes = curved_element_data_get_local_nodes(p4est); */
  /* double* u = P4EST_ALLOC(double, local_nodes); */

  /* for (int i = 0; i < local_nodes; i++){ */
  /*   /\* u = x *\/ */
  /*   u[i] = geometric_factors->xyz[i]; */
  /* } */
  
  int num_of_refinements = 2;
  /* p4est_vtk_write_all */
  /*   (p4est, */
  /*    geom, */
  /*    0.99, */
  /*    1, */
  /*    1, */
  /*    1, */
  /*    0, */
  /*    0, */
  /*    0, */
  /*    "disk0" */
  /*   ); */
  for (int i = 0; i < num_of_refinements; i++){
    p4est_refine_ext (p4est, 0, -1, random_h_refine, NULL, refine_uniform_replace_callback);
    p4est_balance_ext(p4est, P4EST_CONNECT_FACE, NULL, refine_uniform_replace_callback);
    /* p4est_vtk_write_all */
    /*   (p4est, */
    /*    geom, */
    /*    0.99, */
    /*    1, */
    /*    1, */
    /*    1, */
    /*    0, */
    /*    0, */
    /*    0, */
    /*    "disk" */
    /*   ); */
  }

  curved_element_data_init(p4est, geometric_factors, dgmath_jit_dbase, geom, -1);
  int local_nodes = curved_element_data_get_local_nodes(p4est);
  double* u = P4EST_ALLOC(double, local_nodes);

  for (int i = 0; i < local_nodes; i++){
    /* u = x */
    u[i] = geometric_factors->xyz[i];
  }
  
  

  /* curved_element_data_init(p4est, geometric_factors, dgmath_jit_dbase, geom, -1); */

  /* store vector */
  curved_element_data_copy_from_vec_to_storage
    (
     p4est,
     u
    );
  
  test_curved_data_t test_curved_data;
  test_curved_data.mortar_err = 0.;
  test_curved_data.hanging_proj_err = 0.;
  test_curved_data.full_proj_err = 0.;
  test_curved_data.print_data = 1;
  test_curved_data.no_reorient = 0;
  test_curved_data.geom = geom;

  p4est_ghost_t* ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FACE);
  /* create space for storing the ghost data */
  curved_element_data_t* ghost_data = P4EST_ALLOC (curved_element_data_t,
                                                   ghost->ghosts.elem_count);
  
  p4est_ghost_exchange_data (p4est, ghost, ghost_data);
  curved_compute_flux_user_data_t curved_compute_flux_user_data;
  curved_compute_flux_user_data.dgmath_jit_dbase = dgmath_jit_dbase;  

  curved_flux_fcn_ptrs_t flux_fcns = (test_curved_data_fetch_fcns(&test_curved_data));

  curved_compute_flux_user_data.flux_fcn_ptrs = &flux_fcns;
  p4est->user_pointer = &curved_compute_flux_user_data;
  
  p4est_iterate (p4est,
  		 ghost,
  		 (void *) ghost_data,
  		 NULL,
                 curved_compute_flux_on_local_elements,
#if (P4EST_DIM)==3
                 NULL,
#endif
                 NULL);  

  test_curved_data.mortar_err = 0.;
  
  if (world_rank == 0)
    printf("mortar_err = %.20f\n",
           test_curved_data.mortar_err
          );
 
  p4est_ghost_destroy (ghost);
  P4EST_FREE (ghost_data);
  ghost = NULL;
  ghost_data = NULL;
  /* curved_hp_amr(p4est, */
  /*               &u, */
  /*               test_nonconform_random_hp, */
  /*               NULL, */
  /*               NULL, */
  /*               NULL, */
  /*               dgmath_jit_dbase */
  /*              ); */

  /*   curved_element_data_init(p4est, geometric_factors, dgmath_jit_dbase, geom, -1); */
    
  /* double* u_vertex = P4EST_ALLOC(double, p4est->local_num_quadrants*(P4EST_CHILDREN)); */

  /* element_data_store_nodal_vec_in_vertex_array */
  /*   ( */
  /*    p4est, */
  /*    u, */
  /*    u_vertex */
  /*   ); */

  /* char sol_save_as [500]; */
  /* sprintf(sol_save_as, "%s_test_nonconform_sym_level_%d_u", P4EST_STRING, i); */
    
  /* curved_hacked_p4est_vtk_write_all */
  /*   (p4est, */
  /*    NULL, */
  /*    0.99, */
  /*    0,    */
  /*    1,    */
  /*    1,    */
  /*    0, */
  /*    1, */
  /*    0, */
  /*    sol_save_as, */
  /*    "u", */
  /*    u_vertex */
  /*   ); */

  /* P4EST_FREE(u_vertex);    */

    
  /* ip_flux_params_t ip_flux_params; */
  /* ip_flux_params.ip_flux_penalty_prefactor = atoi(argv[6]); */
  /* ip_flux_params.ip_flux_penalty_calculate_fcn = sipg_flux_vector_calc_penalty_maxp2_over_minh; */


  /* problem_data_t vecs; */
  /* vecs.u = u; */
  /* vecs.local_nodes = element_data_get_local_nodes(p4est); */
  /* vecs.vector_flux_fcn_data = sipg_flux_vector_dirichlet_fetch_fcns */
  /* ( */
  /* zero_fcn, */
  /* &ip_flux_params */
  /* ); */
  /* vecs.scalar_flux_fcn_data = sipg_flux_scalar_dirichlet_fetch_fcns(zero_fcn); */

  /* weakeqn_ptrs_t fcns; */
  /* fcns.apply_lhs = poisson_apply_aij; */

  /* matrix_sym_tester */
  /*   ( */
  /*    p4est, */
  /*    &vecs, /\* only needed for # of nodes *\/ */
  /*    &fcns, */
  /*    .000000000000001, */
  /*    dgmath_jit_dbase, */
  /*    0, */
  /*    0 */
  /*   ); */

  /* } */
  
  P4EST_FREE(u);
  geometric_factors_destroy(geometric_factors);
  /* free pointers */
  dgmath_jit_dbase_destroy(dgmath_jit_dbase);
  
  /* free pXest */
  p4est_destroy(p4est);
  /* p4est_destroy(p4est); */
  if (geom != NULL) {
    p4est_geometry_destroy (geom);
  }
  p4est_connectivity_destroy(conn);

  /* finalize mpi stuff */  
  sc_finalize();
  mpiret = sc_MPI_Finalize ();
  SC_CHECK_MPI(mpiret);  
}
Exemple #8
0
static void
mesh_run (mpi_context_t * mpi, p4est_connectivity_t * connectivity,
          int uniform, int compute_tree_index, int compute_level_lists,
          p4est_connect_type_t mesh_btype)
{
  int                 mpiret;
  unsigned            crc;
  long                local_used[4], global_used[4];
  p4est_t            *p4est;
  p4est_ghost_t      *ghost;
  p4est_mesh_t       *mesh;
  user_data_t        *ghost_data;

  p4est = p4est_new (mpi->mpicomm, connectivity,
                     sizeof (user_data_t), init_fn, NULL);
  if (!uniform)
    p4est_vtk_write_file (p4est, NULL, P4EST_STRING "_mesh_new");

  /* refinement */
  if (uniform) {
    p4est_refine (p4est, 1, refine_uniform, init_fn);
  }
  else {
    p4est_refine (p4est, 1, refine_normal, init_fn);
    p4est_vtk_write_file (p4est, NULL, P4EST_STRING "_mesh_refined");
  }

  /* balance */
  p4est_balance (p4est, P4EST_CONNECT_FULL, init_fn);
  if (!uniform)
    p4est_vtk_write_file (p4est, NULL, P4EST_STRING "_mesh_balanced");

  /* partition */
  p4est_partition (p4est, 0, NULL);
  if (!uniform) {
    p4est_vtk_write_file (p4est, NULL, P4EST_STRING "_mesh_partition");
  }
  crc = p4est_checksum (p4est);

  /* print and verify forest checksum */
  P4EST_GLOBAL_STATISTICSF ("Tree %s checksum 0x%08x\n",
                            uniform ? "uniform" : "adapted", crc);

  /* create ghost layer and mesh */
  ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL);
  ghost_data = P4EST_ALLOC (user_data_t, ghost->ghosts.elem_count);
  p4est_ghost_exchange_data (p4est, ghost, ghost_data);
  mesh = p4est_mesh_new_ext (p4est, ghost,
                             compute_tree_index, compute_level_lists,
                             mesh_btype);
  test_mesh (p4est, ghost, mesh,
             compute_tree_index, compute_level_lists, mesh_btype,
             ghost_data, uniform);

  /* compute memory used */
  local_used[0] = (long) p4est_connectivity_memory_used (p4est->connectivity);
  local_used[1] = (long) p4est_memory_used (p4est);
  local_used[2] = (long) p4est_ghost_memory_used (ghost);
  local_used[3] = (long) p4est_mesh_memory_used (mesh);
  mpiret = sc_MPI_Allreduce (local_used, global_used, 4, sc_MPI_LONG,
                             sc_MPI_SUM, mpi->mpicomm);
  SC_CHECK_MPI (mpiret);
  P4EST_GLOBAL_PRODUCTIONF ("Total %s memory used %ld %ld %ld %ld\n",
                            uniform ? "uniform" : "adapted",
                            global_used[0], global_used[1],
                            global_used[2], global_used[3]);

  /* destroy ghost layer and mesh */
  P4EST_FREE (ghost_data);
  p4est_mesh_destroy (mesh);
  p4est_ghost_destroy (ghost);

  /* destroy the p4est structure */
  p4est_destroy (p4est);
}
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;
}
Exemple #10
0
int
p4est_wrap_partition (p4est_wrap_t * pp, int weight_exponent,
                      p4est_locidx_t * unchanged_first,
                      p4est_locidx_t * unchanged_length,
                      p4est_locidx_t * unchanged_old_first)
{
  int                 changed;
  p4est_gloidx_t      pre_me, pre_next;
  p4est_gloidx_t      post_me, post_next;

  P4EST_ASSERT (!pp->hollow);

  P4EST_ASSERT (pp->ghost != NULL);
  P4EST_ASSERT (pp->mesh != NULL);
  P4EST_ASSERT (pp->ghost_aux != NULL);
  P4EST_ASSERT (pp->mesh_aux != NULL);
  P4EST_ASSERT (pp->match_aux == 1);

  p4est_mesh_destroy (pp->mesh);
  p4est_ghost_destroy (pp->ghost);
  pp->match_aux = 0;

  /* Remember the window onto global quadrant sequence before partition */
  pre_me = pp->p4est->global_first_quadrant[pp->p4est->mpirank];
  pre_next = pp->p4est->global_first_quadrant[pp->p4est->mpirank + 1];

  /* Initialize output for the case that the partition does not change */
  if (unchanged_first != NULL) {
    *unchanged_first = 0;
  }
  if (unchanged_length != NULL) {
    *unchanged_length = pp->p4est->local_num_quadrants;
  }
  if (unchanged_old_first != NULL) {
    *unchanged_old_first = 0;
  }

  /* In the future the flags could be used to pass partition weights */
  /* We need to lift the restriction on 64 bits for the global weight sum */
  P4EST_ASSERT (weight_exponent == 0 || weight_exponent == 1);
  pp->weight_exponent = weight_exponent;
  changed =
    p4est_partition_ext (pp->p4est, 1,
                         weight_exponent ? partition_weight : NULL) > 0;

  if (changed) {
    P4EST_FREE (pp->flags);
    pp->flags = P4EST_ALLOC_ZERO (uint8_t, pp->p4est->local_num_quadrants);

    pp->ghost = p4est_ghost_new (pp->p4est, pp->btype);
    pp->mesh = p4est_mesh_new_ext (pp->p4est, pp->ghost, 1, 1, pp->btype);

    /* Query the window onto global quadrant sequence after partition */
    if (unchanged_first != NULL || unchanged_length != NULL ||
        unchanged_old_first != NULL) {

      /* compute new windof of local quadrants */
      post_me = pp->p4est->global_first_quadrant[pp->p4est->mpirank];
      post_next = pp->p4est->global_first_quadrant[pp->p4est->mpirank + 1];

      /* compute the range of quadrants that have stayed on this processor */
      p4est_wrap_partition_unchanged (pre_me, pre_next, post_me, post_next,
                                      unchanged_first, unchanged_length,
                                      unchanged_old_first);
    }
  }
  else {
    memset (pp->flags, 0, sizeof (uint8_t) * pp->p4est->local_num_quadrants);

    pp->ghost = pp->ghost_aux;
    pp->mesh = pp->mesh_aux;
    pp->ghost_aux = NULL;
    pp->mesh_aux = NULL;
  }

  return changed;
}
Exemple #11
0
int
p4est_wrap_adapt (p4est_wrap_t * pp)
{
  int                 changed;
#ifdef P4EST_ENABLE_DEBUG
  p4est_locidx_t      jl, local_num;
#endif
  p4est_gloidx_t      global_num;
  p4est_t            *p4est = pp->p4est;

  P4EST_ASSERT (!pp->hollow);
  P4EST_ASSERT (pp->coarsen_delay >= 0);

  P4EST_ASSERT (pp->mesh != NULL);
  P4EST_ASSERT (pp->ghost != NULL);
  P4EST_ASSERT (pp->mesh_aux == NULL);
  P4EST_ASSERT (pp->ghost_aux == NULL);
  P4EST_ASSERT (pp->match_aux == 0);

  P4EST_ASSERT (pp->temp_flags == NULL);
  P4EST_ASSERT (pp->num_refine_flags >= 0 &&
                pp->num_refine_flags <= p4est->local_num_quadrants);

  /* This allocation is optimistic when not all refine requests are honored */
  pp->temp_flags = P4EST_ALLOC_ZERO (uint8_t, p4est->local_num_quadrants +
                                     (P4EST_CHILDREN - 1) *
                                     pp->num_refine_flags);

  /* Execute refinement */
  pp->inside_counter = pp->num_replaced = 0;
#ifdef P4EST_ENABLE_DEBUG
  local_num = p4est->local_num_quadrants;
#endif
  global_num = p4est->global_num_quadrants;
  p4est_refine_ext (p4est, 0, -1, refine_callback, NULL, replace_on_refine);
  P4EST_ASSERT (pp->inside_counter == local_num);
  P4EST_ASSERT (p4est->local_num_quadrants - local_num ==
                pp->num_replaced * (P4EST_CHILDREN - 1));
  changed = global_num != p4est->global_num_quadrants;

  /* Execute coarsening */
  pp->inside_counter = pp->num_replaced = 0;
#ifdef P4EST_ENABLE_DEBUG
  local_num = p4est->local_num_quadrants;
#endif
  global_num = p4est->global_num_quadrants;
  p4est_coarsen_ext (p4est, 0, 1, coarsen_callback, NULL,
                     pp->coarsen_delay ? replace_on_coarsen : pp->replace_fn);
  P4EST_ASSERT (pp->inside_counter == local_num);
  P4EST_ASSERT (local_num - p4est->local_num_quadrants ==
                pp->num_replaced * (P4EST_CHILDREN - 1));
  changed = changed || global_num != p4est->global_num_quadrants;

  /* Free temporary flags */
  P4EST_FREE (pp->temp_flags);
  pp->temp_flags = NULL;

  /* Only if refinement and/or coarsening happened do we need to balance */
  if (changed) {
    P4EST_FREE (pp->flags);
    p4est_balance_ext (p4est, pp->btype, NULL, pp->coarsen_delay ?
                       replace_on_balance : pp->replace_fn);
    pp->flags = P4EST_ALLOC_ZERO (uint8_t, p4est->local_num_quadrants);

    pp->ghost_aux = p4est_ghost_new (p4est, pp->btype);
    pp->mesh_aux = p4est_mesh_new_ext (p4est, pp->ghost_aux, 1, 1, pp->btype);
    pp->match_aux = 1;
  }
#ifdef P4EST_ENABLE_DEBUG
  else {
    for (jl = 0; jl < p4est->local_num_quadrants; ++jl) {
      P4EST_ASSERT (pp->flags[jl] == 0);
    }
  }
#endif
  pp->num_refine_flags = 0;

  return changed;
}
Exemple #12
0
/** Timestep the advection problem.
 *
 * Update the state, refine, repartition, and write the solution to file.
 *
 * \param [in,out] p4est the forest, whose state is updated
 * \param [in] time      the end time
 */
static void
step3_timestep (p4est_t * p4est, double time)
{
  double              t = 0.;
  double              dt = 0.;
  int                 i;
  step3_data_t       *ghost_data;
  step3_ctx_t        *ctx = (step3_ctx_t *) p4est->user_pointer;
  int                 refine_period = ctx->refine_period;
  int                 repartition_period = ctx->repartition_period;
  int                 write_period = ctx->write_period;
  int                 recursive = 0;
  int                 allowed_level = P4EST_QMAXLEVEL;
  int                 allowcoarsening = 1;
  int                 callbackorphans = 0;
  int                 mpiret;
  double              orig_max_err = ctx->max_err;
  double              umax, global_umax;
  p4est_ghost_t      *ghost;

  /* create the ghost quadrants */
  ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL);
  /* create space for storing the ghost data */
  ghost_data = P4EST_ALLOC (step3_data_t, ghost->ghosts.elem_count);
  /* synchronize the ghost data */
  p4est_ghost_exchange_data (p4est, ghost, ghost_data);

  /* initialize du/dx estimates */
  p4est_iterate (p4est, ghost, (void *) ghost_data,     /* pass in ghost data that we just exchanged */
                 step3_reset_derivatives,       /* blank the previously calculated derivatives */
                 step3_minmod_estimate, /* compute the minmod estimate of each cell's derivative */
#ifdef P4_TO_P8
                 NULL,          /* there is no callback for the edges between quadrants */
#endif
                 NULL);         /* there is no callback for the corners between quadrants */

  for (t = 0., i = 0; t < time; t += dt, i++) {
    P4EST_GLOBAL_PRODUCTIONF ("time %f\n", t);

    /* refine */
    if (!(i % refine_period)) {
      if (i) {
        /* compute umax */
        umax = 0.;
        /* initialize derivative estimates */
        p4est_iterate (p4est, NULL, (void *) &umax,     /* pass in ghost data that we just exchanged */
                       step3_compute_max,       /* blank the previously calculated derivatives */
                       NULL,    /* there is no callback for the faces between quadrants */
#ifdef P4_TO_P8
                       NULL,    /* there is no callback for the edges between quadrants */
#endif
                       NULL);   /* there is no callback for the corners between quadrants */

        mpiret =
          sc_MPI_Allreduce (&umax, &global_umax, 1, sc_MPI_DOUBLE, sc_MPI_MAX,
                            p4est->mpicomm);
        SC_CHECK_MPI (mpiret);
        ctx->max_err = orig_max_err * global_umax;
        P4EST_GLOBAL_PRODUCTIONF ("u_max %f\n", global_umax);

        /* adapt */
        p4est_refine_ext (p4est, recursive, allowed_level,
                          step3_refine_err_estimate, NULL,
                          step3_replace_quads);
        p4est_coarsen_ext (p4est, recursive, callbackorphans,
                           step3_coarsen_err_estimate, NULL,
                           step3_replace_quads);
        p4est_balance_ext (p4est, P4EST_CONNECT_FACE, NULL,
                           step3_replace_quads);

        p4est_ghost_destroy (ghost);
        P4EST_FREE (ghost_data);
        ghost = NULL;
        ghost_data = NULL;
      }
      dt = step3_get_timestep (p4est);
    }

    /* repartition */
    if (i && !(i % repartition_period)) {
      p4est_partition (p4est, allowcoarsening, NULL);

      if (ghost) {
        p4est_ghost_destroy (ghost);
        P4EST_FREE (ghost_data);
        ghost = NULL;
        ghost_data = NULL;
      }
    }

    /* write out solution */
    if (!(i % write_period)) {
      step3_write_solution (p4est, i);
    }

    /* synchronize the ghost data */
    if (!ghost) {
      ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FULL);
      ghost_data = P4EST_ALLOC (step3_data_t, ghost->ghosts.elem_count);
      p4est_ghost_exchange_data (p4est, ghost, ghost_data);
    }

    /* compute du/dt */
    /* *INDENT-OFF* */
    p4est_iterate (p4est,                 /* the forest */
                   ghost,                 /* the ghost layer */
                   (void *) ghost_data,   /* the synchronized ghost data */
                   step3_quad_divergence, /* callback to compute each quad's
                                             interior contribution to du/dt */
                   step3_upwind_flux,     /* callback to compute each quads'
                                             faces' contributions to du/du */
#ifdef P4_TO_P8
                   NULL,                  /* there is no callback for the
                                             edges between quadrants */
#endif
                   NULL);                 /* there is no callback for the
                                             corners between quadrants */
    /* *INDENT-ON* */

    /* update u */
    p4est_iterate (p4est, NULL, /* ghosts are not needed for this loop */
                   (void *) &dt,        /* pass in dt */
                   step3_timestep_update,       /* update each cell */
                   NULL,        /* there is no callback for the faces between quadrants */
#ifdef P4_TO_P8
                   NULL,        /* there is no callback for the edges between quadrants */
#endif
                   NULL);       /* there is no callback for the corners between quadrants */

    /* synchronize the ghost data */
    p4est_ghost_exchange_data (p4est, ghost, ghost_data);

    /* update du/dx estimate */
    p4est_iterate (p4est, ghost, (void *) ghost_data,   /* pass in ghost data that we just exchanged */
                   step3_reset_derivatives,     /* blank the previously calculated derivatives */
                   step3_minmod_estimate,       /* compute the minmod estimate of each cell's derivative */
#ifdef P4_TO_P8
                   NULL,        /* there is no callback for the edges between quadrants */
#endif
                   NULL);       /* there is no callback for the corners between quadrants */
  }

  P4EST_FREE (ghost_data);
  p4est_ghost_destroy (ghost);
}
void
problem_init
(
 int argc,
 char* argv [],
 p4est_t* p4est,
 p4est_geometry_t* p4est_geom,
 dgmath_jit_dbase_t* dgmath_jit_dbase,
 int proc_size,
 sc_MPI_Comm mpicomm,
 int load_from_checkpoint
)
{
  mpi_assert((P4EST_DIM) == 2 || (P4EST_DIM) == 3);
  int world_rank, world_size;
  sc_MPI_Comm_rank(sc_MPI_COMM_WORLD, &world_rank);
  sc_MPI_Comm_size(sc_MPI_COMM_WORLD, &world_size);

  double* Au = P4EST_ALLOC_ZERO(double, 1);
  double* rhs = P4EST_ALLOC_ZERO(double, 1);
  double* u = P4EST_ALLOC_ZERO(double, 1);
  double* f = P4EST_ALLOC_ZERO(double, 1);
  double* u_analytic = P4EST_ALLOC_ZERO(double, 1);
  int local_nodes = 1;

  problem_input_t input = problem_input("options.input");
  
  int endlevel = input.endlevel;
  int degree = input.degree;         

  ip_flux_params_t ip_flux_params;
  ip_flux_params.ip_flux_penalty_prefactor = input.ip_flux_penalty;
  ip_flux_params.ip_flux_penalty_calculate_fcn = sipg_flux_vector_calc_penalty_maxp2_over_minh;
  
  p4est_ghost_t* ghost = p4est_ghost_new (p4est, P4EST_CONNECT_FACE);
  /* create space for storing the ghost data */
  element_data_t* ghost_data = P4EST_ALLOC (element_data_t,
                                                   ghost->ghosts.elem_count);

  p4est_partition(p4est, 0, NULL);
  p4est_balance (p4est, P4EST_CONNECT_FACE, NULL);

  grid_fcn_t boundary_flux_fcn = zero_fcn;
  
  problem_data_t prob_vecs;
  prob_vecs.rhs = rhs;
  prob_vecs.Au = Au;
  prob_vecs.u = u;
  prob_vecs.f = f;
  prob_vecs.local_nodes = local_nodes;
  
  for (int level = 0; level < endlevel; ++level){

    if (level != 0){
      p4est_refine_ext(p4est,
                       0,
                       -1,
                       refine_function,
                       NULL,
                       NULL
                      );

      p4est_balance_ext
        (
         p4est,
         P4EST_CONNECT_FACE,
         NULL,
         NULL
        );

      p4est_ghost_destroy(ghost);
      P4EST_FREE(ghost_data);

      ghost = p4est_ghost_new(p4est, P4EST_CONNECT_FACE);
      ghost_data = P4EST_ALLOC(element_data_t, ghost->ghosts.elem_count);      
    }

  }


  p4est_partition(p4est, 1, NULL);


  p4est_balance_ext
    (
     p4est,
     P4EST_CONNECT_FACE,
     NULL,
     NULL
    );

  p4est_ghost_destroy(ghost);
  P4EST_FREE(ghost_data);

  ghost = p4est_ghost_new(p4est, P4EST_CONNECT_FACE);
  ghost_data = P4EST_ALLOC(element_data_t, ghost->ghosts.elem_count);      
  

  
  weakeqn_ptrs_t prob_fcns;
  prob_fcns.apply_lhs = problem_apply_aij;
     
  element_data_init(p4est, degree);
  local_nodes = element_data_get_local_nodes(p4est);

  printf("RANK %d: Nodes = %d\n", world_rank, local_nodes);
  
  Au = P4EST_REALLOC(Au, double, local_nodes);
  u = P4EST_REALLOC(u, double, local_nodes);
  f = P4EST_REALLOC(f, double, local_nodes);
  rhs = P4EST_REALLOC(rhs, double, local_nodes);
  u_analytic = P4EST_REALLOC(u_analytic, double, local_nodes);

  prob_vecs.Au = Au;
  prob_vecs.u = u;
  prob_vecs.f = f;
  prob_vecs.rhs = rhs;
  prob_vecs.local_nodes = local_nodes;

  linalg_fill_vec(u, 0., local_nodes);
  element_data_init_node_vec(p4est,f,f_fcn,dgmath_jit_dbase);

  prob_vecs.vector_flux_fcn_data
    = sipg_flux_vector_dirichlet_fetch_fcns
    (
     boundary_fcn,
     &ip_flux_params
    );
  
  prob_vecs.scalar_flux_fcn_data
    = sipg_flux_scalar_dirichlet_fetch_fcns
    (
     boundary_flux_fcn
    );


  problem_build_rhs
    (
     p4est,
     &prob_vecs,
     &prob_fcns,
     ghost,
     ghost_data,
     dgmath_jit_dbase
    );

  clock_t begin = 0;
  clock_t end = -1;

  if (world_rank == 0){
    begin = clock();
  }  

  int vcycle_iter = 3;
  double vcycle_rtol = 1e-3;
  double vcycle_atol = 0.;
  int smooth_iter = 8;
  int cg_eigs_iter = 10;
  double max_eig_factor = 1.1;
  int max_eig_reuse = 1;
  double lmax_lmin_rat = 30.;
  int coarse_iter = 100;
  double coarse_rtol = 1e-8;
  int save_vtk_snapshot = 0;
  int perform_checksum = 0;
  
  multigrid_data_t* mg_data
    = multigrid_data_init
    (
     world_rank,
     endlevel,
     vcycle_iter,
     vcycle_rtol,
     vcycle_atol,
     smooth_iter,
     cg_eigs_iter,
     max_eig_factor,
     max_eig_reuse,
     lmax_lmin_rat,
     CG,
     coarse_iter,
     coarse_rtol,
     save_vtk_snapshot,
     perform_checksum,
     RES_AND_EIG_LOG,
     dgmath_jit_dbase
    );


  multigrid_solve
    (
     p4est,
     &prob_vecs,
     &prob_fcns,
     mg_data,
     &ghost,
     &ghost_data
    );
  
  
  multigrid_data_destroy(mg_data);
  
  element_data_init_node_vec(p4est, u_analytic, analytic_solution_fcn, dgmath_jit_dbase);    
  linalg_vec_axpy(-1., u, u_analytic, local_nodes);

  double local_l2_norm_sqr =  element_data_compute_l2_norm_sqr_no_local
                              (
                               p4est,
                               u_analytic,
                               dgmath_jit_dbase
                              );
  
  double local_nodes_dbl = (double)local_nodes;
  double local_reduce [2];
  local_reduce[0] = local_nodes_dbl;
  local_reduce[1] = local_l2_norm_sqr;

  double global_reduce [2];

  sc_reduce
    (
     &local_reduce[0],
     &global_reduce[0],
     2,
     sc_MPI_DOUBLE,
     sc_MPI_SUM,
     0,
     sc_MPI_COMM_WORLD
    );

  double global_nodes_dbl = global_reduce[0];
  double global_l2_norm_sqr = global_reduce[1];
    
  if (world_rank == 0){
    end = clock();
    double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    printf
      (
       "\n\n[HP_AMR]: %d %d %d %.25f %f \n\n",
       degree,
       (int)p4est->global_num_quadrants,
       (int)global_nodes_dbl,
       sqrt(global_l2_norm_sqr),
       /* info.iterations, */
       /* info.residual_norm, */
       time_spent
      );
  }


  
  if (ghost) {
    p4est_ghost_destroy (ghost);
    P4EST_FREE (ghost_data);
    ghost = NULL;
    ghost_data = NULL;
  }


  
  P4EST_FREE(f);
  P4EST_FREE(Au);
  P4EST_FREE(rhs);
  P4EST_FREE(u_analytic);
  P4EST_FREE(u);
}
Exemple #14
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;
}