diff --git a/doc/release_notes.txt b/doc/release_notes.txt index d03ddc747..68c153bfa 100644 --- a/doc/release_notes.txt +++ b/doc/release_notes.txt @@ -21,8 +21,18 @@ This is the upcoming release with lots of small additions throughout. ### Documentation + - Create a navigation page of examples for users to get familiar with the + software. + - Fix the warnings while generating documentation for p4est_connectivity.h. + - Fix the warnings while generating documentation for p8est_connectivity.h. + - Add more explicit documentation to the p?est_connectivity.h files. + ### Functionality + - Add two connectivities (2d bowtie and 3d drop) to stress the balance demo. + - Add a new 3d connectivity (drop) into the simple example. + - Add three 2d connectivities (circle, drop and bowtie) into simple. + ## 2.8.5 This was the last version without a release notes file. diff --git a/example/balance/Makefile.am b/example/balance/Makefile.am index 383944a88..9372ab3cd 100644 --- a/example/balance/Makefile.am +++ b/example/balance/Makefile.am @@ -5,9 +5,12 @@ if P4EST_ENABLE_BUILD_2D bin_PROGRAMS += example/balance/p4est_balance_seeds +bin_PROGRAMS += example/balance/p4est_balance_corner example_balance_p4est_balance_seeds_SOURCES = \ example/balance/balance_seeds2.c +example_balance_p4est_balance_corner_SOURCES = \ + example/balance/balance_corner2.c LINT_CSOURCES += \ $(example_balance_p4est_balance_seeds_SOURCES) @@ -15,9 +18,12 @@ endif if P4EST_ENABLE_BUILD_3D bin_PROGRAMS += example/balance/p8est_balance_seeds +bin_PROGRAMS += example/balance/p8est_balance_corner example_balance_p8est_balance_seeds_SOURCES = \ example/balance/balance_seeds3.c +example_balance_p8est_balance_corner_SOURCES = \ + example/balance/balance_corner3.c LINT_CSOURCES += \ $(example_balance_p8est_balance_seeds_SOURCES) diff --git a/example/balance/balance_corner2.c b/example/balance/balance_corner2.c new file mode 100644 index 000000000..f4c10c8ca --- /dev/null +++ b/example/balance/balance_corner2.c @@ -0,0 +1,142 @@ +/* + This file is part of p4est. + p4est is a C library to manage a collection (a forest) of multiple + connected adaptive quadtrees or octrees in parallel. + + Copyright (C) 2010 The University of Texas System + Additional copyright (C) 2011 individual authors + Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + + p4est is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + p4est is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with p4est; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef P4_TO_P8 +#include +#include +#include +#else +#include +#include +#include +#endif + +typedef struct +{ + sc_MPI_Comm mpicomm; + int mpisize; + int mpirank; +} +mpi_context_t; + +/* refinement level initialization */ +static int refine_level = 0; + +/* refinement function */ +static int +refine_fn (p4est_t * p4est, p4est_topidx_t which_tree, + p4est_quadrant_t * quadrant) +{ + if ((int) quadrant->level >= (refine_level - (int) (which_tree % 3))) { + return 0; + } + if (quadrant->level == 1 && p4est_quadrant_child_id (quadrant) == 3) { + return 1; + } + if (quadrant->x == P4EST_LAST_OFFSET (2) && + quadrant->y == P4EST_LAST_OFFSET (2)) { + return 1; + } + if (quadrant->x >= P4EST_QUADRANT_LEN (2)) { + return 0; + } + + return 1; +} + +int +main (int argc, char **argv) +{ + int mpiret; + int wrongusage; + const char *usage; + p4est_connectivity_t *connectivity; + mpi_context_t mpi_context, *mpi = &mpi_context; + p4est_geometry_t *geom; + p4est_t *p4est; + + /* initialize MPI and p4est internals */ + mpiret = sc_MPI_Init (&argc, &argv); + SC_CHECK_MPI (mpiret); + mpi->mpicomm = sc_MPI_COMM_WORLD; + mpiret = sc_MPI_Comm_size (mpi->mpicomm, &mpi->mpisize); + SC_CHECK_MPI (mpiret); + mpiret = sc_MPI_Comm_rank (mpi->mpicomm, &mpi->mpirank); + SC_CHECK_MPI (mpiret); + + sc_init (mpi->mpicomm, 1, 1, NULL, SC_LP_DEFAULT); + p4est_init (NULL, SC_LP_DEFAULT); + + /* usage error if the input is not in the correct format */ + usage = + "Arguments: \n" + " Level: controls the maximum depth of refinement\n"; + wrongusage = 0; + if (!wrongusage && argc != 2) { + wrongusage = 1; + } + if (wrongusage) { + P4EST_GLOBAL_LERROR (usage); + sc_abort_collective ("Usage error"); + } + + /* assign variables based on configuration */ + refine_level = atoi (argv[1]); + + /* create connectivity and forest structures */ + geom = NULL; +#ifndef P4_TO_P8 + /* this 2D connectivity is challenging for the balance algorithm */ + connectivity = p4est_connectivity_new_bowtie (); +#else + /* this 3D connectivity is challenging for the balance algorithm */ + connectivity = p8est_connectivity_new_drop (); +#endif + p4est = p4est_new_ext (mpi->mpicomm, connectivity, 0, 0, 1, 0, NULL, geom); + p4est_vtk_write_file (p4est, geom, P4EST_STRING "_corner_new"); + + /* refinement */ + p4est_refine (p4est, 1, refine_fn, NULL); + p4est_vtk_write_file (p4est, geom, P4EST_STRING "_corner_refine"); + + /* balance */ + p4est_balance (p4est, P4EST_CONNECT_FULL, NULL); + p4est_vtk_write_file (p4est, geom, P4EST_STRING "_corner_balance"); + + /* partition */ + p4est_partition (p4est, 0, NULL); + p4est_vtk_write_file (p4est, geom, P4EST_STRING "_corner_partition"); + + /* destroy p4est and its connectivity */ + p4est_destroy (p4est); + p4est_connectivity_destroy (connectivity); + + /* clean up and exit */ + sc_finalize (); + + mpiret = sc_MPI_Finalize (); + SC_CHECK_MPI (mpiret); + + return 0; +} diff --git a/example/balance/balance_corner3.c b/example/balance/balance_corner3.c new file mode 100644 index 000000000..39a124db0 --- /dev/null +++ b/example/balance/balance_corner3.c @@ -0,0 +1,26 @@ +/* + This file is part of p4est. + p4est is a C library to manage a collection (a forest) of multiple + connected adaptive quadtrees or octrees in parallel. + + Copyright (C) 2010 The University of Texas System + Additional copyright (C) 2011 individual authors + Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + + p4est is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + p4est is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with p4est; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include +#include "balance_corner2.c" diff --git a/src/p4est_connectivity.h b/src/p4est_connectivity.h index 29c5cb9bd..5458a21ee 100644 --- a/src/p4est_connectivity.h +++ b/src/p4est_connectivity.h @@ -32,7 +32,7 @@ * direction of its x- and y-axes as well as the numbering of its faces and * corners. * Each tree may connect to any other tree (including itself) across any of - * its faces and/or edges, where the neighbor may be arbitrarily rotated + * its faces and/or corners, where the neighbor may be arbitrarily rotated * and/or flipped. * The \ref p4est_connectivity data structure stores these connections. * @@ -292,7 +292,7 @@ void p4est_neighbor_transform_coordinates_reverse * * \param [in] conn Connectivity structure. * \param [in] tree_id The number of the tree. - * \param [in] boundary_type The type of the boundary connection (self, face, corner, edge). + * \param [in] boundary_type The type of the boundary connection (self, face, corner). * \param [in] boundary_index The index of the boundary. * \param [in,out] neighbor_transform_array Array of the neighbor transforms. */ @@ -660,13 +660,13 @@ p4est_connectivity_t *p4est_connectivity_new_byname (const char *name); * than a power of 2. * * \param [in] conn A valid connectivity - * \param [in] num_per_edge The number of new trees in each direction. + * \param [in] num_per_dim The number of new trees in each direction. * Must use no more than \ref P4EST_OLD_QMAXLEVEL bits. * * \return a refined connectivity. */ p4est_connectivity_t *p4est_connectivity_refine (p4est_connectivity_t * conn, - int num_per_edge); + int num_per_dim); /** Fill an array with the axis combination of a face neighbor transform. * \param [in] iface The number of the originating face. @@ -679,7 +679,7 @@ p4est_connectivity_t *p4est_connectivity_refine (p4est_connectivity_t * conn, * the first referring to the tangential and the second * to the normal. A permutation of (0, 1). * [3,5] The coordinate axis sequence of the target face. - * [6,8] Edge reversal flag for tangential axis (boolean); + * [6,8] Face reversal flag for tangential axis (boolean); * face code in [0, 3] for the normal coordinate q: * 0: q' = -q * 1: q' = q + 1 @@ -697,7 +697,8 @@ void p4est_expand_face_transform (int iface, int nface, * \param [out] ftransform This array holds 9 integers. * [0,2] The coordinate axis sequence of the origin face. * [3,5] The coordinate axis sequence of the target face. - * [6,8] Edge reverse flag for axis t; face code for axis n. + * [6,8] Face reversal flag for axis t; face code for axis n. + * \see p4est_expand_face_transform. * [1,4,7] 0 (unused for compatibility with 3D). * \return The face neighbor tree if it exists, -1 otherwise. */ diff --git a/src/p8est_connectivity.h b/src/p8est_connectivity.h index 9d2553297..1cb130b20 100644 --- a/src/p8est_connectivity.h +++ b/src/p8est_connectivity.h @@ -24,7 +24,36 @@ /** \file p8est_connectivity.h * - * The coarse topological description of the forest. + * The connectivity defines the coarse topology of the forest. + * + * A 3D forest consists of one or more octrees, each of which a logical + * cube. + * Each tree has a local coordinate system, which defines the origin and the + * direction of its x-, y-, and z-axes as well as the numbering of its + * faces, edges, and corners. + * Each tree may connect to any other tree (including itself) across any of + * its faces, edges and/or corners, where the neighbor may be arbitrarily + * rotated and/or flipped. + * The \ref p8est_connectivity data structure stores these connections. + * + * We impose the following requirement for consistency of \ref p8est_balance : + * + * \note If a connectivity implies natural connections between trees that + * are edge neighbors without being face neighbors, these edges shall be + * encoded explicitly in the connectivity. If a connectivity implies + * natural connections between trees that are corner neighbors without being + * edge or face neighbors, these corners shall be encoded explicitly in the + * connectivity. + * Please see the documentation of \ref p8est_connectivity_t for the exact + * encoding convention. + * + * We provide various predefined connectivitys by dedicated constructors, + * such as + * + * * \ref p8est_connectivity_new_unitcube for the unit square, + * * \ref p8est_connectivity_new_periodic for the periodic unit square, + * * \ref p8est_connectivity_new_brick for a rectangular grid of trees, + * * \ref p8est_connectivity_new_drop for a sparsely loop of trees. * * \ingroup p8est */ @@ -64,13 +93,13 @@ SC_EXTERN_C_BEGIN; /** Exponentiate with dimension */ #define P8EST_DIM_POW(a) ((a) * (a) * (a)) -/* size of face transformation encoding */ +/** size of face transformation encoding */ #define P8EST_FTRANSFORM 9 /** p8est identification string */ #define P8EST_STRING "p8est" -/* Increase this number whenever the on-disk format for +/** Increase this number whenever the on-disk format for * p8est_connectivity, p8est, or any other 3D data structure changes. * The format for reading and writing must be the same. */ @@ -129,6 +158,7 @@ const char *p8est_connect_type_string (p8est_connect_type_t btype); * For faces the order is -x +x -y +y -z +z. * They are allocated [0][0]..[0][N-1]..[num_trees-1][0]..[num_trees-1][N-1]. * where N is 6 for tree and face, 8 for corner, 12 for edge. + * If a face is on the physical boundary it must connect to itself. * * The values for tree_to_face are in 0..23 * where ttf % 6 gives the face number and ttf / 6 the face orientation code. @@ -143,8 +173,10 @@ const char *p8est_connect_type_string (p8est_connect_type_t btype); * In this case vertices and tree_to_vertex are set to NULL. * Otherwise the vertex coordinates are stored in the array vertices as * [0][0]..[0][2]..[num_vertices-1][0]..[num_vertices-1][2]. + * Vertex coordinates are optional and not used for inferring topology. * - * The edges are only stored when they connect trees. + * The edges are stored when they connect trees that are not already face + * neighbors at that specific edge. * In this case tree_to_edge indexes into \a ett_offset. * Otherwise the tree_to_edge entry must be -1 and this edge is ignored. * If num_edges == 0, tree_to_edge and edge_to_* arrays are set to NULL. @@ -157,7 +189,8 @@ const char *p8est_connect_type_string (p8est_connect_type_t btype); * The edge_to_edge array holds values in 0..23, where the lower 12 indicate * one edge orientation and the higher 12 the opposite edge orientation. * - * The corners are only stored when they connect trees. + * The corners are stored when they connect trees that are not already edge + * or face neighbors at that specific corner. * In this case tree_to_corner indexes into \a ctt_offset. * Otherwise the tree_to_corner entry must be -1 and this corner is ignored. * If num_corners == 0, tree_to_corner and corner_to_* arrays are set to NULL. @@ -169,6 +202,13 @@ const char *p8est_connect_type_string (p8est_connect_type_t btype); * The size of the corner_to_* arrays is num_ctt = ctt_offset[num_corners]. * * The *_to_attr arrays may have arbitrary contents defined by the user. + * + * \note If a connectivity implies natural connections between trees that + * are edge neighbors without being face neighbors, these edges shall be + * encoded explicitly in the connectivity. If a connectivity implies + * natural connections between trees that are corner neighbors without being + * edge or face neighbors, these corners shall be encoded explicitly in the + * connectivity. */ typedef struct p8est_connectivity { @@ -218,31 +258,40 @@ p8est_connectivity_t; size_t p8est_connectivity_memory_used (p8est_connectivity_t * conn); +/** Generic interface for transformations between a tree and any of its edge */ typedef struct { - p4est_topidx_t ntree; - int8_t nedge, naxis[3], nflip, corners; + p4est_topidx_t ntree; /**< The number of the tree*/ + int8_t nedge; /**< The number of the edge*/ + int8_t naxis[3]; /**< The 3 edge coordinate axes*/ + int8_t nflip; /**< The orientation of the edge*/ + int8_t corners; /**< The corners connected to the edge*/ } p8est_edge_transform_t; +/** Information about the neighbors of an edge*/ typedef struct { - int8_t iedge; - sc_array_t edge_transforms; + int8_t iedge; /**< The information of the edge*/ + sc_array_t edge_transforms; /**< The array of neighbors of the originating + edge */ } p8est_edge_info_t; +/** Generic interface for transformations between a tree and any of its corner */ typedef struct { - p4est_topidx_t ntree; - int8_t ncorner; + p4est_topidx_t ntree; /**< The number of the tree*/ + int8_t ncorner; /**< The number of the corner*/ } p8est_corner_transform_t; +/** Information about the neighbors of a corner*/ typedef struct { - p4est_topidx_t icorner; - sc_array_t corner_transforms; + p4est_topidx_t icorner; /**< The number of the originating corner */ + sc_array_t corner_transforms; /**< The array of neighbors of the originating + corner */ } p8est_corner_info_t; @@ -260,9 +309,9 @@ typedef struct neighbor coords */ int8_t sign[P8EST_DIM]; /**< sign changes when transforming self coords to neighbor coords */ - p4est_qcoord_t origin_self[P8EST_DIM]; /** point on the interface from + p4est_qcoord_t origin_self[P8EST_DIM]; /**< point on the interface from self's perspective */ - p4est_qcoord_t origin_neighbor[P8EST_DIM]; /** point on the interface + p4est_qcoord_t origin_neighbor[P8EST_DIM]; /**< point on the interface from neighbor's perspective */ } @@ -292,6 +341,15 @@ void p8est_neighbor_transform_coordinates_reverse const p4est_qcoord_t neigh_coords[P8EST_DIM], p4est_qcoord_t self_coords[P8EST_DIM]); +/** Fill an array with the neighbor transforms based on a specific boundary type. + * This function generalizes all other inter-tree transformation objects + * + * \param [in] conn Connectivity structure. + * \param [in] tree_id The number of the tree. + * \param [in] boundary_type Type of boundary connection (self, face, edge, corner). + * \param [in] boundary_index The index of the boundary. + * \param [in,out] neighbor_transform_array Array of the neighbor transforms. + */ void p8est_connectivity_get_neighbor_transforms (p8est_connectivity_t *conn, p4est_topidx_t tree_id, @@ -441,7 +499,7 @@ int p8est_connectivity_edge_neighbor_edge_corner * This version expects the neighbor edge and orientation separately. * \param [in] c A corner number in 0..7. * \param [in] e An edge 0..11 that touches the corner \a c. - * \param [in] ne A neighbor edge that is on the other side of \e. + * \param [in] ne A neighbor edge that is on the other side of \a e. * \param [in] o The orientation between tree boundary edges \a e and \a ne. * \return Corner number seen from the neighbor. */ @@ -471,12 +529,22 @@ p8est_connectivity_t *p8est_connectivity_new (p4est_topidx_t num_vertices, * \param [in] num_trees Number of trees in the forest. * \param [in] num_edges Number of tree-connecting edges. * \param [in] num_corners Number of tree-connecting corners. + * \param [in] vertices Coordinates of the vertices of the trees. + * \param [in] ttv The tree-to-vertex array. + * \param [in] ttt The tree-to-tree array. + * \param [in] ttf The tree-to-face array (int8_t). + * \param [in] tte The tree-to-edge array. * \param [in] eoff Edge-to-tree offsets (num_edges + 1 values). * This must always be non-NULL; in trivial cases * it is just a pointer to a p4est_topix value of 0. + * \param [in] ett The edge-to-tree array. + * \param [in] ete The edge-to-edge array. + * \param [in] ttc The tree-to-corner array. * \param [in] coff Corner-to-tree offsets (num_corners + 1 values). * This must always be non-NULL; in trivial cases * it is just a pointer to a p4est_topix value of 0. + * \param [in] ctt The corner-to-tree array. + * \param [in] ctc The corner-to-corner array. * \return The connectivity is checked for validity. */ p8est_connectivity_t *p8est_connectivity_new_copy (p4est_topidx_t @@ -691,13 +759,13 @@ p8est_connectivity_t *p8est_connectivity_new_byname (const char *name); * than a power of 2. * * \param [in] conn A valid connectivity - * \param [in] num_per_edge The number of new trees in each direction. + * \param [in] num_per_dim The number of new trees in each direction. * Must use no more than \ref P8EST_OLD_QMAXLEVEL bits. * * \return a refined connectivity. */ p8est_connectivity_t *p8est_connectivity_refine (p8est_connectivity_t * conn, - int num_per_edge); + int num_per_dim); /** Fill an array with the axis combination of a face neighbor transform. * \param [in] iface The number of the originating face. @@ -721,12 +789,14 @@ void p8est_expand_face_transform (int iface, int nface, int ftransform[]); /** Fill an array with the axis combination of a face neighbor transform. + * \param [in] connectivity Connectivity structure. * \param [in] itree The number of the originating tree. * \param [in] iface The number of the originating tree's face. * \param [out] ftransform This array holds 9 integers. * [0]..[2] The coordinate axis sequence of the origin face. * [3]..[5] The coordinate axis sequence of the target face. - * [6]..[8] Edge reverse flag for axes t1, t2; face code for n. + * [6]..[8] Edge reversal flag for axes t1, t2; face code for n; + * \see p8est_expand_face_transform. * \return The face neighbor tree if it exists, -1 otherwise. */ p4est_topidx_t p8est_find_face_transform (p8est_connectivity_t * @@ -735,6 +805,7 @@ p4est_topidx_t p8est_find_face_transform (p8est_connectivity_t * int iface, int ftransform[]); /** Fills an array with information about edge neighbors. + * \param [in] connectivity Connectivity structure. * \param [in] itree The number of the originating tree. * \param [in] iedge The number of the originating edge. * \param [in,out] ei A p8est_edge_info_t structure with initialized array. @@ -746,6 +817,7 @@ void p8est_find_edge_transform (p8est_connectivity_t * p8est_edge_info_t * ei); /** Fills an array with information about corner neighbors. + * \param [in] connectivity Connectivity structure. * \param [in] itree The number of the originating tree. * \param [in] icorner The number of the originating corner. * \param [in,out] ci A p8est_corner_info_t structure with initialized array.