Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
DLR-AMR
GitHub Repository: DLR-AMR/t8code
Path: blob/main/src/t8_cmesh/t8_cmesh.h
901 views
1
/*
2
This file is part of t8code.
3
t8code is a C library to manage a collection (a forest) of multiple
4
connected adaptive space-trees of general element classes in parallel.
5
6
Copyright (C) 2015 the developers
7
8
t8code is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
12
13
t8code is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
17
18
You should have received a copy of the GNU General Public License
19
along with t8code; if not, write to the Free Software Foundation, Inc.,
20
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
*/
22
23
/** \file t8_cmesh.h
24
* We define the coarse mesh of trees in this file.
25
*/
26
27
#ifndef T8_CMESH_H
28
#define T8_CMESH_H
29
30
#include <t8.h>
31
#include <t8_data/t8_shmem.h>
32
#include <t8_cmesh/t8_cmesh_io/t8_cmesh_save.h>
33
#include <t8_element.h>
34
#include <t8_schemes/t8_scheme.h>
35
36
/** Forward pointer reference to hidden cmesh implementation.
37
* This reference needs to be known by t8_geometry, hence we
38
* put it before the include. */
39
typedef struct t8_cmesh *t8_cmesh_t;
40
41
#include <t8_geometry/t8_geometry.h>
42
43
/* TODO: If including eclass were just for the cmesh_new routines, we should
44
* move them into a different file.
45
* However, when specifying the parent-child order in cmesh_reorder,
46
* we might keep the eclass interface for virtual functions.
47
* Actually, we need eclass in the type definition in cmesh.c.
48
* So we might as well use tree-related virtual functions there too.
49
*/
50
#include <t8_eclass.h>
51
52
/* TODO: make it legal to call cmesh_set functions multiple times,
53
* just overwrite the previous setting if no inconsistency can occur.
54
* edit: This should be achieved now.
55
*/
56
57
/** Forward pointer references to hidden implementations of
58
* tree. */
59
typedef struct t8_ctree *t8_ctree_t;
60
/** Forward pointer references to hidden implementations of
61
* ghost tree. */
62
typedef struct t8_cghost *t8_cghost_t;
63
64
T8_EXTERN_C_BEGIN ();
65
66
/** Create a new cmesh with reference count one.
67
* This cmesh needs to be specialized with the t8_cmesh_set_* calls.
68
* Then it needs to be set up with \ref t8_cmesh_commit.
69
* \param [in,out] pcmesh On input, this pointer must be non-NULL.
70
* On return, this pointer set to the new cmesh.
71
*/
72
void
73
t8_cmesh_init (t8_cmesh_t *pcmesh);
74
75
/** Allocate a new un-committed cmesh.
76
* \return A pointer to an un-committed t8_cmesh structure.
77
*/
78
t8_cmesh_t
79
t8_cmesh_new ();
80
81
/** Check whether a cmesh is not NULL, initialized and not committed.
82
* In addition, it asserts that the cmesh is consistent as much as possible.
83
* \param [in] cmesh This cmesh is examined. May be NULL.
84
* \return True if cmesh is not NULL,
85
* \ref t8_cmesh_init has been called on it,
86
* but not \ref t8_cmesh_commit.
87
* False otherwise.
88
*/
89
int
90
t8_cmesh_is_initialized (t8_cmesh_t cmesh);
91
92
/** Check whether a cmesh is not NULL, initialized and committed.
93
* In addition, it asserts that the cmesh is consistent as much as possible.
94
* \param [in] cmesh This cmesh is examined. May be NULL.
95
* \return True if cmesh is not NULL and
96
* \ref t8_cmesh_init has been called on it
97
* as well as \ref t8_cmesh_commit.
98
* False otherwise.
99
*/
100
int
101
t8_cmesh_is_committed (const t8_cmesh_t cmesh);
102
103
/** Disable the debug check for negative volumes in trees during \ref t8_cmesh_commit.
104
* Does nothing outside of debug mode.
105
* \param [in, out] cmesh
106
*/
107
void
108
t8_cmesh_disable_negative_volume_check (t8_cmesh_t cmesh);
109
110
#if T8_ENABLE_DEBUG
111
/** Check the geometry of the mesh for validity, this means checking if trees and their geometries
112
* are compatible and if they have negative volume.
113
* \param [in] cmesh This cmesh is examined.
114
* \param [in] check_for_negative_volume Enable the negative volume check.
115
* \return True if the geometry of the cmesh is valid.
116
*/
117
int
118
119
t8_cmesh_validate_geometry (const t8_cmesh_t cmesh, const int check_for_negative_volume);
120
#endif
121
122
/* TODO: Currently it is not possible to destroy set_from before
123
* cmesh is destroyed. */
124
/** This function sets a cmesh to be derived from.
125
* The default is to create a cmesh standalone by specifying all data manually.
126
* A coarse mesh can also be constructed by deriving it from an existing one.
127
* The derivation from another cmesh may optionally be combined with a
128
* repartition or uniform refinement of each tree.
129
* This function overrides a previously set cmesh to be derived from.
130
* \param [in,out] cmesh Must be initialized, but not committed.
131
* May even be NULL to revert to standalone.
132
* \param [in,out] set_from Reference counter on this cmesh is bumped.
133
* It will be unbumped by \ref t8_cmesh_commit,
134
* after which \a from is no longer remembered.
135
* Other than that the from object is not changed.
136
*/
137
void
138
t8_cmesh_set_derive (t8_cmesh_t cmesh, t8_cmesh_t set_from);
139
140
/** Allocate a shared memory array to store the tree offsets of a cmesh.
141
* \param [in] mpisize The number of processes.
142
* \param [in] comm The MPI communicator to use. Its mpisize must match \a mpisize.
143
* The shared memory type must have been set. Best practice would be
144
* calling sc_shmem_set_type (comm, T8_SHMEM_BEST_TYPE).
145
* \return A t8_shmem_array struct that stores \a mpisize + 1 t8_gloidx_t entries.
146
* \see t8_shmem.h
147
*/
148
t8_shmem_array_t
149
t8_cmesh_alloc_offsets (int mpisize, sc_MPI_Comm comm);
150
151
/** Declare if the cmesh is understood as a partitioned cmesh and specify
152
* the processor local tree range.
153
* This function should be preferred over \ref t8_cmesh_set_partition_offsets
154
* when the cmesh is not derived from another cmesh.
155
* This call is only valid when the cmesh is not yet committed via a call
156
* to \ref t8_cmesh_commit.
157
* \param [in,out] cmesh The cmesh to be updated.
158
* \param [in] set_face_knowledge Several values are possible that define
159
* how much information is required on face connections,
160
* specified by \ref t8_cmesh_set_join.
161
* 0: Expect face connection of local trees.
162
* 1: In addition, expect face connection from
163
* ghost trees to local trees.
164
* 2: In addition, expect face connection between
165
* ghost trees.
166
* 3: Expect face connection of local and ghost trees.
167
* Consistency of this requirement is checked on
168
* \ref t8_cmesh_commit.
169
* -1: Do not change the face_knowledge level but keep any
170
* previously set ones. (Possibly by a previous call to \ref t8_cmesh_set_partition_range)
171
* \param [in] first_local_tree The global index ID of the first tree on this process.
172
* If this tree is also the last tree on the previous process,
173
* then the argument must be -ID - 1.
174
* \param [in] last_local_tree The global index of the last tree on this process.
175
* If this process should be empty then \a last_local_tree
176
* must be strictly smaller than \a first_local_tree.
177
*
178
* \see t8_cmesh_set_partition_offset \see t8_cmesh_set_partition_uniform
179
* \note A value of \a set_face_knowledge other than -1 or 3 is not yet supported.
180
*/
181
void
182
t8_cmesh_set_partition_range (t8_cmesh_t cmesh, int set_face_knowledge, t8_gloidx_t first_local_tree,
183
t8_gloidx_t last_local_tree);
184
185
/** Declare if the cmesh is understood as a partitioned cmesh and specify
186
* the first local tree for each process.
187
* This call is only valid when the cmesh is not yet committed via a call
188
* to \ref t8_cmesh_commit.
189
* If instead \ref t8_cmesh_set_partition_range was called and the cmesh is
190
* derived then the offset array is constructed during commit.
191
* \param [in,out] cmesh The cmesh to be updated.
192
* \param [in] tree_offsets An array of global tree_id offsets
193
* for each process can be specified here.
194
* TODO: document flag for shared trees.
195
*/
196
void
197
t8_cmesh_set_partition_offsets (t8_cmesh_t cmesh, t8_shmem_array_t tree_offsets);
198
199
/** Declare if a derived cmesh should be partitioned according to a
200
* uniform refinement of a given level for the provided scheme.
201
* This call is only valid when the cmesh is not yet committed via a call
202
* to \ref t8_cmesh_commit and when the cmesh will be derived.
203
* \param [in,out] cmesh The cmesh to be updated.
204
* \param [in] element_level The refinement_level.
205
* \param [in] scheme The element scheme describing the refinement pattern.
206
* We take ownership. This can be prevented by
207
* referencing \b scheme before calling this function.
208
*/
209
void
210
t8_cmesh_set_partition_uniform (t8_cmesh_t cmesh, const int element_level, const t8_scheme_c *scheme);
211
212
/** Refine the cmesh to a given level.
213
* Thus split each tree into x^level subtrees
214
* TODO: implement */
215
/* If level = 0 then no refinement is performed */
216
void
217
t8_cmesh_set_refine (t8_cmesh_t cmesh, const int level, const t8_scheme_c *scheme);
218
219
/** Set the dimension of a cmesh. If any tree is inserted to the cmesh
220
* via \a t8_cmesh_set_tree_class, then the dimension is set automatically
221
* to that of the inserted tree.
222
* However, if the cmesh is constructed partitioned and the part on this process
223
* is empty, it is necessary to set the dimension by hand.
224
* \param [in,out] cmesh The cmesh to be updated.
225
* \param [in] dim The dimension to be set. Must satisfy 0 <= dim <= 3.
226
* The cmesh must not be committed before calling this function.
227
*/
228
void
229
t8_cmesh_set_dimension (t8_cmesh_t cmesh, int dim);
230
231
/** Set the class of a tree in the cmesh.
232
* It is not allowed to call this function after \ref t8_cmesh_commit.
233
* It is not allowed to call this function multiple times for the same tree.
234
* \param [in,out] cmesh The cmesh to be updated.
235
* \param [in] gtree_id The global number of the tree.
236
* \param [in] tree_class The element class of this tree.
237
*/
238
void
239
t8_cmesh_set_tree_class (t8_cmesh_t cmesh, t8_gloidx_t gtree_id, t8_eclass_t tree_class);
240
241
/** Store an attribute at a tree in a cmesh.
242
* Attributes can be arbitrary data that is copied to an internal storage
243
* associated to the tree.
244
* Each application can set multiple attributes and attributes are distinguished
245
* by an integer key, where each application can use any integer as key.
246
*
247
* \param [in, out] cmesh The cmesh to be updated.
248
* \param [in] gtree_id The global id of the tree.
249
* \param [in] package_id Unique identifier of a valid software package. \see sc_package_register
250
* \param [in] key An integer key used to identify this attribute under all
251
* attributes with the same package_id.
252
* \a key must be a unique value for this tree and package_id.
253
* \param [in] data A pointer to the attribute data.
254
* \param [in] data_size The number of bytes of the attribute.
255
* \param [in] data_persists This flag can be used to optimize memory. If true
256
* then t8code assumes that the attribute data is present at the
257
* memory that \a data points to when \ref t8_cmesh_commit is called
258
* (This is more memory efficient).
259
* If the flag is false an internal copy of the data is created
260
* immediately and this copy is used at commit.
261
* In both cases a copy of the data is used by t8_code after t8_cmesh_commit.
262
* \note If an attribute with the given package_id and key already exists, then it will get overwritten.
263
*/
264
void
265
t8_cmesh_set_attribute (t8_cmesh_t cmesh, t8_gloidx_t gtree_id, int package_id, int key, void *data, size_t data_size,
266
int data_persists);
267
268
/** Store a string as an attribute at a tree in a cmesh.
269
* \param [in, out] cmesh The cmesh to be updated.
270
* \param [in] gtree_id The global id of the tree.
271
* \param [in] package_id Unique identifier of a valid software package. \see sc_package_register
272
* \param [in] key An integer key used to identify this attribute under all
273
* attributes with the same package_id.
274
* \a key must be a unique value for this tree and package_id.
275
* \param [in] string The string to store as attribute.
276
* \note You can also use \ref t8_cmesh_set_attribute, but we recommend using this
277
* specialized function for strings.
278
* \note If an attribute with the given package_id and key already exists, then it will get overwritten.
279
*/
280
void
281
t8_cmesh_set_attribute_string (t8_cmesh_t cmesh, t8_gloidx_t gtree_id, int package_id, int key, const char *string);
282
283
/** Store an array of t8_gloidx_t as an attribute at a tree in a cmesh.
284
* \param [in, out] cmesh The cmesh to be updated.
285
* \param [in] gtree_id The global id of the tree.
286
* \param [in] package_id Unique identifier of a valid software package. \see sc_package_register
287
* \param [in] key An integer key used to identify this attribute under all
288
* attributes with the same package_id.
289
* \a key must be a unique value for this tree and package_id.
290
* \param [in] data The array to store as attribute.
291
* \param [in] data_count The number of entries in \a data.
292
* \param [in] data_persists This flag can be used to optimize memory. If true
293
* then t8code assumes that the attribute data is present at the
294
* memory that \a data points to when \ref t8_cmesh_commit is called
295
* (This is more memory efficient).
296
* If the flag is false an internal copy of the data is created
297
* immediately and this copy is used at commit.
298
* In both cases a copy of the data is used by t8_code after t8_cmesh_commit.
299
* \note You can also use \ref t8_cmesh_set_attribute, but we recommend using this
300
* specialized function for arrays.
301
* \note If an attribute with the given package_id and key already exists, then it will get overwritten.
302
* \note We do not store the number of data entries \a data_count of the attribute array.
303
* You can keep track of the data count yourself by using another attribute.
304
*/
305
void
306
t8_cmesh_set_attribute_gloidx_array (t8_cmesh_t cmesh, t8_gloidx_t gtree_id, int package_id, int key,
307
const t8_gloidx_t *data, const size_t data_count, int data_persists);
308
309
/** Insert a face-connection between two trees in a cmesh.
310
* \param [in,out] cmesh The cmesh to be updated.
311
* \param [in] gtree1 The tree id of the first of the two trees.
312
* \param [in] gtree2 The tree id of the second of the two trees.
313
* \param [in] face1 The face number of the first tree.
314
* \param [in] face2 The face number of the second tree.
315
* \param [in] orientation Specify how face1 and face2 are oriented to each other
316
*
317
* \note The orientation is defined as:
318
* Let my_face and other_face be the two face numbers of the connecting trees.
319
* We chose a main_face from them as follows: Either both trees have the same
320
* element class, then the face with the lower face number is the main_face or
321
* the trees belong to different classes in which case the face belonging to the
322
* tree with the lower class according to the ordering
323
* triangle < quad, hex < tet < prism < pyramid, is the main_face.
324
* Then face corner 0 of the main_face connects to a face
325
* corner k in the other face. The face orientation is defined as the number k.
326
* If the classes are equal and my_face == other_face, treating
327
* either of both faces as the main_face leads to the same result.
328
* See https://arxiv.org/pdf/1611.02929.pdf for more details.
329
*/
330
void
331
t8_cmesh_set_join (t8_cmesh_t cmesh, t8_gloidx_t gtree1, t8_gloidx_t gtree2, int face1, int face2, int orientation);
332
333
/** Enable or disable profiling for a cmesh. If profiling is enabled, runtimes
334
* and statistics are collected during cmesh_commit.
335
* \param [in,out] cmesh The cmesh to be updated.
336
* \param [in] set_profiling If true, profiling will be enabled, if false
337
* disabled.
338
*
339
* Profiling is disabled by default.
340
* The cmesh must not be committed before calling this function.
341
* \see t8_cmesh_print_profile
342
*/
343
void
344
t8_cmesh_set_profiling (t8_cmesh_t cmesh, int set_profiling);
345
346
/* returns true if cmesh_a equals cmesh_b */
347
/* TODO: document
348
* collective or serial */
349
/** Check whether two given cmeshes carry the same information.
350
* \param [in] cmesh_a The first of the two cmeshes to be checked.
351
* \param [in] cmesh_b The second of the two cmeshes to be checked.
352
* \return True if both cmeshes carry the same information,
353
* false otherwise.
354
* TODO: define carefully.
355
* Orders, sequences, equivalences?
356
* This function works on committed and uncommitted cmeshes.
357
*/
358
int
359
t8_cmesh_is_equal (t8_cmesh_t cmesh_a, t8_cmesh_t cmesh_b);
360
361
/** Check whether a cmesh is empty on all processes.
362
* \param [in] cmesh A committed cmesh.
363
* \return True (non-zero) if and only if the cmesh has trees at all.
364
*/
365
int
366
t8_cmesh_is_empty (t8_cmesh_t cmesh);
367
368
/** Broadcast a cmesh structure that exists only on one process to all
369
* processes in the cmesh's communicator.
370
* TODO: Input structure must be replicated, not parallelized.
371
* TODO: Recommend to call this just before commit. Earlier is thinkable too.
372
* On the other processors, it will be allocated.
373
* It is not allowed to call this function after \ref t8_cmesh_commit.
374
* \param [in] cmesh_in For the root process the cmesh to be broadcast,
375
* for the other processes it must be NULL.
376
* \param [in] root The rank of the process that provides the cmesh.
377
* \param [in] comm The mpi communicator. Must match cmesh's communicator
378
* on the root process.
379
* \return For the root process this is a pointer to \a cmesh_in.
380
* Else, a pointer to a newly allocated cmesh
381
* structure with the same values as \a conn_in on the
382
* root process.
383
* \note It is illegal to broadcast a cmesh with a registered geometry (\ref t8_cmesh_register_geometry).
384
* All geometries must be registered after the broadcast (You can set tree attributes before bcast, though).
385
*/
386
t8_cmesh_t
387
t8_cmesh_bcast (t8_cmesh_t cmesh_in, int root, sc_MPI_Comm comm);
388
389
#if T8_ENABLE_METIS
390
/* TODO: document this. */
391
/* TODO: think about making this a pre-commit set_reorder function. */
392
void
393
t8_cmesh_reorder (t8_cmesh_t cmesh, sc_MPI_Comm comm);
394
395
/* TODO: think about a sensible interface for a parmetis reordering. */
396
#endif
397
398
/** Register a geometry in the cmesh. The cmesh takes ownership of the geometry.
399
* \param [in,out] cmesh The cmesh.
400
* \param [in] geometry The geometry to register.
401
*
402
* If no geometry is registered and cmesh is modified from another cmesh then
403
* the other cmesh's geometries are used.
404
* \note If you need to use \ref t8_cmesh_bcast, then all geometries must be
405
* registered \a after the bcast operation, not before.
406
*/
407
void
408
t8_cmesh_register_geometry (t8_cmesh_t cmesh, t8_geometry_c *geometry);
409
410
/** Set the geometry for a tree, thus specify which geometry to use for this tree.
411
* \param [in] cmesh A non-committed cmesh.
412
* \param [in] gtreeid A global tree id in \a cmesh.
413
* \param [in] geom The geometry to use for this tree.
414
* See also \ref t8_cmesh_get_tree_geometry
415
*/
416
void
417
t8_cmesh_set_tree_geometry (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const t8_geometry_c *geom);
418
419
/** After allocating and adding properties to a cmesh, finish its construction.
420
* TODO: this function is MPI collective.
421
* \param [in,out] cmesh Must be created with \ref t8_cmesh_init
422
* (TODO: or bcast) and
423
* specialized with t8_cmesh_set_* calls first (?).
424
* \param [in] comm The MPI communicator to use.
425
*/
426
void
427
t8_cmesh_commit (t8_cmesh_t cmesh, sc_MPI_Comm comm);
428
429
/**
430
* Save the cmesh to a file with the given fileprefix.
431
*
432
* \param[in] cmesh The cmesh to save.
433
* \param[in] fileprefix The prefix of the file to save the cmesh to.
434
*
435
* \note Currently, it is only legal to save cmeshes that use the linear geometry.
436
*/
437
int
438
t8_cmesh_save (t8_cmesh_t cmesh, const char *fileprefix);
439
440
/**
441
* Load a cmesh from a file.
442
*
443
* \param[in] filename The name of the file to load the cmesh from.
444
* \param[in] comm The MPI communicator to use.
445
*/
446
t8_cmesh_t
447
t8_cmesh_load (const char *filename, sc_MPI_Comm comm);
448
449
/**
450
* Load a cmesh from multiple files and distribute it across the processes.
451
*
452
* \param[in] fileprefix The prefix of the files to load the cmesh from.
453
* \param[in] num_files The number of files to load.
454
* \param[in] comm The MPI communicator to use.
455
* \param[in] mode The load mode to use, see \ref t8_load_mode_t.
456
* \param[in] procs_per_node The number of processes per node, only relevant in JUQUEEN mode.
457
*
458
* \note \a procs_per_node is only relevant in mode==JUQUEEN. If \a num_files = 1 a replicated cmesh is constructed.
459
*/
460
t8_cmesh_t
461
t8_cmesh_load_and_distribute (const char *fileprefix, int num_files, sc_MPI_Comm comm, t8_load_mode_t mode,
462
int procs_per_node);
463
464
/** Check whether a given MPI communicator assigns the same rank and mpisize
465
* as stored in a cmesh.
466
* \param [in] cmesh The cmesh to be considered.
467
* \param [in] comm A MPI communicator.
468
* \return True if mpirank and mpisize from \a comm are the same as
469
* the values stored in \a cmesh.
470
* False otherwise.
471
* \a cmesh must be committed before calling this function.
472
* */
473
int
474
t8_cmesh_comm_is_valid (t8_cmesh_t cmesh, sc_MPI_Comm comm);
475
476
/** Query whether a committed cmesh is partitioned or replicated.
477
* \param [in] cmesh A committed cmesh.
478
* \return True if \a cmesh is partitioned.
479
* False otherwise.
480
* \a cmesh must be committed before calling this function.
481
*/
482
int
483
t8_cmesh_is_partitioned (t8_cmesh_t cmesh);
484
485
/** Get the dimension of a cmesh.
486
* \param [in] cmesh The cmesh.
487
* \a cmesh must be committed before calling this function.
488
*/
489
int
490
t8_cmesh_get_dimension (const t8_cmesh_t cmesh);
491
492
/** Return the global number of trees in a cmesh.
493
* \param [in] cmesh The cmesh to be considered.
494
* \return The number of trees associated to \a cmesh.
495
* \a cmesh must be committed before calling this function.
496
*/
497
t8_gloidx_t
498
t8_cmesh_get_num_trees (t8_cmesh_t cmesh);
499
500
/** Return the number of local trees of a cmesh.
501
* If the cmesh is not partitioned this is equivalent to \ref t8_cmesh_get_num_trees.
502
* \param [in] cmesh The cmesh to be considered.
503
* \return The number of local trees of the cmesh.
504
* \a cmesh must be committed before calling this function.
505
*/
506
t8_locidx_t
507
t8_cmesh_get_num_local_trees (t8_cmesh_t cmesh);
508
509
/** Return the number of ghost trees of a cmesh.
510
* If the cmesh is not partitioned this is equivalent to \ref t8_cmesh_get_num_trees.
511
* \param [in] cmesh The cmesh to be considered.
512
* \return The number of ghost trees of the cmesh.
513
* \a cmesh must be committed before calling this function.
514
*/
515
t8_locidx_t
516
t8_cmesh_get_num_ghosts (t8_cmesh_t cmesh);
517
518
/** Return the global index of the first local tree of a cmesh.
519
* If the cmesh is not partitioned this is always 0.
520
* \param [in] cmesh The cmesh to be considered.
521
* \return The global id of the first local tree in cmesh.
522
* \a cmesh must be committed before calling this function.
523
*/
524
t8_gloidx_t
525
t8_cmesh_get_first_treeid (t8_cmesh_t cmesh);
526
527
/** Get the geometry of a tree.
528
* \param [in] cmesh The cmesh.
529
* \param [in] gtreeid The global tree id of the tree for which the geometry should be returned.
530
* \return The geometry of the tree.
531
*/
532
const t8_geometry_c *
533
t8_cmesh_get_tree_geometry (t8_cmesh_t cmesh, t8_gloidx_t gtreeid);
534
535
/** Query whether a given t8_locidx_t belongs to a local tree of a cmesh.
536
* \param [in] cmesh The cmesh to be considered.
537
* \param [in] ltreeid An (possible) tree index.
538
* \return True if \a ltreeid matches the range of local trees of \a cmesh.
539
* False if not.
540
* \a cmesh must be committed before calling this function.
541
*/
542
int
543
t8_cmesh_treeid_is_local_tree (const t8_cmesh_t cmesh, const t8_locidx_t ltreeid);
544
545
/** Query whether a given t8_locidx_t belongs to a ghost of a cmesh.
546
* \param [in] cmesh The cmesh to be considered.
547
* \param [in] ltreeid An (possible) ghost index.
548
* \return True if \a ltreeid matches the range of ghost trees of \a cmesh.
549
* False if not.
550
* \a cmesh must be committed before calling this function.
551
*/
552
int
553
t8_cmesh_treeid_is_ghost (const t8_cmesh_t cmesh, const t8_locidx_t ltreeid);
554
555
/** Given a local tree id that belongs to a ghost, return the index of the ghost.
556
* \param [in] cmesh The cmesh to be considered.
557
* \param [in] ltreeid The local id of a ghost, satisfying \ref t8_cmesh_treeid_is_ghost,
558
* thus num_trees <= \a ltreeid < num_trees + num_ghosts
559
* \return The index of the ghost within all ghosts, thus an index
560
* 0 <= index < num_ghosts
561
* \a cmesh must be committed before calling this function.
562
*/
563
t8_locidx_t
564
t8_cmesh_ltreeid_to_ghostid (const t8_cmesh_t cmesh, const t8_locidx_t ltreeid);
565
566
/* TODO: Replace this iterator with a new one that does not need the
567
* treeid to be part of the ctree struct */
568
/* TODO: should this and the next function be part of the interface? */
569
/** Return a pointer to the first local tree in a cmesh.
570
* \param [in] cmesh The cmesh to be queried.
571
* \return A pointer to the first local tree in \a cmesh.
572
* If \a cmesh has no local trees, NULL is returned.
573
* \a cmesh must be committed before calling this function.
574
*/
575
t8_ctree_t
576
t8_cmesh_get_first_tree (t8_cmesh_t cmesh);
577
578
/* TODO: should this function behave like first_tree if tree argument is NULL? */
579
/** Given a local tree in a cmesh return a pointer to the next local tree.
580
* \param [in] cmesh The cmesh to be queried.
581
* \param [in] tree A local tree in \a cmesh.
582
* \return A pointer to the next local tree in \a cmesh
583
* after \a tree. If no such tree exists, NULL is
584
* returned.
585
* * \a cmesh must be committed before calling this function.
586
* TODO: If we run over tree numbers only, don't use ctree_t in API if possible.
587
*/
588
t8_ctree_t
589
t8_cmesh_get_next_tree (t8_cmesh_t cmesh, t8_ctree_t tree);
590
591
/** Return a pointer to a given local tree.
592
* \param [in] cmesh The cmesh to be queried.
593
* \param [in] ltree_id The local id of the tree that is asked for.
594
* \return A pointer to tree in \a cmesh with local
595
* id \a ltree_id.
596
* The cmesh must have at least \a ltree_id + 1 local trees when
597
* calling this function.
598
* \a cmesh must be committed before calling this function.
599
*/
600
t8_ctree_t
601
t8_cmesh_get_tree (t8_cmesh_t cmesh, t8_locidx_t ltree_id);
602
603
/** Return the eclass of a given local tree.
604
* TODO: Should we refer to indices or consequently use ctree_t?
605
* \param [in] cmesh The cmesh to be considered.
606
* \param [in] ltree_id The local id of the tree whose eclass will be returned.
607
* \return The eclass of the given tree.
608
* TODO: Call tree ids ltree_id or gtree_id etc. instead of tree_id.
609
* \a cmesh must be committed before calling this function.
610
*/
611
t8_eclass_t
612
t8_cmesh_get_tree_class (t8_cmesh_t cmesh, t8_locidx_t ltree_id);
613
614
/** Query whether a face of a local tree or ghost is at the domain boundary.
615
* \param [in] cmesh The cmesh to be considered.
616
* \param [in] ltree_id The local id of a tree.
617
* \param [in] face The number of a face of the tree.
618
* \return True if the face is at the domain boundary.
619
* False otherwise.
620
* \a cmesh must be committed before calling this function.
621
*/
622
int
623
t8_cmesh_tree_face_is_boundary (t8_cmesh_t cmesh, t8_locidx_t ltree_id, int face);
624
625
/** Return the eclass of a given local ghost.
626
* TODO: Should we refer to indices or consequently use cghost_t?
627
* \param [in] cmesh The cmesh to be considered.
628
* \param [in] lghost_id The local id of the ghost whose eclass will be returned.
629
* 0 <= \a tree_id < cmesh.num_ghosts.
630
* \return The eclass of the given ghost.
631
* \a cmesh must be committed before calling this function.
632
*/
633
t8_eclass_t
634
t8_cmesh_get_ghost_class (t8_cmesh_t cmesh, t8_locidx_t lghost_id);
635
636
/** Return the global id of a given local tree or ghost.
637
* \param [in] cmesh The cmesh to be considered.
638
* \param [in] local_id The local id of a tree or a ghost.
639
* If \a local_id < cmesh.num_local_trees then it is
640
* a tree, otherwise a ghost.
641
* \return The global id of the tree/ghost.
642
* \see https://github.com/DLR-AMR/t8code/wiki/Tree-indexing for more details about tree indexing.
643
*/
644
t8_gloidx_t
645
t8_cmesh_get_global_id (t8_cmesh_t cmesh, t8_locidx_t local_id);
646
647
/** Return the local id of a give global tree.
648
* \param [in] cmesh The cmesh.
649
* \param [in] global_id A global tree id.
650
* \return Either a value l 0 <= \a l < num_local_trees
651
* if \a global_id corresponds to a local tree,
652
* or num_local_trees <= \a l < num_local_trees
653
* + num_ghosts
654
* if \a global_id corresponds to a ghost trees,
655
* or negative if \a global_id neither matches a local
656
* nor a ghost tree.
657
* \see https://github.com/DLR-AMR/t8code/wiki/Tree-indexing for more details about tree indexing.
658
*/
659
t8_locidx_t
660
t8_cmesh_get_local_id (t8_cmesh_t cmesh, t8_gloidx_t global_id);
661
662
/** Given a local tree id and a face number, get information about the face neighbor tree.
663
* \param [in] cmesh The cmesh to be considered.
664
* \param [in] ltreeid The local id of a tree or a ghost.
665
* \param [in] face A face number of the tree/ghost.
666
* \param [out] dual_face If not NULL, the face number of the neighbor tree at this connection.
667
* \param [out] orientation If not NULL, the face orientation of the connection.
668
* \return If non-negative: The local id of the neighbor tree or ghost.
669
* If negative: There is no neighbor across this face. \a dual_face and
670
* \a orientation remain unchanged.
671
* \note If \a ltreeid is a ghost and it has a neighbor which is neither a local tree or ghost,
672
* then the return value will be negative.
673
* Thus, a negative return value does not necessarily mean that this is a domain boundary.
674
* To find out whether a tree is a domain boundary or not \see t8_cmesh_tree_face_is_boundary.
675
*/
676
t8_locidx_t
677
t8_cmesh_get_face_neighbor (const t8_cmesh_t cmesh, const t8_locidx_t ltreeid, const int face, int *dual_face,
678
int *orientation);
679
680
/**
681
* Given a local tree id (of a local tree or ghost tree) and a face compute the eclass of the
682
* tree's face neighbor.
683
*
684
* \param [in] cmesh The cmesh to be considered.
685
* \param [in] ltreeid The local id of a tree or a ghost.
686
* \param [in] face A face number of the tree/ghost.
687
* \return The eclass of a neighbor tree of \a ltreeid across \a face. T8_ECLASS_INVALID if no neighbor exists.
688
*/
689
t8_eclass_t
690
t8_cmesh_get_tree_face_neighbor_eclass (const t8_cmesh_t cmesh, const t8_locidx_t ltreeid, const int face);
691
692
/** Print the collected statistics from a cmesh profile.
693
* \param [in] cmesh The cmesh.
694
*
695
* \a cmesh must be committed before calling this function.
696
* \see t8_cmesh_set_profiling
697
*/
698
void
699
t8_cmesh_print_profile (t8_cmesh_t cmesh);
700
701
/** Return a pointer to the vertex coordinates of a tree.
702
* \param [in] cmesh The cmesh.
703
* \param [in] ltreeid The id of a local tree.
704
* \return If stored, a pointer to the vertex coordinates of \a tree.
705
* If no coordinates for this tree are found, NULL.
706
*/
707
double *
708
t8_cmesh_get_tree_vertices (t8_cmesh_t cmesh, t8_locidx_t ltreeid);
709
710
/** Return the attribute pointer of a tree.
711
* \param [in] cmesh The cmesh.
712
* \param [in] package_id The identifier of a valid software package. \see sc_package_register
713
* \param [in] key A key used to identify the attribute under all
714
* attributes of this tree with the same \a package_id.
715
* \param [in] ltree_id The local number of the tree.
716
* \return The attribute pointer of the tree \a ltree_id or NULL if the attribute is not found.
717
* \note \a cmesh must be committed before calling this function.
718
* \see t8_cmesh_set_attribute
719
*/
720
void *
721
t8_cmesh_get_attribute (const t8_cmesh_t cmesh, const int package_id, const int key, const t8_locidx_t ltree_id);
722
723
/** Return the attribute pointer of a tree for a gloidx_t array.
724
* \param [in] cmesh The cmesh.
725
* \param [in] package_id The identifier of a valid software package. \see sc_package_register
726
* \param [in] key A key used to identify the attribute under all
727
* attributes of this tree with the same \a package_id.
728
* \param [in] ltree_id The local number of the tree.
729
* \param [in] data_count The number of entries in the array that are requested.
730
* This must be smaller or equal to the \a data_count parameter
731
* of the corresponding call to \ref t8_cmesh_set_attribute_gloidx_array
732
* \return The attribute pointer of the tree \a ltree_id or NULL if the attribute is not found.
733
* \note \a cmesh must be committed before calling this function.
734
* \note No check is performed whether the attribute actually stored \a data_count many entries since
735
* we do not store the number of data entries of the attribute array.
736
* You can keep track of the data count yourself by using another attribute.
737
* \see t8_cmesh_set_attribute_gloidx_array
738
*/
739
t8_gloidx_t *
740
t8_cmesh_get_attribute_gloidx_array (const t8_cmesh_t cmesh, const int package_id, const int key,
741
const t8_locidx_t ltree_id, const size_t data_count);
742
743
/** Return the shared memory array storing the partition table of
744
* a partitioned cmesh.
745
* \param [in] cmesh The cmesh.
746
* \return The partition array.
747
* NULL if the cmesh is not partitioned or
748
* the partition array is not stored in \a cmesh.
749
* \a cmesh must be committed before calling this function.
750
*/
751
t8_shmem_array_t
752
t8_cmesh_get_partition_table (t8_cmesh_t cmesh);
753
754
/* TODO: remove get_ when there is no risk of confusion? Convention?
755
* Update: use get throughout for access functions that do not change the object.
756
* */
757
758
/** Calculate the section of a uniform forest for the current rank.
759
* \param [in] cmesh The cmesh to be considered.
760
* \param [in] level The uniform refinement level to be created.
761
* \param [in] tree_scheme The element scheme for which to compute the bounds.
762
* \param [out] first_local_tree The first tree that contains elements belonging to the calling processor.
763
* \param [out] child_in_tree_begin The tree-local index of the first element belonging to the calling processor. Not computed if NULL.
764
* \param [out] last_local_tree The last tree that contains elements belonging to the calling processor.
765
* \param [out] child_in_tree_end The tree-local index of the first element that does not belonging to
766
* the calling processor anymore. Not computed if NULL.
767
* \param [out] first_tree_shared If not NULL, 1 or 0 is stored here depending on whether \a first_local_tree is the
768
* same as \a last_local_tree on the previous process.
769
* \a cmesh must be committed before calling this function.
770
*/
771
void
772
t8_cmesh_uniform_bounds_equal_element_count (t8_cmesh_t cmesh, const int level, const t8_scheme_c *tree_scheme,
773
t8_gloidx_t *first_local_tree, t8_gloidx_t *child_in_tree_begin,
774
t8_gloidx_t *last_local_tree, t8_gloidx_t *child_in_tree_end,
775
int8_t *first_tree_shared);
776
777
/**
778
* Calculate the section of a uniform hybrid forest for the current rank. Needed for hybrid meshes, especially
779
* meshes where not all elements refine into 1:2^dim manner. The section is calculated without assuming such refinement
780
* and each process computes its number of elements on the given \a level, communicates the number to other processes,
781
* and the correct section is computed based on this information.
782
*
783
* \param [in] cmesh The cmesh to be considered.
784
* \param [in] level The uniform refinement level to be created.
785
* \param [in] scheme The element scheme for which to compute the bounds.
786
* \param [out] first_local_tree The global index of the first tree that contains elements belonging to the calling process.
787
* \param [out] child_in_tree_begin The global index of the first element belonging to the calling processor. Not computed if NULL.
788
* \param [out] last_local_tree The global index of the last tree that contains elements belonging to the calling process.
789
* \param [out] child_in_tree_end The global index of the first element that does not belonging to
790
* the calling process anymore. Not computed if NULL.
791
* \param [out] first_tree_shared If not NULL, 1 or 0 is stored here depending on whether \a first_local_tree is the
792
* same as \a last_local_tree on the previous process.
793
* \param [in] comm The communicator
794
*/
795
void
796
t8_cmesh_uniform_bounds_for_irregular_refinement (const t8_cmesh_t cmesh, const int level, const t8_scheme_c *scheme,
797
t8_gloidx_t *first_local_tree, t8_gloidx_t *child_in_tree_begin,
798
t8_gloidx_t *last_local_tree, t8_gloidx_t *child_in_tree_end,
799
int8_t *first_tree_shared, sc_MPI_Comm comm);
800
801
/** Increase the reference counter of a cmesh.
802
* \param [in,out] cmesh On input, this cmesh must exist with positive
803
* reference count. It may be in any state.
804
*/
805
void
806
t8_cmesh_ref (t8_cmesh_t cmesh);
807
808
/** Decrease the reference counter of a cmesh.
809
* If the counter reaches zero, this cmesh is destroyed.
810
* See also \ref t8_cmesh_destroy, which is to be preferred when it is
811
* known that the last reference to a cmesh is deleted.
812
* \param [in,out] pcmesh On input, the cmesh pointed to must exist
813
* with positive reference count. It may be in
814
* any state. If the reference count reaches
815
* zero, the cmesh is destroyed and this pointer
816
* set to NULL.
817
* Otherwise, the pointer is not changed and
818
* the cmesh is not modified in other ways.
819
*/
820
void
821
t8_cmesh_unref (t8_cmesh_t *pcmesh);
822
823
/** Verify that a coarse mesh has only one reference left and destroy it.
824
* This function is preferred over \ref t8_cmesh_unref when it is known
825
* that the last reference is to be deleted.
826
* \param [in,out] pcmesh This cmesh must have a reference count of one.
827
* It can be in any state (committed or not).
828
* Then it effectively calls \ref t8_cmesh_unref.
829
*/
830
void
831
t8_cmesh_destroy (t8_cmesh_t *pcmesh);
832
833
/** Compute y = ax + b on an array of doubles, interpreting
834
* each 3 as one vector x
835
* \param[in] coords_in The incoming coordinates of the vectors
836
* \param[out] coords_out The computed coordinates of the vectors
837
* \param[in] num_vertices The number of vertices/vectors
838
* \param[in] alpha Scaling factor for the vectors
839
* \param[in] b Translation of the vectors.*/
840
841
void
842
t8_cmesh_coords_axb (const double *coords_in, double *coords_out, int num_vertices, double alpha, const double b[3]);
843
844
/** Compute y = x + translate on an array of doubles, interpreting
845
* each 3 as one vector x
846
* \param[in] coords_in The incoming coordinates of the vectors
847
* \param[out] coords_out The computed coordinates of the vectors
848
* \param[in] num_vertices The number of vertices/vectors
849
* \param[in] translate Translation of the vectors.
850
*/
851
void
852
t8_cmesh_translate_coordinates (const double *coords_in, double *coords_out, const int num_vertices,
853
const double translate[3]);
854
855
/**TODO: Add proper documentation*/
856
void
857
t8_cmesh_new_translate_vertices_to_attributes (const t8_locidx_t *tvertices, const double *vertices,
858
double *attr_vertices, const int num_vertices);
859
860
/**
861
* \warning This function is only available in debug-modus and should only
862
* be used in debug-modus.
863
*
864
* Prints the vertices of each tree of each process
865
*
866
* \param[in] cmesh Source-cmesh, which trees get printed.
867
* \param[in] comm The MPI communicator to use for printing.
868
*/
869
void
870
t8_cmesh_debug_print_trees (const t8_cmesh_t cmesh, sc_MPI_Comm comm);
871
872
/**
873
* Compute the process local bounding box of the cmesh.
874
* The bounding box is stored in the array \a bounds in the following order:
875
* bounds[0] = x_min
876
* bounds[1] = x_max
877
* bounds[2] = y_min
878
* bounds[3] = y_max
879
* bounds[4] = z_min
880
* bounds[5] = z_max
881
*
882
* \param [in] cmesh The cmesh to be considered.
883
* \param [out] bounds The bounding box of the cmesh. If the box is flat (for quads for example, z_min == z_max)
884
*
885
* \return True if the computation was successful, false if the cmesh is empty.
886
*/
887
int
888
t8_cmesh_get_local_bounding_box (const t8_cmesh_t cmesh, double bounds[6]);
889
T8_EXTERN_C_END ();
890
891
#endif /* !T8_CMESH_H */
892
893