diff --git a/src/p4est_mesh.c b/src/p4est_mesh.c index 35b6aca9b..70961a620 100644 --- a/src/p4est_mesh.c +++ b/src/p4est_mesh.c @@ -1273,6 +1273,7 @@ p4est_mesh_new_params (p4est_t * p4est, p4est_ghost_t * ghost, /* store mesh creation parameters in mesh */ if (params != NULL) { mesh->params = *params; + params = NULL; } else { p4est_mesh_params_init (&mesh->params); diff --git a/src/p4est_to_p8est.h b/src/p4est_to_p8est.h index 719fcea82..ce2d0fb1b 100644 --- a/src/p4est_to_p8est.h +++ b/src/p4est_to_p8est.h @@ -177,6 +177,7 @@ #define p4est_wrap_t p8est_wrap_t #define p4est_wrap_leaf_t p8est_wrap_leaf_t #define p4est_wrap_flags_t p8est_wrap_flags_t +#define p4est_wrap_params_t p8est_wrap_params_t #define p4est_vtk_context_t p8est_vtk_context_t #define p4est_file_context_t p8est_file_context_t #define p4est_file_section_metadata_t p8est_file_section_metadata_t @@ -601,11 +602,13 @@ #define p4est_balance_seeds p8est_balance_seeds /* functions in p4est_wrap */ +#define p4est_wrap_params_init p8est_wrap_params_init #define p4est_wrap_new_conn p8est_wrap_new_conn #define p4est_wrap_new_p4est p8est_wrap_new_p8est #define p4est_wrap_new_brick p8est_wrap_new_brick #define p4est_wrap_new_world p8est_wrap_new_world #define p4est_wrap_new_ext p8est_wrap_new_ext +#define p4est_wrap_new_params p8est_wrap_new_params #define p4est_wrap_new_copy p8est_wrap_new_copy #define p4est_wrap_destroy p8est_wrap_destroy #define p4est_wrap_set_hollow p8est_wrap_set_hollow diff --git a/src/p4est_wrap.c b/src/p4est_wrap.c index 79476f280..3601aa970 100644 --- a/src/p4est_wrap.c +++ b/src/p4est_wrap.c @@ -171,12 +171,32 @@ replace_on_balance (p4est_t * p4est, p4est_topidx_t which_tree, } } +void +p4est_wrap_params_init (p4est_wrap_params_t *params) +{ + memset (params, 0, sizeof (p4est_wrap_params_t)); + + params->initial_level = 0; + params->hollow = 1; + p4est_mesh_params_init (¶ms->mesh_params); + params->replace_fn = NULL; + params->user_pointer = NULL; +} + p4est_wrap_t * p4est_wrap_new_conn (sc_MPI_Comm mpicomm, p4est_connectivity_t * conn, int initial_level) { - return p4est_wrap_new_ext (mpicomm, conn, initial_level, - 0, P4EST_CONNECT_FULL, NULL, NULL); + p4est_wrap_params_t params; + + p4est_wrap_params_init (¶ms); + params.initial_level = initial_level; + params.hollow = 0; + params.mesh_params.btype = P4EST_CONNECT_FULL; + params.mesh_params.compute_level_lists = 1; + params.mesh_params.compute_tree_index = 1; + + return p4est_wrap_new_params (mpicomm, conn, ¶ms); } p4est_wrap_t * @@ -225,12 +245,56 @@ p4est_wrap_new_ext (sc_MPI_Comm mpicomm, p4est_connectivity_t * conn, int initial_level, int hollow, p4est_connect_type_t btype, p4est_replace_t replace_fn, void *user_pointer) { + p4est_wrap_params_t params; + + p4est_wrap_params_init (¶ms); + params.initial_level = initial_level; + params.hollow = hollow; + params.mesh_params.btype = btype; + params.mesh_params.compute_level_lists = 1; + params.mesh_params.compute_tree_index = 1; + params.replace_fn = replace_fn; + params.user_pointer = user_pointer; + + return p4est_wrap_new_params (mpicomm, conn, ¶ms); +} + +p4est_wrap_t * +p4est_wrap_new_params (sc_MPI_Comm mpicomm, p4est_connectivity_t * conn, + p4est_wrap_params_t * params) +{ + p4est_wrap_params_t wrap_params; + p4est_wrap_t *pp; + P4EST_ASSERT (p4est_connectivity_is_valid (conn)); - return p4est_wrap_new_p4est (p4est_new_ext (mpicomm, conn, - 0, initial_level, 1, - 0, NULL, NULL), - hollow, btype, replace_fn, user_pointer); + if (params != NULL) { + wrap_params = *params; + params = NULL; + } + else { + p4est_wrap_params_init (&wrap_params); + } + + /* create a p4est and use it to create a hollow wrap */ + pp = p4est_wrap_new_p4est (p4est_new_ext (mpicomm, conn, + 0, wrap_params.initial_level, 1, + 0, NULL, NULL), + 1, wrap_params.mesh_params.btype, + wrap_params.replace_fn, + wrap_params.user_pointer); + + if (!wrap_params.hollow) { + /* fill the hollow wrap and use wrap_params for mesh creation */ + pp->hollow = 0; + 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_params (pp->p4est, pp->ghost, + &wrap_params.mesh_params); + } + P4EST_ASSERT (pp->hollow || pp->ghost != NULL); + + return pp; } p4est_wrap_t * diff --git a/src/p4est_wrap.h b/src/p4est_wrap.h index 2ea95de5f..4c667bde1 100644 --- a/src/p4est_wrap.h +++ b/src/p4est_wrap.h @@ -47,6 +47,32 @@ typedef enum p4est_wrap_flags } p4est_wrap_flags_t; +/** This structure contains the different parameters of wrap creation. + * A default instance can be initialized by calling \ref p4est_wrap_params_init + * and used for wrap creation by calling \ref p4est_wrap_new_params. */ +typedef struct +{ + int initial_level; /**< Initial level of uniform refinement + of the p4est that will be created + and wrapped. + No effect if less/equal to zero. */ + int hollow; /**< Do not allocate flags, ghost, and + mesh members. */ + p4est_mesh_params_t mesh_params; /**< Parameters for mesh creation. The + btype member is used for ghost + creation as well. */ + p4est_replace_t replace_fn; /**< This member may be removed soon. + Callback to replace quadrants during + refinement, coarsening or balancing + in \ref p4est_wrap_adapt. May be NULL. + The callback should not change the + p4est's user data. */ + void *user_pointer; /**< Set the user pointer in + \ref p4est_wrap_t. Subsequently, we + will never access it. */ +} +p4est_wrap_params_t; + typedef struct p4est_wrap { /* this member is never used or changed by p4est_wrap */ @@ -96,9 +122,15 @@ typedef struct p4est_wrap } p4est_wrap_t; +/** Initialize a default \ref p4est_wrap_params_t structure. + * The parameters are set to create the most basic, hollow wrap structure. */ +void p4est_wrap_params_init (p4est_wrap_params_t * params); + /** Create a p4est wrapper from a given connectivity structure. * The ghost and mesh members are initialized as well as the flags. * The btype is set to P4EST_CONNECT_FULL. + * This function sets a subset of the wrap creation parameters. For full control + * use \ref p4est_wrap_new_params. * \param [in] mpicomm We expect sc_MPI_Init to be called already. * \param [in] conn Connectivity structure. Wrap takes ownership. * \param [in] initial_level Initial level of uniform refinement. @@ -129,7 +161,9 @@ p4est_wrap_t *p4est_wrap_new_p4est (p4est_t * p4est, int hollow, void *user_pointer); /** Create a p4est wrapper from a given connectivity structure. - * Like p4est_wrap_new_conn, but with extra parameters \a hollow and \a btype. + * Like \ref p4est_wrap_new_conn, but with extra parameters \a hollow and \a btype. + * This function sets a subset of the wrap creation parameters. For full control + * use \ref p4est_wrap_new_params. * \param [in] mpicomm We expect sc_MPI_Init to be called already. * \param [in] conn Connectivity structure. Wrap takes ownership. * \param [in] initial_level Initial level of uniform refinement. @@ -150,6 +184,20 @@ p4est_wrap_t *p4est_wrap_new_ext (sc_MPI_Comm mpicomm, p4est_replace_t replace_fn, void *user_pointer); +/** Create a p4est wrapper from a given connectivity structure. + * Like \ref p4est_wrap_new_conn, but with \a params to completely control the + * wrap creation process. + * \param [in] mpicomm We expect sc_MPI_Init to be called already. + * \param [in] conn Connectivity structure. Wrap takes ownership. + * \param [in] params The wrap creation parameters. If NULL, the function + * defaults to the parameters of + \ref p4est_wrap_params_init. + * \return A fully initialized p4est_wrap structure. + */ +p4est_wrap_t *p4est_wrap_new_params (sc_MPI_Comm mpicomm, + p4est_connectivity_t * conn, + p4est_wrap_params_t * params); + /** Create a p4est wrapper from an existing one. * \note This wrapper must be destroyed before the original one. * We set it to hollow and copy the original p4est data structure. diff --git a/src/p8est_wrap.h b/src/p8est_wrap.h index 198e4e9b8..c3f2bbe7b 100644 --- a/src/p8est_wrap.h +++ b/src/p8est_wrap.h @@ -47,6 +47,32 @@ typedef enum p8est_wrap_flags } p8est_wrap_flags_t; +/** This structure contains the different parameters of wrap creation. + * A default instance can be initialized by calling \ref p8est_wrap_params_init + * and used for wrap creation by calling \ref p8est_wrap_new_params. */ +typedef struct +{ + int initial_level; /**< Initial level of uniform refinement + of the p8est that will be created + and wrapped. + No effect if less/equal to zero. */ + int hollow; /**< Do not allocate flags, ghost, and + mesh members. */ + p8est_mesh_params_t mesh_params; /**< Parameters for mesh creation. The + btype member is used for ghost + creation as well. */ + p8est_replace_t replace_fn; /**< This member may be removed soon. + Callback to replace quadrants during + refinement, coarsening or balancing + in \ref p8est_wrap_adapt. May be NULL. + The callback should not change the + p8est's user data. */ + void *user_pointer; /**< Set the user pointer in + \ref p8est_wrap_t. Subsequently, we + will never access it. */ +} +p8est_wrap_params_t; + typedef struct p8est_wrap { /* this member is never used or changed by p8est_wrap */ @@ -96,9 +122,15 @@ typedef struct p8est_wrap } p8est_wrap_t; +/** Initialize a default \ref p8est_wrap_params_t structure. + * The parameters are set to create the most basic, hollow wrap structure. */ +void p8est_wrap_params_init (p8est_wrap_params_t * params); + /** Create a p8est wrapper from a given connectivity structure. * The ghost and mesh members are initialized as well as the flags. * The btype is set to P8EST_CONNECT_FULL. + * This function sets a subset of the wrap creation parameters. For full control + * use \ref p8est_wrap_new_params. * \param [in] mpicomm We expect sc_MPI_Init to be called already. * \param [in] conn Connectivity structure. Wrap takes ownership. * \param [in] initial_level Initial level of uniform refinement. @@ -129,7 +161,9 @@ p8est_wrap_t *p8est_wrap_new_p8est (p8est_t * p8est, int hollow, void *user_pointer); /** Create a p8est wrapper from a given connectivity structure. - * Like p8est_wrap_new_conn, but with extra parameters \a hollow and \a btype. + * Like \ref p8est_wrap_new_conn, but with extra parameters \a hollow and \a btype. + * This function sets a subset of the wrap creation parameters. For full control + * use \ref p8est_wrap_new_params. * \param [in] mpicomm We expect sc_MPI_Init to be called already. * \param [in] conn Connectivity structure. Wrap takes ownership. * \param [in] initial_level Initial level of uniform refinement. @@ -150,6 +184,20 @@ p8est_wrap_t *p8est_wrap_new_ext (sc_MPI_Comm mpicomm, p8est_replace_t replace_fn, void *user_pointer); +/** Create a p8est wrapper from a given connectivity structure. + * Like \ref p8est_wrap_new_conn, but with \a params to completely control the + * wrap creation process. + * \param [in] mpicomm We expect sc_MPI_Init to be called already. + * \param [in] conn Connectivity structure. Wrap takes ownership. + * \param [in] params The wrap creation parameters. If NULL, the function + * defaults to the parameters of + \ref p8est_wrap_params_init. + * \return A fully initialized p8est_wrap structure. + */ +p8est_wrap_t *p8est_wrap_new_params (sc_MPI_Comm mpicomm, + p8est_connectivity_t * conn, + p8est_wrap_params_t * params); + /** Create a p8est wrapper from an existing one. * \note This wrapper must be destroyed before the original one. * We set it to hollow and copy the original p8est data structure.