/*1This file is part of t8code.2t8code is a C library to manage a collection (a forest) of multiple3connected adaptive space-trees of general element classes in parallel.45Copyright (C) 2015 the developers67t8code is free software; you can redistribute it and/or modify8it under the terms of the GNU General Public License as published by9the Free Software Foundation; either version 2 of the License, or10(at your option) any later version.1112t8code is distributed in the hope that it will be useful,13but WITHOUT ANY WARRANTY; without even the implied warranty of14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15GNU General Public License for more details.1617You should have received a copy of the GNU General Public License18along with t8code; if not, write to the Free Software Foundation, Inc.,1951 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.20*/2122/** \file t8_cmesh.h23* We define the coarse mesh of trees in this file.24*/2526#ifndef T8_CMESH_H27#define T8_CMESH_H2829#include <t8.h>30#include <t8_data/t8_shmem.h>31#include <t8_cmesh/t8_cmesh_io/t8_cmesh_save.h>32#include <t8_element.h>33#include <t8_schemes/t8_scheme.h>3435/** Forward pointer reference to hidden cmesh implementation.36* This reference needs to be known by t8_geometry, hence we37* put it before the include. */38typedef struct t8_cmesh *t8_cmesh_t;3940#include <t8_geometry/t8_geometry.h>4142/* TODO: If including eclass were just for the cmesh_new routines, we should43* move them into a different file.44* However, when specifying the parent-child order in cmesh_reorder,45* we might keep the eclass interface for virtual functions.46* Actually, we need eclass in the type definition in cmesh.c.47* So we might as well use tree-related virtual functions there too.48*/49#include <t8_eclass.h>5051/* TODO: make it legal to call cmesh_set functions multiple times,52* just overwrite the previous setting if no inconsistency can occur.53* edit: This should be achieved now.54*/5556/** Forward pointer references to hidden implementations of57* tree. */58typedef struct t8_ctree *t8_ctree_t;59/** Forward pointer references to hidden implementations of60* ghost tree. */61typedef struct t8_cghost *t8_cghost_t;6263T8_EXTERN_C_BEGIN ();6465/** Create a new cmesh with reference count one.66* This cmesh needs to be specialized with the t8_cmesh_set_* calls.67* Then it needs to be set up with \ref t8_cmesh_commit.68* \param [in,out] pcmesh On input, this pointer must be non-NULL.69* On return, this pointer set to the new cmesh.70*/71void72t8_cmesh_init (t8_cmesh_t *pcmesh);7374/** Allocate a new un-committed cmesh.75* \return A pointer to an un-committed t8_cmesh structure.76*/77t8_cmesh_t78t8_cmesh_new ();7980/** Check whether a cmesh is not NULL, initialized and not committed.81* In addition, it asserts that the cmesh is consistent as much as possible.82* \param [in] cmesh This cmesh is examined. May be NULL.83* \return True if cmesh is not NULL,84* \ref t8_cmesh_init has been called on it,85* but not \ref t8_cmesh_commit.86* False otherwise.87*/88int89t8_cmesh_is_initialized (t8_cmesh_t cmesh);9091/** Check whether a cmesh is not NULL, initialized and committed.92* In addition, it asserts that the cmesh is consistent as much as possible.93* \param [in] cmesh This cmesh is examined. May be NULL.94* \return True if cmesh is not NULL and95* \ref t8_cmesh_init has been called on it96* as well as \ref t8_cmesh_commit.97* False otherwise.98*/99int100t8_cmesh_is_committed (const t8_cmesh_t cmesh);101102/** Disable the debug check for negative volumes in trees during \ref t8_cmesh_commit.103* Does nothing outside of debug mode.104* \param [in, out] cmesh105*/106void107t8_cmesh_disable_negative_volume_check (t8_cmesh_t cmesh);108109#if T8_ENABLE_DEBUG110/** Check the geometry of the mesh for validity, this means checking if trees and their geometries111* are compatible and if they have negative volume.112* \param [in] cmesh This cmesh is examined.113* \param [in] check_for_negative_volume Enable the negative volume check.114* \return True if the geometry of the cmesh is valid.115*/116int117118t8_cmesh_validate_geometry (const t8_cmesh_t cmesh, const int check_for_negative_volume);119#endif120121/* TODO: Currently it is not possible to destroy set_from before122* cmesh is destroyed. */123/** This function sets a cmesh to be derived from.124* The default is to create a cmesh standalone by specifying all data manually.125* A coarse mesh can also be constructed by deriving it from an existing one.126* The derivation from another cmesh may optionally be combined with a127* repartition or uniform refinement of each tree.128* This function overrides a previously set cmesh to be derived from.129* \param [in,out] cmesh Must be initialized, but not committed.130* May even be NULL to revert to standalone.131* \param [in,out] set_from Reference counter on this cmesh is bumped.132* It will be unbumped by \ref t8_cmesh_commit,133* after which \a from is no longer remembered.134* Other than that the from object is not changed.135*/136void137t8_cmesh_set_derive (t8_cmesh_t cmesh, t8_cmesh_t set_from);138139/** Allocate a shared memory array to store the tree offsets of a cmesh.140* \param [in] mpisize The number of processes.141* \param [in] comm The MPI communicator to use. Its mpisize must match \a mpisize.142* The shared memory type must have been set. Best practice would be143* calling sc_shmem_set_type (comm, T8_SHMEM_BEST_TYPE).144* \return A t8_shmem_array struct that stores \a mpisize + 1 t8_gloidx_t entries.145* \see t8_shmem.h146*/147t8_shmem_array_t148t8_cmesh_alloc_offsets (int mpisize, sc_MPI_Comm comm);149150/** Declare if the cmesh is understood as a partitioned cmesh and specify151* the processor local tree range.152* This function should be preferred over \ref t8_cmesh_set_partition_offsets153* when the cmesh is not derived from another cmesh.154* This call is only valid when the cmesh is not yet committed via a call155* to \ref t8_cmesh_commit.156* \param [in,out] cmesh The cmesh to be updated.157* \param [in] set_face_knowledge Several values are possible that define158* how much information is required on face connections,159* specified by \ref t8_cmesh_set_join.160* 0: Expect face connection of local trees.161* 1: In addition, expect face connection from162* ghost trees to local trees.163* 2: In addition, expect face connection between164* ghost trees.165* 3: Expect face connection of local and ghost trees.166* Consistency of this requirement is checked on167* \ref t8_cmesh_commit.168* -1: Do not change the face_knowledge level but keep any169* previously set ones. (Possibly by a previous call to \ref t8_cmesh_set_partition_range)170* \param [in] first_local_tree The global index ID of the first tree on this process.171* If this tree is also the last tree on the previous process,172* then the argument must be -ID - 1.173* \param [in] last_local_tree The global index of the last tree on this process.174* If this process should be empty then \a last_local_tree175* must be strictly smaller than \a first_local_tree.176*177* \see t8_cmesh_set_partition_offset \see t8_cmesh_set_partition_uniform178* \note A value of \a set_face_knowledge other than -1 or 3 is not yet supported.179*/180void181t8_cmesh_set_partition_range (t8_cmesh_t cmesh, int set_face_knowledge, t8_gloidx_t first_local_tree,182t8_gloidx_t last_local_tree);183184/** Declare if the cmesh is understood as a partitioned cmesh and specify185* the first local tree for each process.186* This call is only valid when the cmesh is not yet committed via a call187* to \ref t8_cmesh_commit.188* If instead \ref t8_cmesh_set_partition_range was called and the cmesh is189* derived then the offset array is constructed during commit.190* \param [in,out] cmesh The cmesh to be updated.191* \param [in] tree_offsets An array of global tree_id offsets192* for each process can be specified here.193* TODO: document flag for shared trees.194*/195void196t8_cmesh_set_partition_offsets (t8_cmesh_t cmesh, t8_shmem_array_t tree_offsets);197198/** Declare if a derived cmesh should be partitioned according to a199* uniform refinement of a given level for the provided scheme.200* This call is only valid when the cmesh is not yet committed via a call201* to \ref t8_cmesh_commit and when the cmesh will be derived.202* \param [in,out] cmesh The cmesh to be updated.203* \param [in] element_level The refinement_level.204* \param [in] scheme The element scheme describing the refinement pattern.205* We take ownership. This can be prevented by206* referencing \b scheme before calling this function.207*/208void209t8_cmesh_set_partition_uniform (t8_cmesh_t cmesh, const int element_level, const t8_scheme_c *scheme);210211/** Refine the cmesh to a given level.212* Thus split each tree into x^level subtrees213* TODO: implement */214/* If level = 0 then no refinement is performed */215void216t8_cmesh_set_refine (t8_cmesh_t cmesh, const int level, const t8_scheme_c *scheme);217218/** Set the dimension of a cmesh. If any tree is inserted to the cmesh219* via \a t8_cmesh_set_tree_class, then the dimension is set automatically220* to that of the inserted tree.221* However, if the cmesh is constructed partitioned and the part on this process222* is empty, it is necessary to set the dimension by hand.223* \param [in,out] cmesh The cmesh to be updated.224* \param [in] dim The dimension to be set. Must satisfy 0 <= dim <= 3.225* The cmesh must not be committed before calling this function.226*/227void228t8_cmesh_set_dimension (t8_cmesh_t cmesh, int dim);229230/** Set the class of a tree in the cmesh.231* It is not allowed to call this function after \ref t8_cmesh_commit.232* It is not allowed to call this function multiple times for the same tree.233* \param [in,out] cmesh The cmesh to be updated.234* \param [in] gtree_id The global number of the tree.235* \param [in] tree_class The element class of this tree.236*/237void238t8_cmesh_set_tree_class (t8_cmesh_t cmesh, t8_gloidx_t gtree_id, t8_eclass_t tree_class);239240/** Store an attribute at a tree in a cmesh.241* Attributes can be arbitrary data that is copied to an internal storage242* associated to the tree.243* Each application can set multiple attributes and attributes are distinguished244* by an integer key, where each application can use any integer as key.245*246* \param [in, out] cmesh The cmesh to be updated.247* \param [in] gtree_id The global id of the tree.248* \param [in] package_id Unique identifier of a valid software package. \see sc_package_register249* \param [in] key An integer key used to identify this attribute under all250* attributes with the same package_id.251* \a key must be a unique value for this tree and package_id.252* \param [in] data A pointer to the attribute data.253* \param [in] data_size The number of bytes of the attribute.254* \param [in] data_persists This flag can be used to optimize memory. If true255* then t8code assumes that the attribute data is present at the256* memory that \a data points to when \ref t8_cmesh_commit is called257* (This is more memory efficient).258* If the flag is false an internal copy of the data is created259* immediately and this copy is used at commit.260* In both cases a copy of the data is used by t8_code after t8_cmesh_commit.261* \note If an attribute with the given package_id and key already exists, then it will get overwritten.262*/263void264t8_cmesh_set_attribute (t8_cmesh_t cmesh, t8_gloidx_t gtree_id, int package_id, int key, void *data, size_t data_size,265int data_persists);266267/** Store a string as an attribute at a tree in a cmesh.268* \param [in, out] cmesh The cmesh to be updated.269* \param [in] gtree_id The global id of the tree.270* \param [in] package_id Unique identifier of a valid software package. \see sc_package_register271* \param [in] key An integer key used to identify this attribute under all272* attributes with the same package_id.273* \a key must be a unique value for this tree and package_id.274* \param [in] string The string to store as attribute.275* \note You can also use \ref t8_cmesh_set_attribute, but we recommend using this276* specialized function for strings.277* \note If an attribute with the given package_id and key already exists, then it will get overwritten.278*/279void280t8_cmesh_set_attribute_string (t8_cmesh_t cmesh, t8_gloidx_t gtree_id, int package_id, int key, const char *string);281282/** Store an array of t8_gloidx_t as an attribute at a tree in a cmesh.283* \param [in, out] cmesh The cmesh to be updated.284* \param [in] gtree_id The global id of the tree.285* \param [in] package_id Unique identifier of a valid software package. \see sc_package_register286* \param [in] key An integer key used to identify this attribute under all287* attributes with the same package_id.288* \a key must be a unique value for this tree and package_id.289* \param [in] data The array to store as attribute.290* \param [in] data_count The number of entries in \a data.291* \param [in] data_persists This flag can be used to optimize memory. If true292* then t8code assumes that the attribute data is present at the293* memory that \a data points to when \ref t8_cmesh_commit is called294* (This is more memory efficient).295* If the flag is false an internal copy of the data is created296* immediately and this copy is used at commit.297* In both cases a copy of the data is used by t8_code after t8_cmesh_commit.298* \note You can also use \ref t8_cmesh_set_attribute, but we recommend using this299* specialized function for arrays.300* \note If an attribute with the given package_id and key already exists, then it will get overwritten.301* \note We do not store the number of data entries \a data_count of the attribute array.302* You can keep track of the data count yourself by using another attribute.303*/304void305t8_cmesh_set_attribute_gloidx_array (t8_cmesh_t cmesh, t8_gloidx_t gtree_id, int package_id, int key,306const t8_gloidx_t *data, const size_t data_count, int data_persists);307308/** Insert a face-connection between two trees in a cmesh.309* \param [in,out] cmesh The cmesh to be updated.310* \param [in] gtree1 The tree id of the first of the two trees.311* \param [in] gtree2 The tree id of the second of the two trees.312* \param [in] face1 The face number of the first tree.313* \param [in] face2 The face number of the second tree.314* \param [in] orientation Specify how face1 and face2 are oriented to each other315*316* \note The orientation is defined as:317* Let my_face and other_face be the two face numbers of the connecting trees.318* We chose a main_face from them as follows: Either both trees have the same319* element class, then the face with the lower face number is the main_face or320* the trees belong to different classes in which case the face belonging to the321* tree with the lower class according to the ordering322* triangle < quad, hex < tet < prism < pyramid, is the main_face.323* Then face corner 0 of the main_face connects to a face324* corner k in the other face. The face orientation is defined as the number k.325* If the classes are equal and my_face == other_face, treating326* either of both faces as the main_face leads to the same result.327* See https://arxiv.org/pdf/1611.02929.pdf for more details.328*/329void330t8_cmesh_set_join (t8_cmesh_t cmesh, t8_gloidx_t gtree1, t8_gloidx_t gtree2, int face1, int face2, int orientation);331332/** Enable or disable profiling for a cmesh. If profiling is enabled, runtimes333* and statistics are collected during cmesh_commit.334* \param [in,out] cmesh The cmesh to be updated.335* \param [in] set_profiling If true, profiling will be enabled, if false336* disabled.337*338* Profiling is disabled by default.339* The cmesh must not be committed before calling this function.340* \see t8_cmesh_print_profile341*/342void343t8_cmesh_set_profiling (t8_cmesh_t cmesh, int set_profiling);344345/* returns true if cmesh_a equals cmesh_b */346/* TODO: document347* collective or serial */348/** Check whether two given cmeshes carry the same information.349* \param [in] cmesh_a The first of the two cmeshes to be checked.350* \param [in] cmesh_b The second of the two cmeshes to be checked.351* \return True if both cmeshes carry the same information,352* false otherwise.353* TODO: define carefully.354* Orders, sequences, equivalences?355* This function works on committed and uncommitted cmeshes.356*/357int358t8_cmesh_is_equal (t8_cmesh_t cmesh_a, t8_cmesh_t cmesh_b);359360/** Check whether a cmesh is empty on all processes.361* \param [in] cmesh A committed cmesh.362* \return True (non-zero) if and only if the cmesh has trees at all.363*/364int365t8_cmesh_is_empty (t8_cmesh_t cmesh);366367/** Broadcast a cmesh structure that exists only on one process to all368* processes in the cmesh's communicator.369* TODO: Input structure must be replicated, not parallelized.370* TODO: Recommend to call this just before commit. Earlier is thinkable too.371* On the other processors, it will be allocated.372* It is not allowed to call this function after \ref t8_cmesh_commit.373* \param [in] cmesh_in For the root process the cmesh to be broadcast,374* for the other processes it must be NULL.375* \param [in] root The rank of the process that provides the cmesh.376* \param [in] comm The mpi communicator. Must match cmesh's communicator377* on the root process.378* \return For the root process this is a pointer to \a cmesh_in.379* Else, a pointer to a newly allocated cmesh380* structure with the same values as \a conn_in on the381* root process.382* \note It is illegal to broadcast a cmesh with a registered geometry (\ref t8_cmesh_register_geometry).383* All geometries must be registered after the broadcast (You can set tree attributes before bcast, though).384*/385t8_cmesh_t386t8_cmesh_bcast (t8_cmesh_t cmesh_in, int root, sc_MPI_Comm comm);387388#if T8_ENABLE_METIS389/* TODO: document this. */390/* TODO: think about making this a pre-commit set_reorder function. */391void392t8_cmesh_reorder (t8_cmesh_t cmesh, sc_MPI_Comm comm);393394/* TODO: think about a sensible interface for a parmetis reordering. */395#endif396397/** Register a geometry in the cmesh. The cmesh takes ownership of the geometry.398* \param [in,out] cmesh The cmesh.399* \param [in] geometry The geometry to register.400*401* If no geometry is registered and cmesh is modified from another cmesh then402* the other cmesh's geometries are used.403* \note If you need to use \ref t8_cmesh_bcast, then all geometries must be404* registered \a after the bcast operation, not before.405*/406void407t8_cmesh_register_geometry (t8_cmesh_t cmesh, t8_geometry_c *geometry);408409/** Set the geometry for a tree, thus specify which geometry to use for this tree.410* \param [in] cmesh A non-committed cmesh.411* \param [in] gtreeid A global tree id in \a cmesh.412* \param [in] geom The geometry to use for this tree.413* See also \ref t8_cmesh_get_tree_geometry414*/415void416t8_cmesh_set_tree_geometry (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const t8_geometry_c *geom);417418/** After allocating and adding properties to a cmesh, finish its construction.419* TODO: this function is MPI collective.420* \param [in,out] cmesh Must be created with \ref t8_cmesh_init421* (TODO: or bcast) and422* specialized with t8_cmesh_set_* calls first (?).423* \param [in] comm The MPI communicator to use.424*/425void426t8_cmesh_commit (t8_cmesh_t cmesh, sc_MPI_Comm comm);427428/**429* Save the cmesh to a file with the given fileprefix.430*431* \param[in] cmesh The cmesh to save.432* \param[in] fileprefix The prefix of the file to save the cmesh to.433*434* \note Currently, it is only legal to save cmeshes that use the linear geometry.435*/436int437t8_cmesh_save (t8_cmesh_t cmesh, const char *fileprefix);438439/**440* Load a cmesh from a file.441*442* \param[in] filename The name of the file to load the cmesh from.443* \param[in] comm The MPI communicator to use.444*/445t8_cmesh_t446t8_cmesh_load (const char *filename, sc_MPI_Comm comm);447448/**449* Load a cmesh from multiple files and distribute it across the processes.450*451* \param[in] fileprefix The prefix of the files to load the cmesh from.452* \param[in] num_files The number of files to load.453* \param[in] comm The MPI communicator to use.454* \param[in] mode The load mode to use, see \ref t8_load_mode_t.455* \param[in] procs_per_node The number of processes per node, only relevant in JUQUEEN mode.456*457* \note \a procs_per_node is only relevant in mode==JUQUEEN. If \a num_files = 1 a replicated cmesh is constructed.458*/459t8_cmesh_t460t8_cmesh_load_and_distribute (const char *fileprefix, int num_files, sc_MPI_Comm comm, t8_load_mode_t mode,461int procs_per_node);462463/** Check whether a given MPI communicator assigns the same rank and mpisize464* as stored in a cmesh.465* \param [in] cmesh The cmesh to be considered.466* \param [in] comm A MPI communicator.467* \return True if mpirank and mpisize from \a comm are the same as468* the values stored in \a cmesh.469* False otherwise.470* \a cmesh must be committed before calling this function.471* */472int473t8_cmesh_comm_is_valid (t8_cmesh_t cmesh, sc_MPI_Comm comm);474475/** Query whether a committed cmesh is partitioned or replicated.476* \param [in] cmesh A committed cmesh.477* \return True if \a cmesh is partitioned.478* False otherwise.479* \a cmesh must be committed before calling this function.480*/481int482t8_cmesh_is_partitioned (t8_cmesh_t cmesh);483484/** Get the dimension of a cmesh.485* \param [in] cmesh The cmesh.486* \a cmesh must be committed before calling this function.487*/488int489t8_cmesh_get_dimension (const t8_cmesh_t cmesh);490491/** Return the global number of trees in a cmesh.492* \param [in] cmesh The cmesh to be considered.493* \return The number of trees associated to \a cmesh.494* \a cmesh must be committed before calling this function.495*/496t8_gloidx_t497t8_cmesh_get_num_trees (t8_cmesh_t cmesh);498499/** Return the number of local trees of a cmesh.500* If the cmesh is not partitioned this is equivalent to \ref t8_cmesh_get_num_trees.501* \param [in] cmesh The cmesh to be considered.502* \return The number of local trees of the cmesh.503* \a cmesh must be committed before calling this function.504*/505t8_locidx_t506t8_cmesh_get_num_local_trees (t8_cmesh_t cmesh);507508/** Return the number of ghost trees of a cmesh.509* If the cmesh is not partitioned this is equivalent to \ref t8_cmesh_get_num_trees.510* \param [in] cmesh The cmesh to be considered.511* \return The number of ghost trees of the cmesh.512* \a cmesh must be committed before calling this function.513*/514t8_locidx_t515t8_cmesh_get_num_ghosts (t8_cmesh_t cmesh);516517/** Return the global index of the first local tree of a cmesh.518* If the cmesh is not partitioned this is always 0.519* \param [in] cmesh The cmesh to be considered.520* \return The global id of the first local tree in cmesh.521* \a cmesh must be committed before calling this function.522*/523t8_gloidx_t524t8_cmesh_get_first_treeid (t8_cmesh_t cmesh);525526/** Get the geometry of a tree.527* \param [in] cmesh The cmesh.528* \param [in] gtreeid The global tree id of the tree for which the geometry should be returned.529* \return The geometry of the tree.530*/531const t8_geometry_c *532t8_cmesh_get_tree_geometry (t8_cmesh_t cmesh, t8_gloidx_t gtreeid);533534/** Query whether a given t8_locidx_t belongs to a local tree of a cmesh.535* \param [in] cmesh The cmesh to be considered.536* \param [in] ltreeid An (possible) tree index.537* \return True if \a ltreeid matches the range of local trees of \a cmesh.538* False if not.539* \a cmesh must be committed before calling this function.540*/541int542t8_cmesh_treeid_is_local_tree (const t8_cmesh_t cmesh, const t8_locidx_t ltreeid);543544/** Query whether a given t8_locidx_t belongs to a ghost of a cmesh.545* \param [in] cmesh The cmesh to be considered.546* \param [in] ltreeid An (possible) ghost index.547* \return True if \a ltreeid matches the range of ghost trees of \a cmesh.548* False if not.549* \a cmesh must be committed before calling this function.550*/551int552t8_cmesh_treeid_is_ghost (const t8_cmesh_t cmesh, const t8_locidx_t ltreeid);553554/** Given a local tree id that belongs to a ghost, return the index of the ghost.555* \param [in] cmesh The cmesh to be considered.556* \param [in] ltreeid The local id of a ghost, satisfying \ref t8_cmesh_treeid_is_ghost,557* thus num_trees <= \a ltreeid < num_trees + num_ghosts558* \return The index of the ghost within all ghosts, thus an index559* 0 <= index < num_ghosts560* \a cmesh must be committed before calling this function.561*/562t8_locidx_t563t8_cmesh_ltreeid_to_ghostid (const t8_cmesh_t cmesh, const t8_locidx_t ltreeid);564565/* TODO: Replace this iterator with a new one that does not need the566* treeid to be part of the ctree struct */567/* TODO: should this and the next function be part of the interface? */568/** Return a pointer to the first local tree in a cmesh.569* \param [in] cmesh The cmesh to be queried.570* \return A pointer to the first local tree in \a cmesh.571* If \a cmesh has no local trees, NULL is returned.572* \a cmesh must be committed before calling this function.573*/574t8_ctree_t575t8_cmesh_get_first_tree (t8_cmesh_t cmesh);576577/* TODO: should this function behave like first_tree if tree argument is NULL? */578/** Given a local tree in a cmesh return a pointer to the next local tree.579* \param [in] cmesh The cmesh to be queried.580* \param [in] tree A local tree in \a cmesh.581* \return A pointer to the next local tree in \a cmesh582* after \a tree. If no such tree exists, NULL is583* returned.584* * \a cmesh must be committed before calling this function.585* TODO: If we run over tree numbers only, don't use ctree_t in API if possible.586*/587t8_ctree_t588t8_cmesh_get_next_tree (t8_cmesh_t cmesh, t8_ctree_t tree);589590/** Return a pointer to a given local tree.591* \param [in] cmesh The cmesh to be queried.592* \param [in] ltree_id The local id of the tree that is asked for.593* \return A pointer to tree in \a cmesh with local594* id \a ltree_id.595* The cmesh must have at least \a ltree_id + 1 local trees when596* calling this function.597* \a cmesh must be committed before calling this function.598*/599t8_ctree_t600t8_cmesh_get_tree (t8_cmesh_t cmesh, t8_locidx_t ltree_id);601602/** Return the eclass of a given local tree.603* TODO: Should we refer to indices or consequently use ctree_t?604* \param [in] cmesh The cmesh to be considered.605* \param [in] ltree_id The local id of the tree whose eclass will be returned.606* \return The eclass of the given tree.607* TODO: Call tree ids ltree_id or gtree_id etc. instead of tree_id.608* \a cmesh must be committed before calling this function.609*/610t8_eclass_t611t8_cmesh_get_tree_class (t8_cmesh_t cmesh, t8_locidx_t ltree_id);612613/** Query whether a face of a local tree or ghost is at the domain boundary.614* \param [in] cmesh The cmesh to be considered.615* \param [in] ltree_id The local id of a tree.616* \param [in] face The number of a face of the tree.617* \return True if the face is at the domain boundary.618* False otherwise.619* \a cmesh must be committed before calling this function.620*/621int622t8_cmesh_tree_face_is_boundary (t8_cmesh_t cmesh, t8_locidx_t ltree_id, int face);623624/** Return the eclass of a given local ghost.625* TODO: Should we refer to indices or consequently use cghost_t?626* \param [in] cmesh The cmesh to be considered.627* \param [in] lghost_id The local id of the ghost whose eclass will be returned.628* 0 <= \a tree_id < cmesh.num_ghosts.629* \return The eclass of the given ghost.630* \a cmesh must be committed before calling this function.631*/632t8_eclass_t633t8_cmesh_get_ghost_class (t8_cmesh_t cmesh, t8_locidx_t lghost_id);634635/** Return the global id of a given local tree or ghost.636* \param [in] cmesh The cmesh to be considered.637* \param [in] local_id The local id of a tree or a ghost.638* If \a local_id < cmesh.num_local_trees then it is639* a tree, otherwise a ghost.640* \return The global id of the tree/ghost.641* \see https://github.com/DLR-AMR/t8code/wiki/Tree-indexing for more details about tree indexing.642*/643t8_gloidx_t644t8_cmesh_get_global_id (t8_cmesh_t cmesh, t8_locidx_t local_id);645646/** Return the local id of a give global tree.647* \param [in] cmesh The cmesh.648* \param [in] global_id A global tree id.649* \return Either a value l 0 <= \a l < num_local_trees650* if \a global_id corresponds to a local tree,651* or num_local_trees <= \a l < num_local_trees652* + num_ghosts653* if \a global_id corresponds to a ghost trees,654* or negative if \a global_id neither matches a local655* nor a ghost tree.656* \see https://github.com/DLR-AMR/t8code/wiki/Tree-indexing for more details about tree indexing.657*/658t8_locidx_t659t8_cmesh_get_local_id (t8_cmesh_t cmesh, t8_gloidx_t global_id);660661/** Given a local tree id and a face number, get information about the face neighbor tree.662* \param [in] cmesh The cmesh to be considered.663* \param [in] ltreeid The local id of a tree or a ghost.664* \param [in] face A face number of the tree/ghost.665* \param [out] dual_face If not NULL, the face number of the neighbor tree at this connection.666* \param [out] orientation If not NULL, the face orientation of the connection.667* \return If non-negative: The local id of the neighbor tree or ghost.668* If negative: There is no neighbor across this face. \a dual_face and669* \a orientation remain unchanged.670* \note If \a ltreeid is a ghost and it has a neighbor which is neither a local tree or ghost,671* then the return value will be negative.672* Thus, a negative return value does not necessarily mean that this is a domain boundary.673* To find out whether a tree is a domain boundary or not \see t8_cmesh_tree_face_is_boundary.674*/675t8_locidx_t676t8_cmesh_get_face_neighbor (const t8_cmesh_t cmesh, const t8_locidx_t ltreeid, const int face, int *dual_face,677int *orientation);678679/**680* Given a local tree id (of a local tree or ghost tree) and a face compute the eclass of the681* tree's face neighbor.682*683* \param [in] cmesh The cmesh to be considered.684* \param [in] ltreeid The local id of a tree or a ghost.685* \param [in] face A face number of the tree/ghost.686* \return The eclass of a neighbor tree of \a ltreeid across \a face. T8_ECLASS_INVALID if no neighbor exists.687*/688t8_eclass_t689t8_cmesh_get_tree_face_neighbor_eclass (const t8_cmesh_t cmesh, const t8_locidx_t ltreeid, const int face);690691/** Print the collected statistics from a cmesh profile.692* \param [in] cmesh The cmesh.693*694* \a cmesh must be committed before calling this function.695* \see t8_cmesh_set_profiling696*/697void698t8_cmesh_print_profile (t8_cmesh_t cmesh);699700/** Return a pointer to the vertex coordinates of a tree.701* \param [in] cmesh The cmesh.702* \param [in] ltreeid The id of a local tree.703* \return If stored, a pointer to the vertex coordinates of \a tree.704* If no coordinates for this tree are found, NULL.705*/706double *707t8_cmesh_get_tree_vertices (t8_cmesh_t cmesh, t8_locidx_t ltreeid);708709/** Return the attribute pointer of a tree.710* \param [in] cmesh The cmesh.711* \param [in] package_id The identifier of a valid software package. \see sc_package_register712* \param [in] key A key used to identify the attribute under all713* attributes of this tree with the same \a package_id.714* \param [in] ltree_id The local number of the tree.715* \return The attribute pointer of the tree \a ltree_id or NULL if the attribute is not found.716* \note \a cmesh must be committed before calling this function.717* \see t8_cmesh_set_attribute718*/719void *720t8_cmesh_get_attribute (const t8_cmesh_t cmesh, const int package_id, const int key, const t8_locidx_t ltree_id);721722/** Return the attribute pointer of a tree for a gloidx_t array.723* \param [in] cmesh The cmesh.724* \param [in] package_id The identifier of a valid software package. \see sc_package_register725* \param [in] key A key used to identify the attribute under all726* attributes of this tree with the same \a package_id.727* \param [in] ltree_id The local number of the tree.728* \param [in] data_count The number of entries in the array that are requested.729* This must be smaller or equal to the \a data_count parameter730* of the corresponding call to \ref t8_cmesh_set_attribute_gloidx_array731* \return The attribute pointer of the tree \a ltree_id or NULL if the attribute is not found.732* \note \a cmesh must be committed before calling this function.733* \note No check is performed whether the attribute actually stored \a data_count many entries since734* we do not store the number of data entries of the attribute array.735* You can keep track of the data count yourself by using another attribute.736* \see t8_cmesh_set_attribute_gloidx_array737*/738t8_gloidx_t *739t8_cmesh_get_attribute_gloidx_array (const t8_cmesh_t cmesh, const int package_id, const int key,740const t8_locidx_t ltree_id, const size_t data_count);741742/** Return the shared memory array storing the partition table of743* a partitioned cmesh.744* \param [in] cmesh The cmesh.745* \return The partition array.746* NULL if the cmesh is not partitioned or747* the partition array is not stored in \a cmesh.748* \a cmesh must be committed before calling this function.749*/750t8_shmem_array_t751t8_cmesh_get_partition_table (t8_cmesh_t cmesh);752753/* TODO: remove get_ when there is no risk of confusion? Convention?754* Update: use get throughout for access functions that do not change the object.755* */756757/** Calculate the section of a uniform forest for the current rank.758* \param [in] cmesh The cmesh to be considered.759* \param [in] level The uniform refinement level to be created.760* \param [in] tree_scheme The element scheme for which to compute the bounds.761* \param [out] first_local_tree The first tree that contains elements belonging to the calling processor.762* \param [out] child_in_tree_begin The tree-local index of the first element belonging to the calling processor. Not computed if NULL.763* \param [out] last_local_tree The last tree that contains elements belonging to the calling processor.764* \param [out] child_in_tree_end The tree-local index of the first element that does not belonging to765* the calling processor anymore. Not computed if NULL.766* \param [out] first_tree_shared If not NULL, 1 or 0 is stored here depending on whether \a first_local_tree is the767* same as \a last_local_tree on the previous process.768* \a cmesh must be committed before calling this function.769*/770void771t8_cmesh_uniform_bounds_equal_element_count (t8_cmesh_t cmesh, const int level, const t8_scheme_c *tree_scheme,772t8_gloidx_t *first_local_tree, t8_gloidx_t *child_in_tree_begin,773t8_gloidx_t *last_local_tree, t8_gloidx_t *child_in_tree_end,774int8_t *first_tree_shared);775776/**777* Calculate the section of a uniform hybrid forest for the current rank. Needed for hybrid meshes, especially778* meshes where not all elements refine into 1:2^dim manner. The section is calculated without assuming such refinement779* and each process computes its number of elements on the given \a level, communicates the number to other processes,780* and the correct section is computed based on this information.781*782* \param [in] cmesh The cmesh to be considered.783* \param [in] level The uniform refinement level to be created.784* \param [in] scheme The element scheme for which to compute the bounds.785* \param [out] first_local_tree The global index of the first tree that contains elements belonging to the calling process.786* \param [out] child_in_tree_begin The global index of the first element belonging to the calling processor. Not computed if NULL.787* \param [out] last_local_tree The global index of the last tree that contains elements belonging to the calling process.788* \param [out] child_in_tree_end The global index of the first element that does not belonging to789* the calling process anymore. Not computed if NULL.790* \param [out] first_tree_shared If not NULL, 1 or 0 is stored here depending on whether \a first_local_tree is the791* same as \a last_local_tree on the previous process.792* \param [in] comm The communicator793*/794void795t8_cmesh_uniform_bounds_for_irregular_refinement (const t8_cmesh_t cmesh, const int level, const t8_scheme_c *scheme,796t8_gloidx_t *first_local_tree, t8_gloidx_t *child_in_tree_begin,797t8_gloidx_t *last_local_tree, t8_gloidx_t *child_in_tree_end,798int8_t *first_tree_shared, sc_MPI_Comm comm);799800/** Increase the reference counter of a cmesh.801* \param [in,out] cmesh On input, this cmesh must exist with positive802* reference count. It may be in any state.803*/804void805t8_cmesh_ref (t8_cmesh_t cmesh);806807/** Decrease the reference counter of a cmesh.808* If the counter reaches zero, this cmesh is destroyed.809* See also \ref t8_cmesh_destroy, which is to be preferred when it is810* known that the last reference to a cmesh is deleted.811* \param [in,out] pcmesh On input, the cmesh pointed to must exist812* with positive reference count. It may be in813* any state. If the reference count reaches814* zero, the cmesh is destroyed and this pointer815* set to NULL.816* Otherwise, the pointer is not changed and817* the cmesh is not modified in other ways.818*/819void820t8_cmesh_unref (t8_cmesh_t *pcmesh);821822/** Verify that a coarse mesh has only one reference left and destroy it.823* This function is preferred over \ref t8_cmesh_unref when it is known824* that the last reference is to be deleted.825* \param [in,out] pcmesh This cmesh must have a reference count of one.826* It can be in any state (committed or not).827* Then it effectively calls \ref t8_cmesh_unref.828*/829void830t8_cmesh_destroy (t8_cmesh_t *pcmesh);831832/** Compute y = ax + b on an array of doubles, interpreting833* each 3 as one vector x834* \param[in] coords_in The incoming coordinates of the vectors835* \param[out] coords_out The computed coordinates of the vectors836* \param[in] num_vertices The number of vertices/vectors837* \param[in] alpha Scaling factor for the vectors838* \param[in] b Translation of the vectors.*/839840void841t8_cmesh_coords_axb (const double *coords_in, double *coords_out, int num_vertices, double alpha, const double b[3]);842843/** Compute y = x + translate on an array of doubles, interpreting844* each 3 as one vector x845* \param[in] coords_in The incoming coordinates of the vectors846* \param[out] coords_out The computed coordinates of the vectors847* \param[in] num_vertices The number of vertices/vectors848* \param[in] translate Translation of the vectors.849*/850void851t8_cmesh_translate_coordinates (const double *coords_in, double *coords_out, const int num_vertices,852const double translate[3]);853854/**TODO: Add proper documentation*/855void856t8_cmesh_new_translate_vertices_to_attributes (const t8_locidx_t *tvertices, const double *vertices,857double *attr_vertices, const int num_vertices);858859/**860* \warning This function is only available in debug-modus and should only861* be used in debug-modus.862*863* Prints the vertices of each tree of each process864*865* \param[in] cmesh Source-cmesh, which trees get printed.866* \param[in] comm The MPI communicator to use for printing.867*/868void869t8_cmesh_debug_print_trees (const t8_cmesh_t cmesh, sc_MPI_Comm comm);870871/**872* Compute the process local bounding box of the cmesh.873* The bounding box is stored in the array \a bounds in the following order:874* bounds[0] = x_min875* bounds[1] = x_max876* bounds[2] = y_min877* bounds[3] = y_max878* bounds[4] = z_min879* bounds[5] = z_max880*881* \param [in] cmesh The cmesh to be considered.882* \param [out] bounds The bounding box of the cmesh. If the box is flat (for quads for example, z_min == z_max)883*884* \return True if the computation was successful, false if the cmesh is empty.885*/886int887t8_cmesh_get_local_bounding_box (const t8_cmesh_t cmesh, double bounds[6]);888T8_EXTERN_C_END ();889890#endif /* !T8_CMESH_H */891892893