deal.II version GIT relicensing-6809-ge913b9bb34 2026-09-25 17:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
p4est_wrappers.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2016 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13
16
17#ifdef DEAL_II_WITH_P4EST
18# include <p4est.h>
19# include <p8est.h>
20# include <sc_containers.h>
21
22// Below, we will use the P4EST_QUADRANT_INIT and P8EST_QUADRANT_INIT
23// function-like macros. If we are building the library based on
24// header files, we get these from the <p4est.h> and <p8est.h> header
25// inclusions. But if we build a C++20 module, we only import
26// declarations, not preprocessor macros. As a consequence, let us
27// duplicate these macros here, hoping that at some point, the p4est
28// library folks add regular functions that can do the job.
29# ifndef P4EST_QUADRANT_INIT
30# define P4EST_QUADRANT_INIT(q) \
31 ((void)std::memset((q), -1, sizeof(p4est_quadrant_t)))
32# endif
33
34# ifndef P8EST_QUADRANT_INIT
35# define P8EST_QUADRANT_INIT(q) \
36 ((void)std::memset((q), -1, sizeof(p8est_quadrant_t)))
37# endif
38
39#endif
40
41
43
44#ifdef DEAL_II_WITH_P4EST
45
46namespace internal
47{
48 namespace p4est
49 {
50 int (&functions<2>::quadrant_compare)(const void *v1, const void *v2) =
51 p4est_quadrant_compare;
52
55 p4est_quadrant_childrenv;
56
58 const types<2>::quadrant *q) =
59 p4est_quadrant_overlaps_tree;
60
62 int level,
63 std::uint64_t id) =
64 p4est_quadrant_set_morton;
65
66 void
71
73 const types<2>::quadrant *q2) =
74 p4est_quadrant_is_equal;
75
77 const types<2>::quadrant *q2) =
78 p4est_quadrant_is_sibling;
79
81 const types<2>::quadrant *q2) =
82 p4est_quadrant_is_ancestor;
83
85 int level) =
86 p4est_quadrant_ancestor_id;
87
89 const types<2>::locidx which_tree,
90 const types<2>::quadrant *q,
91 const int guess) =
92 p4est_comm_find_owner;
93
95 types<2>::topidx num_vertices,
96 types<2>::topidx num_trees,
97 types<2>::topidx num_corners,
98 types<2>::topidx num_vtt) = p4est_connectivity_new;
99
101 types<2>::topidx num_vertices,
102 types<2>::topidx num_trees,
103 types<2>::topidx num_corners,
104 const double *vertices,
105 const types<2>::topidx *ttv,
106 const types<2>::topidx *ttt,
107 const int8_t *ttf,
108 const types<2>::topidx *ttc,
109 const types<2>::topidx *coff,
110 const types<2>::topidx *ctt,
111 const int8_t *ctc) = p4est_connectivity_new_copy;
112
114 types<2>::topidx tree_left,
115 types<2>::topidx tree_right,
116 int face_left,
117 int face_right,
118 int orientation) =
119 p4est_connectivity_join_faces;
120
122 p4est_connectivity_t *connectivity) = p4est_connectivity_destroy;
123
125 MPI_Comm mpicomm,
126 types<2>::connectivity *connectivity,
127 types<2>::locidx min_quadrants,
128 int min_level,
129 int fill_uniform,
130 std::size_t data_size,
131 p4est_init_t init_fn,
132 void *user_pointer) = p4est_new_ext;
133
135 int copy_data) = p4est_copy;
136
137 void (&functions<2>::destroy)(types<2>::forest *p4est) = p4est_destroy;
138
140 int refine_recursive,
141 p4est_refine_t refine_fn,
142 p4est_init_t init_fn) = p4est_refine;
143
145 int coarsen_recursive,
146 p4est_coarsen_t coarsen_fn,
147 p4est_init_t init_fn) = p4est_coarsen;
148
151 p4est_init_t init_fn) = p4est_balance;
152
154 int partition_for_coarsening,
155 p4est_weight_t weight_fn) =
156 p4est_partition_ext;
157
158 void (&functions<2>::save)(const char *filename,
159 types<2>::forest *p4est,
160 int save_data) = p4est_save;
161
163 const char *filename,
164 MPI_Comm mpicomm,
165 std::size_t data_size,
166 int load_data,
167 int autopartition,
168 int broadcasthead,
169 void *user_pointer,
170 types<2>::connectivity **p4est) = p4est_load_ext;
171
173 const char *filename,
174 types<2>::connectivity *connectivity) = p4est_connectivity_save;
175
177 types<2>::connectivity *connectivity) = p4est_connectivity_is_valid;
178
180 const char *filename,
181 std::size_t *length) = p4est_connectivity_load;
182
183 unsigned int (&functions<2>::checksum)(types<2>::forest *p4est) =
184 p4est_checksum;
185
187 p4est_geometry_t *,
188 const char *baseName) =
189 p4est_vtk_write_file;
190
193 p4est_ghost_new;
194
196 p4est_ghost_destroy;
197
199 std::size_t data_size,
200 p4est_init_t init_fn,
201 void *user_pointer) = p4est_reset_data;
202
204 p4est_memory_used;
205
207 types<2>::connectivity *p4est) = p4est_connectivity_memory_used;
208
209 constexpr unsigned int functions<2>::max_level;
210
211 void (&functions<2>::transfer_fixed)(const types<2>::gloidx *dest_gfq,
212 const types<2>::gloidx *src_gfq,
213 MPI_Comm mpicomm,
214 int tag,
215 void *dest_data,
216 const void *src_data,
217 std::size_t data_size) =
218 p4est_transfer_fixed;
219
221 const types<2>::gloidx *dest_gfq,
222 const types<2>::gloidx *src_gfq,
223 MPI_Comm mpicomm,
224 int tag,
225 void *dest_data,
226 const void *src_data,
227 std::size_t data_size) = p4est_transfer_fixed_begin;
228
230 p4est_transfer_fixed_end;
231
232 void (&functions<2>::transfer_custom)(const types<2>::gloidx *dest_gfq,
233 const types<2>::gloidx *src_gfq,
234 MPI_Comm mpicomm,
235 int tag,
236 void *dest_data,
237 const int *dest_sizes,
238 const void *src_data,
239 const int *src_sizes) =
240 p4est_transfer_custom;
241
243 const types<2>::gloidx *dest_gfq,
244 const types<2>::gloidx *src_gfq,
245 MPI_Comm mpicomm,
246 int tag,
247 void *dest_data,
248 const int *dest_sizes,
249 const void *src_data,
250 const int *src_sizes) = p4est_transfer_custom_begin;
251
253 p4est_transfer_custom_end;
254
256 types<2>::forest *p4est,
257 int call_post,
260 sc_array_t *points) = p4est_search_partition;
261
263 types<2>::connectivity *connectivity,
264 types<2>::topidx treeid,
267 double vxyz[3]) = p4est_qcoord_to_vertex;
268
269 int (&functions<3>::quadrant_compare)(const void *v1, const void *v2) =
270 p8est_quadrant_compare;
271
273 types<3>::quadrant c[]) =
274 p8est_quadrant_childrenv;
275
277 const types<3>::quadrant *q) =
278 p8est_quadrant_overlaps_tree;
279
281 int level,
282 std::uint64_t id) =
283 p8est_quadrant_set_morton;
284
285 void
290
292 const types<3>::quadrant *q2) =
293 p8est_quadrant_is_equal;
294
296 const types<3>::quadrant *q2) =
297 p8est_quadrant_is_sibling;
298
300 const types<3>::quadrant *q2) =
301 p8est_quadrant_is_ancestor;
302
304 int level) =
305 p8est_quadrant_ancestor_id;
306
308 const types<3>::locidx which_tree,
309 const types<3>::quadrant *q,
310 const int guess) =
311 p8est_comm_find_owner;
312
314 types<3>::topidx num_vertices,
315 types<3>::topidx num_trees,
316 types<3>::topidx num_edges,
317 types<3>::topidx num_ett,
318 types<3>::topidx num_corners,
319 types<3>::topidx num_ctt) = p8est_connectivity_new;
320
322 types<3>::topidx num_vertices,
323 types<3>::topidx num_trees,
324 types<3>::topidx num_edges,
325 types<3>::topidx num_corners,
326 const double *vertices,
327 const types<3>::topidx *ttv,
328 const types<3>::topidx *ttt,
329 const int8_t *ttf,
330 const types<3>::topidx *tte,
331 const types<3>::topidx *eoff,
332 const types<3>::topidx *ett,
333 const int8_t *ete,
334 const types<3>::topidx *ttc,
335 const types<3>::topidx *coff,
336 const types<3>::topidx *ctt,
337 const int8_t *ctc) = p8est_connectivity_new_copy;
338
340 p8est_connectivity_t *connectivity) = p8est_connectivity_destroy;
341
343 types<3>::topidx tree_left,
344 types<3>::topidx tree_right,
345 int face_left,
346 int face_right,
347 int orientation) =
348 p8est_connectivity_join_faces;
349
351 MPI_Comm mpicomm,
352 types<3>::connectivity *connectivity,
353 types<3>::locidx min_quadrants,
354 int min_level,
355 int fill_uniform,
356 std::size_t data_size,
357 p8est_init_t init_fn,
358 void *user_pointer) = p8est_new_ext;
359
361 int copy_data) = p8est_copy;
362
363 void (&functions<3>::destroy)(types<3>::forest *p8est) = p8est_destroy;
364
366 int refine_recursive,
367 p8est_refine_t refine_fn,
368 p8est_init_t init_fn) = p8est_refine;
369
371 int coarsen_recursive,
372 p8est_coarsen_t coarsen_fn,
373 p8est_init_t init_fn) = p8est_coarsen;
374
377 p8est_init_t init_fn) = p8est_balance;
378
380 int partition_for_coarsening,
381 p8est_weight_t weight_fn) =
382 p8est_partition_ext;
383
384 void (&functions<3>::save)(const char *filename,
385 types<3>::forest *p4est,
386 int save_data) = p8est_save;
387
389 const char *filename,
390 MPI_Comm mpicomm,
391 std::size_t data_size,
392 int load_data,
393 int autopartition,
394 int broadcasthead,
395 void *user_pointer,
396 types<3>::connectivity **p4est) = p8est_load_ext;
397
399 const char *filename,
400 types<3>::connectivity *connectivity) = p8est_connectivity_save;
401
403 types<3>::connectivity *connectivity) = p8est_connectivity_is_valid;
404
406 const char *filename,
407 std::size_t *length) = p8est_connectivity_load;
408
409 unsigned int (&functions<3>::checksum)(types<3>::forest *p8est) =
410 p8est_checksum;
411
413 p8est_geometry_t *,
414 const char *baseName) =
415 p8est_vtk_write_file;
416
419 p8est_ghost_new;
420
422 p8est_ghost_destroy;
423
425 std::size_t data_size,
426 p8est_init_t init_fn,
427 void *user_pointer) = p8est_reset_data;
428
430 p8est_memory_used;
431
433 types<3>::connectivity *p4est) = p8est_connectivity_memory_used;
434
435 constexpr unsigned int functions<3>::max_level;
436
437 void (&functions<3>::transfer_fixed)(const types<3>::gloidx *dest_gfq,
438 const types<3>::gloidx *src_gfq,
439 MPI_Comm mpicomm,
440 int tag,
441 void *dest_data,
442 const void *src_data,
443 std::size_t data_size) =
444 p8est_transfer_fixed;
445
447 const types<3>::gloidx *dest_gfq,
448 const types<3>::gloidx *src_gfq,
449 MPI_Comm mpicomm,
450 int tag,
451 void *dest_data,
452 const void *src_data,
453 std::size_t data_size) = p8est_transfer_fixed_begin;
454
456 p8est_transfer_fixed_end;
457
458 void (&functions<3>::transfer_custom)(const types<3>::gloidx *dest_gfq,
459 const types<3>::gloidx *src_gfq,
460 MPI_Comm mpicomm,
461 int tag,
462 void *dest_data,
463 const int *dest_sizes,
464 const void *src_data,
465 const int *src_sizes) =
466 p8est_transfer_custom;
467
469 const types<3>::gloidx *dest_gfq,
470 const types<3>::gloidx *src_gfq,
471 MPI_Comm mpicomm,
472 int tag,
473 void *dest_data,
474 const int *dest_sizes,
475 const void *src_data,
476 const int *src_sizes) = p8est_transfer_custom_begin;
477
479 p8est_transfer_custom_end;
480
482 types<3>::forest *p4est,
483 int call_post,
486 sc_array_t *points) = p8est_search_partition;
487
489 types<3>::connectivity *connectivity,
490 types<3>::topidx treeid,
494 double vxyz[3]) = p8est_qcoord_to_vertex;
495
496 template <int dim>
497 void
499 const typename types<dim>::quadrant &p4est_cell,
500 typename types<dim>::quadrant (
502 {
503 for (unsigned int c = 0;
504 c < ::GeometryInfo<dim>::max_children_per_cell;
505 ++c)
506 functions<dim>::quadrant_init(p4est_children[c]);
507
508 functions<dim>::quadrant_childrenv(&p4est_cell, p4est_children);
509 }
510
511 template <int dim>
512 void
514 {
517 /*level=*/0,
518 /*index=*/0);
519 }
520
521 template <int dim>
522 bool
524 const typename types<dim>::quadrant &q2)
525 {
526 return functions<dim>::quadrant_is_equal(&q1, &q2);
527 }
528
529
530
531 template <int dim>
532 bool
534 const typename types<dim>::quadrant &q2)
535 {
537 }
538
539 template <int dim>
540 bool
541 tree_exists_locally(const typename types<dim>::forest *parallel_forest,
542 const typename types<dim>::topidx coarse_grid_cell)
543 {
544 Assert(coarse_grid_cell < parallel_forest->connectivity->num_trees,
546 return ((coarse_grid_cell >= parallel_forest->first_local_tree) &&
547 (coarse_grid_cell <= parallel_forest->last_local_tree));
548 }
549
550
551
552 // template specializations
553
554 template <>
556 copy_connectivity<2>(const typename types<2>::connectivity *connectivity)
557 {
559 connectivity->num_vertices,
560 connectivity->num_trees,
561 connectivity->num_corners,
562 connectivity->vertices,
563 connectivity->tree_to_vertex,
564 connectivity->tree_to_tree,
565 connectivity->tree_to_face,
566 connectivity->tree_to_corner,
567 connectivity->ctt_offset,
568 connectivity->corner_to_tree,
569 connectivity->corner_to_corner);
570 }
571
572 template <>
574 copy_connectivity<3>(const typename types<3>::connectivity *connectivity)
575 {
577 connectivity->num_vertices,
578 connectivity->num_trees,
579 connectivity->num_edges,
580 connectivity->num_corners,
581 connectivity->vertices,
582 connectivity->tree_to_vertex,
583 connectivity->tree_to_tree,
584 connectivity->tree_to_face,
585 connectivity->tree_to_edge,
586 connectivity->ett_offset,
587 connectivity->edge_to_tree,
588 connectivity->edge_to_edge,
589 connectivity->tree_to_corner,
590 connectivity->ctt_offset,
591 connectivity->corner_to_tree,
592 connectivity->corner_to_corner);
593 }
594
595
596
597 template <>
598 bool
599 quadrant_is_equal<1>(const typename types<1>::quadrant &q1,
600 const typename types<1>::quadrant &q2)
601 {
602 return q1 == q2;
603 }
604
605
606
607 template <>
608 bool
610 const types<1>::quadrant &q2)
611 {
612 // determine level of quadrants
613 const int level_1 = (q1 << types<1>::max_n_child_indices_bits) >>
615 const int level_2 = (q2 << types<1>::max_n_child_indices_bits) >>
617
618 // q1 can be an ancestor of q2 if q1's level is smaller
619 if (level_1 >= level_2)
620 return false;
621
622 // extract path of quadrants up to level of possible ancestor q1
623 const int truncated_id_1 = (q1 >> (types<1>::n_bits - 1 - level_1))
624 << (types<1>::n_bits - 1 - level_1);
625 const int truncated_id_2 = (q2 >> (types<1>::n_bits - 1 - level_1))
626 << (types<1>::n_bits - 1 - level_1);
627
628 // compare paths
629 return truncated_id_1 == truncated_id_2;
630 }
631
632
633
634 template <>
635 void
637 const typename types<1>::quadrant &q,
638 typename types<1>::quadrant (
640 {
641 // determine the current level of quadrant
642 const int level_parent = (q << types<1>::max_n_child_indices_bits) >>
644 const int level_child = level_parent + 1;
645
646 // left child: only n_child_indices has to be incremented
647 p4est_children[0] = (q + 1);
648
649 // right child: increment and set a bit to 1 indicating that it is a right
650 // child
651 p4est_children[1] = (q + 1) | (1 << (types<1>::n_bits - 1 - level_child));
652 }
653
654
655
656 template <>
657 void
659 {
660 quad = 0;
661 }
662
663 } // namespace p4est
664} // namespace internal
665
666#endif // DEAL_II_WITH_P4EST
667
668/*-------------- Explicit Instantiations -------------------------------*/
669#include "distributed/p4est_wrappers.inst"
670
671
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
unsigned int level
Definition grid_out.cc:4642
const unsigned int v1
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
void init_quadrant_children< 1 >(const typename types< 1 >::quadrant &q, typename types< 1 >::quadrant(&p4est_children)[::GeometryInfo< 1 >::max_children_per_cell])
void init_coarse_quadrant(typename types< dim >::quadrant &quad)
bool quadrant_is_equal< 1 >(const typename types< 1 >::quadrant &q1, const typename types< 1 >::quadrant &q2)
types< 2 >::connectivity * copy_connectivity< 2 >(const typename types< 2 >::connectivity *connectivity)
bool quadrant_is_ancestor< 1 >(const types< 1 >::quadrant &q1, const types< 1 >::quadrant &q2)
types< 3 >::connectivity * copy_connectivity< 3 >(const typename types< 3 >::connectivity *connectivity)
bool quadrant_is_equal(const typename types< dim >::quadrant &q1, const typename types< dim >::quadrant &q2)
void init_quadrant_children(const typename types< dim >::quadrant &p4est_cell, typename types< dim >::quadrant(&p4est_children)[::GeometryInfo< dim >::max_children_per_cell])
bool quadrant_is_ancestor(const typename types< dim >::quadrant &q1, const typename types< dim >::quadrant &q2)
void init_coarse_quadrant< 1 >(typename types< 1 >::quadrant &quad)
bool tree_exists_locally(const typename types< dim >::forest *parallel_forest, const typename types< dim >::topidx coarse_grid_cell)
#define P8EST_QUADRANT_INIT(q)
#define P4EST_QUADRANT_INIT(q)