deal.II version 9.8.0
\(\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 namespace
51 {
52 template <int dim, int spacedim>
53 typename ::Triangulation<dim, spacedim>::cell_iterator
54 cell_from_quad(
55 const ::parallel::distributed::Triangulation<dim, spacedim>
56 *triangulation,
57 const typename ::internal::p4est::types<dim>::topidx treeidx,
58 const typename ::internal::p4est::types<dim>::quadrant &quad)
59 {
60 int i, l = quad.level;
61 ::types::global_dof_index dealii_index =
62 triangulation->get_p4est_tree_to_coarse_cell_permutation()[treeidx];
63
64 for (i = 0; i < l; ++i)
65 {
66 typename ::Triangulation<dim, spacedim>::cell_iterator cell(
67 triangulation, i, dealii_index);
68 const int child_id =
70 &quad, i + 1);
71 Assert(cell->has_children(),
72 ExcMessage("p4est quadrant does not correspond to a cell!"));
73 dealii_index = cell->child_index(child_id);
74 }
75
76 typename ::Triangulation<dim, spacedim>::cell_iterator out_cell(
77 triangulation, l, dealii_index);
78
79 return out_cell;
80 }
81
86 template <int dim, int spacedim>
87 struct FindGhosts
88 {
89 const typename ::parallel::distributed::Triangulation<dim,
90 spacedim>
91 *triangulation;
92 sc_array_t *subids;
93 std::map<unsigned int, std::set<::types::subdomain_id>>
94 *vertices_with_ghost_neighbors;
95 };
96
97
103 template <int dim, int spacedim>
104 void
105 find_ghosts_corner(
106 typename ::internal::p4est::iter<dim>::corner_info *info,
107 void *user_data)
108 {
109 int i, j;
110 int nsides = info->sides.elem_count;
111 auto *sides = reinterpret_cast<
112 typename ::internal::p4est::iter<dim>::corner_side *>(
113 info->sides.array);
114 FindGhosts<dim, spacedim> *fg =
115 static_cast<FindGhosts<dim, spacedim> *>(user_data);
116 sc_array_t *subids = fg->subids;
117 const ::parallel::distributed::Triangulation<dim, spacedim>
118 *triangulation = fg->triangulation;
119 int nsubs;
120 ::types::subdomain_id *subdomain_ids;
121 std::map<unsigned int, std::set<::types::subdomain_id>>
122 *vertices_with_ghost_neighbors = fg->vertices_with_ghost_neighbors;
123
124 subids->elem_count = 0;
125 for (i = 0; i < nsides; ++i)
126 {
127 if (sides[i].is_ghost)
128 {
129 typename ::parallel::distributed::
130 Triangulation<dim, spacedim>::cell_iterator cell =
131 cell_from_quad(triangulation,
132 sides[i].treeid,
133 *(sides[i].quad));
134 Assert(cell->is_ghost(),
135 ExcMessage("ghost quad did not find ghost cell"));
136 ::types::subdomain_id *subid =
137 static_cast<::types::subdomain_id *>(
138 sc_array_push(subids));
139 *subid = cell->subdomain_id();
140 }
141 }
142
143 if (!subids->elem_count)
144 {
145 return;
146 }
147
148 nsubs = static_cast<int>(subids->elem_count);
149 subdomain_ids =
150 reinterpret_cast<::types::subdomain_id *>(subids->array);
151
152 for (i = 0; i < nsides; ++i)
153 {
154 if (!sides[i].is_ghost)
155 {
156 typename ::parallel::distributed::
157 Triangulation<dim, spacedim>::cell_iterator cell =
158 cell_from_quad(triangulation,
159 sides[i].treeid,
160 *(sides[i].quad));
161
162 Assert(!cell->is_ghost(),
163 ExcMessage("local quad found ghost cell"));
164
165 for (j = 0; j < nsubs; ++j)
166 {
167 (*vertices_with_ghost_neighbors)[cell->vertex_index(
168 sides[i].corner)]
169 .insert(subdomain_ids[j]);
170 }
171 }
172 }
173
174 subids->elem_count = 0;
175 }
176
180 template <int dim, int spacedim>
181 void
182 find_ghosts_edge(
183 typename ::internal::p4est::iter<dim>::edge_info *info,
184 void *user_data)
185 {
186 int i, j, k;
187 int nsides = info->sides.elem_count;
188 auto *sides = reinterpret_cast<
189 typename ::internal::p4est::iter<dim>::edge_side *>(
190 info->sides.array);
191 auto *fg = static_cast<FindGhosts<dim, spacedim> *>(user_data);
192 sc_array_t *subids = fg->subids;
193 const ::parallel::distributed::Triangulation<dim, spacedim>
194 *triangulation = fg->triangulation;
195 int nsubs;
196 ::types::subdomain_id *subdomain_ids;
197 std::map<unsigned int, std::set<::types::subdomain_id>>
198 *vertices_with_ghost_neighbors = fg->vertices_with_ghost_neighbors;
199
200 subids->elem_count = 0;
201 for (i = 0; i < nsides; ++i)
202 {
203 if (sides[i].is_hanging)
204 {
205 for (j = 0; j < 2; ++j)
206 {
207 if (sides[i].is.hanging.is_ghost[j])
208 {
209 typename ::parallel::distributed::
210 Triangulation<dim, spacedim>::cell_iterator cell =
211 cell_from_quad(triangulation,
212 sides[i].treeid,
213 *(sides[i].is.hanging.quad[j]));
214 ::types::subdomain_id *subid =
215 static_cast<::types::subdomain_id *>(
216 sc_array_push(subids));
217 *subid = cell->subdomain_id();
218 }
219 }
220 }
221 }
222
223 if (!subids->elem_count)
224 {
225 return;
226 }
227
228 nsubs = static_cast<int>(subids->elem_count);
229 subdomain_ids =
230 reinterpret_cast<::types::subdomain_id *>(subids->array);
231
232 for (i = 0; i < nsides; ++i)
233 {
234 if (sides[i].is_hanging)
235 {
236 for (j = 0; j < 2; ++j)
237 {
238 if (!sides[i].is.hanging.is_ghost[j])
239 {
240 typename ::parallel::distributed::
241 Triangulation<dim, spacedim>::cell_iterator cell =
242 cell_from_quad(triangulation,
243 sides[i].treeid,
244 *(sides[i].is.hanging.quad[j]));
245
246 for (k = 0; k < nsubs; ++k)
247 {
248 (*vertices_with_ghost_neighbors)
249 [cell->vertex_index(
250 p8est_edge_corners[sides[i].edge][1 ^ j])]
251 .insert(subdomain_ids[k]);
252 }
253 }
254 }
255 }
256 }
257
258 subids->elem_count = 0;
259 }
260
264 template <int dim, int spacedim>
265 void
266 find_ghosts_face(
267 typename ::internal::p4est::iter<dim>::face_info *info,
268 void *user_data)
269 {
270 int i, j, k;
271 int nsides = info->sides.elem_count;
272 auto *sides = reinterpret_cast<
273 typename ::internal::p4est::iter<dim>::face_side *>(
274 info->sides.array);
275 FindGhosts<dim, spacedim> *fg =
276 static_cast<FindGhosts<dim, spacedim> *>(user_data);
277 sc_array_t *subids = fg->subids;
278 const ::parallel::distributed::Triangulation<dim, spacedim>
279 *triangulation = fg->triangulation;
280 int nsubs;
281 ::types::subdomain_id *subdomain_ids;
282 std::map<unsigned int, std::set<::types::subdomain_id>>
283 *vertices_with_ghost_neighbors = fg->vertices_with_ghost_neighbors;
284 int limit = (dim == 2) ? 2 : 4;
285
286 subids->elem_count = 0;
287 for (i = 0; i < nsides; ++i)
288 {
289 if (sides[i].is_hanging)
290 {
291 for (j = 0; j < limit; ++j)
292 {
293 if (sides[i].is.hanging.is_ghost[j])
294 {
295 typename ::parallel::distributed::
296 Triangulation<dim, spacedim>::cell_iterator cell =
297 cell_from_quad(triangulation,
298 sides[i].treeid,
299 *(sides[i].is.hanging.quad[j]));
300 ::types::subdomain_id *subid =
301 static_cast<::types::subdomain_id *>(
302 sc_array_push(subids));
303 *subid = cell->subdomain_id();
304 }
305 }
306 }
307 }
308
309 if (!subids->elem_count)
310 {
311 return;
312 }
313
314 nsubs = static_cast<int>(subids->elem_count);
315 subdomain_ids =
316 reinterpret_cast<::types::subdomain_id *>(subids->array);
317
318 for (i = 0; i < nsides; ++i)
319 {
320 if (sides[i].is_hanging)
321 {
322 for (j = 0; j < limit; ++j)
323 {
324 if (!sides[i].is.hanging.is_ghost[j])
325 {
326 typename ::parallel::distributed::
327 Triangulation<dim, spacedim>::cell_iterator cell =
328 cell_from_quad(triangulation,
329 sides[i].treeid,
330 *(sides[i].is.hanging.quad[j]));
331
332 for (k = 0; k < nsubs; ++k)
333 {
334 if (dim == 2)
335 {
336 (*vertices_with_ghost_neighbors)
337 [cell->vertex_index(
338 p4est_face_corners[sides[i].face]
339 [(limit - 1) ^ j])]
340 .insert(subdomain_ids[k]);
341 }
342 else
343 {
344 (*vertices_with_ghost_neighbors)
345 [cell->vertex_index(
346 p8est_face_corners[sides[i].face]
347 [(limit - 1) ^ j])]
348 .insert(subdomain_ids[k]);
349 }
350 }
351 }
352 }
353 }
354 }
355
356 subids->elem_count = 0;
357 }
358 } // namespace
359
360
361 int (&functions<2>::quadrant_compare)(const void *v1, const void *v2) =
362 p4est_quadrant_compare;
363
365 types<2>::quadrant c[]) =
366 p4est_quadrant_childrenv;
367
369 const types<2>::quadrant *q) =
370 p4est_quadrant_overlaps_tree;
371
373 int level,
374 std::uint64_t id) =
375 p4est_quadrant_set_morton;
376
377 void
382
384 const types<2>::quadrant *q2) =
385 p4est_quadrant_is_equal;
386
388 const types<2>::quadrant *q2) =
389 p4est_quadrant_is_sibling;
390
392 const types<2>::quadrant *q2) =
393 p4est_quadrant_is_ancestor;
394
396 int level) =
397 p4est_quadrant_ancestor_id;
398
400 const types<2>::locidx which_tree,
401 const types<2>::quadrant *q,
402 const int guess) =
403 p4est_comm_find_owner;
404
406 types<2>::topidx num_vertices,
407 types<2>::topidx num_trees,
408 types<2>::topidx num_corners,
409 types<2>::topidx num_vtt) = p4est_connectivity_new;
410
412 types<2>::topidx num_vertices,
413 types<2>::topidx num_trees,
414 types<2>::topidx num_corners,
415 const double *vertices,
416 const types<2>::topidx *ttv,
417 const types<2>::topidx *ttt,
418 const int8_t *ttf,
419 const types<2>::topidx *ttc,
420 const types<2>::topidx *coff,
421 const types<2>::topidx *ctt,
422 const int8_t *ctc) = p4est_connectivity_new_copy;
423
425 types<2>::topidx tree_left,
426 types<2>::topidx tree_right,
427 int face_left,
428 int face_right,
429 int orientation) =
430 p4est_connectivity_join_faces;
431
433 p4est_connectivity_t *connectivity) = p4est_connectivity_destroy;
434
436 MPI_Comm mpicomm,
437 types<2>::connectivity *connectivity,
438 types<2>::locidx min_quadrants,
439 int min_level,
440 int fill_uniform,
441 std::size_t data_size,
442 p4est_init_t init_fn,
443 void *user_pointer) = p4est_new_ext;
444
446 int copy_data) = p4est_copy;
447
448 void (&functions<2>::destroy)(types<2>::forest *p4est) = p4est_destroy;
449
451 int refine_recursive,
452 p4est_refine_t refine_fn,
453 p4est_init_t init_fn) = p4est_refine;
454
456 int coarsen_recursive,
457 p4est_coarsen_t coarsen_fn,
458 p4est_init_t init_fn) = p4est_coarsen;
459
462 p4est_init_t init_fn) = p4est_balance;
463
465 int partition_for_coarsening,
466 p4est_weight_t weight_fn) =
467 p4est_partition_ext;
468
469 void (&functions<2>::save)(const char *filename,
471 int save_data) = p4est_save;
472
474 const char *filename,
475 MPI_Comm mpicomm,
476 std::size_t data_size,
477 int load_data,
478 int autopartition,
479 int broadcasthead,
480 void *user_pointer,
481 types<2>::connectivity **p4est) = p4est_load_ext;
482
484 const char *filename,
485 types<2>::connectivity *connectivity) = p4est_connectivity_save;
486
488 types<2>::connectivity *connectivity) = p4est_connectivity_is_valid;
489
491 const char *filename,
492 std::size_t *length) = p4est_connectivity_load;
493
495 p4est_checksum;
496
498 p4est_geometry_t *,
499 const char *baseName) =
500 p4est_vtk_write_file;
501
504 p4est_ghost_new;
505
507 p4est_ghost_destroy;
508
510 std::size_t data_size,
511 p4est_init_t init_fn,
512 void *user_pointer) = p4est_reset_data;
513
515 p4est_memory_used;
516
518 types<2>::connectivity *p4est) = p4est_connectivity_memory_used;
519
520 constexpr unsigned int functions<2>::max_level;
521
522 void (&functions<2>::transfer_fixed)(const types<2>::gloidx *dest_gfq,
523 const types<2>::gloidx *src_gfq,
524 MPI_Comm mpicomm,
525 int tag,
526 void *dest_data,
527 const void *src_data,
528 std::size_t data_size) =
529 p4est_transfer_fixed;
530
532 const types<2>::gloidx *dest_gfq,
533 const types<2>::gloidx *src_gfq,
534 MPI_Comm mpicomm,
535 int tag,
536 void *dest_data,
537 const void *src_data,
538 std::size_t data_size) = p4est_transfer_fixed_begin;
539
541 p4est_transfer_fixed_end;
542
543 void (&functions<2>::transfer_custom)(const types<2>::gloidx *dest_gfq,
544 const types<2>::gloidx *src_gfq,
545 MPI_Comm mpicomm,
546 int tag,
547 void *dest_data,
548 const int *dest_sizes,
549 const void *src_data,
550 const int *src_sizes) =
551 p4est_transfer_custom;
552
554 const types<2>::gloidx *dest_gfq,
555 const types<2>::gloidx *src_gfq,
556 MPI_Comm mpicomm,
557 int tag,
558 void *dest_data,
559 const int *dest_sizes,
560 const void *src_data,
561 const int *src_sizes) = p4est_transfer_custom_begin;
562
564 p4est_transfer_custom_end;
565
568 int call_post,
571 sc_array_t *points) = p4est_search_partition;
572
574 types<2>::connectivity *connectivity,
575 types<2>::topidx treeid,
578 double vxyz[3]) = p4est_qcoord_to_vertex;
579
580 int (&functions<3>::quadrant_compare)(const void *v1, const void *v2) =
581 p8est_quadrant_compare;
582
584 types<3>::quadrant c[]) =
585 p8est_quadrant_childrenv;
586
588 const types<3>::quadrant *q) =
589 p8est_quadrant_overlaps_tree;
590
592 int level,
593 std::uint64_t id) =
594 p8est_quadrant_set_morton;
595
596 void
601
603 const types<3>::quadrant *q2) =
604 p8est_quadrant_is_equal;
605
607 const types<3>::quadrant *q2) =
608 p8est_quadrant_is_sibling;
609
611 const types<3>::quadrant *q2) =
612 p8est_quadrant_is_ancestor;
613
615 int level) =
616 p8est_quadrant_ancestor_id;
617
619 const types<3>::locidx which_tree,
620 const types<3>::quadrant *q,
621 const int guess) =
622 p8est_comm_find_owner;
623
625 types<3>::topidx num_vertices,
626 types<3>::topidx num_trees,
627 types<3>::topidx num_edges,
628 types<3>::topidx num_ett,
629 types<3>::topidx num_corners,
630 types<3>::topidx num_ctt) = p8est_connectivity_new;
631
633 types<3>::topidx num_vertices,
634 types<3>::topidx num_trees,
635 types<3>::topidx num_edges,
636 types<3>::topidx num_corners,
637 const double *vertices,
638 const types<3>::topidx *ttv,
639 const types<3>::topidx *ttt,
640 const int8_t *ttf,
641 const types<3>::topidx *tte,
642 const types<3>::topidx *eoff,
643 const types<3>::topidx *ett,
644 const int8_t *ete,
645 const types<3>::topidx *ttc,
646 const types<3>::topidx *coff,
647 const types<3>::topidx *ctt,
648 const int8_t *ctc) = p8est_connectivity_new_copy;
649
651 p8est_connectivity_t *connectivity) = p8est_connectivity_destroy;
652
654 types<3>::topidx tree_left,
655 types<3>::topidx tree_right,
656 int face_left,
657 int face_right,
658 int orientation) =
659 p8est_connectivity_join_faces;
660
662 MPI_Comm mpicomm,
663 types<3>::connectivity *connectivity,
664 types<3>::locidx min_quadrants,
665 int min_level,
666 int fill_uniform,
667 std::size_t data_size,
668 p8est_init_t init_fn,
669 void *user_pointer) = p8est_new_ext;
670
672 int copy_data) = p8est_copy;
673
674 void (&functions<3>::destroy)(types<3>::forest *p8est) = p8est_destroy;
675
677 int refine_recursive,
678 p8est_refine_t refine_fn,
679 p8est_init_t init_fn) = p8est_refine;
680
682 int coarsen_recursive,
683 p8est_coarsen_t coarsen_fn,
684 p8est_init_t init_fn) = p8est_coarsen;
685
688 p8est_init_t init_fn) = p8est_balance;
689
691 int partition_for_coarsening,
692 p8est_weight_t weight_fn) =
693 p8est_partition_ext;
694
695 void (&functions<3>::save)(const char *filename,
697 int save_data) = p8est_save;
698
700 const char *filename,
701 MPI_Comm mpicomm,
702 std::size_t data_size,
703 int load_data,
704 int autopartition,
705 int broadcasthead,
706 void *user_pointer,
707 types<3>::connectivity **p4est) = p8est_load_ext;
708
710 const char *filename,
711 types<3>::connectivity *connectivity) = p8est_connectivity_save;
712
714 types<3>::connectivity *connectivity) = p8est_connectivity_is_valid;
715
717 const char *filename,
718 std::size_t *length) = p8est_connectivity_load;
719
720 unsigned int (&functions<3>::checksum)(types<3>::forest *p8est) =
721 p8est_checksum;
722
724 p8est_geometry_t *,
725 const char *baseName) =
726 p8est_vtk_write_file;
727
730 p8est_ghost_new;
731
733 p8est_ghost_destroy;
734
736 std::size_t data_size,
737 p8est_init_t init_fn,
738 void *user_pointer) = p8est_reset_data;
739
741 p8est_memory_used;
742
744 types<3>::connectivity *p4est) = p8est_connectivity_memory_used;
745
746 constexpr unsigned int functions<3>::max_level;
747
748 void (&functions<3>::transfer_fixed)(const types<3>::gloidx *dest_gfq,
749 const types<3>::gloidx *src_gfq,
750 MPI_Comm mpicomm,
751 int tag,
752 void *dest_data,
753 const void *src_data,
754 std::size_t data_size) =
755 p8est_transfer_fixed;
756
758 const types<3>::gloidx *dest_gfq,
759 const types<3>::gloidx *src_gfq,
760 MPI_Comm mpicomm,
761 int tag,
762 void *dest_data,
763 const void *src_data,
764 std::size_t data_size) = p8est_transfer_fixed_begin;
765
767 p8est_transfer_fixed_end;
768
769 void (&functions<3>::transfer_custom)(const types<3>::gloidx *dest_gfq,
770 const types<3>::gloidx *src_gfq,
771 MPI_Comm mpicomm,
772 int tag,
773 void *dest_data,
774 const int *dest_sizes,
775 const void *src_data,
776 const int *src_sizes) =
777 p8est_transfer_custom;
778
780 const types<3>::gloidx *dest_gfq,
781 const types<3>::gloidx *src_gfq,
782 MPI_Comm mpicomm,
783 int tag,
784 void *dest_data,
785 const int *dest_sizes,
786 const void *src_data,
787 const int *src_sizes) = p8est_transfer_custom_begin;
788
790 p8est_transfer_custom_end;
791
794 int call_post,
797 sc_array_t *points) = p8est_search_partition;
798
800 types<3>::connectivity *connectivity,
801 types<3>::topidx treeid,
805 double vxyz[3]) = p8est_qcoord_to_vertex;
806
807 template <int dim>
808 void
810 const typename types<dim>::quadrant &p4est_cell,
811 typename types<dim>::quadrant (
813 {
814 for (unsigned int c = 0;
815 c < ::GeometryInfo<dim>::max_children_per_cell;
816 ++c)
817 functions<dim>::quadrant_init(p4est_children[c]);
818
819 functions<dim>::quadrant_childrenv(&p4est_cell, p4est_children);
820 }
821
822 template <int dim>
823 void
825 {
828 /*level=*/0,
829 /*index=*/0);
830 }
831
832 template <int dim>
833 bool
835 const typename types<dim>::quadrant &q2)
836 {
837 return functions<dim>::quadrant_is_equal(&q1, &q2);
838 }
839
840
841
842 template <int dim>
843 bool
845 const typename types<dim>::quadrant &q2)
846 {
848 }
849
850 template <int dim>
851 bool
852 tree_exists_locally(const typename types<dim>::forest *parallel_forest,
853 const typename types<dim>::topidx coarse_grid_cell)
854 {
855 Assert(coarse_grid_cell < parallel_forest->connectivity->num_trees,
857 return ((coarse_grid_cell >= parallel_forest->first_local_tree) &&
858 (coarse_grid_cell <= parallel_forest->last_local_tree));
859 }
860
861
862
863 // template specializations
864
865 template <>
867 copy_connectivity<2>(const typename types<2>::connectivity *connectivity)
868 {
870 connectivity->num_vertices,
871 connectivity->num_trees,
872 connectivity->num_corners,
873 connectivity->vertices,
874 connectivity->tree_to_vertex,
875 connectivity->tree_to_tree,
876 connectivity->tree_to_face,
877 connectivity->tree_to_corner,
878 connectivity->ctt_offset,
879 connectivity->corner_to_tree,
880 connectivity->corner_to_corner);
881 }
882
883 template <>
885 copy_connectivity<3>(const typename types<3>::connectivity *connectivity)
886 {
888 connectivity->num_vertices,
889 connectivity->num_trees,
890 connectivity->num_edges,
891 connectivity->num_corners,
892 connectivity->vertices,
893 connectivity->tree_to_vertex,
894 connectivity->tree_to_tree,
895 connectivity->tree_to_face,
896 connectivity->tree_to_edge,
897 connectivity->ett_offset,
898 connectivity->edge_to_tree,
899 connectivity->edge_to_edge,
900 connectivity->tree_to_corner,
901 connectivity->ctt_offset,
902 connectivity->corner_to_tree,
903 connectivity->corner_to_corner);
904 }
905
906
907
908 template <>
909 bool
910 quadrant_is_equal<1>(const typename types<1>::quadrant &q1,
911 const typename types<1>::quadrant &q2)
912 {
913 return q1 == q2;
914 }
915
916
917
918 template <>
919 bool
921 const types<1>::quadrant &q2)
922 {
923 // determine level of quadrants
924 const int level_1 = (q1 << types<1>::max_n_child_indices_bits) >>
926 const int level_2 = (q2 << types<1>::max_n_child_indices_bits) >>
928
929 // q1 can be an ancestor of q2 if q1's level is smaller
930 if (level_1 >= level_2)
931 return false;
932
933 // extract path of quadrants up to level of possible ancestor q1
934 const int truncated_id_1 = (q1 >> (types<1>::n_bits - 1 - level_1))
935 << (types<1>::n_bits - 1 - level_1);
936 const int truncated_id_2 = (q2 >> (types<1>::n_bits - 1 - level_1))
937 << (types<1>::n_bits - 1 - level_1);
938
939 // compare paths
940 return truncated_id_1 == truncated_id_2;
941 }
942
943
944
945 template <>
946 void
948 const typename types<1>::quadrant &q,
949 typename types<1>::quadrant (
951 {
952 // determine the current level of quadrant
953 const int level_parent = (q << types<1>::max_n_child_indices_bits) >>
955 const int level_child = level_parent + 1;
956
957 // left child: only n_child_indices has to be incremented
958 p4est_children[0] = (q + 1);
959
960 // right child: increment and set a bit to 1 indicating that it is a right
961 // child
962 p4est_children[1] = (q + 1) | (1 << (types<1>::n_bits - 1 - level_child));
963 }
964
965
966
967 template <>
968 void
970 {
971 quad = 0;
972 }
973
974 } // namespace p4est
975} // namespace internal
976
977#endif // DEAL_II_WITH_P4EST
978
979/*-------------- Explicit Instantiations -------------------------------*/
980#include "distributed/p4est_wrappers.inst"
981
982
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
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)
unsigned int subdomain_id
Definition types.h:50
unsigned int global_dof_index
Definition types.h:92
#define P8EST_QUADRANT_INIT(q)
#define P4EST_QUADRANT_INIT(q)
static constexpr unsigned int max_children_per_cell