1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2020 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #include <deal.II/base/geometry_info.h>
18 #include <deal.II/base/memory_consumption.h>
19 
20 #include <deal.II/fe/mapping_q1.h>
21 
22 #include <deal.II/grid/connectivity.h>
23 #include <deal.II/grid/grid_tools.h>
24 #include <deal.II/grid/magic_numbers.h>
25 #include <deal.II/grid/manifold.h>
26 #include <deal.II/grid/tria.h>
27 #include <deal.II/grid/tria_accessor.h>
28 #include <deal.II/grid/tria_faces.h>
29 #include <deal.II/grid/tria_iterator.h>
30 #include <deal.II/grid/tria_levels.h>
31 
32 #include <deal.II/lac/full_matrix.h>
33 #include <deal.II/lac/vector.h>
34 
35 #include <algorithm>
36 #include <array>
37 #include <cmath>
38 #include <functional>
39 #include <list>
40 #include <map>
41 #include <memory>
42 #include <numeric>
43 
44 
45 DEAL_II_NAMESPACE_OPEN
46 
47 
48 namespace internal
49 {
50   namespace TriangulationImplementation
51   {
NumberCache()52     NumberCache<1>::NumberCache()
53       : n_levels(0)
54       , n_lines(0)
55       , n_active_lines(0)
56     // all other fields are
57     // default constructed
58     {}
59 
60 
61 
62     std::size_t
memory_consumption() const63     NumberCache<1>::memory_consumption() const
64     {
65       return (MemoryConsumption::memory_consumption(n_levels) +
66               MemoryConsumption::memory_consumption(n_lines) +
67               MemoryConsumption::memory_consumption(n_lines_level) +
68               MemoryConsumption::memory_consumption(n_active_lines) +
69               MemoryConsumption::memory_consumption(n_active_lines_level));
70     }
71 
72 
NumberCache()73     NumberCache<2>::NumberCache()
74       : n_quads(0)
75       , n_active_quads(0)
76     // all other fields are
77     // default constructed
78     {}
79 
80 
81 
82     std::size_t
memory_consumption() const83     NumberCache<2>::memory_consumption() const
84     {
85       return (NumberCache<1>::memory_consumption() +
86               MemoryConsumption::memory_consumption(n_quads) +
87               MemoryConsumption::memory_consumption(n_quads_level) +
88               MemoryConsumption::memory_consumption(n_active_quads) +
89               MemoryConsumption::memory_consumption(n_active_quads_level));
90     }
91 
92 
93 
NumberCache()94     NumberCache<3>::NumberCache()
95       : n_hexes(0)
96       , n_active_hexes(0)
97     // all other fields are
98     // default constructed
99     {}
100 
101 
102 
103     std::size_t
memory_consumption() const104     NumberCache<3>::memory_consumption() const
105     {
106       return (NumberCache<2>::memory_consumption() +
107               MemoryConsumption::memory_consumption(n_hexes) +
108               MemoryConsumption::memory_consumption(n_hexes_level) +
109               MemoryConsumption::memory_consumption(n_active_hexes) +
110               MemoryConsumption::memory_consumption(n_active_hexes_level));
111     }
112   } // namespace TriangulationImplementation
113 } // namespace internal
114 
115 // anonymous namespace for internal helper functions
116 namespace
117 {
118   // return whether the given cell is
119   // patch_level_1, i.e. determine
120   // whether either all or none of
121   // its children are further
122   // refined. this function can only
123   // be called for non-active cells.
124   template <int dim, int spacedim>
125   bool
cell_is_patch_level_1(const TriaIterator<dealii::CellAccessor<dim,spacedim>> & cell)126   cell_is_patch_level_1(
127     const TriaIterator<dealii::CellAccessor<dim, spacedim>> &cell)
128   {
129     Assert(cell->is_active() == false, ExcInternalError());
130 
131     unsigned int n_active_children = 0;
132     for (unsigned int i = 0; i < cell->n_children(); ++i)
133       if (cell->child(i)->is_active())
134         ++n_active_children;
135 
136     return (n_active_children == 0) ||
137            (n_active_children == cell->n_children());
138   }
139 
140 
141 
142   // return, whether a given @p cell will be
143   // coarsened, which is the case if all
144   // children are active and have their coarsen
145   // flag set. In case only part of the coarsen
146   // flags are set, remove them.
147   template <int dim, int spacedim>
148   bool
cell_will_be_coarsened(const TriaIterator<dealii::CellAccessor<dim,spacedim>> & cell)149   cell_will_be_coarsened(
150     const TriaIterator<dealii::CellAccessor<dim, spacedim>> &cell)
151   {
152     // only cells with children should be
153     // considered for coarsening
154 
155     if (cell->has_children())
156       {
157         unsigned int       children_to_coarsen = 0;
158         const unsigned int n_children          = cell->n_children();
159 
160         for (unsigned int c = 0; c < n_children; ++c)
161           if (cell->child(c)->is_active() && cell->child(c)->coarsen_flag_set())
162             ++children_to_coarsen;
163         if (children_to_coarsen == n_children)
164           return true;
165         else
166           for (unsigned int c = 0; c < n_children; ++c)
167             if (cell->child(c)->is_active())
168               cell->child(c)->clear_coarsen_flag();
169       }
170     // no children, so no coarsening
171     // possible. however, no children also
172     // means that this cell will be in the same
173     // state as if it had children and was
174     // coarsened. So, what should we return -
175     // false or true?
176     // make sure we do not have to do this at
177     // all...
178     Assert(cell->has_children(), ExcInternalError());
179     // ... and then simply return false
180     return false;
181   }
182 
183 
184   // return, whether the face @p face_no of the
185   // given @p cell will be refined after the
186   // current refinement step, considering
187   // refine and coarsen flags and considering
188   // only those refinemnts that will be caused
189   // by the neighboring cell.
190 
191   // this function is used on both active cells
192   // and cells with children. on cells with
193   // children it also of interest to know 'how'
194   // the face will be refined. thus there is an
195   // additional third argument @p
196   // expected_face_ref_case returning just
197   // that. be aware, that this variable will
198   // only contain useful information if this
199   // function is called for an active cell.
200   //
201   // thus, this is an internal function, users
202   // should call one of the two alternatives
203   // following below.
204   template <int dim, int spacedim>
205   bool
face_will_be_refined_by_neighbor_internal(const TriaIterator<dealii::CellAccessor<dim,spacedim>> & cell,const unsigned int face_no,RefinementCase<dim-1> & expected_face_ref_case)206   face_will_be_refined_by_neighbor_internal(
207     const TriaIterator<dealii::CellAccessor<dim, spacedim>> &cell,
208     const unsigned int                                       face_no,
209     RefinementCase<dim - 1> &expected_face_ref_case)
210   {
211     // first of all: set the default value for
212     // expected_face_ref_case, which is no
213     // refinement at all
214     expected_face_ref_case = RefinementCase<dim - 1>::no_refinement;
215 
216     const typename Triangulation<dim, spacedim>::cell_iterator neighbor =
217       cell->neighbor(face_no);
218 
219     // If we are at the boundary, there is no
220     // neighbor which could refine the face
221     if (neighbor.state() != IteratorState::valid)
222       return false;
223 
224     if (neighbor->has_children())
225       {
226         // if the neighbor is refined, it may be
227         // coarsened. if so, then it won't refine
228         // the face, no matter what else happens
229         if (cell_will_be_coarsened(neighbor))
230           return false;
231         else
232           // if the neighbor is refined, then it
233           // is also refined at our current
234           // face. He will stay so without
235           // coarsening, so return true in that
236           // case.
237           {
238             expected_face_ref_case = cell->face(face_no)->refinement_case();
239             return true;
240           }
241       }
242 
243     // now, the neighbor is not refined, but
244     // perhaps it will be
245     const RefinementCase<dim> nb_ref_flag = neighbor->refine_flag_set();
246     if (nb_ref_flag != RefinementCase<dim>::no_refinement)
247       {
248         // now we need to know, which of the
249         // neighbors faces points towards us
250         const unsigned int neighbor_neighbor = cell->neighbor_face_no(face_no);
251         // check, whether the cell will be
252         // refined in a way that refines our
253         // face
254         const RefinementCase<dim - 1> face_ref_case =
255           GeometryInfo<dim>::face_refinement_case(
256             nb_ref_flag,
257             neighbor_neighbor,
258             neighbor->face_orientation(neighbor_neighbor),
259             neighbor->face_flip(neighbor_neighbor),
260             neighbor->face_rotation(neighbor_neighbor));
261         if (face_ref_case != RefinementCase<dim - 1>::no_refinement)
262           {
263             const typename Triangulation<dim, spacedim>::face_iterator
264                       neighbor_face   = neighbor->face(neighbor_neighbor);
265             const int this_face_index = cell->face_index(face_no);
266 
267             // there are still two basic
268             // possibilities here: the neighbor
269             // might be coarser or as coarse
270             // as we are
271             if (neighbor_face->index() == this_face_index)
272               // the neighbor is as coarse as
273               // we are and will be refined at
274               // the face of consideration, so
275               // return true
276               {
277                 expected_face_ref_case = face_ref_case;
278                 return true;
279               }
280             else
281               {
282                 // the neighbor is coarser.
283                 // this is the most complicated
284                 // case. It might be, that the
285                 // neighbor's face will be
286                 // refined, but that we will
287                 // not see this, as we are
288                 // refined in a similar way.
289 
290                 // so, the neighbor's face must
291                 // have children. check, if our
292                 // cell's face is one of these
293                 // (it could also be a
294                 // grand_child)
295                 for (unsigned int c = 0; c < neighbor_face->n_children(); ++c)
296                   if (neighbor_face->child_index(c) == this_face_index)
297                     {
298                       // if the flagged refine
299                       // case of the face is a
300                       // subset or the same as
301                       // the current refine case,
302                       // then the face, as seen
303                       // from our cell, won't be
304                       // refined by the neighbor
305                       if ((neighbor_face->refinement_case() | face_ref_case) ==
306                           neighbor_face->refinement_case())
307                         return false;
308                       else
309                         {
310                           // if we are active, we
311                           // must be an
312                           // anisotropic child
313                           // and the coming
314                           // face_ref_case is
315                           // isotropic. Thus,
316                           // from our cell we
317                           // will see exactly the
318                           // opposite refine case
319                           // that the face has
320                           // now...
321                           Assert(
322                             face_ref_case ==
323                               RefinementCase<dim - 1>::isotropic_refinement,
324                             ExcInternalError());
325                           expected_face_ref_case =
326                             ~neighbor_face->refinement_case();
327                           return true;
328                         }
329                     }
330 
331                 // so, obviously we were not
332                 // one of the children, but a
333                 // grandchild. This is only
334                 // possible in 3d.
335                 Assert(dim == 3, ExcInternalError());
336                 // In that case, however, no
337                 // matter what the neighbor
338                 // does, it won't be finer
339                 // after the next refinement
340                 // step.
341                 return false;
342               }
343           } // if face will be refined
344       }     // if neighbor is flagged for refinement
345 
346     // no cases left, so the neighbor will not
347     // refine the face
348     return false;
349   }
350 
351   // version of above function for both active
352   // and non-active cells
353   template <int dim, int spacedim>
354   bool
face_will_be_refined_by_neighbor(const TriaIterator<dealii::CellAccessor<dim,spacedim>> & cell,const unsigned int face_no)355   face_will_be_refined_by_neighbor(
356     const TriaIterator<dealii::CellAccessor<dim, spacedim>> &cell,
357     const unsigned int                                       face_no)
358   {
359     RefinementCase<dim - 1> dummy = RefinementCase<dim - 1>::no_refinement;
360     return face_will_be_refined_by_neighbor_internal(cell, face_no, dummy);
361   }
362 
363   // version of above function for active cells
364   // only. Additionally returning the refine
365   // case (to come) of the face under
366   // consideration
367   template <int dim, int spacedim>
368   bool
face_will_be_refined_by_neighbor(const TriaActiveIterator<dealii::CellAccessor<dim,spacedim>> & cell,const unsigned int face_no,RefinementCase<dim-1> & expected_face_ref_case)369   face_will_be_refined_by_neighbor(
370     const TriaActiveIterator<dealii::CellAccessor<dim, spacedim>> &cell,
371     const unsigned int                                             face_no,
372     RefinementCase<dim - 1> &expected_face_ref_case)
373   {
374     return face_will_be_refined_by_neighbor_internal(cell,
375                                                      face_no,
376                                                      expected_face_ref_case);
377   }
378 
379 
380 
381   template <int dim, int spacedim>
382   bool
satisfies_level1_at_vertex_rule(const Triangulation<dim,spacedim> & triangulation)383   satisfies_level1_at_vertex_rule(
384     const Triangulation<dim, spacedim> &triangulation)
385   {
386     std::vector<unsigned int> min_adjacent_cell_level(
387       triangulation.n_vertices(), triangulation.n_levels());
388     std::vector<unsigned int> max_adjacent_cell_level(
389       triangulation.n_vertices(), 0);
390 
391     for (const auto &cell : triangulation.active_cell_iterators())
392       for (const unsigned int v : GeometryInfo<dim>::vertex_indices())
393         {
394           min_adjacent_cell_level[cell->vertex_index(v)] =
395             std::min<unsigned int>(
396               min_adjacent_cell_level[cell->vertex_index(v)], cell->level());
397           max_adjacent_cell_level[cell->vertex_index(v)] =
398             std::max<unsigned int>(
399               min_adjacent_cell_level[cell->vertex_index(v)], cell->level());
400         }
401 
402     for (unsigned int k = 0; k < triangulation.n_vertices(); ++k)
403       if (triangulation.vertex_used(k))
404         if (max_adjacent_cell_level[k] - min_adjacent_cell_level[k] > 1)
405           return false;
406     return true;
407   }
408 
409 
410 
411   /**
412    * Fill the vector @p line_cell_count
413    * needed by @p delete_children with the
414    * number of cells bounded by a given
415    * line.
416    */
417   template <int dim, int spacedim>
418   std::vector<unsigned int>
count_cells_bounded_by_line(const Triangulation<dim,spacedim> & triangulation)419   count_cells_bounded_by_line(const Triangulation<dim, spacedim> &triangulation)
420   {
421     if (dim >= 2)
422       {
423         std::vector<unsigned int> line_cell_count(triangulation.n_raw_lines(),
424                                                   0);
425         for (const auto &cell : triangulation.cell_iterators())
426           for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
427             ++line_cell_count[cell->line_index(l)];
428         return line_cell_count;
429       }
430     else
431       return std::vector<unsigned int>();
432   }
433 
434 
435 
436   /**
437    * Fill the vector @p quad_cell_count
438    * needed by @p delete_children with the
439    * number of cells bounded by a given
440    * quad.
441    */
442   template <int dim, int spacedim>
443   std::vector<unsigned int>
count_cells_bounded_by_quad(const Triangulation<dim,spacedim> & triangulation)444   count_cells_bounded_by_quad(const Triangulation<dim, spacedim> &triangulation)
445   {
446     if (dim >= 3)
447       {
448         std::vector<unsigned int> quad_cell_count(triangulation.n_raw_quads(),
449                                                   0);
450         for (const auto &cell : triangulation.cell_iterators())
451           for (unsigned int q : GeometryInfo<dim>::face_indices())
452             ++quad_cell_count[cell->quad_index(q)];
453         return quad_cell_count;
454       }
455     else
456       return std::vector<unsigned int>();
457   }
458 
459 
460 
461   /**
462    * A set of three functions that
463    * reorder the data given to
464    * create_triangulation_compatibility
465    * from the "classic" to the
466    * "current" format of vertex
467    * numbering of cells and
468    * faces. These functions do the
469    * reordering of their arguments
470    * in-place.
471    */
472   void
reorder_compatibility(const std::vector<CellData<1>> &,const SubCellData &)473   reorder_compatibility(const std::vector<CellData<1>> &, const SubCellData &)
474   {
475     // nothing to do here: the format
476     // hasn't changed for 1d
477   }
478 
479 
reorder_compatibility(std::vector<CellData<2>> & cells,const SubCellData &)480   void reorder_compatibility(std::vector<CellData<2>> &cells,
481                              const SubCellData &)
482   {
483     for (auto &cell : cells)
484       std::swap(cell.vertices[2], cell.vertices[3]);
485   }
486 
487 
reorder_compatibility(std::vector<CellData<3>> & cells,SubCellData & subcelldata)488   void reorder_compatibility(std::vector<CellData<3>> &cells,
489                              SubCellData &             subcelldata)
490   {
491     unsigned int tmp[GeometryInfo<3>::vertices_per_cell];
492     for (auto &cell : cells)
493       {
494         for (const unsigned int i : GeometryInfo<3>::vertex_indices())
495           tmp[i] = cell.vertices[i];
496         for (const unsigned int i : GeometryInfo<3>::vertex_indices())
497           cell.vertices[GeometryInfo<3>::ucd_to_deal[i]] = tmp[i];
498       }
499 
500     // now points in boundary quads
501     std::vector<CellData<2>>::iterator boundary_quad =
502       subcelldata.boundary_quads.begin();
503     std::vector<CellData<2>>::iterator end_quad =
504       subcelldata.boundary_quads.end();
505     for (unsigned int quad_no = 0; boundary_quad != end_quad;
506          ++boundary_quad, ++quad_no)
507       std::swap(boundary_quad->vertices[2], boundary_quad->vertices[3]);
508   }
509 
510 
511 
512   /**
513    * Return the index of the vertex
514    * in the middle of this object,
515    * if it exists. In order to
516    * exist, the object needs to be
517    * refined - for 2D and 3D it
518    * needs to be refined
519    * isotropically or else the
520    * anisotropic children have to
521    * be refined again. If the
522    * middle vertex does not exist,
523    * return
524    * <tt>numbers::invalid_unsigned_int</tt>.
525    *
526    * This function should not really be
527    * used in application programs.
528    */
529   template <int dim, int spacedim>
530   unsigned int
middle_vertex_index(const typename Triangulation<dim,spacedim>::line_iterator & line)531   middle_vertex_index(
532     const typename Triangulation<dim, spacedim>::line_iterator &line)
533   {
534     if (line->has_children())
535       return line->child(0)->vertex_index(1);
536     return numbers::invalid_unsigned_int;
537   }
538 
539 
540   template <int dim, int spacedim>
541   unsigned int
middle_vertex_index(const typename Triangulation<dim,spacedim>::quad_iterator & quad)542   middle_vertex_index(
543     const typename Triangulation<dim, spacedim>::quad_iterator &quad)
544   {
545     switch (static_cast<unsigned char>(quad->refinement_case()))
546       {
547         case RefinementCase<2>::cut_x:
548           return middle_vertex_index<dim, spacedim>(quad->child(0)->line(1));
549           break;
550         case RefinementCase<2>::cut_y:
551           return middle_vertex_index<dim, spacedim>(quad->child(0)->line(3));
552           break;
553         case RefinementCase<2>::cut_xy:
554           return quad->child(0)->vertex_index(3);
555           break;
556         default:
557           break;
558       }
559     return numbers::invalid_unsigned_int;
560   }
561 
562 
563   template <int dim, int spacedim>
564   unsigned int
middle_vertex_index(const typename Triangulation<dim,spacedim>::hex_iterator & hex)565   middle_vertex_index(
566     const typename Triangulation<dim, spacedim>::hex_iterator &hex)
567   {
568     switch (static_cast<unsigned char>(hex->refinement_case()))
569       {
570         case RefinementCase<3>::cut_x:
571           return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(1));
572           break;
573         case RefinementCase<3>::cut_y:
574           return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(3));
575           break;
576         case RefinementCase<3>::cut_z:
577           return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(5));
578           break;
579         case RefinementCase<3>::cut_xy:
580           return middle_vertex_index<dim, spacedim>(hex->child(0)->line(11));
581           break;
582         case RefinementCase<3>::cut_xz:
583           return middle_vertex_index<dim, spacedim>(hex->child(0)->line(5));
584           break;
585         case RefinementCase<3>::cut_yz:
586           return middle_vertex_index<dim, spacedim>(hex->child(0)->line(7));
587           break;
588         case RefinementCase<3>::cut_xyz:
589           return hex->child(0)->vertex_index(7);
590           break;
591         default:
592           break;
593       }
594     return numbers::invalid_unsigned_int;
595   }
596 
597 
598   /**
599    * Collect all coarse mesh cells
600    * with at least one vertex at
601    * which the determinant of the
602    * Jacobian is zero or
603    * negative. This is the function
604    * for the case dim!=spacedim,
605    * where we can not determine
606    * whether a cell is twisted as it
607    * may, for example, discretize a
608    * manifold with a twist.
609    */
610   template <class TRIANGULATION>
611   inline typename TRIANGULATION::DistortedCellList
collect_distorted_coarse_cells(const TRIANGULATION &)612   collect_distorted_coarse_cells(const TRIANGULATION &)
613   {
614     return typename TRIANGULATION::DistortedCellList();
615   }
616 
617 
618 
619   /**
620    * Collect all coarse mesh cells
621    * with at least one vertex at
622    * which the determinant of the
623    * Jacobian is zero or
624    * negative. This is the function
625    * for the case dim==spacedim.
626    */
627   template <int dim>
628   inline typename Triangulation<dim, dim>::DistortedCellList
collect_distorted_coarse_cells(const Triangulation<dim,dim> & triangulation)629   collect_distorted_coarse_cells(const Triangulation<dim, dim> &triangulation)
630   {
631     typename Triangulation<dim, dim>::DistortedCellList distorted_cells;
632     for (const auto &cell : triangulation.cell_iterators_on_level(0))
633       {
634         Point<dim> vertices[GeometryInfo<dim>::vertices_per_cell];
635         for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
636           vertices[i] = cell->vertex(i);
637 
638         Tensor<0, dim> determinants[GeometryInfo<dim>::vertices_per_cell];
639         GeometryInfo<dim>::alternating_form_at_vertices(vertices, determinants);
640 
641         for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
642           if (determinants[i] <= 1e-9 * std::pow(cell->diameter(), 1. * dim))
643             {
644               distorted_cells.distorted_cells.push_back(cell);
645               break;
646             }
647       }
648 
649     return distorted_cells;
650   }
651 
652 
653   /**
654    * Return whether any of the
655    * children of the given cell is
656    * distorted or not. This is the
657    * function for dim==spacedim.
658    */
659   template <int dim>
660   bool
has_distorted_children(const typename Triangulation<dim,dim>::cell_iterator & cell,std::integral_constant<int,dim>,std::integral_constant<int,dim>)661   has_distorted_children(
662     const typename Triangulation<dim, dim>::cell_iterator &cell,
663     std::integral_constant<int, dim>,
664     std::integral_constant<int, dim>)
665   {
666     Assert(cell->has_children(), ExcInternalError());
667 
668     for (unsigned int c = 0; c < cell->n_children(); ++c)
669       {
670         Point<dim> vertices[GeometryInfo<dim>::vertices_per_cell];
671         for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
672           vertices[i] = cell->child(c)->vertex(i);
673 
674         Tensor<0, dim> determinants[GeometryInfo<dim>::vertices_per_cell];
675         GeometryInfo<dim>::alternating_form_at_vertices(vertices, determinants);
676 
677         for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
678           if (determinants[i] <=
679               1e-9 * std::pow(cell->child(c)->diameter(), 1. * dim))
680             return true;
681       }
682 
683     return false;
684   }
685 
686 
687   /**
688    * Function for dim!=spacedim. As
689    * for
690    * collect_distorted_coarse_cells,
691    * there is nothing that we can do
692    * in this case.
693    */
694   template <int dim, int spacedim>
695   bool
has_distorted_children(const typename Triangulation<dim,spacedim>::cell_iterator &,std::integral_constant<int,dim>,std::integral_constant<int,spacedim>)696   has_distorted_children(
697     const typename Triangulation<dim, spacedim>::cell_iterator &,
698     std::integral_constant<int, dim>,
699     std::integral_constant<int, spacedim>)
700   {
701     return false;
702   }
703 
704 
705 
706   /**
707    * For a given triangulation: set up the
708    * neighbor information on all cells.
709    */
710   template <int spacedim>
update_neighbors(Triangulation<1,spacedim> &)711   void update_neighbors(Triangulation<1, spacedim> &)
712   {}
713 
714 
715   template <int dim, int spacedim>
716   void
update_neighbors(Triangulation<dim,spacedim> & triangulation)717   update_neighbors(Triangulation<dim, spacedim> &triangulation)
718   {
719     // each face can be neighbored on two sides
720     // by cells. according to the face's
721     // intrinsic normal we define the left
722     // neighbor as the one for which the face
723     // normal points outward, and store that
724     // one first; the second one is then
725     // the right neighbor for which the
726     // face normal points inward. This
727     // information depends on the type of cell
728     // and local number of face for the
729     // 'standard ordering and orientation' of
730     // faces and then on the face_orientation
731     // information for the real mesh. Set up a
732     // table to have fast access to those
733     // offsets (0 for left and 1 for
734     // right). Some of the values are invalid
735     // as they reference too large face
736     // numbers, but we just leave them at a
737     // zero value.
738     //
739     // Note, that in 2d for lines as faces the
740     // normal direction given in the
741     // GeometryInfo class is not consistent. We
742     // thus define here that the normal for a
743     // line points to the right if the line
744     // points upwards.
745     //
746     // There is one more point to
747     // consider, however: if we have
748     // dim<spacedim, then we may have
749     // cases where cells are
750     // inverted. In effect, both
751     // cells think they are the left
752     // neighbor of an edge, for
753     // example, which leads us to
754     // forget neighborship
755     // information (a case that shows
756     // this is
757     // codim_one/hanging_nodes_02). We
758     // store whether a cell is
759     // inverted using the
760     // direction_flag, so if a cell
761     // has a false direction_flag,
762     // then we need to invert our
763     // selection whether we are a
764     // left or right neighbor in all
765     // following computations.
766     //
767     // first index:  dimension (minus 2)
768     // second index: local face index
769     // third index:  face_orientation (false and true)
770     static const unsigned int left_right_offset[2][6][2] = {
771       // quadrilateral
772       {{0, 1},  // face 0, face_orientation = false and true
773        {1, 0},  // face 1, face_orientation = false and true
774        {1, 0},  // face 2, face_orientation = false and true
775        {0, 1},  // face 3, face_orientation = false and true
776        {0, 0},  // face 4, invalid face
777        {0, 0}}, // face 5, invalid face
778                 // hexahedron
779       {{0, 1}, {1, 0}, {0, 1}, {1, 0}, {0, 1}, {1, 0}}};
780 
781     // now create a vector of the two active
782     // neighbors (left and right) for each face
783     // and fill it by looping over all cells. For
784     // cases with anisotropic refinement and more
785     // then one cell neighboring at a given side
786     // of the face we will automatically get the
787     // active one on the highest level as we loop
788     // over cells from lower levels first.
789     const typename Triangulation<dim, spacedim>::cell_iterator dummy;
790     std::vector<typename Triangulation<dim, spacedim>::cell_iterator>
791       adjacent_cells(2 * triangulation.n_raw_faces(), dummy);
792 
793     for (const auto &cell : triangulation.cell_iterators())
794       for (auto f : GeometryInfo<dim>::face_indices())
795         {
796           const typename Triangulation<dim, spacedim>::face_iterator face =
797             cell->face(f);
798 
799           const unsigned int offset =
800             (cell->direction_flag() ?
801                left_right_offset[dim - 2][f][cell->face_orientation(f)] :
802                1 - left_right_offset[dim - 2][f][cell->face_orientation(f)]);
803 
804           adjacent_cells[2 * face->index() + offset] = cell;
805 
806           // if this cell is not refined, but the
807           // face is, then we'll have to set our
808           // cell as neighbor for the child faces
809           // as well. Fortunately the normal
810           // orientation of children will be just
811           // the same.
812           if (dim == 2)
813             {
814               if (cell->is_active() && face->has_children())
815                 {
816                   adjacent_cells[2 * face->child(0)->index() + offset] = cell;
817                   adjacent_cells[2 * face->child(1)->index() + offset] = cell;
818                 }
819             }
820           else // -> dim == 3
821             {
822               // We need the same as in 2d
823               // here. Furthermore, if the face is
824               // refined with cut_x or cut_y then
825               // those children again in the other
826               // direction, and if this cell is
827               // refined isotropically (along the
828               // face) then the neighbor will
829               // (probably) be refined as cut_x or
830               // cut_y along the face. For those
831               // neighboring children cells, their
832               // neighbor will be the current,
833               // inactive cell, as our children are
834               // too fine to be neighbors. Catch that
835               // case by also acting on inactive
836               // cells with isotropic refinement
837               // along the face. If the situation
838               // described is not present, the data
839               // will be overwritten later on when we
840               // visit cells on finer levels, so no
841               // harm will be done.
842               if (face->has_children() &&
843                   (cell->is_active() ||
844                    GeometryInfo<dim>::face_refinement_case(
845                      cell->refinement_case(), f) ==
846                      RefinementCase<dim - 1>::isotropic_refinement))
847                 {
848                   for (unsigned int c = 0; c < face->n_children(); ++c)
849                     adjacent_cells[2 * face->child(c)->index() + offset] = cell;
850                   if (face->child(0)->has_children())
851                     {
852                       adjacent_cells[2 * face->child(0)->child(0)->index() +
853                                      offset] = cell;
854                       adjacent_cells[2 * face->child(0)->child(1)->index() +
855                                      offset] = cell;
856                     }
857                   if (face->child(1)->has_children())
858                     {
859                       adjacent_cells[2 * face->child(1)->child(0)->index() +
860                                      offset] = cell;
861                       adjacent_cells[2 * face->child(1)->child(1)->index() +
862                                      offset] = cell;
863                     }
864                 } // if cell active and face refined
865             }     // else -> dim==3
866         }         // for all faces of all cells
867 
868     // now loop again over all cells and set the
869     // corresponding neighbor cell. Note, that we
870     // have to use the opposite of the
871     // left_right_offset in this case as we want
872     // the offset of the neighbor, not our own.
873     for (const auto &cell : triangulation.cell_iterators())
874       for (auto f : GeometryInfo<dim>::face_indices())
875         {
876           const unsigned int offset =
877             (cell->direction_flag() ?
878                left_right_offset[dim - 2][f][cell->face_orientation(f)] :
879                1 - left_right_offset[dim - 2][f][cell->face_orientation(f)]);
880           cell->set_neighbor(
881             f, adjacent_cells[2 * cell->face(f)->index() + 1 - offset]);
882         }
883   }
884 
885 
886   template <int dim, int spacedim>
887   void
update_periodic_face_map_recursively(const typename Triangulation<dim,spacedim>::cell_iterator & cell_1,const typename Triangulation<dim,spacedim>::cell_iterator & cell_2,unsigned int n_face_1,unsigned int n_face_2,const std::bitset<3> & orientation,typename std::map<std::pair<typename Triangulation<dim,spacedim>::cell_iterator,unsigned int>,std::pair<std::pair<typename Triangulation<dim,spacedim>::cell_iterator,unsigned int>,std::bitset<3>>> & periodic_face_map)888   update_periodic_face_map_recursively(
889     const typename Triangulation<dim, spacedim>::cell_iterator &cell_1,
890     const typename Triangulation<dim, spacedim>::cell_iterator &cell_2,
891     unsigned int                                                n_face_1,
892     unsigned int                                                n_face_2,
893     const std::bitset<3> &                                      orientation,
894     typename std::map<
895       std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
896                 unsigned int>,
897       std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
898                           unsigned int>,
899                 std::bitset<3>>> &periodic_face_map)
900   {
901     using FaceIterator = typename Triangulation<dim, spacedim>::face_iterator;
902     const FaceIterator face_1 = cell_1->face(n_face_1);
903     const FaceIterator face_2 = cell_2->face(n_face_2);
904 
905     const bool face_orientation = orientation[0];
906     const bool face_flip        = orientation[1];
907     const bool face_rotation    = orientation[2];
908 
909     Assert((dim != 1) || (face_orientation == true && face_flip == false &&
910                           face_rotation == false),
911            ExcMessage("The supplied orientation "
912                       "(face_orientation, face_flip, face_rotation) "
913                       "is invalid for 1D"));
914 
915     Assert((dim != 2) || (face_orientation == true && face_rotation == false),
916            ExcMessage("The supplied orientation "
917                       "(face_orientation, face_flip, face_rotation) "
918                       "is invalid for 2D"));
919 
920     Assert(face_1 != face_2, ExcMessage("face_1 and face_2 are equal!"));
921 
922     Assert(face_1->at_boundary() && face_2->at_boundary(),
923            ExcMessage("Periodic faces must be on the boundary"));
924 
925     // Check if the requirement that each edge can only have at most one hanging
926     // node, and as a consequence neighboring cells can differ by at most
927     // one refinement level is enforced. In 1d, there are no hanging nodes and
928     // so neighboring cells can differ by more than one refinement level.
929     Assert(dim == 1 || std::abs(cell_1->level() - cell_2->level()) < 2,
930            ExcInternalError());
931 
932     // insert periodic face pair for both cells
933     using CellFace =
934       std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
935                 unsigned int>;
936     const CellFace                            cell_face_1(cell_1, n_face_1);
937     const CellFace                            cell_face_2(cell_2, n_face_2);
938     const std::pair<CellFace, std::bitset<3>> cell_face_orientation_2(
939       cell_face_2, orientation);
940 
941     const std::pair<CellFace, std::pair<CellFace, std::bitset<3>>>
942       periodic_faces(cell_face_1, cell_face_orientation_2);
943 
944     // Only one periodic neighbor is allowed
945     Assert(periodic_face_map.count(cell_face_1) == 0, ExcInternalError());
946     periodic_face_map.insert(periodic_faces);
947 
948     if (dim == 1)
949       {
950         if (cell_1->has_children())
951           {
952             if (cell_2->has_children())
953               {
954                 update_periodic_face_map_recursively<dim, spacedim>(
955                   cell_1->child(n_face_1),
956                   cell_2->child(n_face_2),
957                   n_face_1,
958                   n_face_2,
959                   orientation,
960                   periodic_face_map);
961               }
962             else // only face_1 has children
963               {
964                 update_periodic_face_map_recursively<dim, spacedim>(
965                   cell_1->child(n_face_1),
966                   cell_2,
967                   n_face_1,
968                   n_face_2,
969                   orientation,
970                   periodic_face_map);
971               }
972           }
973       }
974     else // dim == 2 || dim == 3
975       {
976         // A lookup table on how to go through the child cells depending on the
977         // orientation:
978         // see Documentation of GeometryInfo for details
979 
980         static const int lookup_table_2d[2][2] =
981           //               flip:
982           {
983             {0, 1}, // false
984             {1, 0}  // true
985           };
986 
987         static const int lookup_table_3d[2][2][2][4] =
988           //                           orientation flip  rotation
989           {{{
990               {0, 2, 1, 3}, // false       false false
991               {2, 3, 0, 1}  // false       false true
992             },
993             {
994               {3, 1, 2, 0}, // false       true  false
995               {1, 0, 3, 2}  // false       true  true
996             }},
997            {{
998               {0, 1, 2, 3}, // true        false false
999               {1, 3, 0, 2}  // true        false true
1000             },
1001             {
1002               {3, 2, 1, 0}, // true        true  false
1003               {2, 0, 3, 1}  // true        true  true
1004             }}};
1005 
1006         if (cell_1->has_children())
1007           {
1008             if (cell_2->has_children())
1009               {
1010                 // In the case that both faces have children, we loop over all
1011                 // children and apply update_periodic_face_map_recursively
1012                 // recursively:
1013 
1014                 Assert(face_1->n_children() ==
1015                            GeometryInfo<dim>::max_children_per_face &&
1016                          face_2->n_children() ==
1017                            GeometryInfo<dim>::max_children_per_face,
1018                        ExcNotImplemented());
1019 
1020                 for (unsigned int i = 0;
1021                      i < GeometryInfo<dim>::max_children_per_face;
1022                      ++i)
1023                   {
1024                     // Lookup the index for the second face
1025                     unsigned int j = 0;
1026                     switch (dim)
1027                       {
1028                         case 2:
1029                           j = lookup_table_2d[face_flip][i];
1030                           break;
1031                         case 3:
1032                           j = lookup_table_3d[face_orientation][face_flip]
1033                                              [face_rotation][i];
1034                           break;
1035                         default:
1036                           AssertThrow(false, ExcNotImplemented());
1037                       }
1038 
1039                     // find subcell ids that belong to the subface indices
1040                     unsigned int child_cell_1 =
1041                       GeometryInfo<dim>::child_cell_on_face(
1042                         cell_1->refinement_case(),
1043                         n_face_1,
1044                         i,
1045                         cell_1->face_orientation(n_face_1),
1046                         cell_1->face_flip(n_face_1),
1047                         cell_1->face_rotation(n_face_1),
1048                         face_1->refinement_case());
1049                     unsigned int child_cell_2 =
1050                       GeometryInfo<dim>::child_cell_on_face(
1051                         cell_2->refinement_case(),
1052                         n_face_2,
1053                         j,
1054                         cell_2->face_orientation(n_face_2),
1055                         cell_2->face_flip(n_face_2),
1056                         cell_2->face_rotation(n_face_2),
1057                         face_2->refinement_case());
1058 
1059                     Assert(cell_1->child(child_cell_1)->face(n_face_1) ==
1060                              face_1->child(i),
1061                            ExcInternalError());
1062                     Assert(cell_2->child(child_cell_2)->face(n_face_2) ==
1063                              face_2->child(j),
1064                            ExcInternalError());
1065 
1066                     // precondition: subcell has the same orientation as cell
1067                     // (so that the face numbers coincide) recursive call
1068                     update_periodic_face_map_recursively<dim, spacedim>(
1069                       cell_1->child(child_cell_1),
1070                       cell_2->child(child_cell_2),
1071                       n_face_1,
1072                       n_face_2,
1073                       orientation,
1074                       periodic_face_map);
1075                   }
1076               }
1077             else // only face_1 has children
1078               {
1079                 for (unsigned int i = 0;
1080                      i < GeometryInfo<dim>::max_children_per_face;
1081                      ++i)
1082                   {
1083                     // find subcell ids that belong to the subface indices
1084                     unsigned int child_cell_1 =
1085                       GeometryInfo<dim>::child_cell_on_face(
1086                         cell_1->refinement_case(),
1087                         n_face_1,
1088                         i,
1089                         cell_1->face_orientation(n_face_1),
1090                         cell_1->face_flip(n_face_1),
1091                         cell_1->face_rotation(n_face_1),
1092                         face_1->refinement_case());
1093 
1094                     // recursive call
1095                     update_periodic_face_map_recursively<dim, spacedim>(
1096                       cell_1->child(child_cell_1),
1097                       cell_2,
1098                       n_face_1,
1099                       n_face_2,
1100                       orientation,
1101                       periodic_face_map);
1102                   }
1103               }
1104           }
1105       }
1106   }
1107 
1108 
1109 } // end of anonymous namespace
1110 
1111 
1112 namespace internal
1113 {
1114   namespace TriangulationImplementation
1115   {
1116     // make sure that if in the following we
1117     // write Triangulation<dim,spacedim>
1118     // we mean the *class*
1119     // dealii::Triangulation, not the
1120     // enclosing namespace
1121     // internal::TriangulationImplementation
1122     using dealii::Triangulation;
1123 
1124     /**
1125      * Exception
1126      * @ingroup Exceptions
1127      */
1128     DeclException1(ExcGridHasInvalidCell,
1129                    int,
1130                    << "Something went wrong when making cell " << arg1
1131                    << ". Read the docs and the source code "
1132                    << "for more information.");
1133     /**
1134      * Exception
1135      * @ingroup Exceptions
1136      */
1137     DeclException1(ExcInternalErrorOnCell,
1138                    int,
1139                    << "Something went wrong upon construction of cell "
1140                    << arg1);
1141     /**
1142      * A cell was entered which has
1143      * negative measure. In most
1144      * cases, this is due to a wrong
1145      * order of the vertices of the
1146      * cell.
1147      *
1148      * @ingroup Exceptions
1149      */
1150     DeclException1(ExcCellHasNegativeMeasure,
1151                    int,
1152                    << "Cell " << arg1
1153                    << " has negative measure. This typically "
1154                    << "indicates some distortion in the cell, or a mistakenly "
1155                    << "swapped pair of vertices in the input to "
1156                    << "Triangulation::create_triangulation().");
1157     /**
1158      * A cell is created with a
1159      * vertex number exceeding the
1160      * vertex array.
1161      *
1162      * @ingroup Exceptions
1163      */
1164     DeclException3(ExcInvalidVertexIndex,
1165                    int,
1166                    int,
1167                    int,
1168                    << "Error while creating cell " << arg1
1169                    << ": the vertex index " << arg2 << " must be between 0 and "
1170                    << arg3 << ".");
1171     /**
1172      * Exception
1173      * @ingroup Exceptions
1174      */
1175     DeclException2(ExcLineInexistant,
1176                    int,
1177                    int,
1178                    << "While trying to assign a boundary indicator to a line: "
1179                    << "the line with end vertices " << arg1 << " and " << arg2
1180                    << " does not exist.");
1181     /**
1182      * Exception
1183      * @ingroup Exceptions
1184      */
1185     DeclException4(ExcQuadInexistant,
1186                    int,
1187                    int,
1188                    int,
1189                    int,
1190                    << "While trying to assign a boundary indicator to a quad: "
1191                    << "the quad with bounding lines " << arg1 << ", " << arg2
1192                    << ", " << arg3 << ", " << arg4 << " does not exist.");
1193     /**
1194      * Exception
1195      * @ingroup Exceptions
1196      */
1197     DeclException3(
1198       ExcInteriorLineCantBeBoundary,
1199       int,
1200       int,
1201       types::boundary_id,
1202       << "The input data for creating a triangulation contained "
1203       << "information about a line with indices " << arg1 << " and " << arg2
1204       << " that is described to have boundary indicator "
1205       << static_cast<int>(arg3)
1206       << ". However, this is an internal line not located on the "
1207       << "boundary. You cannot assign a boundary indicator to it." << std::endl
1208       << std::endl
1209       << "If this happened at a place where you call "
1210       << "Triangulation::create_triangulation() yourself, you need "
1211       << "to check the SubCellData object you pass to this function."
1212       << std::endl
1213       << std::endl
1214       << "If this happened in a place where you are reading a mesh "
1215       << "from a file, then you need to investigate why such a line "
1216       << "ended up in the input file. A typical case is a geometry "
1217       << "that consisted of multiple parts and for which the mesh "
1218       << "generator program assumes that the interface between "
1219       << "two parts is a boundary when that isn't supposed to be "
1220       << "the case, or where the mesh generator simply assigns "
1221       << "'geometry indicators' to lines at the perimeter of "
1222       << "a part that are not supposed to be interpreted as "
1223       << "'boundary indicators'.");
1224     /**
1225      * Exception
1226      * @ingroup Exceptions
1227      */
1228     DeclException5(
1229       ExcInteriorQuadCantBeBoundary,
1230       int,
1231       int,
1232       int,
1233       int,
1234       types::boundary_id,
1235       << "The input data for creating a triangulation contained "
1236       << "information about a quad with indices " << arg1 << ", " << arg2
1237       << ", " << arg3 << ", and " << arg4
1238       << " that is described to have boundary indicator "
1239       << static_cast<int>(arg5)
1240       << ". However, this is an internal quad not located on the "
1241       << "boundary. You cannot assign a boundary indicator to it." << std::endl
1242       << std::endl
1243       << "If this happened at a place where you call "
1244       << "Triangulation::create_triangulation() yourself, you need "
1245       << "to check the SubCellData object you pass to this function."
1246       << std::endl
1247       << std::endl
1248       << "If this happened in a place where you are reading a mesh "
1249       << "from a file, then you need to investigate why such a quad "
1250       << "ended up in the input file. A typical case is a geometry "
1251       << "that consisted of multiple parts and for which the mesh "
1252       << "generator program assumes that the interface between "
1253       << "two parts is a boundary when that isn't supposed to be "
1254       << "the case, or where the mesh generator simply assigns "
1255       << "'geometry indicators' to quads at the surface of "
1256       << "a part that are not supposed to be interpreted as "
1257       << "'boundary indicators'.");
1258     /**
1259      * Exception
1260      * @ingroup Exceptions
1261      */
1262     DeclException2(
1263       ExcMultiplySetLineInfoOfLine,
1264       int,
1265       int,
1266       << "In SubCellData the line info of the line with vertex indices " << arg1
1267       << " and " << arg2 << " appears more than once. "
1268       << "This is not allowed.");
1269     /**
1270      * Exception
1271      * @ingroup Exceptions
1272      */
1273     DeclException3(
1274       ExcInconsistentLineInfoOfLine,
1275       int,
1276       int,
1277       std::string,
1278       << "In SubCellData the line info of the line with vertex indices " << arg1
1279       << " and " << arg2 << " appears multiple times with different (valid) "
1280       << arg3 << ". This is not allowed.");
1281     /**
1282      * Exception
1283      * @ingroup Exceptions
1284      */
1285     DeclException5(
1286       ExcInconsistentQuadInfoOfQuad,
1287       int,
1288       int,
1289       int,
1290       int,
1291       std::string,
1292       << "In SubCellData the quad info of the quad with line indices " << arg1
1293       << ", " << arg2 << ", " << arg3 << " and " << arg4
1294       << " appears multiple times with different (valid) " << arg5
1295       << ". This is not allowed.");
1296 
1297     /*
1298      * Reserve space for TriaFaces. Details:
1299      *
1300      * Reserve space for line_orientations.
1301      *
1302      * @note Used only for dim=3.
1303      */
1304     void
reserve_space(TriaFaces & tria_faces,const unsigned int new_quads_in_pairs,const unsigned int new_quads_single)1305     reserve_space(TriaFaces &        tria_faces,
1306                   const unsigned int new_quads_in_pairs,
1307                   const unsigned int new_quads_single)
1308     {
1309       AssertDimension(tria_faces.dim, 3);
1310 
1311       Assert(new_quads_in_pairs % 2 == 0, ExcInternalError());
1312 
1313       unsigned int next_free_single = 0;
1314       unsigned int next_free_pair   = 0;
1315 
1316       // count the number of objects, of unused single objects and of
1317       // unused pairs of objects
1318       unsigned int n_quads          = 0;
1319       unsigned int n_unused_pairs   = 0;
1320       unsigned int n_unused_singles = 0;
1321       for (unsigned int i = 0; i < tria_faces.quads.used.size(); ++i)
1322         {
1323           if (tria_faces.quads.used[i])
1324             ++n_quads;
1325           else if (i + 1 < tria_faces.quads.used.size())
1326             {
1327               if (tria_faces.quads.used[i + 1])
1328                 {
1329                   ++n_unused_singles;
1330                   if (next_free_single == 0)
1331                     next_free_single = i;
1332                 }
1333               else
1334                 {
1335                   ++n_unused_pairs;
1336                   if (next_free_pair == 0)
1337                     next_free_pair = i;
1338                   ++i;
1339                 }
1340             }
1341           else
1342             ++n_unused_singles;
1343         }
1344       Assert(n_quads + 2 * n_unused_pairs + n_unused_singles ==
1345                tria_faces.quads.used.size(),
1346              ExcInternalError());
1347 
1348       // how many single quads are needed in addition to n_unused_quads?
1349       const int additional_single_quads = new_quads_single - n_unused_singles;
1350 
1351       unsigned int new_size =
1352         tria_faces.quads.used.size() + new_quads_in_pairs - 2 * n_unused_pairs;
1353       if (additional_single_quads > 0)
1354         new_size += additional_single_quads;
1355 
1356       // see above...
1357       if (new_size > tria_faces.quads.n_objects())
1358         {
1359           // reserve the field of the derived class
1360           tria_faces.quads_line_orientations.reserve(
1361             new_size * GeometryInfo<2>::lines_per_cell);
1362           tria_faces.quads_line_orientations.insert(
1363             tria_faces.quads_line_orientations.end(),
1364             new_size * GeometryInfo<2>::lines_per_cell -
1365               tria_faces.quads_line_orientations.size(),
1366             true);
1367 
1368           tria_faces.quad_reference_cell_type.reserve(new_size);
1369           tria_faces.quad_reference_cell_type.insert(
1370             tria_faces.quad_reference_cell_type.end(),
1371             new_size - tria_faces.quad_reference_cell_type.size(),
1372             ReferenceCell::Type::Quad);
1373         }
1374     }
1375 
1376 
1377 
1378     /**
1379      * Reserve space for TriaLevel. Details:
1380      *
1381      * Reserve enough space to accommodate @p total_cells cells on this
1382      * level. Since there are no @p used flags on this level, you have to
1383      * give the total number of cells, not only the number of newly to
1384      * accommodate ones, like in the <tt>TriaLevel<N>::reserve_space</tt>
1385      * functions, with <tt>N>0</tt>.
1386      *
1387      * Since the number of neighbors per cell depends on the dimensions, you
1388      * have to pass that additionally.
1389      */
1390 
1391     void
reserve_space(TriaLevel & tria_level,const unsigned int total_cells,const unsigned int dimension,const unsigned int space_dimension)1392     reserve_space(TriaLevel &        tria_level,
1393                   const unsigned int total_cells,
1394                   const unsigned int dimension,
1395                   const unsigned int space_dimension)
1396     {
1397       // we need space for total_cells cells. Maybe we have more already
1398       // with those cells which are unused, so only allocate new space if
1399       // needed.
1400       //
1401       // note that all arrays should have equal sizes (checked by
1402       // @p{monitor_memory}
1403       if (total_cells > tria_level.refine_flags.size())
1404         {
1405           tria_level.refine_flags.reserve(total_cells);
1406           tria_level.refine_flags.insert(tria_level.refine_flags.end(),
1407                                          total_cells -
1408                                            tria_level.refine_flags.size(),
1409                                          /*RefinementCase::no_refinement=*/0);
1410 
1411           tria_level.coarsen_flags.reserve(total_cells);
1412           tria_level.coarsen_flags.insert(tria_level.coarsen_flags.end(),
1413                                           total_cells -
1414                                             tria_level.coarsen_flags.size(),
1415                                           false);
1416 
1417           tria_level.active_cell_indices.reserve(total_cells);
1418           tria_level.active_cell_indices.insert(
1419             tria_level.active_cell_indices.end(),
1420             total_cells - tria_level.active_cell_indices.size(),
1421             numbers::invalid_unsigned_int);
1422 
1423           tria_level.subdomain_ids.reserve(total_cells);
1424           tria_level.subdomain_ids.insert(tria_level.subdomain_ids.end(),
1425                                           total_cells -
1426                                             tria_level.subdomain_ids.size(),
1427                                           0);
1428 
1429           tria_level.level_subdomain_ids.reserve(total_cells);
1430           tria_level.level_subdomain_ids.insert(
1431             tria_level.level_subdomain_ids.end(),
1432             total_cells - tria_level.level_subdomain_ids.size(),
1433             0);
1434 
1435           if (dimension < space_dimension)
1436             {
1437               tria_level.direction_flags.reserve(total_cells);
1438               tria_level.direction_flags.insert(
1439                 tria_level.direction_flags.end(),
1440                 total_cells - tria_level.direction_flags.size(),
1441                 true);
1442             }
1443           else
1444             tria_level.direction_flags.clear();
1445 
1446           tria_level.parents.reserve((total_cells + 1) / 2);
1447           tria_level.parents.insert(tria_level.parents.end(),
1448                                     (total_cells + 1) / 2 -
1449                                       tria_level.parents.size(),
1450                                     -1);
1451 
1452           tria_level.neighbors.reserve(total_cells * (2 * dimension));
1453           tria_level.neighbors.insert(tria_level.neighbors.end(),
1454                                       total_cells * (2 * dimension) -
1455                                         tria_level.neighbors.size(),
1456                                       std::make_pair(-1, -1));
1457 
1458 
1459           if (tria_level.dim == 3)
1460             {
1461               tria_level.face_orientations.reserve(
1462                 total_cells * GeometryInfo<3>::faces_per_cell);
1463               tria_level.face_orientations.insert(
1464                 tria_level.face_orientations.end(),
1465                 total_cells * GeometryInfo<3>::faces_per_cell -
1466                   tria_level.face_orientations.size(),
1467                 true);
1468             }
1469 
1470           if (tria_level.dim == 2 || tria_level.dim == 3)
1471             {
1472               tria_level.reference_cell_type.reserve(total_cells);
1473               tria_level.reference_cell_type.insert(
1474                 tria_level.reference_cell_type.end(),
1475                 total_cells - tria_level.reference_cell_type.size(),
1476                 tria_level.dim == 2 ? ReferenceCell::Type::Quad :
1477                                       ReferenceCell::Type::Hex);
1478             }
1479         }
1480     }
1481 
1482 
1483 
1484     /**
1485      * Exception
1486      */
1487     DeclException2(ExcMemoryInexact,
1488                    int,
1489                    int,
1490                    << "The containers have sizes " << arg1 << " and " << arg2
1491                    << ", which is not as expected.");
1492 
1493     /**
1494      * Check the memory consistency of the different containers. Should only
1495      * be called with the preprocessor flag @p DEBUG set. The function
1496      * should be called from the functions of the higher TriaLevel classes.
1497      */
1498     void
monitor_memory(const TriaLevel & tria_level,const unsigned int true_dimension)1499     monitor_memory(const TriaLevel &  tria_level,
1500                    const unsigned int true_dimension)
1501     {
1502       (void)tria_level;
1503       (void)true_dimension;
1504       Assert(2 * true_dimension * tria_level.refine_flags.size() ==
1505                tria_level.neighbors.size(),
1506              ExcMemoryInexact(tria_level.refine_flags.size(),
1507                               tria_level.neighbors.size()));
1508       Assert(2 * true_dimension * tria_level.coarsen_flags.size() ==
1509                tria_level.neighbors.size(),
1510              ExcMemoryInexact(tria_level.coarsen_flags.size(),
1511                               tria_level.neighbors.size()));
1512     }
1513 
1514 
1515 
1516     /**
1517      * Reserve space for TriaObjects. Details:
1518      *
1519      * Assert that enough space is allocated to accommodate
1520      * <code>new_objs_in_pairs</code> new objects, stored in pairs, plus
1521      * <code>new_obj_single</code> stored individually. This function does
1522      * not only call <code>vector::reserve()</code>, but does really append
1523      * the needed elements.
1524      *
1525      * In 2D e.g. refined lines have to be stored in pairs, whereas new
1526      * lines in the interior of refined cells can be stored as single lines.
1527      */
1528     void
reserve_space(TriaObjects & tria_objects,const unsigned int new_objects_in_pairs,const unsigned int new_objects_single=0)1529     reserve_space(TriaObjects &      tria_objects,
1530                   const unsigned int new_objects_in_pairs,
1531                   const unsigned int new_objects_single = 0)
1532     {
1533       if (tria_objects.structdim <= 2)
1534         {
1535           Assert(new_objects_in_pairs % 2 == 0, ExcInternalError());
1536 
1537           tria_objects.next_free_single               = 0;
1538           tria_objects.next_free_pair                 = 0;
1539           tria_objects.reverse_order_next_free_single = false;
1540 
1541           // count the number of objects, of unused single objects and of
1542           // unused pairs of objects
1543           unsigned int n_objects        = 0;
1544           unsigned int n_unused_pairs   = 0;
1545           unsigned int n_unused_singles = 0;
1546           for (unsigned int i = 0; i < tria_objects.used.size(); ++i)
1547             {
1548               if (tria_objects.used[i])
1549                 ++n_objects;
1550               else if (i + 1 < tria_objects.used.size())
1551                 {
1552                   if (tria_objects.used[i + 1])
1553                     {
1554                       ++n_unused_singles;
1555                       if (tria_objects.next_free_single == 0)
1556                         tria_objects.next_free_single = i;
1557                     }
1558                   else
1559                     {
1560                       ++n_unused_pairs;
1561                       if (tria_objects.next_free_pair == 0)
1562                         tria_objects.next_free_pair = i;
1563                       ++i;
1564                     }
1565                 }
1566               else
1567                 ++n_unused_singles;
1568             }
1569           Assert(n_objects + 2 * n_unused_pairs + n_unused_singles ==
1570                    tria_objects.used.size(),
1571                  ExcInternalError());
1572 
1573           // how many single objects are needed in addition to
1574           // n_unused_objects?
1575           const int additional_single_objects =
1576             new_objects_single - n_unused_singles;
1577 
1578           unsigned int new_size = tria_objects.used.size() +
1579                                   new_objects_in_pairs - 2 * n_unused_pairs;
1580           if (additional_single_objects > 0)
1581             new_size += additional_single_objects;
1582 
1583           // only allocate space if necessary
1584           if (new_size > tria_objects.n_objects())
1585             {
1586               unsigned int faces_per_cell        = 1;
1587               unsigned int max_children_per_cell = 1;
1588 
1589               if (tria_objects.structdim == 1)
1590                 faces_per_cell = GeometryInfo<1>::faces_per_cell;
1591               else if (tria_objects.structdim == 2)
1592                 faces_per_cell = GeometryInfo<2>::faces_per_cell;
1593               else if (tria_objects.structdim == 3)
1594                 faces_per_cell = GeometryInfo<3>::faces_per_cell;
1595               else
1596                 AssertThrow(false, ExcNotImplemented());
1597 
1598               if (tria_objects.structdim == 1)
1599                 max_children_per_cell = GeometryInfo<1>::max_children_per_cell;
1600               else if (tria_objects.structdim == 2)
1601                 max_children_per_cell = GeometryInfo<2>::max_children_per_cell;
1602               else if (tria_objects.structdim == 3)
1603                 max_children_per_cell = GeometryInfo<3>::max_children_per_cell;
1604               else
1605                 AssertThrow(false, ExcNotImplemented());
1606 
1607               tria_objects.cells.reserve(new_size * faces_per_cell);
1608               tria_objects.cells.insert(tria_objects.cells.end(),
1609                                         (new_size - tria_objects.n_objects()) *
1610                                           faces_per_cell,
1611                                         -1);
1612 
1613               tria_objects.used.reserve(new_size);
1614               tria_objects.used.insert(tria_objects.used.end(),
1615                                        new_size - tria_objects.used.size(),
1616                                        false);
1617 
1618               tria_objects.user_flags.reserve(new_size);
1619               tria_objects.user_flags.insert(tria_objects.user_flags.end(),
1620                                              new_size -
1621                                                tria_objects.user_flags.size(),
1622                                              false);
1623 
1624               const unsigned int factor = max_children_per_cell / 2;
1625               tria_objects.children.reserve(factor * new_size);
1626               tria_objects.children.insert(tria_objects.children.end(),
1627                                            factor * new_size -
1628                                              tria_objects.children.size(),
1629                                            -1);
1630 
1631               if (tria_objects.structdim > 1)
1632                 {
1633                   tria_objects.refinement_cases.reserve(new_size);
1634                   tria_objects.refinement_cases.insert(
1635                     tria_objects.refinement_cases.end(),
1636                     new_size - tria_objects.refinement_cases.size(),
1637                     /*RefinementCase::no_refinement=*/0);
1638                 }
1639 
1640               // first reserve, then resize. Otherwise the std library can
1641               // decide to allocate more entries.
1642               tria_objects.boundary_or_material_id.reserve(new_size);
1643               tria_objects.boundary_or_material_id.resize(new_size);
1644 
1645               tria_objects.user_data.reserve(new_size);
1646               tria_objects.user_data.resize(new_size);
1647 
1648               tria_objects.manifold_id.reserve(new_size);
1649               tria_objects.manifold_id.insert(tria_objects.manifold_id.end(),
1650                                               new_size -
1651                                                 tria_objects.manifold_id.size(),
1652                                               numbers::flat_manifold_id);
1653             }
1654 
1655           if (n_unused_singles == 0)
1656             {
1657               tria_objects.next_free_single               = new_size - 1;
1658               tria_objects.reverse_order_next_free_single = true;
1659             }
1660         }
1661       else
1662         {
1663           const unsigned int new_hexes = new_objects_in_pairs;
1664 
1665           const unsigned int new_size =
1666             new_hexes + std::count(tria_objects.used.begin(),
1667                                    tria_objects.used.end(),
1668                                    true);
1669 
1670           // see above...
1671           if (new_size > tria_objects.n_objects())
1672             {
1673               unsigned int faces_per_cell = 1;
1674 
1675               if (tria_objects.structdim == 1)
1676                 faces_per_cell = GeometryInfo<1>::faces_per_cell;
1677               else if (tria_objects.structdim == 2)
1678                 faces_per_cell = GeometryInfo<2>::faces_per_cell;
1679               else if (tria_objects.structdim == 3)
1680                 faces_per_cell = GeometryInfo<3>::faces_per_cell;
1681               else
1682                 AssertThrow(false, ExcNotImplemented());
1683 
1684               tria_objects.cells.reserve(new_size * faces_per_cell);
1685               tria_objects.cells.insert(tria_objects.cells.end(),
1686                                         (new_size - tria_objects.n_objects()) *
1687                                           faces_per_cell,
1688                                         -1);
1689 
1690               tria_objects.used.reserve(new_size);
1691               tria_objects.used.insert(tria_objects.used.end(),
1692                                        new_size - tria_objects.used.size(),
1693                                        false);
1694 
1695               tria_objects.user_flags.reserve(new_size);
1696               tria_objects.user_flags.insert(tria_objects.user_flags.end(),
1697                                              new_size -
1698                                                tria_objects.user_flags.size(),
1699                                              false);
1700 
1701               tria_objects.children.reserve(4 * new_size);
1702               tria_objects.children.insert(tria_objects.children.end(),
1703                                            4 * new_size -
1704                                              tria_objects.children.size(),
1705                                            -1);
1706 
1707               // for the following fields, we know exactly how many elements
1708               // we need, so first reserve then resize (resize itself, at least
1709               // with some compiler libraries, appears to round up the size it
1710               // actually reserves)
1711               tria_objects.boundary_or_material_id.reserve(new_size);
1712               tria_objects.boundary_or_material_id.resize(new_size);
1713 
1714               tria_objects.manifold_id.reserve(new_size);
1715               tria_objects.manifold_id.insert(tria_objects.manifold_id.end(),
1716                                               new_size -
1717                                                 tria_objects.manifold_id.size(),
1718                                               numbers::flat_manifold_id);
1719 
1720               tria_objects.user_data.reserve(new_size);
1721               tria_objects.user_data.resize(new_size);
1722 
1723               tria_objects.refinement_cases.reserve(new_size);
1724               tria_objects.refinement_cases.insert(
1725                 tria_objects.refinement_cases.end(),
1726                 new_size - tria_objects.refinement_cases.size(),
1727                 /*RefinementCase::no_refinement=*/0);
1728             }
1729           tria_objects.next_free_single = tria_objects.next_free_pair = 0;
1730         }
1731     }
1732 
1733 
1734 
1735     /**
1736      * Check the memory consistency of the different containers. Should only
1737      * be called with the preprocessor flag @p DEBUG set. The function
1738      * should be called from the functions of the higher TriaLevel classes.
1739      */
1740     void
monitor_memory(const TriaObjects & tria_object,const unsigned int)1741     monitor_memory(const TriaObjects &tria_object, const unsigned int)
1742     {
1743       Assert(tria_object.n_objects() == tria_object.used.size(),
1744              ExcMemoryInexact(tria_object.n_objects(),
1745                               tria_object.used.size()));
1746       Assert(tria_object.n_objects() == tria_object.user_flags.size(),
1747              ExcMemoryInexact(tria_object.n_objects(),
1748                               tria_object.user_flags.size()));
1749       Assert(tria_object.n_objects() ==
1750                tria_object.boundary_or_material_id.size(),
1751              ExcMemoryInexact(tria_object.n_objects(),
1752                               tria_object.boundary_or_material_id.size()));
1753       Assert(tria_object.n_objects() == tria_object.manifold_id.size(),
1754              ExcMemoryInexact(tria_object.n_objects(),
1755                               tria_object.manifold_id.size()));
1756       Assert(tria_object.n_objects() == tria_object.user_data.size(),
1757              ExcMemoryInexact(tria_object.n_objects(),
1758                               tria_object.user_data.size()));
1759 
1760       if (tria_object.structdim == 1)
1761         {
1762           Assert(1 * tria_object.n_objects() == tria_object.children.size(),
1763                  ExcMemoryInexact(tria_object.n_objects(),
1764                                   tria_object.children.size()));
1765         }
1766       else if (tria_object.structdim == 2)
1767         {
1768           Assert(2 * tria_object.n_objects() == tria_object.children.size(),
1769                  ExcMemoryInexact(tria_object.n_objects(),
1770                                   tria_object.children.size()));
1771         }
1772       else if (tria_object.structdim == 3)
1773         {
1774           Assert(4 * tria_object.n_objects() == tria_object.children.size(),
1775                  ExcMemoryInexact(tria_object.n_objects(),
1776                                   tria_object.children.size()));
1777         }
1778     }
1779 
1780     /**
1781      * A class into which we put many of the functions that implement
1782      * functionality of the Triangulation class. The main reason for this
1783      * class is as follows: the majority of the functions in Triangulation
1784      * need to be implemented differently for dim==1, dim==2, and
1785      * dim==3. However, their implementation is largly independent of the
1786      * spacedim template parameter. So we would like to write things like
1787      *
1788      * @code
1789      * template <int spacedim>
1790      * void Triangulation<1,spacedim>::create_triangulation (...) {...}
1791      * @endcode
1792      *
1793      * Unfortunately, C++ doesn't allow this: member functions of class
1794      * templates have to be either not specialized at all, or fully
1795      * specialized. No partial specialization is allowed. One possible
1796      * solution would be to just duplicate the bodies of the functions and
1797      * have equally implemented functions
1798      *
1799      * @code
1800      * template <>
1801      * void Triangulation<1,1>::create_triangulation (...) {...}
1802      *
1803      * template <>
1804      * void Triangulation<1,2>::create_triangulation (...) {...}
1805      * @endcode
1806      *
1807      * but that is clearly an unsatisfactory solution. Rather, what we do
1808      * is introduce the current Implementation class in which we can write
1809      * these functions as member templates over spacedim, i.e. we can have
1810      *
1811      * @code
1812      * template <int dim_, int spacedim_>
1813      * template <int spacedim>
1814      * void Triangulation<dim_,spacedim_>::Implementation::
1815      *            create_triangulation (...,
1816      *                                  Triangulation<1,spacedim> &tria ) {...}
1817      * @endcode
1818      *
1819      * The outer template parameters are here unused, only the inner
1820      * ones are of real interest.
1821      *
1822      * One may ask why we put these functions into an class rather
1823      * than an anonymous namespace, for example?
1824      *
1825      * First, these implementation functions need to be friends of the
1826      * Triangulation class. It is simpler to make the entire class a friend
1827      * rather than listing all members of an implementation namespace as
1828      * friends of the Triangulation class (there is no such thing as a "friend
1829      * namespace XXX" directive).
1830      *
1831      * Ideally, we would make this class a member class of the
1832      * Triangulation<dim,spacedim> class, since then our implementation
1833      * functions have immediate access to the alias and static functions of
1834      * the surrounding Triangulation class. I.e., we do not have to write
1835      * "typename Triangulation<dim,spacedim>::active_cell_iterator" but can
1836      * write "active_cell_iterator" right away. This is, in fact, the way it was
1837      * implemented first, but we ran into a bug in gcc4.0:
1838      * @code
1839      *  class Triangulation {
1840      *    struct Implementation;
1841      *    friend class TriaAccessor;
1842      *  };
1843      *
1844      *  class TriaAccessor {
1845      *    struct Implementation;
1846      *    friend class Triangulation;
1847      *  };
1848      * @endcode
1849      *
1850      * Here, friendship (per C++ standard) is supposed to extend to all members
1851      * of the befriended class, including its 'Implementation' member class. But
1852      * gcc4.0 gets this wrong: the members of Triangulation::Implementation are
1853      * not friends of TriaAccessor and the other way around. Ideally, one would
1854      * fix this by saying
1855      * @code
1856      *  class Triangulation {
1857      *    struct Implementation;
1858      *    friend class TriaAccessor;
1859      *    friend class TriaAccessor::Implementation;   // **
1860      *  };
1861      *
1862      *  class TriaAccessor {
1863      *    struct Implementation;
1864      *    friend class Triangulation;
1865      *    friend class Triangulation::Implementation;
1866      *  };
1867      * @endcode
1868      * but that's not legal because in ** we don't know yet that TriaAccessor
1869      * has a member class Implementation and so we can't make it a friend. The
1870      * only way forward at this point was to make Implementation a class in the
1871      * internal namespace so that we can forward declare it and make it a friend
1872      * of the respective other outer class -- not quite what we wanted but the
1873      * only way I could see to make it work...
1874      */
1875     struct Implementation
1876     {
1877       /**
1878        * For a given Triangulation, update that part of the number
1879        * cache that relates to lines. For 1d, we have to deal with the
1880        * fact that lines have levels, whereas for higher dimensions
1881        * they do not.
1882        *
1883        * The second argument indicates for how many levels the
1884        * Triangulation has objects, though the highest levels need not
1885        * contain active cells if they have previously all been
1886        * coarsened away.
1887        */
1888       template <int dim, int spacedim>
1889       static void
compute_number_cacheinternal::TriangulationImplementation::Implementation1890       compute_number_cache(
1891         const Triangulation<dim, spacedim> &                   triangulation,
1892         const unsigned int                                     level_objects,
1893         internal::TriangulationImplementation::NumberCache<1> &number_cache)
1894       {
1895         using line_iterator =
1896           typename Triangulation<dim, spacedim>::line_iterator;
1897 
1898         number_cache.n_levels = 0;
1899         if (level_objects > 0)
1900           // find the last level on which there are used cells
1901           for (unsigned int level = 0; level < level_objects; ++level)
1902             if (triangulation.begin(level) != triangulation.end(level))
1903               number_cache.n_levels = level + 1;
1904 
1905         // no cells at all?
1906         Assert(number_cache.n_levels > 0, ExcInternalError());
1907 
1908         ///////////////////////////////////
1909         // update the number of lines on the different levels in the
1910         // cache
1911         number_cache.n_lines        = 0;
1912         number_cache.n_active_lines = 0;
1913 
1914         // for 1d, lines have levels so take count the objects per
1915         // level and globally
1916         if (dim == 1)
1917           {
1918             number_cache.n_lines_level.resize(number_cache.n_levels);
1919             number_cache.n_active_lines_level.resize(number_cache.n_levels);
1920 
1921             for (unsigned int level = 0; level < number_cache.n_levels; ++level)
1922               {
1923                 // count lines on this level
1924                 number_cache.n_lines_level[level]        = 0;
1925                 number_cache.n_active_lines_level[level] = 0;
1926 
1927                 line_iterator line = triangulation.begin_line(level),
1928                               endc =
1929                                 (level == number_cache.n_levels - 1 ?
1930                                    line_iterator(triangulation.end_line()) :
1931                                    triangulation.begin_line(level + 1));
1932                 for (; line != endc; ++line)
1933                   {
1934                     ++number_cache.n_lines_level[level];
1935                     if (line->has_children() == false)
1936                       ++number_cache.n_active_lines_level[level];
1937                   }
1938 
1939                 // update total number of lines
1940                 number_cache.n_lines += number_cache.n_lines_level[level];
1941                 number_cache.n_active_lines +=
1942                   number_cache.n_active_lines_level[level];
1943               }
1944           }
1945         else
1946           {
1947             // for dim>1, there are no levels for lines
1948             number_cache.n_lines_level.clear();
1949             number_cache.n_active_lines_level.clear();
1950 
1951             line_iterator line = triangulation.begin_line(),
1952                           endc = triangulation.end_line();
1953             for (; line != endc; ++line)
1954               {
1955                 ++number_cache.n_lines;
1956                 if (line->has_children() == false)
1957                   ++number_cache.n_active_lines;
1958               }
1959           }
1960       }
1961 
1962       /**
1963        * For a given Triangulation, update that part of the number
1964        * cache that relates to quads. For 2d, we have to deal with the
1965        * fact that quads have levels, whereas for higher dimensions
1966        * they do not.
1967        *
1968        * The second argument indicates for how many levels the
1969        * Triangulation has objects, though the highest levels need not
1970        * contain active cells if they have previously all been
1971        * coarsened away.
1972        *
1973        * At the beginning of the function, we call the respective
1974        * function to update the number cache for lines.
1975        */
1976       template <int dim, int spacedim>
1977       static void
compute_number_cacheinternal::TriangulationImplementation::Implementation1978       compute_number_cache(
1979         const Triangulation<dim, spacedim> &                   triangulation,
1980         const unsigned int                                     level_objects,
1981         internal::TriangulationImplementation::NumberCache<2> &number_cache)
1982       {
1983         // update lines and n_levels in number_cache. since we don't
1984         // access any of these numbers, we can do this in the
1985         // background
1986         Threads::Task<void> update_lines = Threads::new_task(
1987           static_cast<
1988             void (*)(const Triangulation<dim, spacedim> &,
1989                      const unsigned int,
1990                      internal::TriangulationImplementation::NumberCache<1> &)>(
1991             &compute_number_cache<dim, spacedim>),
1992           triangulation,
1993           level_objects,
1994           static_cast<internal::TriangulationImplementation::NumberCache<1> &>(
1995             number_cache));
1996 
1997         using quad_iterator =
1998           typename Triangulation<dim, spacedim>::quad_iterator;
1999 
2000         ///////////////////////////////////
2001         // update the number of quads on the different levels in the
2002         // cache
2003         number_cache.n_quads        = 0;
2004         number_cache.n_active_quads = 0;
2005 
2006         // for 2d, quads have levels so take count the objects per
2007         // level and globally
2008         if (dim == 2)
2009           {
2010             // count the number of levels; the function we called above
2011             // on a separate Task for lines also does this and puts it into
2012             // number_cache.n_levels, but this datum may not yet be
2013             // available as we call the function on a separate task
2014             unsigned int n_levels = 0;
2015             if (level_objects > 0)
2016               // find the last level on which there are used cells
2017               for (unsigned int level = 0; level < level_objects; ++level)
2018                 if (triangulation.begin(level) != triangulation.end(level))
2019                   n_levels = level + 1;
2020 
2021             number_cache.n_quads_level.resize(n_levels);
2022             number_cache.n_active_quads_level.resize(n_levels);
2023 
2024             for (unsigned int level = 0; level < n_levels; ++level)
2025               {
2026                 // count quads on this level
2027                 number_cache.n_quads_level[level]        = 0;
2028                 number_cache.n_active_quads_level[level] = 0;
2029 
2030                 quad_iterator quad = triangulation.begin_quad(level),
2031                               endc =
2032                                 (level == n_levels - 1 ?
2033                                    quad_iterator(triangulation.end_quad()) :
2034                                    triangulation.begin_quad(level + 1));
2035                 for (; quad != endc; ++quad)
2036                   {
2037                     ++number_cache.n_quads_level[level];
2038                     if (quad->has_children() == false)
2039                       ++number_cache.n_active_quads_level[level];
2040                   }
2041 
2042                 // update total number of quads
2043                 number_cache.n_quads += number_cache.n_quads_level[level];
2044                 number_cache.n_active_quads +=
2045                   number_cache.n_active_quads_level[level];
2046               }
2047           }
2048         else
2049           {
2050             // for dim>2, there are no levels for quads
2051             number_cache.n_quads_level.clear();
2052             number_cache.n_active_quads_level.clear();
2053 
2054             quad_iterator quad = triangulation.begin_quad(),
2055                           endc = triangulation.end_quad();
2056             for (; quad != endc; ++quad)
2057               {
2058                 ++number_cache.n_quads;
2059                 if (quad->has_children() == false)
2060                   ++number_cache.n_active_quads;
2061               }
2062           }
2063 
2064         // wait for the background computation for lines
2065         update_lines.join();
2066       }
2067 
2068       /**
2069        * For a given Triangulation, update that part of the number
2070        * cache that relates to hexes. For 3d, we have to deal with the
2071        * fact that hexes have levels, whereas for higher dimensions
2072        * they do not.
2073        *
2074        * The second argument indicates for how many levels the
2075        * Triangulation has objects, though the highest levels need not
2076        * contain active cells if they have previously all been
2077        * coarsened away.
2078        *
2079        * At the end of the function, we call the respective function
2080        * to update the number cache for quads, which will in turn call
2081        * the respective function for lines.
2082        */
2083       template <int dim, int spacedim>
2084       static void
compute_number_cacheinternal::TriangulationImplementation::Implementation2085       compute_number_cache(
2086         const Triangulation<dim, spacedim> &                   triangulation,
2087         const unsigned int                                     level_objects,
2088         internal::TriangulationImplementation::NumberCache<3> &number_cache)
2089       {
2090         // update quads, lines and n_levels in number_cache. since we
2091         // don't access any of these numbers, we can do this in the
2092         // background
2093         Threads::Task<void> update_quads_and_lines = Threads::new_task(
2094           static_cast<
2095             void (*)(const Triangulation<dim, spacedim> &,
2096                      const unsigned int,
2097                      internal::TriangulationImplementation::NumberCache<2> &)>(
2098             &compute_number_cache<dim, spacedim>),
2099           triangulation,
2100           level_objects,
2101           static_cast<internal::TriangulationImplementation::NumberCache<2> &>(
2102             number_cache));
2103 
2104         using hex_iterator =
2105           typename Triangulation<dim, spacedim>::hex_iterator;
2106 
2107         ///////////////////////////////////
2108         // update the number of hexes on the different levels in the
2109         // cache
2110         number_cache.n_hexes        = 0;
2111         number_cache.n_active_hexes = 0;
2112 
2113         // for 3d, hexes have levels so take count the objects per
2114         // level and globally
2115         if (dim == 3)
2116           {
2117             // count the number of levels; the function we called
2118             // above on a separate Task for quads (recursively, via
2119             // the lines function) also does this and puts it into
2120             // number_cache.n_levels, but this datum may not yet be
2121             // available as we call the function on a separate task
2122             unsigned int n_levels = 0;
2123             if (level_objects > 0)
2124               // find the last level on which there are used cells
2125               for (unsigned int level = 0; level < level_objects; ++level)
2126                 if (triangulation.begin(level) != triangulation.end(level))
2127                   n_levels = level + 1;
2128 
2129             number_cache.n_hexes_level.resize(n_levels);
2130             number_cache.n_active_hexes_level.resize(n_levels);
2131 
2132             for (unsigned int level = 0; level < n_levels; ++level)
2133               {
2134                 // count hexes on this level
2135                 number_cache.n_hexes_level[level]        = 0;
2136                 number_cache.n_active_hexes_level[level] = 0;
2137 
2138                 hex_iterator hex  = triangulation.begin_hex(level),
2139                              endc = (level == n_levels - 1 ?
2140                                        hex_iterator(triangulation.end_hex()) :
2141                                        triangulation.begin_hex(level + 1));
2142                 for (; hex != endc; ++hex)
2143                   {
2144                     ++number_cache.n_hexes_level[level];
2145                     if (hex->has_children() == false)
2146                       ++number_cache.n_active_hexes_level[level];
2147                   }
2148 
2149                 // update total number of hexes
2150                 number_cache.n_hexes += number_cache.n_hexes_level[level];
2151                 number_cache.n_active_hexes +=
2152                   number_cache.n_active_hexes_level[level];
2153               }
2154           }
2155         else
2156           {
2157             // for dim>3, there are no levels for hexes
2158             number_cache.n_hexes_level.clear();
2159             number_cache.n_active_hexes_level.clear();
2160 
2161             hex_iterator hex  = triangulation.begin_hex(),
2162                          endc = triangulation.end_hex();
2163             for (; hex != endc; ++hex)
2164               {
2165                 ++number_cache.n_hexes;
2166                 if (hex->has_children() == false)
2167                   ++number_cache.n_active_hexes;
2168               }
2169           }
2170 
2171         // wait for the background computation for quads
2172         update_quads_and_lines.join();
2173       }
2174 
2175 
2176       /**
2177        * Create a triangulation from given data.
2178        */
2179       template <int dim, int spacedim>
2180       static void
create_triangulationinternal::TriangulationImplementation::Implementation2181       create_triangulation(const std::vector<Point<spacedim>> &vertices,
2182                            const std::vector<CellData<dim>> &  cells,
2183                            const SubCellData &                 subcelldata,
2184                            Triangulation<dim, spacedim> &      tria)
2185       {
2186         AssertThrow(vertices.size() > 0, ExcMessage("No vertices given"));
2187         AssertThrow(cells.size() > 0, ExcMessage("No cells given"));
2188 
2189         // Check that all cells have positive volume.
2190 #ifndef _MSC_VER
2191         // TODO: The following code does not compile with MSVC. Find a way
2192         // around it
2193         if (dim == spacedim)
2194           for (unsigned int cell_no = 0; cell_no < cells.size(); ++cell_no)
2195             {
2196               // If we should check for distorted cells, then we permit them
2197               // to exist. If a cell has negative measure, then it must be
2198               // distorted (the converse is not necessarily true); hence
2199               // throw an exception if no such cells should exist.
2200               if (tria.check_for_distorted_cells)
2201                 {
2202                   const double cell_measure = GridTools::cell_measure<spacedim>(
2203                     vertices,
2204                     ArrayView<const unsigned int>(cells[cell_no].vertices));
2205                   AssertThrow(cell_measure > 0, ExcGridHasInvalidCell(cell_no));
2206                 }
2207             }
2208 #endif
2209 
2210         // clear old content
2211         tria.levels.clear();
2212         tria.levels.push_back(
2213           std::make_unique<
2214             dealii::internal::TriangulationImplementation::TriaLevel>(dim));
2215 
2216         if (dim > 1)
2217           tria.faces = std::make_unique<
2218             dealii::internal::TriangulationImplementation::TriaFaces>(dim);
2219 
2220         // copy vertices
2221         tria.vertices = vertices;
2222         tria.vertices_used.assign(vertices.size(), true);
2223 
2224         // compute connectivity
2225         const auto connectivity   = build_connectivity<unsigned int>(cells);
2226         const unsigned int n_cell = cells.size();
2227 
2228         // TriaObjects: lines
2229         if (dim >= 2)
2230           {
2231             auto &lines_0 = tria.faces->lines; // data structure to be filled
2232 
2233             // get connectivity between quads and lines
2234             const auto &       crs     = connectivity.entity_to_entities(1, 0);
2235             const unsigned int n_lines = crs.ptr.size() - 1;
2236 
2237             // allocate memory
2238             reserve_space_(lines_0, n_lines);
2239 
2240             // loop over lines
2241             for (unsigned int line = 0; line < n_lines; ++line)
2242               for (unsigned int i = crs.ptr[line], j = 0; i < crs.ptr[line + 1];
2243                    ++i, ++j)
2244                 lines_0.cells[line * GeometryInfo<1>::faces_per_cell + j] =
2245                   crs.col[i]; // set vertex indices
2246           }
2247 
2248         // TriaObjects: quads
2249         if (dim == 3)
2250           {
2251             auto &quads_0 = tria.faces->quads; // data structures to be filled
2252             auto &faces   = *tria.faces;
2253 
2254             // get connectivity between quads and lines
2255             const auto &       crs     = connectivity.entity_to_entities(2, 1);
2256             const unsigned int n_quads = crs.ptr.size() - 1;
2257 
2258             // allocate memory
2259             reserve_space_(quads_0, n_quads);
2260             reserve_space_(faces, 2 /*structdim*/, n_quads);
2261 
2262             // loop over all quads -> entity type, line indices/orientations
2263             for (unsigned int q = 0, k = 0; q < n_quads; ++q)
2264               {
2265                 // set entity type of quads
2266                 faces.quad_reference_cell_type[q] =
2267                   connectivity.entity_types(2)[q];
2268 
2269                 // loop over all its lines
2270                 for (unsigned int i = crs.ptr[q], j = 0; i < crs.ptr[q + 1];
2271                      ++i, ++j, ++k)
2272                   {
2273                     // set line index
2274                     quads_0.cells[q * GeometryInfo<2>::faces_per_cell + j] =
2275                       crs.col[i];
2276 
2277                     // set line orientations
2278                     faces.quads_line_orientations
2279                       [q * GeometryInfo<2>::faces_per_cell + j] =
2280                       connectivity.entity_orientations(1)[k];
2281                   }
2282               }
2283           }
2284 
2285         // TriaObjects/TriaLevel: cell
2286         {
2287           auto &cells_0 = tria.levels[0]->cells; // data structure to be filled
2288           auto &level   = *tria.levels[0];
2289 
2290           // get connectivity between cells/faces and cells/cells
2291           const auto &crs = connectivity.entity_to_entities(dim, dim - 1);
2292           const auto &nei = connectivity.entity_to_entities(dim, dim);
2293 
2294           // in 2D optional: since in in pure QUAD meshes same line
2295           // orientations can be guaranteed
2296           const bool orientation_needed =
2297             dim == 3 ||
2298             (dim == 2 &&
2299              std::any_of(connectivity.entity_orientations(1).begin(),
2300                          connectivity.entity_orientations(1).end(),
2301                          [](const auto &i) { return i == 0; }));
2302 
2303           // allocate memory
2304           reserve_space_(cells_0, n_cell);
2305           reserve_space_(level, spacedim, n_cell, orientation_needed);
2306 
2307           // loop over all cells
2308           for (unsigned int cell = 0; cell < n_cell; ++cell)
2309             {
2310               // set material ids
2311               cells_0.boundary_or_material_id[cell].material_id =
2312                 cells[cell].material_id;
2313 
2314               // set manifold ids
2315               cells_0.manifold_id[cell] = cells[cell].manifold_id;
2316 
2317               // set entity types
2318               level.reference_cell_type[cell] =
2319                 connectivity.entity_types(dim)[cell];
2320 
2321               // loop over faces
2322               for (unsigned int i = crs.ptr[cell], j = 0; i < crs.ptr[cell + 1];
2323                    ++i, ++j)
2324                 {
2325                   // set neighbor if not at boundary
2326                   if (nei.col[i] != static_cast<unsigned int>(-1))
2327                     level.neighbors[cell * GeometryInfo<dim>::faces_per_cell +
2328                                     j] = {0, nei.col[i]};
2329 
2330                   // set face indices
2331                   cells_0.cells[cell * GeometryInfo<dim>::faces_per_cell + j] =
2332                     crs.col[i];
2333 
2334                   // set face orientation if needed
2335                   if (orientation_needed)
2336                     level.face_orientations
2337                       [cell * GeometryInfo<dim>::faces_per_cell + j] =
2338                       connectivity.entity_orientations(dim - 1)[i];
2339                 }
2340             }
2341         }
2342 
2343         // TriaFaces: boundary id of boundary faces
2344         if (dim > 1)
2345           {
2346             auto &bids_face = dim == 3 ?
2347                                 tria.faces->quads.boundary_or_material_id :
2348                                 tria.faces->lines.boundary_or_material_id;
2349 
2350             // count number of cells a face is belonging to
2351             std::vector<unsigned int> count(bids_face.size(), 0);
2352 
2353             // get connectivity between cells/faces
2354             const auto &crs = connectivity.entity_to_entities(dim, dim - 1);
2355 
2356             // count how many cells are adjacent to the same face
2357             for (unsigned int cell = 0; cell < cells.size(); ++cell)
2358               for (unsigned int i = crs.ptr[cell]; i < crs.ptr[cell + 1]; ++i)
2359                 count[crs.col[i]]++;
2360 
2361             // loop over all faces
2362             for (unsigned int face = 0; face < count.size(); ++face)
2363               {
2364                 if (count[face] != 1) // inner face
2365                   continue;
2366 
2367                 // boundary faces ...
2368                 bids_face[face].boundary_id = 0;
2369 
2370                 if (dim != 3)
2371                   continue;
2372 
2373                 // ... and the lines of quads in 3D
2374                 const auto &crs = connectivity.entity_to_entities(2, 1);
2375                 for (unsigned int i = crs.ptr[face]; i < crs.ptr[face + 1]; ++i)
2376                   tria.faces->lines.boundary_or_material_id[crs.col[i]]
2377                     .boundary_id = 0;
2378               }
2379           }
2380         else // 1D
2381           {
2382             static const unsigned int t_tba   = static_cast<unsigned int>(-1);
2383             static const unsigned int t_inner = static_cast<unsigned int>(-2);
2384 
2385             std::vector<unsigned int> type(vertices.size(), t_tba);
2386 
2387             const auto &crs = connectivity.entity_to_entities(1, 0);
2388 
2389             for (unsigned int cell = 0; cell < cells.size(); ++cell)
2390               for (unsigned int i = crs.ptr[cell], j = 0; i < crs.ptr[cell + 1];
2391                    ++i, ++j)
2392                 if (type[crs.col[i]] != t_inner)
2393                   type[crs.col[i]] = type[crs.col[i]] == t_tba ? j : t_inner;
2394 
2395             for (unsigned int face = 0; face < type.size(); ++face)
2396               {
2397                 // note: we also treat manifolds here!?
2398                 (*tria.vertex_to_manifold_id_map_1d)[face] =
2399                   numbers::flat_manifold_id;
2400                 if (type[face] != t_inner && type[face] != t_tba)
2401                   (*tria.vertex_to_boundary_id_map_1d)[face] = type[face];
2402               }
2403           }
2404 
2405         // SubCellData: line
2406         if (dim >= 2)
2407           process_subcelldata(connectivity.entity_to_entities(1, 0),
2408                               tria.faces->lines,
2409                               subcelldata.boundary_lines);
2410 
2411         // SubCellData: quad
2412         if (dim == 3)
2413           process_subcelldata(connectivity.entity_to_entities(2, 0),
2414                               tria.faces->quads,
2415                               subcelldata.boundary_quads);
2416       }
2417 
2418 
2419       template <int structdim, typename T>
2420       static void
process_subcelldatainternal::TriangulationImplementation::Implementation2421       process_subcelldata(
2422         const CRS<T> &                          crs,
2423         TriaObjects &                           obj,
2424         const std::vector<CellData<structdim>> &boundary_objects_in)
2425       {
2426         AssertDimension(obj.structdim, structdim);
2427 
2428         if (boundary_objects_in.size() == 0)
2429           return; // empty subcelldata -> nothing to do
2430 
2431         // pre-sort subcelldata
2432         auto boundary_objects = boundary_objects_in;
2433 
2434         // ... sort vertices
2435         for (auto &boundary_object : boundary_objects)
2436           std::sort(boundary_object.vertices.begin(),
2437                     boundary_object.vertices.end());
2438 
2439         // ... sort cells
2440         std::sort(boundary_objects.begin(),
2441                   boundary_objects.end(),
2442                   [](const auto &a, const auto &b) {
2443                     return a.vertices < b.vertices;
2444                   });
2445 
2446         unsigned int counter = 0;
2447 
2448         std::vector<unsigned int> key;
2449         key.reserve(GeometryInfo<structdim>::vertices_per_cell);
2450 
2451         for (unsigned int o = 0; o < obj.n_objects(); ++o)
2452           {
2453             auto &boundary_id = obj.boundary_or_material_id[o].boundary_id;
2454             auto &manifold_id = obj.manifold_id[o];
2455 
2456             // assert that object has not been visited yet and its value
2457             // has not been modified yet
2458             AssertThrow(boundary_id == 0 ||
2459                           boundary_id == numbers::internal_face_boundary_id,
2460                         ExcNotImplemented());
2461             AssertThrow(manifold_id == numbers::flat_manifold_id,
2462                         ExcNotImplemented());
2463 
2464             // create key
2465             key.assign(crs.col.data() + crs.ptr[o],
2466                        crs.col.data() + crs.ptr[o + 1]);
2467             std::sort(key.begin(), key.end());
2468 
2469             // is subcelldata provided? -> binary search
2470             const auto subcell_object =
2471               std::lower_bound(boundary_objects.begin(),
2472                                boundary_objects.end(),
2473                                key,
2474                                [&](const auto &cell, const auto &key) {
2475                                  return cell.vertices < key;
2476                                });
2477 
2478             // no subcelldata provided for this object
2479             if (subcell_object == boundary_objects.end() ||
2480                 subcell_object->vertices != key)
2481               continue;
2482 
2483             counter++;
2484 
2485             // set manifold id
2486             manifold_id = subcell_object->manifold_id;
2487 
2488             // set boundary id
2489             if (subcell_object->boundary_id !=
2490                 numbers::internal_face_boundary_id)
2491               {
2492                 AssertThrow(boundary_id != numbers::internal_face_boundary_id,
2493                             ExcNotImplemented());
2494                 boundary_id = subcell_object->boundary_id;
2495               }
2496           }
2497 
2498         // make sure that all subcelldata entries have been processed
2499         // TODO: this is not guaranteed, why?
2500         // AssertDimension(counter, boundary_objects_in.size());
2501       }
2502 
2503 
2504 
2505       static void
reserve_space_internal::TriangulationImplementation::Implementation2506       reserve_space_(TriaFaces &        faces,
2507                      const unsigned     structdim,
2508                      const unsigned int size)
2509       {
2510         const unsigned int dim = faces.dim;
2511 
2512         const unsigned int faces_per_cell =
2513           structdim == 1 ? GeometryInfo<1>::faces_per_cell :
2514                            (structdim == 2 ? GeometryInfo<2>::faces_per_cell :
2515                                              GeometryInfo<3>::faces_per_cell);
2516 
2517         if (dim == 3 && structdim == 2)
2518           {
2519             // quad entity types
2520             faces.quad_reference_cell_type.assign(size,
2521                                                   ReferenceCell::Type::Invalid);
2522 
2523             // quad line orientations
2524             faces.quads_line_orientations.assign(size * faces_per_cell, -1);
2525           }
2526       }
2527 
2528 
2529 
2530       static void
reserve_space_internal::TriangulationImplementation::Implementation2531       reserve_space_(TriaLevel &        level,
2532                      const unsigned int spacedim,
2533                      const unsigned int size,
2534                      const bool         orientation_needed)
2535       {
2536         const unsigned int dim = level.dim;
2537 
2538         const unsigned int faces_per_cell =
2539           dim == 1 ? GeometryInfo<1>::faces_per_cell :
2540                      (dim == 2 ? GeometryInfo<2>::faces_per_cell :
2541                                  GeometryInfo<3>::faces_per_cell);
2542 
2543         level.active_cell_indices.assign(size, -1);
2544         level.subdomain_ids.assign(size, 0);
2545         level.level_subdomain_ids.assign(size, 0);
2546 
2547         level.refine_flags.assign(size, false);
2548         level.coarsen_flags.assign(size, false);
2549 
2550         level.parents.assign((size + 1) / 2, -1);
2551 
2552         if (dim < spacedim)
2553           level.direction_flags.assign(size, true);
2554 
2555         level.neighbors.assign(size * faces_per_cell, {-1, -1});
2556 
2557         level.reference_cell_type.assign(size, ReferenceCell::Type::Invalid);
2558 
2559         if (orientation_needed)
2560           level.face_orientations.assign(size * faces_per_cell, -1);
2561       }
2562 
2563 
2564 
2565       static void
reserve_space_internal::TriangulationImplementation::Implementation2566       reserve_space_(TriaObjects &obj, const unsigned int size)
2567       {
2568         const unsigned int structdim = obj.structdim;
2569 
2570         const unsigned int max_children_per_cell =
2571           structdim == 1 ?
2572             GeometryInfo<1>::max_children_per_cell :
2573             (structdim == 2 ? GeometryInfo<2>::max_children_per_cell :
2574                               GeometryInfo<3>::max_children_per_cell);
2575         const unsigned int faces_per_cell =
2576           structdim == 1 ? GeometryInfo<1>::faces_per_cell :
2577                            (structdim == 2 ? GeometryInfo<2>::faces_per_cell :
2578                                              GeometryInfo<3>::faces_per_cell);
2579 
2580         obj.used.assign(size, true);
2581         obj.boundary_or_material_id.assign(
2582           size,
2583           internal::TriangulationImplementation::TriaObjects::
2584             BoundaryOrMaterialId());
2585         obj.manifold_id.assign(size, -1);
2586         obj.user_flags.assign(size, false);
2587         obj.user_data.resize(size);
2588 
2589         if (structdim > 1) // TODO: why?
2590           obj.refinement_cases.assign(size, 0);
2591 
2592         obj.children.assign(max_children_per_cell / 2 * size, -1);
2593 
2594         obj.cells.assign(faces_per_cell * size, -1);
2595 
2596         if (structdim <= 2)
2597           {
2598             obj.next_free_single               = size - 1;
2599             obj.next_free_pair                 = 0;
2600             obj.reverse_order_next_free_single = true;
2601           }
2602         else
2603           {
2604             obj.next_free_single = obj.next_free_pair = 0;
2605           }
2606       }
2607 
2608 
2609       /**
2610        * Actually delete a cell, or rather all
2611        * its children, which is the main step for
2612        * the coarsening process.  This is the
2613        * dimension dependent part of @p
2614        * execute_coarsening. The second argument
2615        * is a vector which gives for each line
2616        * index the number of cells containing
2617        * this line. This information is needed to
2618        * decide whether a refined line may be
2619        * coarsened or not in 3D. In 1D and 2D
2620        * this argument is not needed and thus
2621        * ignored. The same applies for the last
2622        * argument and quads instead of lines.
2623        */
2624       template <int spacedim>
delete_childreninternal::TriangulationImplementation::Implementation2625       static void delete_children(
2626         Triangulation<1, spacedim> &                        triangulation,
2627         typename Triangulation<1, spacedim>::cell_iterator &cell,
2628         std::vector<unsigned int> &,
2629         std::vector<unsigned int> &)
2630       {
2631         const unsigned int dim = 1;
2632 
2633         // first we need to reset the
2634         // neighbor pointers of the
2635         // neighbors of this cell's
2636         // children to this cell. This is
2637         // different for one dimension,
2638         // since there neighbors can have a
2639         // refinement level differing from
2640         // that of this cell's children by
2641         // more than one level.
2642 
2643         Assert(!cell->child(0)->has_children() &&
2644                  !cell->child(1)->has_children(),
2645                ExcInternalError());
2646 
2647         // first do it for the cells to the
2648         // left
2649         if (cell->neighbor(0).state() == IteratorState::valid)
2650           if (cell->neighbor(0)->has_children())
2651             {
2652               typename Triangulation<dim, spacedim>::cell_iterator neighbor =
2653                 cell->neighbor(0);
2654               Assert(neighbor->level() == cell->level(), ExcInternalError());
2655 
2656               // right child
2657               neighbor = neighbor->child(1);
2658               while (true)
2659                 {
2660                   Assert(neighbor->neighbor(1) == cell->child(0),
2661                          ExcInternalError());
2662                   neighbor->set_neighbor(1, cell);
2663 
2664                   // move on to further
2665                   // children on the
2666                   // boundary between this
2667                   // cell and its neighbor
2668                   if (neighbor->has_children())
2669                     neighbor = neighbor->child(1);
2670                   else
2671                     break;
2672                 }
2673             }
2674 
2675         // now do it for the cells to the
2676         // left
2677         if (cell->neighbor(1).state() == IteratorState::valid)
2678           if (cell->neighbor(1)->has_children())
2679             {
2680               typename Triangulation<dim, spacedim>::cell_iterator neighbor =
2681                 cell->neighbor(1);
2682               Assert(neighbor->level() == cell->level(), ExcInternalError());
2683 
2684               // left child
2685               neighbor = neighbor->child(0);
2686               while (true)
2687                 {
2688                   Assert(neighbor->neighbor(0) == cell->child(1),
2689                          ExcInternalError());
2690                   neighbor->set_neighbor(0, cell);
2691 
2692                   // move on to further
2693                   // children on the
2694                   // boundary between this
2695                   // cell and its neighbor
2696                   if (neighbor->has_children())
2697                     neighbor = neighbor->child(0);
2698                   else
2699                     break;
2700                 }
2701             }
2702 
2703 
2704         // delete the vertex which will not
2705         // be needed anymore. This vertex
2706         // is the second of the first child
2707         triangulation.vertices_used[cell->child(0)->vertex_index(1)] = false;
2708 
2709         // invalidate children.  clear user
2710         // pointers, to avoid that they may
2711         // appear at unwanted places later
2712         // on...
2713         for (unsigned int child = 0; child < cell->n_children(); ++child)
2714           {
2715             cell->child(child)->clear_user_data();
2716             cell->child(child)->clear_user_flag();
2717             cell->child(child)->clear_used_flag();
2718           }
2719 
2720 
2721         // delete pointer to children
2722         cell->clear_children();
2723         cell->clear_user_flag();
2724       }
2725 
2726 
2727 
2728       template <int spacedim>
delete_childreninternal::TriangulationImplementation::Implementation2729       static void delete_children(
2730         Triangulation<2, spacedim> &                        triangulation,
2731         typename Triangulation<2, spacedim>::cell_iterator &cell,
2732         std::vector<unsigned int> &                         line_cell_count,
2733         std::vector<unsigned int> &)
2734       {
2735         const unsigned int        dim      = 2;
2736         const RefinementCase<dim> ref_case = cell->refinement_case();
2737 
2738         Assert(line_cell_count.size() == triangulation.n_raw_lines(),
2739                ExcInternalError());
2740 
2741         // vectors to hold all lines which
2742         // may be deleted
2743         std::vector<typename Triangulation<dim, spacedim>::line_iterator>
2744           lines_to_delete(0);
2745 
2746         lines_to_delete.reserve(4 * 2 + 4);
2747 
2748         // now we decrease the counters for
2749         // lines contained in the child
2750         // cells
2751         for (unsigned int c = 0; c < cell->n_children(); ++c)
2752           {
2753             typename Triangulation<dim, spacedim>::cell_iterator child =
2754               cell->child(c);
2755             for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
2756               --line_cell_count[child->line_index(l)];
2757           }
2758 
2759 
2760         // delete the vertex which will not
2761         // be needed anymore. This vertex
2762         // is the second of the second line
2763         // of the first child, if the cell
2764         // is refined with cut_xy, else there
2765         // is no inner vertex.
2766         // additionally delete unneeded inner
2767         // lines
2768         if (ref_case == RefinementCase<dim>::cut_xy)
2769           {
2770             triangulation
2771               .vertices_used[cell->child(0)->line(1)->vertex_index(1)] = false;
2772 
2773             lines_to_delete.push_back(cell->child(0)->line(1));
2774             lines_to_delete.push_back(cell->child(0)->line(3));
2775             lines_to_delete.push_back(cell->child(3)->line(0));
2776             lines_to_delete.push_back(cell->child(3)->line(2));
2777           }
2778         else
2779           {
2780             unsigned int inner_face_no =
2781               ref_case == RefinementCase<dim>::cut_x ? 1 : 3;
2782 
2783             // the inner line will not be
2784             // used any more
2785             lines_to_delete.push_back(cell->child(0)->line(inner_face_no));
2786           }
2787 
2788         // invalidate children
2789         for (unsigned int child = 0; child < cell->n_children(); ++child)
2790           {
2791             cell->child(child)->clear_user_data();
2792             cell->child(child)->clear_user_flag();
2793             cell->child(child)->clear_used_flag();
2794           }
2795 
2796 
2797         // delete pointer to children
2798         cell->clear_children();
2799         cell->clear_refinement_case();
2800         cell->clear_user_flag();
2801 
2802         // look at the refinement of outer
2803         // lines. if nobody needs those
2804         // anymore we can add them to the
2805         // list of lines to be deleted.
2806         for (unsigned int line_no = 0;
2807              line_no < GeometryInfo<dim>::lines_per_cell;
2808              ++line_no)
2809           {
2810             typename Triangulation<dim, spacedim>::line_iterator line =
2811               cell->line(line_no);
2812 
2813             if (line->has_children())
2814               {
2815                 // if one of the cell counters is
2816                 // zero, the other has to be as well
2817 
2818                 Assert((line_cell_count[line->child_index(0)] == 0 &&
2819                         line_cell_count[line->child_index(1)] == 0) ||
2820                          (line_cell_count[line->child_index(0)] > 0 &&
2821                           line_cell_count[line->child_index(1)] > 0),
2822                        ExcInternalError());
2823 
2824                 if (line_cell_count[line->child_index(0)] == 0)
2825                   {
2826                     for (unsigned int c = 0; c < 2; ++c)
2827                       Assert(!line->child(c)->has_children(),
2828                              ExcInternalError());
2829 
2830                     // we may delete the line's
2831                     // children and the middle vertex
2832                     // as no cell references them
2833                     // anymore
2834                     triangulation
2835                       .vertices_used[line->child(0)->vertex_index(1)] = false;
2836 
2837                     lines_to_delete.push_back(line->child(0));
2838                     lines_to_delete.push_back(line->child(1));
2839 
2840                     line->clear_children();
2841                   }
2842               }
2843           }
2844 
2845         // finally, delete unneeded lines
2846 
2847         // clear user pointers, to avoid that
2848         // they may appear at unwanted places
2849         // later on...
2850         // same for user flags, then finally
2851         // delete the lines
2852         typename std::vector<
2853           typename Triangulation<dim, spacedim>::line_iterator>::iterator
2854           line    = lines_to_delete.begin(),
2855           endline = lines_to_delete.end();
2856         for (; line != endline; ++line)
2857           {
2858             (*line)->clear_user_data();
2859             (*line)->clear_user_flag();
2860             (*line)->clear_used_flag();
2861           }
2862       }
2863 
2864 
2865 
2866       template <int spacedim>
delete_childreninternal::TriangulationImplementation::Implementation2867       static void delete_children(
2868         Triangulation<3, spacedim> &                        triangulation,
2869         typename Triangulation<3, spacedim>::cell_iterator &cell,
2870         std::vector<unsigned int> &                         line_cell_count,
2871         std::vector<unsigned int> &                         quad_cell_count)
2872       {
2873         const unsigned int dim = 3;
2874 
2875         Assert(line_cell_count.size() == triangulation.n_raw_lines(),
2876                ExcInternalError());
2877         Assert(quad_cell_count.size() == triangulation.n_raw_quads(),
2878                ExcInternalError());
2879 
2880         // first of all, we store the RefineCase of
2881         // this cell
2882         const RefinementCase<dim> ref_case = cell->refinement_case();
2883         // vectors to hold all lines and quads which
2884         // may be deleted
2885         std::vector<typename Triangulation<dim, spacedim>::line_iterator>
2886           lines_to_delete(0);
2887         std::vector<typename Triangulation<dim, spacedim>::quad_iterator>
2888           quads_to_delete(0);
2889 
2890         lines_to_delete.reserve(12 * 2 + 6 * 4 + 6);
2891         quads_to_delete.reserve(6 * 4 + 12);
2892 
2893         // now we decrease the counters for lines and
2894         // quads contained in the child cells
2895         for (unsigned int c = 0; c < cell->n_children(); ++c)
2896           {
2897             typename Triangulation<dim, spacedim>::cell_iterator child =
2898               cell->child(c);
2899             for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
2900               --line_cell_count[child->line_index(l)];
2901             for (auto f : GeometryInfo<dim>::face_indices())
2902               --quad_cell_count[child->quad_index(f)];
2903           }
2904 
2905         ///////////////////////////////////////
2906         // delete interior quads and lines and the
2907         // interior vertex, depending on the
2908         // refinement case of the cell
2909         //
2910         // for append quads and lines: only append
2911         // them to the list of objects to be deleted
2912 
2913         switch (ref_case)
2914           {
2915             case RefinementCase<dim>::cut_x:
2916               quads_to_delete.push_back(cell->child(0)->face(1));
2917               break;
2918             case RefinementCase<dim>::cut_y:
2919               quads_to_delete.push_back(cell->child(0)->face(3));
2920               break;
2921             case RefinementCase<dim>::cut_z:
2922               quads_to_delete.push_back(cell->child(0)->face(5));
2923               break;
2924             case RefinementCase<dim>::cut_xy:
2925               quads_to_delete.push_back(cell->child(0)->face(1));
2926               quads_to_delete.push_back(cell->child(0)->face(3));
2927               quads_to_delete.push_back(cell->child(3)->face(0));
2928               quads_to_delete.push_back(cell->child(3)->face(2));
2929 
2930               lines_to_delete.push_back(cell->child(0)->line(11));
2931               break;
2932             case RefinementCase<dim>::cut_xz:
2933               quads_to_delete.push_back(cell->child(0)->face(1));
2934               quads_to_delete.push_back(cell->child(0)->face(5));
2935               quads_to_delete.push_back(cell->child(3)->face(0));
2936               quads_to_delete.push_back(cell->child(3)->face(4));
2937 
2938               lines_to_delete.push_back(cell->child(0)->line(5));
2939               break;
2940             case RefinementCase<dim>::cut_yz:
2941               quads_to_delete.push_back(cell->child(0)->face(3));
2942               quads_to_delete.push_back(cell->child(0)->face(5));
2943               quads_to_delete.push_back(cell->child(3)->face(2));
2944               quads_to_delete.push_back(cell->child(3)->face(4));
2945 
2946               lines_to_delete.push_back(cell->child(0)->line(7));
2947               break;
2948             case RefinementCase<dim>::cut_xyz:
2949               quads_to_delete.push_back(cell->child(0)->face(1));
2950               quads_to_delete.push_back(cell->child(2)->face(1));
2951               quads_to_delete.push_back(cell->child(4)->face(1));
2952               quads_to_delete.push_back(cell->child(6)->face(1));
2953 
2954               quads_to_delete.push_back(cell->child(0)->face(3));
2955               quads_to_delete.push_back(cell->child(1)->face(3));
2956               quads_to_delete.push_back(cell->child(4)->face(3));
2957               quads_to_delete.push_back(cell->child(5)->face(3));
2958 
2959               quads_to_delete.push_back(cell->child(0)->face(5));
2960               quads_to_delete.push_back(cell->child(1)->face(5));
2961               quads_to_delete.push_back(cell->child(2)->face(5));
2962               quads_to_delete.push_back(cell->child(3)->face(5));
2963 
2964               lines_to_delete.push_back(cell->child(0)->line(5));
2965               lines_to_delete.push_back(cell->child(0)->line(7));
2966               lines_to_delete.push_back(cell->child(0)->line(11));
2967               lines_to_delete.push_back(cell->child(7)->line(0));
2968               lines_to_delete.push_back(cell->child(7)->line(2));
2969               lines_to_delete.push_back(cell->child(7)->line(8));
2970               // delete the vertex which will not
2971               // be needed anymore. This vertex
2972               // is the vertex at the heart of
2973               // this cell, which is the sixth of
2974               // the first child
2975               triangulation.vertices_used[cell->child(0)->vertex_index(7)] =
2976                 false;
2977               break;
2978             default:
2979               // only remaining case is
2980               // no_refinement, thus an error
2981               Assert(false, ExcInternalError());
2982               break;
2983           }
2984 
2985 
2986         // invalidate children
2987         for (unsigned int child = 0; child < cell->n_children(); ++child)
2988           {
2989             cell->child(child)->clear_user_data();
2990             cell->child(child)->clear_user_flag();
2991 
2992             for (auto f : GeometryInfo<dim>::face_indices())
2993               {
2994                 // set flags denoting deviations from
2995                 // standard orientation of faces back
2996                 // to initialization values
2997                 cell->child(child)->set_face_orientation(f, true);
2998                 cell->child(child)->set_face_flip(f, false);
2999                 cell->child(child)->set_face_rotation(f, false);
3000               }
3001 
3002             cell->child(child)->clear_used_flag();
3003           }
3004 
3005 
3006         // delete pointer to children
3007         cell->clear_children();
3008         cell->clear_refinement_case();
3009         cell->clear_user_flag();
3010 
3011         // so far we only looked at inner quads,
3012         // lines and vertices. Now we have to
3013         // consider outer ones as well. here, we have
3014         // to check, whether there are other cells
3015         // still needing these objects. otherwise we
3016         // can delete them. first for quads (and
3017         // their inner lines).
3018 
3019         for (const unsigned int quad_no : GeometryInfo<dim>::face_indices())
3020           {
3021             typename Triangulation<dim, spacedim>::quad_iterator quad =
3022               cell->face(quad_no);
3023 
3024             Assert(
3025               (GeometryInfo<dim>::face_refinement_case(ref_case, quad_no) &&
3026                quad->has_children()) ||
3027                 GeometryInfo<dim>::face_refinement_case(ref_case, quad_no) ==
3028                   RefinementCase<dim - 1>::no_refinement,
3029               ExcInternalError());
3030 
3031             switch (quad->refinement_case())
3032               {
3033                 case RefinementCase<dim - 1>::no_refinement:
3034                   // nothing to do as the quad
3035                   // is not refined
3036                   break;
3037                 case RefinementCase<dim - 1>::cut_x:
3038                 case RefinementCase<dim - 1>::cut_y:
3039                   {
3040                     // if one of the cell counters is
3041                     // zero, the other has to be as
3042                     // well
3043                     Assert((quad_cell_count[quad->child_index(0)] == 0 &&
3044                             quad_cell_count[quad->child_index(1)] == 0) ||
3045                              (quad_cell_count[quad->child_index(0)] > 0 &&
3046                               quad_cell_count[quad->child_index(1)] > 0),
3047                            ExcInternalError());
3048                     // it might be, that the quad is
3049                     // refined twice anisotropically,
3050                     // first check, whether we may
3051                     // delete possible grand_children
3052                     unsigned int deleted_grandchildren       = 0;
3053                     unsigned int number_of_child_refinements = 0;
3054 
3055                     for (unsigned int c = 0; c < 2; ++c)
3056                       if (quad->child(c)->has_children())
3057                         {
3058                           ++number_of_child_refinements;
3059                           // if one of the cell counters is
3060                           // zero, the other has to be as
3061                           // well
3062                           Assert(
3063                             (quad_cell_count[quad->child(c)->child_index(0)] ==
3064                                0 &&
3065                              quad_cell_count[quad->child(c)->child_index(1)] ==
3066                                0) ||
3067                               (quad_cell_count[quad->child(c)->child_index(0)] >
3068                                  0 &&
3069                                quad_cell_count[quad->child(c)->child_index(1)] >
3070                                  0),
3071                             ExcInternalError());
3072                           if (quad_cell_count[quad->child(c)->child_index(0)] ==
3073                               0)
3074                             {
3075                               // Assert, that the two
3076                               // anisotropic
3077                               // refinements add up to
3078                               // isotropic refinement
3079                               Assert(quad->refinement_case() +
3080                                          quad->child(c)->refinement_case() ==
3081                                        RefinementCase<dim>::cut_xy,
3082                                      ExcInternalError());
3083                               // we may delete the
3084                               // quad's children and
3085                               // the inner line as no
3086                               // cell references them
3087                               // anymore
3088                               quads_to_delete.push_back(
3089                                 quad->child(c)->child(0));
3090                               quads_to_delete.push_back(
3091                                 quad->child(c)->child(1));
3092                               if (quad->child(c)->refinement_case() ==
3093                                   RefinementCase<2>::cut_x)
3094                                 lines_to_delete.push_back(
3095                                   quad->child(c)->child(0)->line(1));
3096                               else
3097                                 lines_to_delete.push_back(
3098                                   quad->child(c)->child(0)->line(3));
3099                               quad->child(c)->clear_children();
3100                               quad->child(c)->clear_refinement_case();
3101                               ++deleted_grandchildren;
3102                             }
3103                         }
3104                     // if no grandchildren are left, we
3105                     // may as well delete the
3106                     // refinement of the inner line
3107                     // between our children and the
3108                     // corresponding vertex
3109                     if (number_of_child_refinements > 0 &&
3110                         deleted_grandchildren == number_of_child_refinements)
3111                       {
3112                         typename Triangulation<dim, spacedim>::line_iterator
3113                           middle_line;
3114                         if (quad->refinement_case() == RefinementCase<2>::cut_x)
3115                           middle_line = quad->child(0)->line(1);
3116                         else
3117                           middle_line = quad->child(0)->line(3);
3118 
3119                         lines_to_delete.push_back(middle_line->child(0));
3120                         lines_to_delete.push_back(middle_line->child(1));
3121                         triangulation
3122                           .vertices_used[middle_vertex_index<dim, spacedim>(
3123                             middle_line)] = false;
3124                         middle_line->clear_children();
3125                       }
3126 
3127                     // now consider the direct children
3128                     // of the given quad
3129                     if (quad_cell_count[quad->child_index(0)] == 0)
3130                       {
3131                         // we may delete the quad's
3132                         // children and the inner line
3133                         // as no cell references them
3134                         // anymore
3135                         quads_to_delete.push_back(quad->child(0));
3136                         quads_to_delete.push_back(quad->child(1));
3137                         if (quad->refinement_case() == RefinementCase<2>::cut_x)
3138                           lines_to_delete.push_back(quad->child(0)->line(1));
3139                         else
3140                           lines_to_delete.push_back(quad->child(0)->line(3));
3141 
3142                         // if the counters just dropped
3143                         // to zero, otherwise the
3144                         // children would have been
3145                         // deleted earlier, then this
3146                         // cell's children must have
3147                         // contained the anisotropic
3148                         // quad children. thus, if
3149                         // those have again anisotropic
3150                         // children, which are in
3151                         // effect isotropic children of
3152                         // the original quad, those are
3153                         // still needed by a
3154                         // neighboring cell and we
3155                         // cannot delete them. instead,
3156                         // we have to reset this quad's
3157                         // refine case to isotropic and
3158                         // set the children
3159                         // accordingly.
3160                         if (quad->child(0)->has_children())
3161                           if (quad->refinement_case() ==
3162                               RefinementCase<2>::cut_x)
3163                             {
3164                               // now evereything is
3165                               // quite complicated. we
3166                               // have the children
3167                               // numbered according to
3168                               //
3169                               // *---*---*
3170                               // |n+1|m+1|
3171                               // *---*---*
3172                               // | n | m |
3173                               // *---*---*
3174                               //
3175                               // from the original
3176                               // anisotropic
3177                               // refinement. we have to
3178                               // reorder them as
3179                               //
3180                               // *---*---*
3181                               // | m |m+1|
3182                               // *---*---*
3183                               // | n |n+1|
3184                               // *---*---*
3185                               //
3186                               // for isotropic refinement.
3187                               //
3188                               // this is a bit ugly, of
3189                               // course: loop over all
3190                               // cells on all levels
3191                               // and look for faces n+1
3192                               // (switch_1) and m
3193                               // (switch_2).
3194                               const typename Triangulation<dim, spacedim>::
3195                                 quad_iterator switch_1 =
3196                                                 quad->child(0)->child(1),
3197                                               switch_2 =
3198                                                 quad->child(1)->child(0);
3199 
3200                               Assert(!switch_1->has_children(),
3201                                      ExcInternalError());
3202                               Assert(!switch_2->has_children(),
3203                                      ExcInternalError());
3204 
3205                               const int switch_1_index = switch_1->index();
3206                               const int switch_2_index = switch_2->index();
3207                               for (unsigned int l = 0;
3208                                    l < triangulation.levels.size();
3209                                    ++l)
3210                                 for (unsigned int h = 0;
3211                                      h <
3212                                      triangulation.levels[l]->cells.n_objects();
3213                                      ++h)
3214                                   for (const unsigned int q :
3215                                        GeometryInfo<dim>::face_indices())
3216                                     {
3217                                       const int index =
3218                                         triangulation.levels[l]
3219                                           ->cells.get_bounding_object_indices(
3220                                             h)[q];
3221                                       if (index == switch_1_index)
3222                                         triangulation.levels[l]
3223                                           ->cells.get_bounding_object_indices(
3224                                             h)[q] = switch_2_index;
3225                                       else if (index == switch_2_index)
3226                                         triangulation.levels[l]
3227                                           ->cells.get_bounding_object_indices(
3228                                             h)[q] = switch_1_index;
3229                                     }
3230                               // now we have to copy
3231                               // all information of the
3232                               // two quads
3233                               const int switch_1_lines[4] = {
3234                                 static_cast<signed int>(
3235                                   switch_1->line_index(0)),
3236                                 static_cast<signed int>(
3237                                   switch_1->line_index(1)),
3238                                 static_cast<signed int>(
3239                                   switch_1->line_index(2)),
3240                                 static_cast<signed int>(
3241                                   switch_1->line_index(3))};
3242                               const bool switch_1_line_orientations[4] = {
3243                                 switch_1->line_orientation(0),
3244                                 switch_1->line_orientation(1),
3245                                 switch_1->line_orientation(2),
3246                                 switch_1->line_orientation(3)};
3247                               const types::boundary_id switch_1_boundary_id =
3248                                 switch_1->boundary_id();
3249                               const unsigned int switch_1_user_index =
3250                                 switch_1->user_index();
3251                               const bool switch_1_user_flag =
3252                                 switch_1->user_flag_set();
3253 
3254                               switch_1->set_bounding_object_indices(
3255                                 {switch_2->line_index(0),
3256                                  switch_2->line_index(1),
3257                                  switch_2->line_index(2),
3258                                  switch_2->line_index(3)});
3259                               switch_1->set_line_orientation(
3260                                 0, switch_2->line_orientation(0));
3261                               switch_1->set_line_orientation(
3262                                 1, switch_2->line_orientation(1));
3263                               switch_1->set_line_orientation(
3264                                 2, switch_2->line_orientation(2));
3265                               switch_1->set_line_orientation(
3266                                 3, switch_2->line_orientation(3));
3267                               switch_1->set_boundary_id_internal(
3268                                 switch_2->boundary_id());
3269                               switch_1->set_manifold_id(
3270                                 switch_2->manifold_id());
3271                               switch_1->set_user_index(switch_2->user_index());
3272                               if (switch_2->user_flag_set())
3273                                 switch_1->set_user_flag();
3274                               else
3275                                 switch_1->clear_user_flag();
3276 
3277                               switch_2->set_bounding_object_indices(
3278                                 {switch_1_lines[0],
3279                                  switch_1_lines[1],
3280                                  switch_1_lines[2],
3281                                  switch_1_lines[3]});
3282                               switch_2->set_line_orientation(
3283                                 0, switch_1_line_orientations[0]);
3284                               switch_2->set_line_orientation(
3285                                 1, switch_1_line_orientations[1]);
3286                               switch_2->set_line_orientation(
3287                                 2, switch_1_line_orientations[2]);
3288                               switch_2->set_line_orientation(
3289                                 3, switch_1_line_orientations[3]);
3290                               switch_2->set_boundary_id_internal(
3291                                 switch_1_boundary_id);
3292                               switch_2->set_manifold_id(
3293                                 switch_1->manifold_id());
3294                               switch_2->set_user_index(switch_1_user_index);
3295                               if (switch_1_user_flag)
3296                                 switch_2->set_user_flag();
3297                               else
3298                                 switch_2->clear_user_flag();
3299 
3300                               const unsigned int child_0 =
3301                                 quad->child(0)->child_index(0);
3302                               const unsigned int child_2 =
3303                                 quad->child(1)->child_index(0);
3304                               quad->clear_children();
3305                               quad->clear_refinement_case();
3306                               quad->set_refinement_case(
3307                                 RefinementCase<2>::cut_xy);
3308                               quad->set_children(0, child_0);
3309                               quad->set_children(2, child_2);
3310                               std::swap(quad_cell_count[child_0 + 1],
3311                                         quad_cell_count[child_2]);
3312                             }
3313                           else
3314                             {
3315                               // the face was refined
3316                               // with cut_y, thus the
3317                               // children are already
3318                               // in correct order. we
3319                               // only have to set them
3320                               // correctly, deleting
3321                               // the indirection of two
3322                               // anisotropic refinement
3323                               // and going directly
3324                               // from the quad to
3325                               // isotropic children
3326                               const unsigned int child_0 =
3327                                 quad->child(0)->child_index(0);
3328                               const unsigned int child_2 =
3329                                 quad->child(1)->child_index(0);
3330                               quad->clear_children();
3331                               quad->clear_refinement_case();
3332                               quad->set_refinement_case(
3333                                 RefinementCase<2>::cut_xy);
3334                               quad->set_children(0, child_0);
3335                               quad->set_children(2, child_2);
3336                             }
3337                         else
3338                           {
3339                             quad->clear_children();
3340                             quad->clear_refinement_case();
3341                           }
3342                       }
3343                     break;
3344                   }
3345                 case RefinementCase<dim - 1>::cut_xy:
3346                   {
3347                     // if one of the cell counters is
3348                     // zero, the others have to be as
3349                     // well
3350 
3351                     Assert((quad_cell_count[quad->child_index(0)] == 0 &&
3352                             quad_cell_count[quad->child_index(1)] == 0 &&
3353                             quad_cell_count[quad->child_index(2)] == 0 &&
3354                             quad_cell_count[quad->child_index(3)] == 0) ||
3355                              (quad_cell_count[quad->child_index(0)] > 0 &&
3356                               quad_cell_count[quad->child_index(1)] > 0 &&
3357                               quad_cell_count[quad->child_index(2)] > 0 &&
3358                               quad_cell_count[quad->child_index(3)] > 0),
3359                            ExcInternalError());
3360 
3361                     if (quad_cell_count[quad->child_index(0)] == 0)
3362                       {
3363                         // we may delete the quad's
3364                         // children, the inner lines
3365                         // and the middle vertex as no
3366                         // cell references them anymore
3367                         lines_to_delete.push_back(quad->child(0)->line(1));
3368                         lines_to_delete.push_back(quad->child(3)->line(0));
3369                         lines_to_delete.push_back(quad->child(0)->line(3));
3370                         lines_to_delete.push_back(quad->child(3)->line(2));
3371 
3372                         for (unsigned int child = 0; child < quad->n_children();
3373                              ++child)
3374                           quads_to_delete.push_back(quad->child(child));
3375 
3376                         triangulation
3377                           .vertices_used[quad->child(0)->vertex_index(3)] =
3378                           false;
3379 
3380                         quad->clear_children();
3381                         quad->clear_refinement_case();
3382                       }
3383                   }
3384                   break;
3385 
3386                 default:
3387                   Assert(false, ExcInternalError());
3388                   break;
3389               }
3390           }
3391 
3392         // now we repeat a similar procedure
3393         // for the outer lines of this cell.
3394 
3395         // if in debug mode: check that each
3396         // of the lines for which we consider
3397         // deleting the children in fact has
3398         // children (the bits/coarsening_3d
3399         // test tripped over this initially)
3400         for (unsigned int line_no = 0;
3401              line_no < GeometryInfo<dim>::lines_per_cell;
3402              ++line_no)
3403           {
3404             typename Triangulation<dim, spacedim>::line_iterator line =
3405               cell->line(line_no);
3406 
3407             Assert(
3408               (GeometryInfo<dim>::line_refinement_case(ref_case, line_no) &&
3409                line->has_children()) ||
3410                 GeometryInfo<dim>::line_refinement_case(ref_case, line_no) ==
3411                   RefinementCase<1>::no_refinement,
3412               ExcInternalError());
3413 
3414             if (line->has_children())
3415               {
3416                 // if one of the cell counters is
3417                 // zero, the other has to be as well
3418 
3419                 Assert((line_cell_count[line->child_index(0)] == 0 &&
3420                         line_cell_count[line->child_index(1)] == 0) ||
3421                          (line_cell_count[line->child_index(0)] > 0 &&
3422                           line_cell_count[line->child_index(1)] > 0),
3423                        ExcInternalError());
3424 
3425                 if (line_cell_count[line->child_index(0)] == 0)
3426                   {
3427                     for (unsigned int c = 0; c < 2; ++c)
3428                       Assert(!line->child(c)->has_children(),
3429                              ExcInternalError());
3430 
3431                     // we may delete the line's
3432                     // children and the middle vertex
3433                     // as no cell references them
3434                     // anymore
3435                     triangulation
3436                       .vertices_used[line->child(0)->vertex_index(1)] = false;
3437 
3438                     lines_to_delete.push_back(line->child(0));
3439                     lines_to_delete.push_back(line->child(1));
3440 
3441                     line->clear_children();
3442                   }
3443               }
3444           }
3445 
3446         // finally, delete unneeded quads and lines
3447 
3448         // clear user pointers, to avoid that
3449         // they may appear at unwanted places
3450         // later on...
3451         // same for user flags, then finally
3452         // delete the quads and lines
3453         typename std::vector<
3454           typename Triangulation<dim, spacedim>::line_iterator>::iterator
3455           line    = lines_to_delete.begin(),
3456           endline = lines_to_delete.end();
3457         for (; line != endline; ++line)
3458           {
3459             (*line)->clear_user_data();
3460             (*line)->clear_user_flag();
3461             (*line)->clear_used_flag();
3462           }
3463 
3464         typename std::vector<
3465           typename Triangulation<dim, spacedim>::quad_iterator>::iterator
3466           quad    = quads_to_delete.begin(),
3467           endquad = quads_to_delete.end();
3468         for (; quad != endquad; ++quad)
3469           {
3470             (*quad)->clear_user_data();
3471             (*quad)->clear_children();
3472             (*quad)->clear_refinement_case();
3473             (*quad)->clear_user_flag();
3474             (*quad)->clear_used_flag();
3475           }
3476       }
3477 
3478 
3479       /**
3480        * Create the children of a 2d
3481        * cell. The arguments indicate
3482        * the next free spots in the
3483        * vertices, lines, and cells
3484        * arrays.
3485        *
3486        * The faces of the cell have to
3487        * be refined already, whereas
3488        * the inner lines in 2D will be
3489        * created in this
3490        * function. Therefore iterator
3491        * pointers into the vectors of
3492        * lines, quads and cells have to
3493        * be passed, which point at (or
3494        * "before") the reserved space.
3495        */
3496       template <int spacedim>
create_childreninternal::TriangulationImplementation::Implementation3497       static void create_children(
3498         Triangulation<2, spacedim> &triangulation,
3499         unsigned int &              next_unused_vertex,
3500         typename Triangulation<2, spacedim>::raw_line_iterator
3501           &next_unused_line,
3502         typename Triangulation<2, spacedim>::raw_cell_iterator
3503           &next_unused_cell,
3504         const typename Triangulation<2, spacedim>::cell_iterator &cell)
3505       {
3506         const unsigned int dim = 2;
3507         // clear refinement flag
3508         const RefinementCase<dim> ref_case = cell->refine_flag_set();
3509         cell->clear_refine_flag();
3510 
3511         /* For the refinement process: since we go the levels up from the
3512            lowest, there are (unlike above) only two possibilities: a neighbor
3513            cell is on the same level or one level up (in both cases, it may or
3514            may not be refined later on, but we don't care here).
3515 
3516            First:
3517            Set up an array of the 3x3 vertices, which are distributed on the
3518            cell (the array consists of indices into the @p{vertices} std::vector
3519 
3520            2--7--3
3521            |  |  |
3522            4--8--5
3523            |  |  |
3524            0--6--1
3525 
3526            note: in case of cut_x or cut_y not all these vertices are needed for
3527            the new cells
3528 
3529            Second:
3530            Set up an array of the new lines (the array consists of iterator
3531            pointers into the lines arrays)
3532 
3533            .-6-.-7-.         The directions are:  .->-.->-.
3534            1   9   3                              ^   ^   ^
3535            .-10.11-.                             .->-.->-.
3536            0   8   2                              ^   ^   ^
3537            .-4-.-5-.                              .->-.->-.
3538 
3539            cut_x:
3540            .-4-.-5-.
3541            |   |   |
3542            0   6   1
3543            |   |   |
3544            .-2-.-3-.
3545 
3546            cut_y:
3547            .---5---.
3548            1       3
3549            .---6---.
3550            0       2
3551            .---4---.
3552 
3553 
3554            Third:
3555            Set up an array of neighbors:
3556 
3557            6  7
3558            .--.--.
3559            1|  |  |3
3560            .--.--.
3561            0|  |  |2
3562            .--.--.
3563            4   5
3564 
3565            We need this array for two reasons: first to get the lines which will
3566            bound the four subcells (if the neighboring cell is refined, these
3567            lines already exist), and second to update neighborship information.
3568            Since if a neighbor is not refined, its neighborship record only
3569            points to the present, unrefined, cell rather than the children we
3570            are presently creating, we only need the neighborship information
3571            if the neighbor cells are refined. In all other cases, we store
3572            the unrefined neighbor address
3573 
3574            We also need for every neighbor (if refined) which number among its
3575            neighbors the present (unrefined) cell has, since that number is to
3576            be replaced and because that also is the number of the subline which
3577            will be the interface between that neighbor and the to be created
3578            cell. We will store this number (between 0 and 3) in the field
3579            @p{neighbors_neighbor}.
3580 
3581            It would be sufficient to use the children of the common line to the
3582            neighbor, if we only wanted to get the new sublines and the new
3583            vertex, but because we need to update the neighborship information of
3584            the two refined subcells of the neighbor, we need to search these
3585            anyway.
3586 
3587            Convention:
3588            The created children are numbered like this:
3589 
3590            .--.--.
3591            |2 . 3|
3592            .--.--.
3593            |0 | 1|
3594            .--.--.
3595         */
3596         // collect the
3597         // indices of the
3598         // eight
3599         // surrounding
3600         // vertices
3601         //   2--7--3
3602         //   |  |  |
3603         //   4--9--5
3604         //   |  |  |
3605         //   0--6--1
3606         int new_vertices[9];
3607         for (unsigned int vertex_no = 0; vertex_no < 4; ++vertex_no)
3608           new_vertices[vertex_no] = cell->vertex_index(vertex_no);
3609         for (unsigned int line_no = 0; line_no < 4; ++line_no)
3610           if (cell->line(line_no)->has_children())
3611             new_vertices[4 + line_no] =
3612               cell->line(line_no)->child(0)->vertex_index(1);
3613 
3614         if (ref_case == RefinementCase<dim>::cut_xy)
3615           {
3616             // find the next
3617             // unused vertex and
3618             // allocate it for
3619             // the new vertex we
3620             // need here
3621             while (triangulation.vertices_used[next_unused_vertex] == true)
3622               ++next_unused_vertex;
3623             Assert(
3624               next_unused_vertex < triangulation.vertices.size(),
3625               ExcMessage(
3626                 "Internal error: During refinement, the triangulation wants to access an element of the 'vertices' array but it turns out that the array is not large enough."));
3627             triangulation.vertices_used[next_unused_vertex] = true;
3628 
3629             new_vertices[8] = next_unused_vertex;
3630 
3631             // if this quad lives
3632             // in 2d, then we can
3633             // compute the new
3634             // central vertex
3635             // location just from
3636             // the surrounding
3637             // ones. If this is
3638             // not the case, then
3639             // we need to ask a
3640             // boundary object
3641             if (dim == spacedim)
3642               {
3643                 // triangulation.vertices[next_unused_vertex] = new_point;
3644                 triangulation.vertices[next_unused_vertex] = cell->center(true);
3645 
3646                 // if the user_flag is set, i.e. if the cell is at the
3647                 // boundary, use a different calculation of the middle vertex
3648                 // here. this is of advantage if the boundary is strongly
3649                 // curved (whereas the cell is not) and the cell has a high
3650                 // aspect ratio.
3651                 if (cell->user_flag_set())
3652                   {
3653                     // first reset the user_flag and then refine
3654                     cell->clear_user_flag();
3655                     triangulation.vertices[next_unused_vertex] =
3656                       cell->center(true, true);
3657                   }
3658               }
3659             else
3660               {
3661                 // if this quad lives in a higher dimensional space
3662                 // then we don't need to worry if it is at the
3663                 // boundary of the manifold -- we always have to use
3664                 // the boundary object anyway; so ignore whether the
3665                 // user flag is set or not
3666                 cell->clear_user_flag();
3667 
3668                 // determine middle vertex by transfinite interpolation to be
3669                 // consistent with what happens to quads in a Triangulation<3,
3670                 // 3> when they are refined
3671                 triangulation.vertices[next_unused_vertex] =
3672                   cell->center(true, true);
3673               }
3674           }
3675 
3676 
3677         // Now the lines:
3678         typename Triangulation<dim, spacedim>::raw_line_iterator new_lines[12];
3679         unsigned int                                             lmin = 8;
3680         unsigned int                                             lmax = 12;
3681         if (ref_case != RefinementCase<dim>::cut_xy)
3682           {
3683             lmin = 6;
3684             lmax = 7;
3685           }
3686 
3687         for (unsigned int l = lmin; l < lmax; ++l)
3688           {
3689             while (next_unused_line->used() == true)
3690               ++next_unused_line;
3691             new_lines[l] = next_unused_line;
3692             ++next_unused_line;
3693 
3694             Assert(
3695               new_lines[l]->used() == false,
3696               ExcMessage(
3697                 "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
3698           }
3699 
3700         if (ref_case == RefinementCase<dim>::cut_xy)
3701           {
3702             //   .-6-.-7-.
3703             //   1   9   3
3704             //   .-10.11-.
3705             //   0   8   2
3706             //   .-4-.-5-.
3707 
3708             // lines 0-7 already exist, create only the four interior
3709             // lines 8-11
3710             unsigned int l = 0;
3711             for (const unsigned int face_no : GeometryInfo<dim>::face_indices())
3712               for (unsigned int c = 0; c < 2; ++c, ++l)
3713                 new_lines[l] = cell->line(face_no)->child(c);
3714             Assert(l == 8, ExcInternalError());
3715 
3716             new_lines[8]->set_bounding_object_indices(
3717               {new_vertices[6], new_vertices[8]});
3718             new_lines[9]->set_bounding_object_indices(
3719               {new_vertices[8], new_vertices[7]});
3720             new_lines[10]->set_bounding_object_indices(
3721               {new_vertices[4], new_vertices[8]});
3722             new_lines[11]->set_bounding_object_indices(
3723               {new_vertices[8], new_vertices[5]});
3724           }
3725         else if (ref_case == RefinementCase<dim>::cut_x)
3726           {
3727             //   .-4-.-5-.
3728             //   |   |   |
3729             //   0   6   1
3730             //   |   |   |
3731             //   .-2-.-3-.
3732             new_lines[0] = cell->line(0);
3733             new_lines[1] = cell->line(1);
3734             new_lines[2] = cell->line(2)->child(0);
3735             new_lines[3] = cell->line(2)->child(1);
3736             new_lines[4] = cell->line(3)->child(0);
3737             new_lines[5] = cell->line(3)->child(1);
3738             new_lines[6]->set_bounding_object_indices(
3739               {new_vertices[6], new_vertices[7]});
3740           }
3741         else
3742           {
3743             Assert(ref_case == RefinementCase<dim>::cut_y, ExcInternalError());
3744             //   .---5---.
3745             //   1       3
3746             //   .---6---.
3747             //   0       2
3748             //   .---4---.
3749             new_lines[0] = cell->line(0)->child(0);
3750             new_lines[1] = cell->line(0)->child(1);
3751             new_lines[2] = cell->line(1)->child(0);
3752             new_lines[3] = cell->line(1)->child(1);
3753             new_lines[4] = cell->line(2);
3754             new_lines[5] = cell->line(3);
3755             new_lines[6]->set_bounding_object_indices(
3756               {new_vertices[4], new_vertices[5]});
3757           }
3758 
3759         for (unsigned int l = lmin; l < lmax; ++l)
3760           {
3761             new_lines[l]->set_used_flag();
3762             new_lines[l]->clear_user_flag();
3763             new_lines[l]->clear_user_data();
3764             new_lines[l]->clear_children();
3765             // interior line
3766             new_lines[l]->set_boundary_id_internal(
3767               numbers::internal_face_boundary_id);
3768             new_lines[l]->set_manifold_id(cell->manifold_id());
3769           }
3770 
3771         // Now add the four (two)
3772         // new cells!
3773         typename Triangulation<dim, spacedim>::raw_cell_iterator
3774           subcells[GeometryInfo<dim>::max_children_per_cell];
3775         while (next_unused_cell->used() == true)
3776           ++next_unused_cell;
3777 
3778         const unsigned int n_children = GeometryInfo<dim>::n_children(ref_case);
3779         for (unsigned int i = 0; i < n_children; ++i)
3780           {
3781             Assert(
3782               next_unused_cell->used() == false,
3783               ExcMessage(
3784                 "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
3785             subcells[i] = next_unused_cell;
3786             ++next_unused_cell;
3787             if (i % 2 == 1 && i < n_children - 1)
3788               while (next_unused_cell->used() == true)
3789                 ++next_unused_cell;
3790           }
3791 
3792         if (ref_case == RefinementCase<dim>::cut_xy)
3793           {
3794             // children:
3795             //   .--.--.
3796             //   |2 . 3|
3797             //   .--.--.
3798             //   |0 | 1|
3799             //   .--.--.
3800             // lines:
3801             //   .-6-.-7-.
3802             //   1   9   3
3803             //   .-10.11-.
3804             //   0   8   2
3805             //   .-4-.-5-.
3806             subcells[0]->set_bounding_object_indices({new_lines[0]->index(),
3807                                                       new_lines[8]->index(),
3808                                                       new_lines[4]->index(),
3809                                                       new_lines[10]->index()});
3810             subcells[1]->set_bounding_object_indices({new_lines[8]->index(),
3811                                                       new_lines[2]->index(),
3812                                                       new_lines[5]->index(),
3813                                                       new_lines[11]->index()});
3814             subcells[2]->set_bounding_object_indices({new_lines[1]->index(),
3815                                                       new_lines[9]->index(),
3816                                                       new_lines[10]->index(),
3817                                                       new_lines[6]->index()});
3818             subcells[3]->set_bounding_object_indices({new_lines[9]->index(),
3819                                                       new_lines[3]->index(),
3820                                                       new_lines[11]->index(),
3821                                                       new_lines[7]->index()});
3822           }
3823         else if (ref_case == RefinementCase<dim>::cut_x)
3824           {
3825             // children:
3826             //   .--.--.
3827             //   |  .  |
3828             //   .0 . 1.
3829             //   |  |  |
3830             //   .--.--.
3831             // lines:
3832             //   .-4-.-5-.
3833             //   |   |   |
3834             //   0   6   1
3835             //   |   |   |
3836             //   .-2-.-3-.
3837             subcells[0]->set_bounding_object_indices({new_lines[0]->index(),
3838                                                       new_lines[6]->index(),
3839                                                       new_lines[2]->index(),
3840                                                       new_lines[4]->index()});
3841             subcells[1]->set_bounding_object_indices({new_lines[6]->index(),
3842                                                       new_lines[1]->index(),
3843                                                       new_lines[3]->index(),
3844                                                       new_lines[5]->index()});
3845           }
3846         else
3847           {
3848             Assert(ref_case == RefinementCase<dim>::cut_y, ExcInternalError());
3849             // children:
3850             //   .-----.
3851             //   |  1  |
3852             //   .-----.
3853             //   |  0  |
3854             //   .-----.
3855             // lines:
3856             //   .---5---.
3857             //   1       3
3858             //   .---6---.
3859             //   0       2
3860             //   .---4---.
3861             subcells[0]->set_bounding_object_indices({new_lines[0]->index(),
3862                                                       new_lines[2]->index(),
3863                                                       new_lines[4]->index(),
3864                                                       new_lines[6]->index()});
3865             subcells[1]->set_bounding_object_indices({new_lines[1]->index(),
3866                                                       new_lines[3]->index(),
3867                                                       new_lines[6]->index(),
3868                                                       new_lines[5]->index()});
3869           }
3870 
3871         types::subdomain_id subdomainid = cell->subdomain_id();
3872 
3873         for (unsigned int i = 0; i < n_children; ++i)
3874           {
3875             subcells[i]->set_used_flag();
3876             subcells[i]->clear_refine_flag();
3877             subcells[i]->clear_user_flag();
3878             subcells[i]->clear_user_data();
3879             subcells[i]->clear_children();
3880             // inherit material
3881             // properties
3882             subcells[i]->set_material_id(cell->material_id());
3883             subcells[i]->set_manifold_id(cell->manifold_id());
3884             subcells[i]->set_subdomain_id(subdomainid);
3885 
3886             if (i % 2 == 0)
3887               subcells[i]->set_parent(cell->index());
3888           }
3889 
3890 
3891 
3892         // set child index for
3893         // even children children
3894         // i=0,2 (0)
3895         for (unsigned int i = 0; i < n_children / 2; ++i)
3896           cell->set_children(2 * i, subcells[2 * i]->index());
3897         // set the refine case
3898         cell->set_refinement_case(ref_case);
3899 
3900         // note that the
3901         // refinement flag was
3902         // already cleared at the
3903         // beginning of this function
3904 
3905         if (dim < spacedim)
3906           for (unsigned int c = 0; c < n_children; ++c)
3907             cell->child(c)->set_direction_flag(cell->direction_flag());
3908       }
3909 
3910 
3911 
3912       /**
3913        * A function that performs the
3914        * refinement of a triangulation in 1d.
3915        */
3916       template <int spacedim>
3917       static typename Triangulation<1, spacedim>::DistortedCellList
execute_refinementinternal::TriangulationImplementation::Implementation3918         execute_refinement(Triangulation<1, spacedim> &triangulation,
3919                            const bool /*check_for_distorted_cells*/)
3920       {
3921         const unsigned int dim = 1;
3922 
3923         // check whether a new level is needed we have to check for
3924         // this on the highest level only (on this, all used cells are
3925         // also active, so we only have to check for this)
3926         {
3927           typename Triangulation<dim, spacedim>::raw_cell_iterator
3928             cell = triangulation.begin_active(triangulation.levels.size() - 1),
3929             endc = triangulation.end();
3930           for (; cell != endc; ++cell)
3931             if (cell->used())
3932               if (cell->refine_flag_set())
3933                 {
3934                   triangulation.levels.push_back(
3935                     std::make_unique<
3936                       internal::TriangulationImplementation::TriaLevel>(dim));
3937                   break;
3938                 }
3939         }
3940 
3941 
3942         // check how much space is needed on every level we need not
3943         // check the highest level since either - on the highest level
3944         // no cells are flagged for refinement - there are, but
3945         // prepare_refinement added another empty level
3946         unsigned int needed_vertices = 0;
3947         for (int level = triangulation.levels.size() - 2; level >= 0; --level)
3948           {
3949             // count number of flagged
3950             // cells on this level
3951             unsigned int flagged_cells = 0;
3952 
3953             for (const auto &acell :
3954                  triangulation.active_cell_iterators_on_level(level))
3955               if (acell->refine_flag_set())
3956                 ++flagged_cells;
3957 
3958             // count number of used cells
3959             // on the next higher level
3960             const unsigned int used_cells =
3961               std::count(triangulation.levels[level + 1]->cells.used.begin(),
3962                          triangulation.levels[level + 1]->cells.used.end(),
3963                          true);
3964 
3965             // reserve space for the used_cells cells already existing
3966             // on the next higher level as well as for the
3967             // 2*flagged_cells that will be created on that level
3968             reserve_space(*triangulation.levels[level + 1],
3969                           used_cells + GeometryInfo<1>::max_children_per_cell *
3970                                          flagged_cells,
3971                           1,
3972                           spacedim);
3973             // reserve space for 2*flagged_cells new lines on the next
3974             // higher level
3975             reserve_space(triangulation.levels[level + 1]->cells,
3976                           GeometryInfo<1>::max_children_per_cell *
3977                             flagged_cells,
3978                           0);
3979 
3980             needed_vertices += flagged_cells;
3981           }
3982 
3983         // add to needed vertices how many
3984         // vertices are already in use
3985         needed_vertices += std::count(triangulation.vertices_used.begin(),
3986                                       triangulation.vertices_used.end(),
3987                                       true);
3988         // if we need more vertices: create them, if not: leave the
3989         // array as is, since shrinking is not really possible because
3990         // some of the vertices at the end may be in use
3991         if (needed_vertices > triangulation.vertices.size())
3992           {
3993             triangulation.vertices.resize(needed_vertices, Point<spacedim>());
3994             triangulation.vertices_used.resize(needed_vertices, false);
3995           }
3996 
3997 
3998         // Do REFINEMENT on every level; exclude highest level as
3999         // above
4000 
4001         // index of next unused vertex
4002         unsigned int next_unused_vertex = 0;
4003 
4004         for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4005           {
4006             typename Triangulation<dim, spacedim>::raw_cell_iterator
4007               next_unused_cell = triangulation.begin_raw(level + 1);
4008 
4009             for (const auto &cell :
4010                  triangulation.active_cell_iterators_on_level(level))
4011               if (cell->refine_flag_set())
4012                 {
4013                   // clear refinement flag
4014                   cell->clear_refine_flag();
4015 
4016                   // search for next unused
4017                   // vertex
4018                   while (triangulation.vertices_used[next_unused_vertex] ==
4019                          true)
4020                     ++next_unused_vertex;
4021                   Assert(
4022                     next_unused_vertex < triangulation.vertices.size(),
4023                     ExcMessage(
4024                       "Internal error: During refinement, the triangulation wants to access an element of the 'vertices' array but it turns out that the array is not large enough."));
4025 
4026                   // Now we always ask the cell itself where to put
4027                   // the new point. The cell in turn will query the
4028                   // manifold object internally.
4029                   triangulation.vertices[next_unused_vertex] =
4030                     cell->center(true);
4031 
4032                   triangulation.vertices_used[next_unused_vertex] = true;
4033 
4034                   // search for next two unused cell (++ takes care of
4035                   // the end of the vector)
4036                   typename Triangulation<dim, spacedim>::raw_cell_iterator
4037                     first_child,
4038                     second_child;
4039                   while (next_unused_cell->used() == true)
4040                     ++next_unused_cell;
4041                   first_child = next_unused_cell;
4042                   first_child->set_used_flag();
4043                   first_child->clear_user_data();
4044                   ++next_unused_cell;
4045                   Assert(
4046                     next_unused_cell->used() == false,
4047                     ExcMessage(
4048                       "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4049                   second_child = next_unused_cell;
4050                   second_child->set_used_flag();
4051                   second_child->clear_user_data();
4052 
4053                   types::subdomain_id subdomainid = cell->subdomain_id();
4054 
4055                   // insert first child
4056                   cell->set_children(0, first_child->index());
4057                   first_child->clear_children();
4058                   first_child->set_bounding_object_indices(
4059                     {cell->vertex_index(0), next_unused_vertex});
4060                   first_child->set_material_id(cell->material_id());
4061                   first_child->set_manifold_id(cell->manifold_id());
4062                   first_child->set_subdomain_id(subdomainid);
4063                   first_child->set_direction_flag(cell->direction_flag());
4064 
4065                   first_child->set_parent(cell->index());
4066 
4067                   // Set manifold id of the right face. Only do this
4068                   // on the first child.
4069                   first_child->face(1)->set_manifold_id(cell->manifold_id());
4070 
4071                   // reset neighborship info (refer to
4072                   // internal::TriangulationImplementation::TriaLevel<0> for
4073                   // details)
4074                   first_child->set_neighbor(1, second_child);
4075                   if (cell->neighbor(0).state() != IteratorState::valid)
4076                     first_child->set_neighbor(0, cell->neighbor(0));
4077                   else if (cell->neighbor(0)->is_active())
4078                     {
4079                       // since the neighbors level is always <=level,
4080                       // if the cell is active, then there are no
4081                       // cells to the left which may want to know
4082                       // about this new child cell.
4083                       Assert(cell->neighbor(0)->level() <= cell->level(),
4084                              ExcInternalError());
4085                       first_child->set_neighbor(0, cell->neighbor(0));
4086                     }
4087                   else
4088                     // left neighbor is refined
4089                     {
4090                       // set neighbor to cell on same level
4091                       const unsigned int nbnb = cell->neighbor_of_neighbor(0);
4092                       first_child->set_neighbor(0,
4093                                                 cell->neighbor(0)->child(nbnb));
4094 
4095                       // reset neighbor info of all right descendant
4096                       // of the left neighbor of cell
4097                       typename Triangulation<dim, spacedim>::cell_iterator
4098                         left_neighbor = cell->neighbor(0);
4099                       while (left_neighbor->has_children())
4100                         {
4101                           left_neighbor = left_neighbor->child(nbnb);
4102                           left_neighbor->set_neighbor(nbnb, first_child);
4103                         }
4104                     }
4105 
4106                   // insert second child
4107                   second_child->clear_children();
4108                   second_child->set_bounding_object_indices(
4109                     {next_unused_vertex, cell->vertex_index(1)});
4110                   second_child->set_neighbor(0, first_child);
4111                   second_child->set_material_id(cell->material_id());
4112                   second_child->set_manifold_id(cell->manifold_id());
4113                   second_child->set_subdomain_id(subdomainid);
4114                   second_child->set_direction_flag(cell->direction_flag());
4115 
4116                   if (cell->neighbor(1).state() != IteratorState::valid)
4117                     second_child->set_neighbor(1, cell->neighbor(1));
4118                   else if (cell->neighbor(1)->is_active())
4119                     {
4120                       Assert(cell->neighbor(1)->level() <= cell->level(),
4121                              ExcInternalError());
4122                       second_child->set_neighbor(1, cell->neighbor(1));
4123                     }
4124                   else
4125                     // right neighbor is refined same as above
4126                     {
4127                       const unsigned int nbnb = cell->neighbor_of_neighbor(1);
4128                       second_child->set_neighbor(
4129                         1, cell->neighbor(1)->child(nbnb));
4130 
4131                       typename Triangulation<dim, spacedim>::cell_iterator
4132                         right_neighbor = cell->neighbor(1);
4133                       while (right_neighbor->has_children())
4134                         {
4135                           right_neighbor = right_neighbor->child(nbnb);
4136                           right_neighbor->set_neighbor(nbnb, second_child);
4137                         }
4138                     }
4139                   // inform all listeners that cell refinement is done
4140                   triangulation.signals.post_refinement_on_cell(cell);
4141                 }
4142           }
4143 
4144         // in 1d, we can not have distorted children unless the parent
4145         // was already distorted (that is because we don't use
4146         // boundary information for 1d triangulations). so return an
4147         // empty list
4148         return typename Triangulation<1, spacedim>::DistortedCellList();
4149       }
4150 
4151 
4152       /**
4153        * A function that performs the refinement of a triangulation in
4154        * 2d.
4155        */
4156       template <int spacedim>
4157       static typename Triangulation<2, spacedim>::DistortedCellList
execute_refinementinternal::TriangulationImplementation::Implementation4158         execute_refinement(Triangulation<2, spacedim> &triangulation,
4159                            const bool check_for_distorted_cells)
4160       {
4161         const unsigned int dim = 2;
4162 
4163         // check whether a new level is needed we have to check for
4164         // this on the highest level only (on this, all used cells are
4165         // also active, so we only have to check for this)
4166         {
4167           typename Triangulation<dim, spacedim>::raw_cell_iterator
4168             cell = triangulation.begin_active(triangulation.levels.size() - 1),
4169             endc = triangulation.end();
4170           for (; cell != endc; ++cell)
4171             if (cell->used())
4172               if (cell->refine_flag_set())
4173                 {
4174                   triangulation.levels.push_back(
4175                     std::make_unique<
4176                       internal::TriangulationImplementation::TriaLevel>(dim));
4177                   break;
4178                 }
4179         }
4180 
4181         // TODO[WB]: we clear user flags and pointers of lines; we're going
4182         // to use them to flag which lines need refinement
4183         for (typename Triangulation<dim, spacedim>::line_iterator line =
4184                triangulation.begin_line();
4185              line != triangulation.end_line();
4186              ++line)
4187           {
4188             line->clear_user_flag();
4189             line->clear_user_data();
4190           }
4191         // running over all cells and lines count the number
4192         // n_single_lines of lines which can be stored as single
4193         // lines, e.g. inner lines
4194         unsigned int n_single_lines = 0;
4195 
4196         // New lines to be created: number lines which are stored in
4197         // pairs (the children of lines must be stored in pairs)
4198         unsigned int n_lines_in_pairs = 0;
4199 
4200         // check how much space is needed on every level we need not
4201         // check the highest level since either - on the highest level
4202         // no cells are flagged for refinement - there are, but
4203         // prepare_refinement added another empty level
4204         unsigned int needed_vertices = 0;
4205         for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4206           {
4207             // count number of flagged cells on this level and compute
4208             // how many new vertices and new lines will be needed
4209             unsigned int needed_cells = 0;
4210 
4211             for (const auto &cell :
4212                  triangulation.active_cell_iterators_on_level(level))
4213               if (cell->refine_flag_set())
4214                 {
4215                   if (cell->refine_flag_set() == RefinementCase<dim>::cut_xy)
4216                     {
4217                       needed_cells += 4;
4218 
4219                       // new vertex at center of cell is needed in any
4220                       // case
4221                       ++needed_vertices;
4222 
4223                       // the four inner lines can be stored as singles
4224                       n_single_lines += 4;
4225                     }
4226                   else // cut_x || cut_y
4227                     {
4228                       // set the flag showing that anisotropic
4229                       // refinement is used for at least one cell
4230                       triangulation.anisotropic_refinement = true;
4231 
4232                       needed_cells += 2;
4233                       // no vertex at center
4234 
4235                       // the inner line can be stored as single
4236                       n_single_lines += 1;
4237                     }
4238 
4239                   // mark all faces (lines) for refinement; checking
4240                   // locally whether the neighbor would also like to
4241                   // refine them is rather difficult for lines so we
4242                   // only flag them and after visiting all cells, we
4243                   // decide which lines need refinement;
4244                   for (const unsigned int line_no :
4245                        GeometryInfo<dim>::face_indices())
4246                     {
4247                       if (GeometryInfo<dim>::face_refinement_case(
4248                             cell->refine_flag_set(), line_no) ==
4249                           RefinementCase<1>::cut_x)
4250                         {
4251                           typename Triangulation<dim, spacedim>::line_iterator
4252                             line = cell->line(line_no);
4253                           if (line->has_children() == false)
4254                             line->set_user_flag();
4255                         }
4256                     }
4257                 }
4258 
4259 
4260             // count number of used cells on the next higher level
4261             const unsigned int used_cells =
4262               std::count(triangulation.levels[level + 1]->cells.used.begin(),
4263                          triangulation.levels[level + 1]->cells.used.end(),
4264                          true);
4265 
4266 
4267             // reserve space for the used_cells cells already existing
4268             // on the next higher level as well as for the
4269             // needed_cells that will be created on that level
4270             reserve_space(*triangulation.levels[level + 1],
4271                           used_cells + needed_cells,
4272                           2,
4273                           spacedim);
4274 
4275             // reserve space for needed_cells new quads on the next
4276             // higher level
4277             reserve_space(triangulation.levels[level + 1]->cells,
4278                           needed_cells,
4279                           0);
4280           }
4281 
4282         // now count the lines which were flagged for refinement
4283         for (typename Triangulation<dim, spacedim>::line_iterator line =
4284                triangulation.begin_line();
4285              line != triangulation.end_line();
4286              ++line)
4287           if (line->user_flag_set())
4288             {
4289               Assert(line->has_children() == false, ExcInternalError());
4290               n_lines_in_pairs += 2;
4291               needed_vertices += 1;
4292             }
4293         // reserve space for n_lines_in_pairs new lines.  note, that
4294         // we can't reserve space for the single lines here as well,
4295         // as all the space reserved for lines in pairs would be
4296         // counted as unused and we would end up with too little space
4297         // to store all lines. memory reservation for n_single_lines
4298         // can only be done AFTER we refined the lines of the current
4299         // cells
4300         reserve_space(triangulation.faces->lines, n_lines_in_pairs, 0);
4301 
4302         // add to needed vertices how many vertices are already in use
4303         needed_vertices += std::count(triangulation.vertices_used.begin(),
4304                                       triangulation.vertices_used.end(),
4305                                       true);
4306         // if we need more vertices: create them, if not: leave the
4307         // array as is, since shrinking is not really possible because
4308         // some of the vertices at the end may be in use
4309         if (needed_vertices > triangulation.vertices.size())
4310           {
4311             triangulation.vertices.resize(needed_vertices, Point<spacedim>());
4312             triangulation.vertices_used.resize(needed_vertices, false);
4313           }
4314 
4315 
4316         // Do REFINEMENT on every level; exclude highest level as
4317         // above
4318 
4319         //  index of next unused vertex
4320         unsigned int next_unused_vertex = 0;
4321 
4322         // first the refinement of lines.  children are stored
4323         // pairwise
4324         {
4325           // only active objects can be refined further
4326           typename Triangulation<dim, spacedim>::active_line_iterator
4327             line = triangulation.begin_active_line(),
4328             endl = triangulation.end_line();
4329           typename Triangulation<dim, spacedim>::raw_line_iterator
4330             next_unused_line = triangulation.begin_raw_line();
4331 
4332           for (; line != endl; ++line)
4333             if (line->user_flag_set())
4334               {
4335                 // this line needs to be refined
4336 
4337                 // find the next unused vertex and set it
4338                 // appropriately
4339                 while (triangulation.vertices_used[next_unused_vertex] == true)
4340                   ++next_unused_vertex;
4341                 Assert(
4342                   next_unused_vertex < triangulation.vertices.size(),
4343                   ExcMessage(
4344                     "Internal error: During refinement, the triangulation wants to access an element of the 'vertices' array but it turns out that the array is not large enough."));
4345                 triangulation.vertices_used[next_unused_vertex] = true;
4346 
4347                 triangulation.vertices[next_unused_vertex] = line->center(true);
4348 
4349                 // now that we created the right point, make up the
4350                 // two child lines.  To this end, find a pair of
4351                 // unused lines
4352                 bool pair_found = false;
4353                 (void)pair_found;
4354                 for (; next_unused_line != endl; ++next_unused_line)
4355                   if (!next_unused_line->used() &&
4356                       !(++next_unused_line)->used())
4357                     {
4358                       // go back to the first of the two unused
4359                       // lines
4360                       --next_unused_line;
4361                       pair_found = true;
4362                       break;
4363                     }
4364                 Assert(pair_found, ExcInternalError());
4365 
4366                 // there are now two consecutive unused lines, such
4367                 // that the children of a line will be consecutive.
4368                 // then set the child pointer of the present line
4369                 line->set_children(0, next_unused_line->index());
4370 
4371                 // set the two new lines
4372                 const typename Triangulation<dim, spacedim>::raw_line_iterator
4373                   children[2] = {next_unused_line, ++next_unused_line};
4374                 // some tests; if any of the iterators should be
4375                 // invalid, then already dereferencing will fail
4376                 Assert(
4377                   children[0]->used() == false,
4378                   ExcMessage(
4379                     "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4380                 Assert(
4381                   children[1]->used() == false,
4382                   ExcMessage(
4383                     "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4384 
4385                 children[0]->set_bounding_object_indices(
4386                   {line->vertex_index(0), next_unused_vertex});
4387                 children[1]->set_bounding_object_indices(
4388                   {next_unused_vertex, line->vertex_index(1)});
4389 
4390                 children[0]->set_used_flag();
4391                 children[1]->set_used_flag();
4392                 children[0]->clear_children();
4393                 children[1]->clear_children();
4394                 children[0]->clear_user_data();
4395                 children[1]->clear_user_data();
4396                 children[0]->clear_user_flag();
4397                 children[1]->clear_user_flag();
4398 
4399 
4400                 children[0]->set_boundary_id_internal(line->boundary_id());
4401                 children[1]->set_boundary_id_internal(line->boundary_id());
4402 
4403                 children[0]->set_manifold_id(line->manifold_id());
4404                 children[1]->set_manifold_id(line->manifold_id());
4405 
4406                 // finally clear flag indicating the need for
4407                 // refinement
4408                 line->clear_user_flag();
4409               }
4410         }
4411 
4412 
4413         // Now set up the new cells
4414 
4415         // reserve space for inner lines (can be stored as single
4416         // lines)
4417         reserve_space(triangulation.faces->lines, 0, n_single_lines);
4418 
4419         typename Triangulation<2, spacedim>::DistortedCellList
4420           cells_with_distorted_children;
4421 
4422         // reset next_unused_line, as now also single empty places in
4423         // the vector can be used
4424         typename Triangulation<dim, spacedim>::raw_line_iterator
4425           next_unused_line = triangulation.begin_raw_line();
4426 
4427         for (int level = 0;
4428              level < static_cast<int>(triangulation.levels.size()) - 1;
4429              ++level)
4430           {
4431             typename Triangulation<dim, spacedim>::raw_cell_iterator
4432               next_unused_cell = triangulation.begin_raw(level + 1);
4433 
4434             for (const auto &cell :
4435                  triangulation.active_cell_iterators_on_level(level))
4436               if (cell->refine_flag_set())
4437                 {
4438                   // set the user flag to indicate, that at least one
4439                   // line is at the boundary
4440 
4441                   // TODO[Tobias Leicht] find a better place to set
4442                   // this flag, so that we do not need so much time to
4443                   // check each cell here
4444                   if (cell->at_boundary())
4445                     cell->set_user_flag();
4446 
4447                   // actually set up the children and update neighbor
4448                   // information
4449                   create_children(triangulation,
4450                                   next_unused_vertex,
4451                                   next_unused_line,
4452                                   next_unused_cell,
4453                                   cell);
4454 
4455                   if (check_for_distorted_cells &&
4456                       has_distorted_children(
4457                         cell,
4458                         std::integral_constant<int, dim>(),
4459                         std::integral_constant<int, spacedim>()))
4460                     cells_with_distorted_children.distorted_cells.push_back(
4461                       cell);
4462                   // inform all listeners that cell refinement is done
4463                   triangulation.signals.post_refinement_on_cell(cell);
4464                 }
4465           }
4466 
4467         return cells_with_distorted_children;
4468       }
4469 
4470 
4471       /**
4472        * A function that performs the refinement of a triangulation in
4473        * 3d.
4474        */
4475       template <int spacedim>
4476       static typename Triangulation<3, spacedim>::DistortedCellList
execute_refinementinternal::TriangulationImplementation::Implementation4477         execute_refinement(Triangulation<3, spacedim> &triangulation,
4478                            const bool check_for_distorted_cells)
4479       {
4480         const unsigned int dim = 3;
4481 
4482         // this function probably also works for spacedim>3 but it
4483         // isn't tested. it will probably be necessary to pull new
4484         // vertices onto the manifold just as we do for the other
4485         // functions above.
4486         Assert(spacedim == 3, ExcNotImplemented());
4487 
4488         // check whether a new level is needed we have to check for
4489         // this on the highest level only (on this, all used cells are
4490         // also active, so we only have to check for this)
4491         {
4492           typename Triangulation<dim, spacedim>::raw_cell_iterator
4493             cell = triangulation.begin_active(triangulation.levels.size() - 1),
4494             endc = triangulation.end();
4495           for (; cell != endc; ++cell)
4496             if (cell->used())
4497               if (cell->refine_flag_set())
4498                 {
4499                   triangulation.levels.push_back(
4500                     std::make_unique<
4501                       internal::TriangulationImplementation::TriaLevel>(dim));
4502                   break;
4503                 }
4504         }
4505 
4506 
4507         // first clear user flags for quads and lines; we're going to
4508         // use them to flag which lines and quads need refinement
4509         triangulation.faces->quads.clear_user_data();
4510 
4511         for (typename Triangulation<dim, spacedim>::line_iterator line =
4512                triangulation.begin_line();
4513              line != triangulation.end_line();
4514              ++line)
4515           line->clear_user_flag();
4516         for (typename Triangulation<dim, spacedim>::quad_iterator quad =
4517                triangulation.begin_quad();
4518              quad != triangulation.end_quad();
4519              ++quad)
4520           quad->clear_user_flag();
4521 
4522         // create an array of face refine cases. User indices of faces
4523         // will be set to values corresponding with indices in this
4524         // array.
4525         const RefinementCase<dim - 1> face_refinement_cases[4] = {
4526           RefinementCase<dim - 1>::no_refinement,
4527           RefinementCase<dim - 1>::cut_x,
4528           RefinementCase<dim - 1>::cut_y,
4529           RefinementCase<dim - 1>::cut_xy};
4530 
4531         // check how much space is needed on every level we need not
4532         // check the highest level since either
4533         // - on the highest level no cells are flagged for refinement
4534         // - there are, but prepare_refinement added another empty
4535         // level which then is the highest level
4536 
4537         // variables to hold the number of newly to be created
4538         // vertices, lines and quads. as these are stored globally,
4539         // declare them outside the loop over al levels. we need lines
4540         // and quads in pairs for refinement of old ones and lines and
4541         // quads, that can be stored as single ones, as they are newly
4542         // created in the inside of an existing cell
4543         unsigned int needed_vertices     = 0;
4544         unsigned int needed_lines_single = 0;
4545         unsigned int needed_quads_single = 0;
4546         unsigned int needed_lines_pair   = 0;
4547         unsigned int needed_quads_pair   = 0;
4548         for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4549           {
4550             // count number of flagged cells on this level and compute
4551             // how many new vertices and new lines will be needed
4552             unsigned int new_cells = 0;
4553 
4554             for (const auto &acell :
4555                  triangulation.active_cell_iterators_on_level(level))
4556               if (acell->refine_flag_set())
4557                 {
4558                   RefinementCase<dim> ref_case = acell->refine_flag_set();
4559 
4560                   // now for interior vertices, lines and quads, which
4561                   // are needed in any case
4562                   if (ref_case == RefinementCase<dim>::cut_x ||
4563                       ref_case == RefinementCase<dim>::cut_y ||
4564                       ref_case == RefinementCase<dim>::cut_z)
4565                     {
4566                       ++needed_quads_single;
4567                       new_cells += 2;
4568                       triangulation.anisotropic_refinement = true;
4569                     }
4570                   else if (ref_case == RefinementCase<dim>::cut_xy ||
4571                            ref_case == RefinementCase<dim>::cut_xz ||
4572                            ref_case == RefinementCase<dim>::cut_yz)
4573                     {
4574                       ++needed_lines_single;
4575                       needed_quads_single += 4;
4576                       new_cells += 4;
4577                       triangulation.anisotropic_refinement = true;
4578                     }
4579                   else if (ref_case == RefinementCase<dim>::cut_xyz)
4580                     {
4581                       ++needed_vertices;
4582                       needed_lines_single += 6;
4583                       needed_quads_single += 12;
4584                       new_cells += 8;
4585                     }
4586                   else
4587                     {
4588                       // we should never get here
4589                       Assert(false, ExcInternalError());
4590                     }
4591 
4592                   // mark all faces for refinement; checking locally
4593                   // if and how the neighbor would like to refine
4594                   // these is difficult so we only flag them and after
4595                   // visiting all cells, we decide which faces need
4596                   // which refinement;
4597                   for (const unsigned int face :
4598                        GeometryInfo<dim>::face_indices())
4599                     {
4600                       typename Triangulation<dim, spacedim>::face_iterator
4601                         aface = acell->face(face);
4602                       // get the RefineCase this faces has for the
4603                       // given RefineCase of the cell
4604                       RefinementCase<dim - 1> face_ref_case =
4605                         GeometryInfo<dim>::face_refinement_case(
4606                           ref_case,
4607                           face,
4608                           acell->face_orientation(face),
4609                           acell->face_flip(face),
4610                           acell->face_rotation(face));
4611                       // only do something, if this face has to be
4612                       // refined
4613                       if (face_ref_case)
4614                         {
4615                           if (face_ref_case ==
4616                               RefinementCase<dim - 1>::isotropic_refinement)
4617                             {
4618                               if (aface->number_of_children() < 4)
4619                                 // we use user_flags to denote needed
4620                                 // isotropic refinement
4621                                 aface->set_user_flag();
4622                             }
4623                           else if (aface->refinement_case() != face_ref_case)
4624                             // we use user_indices to denote needed
4625                             // anisotropic refinement. note, that we
4626                             // can have at most one anisotropic
4627                             // refinement case for this face, as
4628                             // otherwise prepare_refinement() would
4629                             // have changed one of the cells to yield
4630                             // isotropic refinement at this
4631                             // face. therefore we set the user_index
4632                             // uniquely
4633                             {
4634                               Assert(aface->refinement_case() ==
4635                                          RefinementCase<
4636                                            dim - 1>::isotropic_refinement ||
4637                                        aface->refinement_case() ==
4638                                          RefinementCase<dim - 1>::no_refinement,
4639                                      ExcInternalError());
4640                               aface->set_user_index(face_ref_case);
4641                             }
4642                         }
4643                     } // for all faces
4644 
4645                   // flag all lines, that have to be refined
4646                   for (unsigned int line = 0;
4647                        line < GeometryInfo<dim>::lines_per_cell;
4648                        ++line)
4649                     if (GeometryInfo<dim>::line_refinement_case(ref_case,
4650                                                                 line) &&
4651                         !acell->line(line)->has_children())
4652                       acell->line(line)->set_user_flag();
4653 
4654                 } // if refine_flag set and for all cells on this level
4655 
4656 
4657             // count number of used cells on the next higher level
4658             const unsigned int used_cells =
4659               std::count(triangulation.levels[level + 1]->cells.used.begin(),
4660                          triangulation.levels[level + 1]->cells.used.end(),
4661                          true);
4662 
4663 
4664             // reserve space for the used_cells cells already existing
4665             // on the next higher level as well as for the
4666             // 8*flagged_cells that will be created on that level
4667             reserve_space(*triangulation.levels[level + 1],
4668                           used_cells + new_cells,
4669                           3,
4670                           spacedim);
4671             // reserve space for 8*flagged_cells new hexes on the next
4672             // higher level
4673             reserve_space(triangulation.levels[level + 1]->cells, new_cells);
4674           } // for all levels
4675         // now count the quads and lines which were flagged for
4676         // refinement
4677         for (typename Triangulation<dim, spacedim>::quad_iterator quad =
4678                triangulation.begin_quad();
4679              quad != triangulation.end_quad();
4680              ++quad)
4681           {
4682             if (quad->user_flag_set())
4683               {
4684                 // isotropic refinement: 1 interior vertex, 4 quads
4685                 // and 4 interior lines. we store the interior lines
4686                 // in pairs in case the face is already or will be
4687                 // refined anisotropically
4688                 needed_quads_pair += 4;
4689                 needed_lines_pair += 4;
4690                 needed_vertices += 1;
4691               }
4692             if (quad->user_index())
4693               {
4694                 // anisotropic refinement: 1 interior
4695                 // line and two quads
4696                 needed_quads_pair += 2;
4697                 needed_lines_single += 1;
4698                 // there is a kind of complicated situation here which
4699                 // requires our attention. if the quad is refined
4700                 // isotropcally, two of the interior lines will get a
4701                 // new mother line - the interior line of our
4702                 // anisotropically refined quad. if those two lines
4703                 // are not consecutive, we cannot do so and have to
4704                 // replace them by two lines that are consecutive. we
4705                 // try to avoid that situation, but it may happen
4706                 // nevertheless through repeated refinement and
4707                 // coarsening. thus we have to check here, as we will
4708                 // need some additional space to store those new lines
4709                 // in case we need them...
4710                 if (quad->has_children())
4711                   {
4712                     Assert(quad->refinement_case() ==
4713                              RefinementCase<dim - 1>::isotropic_refinement,
4714                            ExcInternalError());
4715                     if ((face_refinement_cases[quad->user_index()] ==
4716                            RefinementCase<dim - 1>::cut_x &&
4717                          (quad->child(0)->line_index(1) + 1 !=
4718                           quad->child(2)->line_index(1))) ||
4719                         (face_refinement_cases[quad->user_index()] ==
4720                            RefinementCase<dim - 1>::cut_y &&
4721                          (quad->child(0)->line_index(3) + 1 !=
4722                           quad->child(1)->line_index(3))))
4723                       needed_lines_pair += 2;
4724                   }
4725               }
4726           }
4727 
4728         for (typename Triangulation<dim, spacedim>::line_iterator line =
4729                triangulation.begin_line();
4730              line != triangulation.end_line();
4731              ++line)
4732           if (line->user_flag_set())
4733             {
4734               needed_lines_pair += 2;
4735               needed_vertices += 1;
4736             }
4737 
4738         // reserve space for needed_lines new lines stored in pairs
4739         reserve_space(triangulation.faces->lines,
4740                       needed_lines_pair,
4741                       needed_lines_single);
4742         // reserve space for needed_quads new quads stored in pairs
4743         reserve_space(*triangulation.faces,
4744                       needed_quads_pair,
4745                       needed_quads_single);
4746         reserve_space(triangulation.faces->quads,
4747                       needed_quads_pair,
4748                       needed_quads_single);
4749 
4750 
4751         // add to needed vertices how many vertices are already in use
4752         needed_vertices += std::count(triangulation.vertices_used.begin(),
4753                                       triangulation.vertices_used.end(),
4754                                       true);
4755         // if we need more vertices: create them, if not: leave the
4756         // array as is, since shrinking is not really possible because
4757         // some of the vertices at the end may be in use
4758         if (needed_vertices > triangulation.vertices.size())
4759           {
4760             triangulation.vertices.resize(needed_vertices, Point<spacedim>());
4761             triangulation.vertices_used.resize(needed_vertices, false);
4762           }
4763 
4764 
4765           ///////////////////////////////////////////
4766           // Before we start with the actual refinement, we do some
4767           // sanity checks if in debug mode. especially, we try to catch
4768           // the notorious problem with lines being twice refined,
4769           // i.e. there are cells adjacent at one line ("around the
4770           // edge", but not at a face), with two cells differing by more
4771           // than one refinement level
4772           //
4773           // this check is very simple to implement here, since we have
4774           // all lines flagged if they shall be refined
4775 #ifdef DEBUG
4776         for (const auto &cell : triangulation.active_cell_iterators())
4777           if (!cell->refine_flag_set())
4778             for (unsigned int line = 0;
4779                  line < GeometryInfo<dim>::lines_per_cell;
4780                  ++line)
4781               if (cell->line(line)->has_children())
4782                 for (unsigned int c = 0; c < 2; ++c)
4783                   Assert(cell->line(line)->child(c)->user_flag_set() == false,
4784                          ExcInternalError());
4785 #endif
4786 
4787         ///////////////////////////////////////////
4788         // Do refinement on every level
4789         //
4790         // To make life a bit easier, we first refine those lines and
4791         // quads that were flagged for refinement and then compose the
4792         // newly to be created cells.
4793         //
4794         // index of next unused vertex
4795         unsigned int next_unused_vertex = 0;
4796 
4797         // first for lines
4798         {
4799           // only active objects can be refined further
4800           typename Triangulation<dim, spacedim>::active_line_iterator
4801             line = triangulation.begin_active_line(),
4802             endl = triangulation.end_line();
4803           typename Triangulation<dim, spacedim>::raw_line_iterator
4804             next_unused_line = triangulation.begin_raw_line();
4805 
4806           for (; line != endl; ++line)
4807             if (line->user_flag_set())
4808               {
4809                 // this line needs to be refined
4810 
4811                 // find the next unused vertex and set it
4812                 // appropriately
4813                 while (triangulation.vertices_used[next_unused_vertex] == true)
4814                   ++next_unused_vertex;
4815                 Assert(
4816                   next_unused_vertex < triangulation.vertices.size(),
4817                   ExcMessage(
4818                     "Internal error: During refinement, the triangulation wants to access an element of the 'vertices' array but it turns out that the array is not large enough."));
4819                 triangulation.vertices_used[next_unused_vertex] = true;
4820 
4821                 triangulation.vertices[next_unused_vertex] = line->center(true);
4822 
4823                 // now that we created the right point, make up the
4824                 // two child lines (++ takes care of the end of the
4825                 // vector)
4826                 next_unused_line =
4827                   triangulation.faces->lines.template next_free_pair_object<1>(
4828                     triangulation);
4829                 Assert(next_unused_line.state() == IteratorState::valid,
4830                        ExcInternalError());
4831 
4832                 // now we found two consecutive unused lines, such
4833                 // that the children of a line will be consecutive.
4834                 // then set the child pointer of the present line
4835                 line->set_children(0, next_unused_line->index());
4836 
4837                 // set the two new lines
4838                 const typename Triangulation<dim, spacedim>::raw_line_iterator
4839                   children[2] = {next_unused_line, ++next_unused_line};
4840 
4841                 // some tests; if any of the iterators should be
4842                 // invalid, then already dereferencing will fail
4843                 Assert(
4844                   children[0]->used() == false,
4845                   ExcMessage(
4846                     "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4847                 Assert(
4848                   children[1]->used() == false,
4849                   ExcMessage(
4850                     "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4851 
4852                 children[0]->set_bounding_object_indices(
4853                   {line->vertex_index(0), next_unused_vertex});
4854                 children[1]->set_bounding_object_indices(
4855                   {next_unused_vertex, line->vertex_index(1)});
4856 
4857                 children[0]->set_used_flag();
4858                 children[1]->set_used_flag();
4859                 children[0]->clear_children();
4860                 children[1]->clear_children();
4861                 children[0]->clear_user_data();
4862                 children[1]->clear_user_data();
4863                 children[0]->clear_user_flag();
4864                 children[1]->clear_user_flag();
4865 
4866                 children[0]->set_boundary_id_internal(line->boundary_id());
4867                 children[1]->set_boundary_id_internal(line->boundary_id());
4868 
4869                 children[0]->set_manifold_id(line->manifold_id());
4870                 children[1]->set_manifold_id(line->manifold_id());
4871 
4872                 // finally clear flag
4873                 // indicating the need
4874                 // for refinement
4875                 line->clear_user_flag();
4876               }
4877         }
4878 
4879 
4880         ///////////////////////////////////////
4881         // now refine marked quads
4882         ///////////////////////////////////////
4883 
4884         // here we encounter several cases:
4885 
4886         // a) the quad is unrefined and shall be refined isotropically
4887 
4888         // b) the quad is unrefined and shall be refined
4889         // anisotropically
4890 
4891         // c) the quad is unrefined and shall be refined both
4892         // anisotropically and isotropically (this is reduced to case
4893         // b) and then case b) for the children again)
4894 
4895         // d) the quad is refined anisotropically and shall be refined
4896         // isotropically (this is reduced to case b) for the
4897         // anisotropic children)
4898 
4899         // e) the quad is refined isotropically and shall be refined
4900         // anisotropically (this is transformed to case c), however we
4901         // might have to renumber/rename children...)
4902 
4903         // we need a loop in cases c) and d), as the anisotropic
4904         // children migt have a lower index than the mother quad
4905         for (unsigned int loop = 0; loop < 2; ++loop)
4906           {
4907             // usually, only active objects can be refined
4908             // further. however, in cases d) and e) that is not true,
4909             // so we have to use 'normal' iterators here
4910             typename Triangulation<dim, spacedim>::quad_iterator
4911               quad = triangulation.begin_quad(),
4912               endq = triangulation.end_quad();
4913             typename Triangulation<dim, spacedim>::raw_line_iterator
4914               next_unused_line = triangulation.begin_raw_line();
4915             typename Triangulation<dim, spacedim>::raw_quad_iterator
4916               next_unused_quad = triangulation.begin_raw_quad();
4917 
4918             for (; quad != endq; ++quad)
4919               {
4920                 if (quad->user_index())
4921                   {
4922                     RefinementCase<dim - 1> aniso_quad_ref_case =
4923                       face_refinement_cases[quad->user_index()];
4924                     // there is one unlikely event here, where we
4925                     // already have refind the face: if the face was
4926                     // refined anisotropically and we want to refine
4927                     // it isotropically, both children are flagged for
4928                     // anisotropic refinement. however, if those
4929                     // children were already flagged for anisotropic
4930                     // refinement, they might already be processed and
4931                     // refined.
4932                     if (aniso_quad_ref_case == quad->refinement_case())
4933                       continue;
4934 
4935                     Assert(quad->refinement_case() ==
4936                                RefinementCase<dim - 1>::cut_xy ||
4937                              quad->refinement_case() ==
4938                                RefinementCase<dim - 1>::no_refinement,
4939                            ExcInternalError());
4940 
4941                     // this quad needs to be refined anisotropically
4942                     Assert(quad->user_index() ==
4943                                RefinementCase<dim - 1>::cut_x ||
4944                              quad->user_index() ==
4945                                RefinementCase<dim - 1>::cut_y,
4946                            ExcInternalError());
4947 
4948                     // make the new line interior to the quad
4949                     typename Triangulation<dim, spacedim>::raw_line_iterator
4950                       new_line;
4951 
4952                     new_line =
4953                       triangulation.faces->lines
4954                         .template next_free_single_object<1>(triangulation);
4955                     Assert(
4956                       new_line->used() == false,
4957                       ExcMessage(
4958                         "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4959 
4960                     // first collect the
4961                     // indices of the vertices:
4962                     // *--1--*
4963                     // |  |  |
4964                     // |  |  |    cut_x
4965                     // |  |  |
4966                     // *--0--*
4967                     //
4968                     // *-----*
4969                     // |     |
4970                     // 0-----1    cut_y
4971                     // |     |
4972                     // *-----*
4973                     unsigned int vertex_indices[2];
4974                     if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
4975                       {
4976                         vertex_indices[0] =
4977                           quad->line(2)->child(0)->vertex_index(1);
4978                         vertex_indices[1] =
4979                           quad->line(3)->child(0)->vertex_index(1);
4980                       }
4981                     else
4982                       {
4983                         vertex_indices[0] =
4984                           quad->line(0)->child(0)->vertex_index(1);
4985                         vertex_indices[1] =
4986                           quad->line(1)->child(0)->vertex_index(1);
4987                       }
4988 
4989                     new_line->set_bounding_object_indices(
4990                       {vertex_indices[0], vertex_indices[1]});
4991                     new_line->set_used_flag();
4992                     new_line->clear_user_flag();
4993                     new_line->clear_user_data();
4994                     new_line->clear_children();
4995                     new_line->set_boundary_id_internal(quad->boundary_id());
4996                     new_line->set_manifold_id(quad->manifold_id());
4997 
4998                     // child 0 and 1 of a line are switched if the
4999                     // line orientation is false. set up a miniature
5000                     // table, indicating which child to take for line
5001                     // orientations false and true. first index: child
5002                     // index in standard orientation, second index:
5003                     // line orientation
5004                     const unsigned int index[2][2] = {
5005                       {1, 0},  // child 0, line_orientation=false and true
5006                       {0, 1}}; // child 1, line_orientation=false and true
5007 
5008                     // find some space (consecutive) for the two newly
5009                     // to be created quads.
5010                     typename Triangulation<dim, spacedim>::raw_quad_iterator
5011                       new_quads[2];
5012 
5013                     next_unused_quad =
5014                       triangulation.faces->quads
5015                         .template next_free_pair_object<2>(triangulation);
5016                     new_quads[0] = next_unused_quad;
5017                     Assert(
5018                       new_quads[0]->used() == false,
5019                       ExcMessage(
5020                         "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5021 
5022                     ++next_unused_quad;
5023                     new_quads[1] = next_unused_quad;
5024                     Assert(
5025                       new_quads[1]->used() == false,
5026                       ExcMessage(
5027                         "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5028 
5029 
5030                     if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5031                       {
5032                         new_quads[0]->set_bounding_object_indices(
5033                           {static_cast<int>(quad->line_index(0)),
5034                            new_line->index(),
5035                            quad->line(2)
5036                              ->child(index[0][quad->line_orientation(2)])
5037                              ->index(),
5038                            quad->line(3)
5039                              ->child(index[0][quad->line_orientation(3)])
5040                              ->index()});
5041                         new_quads[1]->set_bounding_object_indices(
5042                           {new_line->index(),
5043                            static_cast<int>(quad->line_index(1)),
5044                            quad->line(2)
5045                              ->child(index[1][quad->line_orientation(2)])
5046                              ->index(),
5047                            quad->line(3)
5048                              ->child(index[1][quad->line_orientation(3)])
5049                              ->index()});
5050                       }
5051                     else
5052                       {
5053                         new_quads[0]->set_bounding_object_indices(
5054                           {quad->line(0)
5055                              ->child(index[0][quad->line_orientation(0)])
5056                              ->index(),
5057                            quad->line(1)
5058                              ->child(index[0][quad->line_orientation(1)])
5059                              ->index(),
5060                            static_cast<int>(quad->line_index(2)),
5061                            new_line->index()});
5062                         new_quads[1]->set_bounding_object_indices(
5063                           {quad->line(0)
5064                              ->child(index[1][quad->line_orientation(0)])
5065                              ->index(),
5066                            quad->line(1)
5067                              ->child(index[1][quad->line_orientation(1)])
5068                              ->index(),
5069                            new_line->index(),
5070                            static_cast<int>(quad->line_index(3))});
5071                       }
5072 
5073                     for (const auto &new_quad : new_quads)
5074                       {
5075                         new_quad->set_used_flag();
5076                         new_quad->clear_user_flag();
5077                         new_quad->clear_user_data();
5078                         new_quad->clear_children();
5079                         new_quad->set_boundary_id_internal(quad->boundary_id());
5080                         new_quad->set_manifold_id(quad->manifold_id());
5081                         // set all line orientations to true, change
5082                         // this after the loop, as we have to consider
5083                         // different lines for each child
5084                         for (unsigned int j = 0;
5085                              j < GeometryInfo<dim>::lines_per_face;
5086                              ++j)
5087                           new_quad->set_line_orientation(j, true);
5088                       }
5089                     // now set the line orientation of children of
5090                     // outer lines correctly, the lines in the
5091                     // interior of the refined quad are automatically
5092                     // oriented conforming to the standard
5093                     new_quads[0]->set_line_orientation(
5094                       0, quad->line_orientation(0));
5095                     new_quads[0]->set_line_orientation(
5096                       2, quad->line_orientation(2));
5097                     new_quads[1]->set_line_orientation(
5098                       1, quad->line_orientation(1));
5099                     new_quads[1]->set_line_orientation(
5100                       3, quad->line_orientation(3));
5101                     if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5102                       {
5103                         new_quads[0]->set_line_orientation(
5104                           3, quad->line_orientation(3));
5105                         new_quads[1]->set_line_orientation(
5106                           2, quad->line_orientation(2));
5107                       }
5108                     else
5109                       {
5110                         new_quads[0]->set_line_orientation(
5111                           1, quad->line_orientation(1));
5112                         new_quads[1]->set_line_orientation(
5113                           0, quad->line_orientation(0));
5114                       }
5115 
5116                     // test, whether this face is refined
5117                     // isotropically already. if so, set the correct
5118                     // children pointers.
5119                     if (quad->refinement_case() ==
5120                         RefinementCase<dim - 1>::cut_xy)
5121                       {
5122                         // we will put a new refinemnt level of
5123                         // anisotropic refinement between the
5124                         // unrefined and isotropically refined quad
5125                         // ending up with the same fine quads but
5126                         // introducing anisotropically refined ones as
5127                         // children of the unrefined quad and mother
5128                         // cells of the original fine ones.
5129 
5130                         // this process includes the creation of a new
5131                         // middle line which we will assign as the
5132                         // mother line of two of the existing inner
5133                         // lines. If those inner lines are not
5134                         // consecutive in memory, we won't find them
5135                         // later on, so we have to create new ones
5136                         // instead and replace all occurrences of the
5137                         // old ones with those new ones. As this is
5138                         // kind of ugly, we hope we don't have to do
5139                         // it often...
5140                         typename Triangulation<dim, spacedim>::line_iterator
5141                           old_child[2];
5142                         if (aniso_quad_ref_case ==
5143                             RefinementCase<dim - 1>::cut_x)
5144                           {
5145                             old_child[0] = quad->child(0)->line(1);
5146                             old_child[1] = quad->child(2)->line(1);
5147                           }
5148                         else
5149                           {
5150                             Assert(aniso_quad_ref_case ==
5151                                      RefinementCase<dim - 1>::cut_y,
5152                                    ExcInternalError());
5153 
5154                             old_child[0] = quad->child(0)->line(3);
5155                             old_child[1] = quad->child(1)->line(3);
5156                           }
5157 
5158                         if (old_child[0]->index() + 1 != old_child[1]->index())
5159                           {
5160                             // this is exactly the ugly case we taked
5161                             // about. so, no coimplaining, lets get
5162                             // two new lines and copy all info
5163                             typename Triangulation<dim,
5164                                                    spacedim>::raw_line_iterator
5165                               new_child[2];
5166 
5167                             new_child[0] = new_child[1] =
5168                               triangulation.faces->lines
5169                                 .template next_free_pair_object<1>(
5170                                   triangulation);
5171                             ++new_child[1];
5172 
5173                             new_child[0]->set_used_flag();
5174                             new_child[1]->set_used_flag();
5175 
5176                             const int old_index_0 = old_child[0]->index(),
5177                                       old_index_1 = old_child[1]->index(),
5178                                       new_index_0 = new_child[0]->index(),
5179                                       new_index_1 = new_child[1]->index();
5180 
5181                             // loop over all quads and replace the old
5182                             // lines
5183                             for (unsigned int q = 0;
5184                                  q < triangulation.faces->quads.n_objects();
5185                                  ++q)
5186                               for (unsigned int l = 0;
5187                                    l < GeometryInfo<dim>::lines_per_face;
5188                                    ++l)
5189                                 {
5190                                   const int this_index =
5191                                     triangulation.faces->quads
5192                                       .get_bounding_object_indices(q)[l];
5193                                   if (this_index == old_index_0)
5194                                     triangulation.faces->quads
5195                                       .get_bounding_object_indices(q)[l] =
5196                                       new_index_0;
5197                                   else if (this_index == old_index_1)
5198                                     triangulation.faces->quads
5199                                       .get_bounding_object_indices(q)[l] =
5200                                       new_index_1;
5201                                 }
5202                             // now we have to copy all information of
5203                             // the two lines
5204                             for (unsigned int i = 0; i < 2; ++i)
5205                               {
5206                                 Assert(!old_child[i]->has_children(),
5207                                        ExcInternalError());
5208 
5209                                 new_child[i]->set_bounding_object_indices(
5210                                   {old_child[i]->vertex_index(0),
5211                                    old_child[i]->vertex_index(1)});
5212                                 new_child[i]->set_boundary_id_internal(
5213                                   old_child[i]->boundary_id());
5214                                 new_child[i]->set_manifold_id(
5215                                   old_child[i]->manifold_id());
5216                                 new_child[i]->set_user_index(
5217                                   old_child[i]->user_index());
5218                                 if (old_child[i]->user_flag_set())
5219                                   new_child[i]->set_user_flag();
5220                                 else
5221                                   new_child[i]->clear_user_flag();
5222 
5223                                 new_child[i]->clear_children();
5224 
5225                                 old_child[i]->clear_user_flag();
5226                                 old_child[i]->clear_user_index();
5227                                 old_child[i]->clear_used_flag();
5228                               }
5229                           }
5230                         // now that we cared about the lines, go on
5231                         // with the quads themselves, where we might
5232                         // encounter similar situations...
5233                         if (aniso_quad_ref_case ==
5234                             RefinementCase<dim - 1>::cut_x)
5235                           {
5236                             new_line->set_children(
5237                               0, quad->child(0)->line_index(1));
5238                             Assert(new_line->child(1) ==
5239                                      quad->child(2)->line(1),
5240                                    ExcInternalError());
5241                             // now evereything is quite
5242                             // complicated. we have the children
5243                             // numbered according to
5244                             //
5245                             // *---*---*
5246                             // |n+2|n+3|
5247                             // *---*---*
5248                             // | n |n+1|
5249                             // *---*---*
5250                             //
5251                             // from the original isotropic
5252                             // refinement. we have to reorder them as
5253                             //
5254                             // *---*---*
5255                             // |n+1|n+3|
5256                             // *---*---*
5257                             // | n |n+2|
5258                             // *---*---*
5259                             //
5260                             // such that n and n+1 are consecutive
5261                             // children of m and n+2 and n+3 are
5262                             // consecutive children of m+1, where m
5263                             // and m+1 are given as in
5264                             //
5265                             // *---*---*
5266                             // |   |   |
5267                             // | m |m+1|
5268                             // |   |   |
5269                             // *---*---*
5270                             //
5271                             // this is a bit ugly, of course: loop
5272                             // over all cells on all levels and look
5273                             // for faces n+1 (switch_1) and n+2
5274                             // (switch_2).
5275                             const typename Triangulation<dim, spacedim>::
5276                               quad_iterator switch_1 = quad->child(1),
5277                                             switch_2 = quad->child(2);
5278                             const int switch_1_index = switch_1->index();
5279                             const int switch_2_index = switch_2->index();
5280                             for (unsigned int l = 0;
5281                                  l < triangulation.levels.size();
5282                                  ++l)
5283                               for (unsigned int h = 0;
5284                                    h <
5285                                    triangulation.levels[l]->cells.n_objects();
5286                                    ++h)
5287                                 for (const unsigned int q :
5288                                      GeometryInfo<dim>::face_indices())
5289                                   {
5290                                     const int face_index =
5291                                       triangulation.levels[l]
5292                                         ->cells.get_bounding_object_indices(
5293                                           h)[q];
5294                                     if (face_index == switch_1_index)
5295                                       triangulation.levels[l]
5296                                         ->cells.get_bounding_object_indices(
5297                                           h)[q] = switch_2_index;
5298                                     else if (face_index == switch_2_index)
5299                                       triangulation.levels[l]
5300                                         ->cells.get_bounding_object_indices(
5301                                           h)[q] = switch_1_index;
5302                                   }
5303                             // now we have to copy all information of
5304                             // the two quads
5305                             const unsigned int switch_1_lines[4] = {
5306                               switch_1->line_index(0),
5307                               switch_1->line_index(1),
5308                               switch_1->line_index(2),
5309                               switch_1->line_index(3)};
5310                             const bool switch_1_line_orientations[4] = {
5311                               switch_1->line_orientation(0),
5312                               switch_1->line_orientation(1),
5313                               switch_1->line_orientation(2),
5314                               switch_1->line_orientation(3)};
5315                             const types::boundary_id switch_1_boundary_id =
5316                               switch_1->boundary_id();
5317                             const unsigned int switch_1_user_index =
5318                               switch_1->user_index();
5319                             const bool switch_1_user_flag =
5320                               switch_1->user_flag_set();
5321                             const RefinementCase<dim - 1>
5322                               switch_1_refinement_case =
5323                                 switch_1->refinement_case();
5324                             const int switch_1_first_child_pair =
5325                               (switch_1_refinement_case ?
5326                                  switch_1->child_index(0) :
5327                                  -1);
5328                             const int switch_1_second_child_pair =
5329                               (switch_1_refinement_case ==
5330                                    RefinementCase<dim - 1>::cut_xy ?
5331                                  switch_1->child_index(2) :
5332                                  -1);
5333 
5334                             switch_1->set_bounding_object_indices(
5335                               {switch_2->line_index(0),
5336                                switch_2->line_index(1),
5337                                switch_2->line_index(2),
5338                                switch_2->line_index(3)});
5339                             switch_1->set_line_orientation(
5340                               0, switch_2->line_orientation(0));
5341                             switch_1->set_line_orientation(
5342                               1, switch_2->line_orientation(1));
5343                             switch_1->set_line_orientation(
5344                               2, switch_2->line_orientation(2));
5345                             switch_1->set_line_orientation(
5346                               3, switch_2->line_orientation(3));
5347                             switch_1->set_boundary_id_internal(
5348                               switch_2->boundary_id());
5349                             switch_1->set_manifold_id(switch_2->manifold_id());
5350                             switch_1->set_user_index(switch_2->user_index());
5351                             if (switch_2->user_flag_set())
5352                               switch_1->set_user_flag();
5353                             else
5354                               switch_1->clear_user_flag();
5355                             switch_1->clear_refinement_case();
5356                             switch_1->set_refinement_case(
5357                               switch_2->refinement_case());
5358                             switch_1->clear_children();
5359                             if (switch_2->refinement_case())
5360                               switch_1->set_children(0,
5361                                                      switch_2->child_index(0));
5362                             if (switch_2->refinement_case() ==
5363                                 RefinementCase<dim - 1>::cut_xy)
5364                               switch_1->set_children(2,
5365                                                      switch_2->child_index(2));
5366 
5367                             switch_2->set_bounding_object_indices(
5368                               {switch_1_lines[0],
5369                                switch_1_lines[1],
5370                                switch_1_lines[2],
5371                                switch_1_lines[3]});
5372                             switch_2->set_line_orientation(
5373                               0, switch_1_line_orientations[0]);
5374                             switch_2->set_line_orientation(
5375                               1, switch_1_line_orientations[1]);
5376                             switch_2->set_line_orientation(
5377                               2, switch_1_line_orientations[2]);
5378                             switch_2->set_line_orientation(
5379                               3, switch_1_line_orientations[3]);
5380                             switch_2->set_boundary_id_internal(
5381                               switch_1_boundary_id);
5382                             switch_2->set_manifold_id(switch_1->manifold_id());
5383                             switch_2->set_user_index(switch_1_user_index);
5384                             if (switch_1_user_flag)
5385                               switch_2->set_user_flag();
5386                             else
5387                               switch_2->clear_user_flag();
5388                             switch_2->clear_refinement_case();
5389                             switch_2->set_refinement_case(
5390                               switch_1_refinement_case);
5391                             switch_2->clear_children();
5392                             switch_2->set_children(0,
5393                                                    switch_1_first_child_pair);
5394                             switch_2->set_children(2,
5395                                                    switch_1_second_child_pair);
5396 
5397                             new_quads[0]->set_refinement_case(
5398                               RefinementCase<2>::cut_y);
5399                             new_quads[0]->set_children(0, quad->child_index(0));
5400                             new_quads[1]->set_refinement_case(
5401                               RefinementCase<2>::cut_y);
5402                             new_quads[1]->set_children(0, quad->child_index(2));
5403                           }
5404                         else
5405                           {
5406                             new_quads[0]->set_refinement_case(
5407                               RefinementCase<2>::cut_x);
5408                             new_quads[0]->set_children(0, quad->child_index(0));
5409                             new_quads[1]->set_refinement_case(
5410                               RefinementCase<2>::cut_x);
5411                             new_quads[1]->set_children(0, quad->child_index(2));
5412                             new_line->set_children(
5413                               0, quad->child(0)->line_index(3));
5414                             Assert(new_line->child(1) ==
5415                                      quad->child(1)->line(3),
5416                                    ExcInternalError());
5417                           }
5418                         quad->clear_children();
5419                       }
5420 
5421                     // note these quads as children to the present one
5422                     quad->set_children(0, new_quads[0]->index());
5423 
5424                     quad->set_refinement_case(aniso_quad_ref_case);
5425 
5426                     // finally clear flag indicating the need for
5427                     // refinement
5428                     quad->clear_user_data();
5429                   } // if (anisotropic refinement)
5430 
5431                 if (quad->user_flag_set())
5432                   {
5433                     // this quad needs to be refined isotropically
5434 
5435                     // first of all: we only get here in the first run
5436                     // of the loop
5437                     Assert(loop == 0, ExcInternalError());
5438 
5439                     // find the next unused vertex. we'll need this in
5440                     // any case
5441                     while (triangulation.vertices_used[next_unused_vertex] ==
5442                            true)
5443                       ++next_unused_vertex;
5444                     Assert(
5445                       next_unused_vertex < triangulation.vertices.size(),
5446                       ExcMessage(
5447                         "Internal error: During refinement, the triangulation wants to access an element of the 'vertices' array but it turns out that the array is not large enough."));
5448 
5449                     // now: if the quad is refined anisotropically
5450                     // already, set the anisotropic refinement flag
5451                     // for both children. Additionally, we have to
5452                     // refine the inner line, as it is an outer line
5453                     // of the two (anisotropic) children
5454                     const RefinementCase<dim - 1> quad_ref_case =
5455                       quad->refinement_case();
5456 
5457                     if (quad_ref_case == RefinementCase<dim - 1>::cut_x ||
5458                         quad_ref_case == RefinementCase<dim - 1>::cut_y)
5459                       {
5460                         // set the 'opposite' refine case for children
5461                         quad->child(0)->set_user_index(
5462                           RefinementCase<dim - 1>::cut_xy - quad_ref_case);
5463                         quad->child(1)->set_user_index(
5464                           RefinementCase<dim - 1>::cut_xy - quad_ref_case);
5465                         // refine the inner line
5466                         typename Triangulation<dim, spacedim>::line_iterator
5467                           middle_line;
5468                         if (quad_ref_case == RefinementCase<dim - 1>::cut_x)
5469                           middle_line = quad->child(0)->line(1);
5470                         else
5471                           middle_line = quad->child(0)->line(3);
5472 
5473                         // if the face has been refined
5474                         // anisotropically in the last refinement step
5475                         // it might be, that it is flagged already and
5476                         // that the middle line is thus refined
5477                         // already. if not create children.
5478                         if (!middle_line->has_children())
5479                           {
5480                             // set the middle vertex
5481                             // appropriately. double refinement of
5482                             // quads can only happen in the interior
5483                             // of the domain, so we need not care
5484                             // about boundary quads here
5485                             triangulation.vertices[next_unused_vertex] =
5486                               middle_line->center(true);
5487                             triangulation.vertices_used[next_unused_vertex] =
5488                               true;
5489 
5490                             // now search a slot for the two
5491                             // child lines
5492                             next_unused_line =
5493                               triangulation.faces->lines
5494                                 .template next_free_pair_object<1>(
5495                                   triangulation);
5496 
5497                             // set the child pointer of the present
5498                             // line
5499                             middle_line->set_children(
5500                               0, next_unused_line->index());
5501 
5502                             // set the two new lines
5503                             const typename Triangulation<dim, spacedim>::
5504                               raw_line_iterator children[2] = {
5505                                 next_unused_line, ++next_unused_line};
5506 
5507                             // some tests; if any of the iterators
5508                             // should be invalid, then already
5509                             // dereferencing will fail
5510                             Assert(
5511                               children[0]->used() == false,
5512                               ExcMessage(
5513                                 "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5514                             Assert(
5515                               children[1]->used() == false,
5516                               ExcMessage(
5517                                 "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5518 
5519                             children[0]->set_bounding_object_indices(
5520                               {middle_line->vertex_index(0),
5521                                next_unused_vertex});
5522                             children[1]->set_bounding_object_indices(
5523                               {next_unused_vertex,
5524                                middle_line->vertex_index(1)});
5525 
5526                             children[0]->set_used_flag();
5527                             children[1]->set_used_flag();
5528                             children[0]->clear_children();
5529                             children[1]->clear_children();
5530                             children[0]->clear_user_data();
5531                             children[1]->clear_user_data();
5532                             children[0]->clear_user_flag();
5533                             children[1]->clear_user_flag();
5534 
5535                             children[0]->set_boundary_id_internal(
5536                               middle_line->boundary_id());
5537                             children[1]->set_boundary_id_internal(
5538                               middle_line->boundary_id());
5539 
5540                             children[0]->set_manifold_id(
5541                               middle_line->manifold_id());
5542                             children[1]->set_manifold_id(
5543                               middle_line->manifold_id());
5544                           }
5545                         // now remove the flag from the quad and go to
5546                         // the next quad, the actual refinement of the
5547                         // quad takes place later on in this pass of
5548                         // the loop or in the next one
5549                         quad->clear_user_flag();
5550                         continue;
5551                       } // if (several refinement cases)
5552 
5553                     // if we got here, we have an unrefined quad and
5554                     // have to do the usual work like in an purely
5555                     // isotropic refinement
5556                     Assert(quad_ref_case ==
5557                              RefinementCase<dim - 1>::no_refinement,
5558                            ExcInternalError());
5559 
5560                     // set the middle vertex appropriately: it might be that
5561                     // the quad itself is not at the boundary, but that one of
5562                     // its lines actually is. in this case, the newly created
5563                     // vertices at the centers of the lines are not
5564                     // necessarily the mean values of the adjacent vertices,
5565                     // so do not compute the new vertex as the mean value of
5566                     // the 4 vertices of the face, but rather as a weighted
5567                     // mean value of the 8 vertices which we already have (the
5568                     // four old ones, and the four ones inserted as middle
5569                     // points for the four lines). summing up some more points
5570                     // is generally cheaper than first asking whether one of
5571                     // the lines is at the boundary
5572                     //
5573                     // note that the exact weights are chosen such as to
5574                     // minimize the distortion of the four new quads from the
5575                     // optimal shape. their description uses the formulas
5576                     // underlying the TransfiniteInterpolationManifold
5577                     // implementation
5578                     triangulation.vertices[next_unused_vertex] =
5579                       quad->center(true, true);
5580                     triangulation.vertices_used[next_unused_vertex] = true;
5581 
5582                     // now that we created the right point, make up
5583                     // the four lines interior to the quad (++ takes
5584                     // care of the end of the vector)
5585                     typename Triangulation<dim, spacedim>::raw_line_iterator
5586                       new_lines[4];
5587 
5588                     for (unsigned int i = 0; i < 4; ++i)
5589                       {
5590                         if (i % 2 == 0)
5591                           // search a free pair of lines for 0. and
5592                           // 2. line, so that two of them end up
5593                           // together, which is necessary if later on
5594                           // we want to refine the quad
5595                           // anisotropically and the two lines end up
5596                           // as children of new line
5597                           next_unused_line =
5598                             triangulation.faces->lines
5599                               .template next_free_pair_object<1>(triangulation);
5600 
5601                         new_lines[i] = next_unused_line;
5602                         ++next_unused_line;
5603 
5604                         Assert(
5605                           new_lines[i]->used() == false,
5606                           ExcMessage(
5607                             "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5608                       }
5609 
5610                     // set the data of the four lines.  first collect
5611                     // the indices of the five vertices:
5612                     //
5613                     // *--3--*
5614                     // |  |  |
5615                     // 0--4--1
5616                     // |  |  |
5617                     // *--2--*
5618                     //
5619                     // the lines are numbered as follows:
5620                     //
5621                     // *--*--*
5622                     // |  1  |
5623                     // *2-*-3*
5624                     // |  0  |
5625                     // *--*--*
5626 
5627                     const unsigned int vertex_indices[5] = {
5628                       quad->line(0)->child(0)->vertex_index(1),
5629                       quad->line(1)->child(0)->vertex_index(1),
5630                       quad->line(2)->child(0)->vertex_index(1),
5631                       quad->line(3)->child(0)->vertex_index(1),
5632                       next_unused_vertex};
5633 
5634                     new_lines[0]->set_bounding_object_indices(
5635                       {vertex_indices[2], vertex_indices[4]});
5636                     new_lines[1]->set_bounding_object_indices(
5637                       {vertex_indices[4], vertex_indices[3]});
5638                     new_lines[2]->set_bounding_object_indices(
5639                       {vertex_indices[0], vertex_indices[4]});
5640                     new_lines[3]->set_bounding_object_indices(
5641                       {vertex_indices[4], vertex_indices[1]});
5642 
5643                     for (const auto &new_line : new_lines)
5644                       {
5645                         new_line->set_used_flag();
5646                         new_line->clear_user_flag();
5647                         new_line->clear_user_data();
5648                         new_line->clear_children();
5649                         new_line->set_boundary_id_internal(quad->boundary_id());
5650                         new_line->set_manifold_id(quad->manifold_id());
5651                       }
5652 
5653                     // now for the quads. again, first collect some
5654                     // data about the indices of the lines, with the
5655                     // following numbering:
5656                     //
5657                     //   .-6-.-7-.
5658                     //   1   9   3
5659                     //   .-10.11-.
5660                     //   0   8   2
5661                     //   .-4-.-5-.
5662 
5663                     // child 0 and 1 of a line are switched if the
5664                     // line orientation is false. set up a miniature
5665                     // table, indicating which child to take for line
5666                     // orientations false and true. first index: child
5667                     // index in standard orientation, second index:
5668                     // line orientation
5669                     const unsigned int index[2][2] = {
5670                       {1, 0},  // child 0, line_orientation=false and true
5671                       {0, 1}}; // child 1, line_orientation=false and true
5672 
5673                     const int line_indices[12] = {
5674                       quad->line(0)
5675                         ->child(index[0][quad->line_orientation(0)])
5676                         ->index(),
5677                       quad->line(0)
5678                         ->child(index[1][quad->line_orientation(0)])
5679                         ->index(),
5680                       quad->line(1)
5681                         ->child(index[0][quad->line_orientation(1)])
5682                         ->index(),
5683                       quad->line(1)
5684                         ->child(index[1][quad->line_orientation(1)])
5685                         ->index(),
5686                       quad->line(2)
5687                         ->child(index[0][quad->line_orientation(2)])
5688                         ->index(),
5689                       quad->line(2)
5690                         ->child(index[1][quad->line_orientation(2)])
5691                         ->index(),
5692                       quad->line(3)
5693                         ->child(index[0][quad->line_orientation(3)])
5694                         ->index(),
5695                       quad->line(3)
5696                         ->child(index[1][quad->line_orientation(3)])
5697                         ->index(),
5698                       new_lines[0]->index(),
5699                       new_lines[1]->index(),
5700                       new_lines[2]->index(),
5701                       new_lines[3]->index()};
5702 
5703                     // find some space (consecutive)
5704                     // for the first two newly to be
5705                     // created quads.
5706                     typename Triangulation<dim, spacedim>::raw_quad_iterator
5707                       new_quads[4];
5708 
5709                     next_unused_quad =
5710                       triangulation.faces->quads
5711                         .template next_free_pair_object<2>(triangulation);
5712 
5713                     new_quads[0] = next_unused_quad;
5714                     Assert(
5715                       new_quads[0]->used() == false,
5716                       ExcMessage(
5717                         "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5718 
5719                     ++next_unused_quad;
5720                     new_quads[1] = next_unused_quad;
5721                     Assert(
5722                       new_quads[1]->used() == false,
5723                       ExcMessage(
5724                         "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5725 
5726                     next_unused_quad =
5727                       triangulation.faces->quads
5728                         .template next_free_pair_object<2>(triangulation);
5729                     new_quads[2] = next_unused_quad;
5730                     Assert(
5731                       new_quads[2]->used() == false,
5732                       ExcMessage(
5733                         "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5734 
5735                     ++next_unused_quad;
5736                     new_quads[3] = next_unused_quad;
5737                     Assert(
5738                       new_quads[3]->used() == false,
5739                       ExcMessage(
5740                         "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5741 
5742                     // note these quads as children to the present one
5743                     quad->set_children(0, new_quads[0]->index());
5744                     quad->set_children(2, new_quads[2]->index());
5745                     quad->set_refinement_case(RefinementCase<2>::cut_xy);
5746 
5747                     new_quads[0]->set_bounding_object_indices(
5748                       {line_indices[0],
5749                        line_indices[8],
5750                        line_indices[4],
5751                        line_indices[10]});
5752                     new_quads[1]->set_bounding_object_indices(
5753                       {line_indices[8],
5754                        line_indices[2],
5755                        line_indices[5],
5756                        line_indices[11]});
5757                     new_quads[2]->set_bounding_object_indices(
5758                       {line_indices[1],
5759                        line_indices[9],
5760                        line_indices[10],
5761                        line_indices[6]});
5762                     new_quads[3]->set_bounding_object_indices(
5763                       {line_indices[9],
5764                        line_indices[3],
5765                        line_indices[11],
5766                        line_indices[7]});
5767                     for (const auto &new_quad : new_quads)
5768                       {
5769                         new_quad->set_used_flag();
5770                         new_quad->clear_user_flag();
5771                         new_quad->clear_user_data();
5772                         new_quad->clear_children();
5773                         new_quad->set_boundary_id_internal(quad->boundary_id());
5774                         new_quad->set_manifold_id(quad->manifold_id());
5775                         // set all line orientations to true, change
5776                         // this after the loop, as we have to consider
5777                         // different lines for each child
5778                         for (unsigned int j = 0;
5779                              j < GeometryInfo<dim>::lines_per_face;
5780                              ++j)
5781                           new_quad->set_line_orientation(j, true);
5782                       }
5783                     // now set the line orientation of children of
5784                     // outer lines correctly, the lines in the
5785                     // interior of the refined quad are automatically
5786                     // oriented conforming to the standard
5787                     new_quads[0]->set_line_orientation(
5788                       0, quad->line_orientation(0));
5789                     new_quads[0]->set_line_orientation(
5790                       2, quad->line_orientation(2));
5791                     new_quads[1]->set_line_orientation(
5792                       1, quad->line_orientation(1));
5793                     new_quads[1]->set_line_orientation(
5794                       2, quad->line_orientation(2));
5795                     new_quads[2]->set_line_orientation(
5796                       0, quad->line_orientation(0));
5797                     new_quads[2]->set_line_orientation(
5798                       3, quad->line_orientation(3));
5799                     new_quads[3]->set_line_orientation(
5800                       1, quad->line_orientation(1));
5801                     new_quads[3]->set_line_orientation(
5802                       3, quad->line_orientation(3));
5803 
5804                     // finally clear flag indicating the need for
5805                     // refinement
5806                     quad->clear_user_flag();
5807                   } // if (isotropic refinement)
5808               }     // for all quads
5809           }         // looped two times over all quads, all quads refined now
5810 
5811         ///////////////////////////////////
5812         // Now, finally, set up the new
5813         // cells
5814         ///////////////////////////////////
5815 
5816         typename Triangulation<3, spacedim>::DistortedCellList
5817           cells_with_distorted_children;
5818 
5819         for (unsigned int level = 0; level != triangulation.levels.size() - 1;
5820              ++level)
5821           {
5822             // only active objects can be refined further; remember
5823             // that we won't operate on the finest level, so
5824             // triangulation.begin_*(level+1) is allowed
5825             typename Triangulation<dim, spacedim>::active_hex_iterator
5826               hex  = triangulation.begin_active_hex(level),
5827               endh = triangulation.begin_active_hex(level + 1);
5828             typename Triangulation<dim, spacedim>::raw_hex_iterator
5829               next_unused_hex = triangulation.begin_raw_hex(level + 1);
5830 
5831             for (; hex != endh; ++hex)
5832               if (hex->refine_flag_set())
5833                 {
5834                   // this hex needs to be refined
5835 
5836                   // clear flag indicating the need for refinement. do
5837                   // it here already, since we can't do it anymore
5838                   // once the cell has children
5839                   const RefinementCase<dim> ref_case = hex->refine_flag_set();
5840                   hex->clear_refine_flag();
5841                   hex->set_refinement_case(ref_case);
5842 
5843                   // depending on the refine case we might have to
5844                   // create additional vertices, lines and quads
5845                   // interior of the hex before the actual children
5846                   // can be set up.
5847 
5848                   // in a first step: reserve the needed space for
5849                   // lines, quads and hexes and initialize them
5850                   // correctly
5851 
5852                   unsigned int n_new_lines = 0;
5853                   unsigned int n_new_quads = 0;
5854                   unsigned int n_new_hexes = 0;
5855                   switch (ref_case)
5856                     {
5857                       case RefinementCase<dim>::cut_x:
5858                       case RefinementCase<dim>::cut_y:
5859                       case RefinementCase<dim>::cut_z:
5860                         n_new_lines = 0;
5861                         n_new_quads = 1;
5862                         n_new_hexes = 2;
5863                         break;
5864                       case RefinementCase<dim>::cut_xy:
5865                       case RefinementCase<dim>::cut_xz:
5866                       case RefinementCase<dim>::cut_yz:
5867                         n_new_lines = 1;
5868                         n_new_quads = 4;
5869                         n_new_hexes = 4;
5870                         break;
5871                       case RefinementCase<dim>::cut_xyz:
5872                         n_new_lines = 6;
5873                         n_new_quads = 12;
5874                         n_new_hexes = 8;
5875                         break;
5876                       default:
5877                         Assert(false, ExcInternalError());
5878                         break;
5879                     }
5880 
5881                   // find some space for the newly to be created
5882                   // interior lines and initialize them.
5883                   std::vector<
5884                     typename Triangulation<dim, spacedim>::raw_line_iterator>
5885                     new_lines(n_new_lines);
5886                   for (unsigned int i = 0; i < n_new_lines; ++i)
5887                     {
5888                       new_lines[i] =
5889                         triangulation.faces->lines
5890                           .template next_free_single_object<1>(triangulation);
5891 
5892                       Assert(
5893                         new_lines[i]->used() == false,
5894                         ExcMessage(
5895                           "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5896                       new_lines[i]->set_used_flag();
5897                       new_lines[i]->clear_user_flag();
5898                       new_lines[i]->clear_user_data();
5899                       new_lines[i]->clear_children();
5900                       // interior line
5901                       new_lines[i]->set_boundary_id_internal(
5902                         numbers::internal_face_boundary_id);
5903                       // they inherit geometry description of the hex they
5904                       // belong to
5905                       new_lines[i]->set_manifold_id(hex->manifold_id());
5906                     }
5907 
5908                   // find some space for the newly to be created
5909                   // interior quads and initialize them.
5910                   std::vector<
5911                     typename Triangulation<dim, spacedim>::raw_quad_iterator>
5912                     new_quads(n_new_quads);
5913                   for (unsigned int i = 0; i < n_new_quads; ++i)
5914                     {
5915                       new_quads[i] =
5916                         triangulation.faces->quads
5917                           .template next_free_single_object<2>(triangulation);
5918 
5919                       Assert(
5920                         new_quads[i]->used() == false,
5921                         ExcMessage(
5922                           "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5923                       new_quads[i]->set_used_flag();
5924                       new_quads[i]->clear_user_flag();
5925                       new_quads[i]->clear_user_data();
5926                       new_quads[i]->clear_children();
5927                       // interior quad
5928                       new_quads[i]->set_boundary_id_internal(
5929                         numbers::internal_face_boundary_id);
5930                       // they inherit geometry description of the hex they
5931                       // belong to
5932                       new_quads[i]->set_manifold_id(hex->manifold_id());
5933                       // set all line orientation flags to true by
5934                       // default, change this afterwards, if necessary
5935                       for (unsigned int j = 0;
5936                            j < GeometryInfo<dim>::lines_per_face;
5937                            ++j)
5938                         new_quads[i]->set_line_orientation(j, true);
5939                     }
5940 
5941                   types::subdomain_id subdomainid = hex->subdomain_id();
5942 
5943                   // find some space for the newly to be created hexes
5944                   // and initialize them.
5945                   std::vector<
5946                     typename Triangulation<dim, spacedim>::raw_hex_iterator>
5947                     new_hexes(n_new_hexes);
5948                   for (unsigned int i = 0; i < n_new_hexes; ++i)
5949                     {
5950                       if (i % 2 == 0)
5951                         next_unused_hex =
5952                           triangulation.levels[level + 1]->cells.next_free_hex(
5953                             triangulation, level + 1);
5954                       else
5955                         ++next_unused_hex;
5956 
5957                       new_hexes[i] = next_unused_hex;
5958 
5959                       Assert(
5960                         new_hexes[i]->used() == false,
5961                         ExcMessage(
5962                           "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5963                       new_hexes[i]->set_used_flag();
5964                       new_hexes[i]->clear_user_flag();
5965                       new_hexes[i]->clear_user_data();
5966                       new_hexes[i]->clear_children();
5967                       // inherit material
5968                       // properties
5969                       new_hexes[i]->set_material_id(hex->material_id());
5970                       new_hexes[i]->set_manifold_id(hex->manifold_id());
5971                       new_hexes[i]->set_subdomain_id(subdomainid);
5972 
5973                       if (i % 2)
5974                         new_hexes[i]->set_parent(hex->index());
5975                       // set the face_orientation flag to true for all
5976                       // faces initially, as this is the default value
5977                       // which is true for all faces interior to the
5978                       // hex. later on go the other way round and
5979                       // reset faces that are at the boundary of the
5980                       // mother cube
5981                       //
5982                       // the same is true for the face_flip and
5983                       // face_rotation flags. however, the latter two
5984                       // are set to false by default as this is the
5985                       // standard value
5986                       for (const unsigned int f :
5987                            GeometryInfo<dim>::face_indices())
5988                         {
5989                           new_hexes[i]->set_face_orientation(f, true);
5990                           new_hexes[i]->set_face_flip(f, false);
5991                           new_hexes[i]->set_face_rotation(f, false);
5992                         }
5993                     }
5994                   // note these hexes as children to the present cell
5995                   for (unsigned int i = 0; i < n_new_hexes / 2; ++i)
5996                     hex->set_children(2 * i, new_hexes[2 * i]->index());
5997 
5998                   // we have to take into account whether the
5999                   // different faces are oriented correctly or in the
6000                   // opposite direction, so store that up front
6001 
6002                   // face_orientation
6003                   const bool f_or[6] = {hex->face_orientation(0),
6004                                         hex->face_orientation(1),
6005                                         hex->face_orientation(2),
6006                                         hex->face_orientation(3),
6007                                         hex->face_orientation(4),
6008                                         hex->face_orientation(5)};
6009 
6010                   // face_flip
6011                   const bool f_fl[6] = {hex->face_flip(0),
6012                                         hex->face_flip(1),
6013                                         hex->face_flip(2),
6014                                         hex->face_flip(3),
6015                                         hex->face_flip(4),
6016                                         hex->face_flip(5)};
6017 
6018                   // face_rotation
6019                   const bool f_ro[6] = {hex->face_rotation(0),
6020                                         hex->face_rotation(1),
6021                                         hex->face_rotation(2),
6022                                         hex->face_rotation(3),
6023                                         hex->face_rotation(4),
6024                                         hex->face_rotation(5)};
6025 
6026                   // little helper table, indicating, whether the
6027                   // child with index 0 or with index 1 can be found
6028                   // at the standard origin of an anisotropically
6029                   // refined quads in real orientation index 1:
6030                   // (RefineCase - 1) index 2: face_flip
6031 
6032                   // index 3: face rotation
6033                   // note: face orientation has no influence
6034                   const unsigned int child_at_origin[2][2][2] = {
6035                     {{0, 0},   // RefinementCase<dim>::cut_x, face_flip=false,
6036                                // face_rotation=false and true
6037                      {1, 1}},  // RefinementCase<dim>::cut_x, face_flip=true,
6038                                // face_rotation=false and true
6039                     {{0, 1},   // RefinementCase<dim>::cut_y, face_flip=false,
6040                                // face_rotation=false and true
6041                      {1, 0}}}; // RefinementCase<dim>::cut_y, face_flip=true,
6042                                // face_rotation=false and true
6043 
6044                   ///////////////////////////////////////
6045                   //
6046                   // in the following we will do the same thing for
6047                   // each refinement case: create a new vertex (if
6048                   // needed), create new interior lines (if needed),
6049                   // create new interior quads and afterwards build
6050                   // the children hexes out of these and the existing
6051                   // subfaces of the outer quads (which have been
6052                   // created above). However, even if the steps are
6053                   // quite similar, the actual work strongly depends
6054                   // on the actual refinement case. therefore, we use
6055                   // separate blocks of code for each of these cases,
6056                   // which hopefully increases the readability to some
6057                   // extend.
6058 
6059                   switch (ref_case)
6060                     {
6061                       case RefinementCase<dim>::cut_x:
6062                         {
6063                           //////////////////////////////
6064                           //
6065                           //     RefinementCase<dim>::cut_x
6066                           //
6067                           // the refined cube will look
6068                           // like this:
6069                           //
6070                           //        *----*----*
6071                           //       /    /    /|
6072                           //      /    /    / |
6073                           //     /    /    /  |
6074                           //    *----*----*   |
6075                           //    |    |    |   |
6076                           //    |    |    |   *
6077                           //    |    |    |  /
6078                           //    |    |    | /
6079                           //    |    |    |/
6080                           //    *----*----*
6081                           //
6082                           // again, first collect some data about the
6083                           // indices of the lines, with the following
6084                           // numbering:
6085 
6086                           // face 2: front plane
6087                           //   (note: x,y exchanged)
6088                           //   *---*---*
6089                           //   |   |   |
6090                           //   |   0   |
6091                           //   |   |   |
6092                           //   *---*---*
6093                           //       m0
6094                           // face 3: back plane
6095                           //   (note: x,y exchanged)
6096                           //       m1
6097                           //   *---*---*
6098                           //   |   |   |
6099                           //   |   1   |
6100                           //   |   |   |
6101                           //   *---*---*
6102                           // face 4: bottom plane
6103                           //       *---*---*
6104                           //      /   /   /
6105                           //     /   2   /
6106                           //    /   /   /
6107                           //   *---*---*
6108                           //       m0
6109                           // face 5: top plane
6110                           //           m1
6111                           //       *---*---*
6112                           //      /   /   /
6113                           //     /   3   /
6114                           //    /   /   /
6115                           //   *---*---*
6116 
6117                           // set up a list of line iterators first. from
6118                           // this, construct lists of line_indices and
6119                           // line orientations later on
6120                           const typename Triangulation<dim, spacedim>::
6121                             raw_line_iterator lines[4] = {
6122                               hex->face(2)->child(0)->line(
6123                                 (hex->face(2)->refinement_case() ==
6124                                  RefinementCase<2>::cut_x) ?
6125                                   1 :
6126                                   3), // 0
6127                               hex->face(3)->child(0)->line(
6128                                 (hex->face(3)->refinement_case() ==
6129                                  RefinementCase<2>::cut_x) ?
6130                                   1 :
6131                                   3), // 1
6132                               hex->face(4)->child(0)->line(
6133                                 (hex->face(4)->refinement_case() ==
6134                                  RefinementCase<2>::cut_x) ?
6135                                   1 :
6136                                   3), // 2
6137                               hex->face(5)->child(0)->line(
6138                                 (hex->face(5)->refinement_case() ==
6139                                  RefinementCase<2>::cut_x) ?
6140                                   1 :
6141                                   3) // 3
6142                             };
6143 
6144                           unsigned int line_indices[4];
6145                           for (unsigned int i = 0; i < 4; ++i)
6146                             line_indices[i] = lines[i]->index();
6147 
6148                           // the orientation of lines for the inner quads
6149                           // is quite tricky. as these lines are newly
6150                           // created ones and thus have no parents, they
6151                           // cannot inherit this property. set up an array
6152                           // and fill it with the respective values
6153                           bool line_orientation[4];
6154 
6155                           // the middle vertex marked as m0 above is the
6156                           // start vertex for lines 0 and 2 in standard
6157                           // orientation, whereas m1 is the end vertex of
6158                           // lines 1 and 3 in standard orientation
6159                           const unsigned int middle_vertices[2] = {
6160                             hex->line(2)->child(0)->vertex_index(1),
6161                             hex->line(7)->child(0)->vertex_index(1)};
6162 
6163                           for (unsigned int i = 0; i < 4; ++i)
6164                             if (lines[i]->vertex_index(i % 2) ==
6165                                 middle_vertices[i % 2])
6166                               line_orientation[i] = true;
6167                             else
6168                               {
6169                                 // it must be the other
6170                                 // way round then
6171                                 Assert(lines[i]->vertex_index((i + 1) % 2) ==
6172                                          middle_vertices[i % 2],
6173                                        ExcInternalError());
6174                                 line_orientation[i] = false;
6175                               }
6176 
6177                           // set up the new quad, line numbering is as
6178                           // indicated above
6179                           new_quads[0]->set_bounding_object_indices(
6180                             {line_indices[0],
6181                              line_indices[1],
6182                              line_indices[2],
6183                              line_indices[3]});
6184 
6185                           new_quads[0]->set_line_orientation(
6186                             0, line_orientation[0]);
6187                           new_quads[0]->set_line_orientation(
6188                             1, line_orientation[1]);
6189                           new_quads[0]->set_line_orientation(
6190                             2, line_orientation[2]);
6191                           new_quads[0]->set_line_orientation(
6192                             3, line_orientation[3]);
6193 
6194                           // the quads are numbered as follows:
6195                           //
6196                           // planes in the interior of the old hex:
6197                           //
6198                           //      *
6199                           //     /|
6200                           //    / | x
6201                           //   /  | *-------*      *---------*
6202                           //  *   | |       |     /         /
6203                           //  | 0 | |       |    /         /
6204                           //  |   * |       |   /         /
6205                           //  |  /  *-------*y *---------*x
6206                           //  | /
6207                           //  |/
6208                           //  *
6209                           //
6210                           // children of the faces of the old hex
6211                           //
6212                           //      *---*---*        *---*---*
6213                           //     /|   |   |       /   /   /|
6214                           //    / |   |   |      / 9 / 10/ |
6215                           //   /  | 5 | 6 |     /   /   /  |
6216                           //  *   |   |   |    *---*---*   |
6217                           //  | 1 *---*---*    |   |   | 2 *
6218                           //  |  /   /   /     |   |   |  /
6219                           //  | / 7 / 8 /      | 3 | 4 | /
6220                           //  |/   /   /       |   |   |/
6221                           //  *---*---*        *---*---*
6222                           //
6223                           // note that we have to take care of the
6224                           // orientation of faces.
6225                           const int quad_indices[11] = {
6226                             new_quads[0]->index(), // 0
6227 
6228                             hex->face(0)->index(), // 1
6229 
6230                             hex->face(1)->index(), // 2
6231 
6232                             hex->face(2)->child_index(
6233                               child_at_origin[hex->face(2)->refinement_case() -
6234                                               1][f_fl[2]][f_ro[2]]), // 3
6235                             hex->face(2)->child_index(
6236                               1 -
6237                               child_at_origin[hex->face(2)->refinement_case() -
6238                                               1][f_fl[2]][f_ro[2]]),
6239 
6240                             hex->face(3)->child_index(
6241                               child_at_origin[hex->face(3)->refinement_case() -
6242                                               1][f_fl[3]][f_ro[3]]), // 5
6243                             hex->face(3)->child_index(
6244                               1 -
6245                               child_at_origin[hex->face(3)->refinement_case() -
6246                                               1][f_fl[3]][f_ro[3]]),
6247 
6248                             hex->face(4)->child_index(
6249                               child_at_origin[hex->face(4)->refinement_case() -
6250                                               1][f_fl[4]][f_ro[4]]), // 7
6251                             hex->face(4)->child_index(
6252                               1 -
6253                               child_at_origin[hex->face(4)->refinement_case() -
6254                                               1][f_fl[4]][f_ro[4]]),
6255 
6256                             hex->face(5)->child_index(
6257                               child_at_origin[hex->face(5)->refinement_case() -
6258                                               1][f_fl[5]][f_ro[5]]), // 9
6259                             hex->face(5)->child_index(
6260                               1 -
6261                               child_at_origin[hex->face(5)->refinement_case() -
6262                                               1][f_fl[5]][f_ro[5]])
6263 
6264                           };
6265 
6266                           new_hexes[0]->set_bounding_object_indices(
6267                             {quad_indices[1],
6268                              quad_indices[0],
6269                              quad_indices[3],
6270                              quad_indices[5],
6271                              quad_indices[7],
6272                              quad_indices[9]});
6273                           new_hexes[1]->set_bounding_object_indices(
6274                             {quad_indices[0],
6275                              quad_indices[2],
6276                              quad_indices[4],
6277                              quad_indices[6],
6278                              quad_indices[8],
6279                              quad_indices[10]});
6280                           break;
6281                         }
6282 
6283                       case RefinementCase<dim>::cut_y:
6284                         {
6285                           //////////////////////////////
6286                           //
6287                           //     RefinementCase<dim>::cut_y
6288                           //
6289                           // the refined cube will look like this:
6290                           //
6291                           //        *---------*
6292                           //       /         /|
6293                           //      *---------* |
6294                           //     /         /| |
6295                           //    *---------* | |
6296                           //    |         | | |
6297                           //    |         | | *
6298                           //    |         | |/
6299                           //    |         | *
6300                           //    |         |/
6301                           //    *---------*
6302                           //
6303                           // again, first collect some data about the
6304                           // indices of the lines, with the following
6305                           // numbering:
6306 
6307                           // face 0: left plane
6308                           //       *
6309                           //      /|
6310                           //     * |
6311                           //    /| |
6312                           //   * | |
6313                           //   | 0 |
6314                           //   | | *
6315                           //   | |/
6316                           //   | *m0
6317                           //   |/
6318                           //   *
6319                           // face 1: right plane
6320                           //       *
6321                           //      /|
6322                           //   m1* |
6323                           //    /| |
6324                           //   * | |
6325                           //   | 1 |
6326                           //   | | *
6327                           //   | |/
6328                           //   | *
6329                           //   |/
6330                           //   *
6331                           // face 4: bottom plane
6332                           //       *-------*
6333                           //      /       /
6334                           //   m0*---2---*
6335                           //    /       /
6336                           //   *-------*
6337                           // face 5: top plane
6338                           //       *-------*
6339                           //      /       /
6340                           //     *---3---*m1
6341                           //    /       /
6342                           //   *-------*
6343 
6344                           // set up a list of line iterators first. from
6345                           // this, construct lists of line_indices and
6346                           // line orientations later on
6347                           const typename Triangulation<dim, spacedim>::
6348                             raw_line_iterator lines[4] = {
6349                               hex->face(0)->child(0)->line(
6350                                 (hex->face(0)->refinement_case() ==
6351                                  RefinementCase<2>::cut_x) ?
6352                                   1 :
6353                                   3), // 0
6354                               hex->face(1)->child(0)->line(
6355                                 (hex->face(1)->refinement_case() ==
6356                                  RefinementCase<2>::cut_x) ?
6357                                   1 :
6358                                   3), // 1
6359                               hex->face(4)->child(0)->line(
6360                                 (hex->face(4)->refinement_case() ==
6361                                  RefinementCase<2>::cut_x) ?
6362                                   1 :
6363                                   3), // 2
6364                               hex->face(5)->child(0)->line(
6365                                 (hex->face(5)->refinement_case() ==
6366                                  RefinementCase<2>::cut_x) ?
6367                                   1 :
6368                                   3) // 3
6369                             };
6370 
6371                           unsigned int line_indices[4];
6372                           for (unsigned int i = 0; i < 4; ++i)
6373                             line_indices[i] = lines[i]->index();
6374 
6375                           // the orientation of lines for the inner quads
6376                           // is quite tricky. as these lines are newly
6377                           // created ones and thus have no parents, they
6378                           // cannot inherit this property. set up an array
6379                           // and fill it with the respective values
6380                           bool line_orientation[4];
6381 
6382                           // the middle vertex marked as m0 above is the
6383                           // start vertex for lines 0 and 2 in standard
6384                           // orientation, whereas m1 is the end vertex of
6385                           // lines 1 and 3 in standard orientation
6386                           const unsigned int middle_vertices[2] = {
6387                             hex->line(0)->child(0)->vertex_index(1),
6388                             hex->line(5)->child(0)->vertex_index(1)};
6389 
6390                           for (unsigned int i = 0; i < 4; ++i)
6391                             if (lines[i]->vertex_index(i % 2) ==
6392                                 middle_vertices[i % 2])
6393                               line_orientation[i] = true;
6394                             else
6395                               {
6396                                 // it must be the other way round then
6397                                 Assert(lines[i]->vertex_index((i + 1) % 2) ==
6398                                          middle_vertices[i % 2],
6399                                        ExcInternalError());
6400                                 line_orientation[i] = false;
6401                               }
6402 
6403                           // set up the new quad, line numbering is as
6404                           // indicated above
6405                           new_quads[0]->set_bounding_object_indices(
6406                             {line_indices[2],
6407                              line_indices[3],
6408                              line_indices[0],
6409                              line_indices[1]});
6410 
6411                           new_quads[0]->set_line_orientation(
6412                             0, line_orientation[2]);
6413                           new_quads[0]->set_line_orientation(
6414                             1, line_orientation[3]);
6415                           new_quads[0]->set_line_orientation(
6416                             2, line_orientation[0]);
6417                           new_quads[0]->set_line_orientation(
6418                             3, line_orientation[1]);
6419 
6420                           // the quads are numbered as follows:
6421                           //
6422                           // planes in the interior of the old hex:
6423                           //
6424                           //      *
6425                           //     /|
6426                           //    / | x
6427                           //   /  | *-------*      *---------*
6428                           //  *   | |       |     /         /
6429                           //  |   | |   0   |    /         /
6430                           //  |   * |       |   /         /
6431                           //  |  /  *-------*y *---------*x
6432                           //  | /
6433                           //  |/
6434                           //  *
6435                           //
6436                           // children of the faces of the old hex
6437                           //
6438                           //      *-------*        *-------*
6439                           //     /|       |       /   10  /|
6440                           //    * |       |      *-------* |
6441                           //   /| |   6   |     /   9   /| |
6442                           //  * |2|       |    *-------* |4|
6443                           //  | | *-------*    |       | | *
6444                           //  |1|/   8   /     |       |3|/
6445                           //  | *-------*      |   5   | *
6446                           //  |/   7   /       |       |/
6447                           //  *-------*        *-------*
6448                           //
6449                           // note that we have to take care of the
6450                           // orientation of faces.
6451                           const int quad_indices[11] = {
6452                             new_quads[0]->index(), // 0
6453 
6454                             hex->face(0)->child_index(
6455                               child_at_origin[hex->face(0)->refinement_case() -
6456                                               1][f_fl[0]][f_ro[0]]), // 1
6457                             hex->face(0)->child_index(
6458                               1 -
6459                               child_at_origin[hex->face(0)->refinement_case() -
6460                                               1][f_fl[0]][f_ro[0]]),
6461 
6462                             hex->face(1)->child_index(
6463                               child_at_origin[hex->face(1)->refinement_case() -
6464                                               1][f_fl[1]][f_ro[1]]), // 3
6465                             hex->face(1)->child_index(
6466                               1 -
6467                               child_at_origin[hex->face(1)->refinement_case() -
6468                                               1][f_fl[1]][f_ro[1]]),
6469 
6470                             hex->face(2)->index(), // 5
6471 
6472                             hex->face(3)->index(), // 6
6473 
6474                             hex->face(4)->child_index(
6475                               child_at_origin[hex->face(4)->refinement_case() -
6476                                               1][f_fl[4]][f_ro[4]]), // 7
6477                             hex->face(4)->child_index(
6478                               1 -
6479                               child_at_origin[hex->face(4)->refinement_case() -
6480                                               1][f_fl[4]][f_ro[4]]),
6481 
6482                             hex->face(5)->child_index(
6483                               child_at_origin[hex->face(5)->refinement_case() -
6484                                               1][f_fl[5]][f_ro[5]]), // 9
6485                             hex->face(5)->child_index(
6486                               1 -
6487                               child_at_origin[hex->face(5)->refinement_case() -
6488                                               1][f_fl[5]][f_ro[5]])
6489 
6490                           };
6491 
6492                           new_hexes[0]->set_bounding_object_indices(
6493                             {quad_indices[1],
6494                              quad_indices[3],
6495                              quad_indices[5],
6496                              quad_indices[0],
6497                              quad_indices[7],
6498                              quad_indices[9]});
6499                           new_hexes[1]->set_bounding_object_indices(
6500                             {quad_indices[2],
6501                              quad_indices[4],
6502                              quad_indices[0],
6503                              quad_indices[6],
6504                              quad_indices[8],
6505                              quad_indices[10]});
6506                           break;
6507                         }
6508 
6509                       case RefinementCase<dim>::cut_z:
6510                         {
6511                           //////////////////////////////
6512                           //
6513                           //     RefinementCase<dim>::cut_z
6514                           //
6515                           // the refined cube will look like this:
6516                           //
6517                           //        *---------*
6518                           //       /         /|
6519                           //      /         / |
6520                           //     /         /  *
6521                           //    *---------*  /|
6522                           //    |         | / |
6523                           //    |         |/  *
6524                           //    *---------*  /
6525                           //    |         | /
6526                           //    |         |/
6527                           //    *---------*
6528                           //
6529                           // again, first collect some data about the
6530                           // indices of the lines, with the following
6531                           // numbering:
6532 
6533                           // face 0: left plane
6534                           //       *
6535                           //      /|
6536                           //     / |
6537                           //    /  *
6538                           //   *  /|
6539                           //   | 0 |
6540                           //   |/  *
6541                           // m0*  /
6542                           //   | /
6543                           //   |/
6544                           //   *
6545                           // face 1: right plane
6546                           //       *
6547                           //      /|
6548                           //     / |
6549                           //    /  *m1
6550                           //   *  /|
6551                           //   | 1 |
6552                           //   |/  *
6553                           //   *  /
6554                           //   | /
6555                           //   |/
6556                           //   *
6557                           // face 2: front plane
6558                           //   (note: x,y exchanged)
6559                           //   *-------*
6560                           //   |       |
6561                           // m0*---2---*
6562                           //   |       |
6563                           //   *-------*
6564                           // face 3: back plane
6565                           //   (note: x,y exchanged)
6566                           //   *-------*
6567                           //   |       |
6568                           //   *---3---*m1
6569                           //   |       |
6570                           //   *-------*
6571 
6572                           // set up a list of line iterators first. from
6573                           // this, construct lists of line_indices and
6574                           // line orientations later on
6575                           const typename Triangulation<dim, spacedim>::
6576                             raw_line_iterator lines[4] = {
6577                               hex->face(0)->child(0)->line(
6578                                 (hex->face(0)->refinement_case() ==
6579                                  RefinementCase<2>::cut_x) ?
6580                                   1 :
6581                                   3), // 0
6582                               hex->face(1)->child(0)->line(
6583                                 (hex->face(1)->refinement_case() ==
6584                                  RefinementCase<2>::cut_x) ?
6585                                   1 :
6586                                   3), // 1
6587                               hex->face(2)->child(0)->line(
6588                                 (hex->face(2)->refinement_case() ==
6589                                  RefinementCase<2>::cut_x) ?
6590                                   1 :
6591                                   3), // 2
6592                               hex->face(3)->child(0)->line(
6593                                 (hex->face(3)->refinement_case() ==
6594                                  RefinementCase<2>::cut_x) ?
6595                                   1 :
6596                                   3) // 3
6597                             };
6598 
6599                           unsigned int line_indices[4];
6600                           for (unsigned int i = 0; i < 4; ++i)
6601                             line_indices[i] = lines[i]->index();
6602 
6603                           // the orientation of lines for the inner quads
6604                           // is quite tricky. as these lines are newly
6605                           // created ones and thus have no parents, they
6606                           // cannot inherit this property. set up an array
6607                           // and fill it with the respective values
6608                           bool line_orientation[4];
6609 
6610                           // the middle vertex marked as m0 above is the
6611                           // start vertex for lines 0 and 2 in standard
6612                           // orientation, whereas m1 is the end vertex of
6613                           // lines 1 and 3 in standard orientation
6614                           const unsigned int middle_vertices[2] = {
6615                             middle_vertex_index<dim, spacedim>(hex->line(8)),
6616                             middle_vertex_index<dim, spacedim>(hex->line(11))};
6617 
6618                           for (unsigned int i = 0; i < 4; ++i)
6619                             if (lines[i]->vertex_index(i % 2) ==
6620                                 middle_vertices[i % 2])
6621                               line_orientation[i] = true;
6622                             else
6623                               {
6624                                 // it must be the other way round then
6625                                 Assert(lines[i]->vertex_index((i + 1) % 2) ==
6626                                          middle_vertices[i % 2],
6627                                        ExcInternalError());
6628                                 line_orientation[i] = false;
6629                               }
6630 
6631                           // set up the new quad, line numbering is as
6632                           // indicated above
6633                           new_quads[0]->set_bounding_object_indices(
6634                             {line_indices[0],
6635                              line_indices[1],
6636                              line_indices[2],
6637                              line_indices[3]});
6638 
6639                           new_quads[0]->set_line_orientation(
6640                             0, line_orientation[0]);
6641                           new_quads[0]->set_line_orientation(
6642                             1, line_orientation[1]);
6643                           new_quads[0]->set_line_orientation(
6644                             2, line_orientation[2]);
6645                           new_quads[0]->set_line_orientation(
6646                             3, line_orientation[3]);
6647 
6648                           // the quads are numbered as follows:
6649                           //
6650                           // planes in the interior of the old hex:
6651                           //
6652                           //      *
6653                           //     /|
6654                           //    / | x
6655                           //   /  | *-------*      *---------*
6656                           //  *   | |       |     /         /
6657                           //  |   | |       |    /    0    /
6658                           //  |   * |       |   /         /
6659                           //  |  /  *-------*y *---------*x
6660                           //  | /
6661                           //  |/
6662                           //  *
6663                           //
6664                           // children of the faces of the old hex
6665                           //
6666                           //      *---*---*        *-------*
6667                           //     /|   8   |       /       /|
6668                           //    / |       |      /   10  / |
6669                           //   /  *-------*     /       /  *
6670                           //  * 2/|       |    *-------* 4/|
6671                           //  | / |   7   |    |   6   | / |
6672                           //  |/1 *-------*    |       |/3 *
6673                           //  *  /       /     *-------*  /
6674                           //  | /   9   /      |       | /
6675                           //  |/       /       |   5   |/
6676                           //  *-------*        *---*---*
6677                           //
6678                           // note that we have to take care of the
6679                           // orientation of faces.
6680                           const int quad_indices[11] = {
6681                             new_quads[0]->index(), // 0
6682 
6683                             hex->face(0)->child_index(
6684                               child_at_origin[hex->face(0)->refinement_case() -
6685                                               1][f_fl[0]][f_ro[0]]), // 1
6686                             hex->face(0)->child_index(
6687                               1 -
6688                               child_at_origin[hex->face(0)->refinement_case() -
6689                                               1][f_fl[0]][f_ro[0]]),
6690 
6691                             hex->face(1)->child_index(
6692                               child_at_origin[hex->face(1)->refinement_case() -
6693                                               1][f_fl[1]][f_ro[1]]), // 3
6694                             hex->face(1)->child_index(
6695                               1 -
6696                               child_at_origin[hex->face(1)->refinement_case() -
6697                                               1][f_fl[1]][f_ro[1]]),
6698 
6699                             hex->face(2)->child_index(
6700                               child_at_origin[hex->face(2)->refinement_case() -
6701                                               1][f_fl[2]][f_ro[2]]), // 5
6702                             hex->face(2)->child_index(
6703                               1 -
6704                               child_at_origin[hex->face(2)->refinement_case() -
6705                                               1][f_fl[2]][f_ro[2]]),
6706 
6707                             hex->face(3)->child_index(
6708                               child_at_origin[hex->face(3)->refinement_case() -
6709                                               1][f_fl[3]][f_ro[3]]), // 7
6710                             hex->face(3)->child_index(
6711                               1 -
6712                               child_at_origin[hex->face(3)->refinement_case() -
6713                                               1][f_fl[3]][f_ro[3]]),
6714 
6715                             hex->face(4)->index(), // 9
6716 
6717                             hex->face(5)->index() // 10
6718                           };
6719 
6720                           new_hexes[0]->set_bounding_object_indices(
6721                             {quad_indices[1],
6722                              quad_indices[3],
6723                              quad_indices[5],
6724                              quad_indices[7],
6725                              quad_indices[9],
6726                              quad_indices[0]});
6727                           new_hexes[1]->set_bounding_object_indices(
6728                             {quad_indices[2],
6729                              quad_indices[4],
6730                              quad_indices[6],
6731                              quad_indices[8],
6732                              quad_indices[0],
6733                              quad_indices[10]});
6734                           break;
6735                         }
6736 
6737                       case RefinementCase<dim>::cut_xy:
6738                         {
6739                           //////////////////////////////
6740                           //
6741                           //     RefinementCase<dim>::cut_xy
6742                           //
6743                           // the refined cube will look like this:
6744                           //
6745                           //        *----*----*
6746                           //       /    /    /|
6747                           //      *----*----* |
6748                           //     /    /    /| |
6749                           //    *----*----* | |
6750                           //    |    |    | | |
6751                           //    |    |    | | *
6752                           //    |    |    | |/
6753                           //    |    |    | *
6754                           //    |    |    |/
6755                           //    *----*----*
6756                           //
6757 
6758                           // first, create the new internal line
6759                           new_lines[0]->set_bounding_object_indices(
6760                             {middle_vertex_index<dim, spacedim>(hex->face(4)),
6761                              middle_vertex_index<dim, spacedim>(hex->face(5))});
6762 
6763                           // again, first collect some data about the
6764                           // indices of the lines, with the following
6765                           // numbering:
6766 
6767                           // face 0: left plane
6768                           //       *
6769                           //      /|
6770                           //     * |
6771                           //    /| |
6772                           //   * | |
6773                           //   | 0 |
6774                           //   | | *
6775                           //   | |/
6776                           //   | *
6777                           //   |/
6778                           //   *
6779                           // face 1: right plane
6780                           //       *
6781                           //      /|
6782                           //     * |
6783                           //    /| |
6784                           //   * | |
6785                           //   | 1 |
6786                           //   | | *
6787                           //   | |/
6788                           //   | *
6789                           //   |/
6790                           //   *
6791                           // face 2: front plane
6792                           //   (note: x,y exchanged)
6793                           //   *---*---*
6794                           //   |   |   |
6795                           //   |   2   |
6796                           //   |   |   |
6797                           //   *-------*
6798                           // face 3: back plane
6799                           //   (note: x,y exchanged)
6800                           //   *---*---*
6801                           //   |   |   |
6802                           //   |   3   |
6803                           //   |   |   |
6804                           //   *---*---*
6805                           // face 4: bottom plane
6806                           //       *---*---*
6807                           //      /   5   /
6808                           //     *-6-*-7-*
6809                           //    /   4   /
6810                           //   *---*---*
6811                           // face 5: top plane
6812                           //       *---*---*
6813                           //      /   9   /
6814                           //     *10-*-11*
6815                           //    /   8   /
6816                           //   *---*---*
6817                           // middle planes
6818                           //     *-------*   *---*---*
6819                           //    /       /    |   |   |
6820                           //   /       /     |   12  |
6821                           //  /       /      |   |   |
6822                           // *-------*       *---*---*
6823 
6824                           // set up a list of line iterators first. from
6825                           // this, construct lists of line_indices and
6826                           // line orientations later on
6827                           const typename Triangulation<
6828                             dim,
6829                             spacedim>::raw_line_iterator lines[13] = {
6830                             hex->face(0)->child(0)->line(
6831                               (hex->face(0)->refinement_case() ==
6832                                RefinementCase<2>::cut_x) ?
6833                                 1 :
6834                                 3), // 0
6835                             hex->face(1)->child(0)->line(
6836                               (hex->face(1)->refinement_case() ==
6837                                RefinementCase<2>::cut_x) ?
6838                                 1 :
6839                                 3), // 1
6840                             hex->face(2)->child(0)->line(
6841                               (hex->face(2)->refinement_case() ==
6842                                RefinementCase<2>::cut_x) ?
6843                                 1 :
6844                                 3), // 2
6845                             hex->face(3)->child(0)->line(
6846                               (hex->face(3)->refinement_case() ==
6847                                RefinementCase<2>::cut_x) ?
6848                                 1 :
6849                                 3), // 3
6850 
6851                             hex->face(4)
6852                               ->isotropic_child(
6853                                 GeometryInfo<dim>::standard_to_real_face_vertex(
6854                                   0, f_or[4], f_fl[4], f_ro[4]))
6855                               ->line(
6856                                 GeometryInfo<dim>::standard_to_real_face_line(
6857                                   1, f_or[4], f_fl[4], f_ro[4])), // 4
6858                             hex->face(4)
6859                               ->isotropic_child(
6860                                 GeometryInfo<dim>::standard_to_real_face_vertex(
6861                                   3, f_or[4], f_fl[4], f_ro[4]))
6862                               ->line(
6863                                 GeometryInfo<dim>::standard_to_real_face_line(
6864                                   0, f_or[4], f_fl[4], f_ro[4])), // 5
6865                             hex->face(4)
6866                               ->isotropic_child(
6867                                 GeometryInfo<dim>::standard_to_real_face_vertex(
6868                                   0, f_or[4], f_fl[4], f_ro[4]))
6869                               ->line(
6870                                 GeometryInfo<dim>::standard_to_real_face_line(
6871                                   3, f_or[4], f_fl[4], f_ro[4])), // 6
6872                             hex->face(4)
6873                               ->isotropic_child(
6874                                 GeometryInfo<dim>::standard_to_real_face_vertex(
6875                                   3, f_or[4], f_fl[4], f_ro[4]))
6876                               ->line(
6877                                 GeometryInfo<dim>::standard_to_real_face_line(
6878                                   2, f_or[4], f_fl[4], f_ro[4])), // 7
6879 
6880                             hex->face(5)
6881                               ->isotropic_child(
6882                                 GeometryInfo<dim>::standard_to_real_face_vertex(
6883                                   0, f_or[5], f_fl[5], f_ro[5]))
6884                               ->line(
6885                                 GeometryInfo<dim>::standard_to_real_face_line(
6886                                   1, f_or[5], f_fl[5], f_ro[5])), // 8
6887                             hex->face(5)
6888                               ->isotropic_child(
6889                                 GeometryInfo<dim>::standard_to_real_face_vertex(
6890                                   3, f_or[5], f_fl[5], f_ro[5]))
6891                               ->line(
6892                                 GeometryInfo<dim>::standard_to_real_face_line(
6893                                   0, f_or[5], f_fl[5], f_ro[5])), // 9
6894                             hex->face(5)
6895                               ->isotropic_child(
6896                                 GeometryInfo<dim>::standard_to_real_face_vertex(
6897                                   0, f_or[5], f_fl[5], f_ro[5]))
6898                               ->line(
6899                                 GeometryInfo<dim>::standard_to_real_face_line(
6900                                   3, f_or[5], f_fl[5], f_ro[5])), // 10
6901                             hex->face(5)
6902                               ->isotropic_child(
6903                                 GeometryInfo<dim>::standard_to_real_face_vertex(
6904                                   3, f_or[5], f_fl[5], f_ro[5]))
6905                               ->line(
6906                                 GeometryInfo<dim>::standard_to_real_face_line(
6907                                   2, f_or[5], f_fl[5], f_ro[5])), // 11
6908 
6909                             new_lines[0] // 12
6910                           };
6911 
6912                           unsigned int line_indices[13];
6913                           for (unsigned int i = 0; i < 13; ++i)
6914                             line_indices[i] = lines[i]->index();
6915 
6916                           // the orientation of lines for the inner quads
6917                           // is quite tricky. as these lines are newly
6918                           // created ones and thus have no parents, they
6919                           // cannot inherit this property. set up an array
6920                           // and fill it with the respective values
6921                           bool line_orientation[13];
6922 
6923                           // the middle vertices of the lines of our
6924                           // bottom face
6925                           const unsigned int middle_vertices[4] = {
6926                             hex->line(0)->child(0)->vertex_index(1),
6927                             hex->line(1)->child(0)->vertex_index(1),
6928                             hex->line(2)->child(0)->vertex_index(1),
6929                             hex->line(3)->child(0)->vertex_index(1),
6930                           };
6931 
6932                           // note: for lines 0 to 3 the orientation of the
6933                           // line is 'true', if vertex 0 is on the bottom
6934                           // face
6935                           for (unsigned int i = 0; i < 4; ++i)
6936                             if (lines[i]->vertex_index(0) == middle_vertices[i])
6937                               line_orientation[i] = true;
6938                             else
6939                               {
6940                                 // it must be the other way round then
6941                                 Assert(lines[i]->vertex_index(1) ==
6942                                          middle_vertices[i],
6943                                        ExcInternalError());
6944                                 line_orientation[i] = false;
6945                               }
6946 
6947                           // note: for lines 4 to 11 (inner lines of the
6948                           // outer quads) the following holds: the second
6949                           // vertex of the even lines in standard
6950                           // orientation is the vertex in the middle of
6951                           // the quad, whereas for odd lines the first
6952                           // vertex is the same middle vertex.
6953                           for (unsigned int i = 4; i < 12; ++i)
6954                             if (lines[i]->vertex_index((i + 1) % 2) ==
6955                                 middle_vertex_index<dim, spacedim>(
6956                                   hex->face(3 + i / 4)))
6957                               line_orientation[i] = true;
6958                             else
6959                               {
6960                                 // it must be the other way
6961                                 // round then
6962                                 Assert(lines[i]->vertex_index(i % 2) ==
6963                                          (middle_vertex_index<dim, spacedim>(
6964                                            hex->face(3 + i / 4))),
6965                                        ExcInternalError());
6966                                 line_orientation[i] = false;
6967                               }
6968                           // for the last line the line orientation is
6969                           // always true, since it was just constructed
6970                           // that way
6971                           line_orientation[12] = true;
6972 
6973                           // set up the 4 quads, numbered as follows (left
6974                           // quad numbering, right line numbering
6975                           // extracted from above)
6976                           //
6977                           //      *          *
6978                           //     /|         9|
6979                           //    * |        * |
6980                           //  y/| |       8| 3
6981                           //  * |1|      * | |
6982                           //  | | |x     | 12|
6983                           //  |0| *      | | *
6984                           //  | |/       2 |5
6985                           //  | *        | *
6986                           //  |/         |4
6987                           //  *          *
6988                           //
6989                           //  x
6990                           //  *---*---*      *10-*-11*
6991                           //  |   |   |      |   |   |
6992                           //  | 2 | 3 |      0   12  1
6993                           //  |   |   |      |   |   |
6994                           //  *---*---*y     *-6-*-7-*
6995 
6996                           new_quads[0]->set_bounding_object_indices(
6997                             {line_indices[2],
6998                              line_indices[12],
6999                              line_indices[4],
7000                              line_indices[8]});
7001                           new_quads[1]->set_bounding_object_indices(
7002                             {line_indices[12],
7003                              line_indices[3],
7004                              line_indices[5],
7005                              line_indices[9]});
7006                           new_quads[2]->set_bounding_object_indices(
7007                             {line_indices[6],
7008                              line_indices[10],
7009                              line_indices[0],
7010                              line_indices[12]});
7011                           new_quads[3]->set_bounding_object_indices(
7012                             {line_indices[7],
7013                              line_indices[11],
7014                              line_indices[12],
7015                              line_indices[1]});
7016 
7017                           new_quads[0]->set_line_orientation(
7018                             0, line_orientation[2]);
7019                           new_quads[0]->set_line_orientation(
7020                             2, line_orientation[4]);
7021                           new_quads[0]->set_line_orientation(
7022                             3, line_orientation[8]);
7023 
7024                           new_quads[1]->set_line_orientation(
7025                             1, line_orientation[3]);
7026                           new_quads[1]->set_line_orientation(
7027                             2, line_orientation[5]);
7028                           new_quads[1]->set_line_orientation(
7029                             3, line_orientation[9]);
7030 
7031                           new_quads[2]->set_line_orientation(
7032                             0, line_orientation[6]);
7033                           new_quads[2]->set_line_orientation(
7034                             1, line_orientation[10]);
7035                           new_quads[2]->set_line_orientation(
7036                             2, line_orientation[0]);
7037 
7038                           new_quads[3]->set_line_orientation(
7039                             0, line_orientation[7]);
7040                           new_quads[3]->set_line_orientation(
7041                             1, line_orientation[11]);
7042                           new_quads[3]->set_line_orientation(
7043                             3, line_orientation[1]);
7044 
7045                           // the quads are numbered as follows:
7046                           //
7047                           // planes in the interior of the old hex:
7048                           //
7049                           //      *
7050                           //     /|
7051                           //    * | x
7052                           //   /| | *---*---*      *---------*
7053                           //  * |1| |   |   |     /         /
7054                           //  | | | | 2 | 3 |    /         /
7055                           //  |0| * |   |   |   /         /
7056                           //  | |/  *---*---*y *---------*x
7057                           //  | *
7058                           //  |/
7059                           //  *
7060                           //
7061                           // children of the faces of the old hex
7062                           //
7063                           //      *---*---*        *---*---*
7064                           //     /|   |   |       /18 / 19/|
7065                           //    * |10 | 11|      /---/---* |
7066                           //   /| |   |   |     /16 / 17/| |
7067                           //  * |5|   |   |    *---*---* |7|
7068                           //  | | *---*---*    |   |   | | *
7069                           //  |4|/14 / 15/     |   |   |6|/
7070                           //  | *---/---/      | 8 | 9 | *
7071                           //  |/12 / 13/       |   |   |/
7072                           //  *---*---*        *---*---*
7073                           //
7074                           // note that we have to take care of the
7075                           // orientation of faces.
7076                           const int quad_indices[20] = {
7077                             new_quads[0]->index(), // 0
7078                             new_quads[1]->index(),
7079                             new_quads[2]->index(),
7080                             new_quads[3]->index(),
7081 
7082                             hex->face(0)->child_index(
7083                               child_at_origin[hex->face(0)->refinement_case() -
7084                                               1][f_fl[0]][f_ro[0]]), // 4
7085                             hex->face(0)->child_index(
7086                               1 -
7087                               child_at_origin[hex->face(0)->refinement_case() -
7088                                               1][f_fl[0]][f_ro[0]]),
7089 
7090                             hex->face(1)->child_index(
7091                               child_at_origin[hex->face(1)->refinement_case() -
7092                                               1][f_fl[1]][f_ro[1]]), // 6
7093                             hex->face(1)->child_index(
7094                               1 -
7095                               child_at_origin[hex->face(1)->refinement_case() -
7096                                               1][f_fl[1]][f_ro[1]]),
7097 
7098                             hex->face(2)->child_index(
7099                               child_at_origin[hex->face(2)->refinement_case() -
7100                                               1][f_fl[2]][f_ro[2]]), // 8
7101                             hex->face(2)->child_index(
7102                               1 -
7103                               child_at_origin[hex->face(2)->refinement_case() -
7104                                               1][f_fl[2]][f_ro[2]]),
7105 
7106                             hex->face(3)->child_index(
7107                               child_at_origin[hex->face(3)->refinement_case() -
7108                                               1][f_fl[3]][f_ro[3]]), // 10
7109                             hex->face(3)->child_index(
7110                               1 -
7111                               child_at_origin[hex->face(3)->refinement_case() -
7112                                               1][f_fl[3]][f_ro[3]]),
7113 
7114                             hex->face(4)->isotropic_child_index(
7115                               GeometryInfo<dim>::standard_to_real_face_vertex(
7116                                 0, f_or[4], f_fl[4], f_ro[4])), // 12
7117                             hex->face(4)->isotropic_child_index(
7118                               GeometryInfo<dim>::standard_to_real_face_vertex(
7119                                 1, f_or[4], f_fl[4], f_ro[4])),
7120                             hex->face(4)->isotropic_child_index(
7121                               GeometryInfo<dim>::standard_to_real_face_vertex(
7122                                 2, f_or[4], f_fl[4], f_ro[4])),
7123                             hex->face(4)->isotropic_child_index(
7124                               GeometryInfo<dim>::standard_to_real_face_vertex(
7125                                 3, f_or[4], f_fl[4], f_ro[4])),
7126 
7127                             hex->face(5)->isotropic_child_index(
7128                               GeometryInfo<dim>::standard_to_real_face_vertex(
7129                                 0, f_or[5], f_fl[5], f_ro[5])), // 16
7130                             hex->face(5)->isotropic_child_index(
7131                               GeometryInfo<dim>::standard_to_real_face_vertex(
7132                                 1, f_or[5], f_fl[5], f_ro[5])),
7133                             hex->face(5)->isotropic_child_index(
7134                               GeometryInfo<dim>::standard_to_real_face_vertex(
7135                                 2, f_or[5], f_fl[5], f_ro[5])),
7136                             hex->face(5)->isotropic_child_index(
7137                               GeometryInfo<dim>::standard_to_real_face_vertex(
7138                                 3, f_or[5], f_fl[5], f_ro[5]))};
7139 
7140                           new_hexes[0]->set_bounding_object_indices(
7141                             {quad_indices[4],
7142                              quad_indices[0],
7143                              quad_indices[8],
7144                              quad_indices[2],
7145                              quad_indices[12],
7146                              quad_indices[16]});
7147                           new_hexes[1]->set_bounding_object_indices(
7148                             {quad_indices[0],
7149                              quad_indices[6],
7150                              quad_indices[9],
7151                              quad_indices[3],
7152                              quad_indices[13],
7153                              quad_indices[17]});
7154                           new_hexes[2]->set_bounding_object_indices(
7155                             {quad_indices[5],
7156                              quad_indices[1],
7157                              quad_indices[2],
7158                              quad_indices[10],
7159                              quad_indices[14],
7160                              quad_indices[18]});
7161                           new_hexes[3]->set_bounding_object_indices(
7162                             {quad_indices[1],
7163                              quad_indices[7],
7164                              quad_indices[3],
7165                              quad_indices[11],
7166                              quad_indices[15],
7167                              quad_indices[19]});
7168                           break;
7169                         }
7170 
7171                       case RefinementCase<dim>::cut_xz:
7172                         {
7173                           //////////////////////////////
7174                           //
7175                           //     RefinementCase<dim>::cut_xz
7176                           //
7177                           // the refined cube will look like this:
7178                           //
7179                           //        *----*----*
7180                           //       /    /    /|
7181                           //      /    /    / |
7182                           //     /    /    /  *
7183                           //    *----*----*  /|
7184                           //    |    |    | / |
7185                           //    |    |    |/  *
7186                           //    *----*----*  /
7187                           //    |    |    | /
7188                           //    |    |    |/
7189                           //    *----*----*
7190                           //
7191 
7192                           // first, create the new internal line
7193                           new_lines[0]->set_bounding_object_indices(
7194                             {middle_vertex_index<dim, spacedim>(hex->face(2)),
7195                              middle_vertex_index<dim, spacedim>(hex->face(3))});
7196 
7197                           // again, first collect some data about the
7198                           // indices of the lines, with the following
7199                           // numbering:
7200 
7201                           // face 0: left plane
7202                           //       *
7203                           //      /|
7204                           //     / |
7205                           //    /  *
7206                           //   *  /|
7207                           //   | 0 |
7208                           //   |/  *
7209                           //   *  /
7210                           //   | /
7211                           //   |/
7212                           //   *
7213                           // face 1: right plane
7214                           //       *
7215                           //      /|
7216                           //     / |
7217                           //    /  *
7218                           //   *  /|
7219                           //   | 1 |
7220                           //   |/  *
7221                           //   *  /
7222                           //   | /
7223                           //   |/
7224                           //   *
7225                           // face 2: front plane
7226                           //   (note: x,y exchanged)
7227                           //   *---*---*
7228                           //   |   5   |
7229                           //   *-6-*-7-*
7230                           //   |   4   |
7231                           //   *---*---*
7232                           // face 3: back plane
7233                           //   (note: x,y exchanged)
7234                           //   *---*---*
7235                           //   |   9   |
7236                           //   *10-*-11*
7237                           //   |   8   |
7238                           //   *---*---*
7239                           // face 4: bottom plane
7240                           //       *---*---*
7241                           //      /   /   /
7242                           //     /   2   /
7243                           //    /   /   /
7244                           //   *---*---*
7245                           // face 5: top plane
7246                           //       *---*---*
7247                           //      /   /   /
7248                           //     /   3   /
7249                           //    /   /   /
7250                           //   *---*---*
7251                           // middle planes
7252                           //     *---*---*   *-------*
7253                           //    /   /   /    |       |
7254                           //   /   12  /     |       |
7255                           //  /   /   /      |       |
7256                           // *---*---*       *-------*
7257 
7258                           // set up a list of line iterators first. from
7259                           // this, construct lists of line_indices and
7260                           // line orientations later on
7261                           const typename Triangulation<
7262                             dim,
7263                             spacedim>::raw_line_iterator lines[13] = {
7264                             hex->face(0)->child(0)->line(
7265                               (hex->face(0)->refinement_case() ==
7266                                RefinementCase<2>::cut_x) ?
7267                                 1 :
7268                                 3), // 0
7269                             hex->face(1)->child(0)->line(
7270                               (hex->face(1)->refinement_case() ==
7271                                RefinementCase<2>::cut_x) ?
7272                                 1 :
7273                                 3), // 1
7274                             hex->face(4)->child(0)->line(
7275                               (hex->face(4)->refinement_case() ==
7276                                RefinementCase<2>::cut_x) ?
7277                                 1 :
7278                                 3), // 2
7279                             hex->face(5)->child(0)->line(
7280                               (hex->face(5)->refinement_case() ==
7281                                RefinementCase<2>::cut_x) ?
7282                                 1 :
7283                                 3), // 3
7284 
7285                             hex->face(2)
7286                               ->isotropic_child(
7287                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7288                                   0, f_or[2], f_fl[2], f_ro[2]))
7289                               ->line(
7290                                 GeometryInfo<dim>::standard_to_real_face_line(
7291                                   3, f_or[2], f_fl[2], f_ro[2])), // 4
7292                             hex->face(2)
7293                               ->isotropic_child(
7294                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7295                                   3, f_or[2], f_fl[2], f_ro[2]))
7296                               ->line(
7297                                 GeometryInfo<dim>::standard_to_real_face_line(
7298                                   2, f_or[2], f_fl[2], f_ro[2])), // 5
7299                             hex->face(2)
7300                               ->isotropic_child(
7301                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7302                                   0, f_or[2], f_fl[2], f_ro[2]))
7303                               ->line(
7304                                 GeometryInfo<dim>::standard_to_real_face_line(
7305                                   1, f_or[2], f_fl[2], f_ro[2])), // 6
7306                             hex->face(2)
7307                               ->isotropic_child(
7308                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7309                                   3, f_or[2], f_fl[2], f_ro[2]))
7310                               ->line(
7311                                 GeometryInfo<dim>::standard_to_real_face_line(
7312                                   0, f_or[2], f_fl[2], f_ro[2])), // 7
7313 
7314                             hex->face(3)
7315                               ->isotropic_child(
7316                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7317                                   0, f_or[3], f_fl[3], f_ro[3]))
7318                               ->line(
7319                                 GeometryInfo<dim>::standard_to_real_face_line(
7320                                   3, f_or[3], f_fl[3], f_ro[3])), // 8
7321                             hex->face(3)
7322                               ->isotropic_child(
7323                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7324                                   3, f_or[3], f_fl[3], f_ro[3]))
7325                               ->line(
7326                                 GeometryInfo<dim>::standard_to_real_face_line(
7327                                   2, f_or[3], f_fl[3], f_ro[3])), // 9
7328                             hex->face(3)
7329                               ->isotropic_child(
7330                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7331                                   0, f_or[3], f_fl[3], f_ro[3]))
7332                               ->line(
7333                                 GeometryInfo<dim>::standard_to_real_face_line(
7334                                   1, f_or[3], f_fl[3], f_ro[3])), // 10
7335                             hex->face(3)
7336                               ->isotropic_child(
7337                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7338                                   3, f_or[3], f_fl[3], f_ro[3]))
7339                               ->line(
7340                                 GeometryInfo<dim>::standard_to_real_face_line(
7341                                   0, f_or[3], f_fl[3], f_ro[3])), // 11
7342 
7343                             new_lines[0] // 12
7344                           };
7345 
7346                           unsigned int line_indices[13];
7347                           for (unsigned int i = 0; i < 13; ++i)
7348                             line_indices[i] = lines[i]->index();
7349 
7350                           // the orientation of lines for the inner quads
7351                           // is quite tricky. as these lines are newly
7352                           // created ones and thus have no parents, they
7353                           // cannot inherit this property. set up an array
7354                           // and fill it with the respective values
7355                           bool line_orientation[13];
7356 
7357                           // the middle vertices of the
7358                           // lines of our front face
7359                           const unsigned int middle_vertices[4] = {
7360                             hex->line(8)->child(0)->vertex_index(1),
7361                             hex->line(9)->child(0)->vertex_index(1),
7362                             hex->line(2)->child(0)->vertex_index(1),
7363                             hex->line(6)->child(0)->vertex_index(1),
7364                           };
7365 
7366                           // note: for lines 0 to 3 the orientation of the
7367                           // line is 'true', if vertex 0 is on the front
7368                           for (unsigned int i = 0; i < 4; ++i)
7369                             if (lines[i]->vertex_index(0) == middle_vertices[i])
7370                               line_orientation[i] = true;
7371                             else
7372                               {
7373                                 // it must be the other way round then
7374                                 Assert(lines[i]->vertex_index(1) ==
7375                                          middle_vertices[i],
7376                                        ExcInternalError());
7377                                 line_orientation[i] = false;
7378                               }
7379 
7380                           // note: for lines 4 to 11 (inner lines of the
7381                           // outer quads) the following holds: the second
7382                           // vertex of the even lines in standard
7383                           // orientation is the vertex in the middle of
7384                           // the quad, whereas for odd lines the first
7385                           // vertex is the same middle vertex.
7386                           for (unsigned int i = 4; i < 12; ++i)
7387                             if (lines[i]->vertex_index((i + 1) % 2) ==
7388                                 middle_vertex_index<dim, spacedim>(
7389                                   hex->face(1 + i / 4)))
7390                               line_orientation[i] = true;
7391                             else
7392                               {
7393                                 // it must be the other way
7394                                 // round then
7395                                 Assert(lines[i]->vertex_index(i % 2) ==
7396                                          (middle_vertex_index<dim, spacedim>(
7397                                            hex->face(1 + i / 4))),
7398                                        ExcInternalError());
7399                                 line_orientation[i] = false;
7400                               }
7401                           // for the last line the line orientation is
7402                           // always true, since it was just constructed
7403                           // that way
7404                           line_orientation[12] = true;
7405 
7406                           // set up the 4 quads, numbered as follows (left
7407                           // quad numbering, right line numbering
7408                           // extracted from above), the drawings denote
7409                           // middle planes
7410                           //
7411                           //      *          *
7412                           //     /|         /|
7413                           //    / |        3 9
7414                           //  y/  *       /  *
7415                           //  * 3/|      *  /|
7416                           //  | / |x     5 12|8
7417                           //  |/  *      |/  *
7418                           //  * 2/       *  /
7419                           //  | /        4 2
7420                           //  |/         |/
7421                           //  *          *
7422                           //
7423                           //       y
7424                           //      *----*----*      *-10-*-11-*
7425                           //     /    /    /      /    /    /
7426                           //    / 0  /  1 /      0    12   1
7427                           //   /    /    /      /    /    /
7428                           //  *----*----*x     *--6-*--7-*
7429 
7430                           new_quads[0]->set_bounding_object_indices(
7431                             {line_indices[0],
7432                              line_indices[12],
7433                              line_indices[6],
7434                              line_indices[10]});
7435                           new_quads[1]->set_bounding_object_indices(
7436                             {line_indices[12],
7437                              line_indices[1],
7438                              line_indices[7],
7439                              line_indices[11]});
7440                           new_quads[2]->set_bounding_object_indices(
7441                             {line_indices[4],
7442                              line_indices[8],
7443                              line_indices[2],
7444                              line_indices[12]});
7445                           new_quads[3]->set_bounding_object_indices(
7446                             {line_indices[5],
7447                              line_indices[9],
7448                              line_indices[12],
7449                              line_indices[3]});
7450 
7451                           new_quads[0]->set_line_orientation(
7452                             0, line_orientation[0]);
7453                           new_quads[0]->set_line_orientation(
7454                             2, line_orientation[6]);
7455                           new_quads[0]->set_line_orientation(
7456                             3, line_orientation[10]);
7457 
7458                           new_quads[1]->set_line_orientation(
7459                             1, line_orientation[1]);
7460                           new_quads[1]->set_line_orientation(
7461                             2, line_orientation[7]);
7462                           new_quads[1]->set_line_orientation(
7463                             3, line_orientation[11]);
7464 
7465                           new_quads[2]->set_line_orientation(
7466                             0, line_orientation[4]);
7467                           new_quads[2]->set_line_orientation(
7468                             1, line_orientation[8]);
7469                           new_quads[2]->set_line_orientation(
7470                             2, line_orientation[2]);
7471 
7472                           new_quads[3]->set_line_orientation(
7473                             0, line_orientation[5]);
7474                           new_quads[3]->set_line_orientation(
7475                             1, line_orientation[9]);
7476                           new_quads[3]->set_line_orientation(
7477                             3, line_orientation[3]);
7478 
7479                           // the quads are numbered as follows:
7480                           //
7481                           // planes in the interior of the old hex:
7482                           //
7483                           //      *
7484                           //     /|
7485                           //    / | x
7486                           //   /3 * *-------*      *----*----*
7487                           //  *  /| |       |     /    /    /
7488                           //  | / | |       |    /  0 /  1 /
7489                           //  |/  * |       |   /    /    /
7490                           //  * 2/  *-------*y *----*----*x
7491                           //  | /
7492                           //  |/
7493                           //  *
7494                           //
7495                           // children of the faces
7496                           // of the old hex
7497                           //      *---*---*        *---*---*
7498                           //     /|13 | 15|       /   /   /|
7499                           //    / |   |   |      /18 / 19/ |
7500                           //   /  *---*---*     /   /   /  *
7501                           //  * 5/|   |   |    *---*---* 7/|
7502                           //  | / |12 | 14|    | 9 | 11| / |
7503                           //  |/4 *---*---*    |   |   |/6 *
7504                           //  *  /   /   /     *---*---*  /
7505                           //  | /16 / 17/      |   |   | /
7506                           //  |/   /   /       | 8 | 10|/
7507                           //  *---*---*        *---*---*
7508                           //
7509                           // note that we have to take care of the
7510                           // orientation of faces.
7511                           const int quad_indices[20] = {
7512                             new_quads[0]->index(), // 0
7513                             new_quads[1]->index(),
7514                             new_quads[2]->index(),
7515                             new_quads[3]->index(),
7516 
7517                             hex->face(0)->child_index(
7518                               child_at_origin[hex->face(0)->refinement_case() -
7519                                               1][f_fl[0]][f_ro[0]]), // 4
7520                             hex->face(0)->child_index(
7521                               1 -
7522                               child_at_origin[hex->face(0)->refinement_case() -
7523                                               1][f_fl[0]][f_ro[0]]),
7524 
7525                             hex->face(1)->child_index(
7526                               child_at_origin[hex->face(1)->refinement_case() -
7527                                               1][f_fl[1]][f_ro[1]]), // 6
7528                             hex->face(1)->child_index(
7529                               1 -
7530                               child_at_origin[hex->face(1)->refinement_case() -
7531                                               1][f_fl[1]][f_ro[1]]),
7532 
7533                             hex->face(2)->isotropic_child_index(
7534                               GeometryInfo<dim>::standard_to_real_face_vertex(
7535                                 0, f_or[2], f_fl[2], f_ro[2])), // 8
7536                             hex->face(2)->isotropic_child_index(
7537                               GeometryInfo<dim>::standard_to_real_face_vertex(
7538                                 1, f_or[2], f_fl[2], f_ro[2])),
7539                             hex->face(2)->isotropic_child_index(
7540                               GeometryInfo<dim>::standard_to_real_face_vertex(
7541                                 2, f_or[2], f_fl[2], f_ro[2])),
7542                             hex->face(2)->isotropic_child_index(
7543                               GeometryInfo<dim>::standard_to_real_face_vertex(
7544                                 3, f_or[2], f_fl[2], f_ro[2])),
7545 
7546                             hex->face(3)->isotropic_child_index(
7547                               GeometryInfo<dim>::standard_to_real_face_vertex(
7548                                 0, f_or[3], f_fl[3], f_ro[3])), // 12
7549                             hex->face(3)->isotropic_child_index(
7550                               GeometryInfo<dim>::standard_to_real_face_vertex(
7551                                 1, f_or[3], f_fl[3], f_ro[3])),
7552                             hex->face(3)->isotropic_child_index(
7553                               GeometryInfo<dim>::standard_to_real_face_vertex(
7554                                 2, f_or[3], f_fl[3], f_ro[3])),
7555                             hex->face(3)->isotropic_child_index(
7556                               GeometryInfo<dim>::standard_to_real_face_vertex(
7557                                 3, f_or[3], f_fl[3], f_ro[3])),
7558 
7559                             hex->face(4)->child_index(
7560                               child_at_origin[hex->face(4)->refinement_case() -
7561                                               1][f_fl[4]][f_ro[4]]), // 16
7562                             hex->face(4)->child_index(
7563                               1 -
7564                               child_at_origin[hex->face(4)->refinement_case() -
7565                                               1][f_fl[4]][f_ro[4]]),
7566 
7567                             hex->face(5)->child_index(
7568                               child_at_origin[hex->face(5)->refinement_case() -
7569                                               1][f_fl[5]][f_ro[5]]), // 18
7570                             hex->face(5)->child_index(
7571                               1 -
7572                               child_at_origin[hex->face(5)->refinement_case() -
7573                                               1][f_fl[5]][f_ro[5]])};
7574 
7575                           // due to the exchange of x and y for the front
7576                           // and back face, we order the children
7577                           // according to
7578                           //
7579                           // *---*---*
7580                           // | 1 | 3 |
7581                           // *---*---*
7582                           // | 0 | 2 |
7583                           // *---*---*
7584                           new_hexes[0]->set_bounding_object_indices(
7585                             {quad_indices[4],
7586                              quad_indices[2],
7587                              quad_indices[8],
7588                              quad_indices[12],
7589                              quad_indices[16],
7590                              quad_indices[0]});
7591                           new_hexes[1]->set_bounding_object_indices(
7592                             {quad_indices[5],
7593                              quad_indices[3],
7594                              quad_indices[9],
7595                              quad_indices[13],
7596                              quad_indices[0],
7597                              quad_indices[18]});
7598                           new_hexes[2]->set_bounding_object_indices(
7599                             {quad_indices[2],
7600                              quad_indices[6],
7601                              quad_indices[10],
7602                              quad_indices[14],
7603                              quad_indices[17],
7604                              quad_indices[1]});
7605                           new_hexes[3]->set_bounding_object_indices(
7606                             {quad_indices[3],
7607                              quad_indices[7],
7608                              quad_indices[11],
7609                              quad_indices[15],
7610                              quad_indices[1],
7611                              quad_indices[19]});
7612                           break;
7613                         }
7614 
7615                       case RefinementCase<dim>::cut_yz:
7616                         {
7617                           //////////////////////////////
7618                           //
7619                           //     RefinementCase<dim>::cut_yz
7620                           //
7621                           // the refined cube will look like this:
7622                           //
7623                           //        *---------*
7624                           //       /         /|
7625                           //      *---------* |
7626                           //     /         /| |
7627                           //    *---------* |/|
7628                           //    |         | * |
7629                           //    |         |/| *
7630                           //    *---------* |/
7631                           //    |         | *
7632                           //    |         |/
7633                           //    *---------*
7634                           //
7635 
7636                           // first, create the new
7637                           // internal line
7638                           new_lines[0]->set_bounding_object_indices(
7639 
7640                             {middle_vertex_index<dim, spacedim>(hex->face(0)),
7641                              middle_vertex_index<dim, spacedim>(hex->face(1))});
7642 
7643                           // again, first collect some data about the
7644                           // indices of the lines, with the following
7645                           // numbering: (note that face 0 and 1 each are
7646                           // shown twice for better readability)
7647 
7648                           // face 0: left plane
7649                           //       *            *
7650                           //      /|           /|
7651                           //     * |          * |
7652                           //    /| *         /| *
7653                           //   * 5/|        * |7|
7654                           //   | * |        | * |
7655                           //   |/| *        |6| *
7656                           //   * 4/         * |/
7657                           //   | *          | *
7658                           //   |/           |/
7659                           //   *            *
7660                           // face 1: right plane
7661                           //       *            *
7662                           //      /|           /|
7663                           //     * |          * |
7664                           //    /| *         /| *
7665                           //   * 9/|        * |11
7666                           //   | * |        | * |
7667                           //   |/| *        |10 *
7668                           //   * 8/         * |/
7669                           //   | *          | *
7670                           //   |/           |/
7671                           //   *            *
7672                           // face 2: front plane
7673                           //   (note: x,y exchanged)
7674                           //   *-------*
7675                           //   |       |
7676                           //   *---0---*
7677                           //   |       |
7678                           //   *-------*
7679                           // face 3: back plane
7680                           //   (note: x,y exchanged)
7681                           //   *-------*
7682                           //   |       |
7683                           //   *---1---*
7684                           //   |       |
7685                           //   *-------*
7686                           // face 4: bottom plane
7687                           //       *-------*
7688                           //      /       /
7689                           //     *---2---*
7690                           //    /       /
7691                           //   *-------*
7692                           // face 5: top plane
7693                           //       *-------*
7694                           //      /       /
7695                           //     *---3---*
7696                           //    /       /
7697                           //   *-------*
7698                           // middle planes
7699                           //     *-------*   *-------*
7700                           //    /       /    |       |
7701                           //   *---12--*     |       |
7702                           //  /       /      |       |
7703                           // *-------*       *-------*
7704 
7705                           // set up a list of line iterators first. from
7706                           // this, construct lists of line_indices and
7707                           // line orientations later on
7708                           const typename Triangulation<
7709                             dim,
7710                             spacedim>::raw_line_iterator lines[13] = {
7711                             hex->face(2)->child(0)->line(
7712                               (hex->face(2)->refinement_case() ==
7713                                RefinementCase<2>::cut_x) ?
7714                                 1 :
7715                                 3), // 0
7716                             hex->face(3)->child(0)->line(
7717                               (hex->face(3)->refinement_case() ==
7718                                RefinementCase<2>::cut_x) ?
7719                                 1 :
7720                                 3), // 1
7721                             hex->face(4)->child(0)->line(
7722                               (hex->face(4)->refinement_case() ==
7723                                RefinementCase<2>::cut_x) ?
7724                                 1 :
7725                                 3), // 2
7726                             hex->face(5)->child(0)->line(
7727                               (hex->face(5)->refinement_case() ==
7728                                RefinementCase<2>::cut_x) ?
7729                                 1 :
7730                                 3), // 3
7731 
7732                             hex->face(0)
7733                               ->isotropic_child(
7734                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7735                                   0, f_or[0], f_fl[0], f_ro[0]))
7736                               ->line(
7737                                 GeometryInfo<dim>::standard_to_real_face_line(
7738                                   1, f_or[0], f_fl[0], f_ro[0])), // 4
7739                             hex->face(0)
7740                               ->isotropic_child(
7741                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7742                                   3, f_or[0], f_fl[0], f_ro[0]))
7743                               ->line(
7744                                 GeometryInfo<dim>::standard_to_real_face_line(
7745                                   0, f_or[0], f_fl[0], f_ro[0])), // 5
7746                             hex->face(0)
7747                               ->isotropic_child(
7748                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7749                                   0, f_or[0], f_fl[0], f_ro[0]))
7750                               ->line(
7751                                 GeometryInfo<dim>::standard_to_real_face_line(
7752                                   3, f_or[0], f_fl[0], f_ro[0])), // 6
7753                             hex->face(0)
7754                               ->isotropic_child(
7755                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7756                                   3, f_or[0], f_fl[0], f_ro[0]))
7757                               ->line(
7758                                 GeometryInfo<dim>::standard_to_real_face_line(
7759                                   2, f_or[0], f_fl[0], f_ro[0])), // 7
7760 
7761                             hex->face(1)
7762                               ->isotropic_child(
7763                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7764                                   0, f_or[1], f_fl[1], f_ro[1]))
7765                               ->line(
7766                                 GeometryInfo<dim>::standard_to_real_face_line(
7767                                   1, f_or[1], f_fl[1], f_ro[1])), // 8
7768                             hex->face(1)
7769                               ->isotropic_child(
7770                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7771                                   3, f_or[1], f_fl[1], f_ro[1]))
7772                               ->line(
7773                                 GeometryInfo<dim>::standard_to_real_face_line(
7774                                   0, f_or[1], f_fl[1], f_ro[1])), // 9
7775                             hex->face(1)
7776                               ->isotropic_child(
7777                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7778                                   0, f_or[1], f_fl[1], f_ro[1]))
7779                               ->line(
7780                                 GeometryInfo<dim>::standard_to_real_face_line(
7781                                   3, f_or[1], f_fl[1], f_ro[1])), // 10
7782                             hex->face(1)
7783                               ->isotropic_child(
7784                                 GeometryInfo<dim>::standard_to_real_face_vertex(
7785                                   3, f_or[1], f_fl[1], f_ro[1]))
7786                               ->line(
7787                                 GeometryInfo<dim>::standard_to_real_face_line(
7788                                   2, f_or[1], f_fl[1], f_ro[1])), // 11
7789 
7790                             new_lines[0] // 12
7791                           };
7792 
7793                           unsigned int line_indices[13];
7794 
7795                           for (unsigned int i = 0; i < 13; ++i)
7796                             line_indices[i] = lines[i]->index();
7797 
7798                           // the orientation of lines for the inner quads
7799                           // is quite tricky. as these lines are newly
7800                           // created ones and thus have no parents, they
7801                           // cannot inherit this property. set up an array
7802                           // and fill it with the respective values
7803                           bool line_orientation[13];
7804 
7805                           // the middle vertices of the lines of our front
7806                           // face
7807                           const unsigned int middle_vertices[4] = {
7808                             hex->line(8)->child(0)->vertex_index(1),
7809                             hex->line(10)->child(0)->vertex_index(1),
7810                             hex->line(0)->child(0)->vertex_index(1),
7811                             hex->line(4)->child(0)->vertex_index(1),
7812                           };
7813 
7814                           // note: for lines 0 to 3 the orientation of the
7815                           // line is 'true', if vertex 0 is on the front
7816                           for (unsigned int i = 0; i < 4; ++i)
7817                             if (lines[i]->vertex_index(0) == middle_vertices[i])
7818                               line_orientation[i] = true;
7819                             else
7820                               {
7821                                 // it must be the other way round then
7822                                 Assert(lines[i]->vertex_index(1) ==
7823                                          middle_vertices[i],
7824                                        ExcInternalError());
7825                                 line_orientation[i] = false;
7826                               }
7827 
7828                           // note: for lines 4 to 11 (inner lines of the
7829                           // outer quads) the following holds: the second
7830                           // vertex of the even lines in standard
7831                           // orientation is the vertex in the middle of
7832                           // the quad, whereas for odd lines the first
7833                           // vertex is the same middle vertex.
7834                           for (unsigned int i = 4; i < 12; ++i)
7835                             if (lines[i]->vertex_index((i + 1) % 2) ==
7836                                 middle_vertex_index<dim, spacedim>(
7837                                   hex->face(i / 4 - 1)))
7838                               line_orientation[i] = true;
7839                             else
7840                               {
7841                                 // it must be the other way
7842                                 // round then
7843                                 Assert(lines[i]->vertex_index(i % 2) ==
7844                                          (middle_vertex_index<dim, spacedim>(
7845                                            hex->face(i / 4 - 1))),
7846                                        ExcInternalError());
7847                                 line_orientation[i] = false;
7848                               }
7849                           // for the last line the line orientation is
7850                           // always true, since it was just constructed
7851                           // that way
7852                           line_orientation[12] = true;
7853 
7854                           // set up the 4 quads, numbered as follows (left
7855                           // quad numbering, right line numbering
7856                           // extracted from above)
7857                           //
7858                           //  x
7859                           //  *-------*      *---3---*
7860                           //  |   3   |      5       9
7861                           //  *-------*      *---12--*
7862                           //  |   2   |      4       8
7863                           //  *-------*y     *---2---*
7864                           //
7865                           //       y
7866                           //      *---------*      *----1----*
7867                           //     /    1    /      7         11
7868                           //    *---------*      *----12---*
7869                           //   /    0    /      6         10
7870                           //  *---------*x     *----0----*
7871 
7872                           new_quads[0]->set_bounding_object_indices(
7873                             {line_indices[6],
7874                              line_indices[10],
7875                              line_indices[0],
7876                              line_indices[12]});
7877                           new_quads[1]->set_bounding_object_indices(
7878                             {line_indices[7],
7879                              line_indices[11],
7880                              line_indices[12],
7881                              line_indices[1]});
7882                           new_quads[2]->set_bounding_object_indices(
7883                             {line_indices[2],
7884                              line_indices[12],
7885                              line_indices[4],
7886                              line_indices[8]});
7887                           new_quads[3]->set_bounding_object_indices(
7888                             {line_indices[12],
7889                              line_indices[3],
7890                              line_indices[5],
7891                              line_indices[9]});
7892 
7893                           new_quads[0]->set_line_orientation(
7894                             0, line_orientation[6]);
7895                           new_quads[0]->set_line_orientation(
7896                             1, line_orientation[10]);
7897                           new_quads[0]->set_line_orientation(
7898                             2, line_orientation[0]);
7899 
7900                           new_quads[1]->set_line_orientation(
7901                             0, line_orientation[7]);
7902                           new_quads[1]->set_line_orientation(
7903                             1, line_orientation[11]);
7904                           new_quads[1]->set_line_orientation(
7905                             3, line_orientation[1]);
7906 
7907                           new_quads[2]->set_line_orientation(
7908                             0, line_orientation[2]);
7909                           new_quads[2]->set_line_orientation(
7910                             2, line_orientation[4]);
7911                           new_quads[2]->set_line_orientation(
7912                             3, line_orientation[8]);
7913 
7914                           new_quads[3]->set_line_orientation(
7915                             1, line_orientation[3]);
7916                           new_quads[3]->set_line_orientation(
7917                             2, line_orientation[5]);
7918                           new_quads[3]->set_line_orientation(
7919                             3, line_orientation[9]);
7920 
7921                           // the quads are numbered as follows:
7922                           //
7923                           // planes in the interior of the old hex:
7924                           //
7925                           //      *
7926                           //     /|
7927                           //    / | x
7928                           //   /  | *-------*      *---------*
7929                           //  *   | |   3   |     /    1    /
7930                           //  |   | *-------*    *---------*
7931                           //  |   * |   2   |   /    0    /
7932                           //  |  /  *-------*y *---------*x
7933                           //  | /
7934                           //  |/
7935                           //  *
7936                           //
7937                           // children of the faces
7938                           // of the old hex
7939                           //      *-------*        *-------*
7940                           //     /|       |       /  19   /|
7941                           //    * |  15   |      *-------* |
7942                           //   /|7*-------*     /  18   /|11
7943                           //  * |/|       |    *-------* |/|
7944                           //  |6* |  14   |    |       10* |
7945                           //  |/|5*-------*    |  13   |/|9*
7946                           //  * |/  17   /     *-------* |/
7947                           //  |4*-------*      |       |8*
7948                           //  |/  16   /       |  12   |/
7949                           //  *-------*        *-------*
7950                           //
7951                           // note that we have to take care of the
7952                           // orientation of faces.
7953                           const int quad_indices[20] = {
7954                             new_quads[0]->index(), // 0
7955                             new_quads[1]->index(),
7956                             new_quads[2]->index(),
7957                             new_quads[3]->index(),
7958 
7959                             hex->face(0)->isotropic_child_index(
7960                               GeometryInfo<dim>::standard_to_real_face_vertex(
7961                                 0, f_or[0], f_fl[0], f_ro[0])), // 4
7962                             hex->face(0)->isotropic_child_index(
7963                               GeometryInfo<dim>::standard_to_real_face_vertex(
7964                                 1, f_or[0], f_fl[0], f_ro[0])),
7965                             hex->face(0)->isotropic_child_index(
7966                               GeometryInfo<dim>::standard_to_real_face_vertex(
7967                                 2, f_or[0], f_fl[0], f_ro[0])),
7968                             hex->face(0)->isotropic_child_index(
7969                               GeometryInfo<dim>::standard_to_real_face_vertex(
7970                                 3, f_or[0], f_fl[0], f_ro[0])),
7971 
7972                             hex->face(1)->isotropic_child_index(
7973                               GeometryInfo<dim>::standard_to_real_face_vertex(
7974                                 0, f_or[1], f_fl[1], f_ro[1])), // 8
7975                             hex->face(1)->isotropic_child_index(
7976                               GeometryInfo<dim>::standard_to_real_face_vertex(
7977                                 1, f_or[1], f_fl[1], f_ro[1])),
7978                             hex->face(1)->isotropic_child_index(
7979                               GeometryInfo<dim>::standard_to_real_face_vertex(
7980                                 2, f_or[1], f_fl[1], f_ro[1])),
7981                             hex->face(1)->isotropic_child_index(
7982                               GeometryInfo<dim>::standard_to_real_face_vertex(
7983                                 3, f_or[1], f_fl[1], f_ro[1])),
7984 
7985                             hex->face(2)->child_index(
7986                               child_at_origin[hex->face(2)->refinement_case() -
7987                                               1][f_fl[2]][f_ro[2]]), // 12
7988                             hex->face(2)->child_index(
7989                               1 -
7990                               child_at_origin[hex->face(2)->refinement_case() -
7991                                               1][f_fl[2]][f_ro[2]]),
7992 
7993                             hex->face(3)->child_index(
7994                               child_at_origin[hex->face(3)->refinement_case() -
7995                                               1][f_fl[3]][f_ro[3]]), // 14
7996                             hex->face(3)->child_index(
7997                               1 -
7998                               child_at_origin[hex->face(3)->refinement_case() -
7999                                               1][f_fl[3]][f_ro[3]]),
8000 
8001                             hex->face(4)->child_index(
8002                               child_at_origin[hex->face(4)->refinement_case() -
8003                                               1][f_fl[4]][f_ro[4]]), // 16
8004                             hex->face(4)->child_index(
8005                               1 -
8006                               child_at_origin[hex->face(4)->refinement_case() -
8007                                               1][f_fl[4]][f_ro[4]]),
8008 
8009                             hex->face(5)->child_index(
8010                               child_at_origin[hex->face(5)->refinement_case() -
8011                                               1][f_fl[5]][f_ro[5]]), // 18
8012                             hex->face(5)->child_index(
8013                               1 -
8014                               child_at_origin[hex->face(5)->refinement_case() -
8015                                               1][f_fl[5]][f_ro[5]])};
8016 
8017                           new_hexes[0]->set_bounding_object_indices(
8018                             {quad_indices[4],
8019                              quad_indices[8],
8020                              quad_indices[12],
8021                              quad_indices[2],
8022                              quad_indices[16],
8023                              quad_indices[0]});
8024                           new_hexes[1]->set_bounding_object_indices(
8025                             {quad_indices[5],
8026                              quad_indices[9],
8027                              quad_indices[2],
8028                              quad_indices[14],
8029                              quad_indices[17],
8030                              quad_indices[1]});
8031                           new_hexes[2]->set_bounding_object_indices(
8032                             {quad_indices[6],
8033                              quad_indices[10],
8034                              quad_indices[13],
8035                              quad_indices[3],
8036                              quad_indices[0],
8037                              quad_indices[18]});
8038                           new_hexes[3]->set_bounding_object_indices(
8039                             {quad_indices[7],
8040                              quad_indices[11],
8041                              quad_indices[3],
8042                              quad_indices[15],
8043                              quad_indices[1],
8044                              quad_indices[19]});
8045                           break;
8046                         }
8047 
8048                       case RefinementCase<dim>::cut_xyz:
8049                         {
8050                           //////////////////////////////
8051                           //
8052                           //     RefinementCase<dim>::cut_xyz
8053                           //     isotropic refinement
8054                           //
8055                           // the refined cube will look
8056                           // like this:
8057                           //
8058                           //        *----*----*
8059                           //       /    /    /|
8060                           //      *----*----* |
8061                           //     /    /    /| *
8062                           //    *----*----* |/|
8063                           //    |    |    | * |
8064                           //    |    |    |/| *
8065                           //    *----*----* |/
8066                           //    |    |    | *
8067                           //    |    |    |/
8068                           //    *----*----*
8069                           //
8070 
8071                           // find the next unused vertex and set it
8072                           // appropriately
8073                           while (
8074                             triangulation.vertices_used[next_unused_vertex] ==
8075                             true)
8076                             ++next_unused_vertex;
8077                           Assert(
8078                             next_unused_vertex < triangulation.vertices.size(),
8079                             ExcMessage(
8080                               "Internal error: During refinement, the triangulation wants to access an element of the 'vertices' array but it turns out that the array is not large enough."));
8081                           triangulation.vertices_used[next_unused_vertex] =
8082                             true;
8083 
8084                           // the new vertex is definitely in the interior,
8085                           // so we need not worry about the
8086                           // boundary. However we need to worry about
8087                           // Manifolds. Let the cell compute its own
8088                           // center, by querying the underlying manifold
8089                           // object.
8090                           triangulation.vertices[next_unused_vertex] =
8091                             hex->center(true, true);
8092 
8093                           // set the data of the six lines.  first collect
8094                           // the indices of the seven vertices (consider
8095                           // the two planes to be crossed to form the
8096                           // planes cutting the hex in two vertically and
8097                           // horizontally)
8098                           //
8099                           //     *--3--*   *--5--*
8100                           //    /  /  /    |  |  |
8101                           //   0--6--1     0--6--1
8102                           //  /  /  /      |  |  |
8103                           // *--2--*       *--4--*
8104                           // the lines are numbered
8105                           // as follows:
8106                           //     *--*--*   *--*--*
8107                           //    /  1  /    |  5  |
8108                           //   *2-*-3*     *2-*-3*
8109                           //  /  0  /      |  4  |
8110                           // *--*--*       *--*--*
8111                           //
8112                           const unsigned int vertex_indices[7] = {
8113                             middle_vertex_index<dim, spacedim>(hex->face(0)),
8114                             middle_vertex_index<dim, spacedim>(hex->face(1)),
8115                             middle_vertex_index<dim, spacedim>(hex->face(2)),
8116                             middle_vertex_index<dim, spacedim>(hex->face(3)),
8117                             middle_vertex_index<dim, spacedim>(hex->face(4)),
8118                             middle_vertex_index<dim, spacedim>(hex->face(5)),
8119                             next_unused_vertex};
8120 
8121                           new_lines[0]->set_bounding_object_indices(
8122                             {vertex_indices[2], vertex_indices[6]});
8123                           new_lines[1]->set_bounding_object_indices(
8124                             {vertex_indices[6], vertex_indices[3]});
8125                           new_lines[2]->set_bounding_object_indices(
8126                             {vertex_indices[0], vertex_indices[6]});
8127                           new_lines[3]->set_bounding_object_indices(
8128                             {vertex_indices[6], vertex_indices[1]});
8129                           new_lines[4]->set_bounding_object_indices(
8130                             {vertex_indices[4], vertex_indices[6]});
8131                           new_lines[5]->set_bounding_object_indices(
8132                             {vertex_indices[6], vertex_indices[5]});
8133 
8134                           // again, first collect some data about the
8135                           // indices of the lines, with the following
8136                           // numbering: (note that face 0 and 1 each are
8137                           // shown twice for better readability)
8138 
8139                           // face 0: left plane
8140                           //       *            *
8141                           //      /|           /|
8142                           //     * |          * |
8143                           //    /| *         /| *
8144                           //   * 1/|        * |3|
8145                           //   | * |        | * |
8146                           //   |/| *        |2| *
8147                           //   * 0/         * |/
8148                           //   | *          | *
8149                           //   |/           |/
8150                           //   *            *
8151                           // face 1: right plane
8152                           //       *            *
8153                           //      /|           /|
8154                           //     * |          * |
8155                           //    /| *         /| *
8156                           //   * 5/|        * |7|
8157                           //   | * |        | * |
8158                           //   |/| *        |6| *
8159                           //   * 4/         * |/
8160                           //   | *          | *
8161                           //   |/           |/
8162                           //   *            *
8163                           // face 2: front plane
8164                           //   (note: x,y exchanged)
8165                           //   *---*---*
8166                           //   |   11  |
8167                           //   *-8-*-9-*
8168                           //   |   10  |
8169                           //   *---*---*
8170                           // face 3: back plane
8171                           //   (note: x,y exchanged)
8172                           //   *---*---*
8173                           //   |   15  |
8174                           //   *12-*-13*
8175                           //   |   14  |
8176                           //   *---*---*
8177                           // face 4: bottom plane
8178                           //       *---*---*
8179                           //      /  17   /
8180                           //     *18-*-19*
8181                           //    /   16  /
8182                           //   *---*---*
8183                           // face 5: top plane
8184                           //       *---*---*
8185                           //      /  21   /
8186                           //     *22-*-23*
8187                           //    /   20  /
8188                           //   *---*---*
8189                           // middle planes
8190                           //     *---*---*   *---*---*
8191                           //    /  25   /    |   29  |
8192                           //   *26-*-27*     *26-*-27*
8193                           //  /   24  /      |   28  |
8194                           // *---*---*       *---*---*
8195 
8196                           // set up a list of line iterators first. from
8197                           // this, construct lists of line_indices and
8198                           // line orientations later on
8199                           const typename Triangulation<
8200                             dim,
8201                             spacedim>::raw_line_iterator lines[30] = {
8202                             hex->face(0)
8203                               ->isotropic_child(
8204                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8205                                   0, f_or[0], f_fl[0], f_ro[0]))
8206                               ->line(
8207                                 GeometryInfo<dim>::standard_to_real_face_line(
8208                                   1, f_or[0], f_fl[0], f_ro[0])), // 0
8209                             hex->face(0)
8210                               ->isotropic_child(
8211                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8212                                   3, f_or[0], f_fl[0], f_ro[0]))
8213                               ->line(
8214                                 GeometryInfo<dim>::standard_to_real_face_line(
8215                                   0, f_or[0], f_fl[0], f_ro[0])), // 1
8216                             hex->face(0)
8217                               ->isotropic_child(
8218                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8219                                   0, f_or[0], f_fl[0], f_ro[0]))
8220                               ->line(
8221                                 GeometryInfo<dim>::standard_to_real_face_line(
8222                                   3, f_or[0], f_fl[0], f_ro[0])), // 2
8223                             hex->face(0)
8224                               ->isotropic_child(
8225                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8226                                   3, f_or[0], f_fl[0], f_ro[0]))
8227                               ->line(
8228                                 GeometryInfo<dim>::standard_to_real_face_line(
8229                                   2, f_or[0], f_fl[0], f_ro[0])), // 3
8230 
8231                             hex->face(1)
8232                               ->isotropic_child(
8233                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8234                                   0, f_or[1], f_fl[1], f_ro[1]))
8235                               ->line(
8236                                 GeometryInfo<dim>::standard_to_real_face_line(
8237                                   1, f_or[1], f_fl[1], f_ro[1])), // 4
8238                             hex->face(1)
8239                               ->isotropic_child(
8240                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8241                                   3, f_or[1], f_fl[1], f_ro[1]))
8242                               ->line(
8243                                 GeometryInfo<dim>::standard_to_real_face_line(
8244                                   0, f_or[1], f_fl[1], f_ro[1])), // 5
8245                             hex->face(1)
8246                               ->isotropic_child(
8247                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8248                                   0, f_or[1], f_fl[1], f_ro[1]))
8249                               ->line(
8250                                 GeometryInfo<dim>::standard_to_real_face_line(
8251                                   3, f_or[1], f_fl[1], f_ro[1])), // 6
8252                             hex->face(1)
8253                               ->isotropic_child(
8254                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8255                                   3, f_or[1], f_fl[1], f_ro[1]))
8256                               ->line(
8257                                 GeometryInfo<dim>::standard_to_real_face_line(
8258                                   2, f_or[1], f_fl[1], f_ro[1])), // 7
8259 
8260                             hex->face(2)
8261                               ->isotropic_child(
8262                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8263                                   0, f_or[2], f_fl[2], f_ro[2]))
8264                               ->line(
8265                                 GeometryInfo<dim>::standard_to_real_face_line(
8266                                   1, f_or[2], f_fl[2], f_ro[2])), // 8
8267                             hex->face(2)
8268                               ->isotropic_child(
8269                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8270                                   3, f_or[2], f_fl[2], f_ro[2]))
8271                               ->line(
8272                                 GeometryInfo<dim>::standard_to_real_face_line(
8273                                   0, f_or[2], f_fl[2], f_ro[2])), // 9
8274                             hex->face(2)
8275                               ->isotropic_child(
8276                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8277                                   0, f_or[2], f_fl[2], f_ro[2]))
8278                               ->line(
8279                                 GeometryInfo<dim>::standard_to_real_face_line(
8280                                   3, f_or[2], f_fl[2], f_ro[2])), // 10
8281                             hex->face(2)
8282                               ->isotropic_child(
8283                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8284                                   3, f_or[2], f_fl[2], f_ro[2]))
8285                               ->line(
8286                                 GeometryInfo<dim>::standard_to_real_face_line(
8287                                   2, f_or[2], f_fl[2], f_ro[2])), // 11
8288 
8289                             hex->face(3)
8290                               ->isotropic_child(
8291                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8292                                   0, f_or[3], f_fl[3], f_ro[3]))
8293                               ->line(
8294                                 GeometryInfo<dim>::standard_to_real_face_line(
8295                                   1, f_or[3], f_fl[3], f_ro[3])), // 12
8296                             hex->face(3)
8297                               ->isotropic_child(
8298                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8299                                   3, f_or[3], f_fl[3], f_ro[3]))
8300                               ->line(
8301                                 GeometryInfo<dim>::standard_to_real_face_line(
8302                                   0, f_or[3], f_fl[3], f_ro[3])), // 13
8303                             hex->face(3)
8304                               ->isotropic_child(
8305                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8306                                   0, f_or[3], f_fl[3], f_ro[3]))
8307                               ->line(
8308                                 GeometryInfo<dim>::standard_to_real_face_line(
8309                                   3, f_or[3], f_fl[3], f_ro[3])), // 14
8310                             hex->face(3)
8311                               ->isotropic_child(
8312                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8313                                   3, f_or[3], f_fl[3], f_ro[3]))
8314                               ->line(
8315                                 GeometryInfo<dim>::standard_to_real_face_line(
8316                                   2, f_or[3], f_fl[3], f_ro[3])), // 15
8317 
8318                             hex->face(4)
8319                               ->isotropic_child(
8320                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8321                                   0, f_or[4], f_fl[4], f_ro[4]))
8322                               ->line(
8323                                 GeometryInfo<dim>::standard_to_real_face_line(
8324                                   1, f_or[4], f_fl[4], f_ro[4])), // 16
8325                             hex->face(4)
8326                               ->isotropic_child(
8327                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8328                                   3, f_or[4], f_fl[4], f_ro[4]))
8329                               ->line(
8330                                 GeometryInfo<dim>::standard_to_real_face_line(
8331                                   0, f_or[4], f_fl[4], f_ro[4])), // 17
8332                             hex->face(4)
8333                               ->isotropic_child(
8334                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8335                                   0, f_or[4], f_fl[4], f_ro[4]))
8336                               ->line(
8337                                 GeometryInfo<dim>::standard_to_real_face_line(
8338                                   3, f_or[4], f_fl[4], f_ro[4])), // 18
8339                             hex->face(4)
8340                               ->isotropic_child(
8341                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8342                                   3, f_or[4], f_fl[4], f_ro[4]))
8343                               ->line(
8344                                 GeometryInfo<dim>::standard_to_real_face_line(
8345                                   2, f_or[4], f_fl[4], f_ro[4])), // 19
8346 
8347                             hex->face(5)
8348                               ->isotropic_child(
8349                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8350                                   0, f_or[5], f_fl[5], f_ro[5]))
8351                               ->line(
8352                                 GeometryInfo<dim>::standard_to_real_face_line(
8353                                   1, f_or[5], f_fl[5], f_ro[5])), // 20
8354                             hex->face(5)
8355                               ->isotropic_child(
8356                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8357                                   3, f_or[5], f_fl[5], f_ro[5]))
8358                               ->line(
8359                                 GeometryInfo<dim>::standard_to_real_face_line(
8360                                   0, f_or[5], f_fl[5], f_ro[5])), // 21
8361                             hex->face(5)
8362                               ->isotropic_child(
8363                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8364                                   0, f_or[5], f_fl[5], f_ro[5]))
8365                               ->line(
8366                                 GeometryInfo<dim>::standard_to_real_face_line(
8367                                   3, f_or[5], f_fl[5], f_ro[5])), // 22
8368                             hex->face(5)
8369                               ->isotropic_child(
8370                                 GeometryInfo<dim>::standard_to_real_face_vertex(
8371                                   3, f_or[5], f_fl[5], f_ro[5]))
8372                               ->line(
8373                                 GeometryInfo<dim>::standard_to_real_face_line(
8374                                   2, f_or[5], f_fl[5], f_ro[5])), // 23
8375 
8376                             new_lines[0], // 24
8377                             new_lines[1], // 25
8378                             new_lines[2], // 26
8379                             new_lines[3], // 27
8380                             new_lines[4], // 28
8381                             new_lines[5]  // 29
8382                           };
8383 
8384                           unsigned int line_indices[30];
8385                           for (unsigned int i = 0; i < 30; ++i)
8386                             line_indices[i] = lines[i]->index();
8387 
8388                           // the orientation of lines for the inner quads
8389                           // is quite tricky. as these lines are newly
8390                           // created ones and thus have no parents, they
8391                           // cannot inherit this property. set up an array
8392                           // and fill it with the respective values
8393                           bool line_orientation[30];
8394 
8395                           // note: for the first 24 lines (inner lines of
8396                           // the outer quads) the following holds: the
8397                           // second vertex of the even lines in standard
8398                           // orientation is the vertex in the middle of
8399                           // the quad, whereas for odd lines the first
8400                           // vertex is the same middle vertex.
8401                           for (unsigned int i = 0; i < 24; ++i)
8402                             if (lines[i]->vertex_index((i + 1) % 2) ==
8403                                 vertex_indices[i / 4])
8404                               line_orientation[i] = true;
8405                             else
8406                               {
8407                                 // it must be the other way
8408                                 // round then
8409                                 Assert(lines[i]->vertex_index(i % 2) ==
8410                                          vertex_indices[i / 4],
8411                                        ExcInternalError());
8412                                 line_orientation[i] = false;
8413                               }
8414                           // for the last 6 lines the line orientation is
8415                           // always true, since they were just constructed
8416                           // that way
8417                           for (unsigned int i = 24; i < 30; ++i)
8418                             line_orientation[i] = true;
8419 
8420                           // set up the 12 quads, numbered as follows
8421                           // (left quad numbering, right line numbering
8422                           // extracted from above)
8423                           //
8424                           //      *          *
8425                           //     /|        21|
8426                           //    * |        * 15
8427                           //  y/|3*      20| *
8428                           //  * |/|      * |/|
8429                           //  |2* |x    11 * 14
8430                           //  |/|1*      |/| *
8431                           //  * |/       * |17
8432                           //  |0*       10 *
8433                           //  |/         |16
8434                           //  *          *
8435                           //
8436                           //  x
8437                           //  *---*---*      *22-*-23*
8438                           //  | 5 | 7 |      1  29   5
8439                           //  *---*---*      *26-*-27*
8440                           //  | 4 | 6 |      0  28   4
8441                           //  *---*---*y     *18-*-19*
8442                           //
8443                           //       y
8444                           //      *----*----*      *-12-*-13-*
8445                           //     / 10 / 11 /      3   25    7
8446                           //    *----*----*      *-26-*-27-*
8447                           //   / 8  / 9  /      2   24    6
8448                           //  *----*----*x     *--8-*--9-*
8449 
8450                           new_quads[0]->set_bounding_object_indices(
8451                             {line_indices[10],
8452                              line_indices[28],
8453                              line_indices[16],
8454                              line_indices[24]});
8455                           new_quads[1]->set_bounding_object_indices(
8456                             {line_indices[28],
8457                              line_indices[14],
8458                              line_indices[17],
8459                              line_indices[25]});
8460                           new_quads[2]->set_bounding_object_indices(
8461                             {line_indices[11],
8462                              line_indices[29],
8463                              line_indices[24],
8464                              line_indices[20]});
8465                           new_quads[3]->set_bounding_object_indices(
8466                             {line_indices[29],
8467                              line_indices[15],
8468                              line_indices[25],
8469                              line_indices[21]});
8470                           new_quads[4]->set_bounding_object_indices(
8471                             {line_indices[18],
8472                              line_indices[26],
8473                              line_indices[0],
8474                              line_indices[28]});
8475                           new_quads[5]->set_bounding_object_indices(
8476                             {line_indices[26],
8477                              line_indices[22],
8478                              line_indices[1],
8479                              line_indices[29]});
8480                           new_quads[6]->set_bounding_object_indices(
8481                             {line_indices[19],
8482                              line_indices[27],
8483                              line_indices[28],
8484                              line_indices[4]});
8485                           new_quads[7]->set_bounding_object_indices(
8486                             {line_indices[27],
8487                              line_indices[23],
8488                              line_indices[29],
8489                              line_indices[5]});
8490                           new_quads[8]->set_bounding_object_indices(
8491                             {line_indices[2],
8492                              line_indices[24],
8493                              line_indices[8],
8494                              line_indices[26]});
8495                           new_quads[9]->set_bounding_object_indices(
8496                             {line_indices[24],
8497                              line_indices[6],
8498                              line_indices[9],
8499                              line_indices[27]});
8500                           new_quads[10]->set_bounding_object_indices(
8501                             {line_indices[3],
8502                              line_indices[25],
8503                              line_indices[26],
8504                              line_indices[12]});
8505                           new_quads[11]->set_bounding_object_indices(
8506                             {line_indices[25],
8507                              line_indices[7],
8508                              line_indices[27],
8509                              line_indices[13]});
8510 
8511                           // now reset the line_orientation flags of outer
8512                           // lines as they cannot be set in a loop (at
8513                           // least not easily)
8514                           new_quads[0]->set_line_orientation(
8515                             0, line_orientation[10]);
8516                           new_quads[0]->set_line_orientation(
8517                             2, line_orientation[16]);
8518 
8519                           new_quads[1]->set_line_orientation(
8520                             1, line_orientation[14]);
8521                           new_quads[1]->set_line_orientation(
8522                             2, line_orientation[17]);
8523 
8524                           new_quads[2]->set_line_orientation(
8525                             0, line_orientation[11]);
8526                           new_quads[2]->set_line_orientation(
8527                             3, line_orientation[20]);
8528 
8529                           new_quads[3]->set_line_orientation(
8530                             1, line_orientation[15]);
8531                           new_quads[3]->set_line_orientation(
8532                             3, line_orientation[21]);
8533 
8534                           new_quads[4]->set_line_orientation(
8535                             0, line_orientation[18]);
8536                           new_quads[4]->set_line_orientation(
8537                             2, line_orientation[0]);
8538 
8539                           new_quads[5]->set_line_orientation(
8540                             1, line_orientation[22]);
8541                           new_quads[5]->set_line_orientation(
8542                             2, line_orientation[1]);
8543 
8544                           new_quads[6]->set_line_orientation(
8545                             0, line_orientation[19]);
8546                           new_quads[6]->set_line_orientation(
8547                             3, line_orientation[4]);
8548 
8549                           new_quads[7]->set_line_orientation(
8550                             1, line_orientation[23]);
8551                           new_quads[7]->set_line_orientation(
8552                             3, line_orientation[5]);
8553 
8554                           new_quads[8]->set_line_orientation(
8555                             0, line_orientation[2]);
8556                           new_quads[8]->set_line_orientation(
8557                             2, line_orientation[8]);
8558 
8559                           new_quads[9]->set_line_orientation(
8560                             1, line_orientation[6]);
8561                           new_quads[9]->set_line_orientation(
8562                             2, line_orientation[9]);
8563 
8564                           new_quads[10]->set_line_orientation(
8565                             0, line_orientation[3]);
8566                           new_quads[10]->set_line_orientation(
8567                             3, line_orientation[12]);
8568 
8569                           new_quads[11]->set_line_orientation(
8570                             1, line_orientation[7]);
8571                           new_quads[11]->set_line_orientation(
8572                             3, line_orientation[13]);
8573 
8574                           /////////////////////////////////
8575                           // create the eight new hexes
8576                           //
8577                           // again first collect some data.  here, we need
8578                           // the indices of a whole lotta quads.
8579 
8580                           // the quads are numbered as follows:
8581                           //
8582                           // planes in the interior of the old hex:
8583                           //
8584                           //      *
8585                           //     /|
8586                           //    * |
8587                           //   /|3*  *---*---*      *----*----*
8588                           //  * |/|  | 5 | 7 |     / 10 / 11 /
8589                           //  |2* |  *---*---*    *----*----*
8590                           //  |/|1*  | 4 | 6 |   / 8  / 9  /
8591                           //  * |/   *---*---*y *----*----*x
8592                           //  |0*
8593                           //  |/
8594                           //  *
8595                           //
8596                           // children of the faces
8597                           // of the old hex
8598                           //      *-------*        *-------*
8599                           //     /|25   27|       /34   35/|
8600                           //    15|       |      /       /19
8601                           //   /  |       |     /32   33/  |
8602                           //  *   |24   26|    *-------*18 |
8603                           //  1413*-------*    |21   23| 17*
8604                           //  |  /30   31/     |       |  /
8605                           //  12/       /      |       |16
8606                           //  |/28   29/       |20   22|/
8607                           //  *-------*        *-------*
8608                           //
8609                           // note that we have to
8610                           // take care of the
8611                           // orientation of
8612                           // faces.
8613                           const int quad_indices[36] = {
8614                             new_quads[0]->index(), // 0
8615                             new_quads[1]->index(),
8616                             new_quads[2]->index(),
8617                             new_quads[3]->index(),
8618                             new_quads[4]->index(),
8619                             new_quads[5]->index(),
8620                             new_quads[6]->index(),
8621                             new_quads[7]->index(),
8622                             new_quads[8]->index(),
8623                             new_quads[9]->index(),
8624                             new_quads[10]->index(),
8625                             new_quads[11]->index(), // 11
8626 
8627                             hex->face(0)->isotropic_child_index(
8628                               GeometryInfo<dim>::standard_to_real_face_vertex(
8629                                 0, f_or[0], f_fl[0], f_ro[0])), // 12
8630                             hex->face(0)->isotropic_child_index(
8631                               GeometryInfo<dim>::standard_to_real_face_vertex(
8632                                 1, f_or[0], f_fl[0], f_ro[0])),
8633                             hex->face(0)->isotropic_child_index(
8634                               GeometryInfo<dim>::standard_to_real_face_vertex(
8635                                 2, f_or[0], f_fl[0], f_ro[0])),
8636                             hex->face(0)->isotropic_child_index(
8637                               GeometryInfo<dim>::standard_to_real_face_vertex(
8638                                 3, f_or[0], f_fl[0], f_ro[0])),
8639 
8640                             hex->face(1)->isotropic_child_index(
8641                               GeometryInfo<dim>::standard_to_real_face_vertex(
8642                                 0, f_or[1], f_fl[1], f_ro[1])), // 16
8643                             hex->face(1)->isotropic_child_index(
8644                               GeometryInfo<dim>::standard_to_real_face_vertex(
8645                                 1, f_or[1], f_fl[1], f_ro[1])),
8646                             hex->face(1)->isotropic_child_index(
8647                               GeometryInfo<dim>::standard_to_real_face_vertex(
8648                                 2, f_or[1], f_fl[1], f_ro[1])),
8649                             hex->face(1)->isotropic_child_index(
8650                               GeometryInfo<dim>::standard_to_real_face_vertex(
8651                                 3, f_or[1], f_fl[1], f_ro[1])),
8652 
8653                             hex->face(2)->isotropic_child_index(
8654                               GeometryInfo<dim>::standard_to_real_face_vertex(
8655                                 0, f_or[2], f_fl[2], f_ro[2])), // 20
8656                             hex->face(2)->isotropic_child_index(
8657                               GeometryInfo<dim>::standard_to_real_face_vertex(
8658                                 1, f_or[2], f_fl[2], f_ro[2])),
8659                             hex->face(2)->isotropic_child_index(
8660                               GeometryInfo<dim>::standard_to_real_face_vertex(
8661                                 2, f_or[2], f_fl[2], f_ro[2])),
8662                             hex->face(2)->isotropic_child_index(
8663                               GeometryInfo<dim>::standard_to_real_face_vertex(
8664                                 3, f_or[2], f_fl[2], f_ro[2])),
8665 
8666                             hex->face(3)->isotropic_child_index(
8667                               GeometryInfo<dim>::standard_to_real_face_vertex(
8668                                 0, f_or[3], f_fl[3], f_ro[3])), // 24
8669                             hex->face(3)->isotropic_child_index(
8670                               GeometryInfo<dim>::standard_to_real_face_vertex(
8671                                 1, f_or[3], f_fl[3], f_ro[3])),
8672                             hex->face(3)->isotropic_child_index(
8673                               GeometryInfo<dim>::standard_to_real_face_vertex(
8674                                 2, f_or[3], f_fl[3], f_ro[3])),
8675                             hex->face(3)->isotropic_child_index(
8676                               GeometryInfo<dim>::standard_to_real_face_vertex(
8677                                 3, f_or[3], f_fl[3], f_ro[3])),
8678 
8679                             hex->face(4)->isotropic_child_index(
8680                               GeometryInfo<dim>::standard_to_real_face_vertex(
8681                                 0, f_or[4], f_fl[4], f_ro[4])), // 28
8682                             hex->face(4)->isotropic_child_index(
8683                               GeometryInfo<dim>::standard_to_real_face_vertex(
8684                                 1, f_or[4], f_fl[4], f_ro[4])),
8685                             hex->face(4)->isotropic_child_index(
8686                               GeometryInfo<dim>::standard_to_real_face_vertex(
8687                                 2, f_or[4], f_fl[4], f_ro[4])),
8688                             hex->face(4)->isotropic_child_index(
8689                               GeometryInfo<dim>::standard_to_real_face_vertex(
8690                                 3, f_or[4], f_fl[4], f_ro[4])),
8691 
8692                             hex->face(5)->isotropic_child_index(
8693                               GeometryInfo<dim>::standard_to_real_face_vertex(
8694                                 0, f_or[5], f_fl[5], f_ro[5])), // 32
8695                             hex->face(5)->isotropic_child_index(
8696                               GeometryInfo<dim>::standard_to_real_face_vertex(
8697                                 1, f_or[5], f_fl[5], f_ro[5])),
8698                             hex->face(5)->isotropic_child_index(
8699                               GeometryInfo<dim>::standard_to_real_face_vertex(
8700                                 2, f_or[5], f_fl[5], f_ro[5])),
8701                             hex->face(5)->isotropic_child_index(
8702                               GeometryInfo<dim>::standard_to_real_face_vertex(
8703                                 3, f_or[5], f_fl[5], f_ro[5]))};
8704 
8705                           // bottom children
8706                           new_hexes[0]->set_bounding_object_indices(
8707                             {quad_indices[12],
8708                              quad_indices[0],
8709                              quad_indices[20],
8710                              quad_indices[4],
8711                              quad_indices[28],
8712                              quad_indices[8]});
8713                           new_hexes[1]->set_bounding_object_indices(
8714                             {quad_indices[0],
8715                              quad_indices[16],
8716                              quad_indices[22],
8717                              quad_indices[6],
8718                              quad_indices[29],
8719                              quad_indices[9]});
8720                           new_hexes[2]->set_bounding_object_indices(
8721                             {quad_indices[13],
8722                              quad_indices[1],
8723                              quad_indices[4],
8724                              quad_indices[24],
8725                              quad_indices[30],
8726                              quad_indices[10]});
8727                           new_hexes[3]->set_bounding_object_indices(
8728                             {quad_indices[1],
8729                              quad_indices[17],
8730                              quad_indices[6],
8731                              quad_indices[26],
8732                              quad_indices[31],
8733                              quad_indices[11]});
8734 
8735                           // top children
8736                           new_hexes[4]->set_bounding_object_indices(
8737                             {quad_indices[14],
8738                              quad_indices[2],
8739                              quad_indices[21],
8740                              quad_indices[5],
8741                              quad_indices[8],
8742                              quad_indices[32]});
8743                           new_hexes[5]->set_bounding_object_indices(
8744                             {quad_indices[2],
8745                              quad_indices[18],
8746                              quad_indices[23],
8747                              quad_indices[7],
8748                              quad_indices[9],
8749                              quad_indices[33]});
8750                           new_hexes[6]->set_bounding_object_indices(
8751                             {quad_indices[15],
8752                              quad_indices[3],
8753                              quad_indices[5],
8754                              quad_indices[25],
8755                              quad_indices[10],
8756                              quad_indices[34]});
8757                           new_hexes[7]->set_bounding_object_indices(
8758                             {quad_indices[3],
8759                              quad_indices[19],
8760                              quad_indices[7],
8761                              quad_indices[27],
8762                              quad_indices[11],
8763                              quad_indices[35]});
8764                           break;
8765                         }
8766                       default:
8767                         // all refinement cases have been treated, there
8768                         // only remains
8769                         // RefinementCase<dim>::no_refinement as
8770                         // untreated enumeration value. However, in that
8771                         // case we should have aborted much
8772                         // earlier. thus we should never get here
8773                         Assert(false, ExcInternalError());
8774                         break;
8775                     } // switch (ref_case)
8776 
8777                   // and set face orientation flags. note that new
8778                   // faces in the interior of the mother cell always
8779                   // have a correctly oriented face, but the ones on
8780                   // the outer faces will inherit this flag
8781                   //
8782                   // the flag have been set to true for all faces
8783                   // initially, now go the other way round and reset
8784                   // faces that are at the boundary of the mother cube
8785                   //
8786                   // the same is true for the face_flip and
8787                   // face_rotation flags. however, the latter two are
8788                   // set to false by default as this is the standard
8789                   // value
8790 
8791                   // loop over all faces and all (relevant) subfaces
8792                   // of that in order to set the correct values for
8793                   // face_orientation, face_flip and face_rotation,
8794                   // which are inherited from the corresponding face
8795                   // of the mother cube
8796                   for (const unsigned int f : GeometryInfo<dim>::face_indices())
8797                     for (unsigned int s = 0;
8798                          s < std::max(GeometryInfo<dim - 1>::n_children(
8799                                         GeometryInfo<dim>::face_refinement_case(
8800                                           ref_case, f)),
8801                                       1U);
8802                          ++s)
8803                       {
8804                         const unsigned int current_child =
8805                           GeometryInfo<dim>::child_cell_on_face(
8806                             ref_case,
8807                             f,
8808                             s,
8809                             f_or[f],
8810                             f_fl[f],
8811                             f_ro[f],
8812                             GeometryInfo<dim>::face_refinement_case(
8813                               ref_case, f, f_or[f], f_fl[f], f_ro[f]));
8814                         new_hexes[current_child]->set_face_orientation(f,
8815                                                                        f_or[f]);
8816                         new_hexes[current_child]->set_face_flip(f, f_fl[f]);
8817                         new_hexes[current_child]->set_face_rotation(f, f_ro[f]);
8818                       }
8819 
8820                   // now see if we have created cells that are
8821                   // distorted and if so add them to our list
8822                   if (check_for_distorted_cells &&
8823                       has_distorted_children(
8824                         hex,
8825                         std::integral_constant<int, dim>(),
8826                         std::integral_constant<int, spacedim>()))
8827                     cells_with_distorted_children.distorted_cells.push_back(
8828                       hex);
8829 
8830                   // note that the refinement flag was already cleared
8831                   // at the beginning of this loop
8832 
8833                   // inform all listeners that cell refinement is done
8834                   triangulation.signals.post_refinement_on_cell(hex);
8835                 }
8836           }
8837 
8838         // clear user data on quads. we used some of this data to
8839         // indicate anisotropic refinemnt cases on faces. all data
8840         // should be cleared by now, but the information whether we
8841         // used indices or pointers is still present. reset it now to
8842         // enable the user to use whichever they like later on.
8843         triangulation.faces->quads.clear_user_data();
8844 
8845         // return the list with distorted children
8846         return cells_with_distorted_children;
8847       }
8848 
8849 
8850       /**
8851        * At the boundary of the domain, the new point on the face may
8852        * be far inside the current cell, if the boundary has a strong
8853        * curvature. If we allow anisotropic refinement here, the
8854        * resulting cell may be strongly distorted. To prevent this,
8855        * this function flags such cells for isotropic refinement. It
8856        * is called automatically from
8857        * prepare_coarsening_and_refinement().
8858        *
8859        * This function does nothing in 1d (therefore the
8860        * specialization).
8861        */
8862       template <int spacedim>
8863       static void
8864       prevent_distorted_boundary_cells(const Triangulation<1, spacedim> &);
8865 
8866 
8867       template <int dim, int spacedim>
8868       static void
prevent_distorted_boundary_cellsinternal::TriangulationImplementation::Implementation8869       prevent_distorted_boundary_cells(
8870         Triangulation<dim, spacedim> &triangulation)
8871       {
8872         // If the codimension is one, we cannot perform this check
8873         // yet.
8874         if (spacedim > dim)
8875           return;
8876 
8877         for (const auto &cell : triangulation.cell_iterators())
8878           if (cell->at_boundary() && cell->refine_flag_set() &&
8879               cell->refine_flag_set() !=
8880                 RefinementCase<dim>::isotropic_refinement)
8881             {
8882               // The cell is at the boundary and it is flagged for
8883               // anisotropic refinement. Therefore, we have a closer
8884               // look
8885               const RefinementCase<dim> ref_case = cell->refine_flag_set();
8886               for (const unsigned int face_no :
8887                    GeometryInfo<dim>::face_indices())
8888                 if (cell->face(face_no)->at_boundary())
8889                   {
8890                     // this is the critical face at the boundary.
8891                     if (GeometryInfo<dim>::face_refinement_case(ref_case,
8892                                                                 face_no) !=
8893                         RefinementCase<dim - 1>::isotropic_refinement)
8894                       {
8895                         // up to now, we do not want to refine this
8896                         // cell along the face under consideration
8897                         // here.
8898                         const typename Triangulation<dim,
8899                                                      spacedim>::face_iterator
8900                           face = cell->face(face_no);
8901                         // the new point on the boundary would be this
8902                         // one.
8903                         const Point<spacedim> new_bound = face->center(true);
8904                         // to check it, transform to the unit cell
8905                         // with Q1Mapping
8906                         const Point<dim> new_unit =
8907                           StaticMappingQ1<dim, spacedim>::mapping
8908                             .transform_real_to_unit_cell(cell, new_bound);
8909 
8910                         // Now, we have to calculate the distance from
8911                         // the face in the unit cell.
8912 
8913                         // take the correct coordinate direction (0
8914                         // for faces 0 and 1, 1 for faces 2 and 3, 2
8915                         // for faces 4 and 5) and subtract the correct
8916                         // boundary value of the face (0 for faces 0,
8917                         // 2, and 4; 1 for faces 1, 3 and 5)
8918                         const double dist =
8919                           std::fabs(new_unit[face_no / 2] - face_no % 2);
8920 
8921                         // compare this with the empirical value
8922                         // allowed. if it is too big, flag the face
8923                         // for isotropic refinement
8924                         const double allowed = 0.25;
8925 
8926                         if (dist > allowed)
8927                           cell->flag_for_face_refinement(face_no);
8928                       } // if flagged for anistropic refinement
8929                   }     // if (cell->face(face)->at_boundary())
8930             }           // for all cells
8931       }
8932 
8933 
8934       /**
8935        * Some dimension dependent stuff for mesh smoothing.
8936        *
8937        * At present, this function does nothing in 1d and 2D, but
8938        * makes sure no two cells with a level difference greater than
8939        * one share one line in 3D. This is a requirement needed for
8940        * the interpolation of hanging nodes, since otherwise to steps
8941        * of interpolation would be necessary. This would make the
8942        * processes implemented in the @p AffineConstraints class much
8943        * more complex, since these two steps of interpolation do not
8944        * commute.
8945        */
8946       template <int dim, int spacedim>
8947       static void
prepare_refinement_dim_dependentinternal::TriangulationImplementation::Implementation8948       prepare_refinement_dim_dependent(const Triangulation<dim, spacedim> &)
8949       {
8950         Assert(dim < 3,
8951                ExcMessage("Wrong function called -- there should "
8952                           "be a specialization."));
8953       }
8954 
8955 
8956       template <int spacedim>
prepare_refinement_dim_dependentinternal::TriangulationImplementation::Implementation8957       static void prepare_refinement_dim_dependent(
8958         Triangulation<3, spacedim> &triangulation)
8959       {
8960         const unsigned int dim = 3;
8961 
8962         // first clear flags on lines, since we need them to determine
8963         // which lines will be refined
8964         triangulation.clear_user_flags_line();
8965 
8966         // also clear flags on hexes, since we need them to mark those
8967         // cells which are to be coarsened
8968         triangulation.clear_user_flags_hex();
8969 
8970         // variable to store whether the mesh was changed in the
8971         // present loop and in the whole process
8972         bool mesh_changed = false;
8973 
8974         do
8975           {
8976             mesh_changed = false;
8977 
8978             // for this following, we need to know which cells are
8979             // going to be coarsened, if we had to make a
8980             // decision. the following function sets these flags:
8981             triangulation.fix_coarsen_flags();
8982 
8983 
8984             // flag those lines that are refined and will not be
8985             // coarsened and those that will be refined
8986             for (const auto &cell : triangulation.cell_iterators())
8987               if (cell->refine_flag_set())
8988                 {
8989                   for (unsigned int line = 0;
8990                        line < GeometryInfo<dim>::lines_per_cell;
8991                        ++line)
8992                     if (GeometryInfo<dim>::line_refinement_case(
8993                           cell->refine_flag_set(), line) ==
8994                         RefinementCase<1>::cut_x)
8995                       // flag a line, that will be
8996                       // refined
8997                       cell->line(line)->set_user_flag();
8998                 }
8999               else if (cell->has_children() &&
9000                        !cell->child(0)->coarsen_flag_set())
9001                 {
9002                   for (unsigned int line = 0;
9003                        line < GeometryInfo<dim>::lines_per_cell;
9004                        ++line)
9005                     if (GeometryInfo<dim>::line_refinement_case(
9006                           cell->refinement_case(), line) ==
9007                         RefinementCase<1>::cut_x)
9008                       // flag a line, that is refined
9009                       // and will stay so
9010                       cell->line(line)->set_user_flag();
9011                 }
9012               else if (cell->has_children() &&
9013                        cell->child(0)->coarsen_flag_set())
9014                 cell->set_user_flag();
9015 
9016 
9017             // now check whether there are cells with lines that are
9018             // more than once refined or that will be more than once
9019             // refined. The first thing should never be the case, in
9020             // the second case we flag the cell for refinement
9021             for (typename Triangulation<dim, spacedim>::active_cell_iterator
9022                    cell = triangulation.last_active();
9023                  cell != triangulation.end();
9024                  --cell)
9025               for (unsigned int line = 0;
9026                    line < GeometryInfo<dim>::lines_per_cell;
9027                    ++line)
9028                 {
9029                   if (cell->line(line)->has_children())
9030                     {
9031                       // if this line is refined, its children should
9032                       // not have further children
9033                       //
9034                       // however, if any of the children is flagged
9035                       // for further refinement, we need to refine
9036                       // this cell also (at least, if the cell is not
9037                       // already flagged)
9038                       bool offending_line_found = false;
9039 
9040                       for (unsigned int c = 0; c < 2; ++c)
9041                         {
9042                           Assert(cell->line(line)->child(c)->has_children() ==
9043                                    false,
9044                                  ExcInternalError());
9045 
9046                           if (cell->line(line)->child(c)->user_flag_set() &&
9047                               (GeometryInfo<dim>::line_refinement_case(
9048                                  cell->refine_flag_set(), line) ==
9049                                RefinementCase<1>::no_refinement))
9050                             {
9051                               // tag this cell for refinement
9052                               cell->clear_coarsen_flag();
9053                               // if anisotropic coarsening is allowed:
9054                               // extend the refine_flag in the needed
9055                               // direction, else set refine_flag
9056                               // (isotropic)
9057                               if (triangulation.smooth_grid &
9058                                   Triangulation<dim, spacedim>::
9059                                     allow_anisotropic_smoothing)
9060                                 cell->flag_for_line_refinement(line);
9061                               else
9062                                 cell->set_refine_flag();
9063 
9064                               for (unsigned int l = 0;
9065                                    l < GeometryInfo<dim>::lines_per_cell;
9066                                    ++l)
9067                                 if (GeometryInfo<dim>::line_refinement_case(
9068                                       cell->refine_flag_set(), line) ==
9069                                     RefinementCase<1>::cut_x)
9070                                   // flag a line, that will be refined
9071                                   cell->line(l)->set_user_flag();
9072 
9073                               // note that we have changed the grid
9074                               offending_line_found = true;
9075 
9076                               // it may save us several loop
9077                               // iterations if we flag all lines of
9078                               // this cell now (and not at the outset
9079                               // of the next iteration) for refinement
9080                               for (unsigned int l = 0;
9081                                    l < GeometryInfo<dim>::lines_per_cell;
9082                                    ++l)
9083                                 if (!cell->line(l)->has_children() &&
9084                                     (GeometryInfo<dim>::line_refinement_case(
9085                                        cell->refine_flag_set(), l) !=
9086                                      RefinementCase<1>::no_refinement))
9087                                   cell->line(l)->set_user_flag();
9088 
9089                               break;
9090                             }
9091                         }
9092 
9093                       if (offending_line_found)
9094                         {
9095                           mesh_changed = true;
9096                           break;
9097                         }
9098                     }
9099                 }
9100 
9101 
9102             // there is another thing here: if any of the lines will
9103             // be refined, then we may not coarsen the present cell
9104             // similarly, if any of the lines *is* already refined, we
9105             // may not coarsen the current cell. however, there's a
9106             // catch: if the line is refined, but the cell behind it
9107             // is going to be coarsened, then the situation
9108             // changes. if we forget this second condition, the
9109             // refine_and_coarsen_3d test will start to fail. note
9110             // that to know which cells are going to be coarsened, the
9111             // call for fix_coarsen_flags above is necessary
9112             for (typename Triangulation<dim, spacedim>::cell_iterator cell =
9113                    triangulation.last();
9114                  cell != triangulation.end();
9115                  --cell)
9116               {
9117                 if (cell->user_flag_set())
9118                   for (unsigned int line = 0;
9119                        line < GeometryInfo<dim>::lines_per_cell;
9120                        ++line)
9121                     if (cell->line(line)->has_children() &&
9122                         (cell->line(line)->child(0)->user_flag_set() ||
9123                          cell->line(line)->child(1)->user_flag_set()))
9124                       {
9125                         for (unsigned int c = 0; c < cell->n_children(); ++c)
9126                           cell->child(c)->clear_coarsen_flag();
9127                         cell->clear_user_flag();
9128                         for (unsigned int l = 0;
9129                              l < GeometryInfo<dim>::lines_per_cell;
9130                              ++l)
9131                           if (GeometryInfo<dim>::line_refinement_case(
9132                                 cell->refinement_case(), l) ==
9133                               RefinementCase<1>::cut_x)
9134                             // flag a line, that is refined
9135                             // and will stay so
9136                             cell->line(l)->set_user_flag();
9137                         mesh_changed = true;
9138                         break;
9139                       }
9140               }
9141           }
9142         while (mesh_changed == true);
9143       }
9144 
9145 
9146 
9147       /**
9148        * Helper function for @p fix_coarsen_flags. Return whether
9149        * coarsening of this cell is allowed.  Coarsening can be
9150        * forbidden if the neighboring cells are or will be refined
9151        * twice along the common face.
9152        */
9153       template <int dim, int spacedim>
9154       static bool
coarsening_allowedinternal::TriangulationImplementation::Implementation9155       coarsening_allowed(
9156         const typename Triangulation<dim, spacedim>::cell_iterator &cell)
9157       {
9158         // in 1d, coarsening is always allowed since we don't enforce
9159         // the 2:1 constraint there
9160         if (dim == 1)
9161           return true;
9162 
9163         const RefinementCase<dim> ref_case = cell->refinement_case();
9164         for (unsigned int n : GeometryInfo<dim>::face_indices())
9165           {
9166             // if the cell is not refined along that face, coarsening
9167             // will not change anything, so do nothing. the same
9168             // applies, if the face is at the boandary
9169             const RefinementCase<dim - 1> face_ref_case =
9170               GeometryInfo<dim>::face_refinement_case(cell->refinement_case(),
9171                                                       n);
9172 
9173             const unsigned int n_subfaces =
9174               GeometryInfo<dim - 1>::n_children(face_ref_case);
9175 
9176             if (n_subfaces == 0 || cell->at_boundary(n))
9177               continue;
9178             for (unsigned int c = 0; c < n_subfaces; ++c)
9179               {
9180                 const typename Triangulation<dim, spacedim>::cell_iterator
9181                   child = cell->child(
9182                     GeometryInfo<dim>::child_cell_on_face(ref_case, n, c));
9183 
9184                 const typename Triangulation<dim, spacedim>::cell_iterator
9185                   child_neighbor = child->neighbor(n);
9186                 if (!child->neighbor_is_coarser(n))
9187                   // in 2d, if the child's neighbor is coarser, then
9188                   // it has no children. however, in 3d it might be
9189                   // otherwise. consider for example, that our face
9190                   // might be refined with cut_x, but the neighbor is
9191                   // refined with cut_xy at that face. then the
9192                   // neighbor pointers of the children of our cell
9193                   // will point to the common neighbor cell, not to
9194                   // its children. what we really want to know in the
9195                   // following is, whether the neighbor cell is
9196                   // refined twice with reference to our cell.  that
9197                   // only has to be asked, if the child's neighbor is
9198                   // not a coarser one.
9199                   if ((child_neighbor->has_children() &&
9200                        !child_neighbor->user_flag_set()) ||
9201                       // neighbor has children, which are further
9202                       // refined along the face, otherwise something
9203                       // went wrong in the construction of neighbor
9204                       // pointers.  then only allow coarsening if this
9205                       // neighbor will be coarsened as well
9206                       // (user_pointer is set).  the same applies, if
9207                       // the neighbors children are not refined but
9208                       // will be after refinement
9209                       child_neighbor->refine_flag_set())
9210                     return false;
9211               }
9212           }
9213         return true;
9214       }
9215     };
9216 
9217 
9218 
9219     template <int dim, int spacedim>
9220     const Manifold<dim, spacedim> &
get_default_flat_manifold()9221     get_default_flat_manifold()
9222     {
9223       static const FlatManifold<dim, spacedim> flat_manifold;
9224       return flat_manifold;
9225     }
9226   } // namespace TriangulationImplementation
9227 } // namespace internal
9228 
9229 
9230 
9231 template <int dim, int spacedim>
9232 const unsigned int Triangulation<dim, spacedim>::dimension;
9233 
9234 
9235 
9236 template <int dim, int spacedim>
Triangulation(const MeshSmoothing smooth_grid,const bool check_for_distorted_cells)9237 Triangulation<dim, spacedim>::Triangulation(
9238   const MeshSmoothing smooth_grid,
9239   const bool          check_for_distorted_cells)
9240   : smooth_grid(smooth_grid)
9241   , anisotropic_refinement(false)
9242   , check_for_distorted_cells(check_for_distorted_cells)
9243 {
9244   if (dim == 1)
9245     {
9246       vertex_to_boundary_id_map_1d =
9247         std::make_unique<std::map<unsigned int, types::boundary_id>>();
9248       vertex_to_manifold_id_map_1d =
9249         std::make_unique<std::map<unsigned int, types::manifold_id>>();
9250     }
9251 
9252   // connect the any_change signal to the other top level signals
9253   signals.create.connect(signals.any_change);
9254   signals.post_refinement.connect(signals.any_change);
9255   signals.clear.connect(signals.any_change);
9256   signals.mesh_movement.connect(signals.any_change);
9257 }
9258 
9259 
9260 
9261 template <int dim, int spacedim>
Triangulation(Triangulation<dim,spacedim> && tria)9262 Triangulation<dim, spacedim>::Triangulation(
9263   Triangulation<dim, spacedim> &&tria) noexcept
9264   : Subscriptor(std::move(tria))
9265   , smooth_grid(tria.smooth_grid)
9266   , periodic_face_pairs_level_0(std::move(tria.periodic_face_pairs_level_0))
9267   , periodic_face_map(std::move(tria.periodic_face_map))
9268   , levels(std::move(tria.levels))
9269   , faces(std::move(tria.faces))
9270   , vertices(std::move(tria.vertices))
9271   , vertices_used(std::move(tria.vertices_used))
9272   , manifold(std::move(tria.manifold))
9273   , anisotropic_refinement(tria.anisotropic_refinement)
9274   , check_for_distorted_cells(tria.check_for_distorted_cells)
9275   , number_cache(std::move(tria.number_cache))
9276   , vertex_to_boundary_id_map_1d(std::move(tria.vertex_to_boundary_id_map_1d))
9277   , vertex_to_manifold_id_map_1d(std::move(tria.vertex_to_manifold_id_map_1d))
9278 {
9279   tria.number_cache = internal::TriangulationImplementation::NumberCache<dim>();
9280 }
9281 
9282 
9283 template <int dim, int spacedim>
9284 Triangulation<dim, spacedim> &
9285 Triangulation<dim, spacedim>::
operator =(Triangulation<dim,spacedim> && tria)9286 operator=(Triangulation<dim, spacedim> &&tria) noexcept
9287 {
9288   Subscriptor::operator=(std::move(tria));
9289 
9290   smooth_grid                  = tria.smooth_grid;
9291   periodic_face_pairs_level_0  = std::move(tria.periodic_face_pairs_level_0);
9292   periodic_face_map            = std::move(tria.periodic_face_map);
9293   levels                       = std::move(tria.levels);
9294   faces                        = std::move(tria.faces);
9295   vertices                     = std::move(tria.vertices);
9296   vertices_used                = std::move(tria.vertices_used);
9297   manifold                     = std::move(tria.manifold);
9298   anisotropic_refinement       = tria.anisotropic_refinement;
9299   number_cache                 = tria.number_cache;
9300   vertex_to_boundary_id_map_1d = std::move(tria.vertex_to_boundary_id_map_1d);
9301   vertex_to_manifold_id_map_1d = std::move(tria.vertex_to_manifold_id_map_1d);
9302 
9303   tria.number_cache = internal::TriangulationImplementation::NumberCache<dim>();
9304 
9305   return *this;
9306 }
9307 
9308 
9309 
9310 template <int dim, int spacedim>
~Triangulation()9311 Triangulation<dim, spacedim>::~Triangulation()
9312 {
9313   // notify listeners that the triangulation is going down...
9314   try
9315     {
9316       signals.clear();
9317     }
9318   catch (...)
9319     {}
9320 
9321   levels.clear();
9322 
9323   // the vertex_to_boundary_id_map_1d field should be unused except in
9324   // 1d. double check this here, as destruction is a good place to
9325   // ensure that what we've done over the course of the lifetime of
9326   // this object makes sense
9327   AssertNothrow((dim == 1) || (vertex_to_boundary_id_map_1d == nullptr),
9328                 ExcInternalError());
9329 
9330   // the vertex_to_manifold_id_map_1d field should be also unused
9331   // except in 1d. check this as well
9332   AssertNothrow((dim == 1) || (vertex_to_manifold_id_map_1d == nullptr),
9333                 ExcInternalError());
9334 }
9335 
9336 
9337 
9338 template <int dim, int spacedim>
9339 void
clear()9340 Triangulation<dim, spacedim>::clear()
9341 {
9342   // notify listeners that the triangulation is going down...
9343   signals.clear();
9344 
9345   // ...and then actually clear all content of it
9346   clear_despite_subscriptions();
9347   periodic_face_pairs_level_0.clear();
9348   periodic_face_map.clear();
9349 }
9350 
9351 
9352 
9353 template <int dim, int spacedim>
9354 void
set_mesh_smoothing(const MeshSmoothing mesh_smoothing)9355 Triangulation<dim, spacedim>::set_mesh_smoothing(
9356   const MeshSmoothing mesh_smoothing)
9357 {
9358   Assert(n_levels() == 0,
9359          ExcTriangulationNotEmpty(vertices.size(), levels.size()));
9360   smooth_grid = mesh_smoothing;
9361 }
9362 
9363 
9364 
9365 template <int dim, int spacedim>
9366 const typename Triangulation<dim, spacedim>::MeshSmoothing &
get_mesh_smoothing() const9367 Triangulation<dim, spacedim>::get_mesh_smoothing() const
9368 {
9369   return smooth_grid;
9370 }
9371 
9372 
9373 
9374 template <int dim, int spacedim>
9375 void
set_manifold(const types::manifold_id m_number,const Manifold<dim,spacedim> & manifold_object)9376 Triangulation<dim, spacedim>::set_manifold(
9377   const types::manifold_id       m_number,
9378   const Manifold<dim, spacedim> &manifold_object)
9379 {
9380   AssertIndexRange(m_number, numbers::flat_manifold_id);
9381 
9382   manifold[m_number] = manifold_object.clone();
9383 }
9384 
9385 
9386 
9387 template <int dim, int spacedim>
9388 void
reset_manifold(const types::manifold_id m_number)9389 Triangulation<dim, spacedim>::reset_manifold(const types::manifold_id m_number)
9390 {
9391   AssertIndexRange(m_number, numbers::flat_manifold_id);
9392 
9393   // delete the entry located at number.
9394   manifold.erase(m_number);
9395 }
9396 
9397 
9398 template <int dim, int spacedim>
9399 void
reset_all_manifolds()9400 Triangulation<dim, spacedim>::reset_all_manifolds()
9401 {
9402   manifold.clear();
9403 }
9404 
9405 
9406 template <int dim, int spacedim>
9407 void
set_all_manifold_ids(const types::manifold_id m_number)9408 Triangulation<dim, spacedim>::set_all_manifold_ids(
9409   const types::manifold_id m_number)
9410 {
9411   Assert(
9412     n_cells() > 0,
9413     ExcMessage(
9414       "Error: set_all_manifold_ids() can not be called on an empty Triangulation."));
9415 
9416   for (const auto &cell : this->active_cell_iterators())
9417     cell->set_all_manifold_ids(m_number);
9418 }
9419 
9420 
9421 template <int dim, int spacedim>
9422 void
set_all_manifold_ids_on_boundary(const types::manifold_id m_number)9423 Triangulation<dim, spacedim>::set_all_manifold_ids_on_boundary(
9424   const types::manifold_id m_number)
9425 {
9426   Assert(
9427     n_cells() > 0,
9428     ExcMessage(
9429       "Error: set_all_manifold_ids_on_boundary() can not be called on an empty Triangulation."));
9430 
9431   for (const auto &cell : this->active_cell_iterators())
9432     for (auto f : GeometryInfo<dim>::face_indices())
9433       if (cell->face(f)->at_boundary())
9434         cell->face(f)->set_all_manifold_ids(m_number);
9435 }
9436 
9437 
9438 template <int dim, int spacedim>
9439 void
set_all_manifold_ids_on_boundary(const types::boundary_id b_id,const types::manifold_id m_number)9440 Triangulation<dim, spacedim>::set_all_manifold_ids_on_boundary(
9441   const types::boundary_id b_id,
9442   const types::manifold_id m_number)
9443 {
9444   Assert(
9445     n_cells() > 0,
9446     ExcMessage(
9447       "Error: set_all_manifold_ids_on_boundary() can not be called on an empty Triangulation."));
9448 
9449   bool boundary_found = false;
9450 
9451   for (const auto &cell : this->active_cell_iterators())
9452     {
9453       // loop on faces
9454       for (auto f : GeometryInfo<dim>::face_indices())
9455         if (cell->face(f)->at_boundary() &&
9456             cell->face(f)->boundary_id() == b_id)
9457           {
9458             boundary_found = true;
9459             cell->face(f)->set_manifold_id(m_number);
9460           }
9461 
9462       // loop on edges if dim >= 3
9463       if (dim >= 3)
9464         for (unsigned int e = 0; e < GeometryInfo<dim>::lines_per_cell; ++e)
9465           if (cell->line(e)->at_boundary() &&
9466               cell->line(e)->boundary_id() == b_id)
9467             {
9468               boundary_found = true;
9469               cell->line(e)->set_manifold_id(m_number);
9470             }
9471     }
9472 
9473   (void)boundary_found;
9474   Assert(boundary_found, ExcBoundaryIdNotFound(b_id));
9475 }
9476 
9477 
9478 
9479 template <int dim, int spacedim>
9480 const Manifold<dim, spacedim> &
get_manifold(const types::manifold_id m_number) const9481 Triangulation<dim, spacedim>::get_manifold(
9482   const types::manifold_id m_number) const
9483 {
9484   // look, if there is a manifold stored at
9485   // manifold_id number.
9486   const auto it = manifold.find(m_number);
9487 
9488   if (it != manifold.end())
9489     {
9490       // if we have found an entry, return it
9491       return *(it->second);
9492     }
9493 
9494   // if we have not found an entry connected with number, we return
9495   // the default (flat) manifold
9496   return internal::TriangulationImplementation::
9497     get_default_flat_manifold<dim, spacedim>();
9498 }
9499 
9500 
9501 
9502 template <int dim, int spacedim>
9503 std::vector<types::boundary_id>
get_boundary_ids() const9504 Triangulation<dim, spacedim>::get_boundary_ids() const
9505 {
9506   // in 1d, we store a map of all used boundary indicators. use it for
9507   // our purposes
9508   if (dim == 1)
9509     {
9510       std::vector<types::boundary_id> boundary_ids;
9511       for (std::map<unsigned int, types::boundary_id>::const_iterator p =
9512              vertex_to_boundary_id_map_1d->begin();
9513            p != vertex_to_boundary_id_map_1d->end();
9514            ++p)
9515         boundary_ids.push_back(p->second);
9516 
9517       return boundary_ids;
9518     }
9519   else
9520     {
9521       std::set<types::boundary_id> b_ids;
9522       for (auto cell : active_cell_iterators())
9523         if (cell->is_locally_owned())
9524           for (const unsigned int face : GeometryInfo<dim>::face_indices())
9525             if (cell->at_boundary(face))
9526               b_ids.insert(cell->face(face)->boundary_id());
9527       std::vector<types::boundary_id> boundary_ids(b_ids.begin(), b_ids.end());
9528       return boundary_ids;
9529     }
9530 }
9531 
9532 
9533 
9534 template <int dim, int spacedim>
9535 std::vector<types::manifold_id>
get_manifold_ids() const9536 Triangulation<dim, spacedim>::get_manifold_ids() const
9537 {
9538   std::set<types::manifold_id> m_ids;
9539   for (auto cell : active_cell_iterators())
9540     if (cell->is_locally_owned())
9541       {
9542         m_ids.insert(cell->manifold_id());
9543         if (dim > 1)
9544           for (const unsigned int face : GeometryInfo<dim>::face_indices())
9545             if (cell->at_boundary(face))
9546               m_ids.insert(cell->face(face)->manifold_id());
9547       }
9548   std::vector<types::manifold_id> manifold_indicators(m_ids.begin(),
9549                                                       m_ids.end());
9550   return manifold_indicators;
9551 }
9552 
9553 /*-----------------------------------------------------------------*/
9554 
9555 
9556 template <int dim, int spacedim>
9557 void
copy_triangulation(const Triangulation<dim,spacedim> & other_tria)9558 Triangulation<dim, spacedim>::copy_triangulation(
9559   const Triangulation<dim, spacedim> &other_tria)
9560 {
9561   Assert((vertices.size() == 0) && (levels.size() == 0) && (faces == nullptr),
9562          ExcTriangulationNotEmpty(vertices.size(), levels.size()));
9563   Assert((other_tria.levels.size() != 0) && (other_tria.vertices.size() != 0) &&
9564            (dim == 1 || other_tria.faces != nullptr),
9565          ExcMessage(
9566            "When calling Triangulation::copy_triangulation(), "
9567            "the target triangulation must be empty but the source "
9568            "triangulation (the argument to this function) must contain "
9569            "something. Here, it seems like the source does not "
9570            "contain anything at all."));
9571 
9572 
9573   // copy normal elements
9574   vertices               = other_tria.vertices;
9575   vertices_used          = other_tria.vertices_used;
9576   anisotropic_refinement = other_tria.anisotropic_refinement;
9577   smooth_grid            = other_tria.smooth_grid;
9578 
9579   if (dim > 1)
9580     faces = std::make_unique<internal::TriangulationImplementation::TriaFaces>(
9581       *other_tria.faces);
9582 
9583   auto bdry_iterator = other_tria.manifold.begin();
9584   for (; bdry_iterator != other_tria.manifold.end(); ++bdry_iterator)
9585     manifold[bdry_iterator->first] = bdry_iterator->second->clone();
9586 
9587 
9588   levels.reserve(other_tria.levels.size());
9589   for (unsigned int level = 0; level < other_tria.levels.size(); ++level)
9590     levels.push_back(
9591       std::make_unique<internal::TriangulationImplementation::TriaLevel>(
9592         *other_tria.levels[level]));
9593 
9594   number_cache = other_tria.number_cache;
9595 
9596   if (dim == 1)
9597     {
9598       vertex_to_boundary_id_map_1d =
9599         std::make_unique<std::map<unsigned int, types::boundary_id>>(
9600           *other_tria.vertex_to_boundary_id_map_1d);
9601 
9602       vertex_to_manifold_id_map_1d =
9603         std::make_unique<std::map<unsigned int, types::manifold_id>>(
9604           *other_tria.vertex_to_manifold_id_map_1d);
9605     }
9606 
9607   // inform those who are listening on other_tria of the copy operation
9608   other_tria.signals.copy(*this);
9609   // also inform all listeners of the current triangulation that the
9610   // triangulation has been created
9611   signals.create();
9612 
9613   // note that we need not copy the
9614   // subscriptor!
9615 }
9616 
9617 
9618 
9619 template <int dim, int spacedim>
9620 void
create_triangulation_compatibility(const std::vector<Point<spacedim>> & v,const std::vector<CellData<dim>> & cells,const SubCellData & subcelldata)9621 Triangulation<dim, spacedim>::create_triangulation_compatibility(
9622   const std::vector<Point<spacedim>> &v,
9623   const std::vector<CellData<dim>> &  cells,
9624   const SubCellData &                 subcelldata)
9625 {
9626   std::vector<CellData<dim>> reordered_cells(cells);             // NOLINT
9627   SubCellData                reordered_subcelldata(subcelldata); // NOLINT
9628 
9629   // in-place reordering of data
9630   reorder_compatibility(reordered_cells, reordered_subcelldata);
9631 
9632   // now create triangulation from
9633   // reordered data
9634   create_triangulation(v, reordered_cells, reordered_subcelldata);
9635 }
9636 
9637 
9638 
9639 template <int dim, int spacedim>
9640 void
create_triangulation(const std::vector<Point<spacedim>> & v,const std::vector<CellData<dim>> & cells,const SubCellData & subcelldata)9641 Triangulation<dim, spacedim>::create_triangulation(
9642   const std::vector<Point<spacedim>> &v,
9643   const std::vector<CellData<dim>> &  cells,
9644   const SubCellData &                 subcelldata)
9645 {
9646   Assert((vertices.size() == 0) && (levels.size() == 0) && (faces == nullptr),
9647          ExcTriangulationNotEmpty(vertices.size(), levels.size()));
9648   // check that no forbidden arrays
9649   // are used
9650   Assert(subcelldata.check_consistency(dim), ExcInternalError());
9651 
9652   // try to create a triangulation; if this fails, we still want to
9653   // throw an exception but if we just do so we'll get into trouble
9654   // because sometimes other objects are already attached to it:
9655   try
9656     {
9657 #ifndef DEAL_II_WITH_SIMPLEX_SUPPORT
9658       AssertThrow(
9659         std::any_of(cells.begin(),
9660                     cells.end(),
9661                     [](const auto &cell) {
9662                       return cell.vertices.size() !=
9663                              GeometryInfo<dim>::vertices_per_cell;
9664                     }) == false,
9665         ExcMessage(
9666           "A cell with invalid number of vertices has been provided."));
9667 #endif
9668 
9669       internal::TriangulationImplementation::Implementation::
9670         create_triangulation(v, cells, subcelldata, *this);
9671     }
9672   catch (...)
9673     {
9674       clear_despite_subscriptions();
9675       throw;
9676     }
9677 
9678   // update our counts of the various elements of a triangulation, and set
9679   // active_cell_indices of all cells
9680   internal::TriangulationImplementation::Implementation::compute_number_cache(
9681     *this, levels.size(), number_cache);
9682   reset_active_cell_indices();
9683 
9684   // now verify that there are indeed no distorted cells. as per the
9685   // documentation of this class, we first collect all distorted cells
9686   // and then throw an exception if there are any
9687   if (check_for_distorted_cells)
9688     {
9689       DistortedCellList distorted_cells = collect_distorted_coarse_cells(*this);
9690       // throw the array (and fill the various location fields) if
9691       // there are distorted cells. otherwise, just fall off the end
9692       // of the function
9693       AssertThrow(distorted_cells.distorted_cells.size() == 0, distorted_cells);
9694     }
9695 
9696 
9697   /*
9698       When the triangulation is a manifold (dim < spacedim), the normal field
9699       provided from the map class depends on the order of the vertices.
9700       It may happen that this normal field is discontinuous.
9701       The following code takes care that this is not the case by setting the
9702       cell direction flag on those cell that produce the wrong orientation.
9703 
9704       To determine if 2 neighbours have the same or opposite orientation
9705       we use a table of truth.
9706       Its entries are indexes by the local indices of the common face.
9707       For example if two elements share a face, and this face is
9708       face 0 for element 0 and face 1 for element 1, then
9709       table(0,1) will tell whether the orientation are the same (true) or
9710       opposite (false).
9711 
9712       Even though there may be a combinatorial/graph theory argument to get
9713       this table in any dimension, I tested by hand all the different possible
9714       cases in 1D and 2D to generate the table.
9715 
9716       Assuming that a surface respects the standard orientation for 2d meshes,
9717       the tables of truth are symmetric and their true values are the following
9718       1D curves:  (0,1)
9719       2D surface: (0,1),(0,2),(1,3),(2,3)
9720 
9721       We store this data using an n_faces x n_faces full matrix, which is
9722      actually much bigger than the minimal data required, but it makes the code
9723      more readable.
9724 
9725     */
9726   if (dim < spacedim)
9727     {
9728       Table<2, bool> correct(GeometryInfo<dim>::faces_per_cell,
9729                              GeometryInfo<dim>::faces_per_cell);
9730       switch (dim)
9731         {
9732           case 1:
9733             {
9734               bool values[][2] = {{false, true}, {true, false}};
9735               for (const unsigned int i : GeometryInfo<dim>::face_indices())
9736                 for (const unsigned int j : GeometryInfo<dim>::face_indices())
9737                   correct(i, j) = (values[i][j]);
9738               break;
9739             }
9740           case 2:
9741             {
9742               bool values[][4] = {{false, true, true, false},
9743                                   {true, false, false, true},
9744                                   {true, false, false, true},
9745                                   {false, true, true, false}};
9746               for (const unsigned int i : GeometryInfo<dim>::face_indices())
9747                 for (const unsigned int j : GeometryInfo<dim>::face_indices())
9748                   correct(i, j) = (values[i][j]);
9749               break;
9750             }
9751           default:
9752             Assert(false, ExcNotImplemented());
9753         }
9754 
9755 
9756       std::list<active_cell_iterator> this_round, next_round;
9757       active_cell_iterator            neighbor;
9758 
9759       this_round.push_back(begin_active());
9760       begin_active()->set_direction_flag(true);
9761       begin_active()->set_user_flag();
9762 
9763       while (this_round.size() > 0)
9764         {
9765           for (typename std::list<active_cell_iterator>::iterator cell =
9766                  this_round.begin();
9767                cell != this_round.end();
9768                ++cell)
9769             {
9770               for (const unsigned int i : (*cell)->face_indices())
9771                 {
9772                   if (!((*cell)->face(i)->at_boundary()))
9773                     {
9774                       neighbor = (*cell)->neighbor(i);
9775 
9776                       unsigned int cf = (*cell)->face_index(i);
9777                       unsigned int j  = 0;
9778                       while (neighbor->face_index(j) != cf)
9779                         {
9780                           ++j;
9781                         }
9782 
9783 
9784                       // If we already saw this guy, check that everything is
9785                       // fine
9786                       if (neighbor->user_flag_set())
9787                         {
9788                           // If we have visited this guy, then the ordering and
9789                           // the orientation should agree
9790                           Assert(!(correct(i, j) ^
9791                                    (neighbor->direction_flag() ==
9792                                     (*cell)->direction_flag())),
9793                                  ExcNonOrientableTriangulation());
9794                         }
9795                       else
9796                         {
9797                           next_round.push_back(neighbor);
9798                           neighbor->set_user_flag();
9799                           if ((correct(i, j) ^ (neighbor->direction_flag() ==
9800                                                 (*cell)->direction_flag())))
9801                             neighbor->set_direction_flag(
9802                               !neighbor->direction_flag());
9803                         }
9804                     }
9805                 }
9806             }
9807 
9808           // Before we quit let's check
9809           // that if the triangulation
9810           // is disconnected that we
9811           // still get all cells
9812           if (next_round.size() == 0)
9813             for (const auto &cell : this->active_cell_iterators())
9814               if (cell->user_flag_set() == false)
9815                 {
9816                   next_round.push_back(cell);
9817                   cell->set_direction_flag(true);
9818                   cell->set_user_flag();
9819                   break;
9820                 }
9821 
9822           this_round = next_round;
9823           next_round.clear();
9824         }
9825     }
9826 
9827   // inform all listeners that the triangulation has been created
9828   signals.create();
9829 }
9830 
9831 
9832 
9833 template <int dim, int spacedim>
9834 void
create_triangulation(const TriangulationDescription::Description<dim,spacedim> & construction_data)9835 Triangulation<dim, spacedim>::create_triangulation(
9836   const TriangulationDescription::Description<dim, spacedim> &construction_data)
9837 {
9838   // 1) create coarse grid
9839   create_triangulation(construction_data.coarse_cell_vertices,
9840                        construction_data.coarse_cells,
9841                        SubCellData());
9842 
9843   // create a copy of cell_infos such that we can sort them
9844   auto cell_infos = construction_data.cell_infos;
9845 
9846   // sort cell_infos on each level separately
9847   for (auto &cell_info : cell_infos)
9848     std::sort(
9849       cell_info.begin(),
9850       cell_info.end(),
9851       [&](TriangulationDescription::CellData<dim> a,
9852           TriangulationDescription::CellData<dim> b) {
9853         const CellId a_id(a.id);
9854         const CellId b_id(b.id);
9855 
9856         const auto a_coarse_cell_index =
9857           this->coarse_cell_id_to_coarse_cell_index(a_id.get_coarse_cell_id());
9858         const auto b_coarse_cell_index =
9859           this->coarse_cell_id_to_coarse_cell_index(b_id.get_coarse_cell_id());
9860 
9861         // according to their coarse-cell index and if that is
9862         // same according to their cell id (the result is that
9863         // cells on each level are sorted according to their
9864         // index on that level - what we need in the following
9865         // operations)
9866         if (a_coarse_cell_index != b_coarse_cell_index)
9867           return a_coarse_cell_index < b_coarse_cell_index;
9868         else
9869           return a_id < b_id;
9870       });
9871 
9872   // 2) create all levels via a sequence of refinements
9873   for (unsigned int level = 0; level < cell_infos.size(); ++level)
9874     {
9875       // a) set manifold ids here (because new vertices have to be
9876       //    positioned correctly during each refinement step)
9877       {
9878         auto cell      = this->begin(level);
9879         auto cell_info = cell_infos[level].begin();
9880         for (; cell_info != cell_infos[level].end(); ++cell_info)
9881           {
9882             while (cell_info->id != cell->id().template to_binary<dim>())
9883               ++cell;
9884             if (dim == 3)
9885               for (const auto quad : cell->face_indices())
9886                 cell->quad(quad)->set_manifold_id(
9887                   cell_info->manifold_quad_ids[quad]);
9888 
9889             if (dim >= 2)
9890               for (const auto line : cell->line_indices())
9891                 cell->line(line)->set_manifold_id(
9892                   cell_info->manifold_line_ids[line]);
9893 
9894             cell->set_manifold_id(cell_info->manifold_id);
9895           }
9896       }
9897 
9898       // b) perform refinement on all levels but on the finest
9899       if (level + 1 != cell_infos.size())
9900         {
9901           // find cells that should have children and mark them for
9902           // refinement
9903           auto coarse_cell    = this->begin(level);
9904           auto fine_cell_info = cell_infos[level + 1].begin();
9905 
9906           // loop over all cells on the next level
9907           for (; fine_cell_info != cell_infos[level + 1].end();
9908                ++fine_cell_info)
9909             {
9910               // find the parent of that cell
9911               while (
9912                 !coarse_cell->id().is_parent_of(CellId(fine_cell_info->id)))
9913                 ++coarse_cell;
9914 
9915               // set parent for refinement
9916               coarse_cell->set_refine_flag();
9917             }
9918 
9919           // execute refinement
9920           dealii::Triangulation<dim,
9921                                 spacedim>::execute_coarsening_and_refinement();
9922         }
9923     }
9924 
9925   // 3) set boundary ids
9926   for (unsigned int level = 0; level < cell_infos.size(); ++level)
9927     {
9928       auto cell      = this->begin(level);
9929       auto cell_info = cell_infos[level].begin();
9930       for (; cell_info != cell_infos[level].end(); ++cell_info)
9931         {
9932           // find cell that has the correct cell
9933           while (cell_info->id != cell->id().template to_binary<dim>())
9934             ++cell;
9935 
9936           // boundary ids
9937           for (auto pair : cell_info->boundary_ids)
9938             {
9939               Assert(cell->at_boundary(pair.first),
9940                      ExcMessage("Cell face is not on the boundary!"));
9941               cell->face(pair.first)->set_boundary_id(pair.second);
9942             }
9943         }
9944     }
9945 }
9946 
9947 
9948 template <int dim, int spacedim>
9949 void
flip_all_direction_flags()9950 Triangulation<dim, spacedim>::flip_all_direction_flags()
9951 {
9952   AssertThrow(dim + 1 == spacedim,
9953               ExcMessage("Only works for dim == spacedim-1"));
9954   for (const auto &cell : this->active_cell_iterators())
9955     cell->set_direction_flag(!cell->direction_flag());
9956 }
9957 
9958 
9959 
9960 template <int dim, int spacedim>
9961 void
set_all_refine_flags()9962 Triangulation<dim, spacedim>::set_all_refine_flags()
9963 {
9964   Assert(n_cells() > 0,
9965          ExcMessage("Error: An empty Triangulation can not be refined."));
9966 
9967   for (const auto &cell : this->active_cell_iterators())
9968     {
9969       cell->clear_coarsen_flag();
9970       cell->set_refine_flag();
9971     }
9972 }
9973 
9974 
9975 
9976 template <int dim, int spacedim>
9977 void
refine_global(const unsigned int times)9978 Triangulation<dim, spacedim>::refine_global(const unsigned int times)
9979 {
9980   for (unsigned int i = 0; i < times; ++i)
9981     {
9982       set_all_refine_flags();
9983       execute_coarsening_and_refinement();
9984     }
9985 }
9986 
9987 
9988 
9989 /*-------------------- refine/coarsen flags -------------------------*/
9990 
9991 
9992 
9993 template <int dim, int spacedim>
9994 void
save_refine_flags(std::vector<bool> & v) const9995 Triangulation<dim, spacedim>::save_refine_flags(std::vector<bool> &v) const
9996 {
9997   v.resize(dim * n_active_cells(), false);
9998   std::vector<bool>::iterator i = v.begin();
9999 
10000   for (const auto &cell : this->active_cell_iterators())
10001     for (unsigned int j = 0; j < dim; ++j, ++i)
10002       if (cell->refine_flag_set() & (1 << j))
10003         *i = true;
10004 
10005   Assert(i == v.end(), ExcInternalError());
10006 }
10007 
10008 
10009 
10010 template <int dim, int spacedim>
10011 void
save_refine_flags(std::ostream & out) const10012 Triangulation<dim, spacedim>::save_refine_flags(std::ostream &out) const
10013 {
10014   std::vector<bool> v;
10015   save_refine_flags(v);
10016   write_bool_vector(mn_tria_refine_flags_begin,
10017                     v,
10018                     mn_tria_refine_flags_end,
10019                     out);
10020 }
10021 
10022 
10023 
10024 template <int dim, int spacedim>
10025 void
load_refine_flags(std::istream & in)10026 Triangulation<dim, spacedim>::load_refine_flags(std::istream &in)
10027 {
10028   std::vector<bool> v;
10029   read_bool_vector(mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end, in);
10030   load_refine_flags(v);
10031 }
10032 
10033 
10034 
10035 template <int dim, int spacedim>
10036 void
load_refine_flags(const std::vector<bool> & v)10037 Triangulation<dim, spacedim>::load_refine_flags(const std::vector<bool> &v)
10038 {
10039   AssertThrow(v.size() == dim * n_active_cells(), ExcGridReadError());
10040 
10041   std::vector<bool>::const_iterator i = v.begin();
10042   for (const auto &cell : this->active_cell_iterators())
10043     {
10044       unsigned int ref_case = 0;
10045 
10046       for (unsigned int j = 0; j < dim; ++j, ++i)
10047         if (*i == true)
10048           ref_case += 1 << j;
10049       Assert(ref_case < RefinementCase<dim>::isotropic_refinement + 1,
10050              ExcGridReadError());
10051       if (ref_case > 0)
10052         cell->set_refine_flag(RefinementCase<dim>(ref_case));
10053       else
10054         cell->clear_refine_flag();
10055     }
10056 
10057   Assert(i == v.end(), ExcInternalError());
10058 }
10059 
10060 
10061 
10062 template <int dim, int spacedim>
10063 void
save_coarsen_flags(std::vector<bool> & v) const10064 Triangulation<dim, spacedim>::save_coarsen_flags(std::vector<bool> &v) const
10065 {
10066   v.resize(n_active_cells(), false);
10067   std::vector<bool>::iterator i = v.begin();
10068   for (const auto &cell : this->active_cell_iterators())
10069     {
10070       *i = cell->coarsen_flag_set();
10071       ++i;
10072     }
10073 
10074   Assert(i == v.end(), ExcInternalError());
10075 }
10076 
10077 
10078 
10079 template <int dim, int spacedim>
10080 void
save_coarsen_flags(std::ostream & out) const10081 Triangulation<dim, spacedim>::save_coarsen_flags(std::ostream &out) const
10082 {
10083   std::vector<bool> v;
10084   save_coarsen_flags(v);
10085   write_bool_vector(mn_tria_coarsen_flags_begin,
10086                     v,
10087                     mn_tria_coarsen_flags_end,
10088                     out);
10089 }
10090 
10091 
10092 
10093 template <int dim, int spacedim>
10094 void
load_coarsen_flags(std::istream & in)10095 Triangulation<dim, spacedim>::load_coarsen_flags(std::istream &in)
10096 {
10097   std::vector<bool> v;
10098   read_bool_vector(mn_tria_coarsen_flags_begin,
10099                    v,
10100                    mn_tria_coarsen_flags_end,
10101                    in);
10102   load_coarsen_flags(v);
10103 }
10104 
10105 
10106 
10107 template <int dim, int spacedim>
10108 void
load_coarsen_flags(const std::vector<bool> & v)10109 Triangulation<dim, spacedim>::load_coarsen_flags(const std::vector<bool> &v)
10110 {
10111   Assert(v.size() == n_active_cells(), ExcGridReadError());
10112 
10113   std::vector<bool>::const_iterator i = v.begin();
10114   for (const auto &cell : this->active_cell_iterators())
10115     {
10116       if (*i == true)
10117         cell->set_coarsen_flag();
10118       else
10119         cell->clear_coarsen_flag();
10120       ++i;
10121     }
10122 
10123   Assert(i == v.end(), ExcInternalError());
10124 }
10125 
10126 
10127 template <int dim, int spacedim>
10128 bool
get_anisotropic_refinement_flag() const10129 Triangulation<dim, spacedim>::get_anisotropic_refinement_flag() const
10130 {
10131   return anisotropic_refinement;
10132 }
10133 
10134 
10135 
10136 /*-------------------- user data/flags -------------------------*/
10137 
10138 
10139 namespace
10140 {
10141   // clear user data of cells
10142   void
clear_user_data(std::vector<std::unique_ptr<internal::TriangulationImplementation::TriaLevel>> & levels)10143   clear_user_data(std::vector<std::unique_ptr<
10144                     internal::TriangulationImplementation::TriaLevel>> &levels)
10145   {
10146     for (auto &level : levels)
10147       level->cells.clear_user_data();
10148   }
10149 
10150 
10151   // clear user data of faces
10152   void
clear_user_data(internal::TriangulationImplementation::TriaFaces * faces)10153   clear_user_data(internal::TriangulationImplementation::TriaFaces *faces)
10154   {
10155     if (faces->dim == 2)
10156       {
10157         faces->lines.clear_user_data();
10158       }
10159 
10160 
10161     if (faces->dim == 3)
10162       {
10163         faces->lines.clear_user_data();
10164         faces->quads.clear_user_data();
10165       }
10166   }
10167 } // namespace
10168 
10169 
10170 template <int dim, int spacedim>
10171 void
clear_user_data()10172 Triangulation<dim, spacedim>::clear_user_data()
10173 {
10174   // let functions in anonymous namespace do their work
10175   dealii::clear_user_data(levels);
10176   dealii::clear_user_data(faces.get());
10177 }
10178 
10179 
10180 
10181 namespace
10182 {
10183   void
clear_user_flags_line(unsigned int dim,std::vector<std::unique_ptr<internal::TriangulationImplementation::TriaLevel>> & levels,internal::TriangulationImplementation::TriaFaces * faces)10184   clear_user_flags_line(
10185     unsigned int dim,
10186     std::vector<
10187       std::unique_ptr<internal::TriangulationImplementation::TriaLevel>>
10188       &                                               levels,
10189     internal::TriangulationImplementation::TriaFaces *faces)
10190   {
10191     if (dim == 1)
10192       {
10193         for (const auto &level : levels)
10194           level->cells.clear_user_flags();
10195       }
10196     else if (dim == 2 || dim == 3)
10197       {
10198         faces->lines.clear_user_flags();
10199       }
10200     else
10201       {
10202         Assert(false, ExcNotImplemented())
10203       }
10204   }
10205 } // namespace
10206 
10207 
10208 template <int dim, int spacedim>
10209 void
clear_user_flags_line()10210 Triangulation<dim, spacedim>::clear_user_flags_line()
10211 {
10212   dealii::clear_user_flags_line(dim, levels, faces.get());
10213 }
10214 
10215 
10216 
10217 namespace
10218 {
10219   void
clear_user_flags_quad(unsigned int dim,std::vector<std::unique_ptr<internal::TriangulationImplementation::TriaLevel>> & levels,internal::TriangulationImplementation::TriaFaces * faces)10220   clear_user_flags_quad(
10221     unsigned int dim,
10222     std::vector<
10223       std::unique_ptr<internal::TriangulationImplementation::TriaLevel>>
10224       &                                               levels,
10225     internal::TriangulationImplementation::TriaFaces *faces)
10226   {
10227     if (dim == 1)
10228       {
10229         // nothing to do in 1d
10230       }
10231     else if (dim == 2)
10232       {
10233         for (const auto &level : levels)
10234           level->cells.clear_user_flags();
10235       }
10236     else if (dim == 3)
10237       {
10238         faces->quads.clear_user_flags();
10239       }
10240     else
10241       {
10242         Assert(false, ExcNotImplemented())
10243       }
10244   }
10245 } // namespace
10246 
10247 
10248 template <int dim, int spacedim>
10249 void
clear_user_flags_quad()10250 Triangulation<dim, spacedim>::clear_user_flags_quad()
10251 {
10252   dealii::clear_user_flags_quad(dim, levels, faces.get());
10253 }
10254 
10255 
10256 
10257 namespace
10258 {
10259   void
clear_user_flags_hex(unsigned int dim,std::vector<std::unique_ptr<internal::TriangulationImplementation::TriaLevel>> & levels,internal::TriangulationImplementation::TriaFaces *)10260   clear_user_flags_hex(
10261     unsigned int dim,
10262     std::vector<
10263       std::unique_ptr<internal::TriangulationImplementation::TriaLevel>>
10264       &levels,
10265     internal::TriangulationImplementation::TriaFaces *)
10266   {
10267     if (dim == 1)
10268       {
10269         // nothing to do in 1d
10270       }
10271     else if (dim == 2)
10272       {
10273         // nothing to do in 2d
10274       }
10275     else if (dim == 3)
10276       {
10277         for (const auto &level : levels)
10278           level->cells.clear_user_flags();
10279       }
10280     else
10281       {
10282         Assert(false, ExcNotImplemented())
10283       }
10284   }
10285 } // namespace
10286 
10287 
10288 template <int dim, int spacedim>
10289 void
clear_user_flags_hex()10290 Triangulation<dim, spacedim>::clear_user_flags_hex()
10291 {
10292   dealii::clear_user_flags_hex(dim, levels, faces.get());
10293 }
10294 
10295 
10296 
10297 template <int dim, int spacedim>
10298 void
clear_user_flags()10299 Triangulation<dim, spacedim>::clear_user_flags()
10300 {
10301   clear_user_flags_line();
10302   clear_user_flags_quad();
10303   clear_user_flags_hex();
10304 }
10305 
10306 
10307 
10308 template <int dim, int spacedim>
10309 void
save_user_flags(std::ostream & out) const10310 Triangulation<dim, spacedim>::save_user_flags(std::ostream &out) const
10311 {
10312   save_user_flags_line(out);
10313 
10314   if (dim >= 2)
10315     save_user_flags_quad(out);
10316 
10317   if (dim >= 3)
10318     save_user_flags_hex(out);
10319 
10320   if (dim >= 4)
10321     Assert(false, ExcNotImplemented());
10322 }
10323 
10324 
10325 
10326 template <int dim, int spacedim>
10327 void
save_user_flags(std::vector<bool> & v) const10328 Triangulation<dim, spacedim>::save_user_flags(std::vector<bool> &v) const
10329 {
10330   // clear vector and append
10331   // all the stuff later on
10332   v.clear();
10333 
10334   std::vector<bool> tmp;
10335 
10336   save_user_flags_line(tmp);
10337   v.insert(v.end(), tmp.begin(), tmp.end());
10338 
10339   if (dim >= 2)
10340     {
10341       save_user_flags_quad(tmp);
10342       v.insert(v.end(), tmp.begin(), tmp.end());
10343     }
10344 
10345   if (dim >= 3)
10346     {
10347       save_user_flags_hex(tmp);
10348       v.insert(v.end(), tmp.begin(), tmp.end());
10349     }
10350 
10351   if (dim >= 4)
10352     Assert(false, ExcNotImplemented());
10353 }
10354 
10355 
10356 
10357 template <int dim, int spacedim>
10358 void
load_user_flags(std::istream & in)10359 Triangulation<dim, spacedim>::load_user_flags(std::istream &in)
10360 {
10361   load_user_flags_line(in);
10362 
10363   if (dim >= 2)
10364     load_user_flags_quad(in);
10365 
10366   if (dim >= 3)
10367     load_user_flags_hex(in);
10368 
10369   if (dim >= 4)
10370     Assert(false, ExcNotImplemented());
10371 }
10372 
10373 
10374 
10375 template <int dim, int spacedim>
10376 void
load_user_flags(const std::vector<bool> & v)10377 Triangulation<dim, spacedim>::load_user_flags(const std::vector<bool> &v)
10378 {
10379   Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
10380   std::vector<bool> tmp;
10381 
10382   // first extract the flags
10383   // belonging to lines
10384   tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
10385   // and set the lines
10386   load_user_flags_line(tmp);
10387 
10388   if (dim >= 2)
10389     {
10390       tmp.clear();
10391       tmp.insert(tmp.end(),
10392                  v.begin() + n_lines(),
10393                  v.begin() + n_lines() + n_quads());
10394       load_user_flags_quad(tmp);
10395     }
10396 
10397   if (dim >= 3)
10398     {
10399       tmp.clear();
10400       tmp.insert(tmp.end(),
10401                  v.begin() + n_lines() + n_quads(),
10402                  v.begin() + n_lines() + n_quads() + n_hexs());
10403       load_user_flags_hex(tmp);
10404     }
10405 
10406   if (dim >= 4)
10407     Assert(false, ExcNotImplemented());
10408 }
10409 
10410 
10411 
10412 template <int dim, int spacedim>
10413 void
save_user_flags_line(std::vector<bool> & v) const10414 Triangulation<dim, spacedim>::save_user_flags_line(std::vector<bool> &v) const
10415 {
10416   v.resize(n_lines(), false);
10417   std::vector<bool>::iterator i    = v.begin();
10418   line_iterator               line = begin_line(), endl = end_line();
10419   for (; line != endl; ++line, ++i)
10420     *i = line->user_flag_set();
10421 
10422   Assert(i == v.end(), ExcInternalError());
10423 }
10424 
10425 
10426 
10427 template <int dim, int spacedim>
10428 void
save_user_flags_line(std::ostream & out) const10429 Triangulation<dim, spacedim>::save_user_flags_line(std::ostream &out) const
10430 {
10431   std::vector<bool> v;
10432   save_user_flags_line(v);
10433   write_bool_vector(mn_tria_line_user_flags_begin,
10434                     v,
10435                     mn_tria_line_user_flags_end,
10436                     out);
10437 }
10438 
10439 
10440 
10441 template <int dim, int spacedim>
10442 void
load_user_flags_line(std::istream & in)10443 Triangulation<dim, spacedim>::load_user_flags_line(std::istream &in)
10444 {
10445   std::vector<bool> v;
10446   read_bool_vector(mn_tria_line_user_flags_begin,
10447                    v,
10448                    mn_tria_line_user_flags_end,
10449                    in);
10450   load_user_flags_line(v);
10451 }
10452 
10453 
10454 
10455 template <int dim, int spacedim>
10456 void
load_user_flags_line(const std::vector<bool> & v)10457 Triangulation<dim, spacedim>::load_user_flags_line(const std::vector<bool> &v)
10458 {
10459   Assert(v.size() == n_lines(), ExcGridReadError());
10460 
10461   line_iterator                     line = begin_line(), endl = end_line();
10462   std::vector<bool>::const_iterator i = v.begin();
10463   for (; line != endl; ++line, ++i)
10464     if (*i == true)
10465       line->set_user_flag();
10466     else
10467       line->clear_user_flag();
10468 
10469   Assert(i == v.end(), ExcInternalError());
10470 }
10471 
10472 
10473 namespace
10474 {
10475   template <typename Iterator>
10476   bool
get_user_flag(const Iterator & i)10477   get_user_flag(const Iterator &i)
10478   {
10479     return i->user_flag_set();
10480   }
10481 
10482 
10483 
10484   template <int structdim, int dim, int spacedim>
10485   bool
get_user_flag(const TriaIterator<InvalidAccessor<structdim,dim,spacedim>> &)10486   get_user_flag(const TriaIterator<InvalidAccessor<structdim, dim, spacedim>> &)
10487   {
10488     Assert(false, ExcInternalError());
10489     return false;
10490   }
10491 
10492 
10493 
10494   template <typename Iterator>
10495   void
set_user_flag(const Iterator & i)10496   set_user_flag(const Iterator &i)
10497   {
10498     i->set_user_flag();
10499   }
10500 
10501 
10502 
10503   template <int structdim, int dim, int spacedim>
10504   void
set_user_flag(const TriaIterator<InvalidAccessor<structdim,dim,spacedim>> &)10505   set_user_flag(const TriaIterator<InvalidAccessor<structdim, dim, spacedim>> &)
10506   {
10507     Assert(false, ExcInternalError());
10508   }
10509 
10510 
10511 
10512   template <typename Iterator>
10513   void
clear_user_flag(const Iterator & i)10514   clear_user_flag(const Iterator &i)
10515   {
10516     i->clear_user_flag();
10517   }
10518 
10519 
10520 
10521   template <int structdim, int dim, int spacedim>
10522   void
clear_user_flag(const TriaIterator<InvalidAccessor<structdim,dim,spacedim>> &)10523   clear_user_flag(
10524     const TriaIterator<InvalidAccessor<structdim, dim, spacedim>> &)
10525   {
10526     Assert(false, ExcInternalError());
10527   }
10528 } // namespace
10529 
10530 
10531 template <int dim, int spacedim>
10532 void
save_user_flags_quad(std::vector<bool> & v) const10533 Triangulation<dim, spacedim>::save_user_flags_quad(std::vector<bool> &v) const
10534 {
10535   v.resize(n_quads(), false);
10536 
10537   if (dim >= 2)
10538     {
10539       std::vector<bool>::iterator i    = v.begin();
10540       quad_iterator               quad = begin_quad(), endq = end_quad();
10541       for (; quad != endq; ++quad, ++i)
10542         *i = get_user_flag(quad);
10543 
10544       Assert(i == v.end(), ExcInternalError());
10545     }
10546 }
10547 
10548 
10549 
10550 template <int dim, int spacedim>
10551 void
save_user_flags_quad(std::ostream & out) const10552 Triangulation<dim, spacedim>::save_user_flags_quad(std::ostream &out) const
10553 {
10554   std::vector<bool> v;
10555   save_user_flags_quad(v);
10556   write_bool_vector(mn_tria_quad_user_flags_begin,
10557                     v,
10558                     mn_tria_quad_user_flags_end,
10559                     out);
10560 }
10561 
10562 
10563 
10564 template <int dim, int spacedim>
10565 void
load_user_flags_quad(std::istream & in)10566 Triangulation<dim, spacedim>::load_user_flags_quad(std::istream &in)
10567 {
10568   std::vector<bool> v;
10569   read_bool_vector(mn_tria_quad_user_flags_begin,
10570                    v,
10571                    mn_tria_quad_user_flags_end,
10572                    in);
10573   load_user_flags_quad(v);
10574 }
10575 
10576 
10577 
10578 template <int dim, int spacedim>
10579 void
load_user_flags_quad(const std::vector<bool> & v)10580 Triangulation<dim, spacedim>::load_user_flags_quad(const std::vector<bool> &v)
10581 {
10582   Assert(v.size() == n_quads(), ExcGridReadError());
10583 
10584   if (dim >= 2)
10585     {
10586       quad_iterator                     quad = begin_quad(), endq = end_quad();
10587       std::vector<bool>::const_iterator i = v.begin();
10588       for (; quad != endq; ++quad, ++i)
10589         if (*i == true)
10590           set_user_flag(quad);
10591         else
10592           clear_user_flag(quad);
10593 
10594       Assert(i == v.end(), ExcInternalError());
10595     }
10596 }
10597 
10598 
10599 
10600 template <int dim, int spacedim>
10601 void
save_user_flags_hex(std::vector<bool> & v) const10602 Triangulation<dim, spacedim>::save_user_flags_hex(std::vector<bool> &v) const
10603 {
10604   v.resize(n_hexs(), false);
10605 
10606   if (dim >= 3)
10607     {
10608       std::vector<bool>::iterator i   = v.begin();
10609       hex_iterator                hex = begin_hex(), endh = end_hex();
10610       for (; hex != endh; ++hex, ++i)
10611         *i = get_user_flag(hex);
10612 
10613       Assert(i == v.end(), ExcInternalError());
10614     }
10615 }
10616 
10617 
10618 
10619 template <int dim, int spacedim>
10620 void
save_user_flags_hex(std::ostream & out) const10621 Triangulation<dim, spacedim>::save_user_flags_hex(std::ostream &out) const
10622 {
10623   std::vector<bool> v;
10624   save_user_flags_hex(v);
10625   write_bool_vector(mn_tria_hex_user_flags_begin,
10626                     v,
10627                     mn_tria_hex_user_flags_end,
10628                     out);
10629 }
10630 
10631 
10632 
10633 template <int dim, int spacedim>
10634 void
load_user_flags_hex(std::istream & in)10635 Triangulation<dim, spacedim>::load_user_flags_hex(std::istream &in)
10636 {
10637   std::vector<bool> v;
10638   read_bool_vector(mn_tria_hex_user_flags_begin,
10639                    v,
10640                    mn_tria_hex_user_flags_end,
10641                    in);
10642   load_user_flags_hex(v);
10643 }
10644 
10645 
10646 
10647 template <int dim, int spacedim>
10648 void
load_user_flags_hex(const std::vector<bool> & v)10649 Triangulation<dim, spacedim>::load_user_flags_hex(const std::vector<bool> &v)
10650 {
10651   Assert(v.size() == n_hexs(), ExcGridReadError());
10652 
10653   if (dim >= 3)
10654     {
10655       hex_iterator                      hex = begin_hex(), endh = end_hex();
10656       std::vector<bool>::const_iterator i = v.begin();
10657       for (; hex != endh; ++hex, ++i)
10658         if (*i == true)
10659           set_user_flag(hex);
10660         else
10661           clear_user_flag(hex);
10662 
10663       Assert(i == v.end(), ExcInternalError());
10664     }
10665 }
10666 
10667 
10668 
10669 template <int dim, int spacedim>
10670 void
save_user_indices(std::vector<unsigned int> & v) const10671 Triangulation<dim, spacedim>::save_user_indices(
10672   std::vector<unsigned int> &v) const
10673 {
10674   // clear vector and append all the
10675   // stuff later on
10676   v.clear();
10677 
10678   std::vector<unsigned int> tmp;
10679 
10680   save_user_indices_line(tmp);
10681   v.insert(v.end(), tmp.begin(), tmp.end());
10682 
10683   if (dim >= 2)
10684     {
10685       save_user_indices_quad(tmp);
10686       v.insert(v.end(), tmp.begin(), tmp.end());
10687     }
10688 
10689   if (dim >= 3)
10690     {
10691       save_user_indices_hex(tmp);
10692       v.insert(v.end(), tmp.begin(), tmp.end());
10693     }
10694 
10695   if (dim >= 4)
10696     Assert(false, ExcNotImplemented());
10697 }
10698 
10699 
10700 
10701 template <int dim, int spacedim>
10702 void
load_user_indices(const std::vector<unsigned int> & v)10703 Triangulation<dim, spacedim>::load_user_indices(
10704   const std::vector<unsigned int> &v)
10705 {
10706   Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
10707   std::vector<unsigned int> tmp;
10708 
10709   // first extract the indices
10710   // belonging to lines
10711   tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
10712   // and set the lines
10713   load_user_indices_line(tmp);
10714 
10715   if (dim >= 2)
10716     {
10717       tmp.clear();
10718       tmp.insert(tmp.end(),
10719                  v.begin() + n_lines(),
10720                  v.begin() + n_lines() + n_quads());
10721       load_user_indices_quad(tmp);
10722     }
10723 
10724   if (dim >= 3)
10725     {
10726       tmp.clear();
10727       tmp.insert(tmp.end(),
10728                  v.begin() + n_lines() + n_quads(),
10729                  v.begin() + n_lines() + n_quads() + n_hexs());
10730       load_user_indices_hex(tmp);
10731     }
10732 
10733   if (dim >= 4)
10734     Assert(false, ExcNotImplemented());
10735 }
10736 
10737 
10738 
10739 namespace
10740 {
10741   template <typename Iterator>
10742   unsigned int
get_user_index(const Iterator & i)10743   get_user_index(const Iterator &i)
10744   {
10745     return i->user_index();
10746   }
10747 
10748 
10749 
10750   template <int structdim, int dim, int spacedim>
10751   unsigned int
get_user_index(const TriaIterator<InvalidAccessor<structdim,dim,spacedim>> &)10752   get_user_index(
10753     const TriaIterator<InvalidAccessor<structdim, dim, spacedim>> &)
10754   {
10755     Assert(false, ExcInternalError());
10756     return numbers::invalid_unsigned_int;
10757   }
10758 
10759 
10760 
10761   template <typename Iterator>
10762   void
set_user_index(const Iterator & i,const unsigned int x)10763   set_user_index(const Iterator &i, const unsigned int x)
10764   {
10765     i->set_user_index(x);
10766   }
10767 
10768 
10769 
10770   template <int structdim, int dim, int spacedim>
10771   void
set_user_index(const TriaIterator<InvalidAccessor<structdim,dim,spacedim>> &,const unsigned int)10772   set_user_index(
10773     const TriaIterator<InvalidAccessor<structdim, dim, spacedim>> &,
10774     const unsigned int)
10775   {
10776     Assert(false, ExcInternalError());
10777   }
10778 } // namespace
10779 
10780 
10781 template <int dim, int spacedim>
10782 void
save_user_indices_line(std::vector<unsigned int> & v) const10783 Triangulation<dim, spacedim>::save_user_indices_line(
10784   std::vector<unsigned int> &v) const
10785 {
10786   v.resize(n_lines(), 0);
10787   std::vector<unsigned int>::iterator i    = v.begin();
10788   line_iterator                       line = begin_line(), endl = end_line();
10789   for (; line != endl; ++line, ++i)
10790     *i = line->user_index();
10791 }
10792 
10793 
10794 
10795 template <int dim, int spacedim>
10796 void
load_user_indices_line(const std::vector<unsigned int> & v)10797 Triangulation<dim, spacedim>::load_user_indices_line(
10798   const std::vector<unsigned int> &v)
10799 {
10800   Assert(v.size() == n_lines(), ExcGridReadError());
10801 
10802   line_iterator line = begin_line(), endl = end_line();
10803   std::vector<unsigned int>::const_iterator i = v.begin();
10804   for (; line != endl; ++line, ++i)
10805     line->set_user_index(*i);
10806 }
10807 
10808 
10809 template <int dim, int spacedim>
10810 void
save_user_indices_quad(std::vector<unsigned int> & v) const10811 Triangulation<dim, spacedim>::save_user_indices_quad(
10812   std::vector<unsigned int> &v) const
10813 {
10814   v.resize(n_quads(), 0);
10815 
10816   if (dim >= 2)
10817     {
10818       std::vector<unsigned int>::iterator i = v.begin();
10819       quad_iterator quad = begin_quad(), endq = end_quad();
10820       for (; quad != endq; ++quad, ++i)
10821         *i = get_user_index(quad);
10822     }
10823 }
10824 
10825 
10826 
10827 template <int dim, int spacedim>
10828 void
load_user_indices_quad(const std::vector<unsigned int> & v)10829 Triangulation<dim, spacedim>::load_user_indices_quad(
10830   const std::vector<unsigned int> &v)
10831 {
10832   Assert(v.size() == n_quads(), ExcGridReadError());
10833 
10834   if (dim >= 2)
10835     {
10836       quad_iterator quad = begin_quad(), endq = end_quad();
10837       std::vector<unsigned int>::const_iterator i = v.begin();
10838       for (; quad != endq; ++quad, ++i)
10839         set_user_index(quad, *i);
10840     }
10841 }
10842 
10843 
10844 template <int dim, int spacedim>
10845 void
save_user_indices_hex(std::vector<unsigned int> & v) const10846 Triangulation<dim, spacedim>::save_user_indices_hex(
10847   std::vector<unsigned int> &v) const
10848 {
10849   v.resize(n_hexs(), 0);
10850 
10851   if (dim >= 3)
10852     {
10853       std::vector<unsigned int>::iterator i   = v.begin();
10854       hex_iterator                        hex = begin_hex(), endh = end_hex();
10855       for (; hex != endh; ++hex, ++i)
10856         *i = get_user_index(hex);
10857     }
10858 }
10859 
10860 
10861 
10862 template <int dim, int spacedim>
10863 void
load_user_indices_hex(const std::vector<unsigned int> & v)10864 Triangulation<dim, spacedim>::load_user_indices_hex(
10865   const std::vector<unsigned int> &v)
10866 {
10867   Assert(v.size() == n_hexs(), ExcGridReadError());
10868 
10869   if (dim >= 3)
10870     {
10871       hex_iterator hex = begin_hex(), endh = end_hex();
10872       std::vector<unsigned int>::const_iterator i = v.begin();
10873       for (; hex != endh; ++hex, ++i)
10874         set_user_index(hex, *i);
10875     }
10876 }
10877 
10878 
10879 
10880 //---------------- user pointers ----------------------------------------//
10881 
10882 
10883 namespace
10884 {
10885   template <typename Iterator>
10886   void *
get_user_pointer(const Iterator & i)10887   get_user_pointer(const Iterator &i)
10888   {
10889     return i->user_pointer();
10890   }
10891 
10892 
10893 
10894   template <int structdim, int dim, int spacedim>
10895   void *
get_user_pointer(const TriaIterator<InvalidAccessor<structdim,dim,spacedim>> &)10896   get_user_pointer(
10897     const TriaIterator<InvalidAccessor<structdim, dim, spacedim>> &)
10898   {
10899     Assert(false, ExcInternalError());
10900     return nullptr;
10901   }
10902 
10903 
10904 
10905   template <typename Iterator>
10906   void
set_user_pointer(const Iterator & i,void * x)10907   set_user_pointer(const Iterator &i, void *x)
10908   {
10909     i->set_user_pointer(x);
10910   }
10911 
10912 
10913 
10914   template <int structdim, int dim, int spacedim>
10915   void
set_user_pointer(const TriaIterator<InvalidAccessor<structdim,dim,spacedim>> &,void *)10916   set_user_pointer(
10917     const TriaIterator<InvalidAccessor<structdim, dim, spacedim>> &,
10918     void *)
10919   {
10920     Assert(false, ExcInternalError());
10921   }
10922 } // namespace
10923 
10924 
10925 template <int dim, int spacedim>
10926 void
save_user_pointers(std::vector<void * > & v) const10927 Triangulation<dim, spacedim>::save_user_pointers(std::vector<void *> &v) const
10928 {
10929   // clear vector and append all the
10930   // stuff later on
10931   v.clear();
10932 
10933   std::vector<void *> tmp;
10934 
10935   save_user_pointers_line(tmp);
10936   v.insert(v.end(), tmp.begin(), tmp.end());
10937 
10938   if (dim >= 2)
10939     {
10940       save_user_pointers_quad(tmp);
10941       v.insert(v.end(), tmp.begin(), tmp.end());
10942     }
10943 
10944   if (dim >= 3)
10945     {
10946       save_user_pointers_hex(tmp);
10947       v.insert(v.end(), tmp.begin(), tmp.end());
10948     }
10949 
10950   if (dim >= 4)
10951     Assert(false, ExcNotImplemented());
10952 }
10953 
10954 
10955 
10956 template <int dim, int spacedim>
10957 void
load_user_pointers(const std::vector<void * > & v)10958 Triangulation<dim, spacedim>::load_user_pointers(const std::vector<void *> &v)
10959 {
10960   Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
10961   std::vector<void *> tmp;
10962 
10963   // first extract the pointers
10964   // belonging to lines
10965   tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
10966   // and set the lines
10967   load_user_pointers_line(tmp);
10968 
10969   if (dim >= 2)
10970     {
10971       tmp.clear();
10972       tmp.insert(tmp.end(),
10973                  v.begin() + n_lines(),
10974                  v.begin() + n_lines() + n_quads());
10975       load_user_pointers_quad(tmp);
10976     }
10977 
10978   if (dim >= 3)
10979     {
10980       tmp.clear();
10981       tmp.insert(tmp.end(),
10982                  v.begin() + n_lines() + n_quads(),
10983                  v.begin() + n_lines() + n_quads() + n_hexs());
10984       load_user_pointers_hex(tmp);
10985     }
10986 
10987   if (dim >= 4)
10988     Assert(false, ExcNotImplemented());
10989 }
10990 
10991 
10992 
10993 template <int dim, int spacedim>
10994 void
save_user_pointers_line(std::vector<void * > & v) const10995 Triangulation<dim, spacedim>::save_user_pointers_line(
10996   std::vector<void *> &v) const
10997 {
10998   v.resize(n_lines(), nullptr);
10999   std::vector<void *>::iterator i    = v.begin();
11000   line_iterator                 line = begin_line(), endl = end_line();
11001   for (; line != endl; ++line, ++i)
11002     *i = line->user_pointer();
11003 }
11004 
11005 
11006 
11007 template <int dim, int spacedim>
11008 void
load_user_pointers_line(const std::vector<void * > & v)11009 Triangulation<dim, spacedim>::load_user_pointers_line(
11010   const std::vector<void *> &v)
11011 {
11012   Assert(v.size() == n_lines(), ExcGridReadError());
11013 
11014   line_iterator                       line = begin_line(), endl = end_line();
11015   std::vector<void *>::const_iterator i = v.begin();
11016   for (; line != endl; ++line, ++i)
11017     line->set_user_pointer(*i);
11018 }
11019 
11020 
11021 
11022 template <int dim, int spacedim>
11023 void
save_user_pointers_quad(std::vector<void * > & v) const11024 Triangulation<dim, spacedim>::save_user_pointers_quad(
11025   std::vector<void *> &v) const
11026 {
11027   v.resize(n_quads(), nullptr);
11028 
11029   if (dim >= 2)
11030     {
11031       std::vector<void *>::iterator i    = v.begin();
11032       quad_iterator                 quad = begin_quad(), endq = end_quad();
11033       for (; quad != endq; ++quad, ++i)
11034         *i = get_user_pointer(quad);
11035     }
11036 }
11037 
11038 
11039 
11040 template <int dim, int spacedim>
11041 void
load_user_pointers_quad(const std::vector<void * > & v)11042 Triangulation<dim, spacedim>::load_user_pointers_quad(
11043   const std::vector<void *> &v)
11044 {
11045   Assert(v.size() == n_quads(), ExcGridReadError());
11046 
11047   if (dim >= 2)
11048     {
11049       quad_iterator quad = begin_quad(), endq = end_quad();
11050       std::vector<void *>::const_iterator i = v.begin();
11051       for (; quad != endq; ++quad, ++i)
11052         set_user_pointer(quad, *i);
11053     }
11054 }
11055 
11056 
11057 template <int dim, int spacedim>
11058 void
save_user_pointers_hex(std::vector<void * > & v) const11059 Triangulation<dim, spacedim>::save_user_pointers_hex(
11060   std::vector<void *> &v) const
11061 {
11062   v.resize(n_hexs(), nullptr);
11063 
11064   if (dim >= 3)
11065     {
11066       std::vector<void *>::iterator i   = v.begin();
11067       hex_iterator                  hex = begin_hex(), endh = end_hex();
11068       for (; hex != endh; ++hex, ++i)
11069         *i = get_user_pointer(hex);
11070     }
11071 }
11072 
11073 
11074 
11075 template <int dim, int spacedim>
11076 void
load_user_pointers_hex(const std::vector<void * > & v)11077 Triangulation<dim, spacedim>::load_user_pointers_hex(
11078   const std::vector<void *> &v)
11079 {
11080   Assert(v.size() == n_hexs(), ExcGridReadError());
11081 
11082   if (dim >= 3)
11083     {
11084       hex_iterator                        hex = begin_hex(), endh = end_hex();
11085       std::vector<void *>::const_iterator i = v.begin();
11086       for (; hex != endh; ++hex, ++i)
11087         set_user_pointer(hex, *i);
11088     }
11089 }
11090 
11091 
11092 
11093 /*------------------------ Cell iterator functions ------------------------*/
11094 
11095 
11096 template <int dim, int spacedim>
11097 typename Triangulation<dim, spacedim>::raw_cell_iterator
begin_raw(const unsigned int level) const11098 Triangulation<dim, spacedim>::begin_raw(const unsigned int level) const
11099 {
11100   switch (dim)
11101     {
11102       case 1:
11103         return begin_raw_line(level);
11104       case 2:
11105         return begin_raw_quad(level);
11106       case 3:
11107         return begin_raw_hex(level);
11108       default:
11109         Assert(false, ExcNotImplemented());
11110         return raw_cell_iterator();
11111     }
11112 }
11113 
11114 
11115 
11116 template <int dim, int spacedim>
11117 typename Triangulation<dim, spacedim>::cell_iterator
begin(const unsigned int level) const11118 Triangulation<dim, spacedim>::begin(const unsigned int level) const
11119 {
11120   switch (dim)
11121     {
11122       case 1:
11123         return begin_line(level);
11124       case 2:
11125         return begin_quad(level);
11126       case 3:
11127         return begin_hex(level);
11128       default:
11129         Assert(false, ExcImpossibleInDim(dim));
11130         return cell_iterator();
11131     }
11132 }
11133 
11134 
11135 
11136 template <int dim, int spacedim>
11137 typename Triangulation<dim, spacedim>::active_cell_iterator
begin_active(const unsigned int level) const11138 Triangulation<dim, spacedim>::begin_active(const unsigned int level) const
11139 {
11140   switch (dim)
11141     {
11142       case 1:
11143         return begin_active_line(level);
11144       case 2:
11145         return begin_active_quad(level);
11146       case 3:
11147         return begin_active_hex(level);
11148       default:
11149         Assert(false, ExcNotImplemented());
11150         return active_cell_iterator();
11151     }
11152 }
11153 
11154 
11155 
11156 template <int dim, int spacedim>
11157 typename Triangulation<dim, spacedim>::cell_iterator
last() const11158 Triangulation<dim, spacedim>::last() const
11159 {
11160   const unsigned int level = levels.size() - 1;
11161   if (levels[level]->cells.n_objects() == 0)
11162     return end(level);
11163 
11164   // find the last raw iterator on
11165   // this level
11166   raw_cell_iterator ri(const_cast<Triangulation<dim, spacedim> *>(this),
11167                        level,
11168                        levels[level]->cells.n_objects() - 1);
11169 
11170   // then move to the last used one
11171   if (ri->used() == true)
11172     return ri;
11173   while ((--ri).state() == IteratorState::valid)
11174     if (ri->used() == true)
11175       return ri;
11176   return ri;
11177 }
11178 
11179 
11180 
11181 template <int dim, int spacedim>
11182 typename Triangulation<dim, spacedim>::active_cell_iterator
last_active() const11183 Triangulation<dim, spacedim>::last_active() const
11184 {
11185   // get the last used cell
11186   cell_iterator cell = last();
11187 
11188   if (cell != end())
11189     {
11190       // then move to the last active one
11191       if (cell->is_active() == true)
11192         return cell;
11193       while ((--cell).state() == IteratorState::valid)
11194         if (cell->is_active() == true)
11195           return cell;
11196     }
11197   return cell;
11198 }
11199 
11200 
11201 
11202 template <int dim, int spacedim>
11203 typename Triangulation<dim, spacedim>::cell_iterator
end() const11204 Triangulation<dim, spacedim>::end() const
11205 {
11206   return cell_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
11207                        -1,
11208                        -1);
11209 }
11210 
11211 
11212 
11213 template <int dim, int spacedim>
11214 typename Triangulation<dim, spacedim>::raw_cell_iterator
end_raw(const unsigned int level) const11215 Triangulation<dim, spacedim>::end_raw(const unsigned int level) const
11216 {
11217   // This function may be called on parallel triangulations on levels
11218   // that exist globally, but not on the local portion of the
11219   // triangulation. In that case, just return the end iterator.
11220   //
11221   // We need to use levels.size() instead of n_levels() because the
11222   // latter function uses the cache, but we need to be able to call
11223   // this function at a time when the cache is not currently up to
11224   // date.
11225   if (level >= levels.size())
11226     {
11227       Assert(level < n_global_levels(),
11228              ExcInvalidLevel(level, n_global_levels()));
11229       return end();
11230     }
11231 
11232   // Query whether the given level is valid for the local portion of the
11233   // triangulation.
11234   Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
11235   if (level < levels.size() - 1)
11236     return begin_raw(level + 1);
11237   else
11238     return end();
11239 }
11240 
11241 
11242 template <int dim, int spacedim>
11243 typename Triangulation<dim, spacedim>::cell_iterator
end(const unsigned int level) const11244 Triangulation<dim, spacedim>::end(const unsigned int level) const
11245 {
11246   // This function may be called on parallel triangulations on levels
11247   // that exist globally, but not on the local portion of the
11248   // triangulation. In that case, just retrn the end iterator.
11249   //
11250   // We need to use levels.size() instead of n_levels() because the
11251   // latter function uses the cache, but we need to be able to call
11252   // this function at a time when the cache is not currently up to
11253   // date.
11254   if (level >= levels.size())
11255     {
11256       Assert(level < n_global_levels(),
11257              ExcInvalidLevel(level, n_global_levels()));
11258       return end();
11259     }
11260 
11261   // Query whether the given level is valid for the local portion of the
11262   // triangulation.
11263   Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
11264   if (level < levels.size() - 1)
11265     return begin(level + 1);
11266   else
11267     return end();
11268 }
11269 
11270 
11271 template <int dim, int spacedim>
11272 typename Triangulation<dim, spacedim>::active_cell_iterator
end_active(const unsigned int level) const11273 Triangulation<dim, spacedim>::end_active(const unsigned int level) const
11274 {
11275   // This function may be called on parallel triangulations on levels
11276   // that exist globally, but not on the local portion of the
11277   // triangulation. In that case, just return the end iterator.
11278   //
11279   // We need to use levels.size() instead of n_levels() because the
11280   // latter function uses the cache, but we need to be able to call
11281   // this function at a time when the cache is not currently up to
11282   // date.
11283   if (level >= levels.size())
11284     {
11285       Assert(level < n_global_levels(),
11286              ExcInvalidLevel(level, n_global_levels()));
11287       return end();
11288     }
11289 
11290   // Query whether the given level is valid for the local portion of the
11291   // triangulation.
11292   Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
11293   return (level >= levels.size() - 1 ? active_cell_iterator(end()) :
11294                                        begin_active(level + 1));
11295 }
11296 
11297 
11298 
11299 template <int dim, int spacedim>
11300 IteratorRange<typename Triangulation<dim, spacedim>::cell_iterator>
cell_iterators() const11301 Triangulation<dim, spacedim>::cell_iterators() const
11302 {
11303   return IteratorRange<typename Triangulation<dim, spacedim>::cell_iterator>(
11304     begin(), end());
11305 }
11306 
11307 
11308 template <int dim, int spacedim>
11309 IteratorRange<typename Triangulation<dim, spacedim>::active_cell_iterator>
active_cell_iterators() const11310 Triangulation<dim, spacedim>::active_cell_iterators() const
11311 {
11312   return IteratorRange<
11313     typename Triangulation<dim, spacedim>::active_cell_iterator>(begin_active(),
11314                                                                  end());
11315 }
11316 
11317 
11318 
11319 template <int dim, int spacedim>
11320 IteratorRange<typename Triangulation<dim, spacedim>::cell_iterator>
cell_iterators_on_level(const unsigned int level) const11321 Triangulation<dim, spacedim>::cell_iterators_on_level(
11322   const unsigned int level) const
11323 {
11324   return IteratorRange<typename Triangulation<dim, spacedim>::cell_iterator>(
11325     begin(level), end(level));
11326 }
11327 
11328 
11329 
11330 template <int dim, int spacedim>
11331 IteratorRange<typename Triangulation<dim, spacedim>::active_cell_iterator>
active_cell_iterators_on_level(const unsigned int level) const11332 Triangulation<dim, spacedim>::active_cell_iterators_on_level(
11333   const unsigned int level) const
11334 {
11335   return IteratorRange<
11336     typename Triangulation<dim, spacedim>::active_cell_iterator>(
11337     begin_active(level), end_active(level));
11338 }
11339 
11340 
11341 /*------------------------ Face iterator functions ------------------------*/
11342 
11343 
11344 template <int dim, int spacedim>
11345 typename Triangulation<dim, spacedim>::face_iterator
begin_face() const11346 Triangulation<dim, spacedim>::begin_face() const
11347 {
11348   switch (dim)
11349     {
11350       case 1:
11351         Assert(false, ExcImpossibleInDim(1));
11352         return raw_face_iterator();
11353       case 2:
11354         return begin_line();
11355       case 3:
11356         return begin_quad();
11357       default:
11358         Assert(false, ExcNotImplemented());
11359         return face_iterator();
11360     }
11361 }
11362 
11363 
11364 
11365 template <int dim, int spacedim>
11366 typename Triangulation<dim, spacedim>::active_face_iterator
begin_active_face() const11367 Triangulation<dim, spacedim>::begin_active_face() const
11368 {
11369   switch (dim)
11370     {
11371       case 1:
11372         Assert(false, ExcImpossibleInDim(1));
11373         return raw_face_iterator();
11374       case 2:
11375         return begin_active_line();
11376       case 3:
11377         return begin_active_quad();
11378       default:
11379         Assert(false, ExcNotImplemented());
11380         return active_face_iterator();
11381     }
11382 }
11383 
11384 
11385 
11386 template <int dim, int spacedim>
11387 typename Triangulation<dim, spacedim>::face_iterator
end_face() const11388 Triangulation<dim, spacedim>::end_face() const
11389 {
11390   switch (dim)
11391     {
11392       case 1:
11393         Assert(false, ExcImpossibleInDim(1));
11394         return raw_face_iterator();
11395       case 2:
11396         return end_line();
11397       case 3:
11398         return end_quad();
11399       default:
11400         Assert(false, ExcNotImplemented());
11401         return raw_face_iterator();
11402     }
11403 }
11404 
11405 
11406 
11407 template <int dim, int spacedim>
11408 IteratorRange<typename Triangulation<dim, spacedim>::active_face_iterator>
active_face_iterators() const11409 Triangulation<dim, spacedim>::active_face_iterators() const
11410 {
11411   return IteratorRange<
11412     typename Triangulation<dim, spacedim>::active_face_iterator>(
11413     begin_active_face(), end_face());
11414 }
11415 
11416 /*------------------------ Vertex iterator functions ------------------------*/
11417 
11418 
11419 template <int dim, int spacedim>
11420 typename Triangulation<dim, spacedim>::vertex_iterator
begin_vertex() const11421 Triangulation<dim, spacedim>::begin_vertex() const
11422 {
11423   vertex_iterator i =
11424     raw_vertex_iterator(const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
11425   if (i.state() != IteratorState::valid)
11426     return i;
11427   // This loop will end because every triangulation has used vertices.
11428   while (i->used() == false)
11429     if ((++i).state() != IteratorState::valid)
11430       return i;
11431   return i;
11432 }
11433 
11434 
11435 
11436 template <int dim, int spacedim>
11437 typename Triangulation<dim, spacedim>::active_vertex_iterator
begin_active_vertex() const11438 Triangulation<dim, spacedim>::begin_active_vertex() const
11439 {
11440   // every vertex is active
11441   return begin_vertex();
11442 }
11443 
11444 
11445 
11446 template <int dim, int spacedim>
11447 typename Triangulation<dim, spacedim>::vertex_iterator
end_vertex() const11448 Triangulation<dim, spacedim>::end_vertex() const
11449 {
11450   return raw_vertex_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
11451                              -1,
11452                              numbers::invalid_unsigned_int);
11453 }
11454 
11455 
11456 
11457 /*------------------------ Line iterator functions ------------------------*/
11458 
11459 
11460 
11461 template <int dim, int spacedim>
11462 typename Triangulation<dim, spacedim>::raw_line_iterator
begin_raw_line(const unsigned int level) const11463 Triangulation<dim, spacedim>::begin_raw_line(const unsigned int level) const
11464 {
11465   // This function may be called on parallel triangulations on levels
11466   // that exist globally, but not on the local portion of the
11467   // triangulation. In that case, just return the end iterator.
11468   //
11469   // We need to use levels.size() instead of n_levels() because the
11470   // latter function uses the cache, but we need to be able to call
11471   // this function at a time when the cache is not currently up to
11472   // date.
11473   if (level >= levels.size())
11474     {
11475       Assert(level < n_global_levels(),
11476              ExcInvalidLevel(level, n_global_levels()));
11477       return end_line();
11478     }
11479 
11480   switch (dim)
11481     {
11482       case 1:
11483         // Query whether the given level is valid for the local portion of the
11484         // triangulation.
11485         Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
11486 
11487         if (level >= levels.size() || levels[level]->cells.n_objects() == 0)
11488           return end_line();
11489 
11490         return raw_line_iterator(
11491           const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
11492 
11493       default:
11494         Assert(level == 0, ExcFacesHaveNoLevel());
11495         return raw_line_iterator(
11496           const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
11497     }
11498 }
11499 
11500 
11501 template <int dim, int spacedim>
11502 typename Triangulation<dim, spacedim>::line_iterator
begin_line(const unsigned int level) const11503 Triangulation<dim, spacedim>::begin_line(const unsigned int level) const
11504 {
11505   // level is checked in begin_raw
11506   raw_line_iterator ri = begin_raw_line(level);
11507   if (ri.state() != IteratorState::valid)
11508     return ri;
11509   while (ri->used() == false)
11510     if ((++ri).state() != IteratorState::valid)
11511       return ri;
11512   return ri;
11513 }
11514 
11515 
11516 
11517 template <int dim, int spacedim>
11518 typename Triangulation<dim, spacedim>::active_line_iterator
begin_active_line(const unsigned int level) const11519 Triangulation<dim, spacedim>::begin_active_line(const unsigned int level) const
11520 {
11521   // level is checked in begin_raw
11522   line_iterator i = begin_line(level);
11523   if (i.state() != IteratorState::valid)
11524     return i;
11525   while (i->has_children())
11526     if ((++i).state() != IteratorState::valid)
11527       return i;
11528   return i;
11529 }
11530 
11531 
11532 
11533 template <int dim, int spacedim>
11534 typename Triangulation<dim, spacedim>::line_iterator
end_line() const11535 Triangulation<dim, spacedim>::end_line() const
11536 {
11537   return raw_line_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
11538                            -1,
11539                            -1);
11540 }
11541 
11542 
11543 
11544 /*------------------------ Quad iterator functions ------------------------*/
11545 
11546 
11547 template <int dim, int spacedim>
11548 typename Triangulation<dim, spacedim>::raw_quad_iterator
begin_raw_quad(const unsigned int level) const11549 Triangulation<dim, spacedim>::begin_raw_quad(const unsigned int level) const
11550 {
11551   // This function may be called on parallel triangulations on levels
11552   // that exist globally, but not on the local portion of the
11553   // triangulation. In that case, just return the end iterator.
11554   //
11555   // We need to use levels.size() instead of n_levels() because the
11556   // latter function uses the cache, but we need to be able to call
11557   // this function at a time when the cache is not currently up to
11558   // date.
11559   if (level >= levels.size())
11560     {
11561       Assert(level < n_global_levels(),
11562              ExcInvalidLevel(level, n_global_levels()));
11563       return end_quad();
11564     }
11565 
11566   switch (dim)
11567     {
11568       case 1:
11569         Assert(false, ExcImpossibleInDim(1));
11570         return raw_hex_iterator();
11571       case 2:
11572         {
11573           // Query whether the given level is valid for the local portion of the
11574           // triangulation.
11575           Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
11576 
11577           if (level >= levels.size() || levels[level]->cells.n_objects() == 0)
11578             return end_quad();
11579 
11580           return raw_quad_iterator(
11581             const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
11582         }
11583 
11584       case 3:
11585         {
11586           Assert(level == 0, ExcFacesHaveNoLevel());
11587 
11588           return raw_quad_iterator(
11589             const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
11590         }
11591 
11592 
11593       default:
11594         Assert(false, ExcNotImplemented());
11595         return raw_hex_iterator();
11596     }
11597 }
11598 
11599 
11600 
11601 template <int dim, int spacedim>
11602 typename Triangulation<dim, spacedim>::quad_iterator
begin_quad(const unsigned int level) const11603 Triangulation<dim, spacedim>::begin_quad(const unsigned int level) const
11604 {
11605   // level is checked in begin_raw
11606   raw_quad_iterator ri = begin_raw_quad(level);
11607   if (ri.state() != IteratorState::valid)
11608     return ri;
11609   while (ri->used() == false)
11610     if ((++ri).state() != IteratorState::valid)
11611       return ri;
11612   return ri;
11613 }
11614 
11615 
11616 
11617 template <int dim, int spacedim>
11618 typename Triangulation<dim, spacedim>::active_quad_iterator
begin_active_quad(const unsigned int level) const11619 Triangulation<dim, spacedim>::begin_active_quad(const unsigned int level) const
11620 {
11621   // level is checked in begin_raw
11622   quad_iterator i = begin_quad(level);
11623   if (i.state() != IteratorState::valid)
11624     return i;
11625   while (i->has_children())
11626     if ((++i).state() != IteratorState::valid)
11627       return i;
11628   return i;
11629 }
11630 
11631 
11632 
11633 template <int dim, int spacedim>
11634 typename Triangulation<dim, spacedim>::quad_iterator
end_quad() const11635 Triangulation<dim, spacedim>::end_quad() const
11636 {
11637   return raw_quad_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
11638                            -1,
11639                            -1);
11640 }
11641 
11642 
11643 /*------------------------ Hex iterator functions ------------------------*/
11644 
11645 
11646 template <int dim, int spacedim>
11647 typename Triangulation<dim, spacedim>::raw_hex_iterator
begin_raw_hex(const unsigned int level) const11648 Triangulation<dim, spacedim>::begin_raw_hex(const unsigned int level) const
11649 {
11650   // This function may be called on parallel triangulations on levels
11651   // that exist globally, but not on the local portion of the
11652   // triangulation. In that case, just return the end iterator.
11653   //
11654   // We need to use levels.size() instead of n_levels() because the
11655   // latter function uses the cache, but we need to be able to call
11656   // this function at a time when the cache is not currently up to
11657   // date.
11658   if (level >= levels.size())
11659     {
11660       Assert(level < n_global_levels(),
11661              ExcInvalidLevel(level, n_global_levels()));
11662       return end_hex();
11663     }
11664 
11665   switch (dim)
11666     {
11667       case 1:
11668       case 2:
11669         Assert(false, ExcImpossibleInDim(1));
11670         return raw_hex_iterator();
11671       case 3:
11672         {
11673           // Query whether the given level is valid for the local portion of the
11674           // triangulation.
11675           Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
11676 
11677           if (level >= levels.size() || levels[level]->cells.n_objects() == 0)
11678             return end_hex();
11679 
11680           return raw_hex_iterator(
11681             const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
11682         }
11683 
11684       default:
11685         Assert(false, ExcNotImplemented());
11686         return raw_hex_iterator();
11687     }
11688 }
11689 
11690 
11691 
11692 template <int dim, int spacedim>
11693 typename Triangulation<dim, spacedim>::hex_iterator
begin_hex(const unsigned int level) const11694 Triangulation<dim, spacedim>::begin_hex(const unsigned int level) const
11695 {
11696   // level is checked in begin_raw
11697   raw_hex_iterator ri = begin_raw_hex(level);
11698   if (ri.state() != IteratorState::valid)
11699     return ri;
11700   while (ri->used() == false)
11701     if ((++ri).state() != IteratorState::valid)
11702       return ri;
11703   return ri;
11704 }
11705 
11706 
11707 
11708 template <int dim, int spacedim>
11709 typename Triangulation<dim, spacedim>::active_hex_iterator
begin_active_hex(const unsigned int level) const11710 Triangulation<dim, spacedim>::begin_active_hex(const unsigned int level) const
11711 {
11712   // level is checked in begin_raw
11713   hex_iterator i = begin_hex(level);
11714   if (i.state() != IteratorState::valid)
11715     return i;
11716   while (i->has_children())
11717     if ((++i).state() != IteratorState::valid)
11718       return i;
11719   return i;
11720 }
11721 
11722 
11723 
11724 template <int dim, int spacedim>
11725 typename Triangulation<dim, spacedim>::hex_iterator
end_hex() const11726 Triangulation<dim, spacedim>::end_hex() const
11727 {
11728   return raw_hex_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
11729                           -1,
11730                           -1);
11731 }
11732 
11733 
11734 
11735 // -------------------------------- number of cells etc ---------------
11736 
11737 
11738 namespace internal
11739 {
11740   namespace TriangulationImplementation
11741   {
11742     inline unsigned int
n_cells(const internal::TriangulationImplementation::NumberCache<1> & c)11743     n_cells(const internal::TriangulationImplementation::NumberCache<1> &c)
11744     {
11745       return c.n_lines;
11746     }
11747 
11748 
11749     inline unsigned int
n_active_cells(const internal::TriangulationImplementation::NumberCache<1> & c)11750     n_active_cells(
11751       const internal::TriangulationImplementation::NumberCache<1> &c)
11752     {
11753       return c.n_active_lines;
11754     }
11755 
11756 
11757     inline unsigned int
n_cells(const internal::TriangulationImplementation::NumberCache<2> & c)11758     n_cells(const internal::TriangulationImplementation::NumberCache<2> &c)
11759     {
11760       return c.n_quads;
11761     }
11762 
11763 
11764     inline unsigned int
n_active_cells(const internal::TriangulationImplementation::NumberCache<2> & c)11765     n_active_cells(
11766       const internal::TriangulationImplementation::NumberCache<2> &c)
11767     {
11768       return c.n_active_quads;
11769     }
11770 
11771 
11772     inline unsigned int
n_cells(const internal::TriangulationImplementation::NumberCache<3> & c)11773     n_cells(const internal::TriangulationImplementation::NumberCache<3> &c)
11774     {
11775       return c.n_hexes;
11776     }
11777 
11778 
11779     inline unsigned int
n_active_cells(const internal::TriangulationImplementation::NumberCache<3> & c)11780     n_active_cells(
11781       const internal::TriangulationImplementation::NumberCache<3> &c)
11782     {
11783       return c.n_active_hexes;
11784     }
11785   } // namespace TriangulationImplementation
11786 } // namespace internal
11787 
11788 
11789 
11790 template <int dim, int spacedim>
11791 unsigned int
n_cells() const11792 Triangulation<dim, spacedim>::n_cells() const
11793 {
11794   return internal::TriangulationImplementation::n_cells(number_cache);
11795 }
11796 
11797 
11798 template <int dim, int spacedim>
11799 unsigned int
n_active_cells() const11800 Triangulation<dim, spacedim>::n_active_cells() const
11801 {
11802   return internal::TriangulationImplementation::n_active_cells(number_cache);
11803 }
11804 
11805 template <int dim, int spacedim>
11806 types::global_cell_index
n_global_active_cells() const11807 Triangulation<dim, spacedim>::n_global_active_cells() const
11808 {
11809   return n_active_cells();
11810 }
11811 
11812 
11813 
11814 template <int dim, int spacedim>
11815 unsigned int
n_faces() const11816 Triangulation<dim, spacedim>::n_faces() const
11817 {
11818   switch (dim)
11819     {
11820       case 1:
11821         return n_used_vertices();
11822       case 2:
11823         return n_lines();
11824       case 3:
11825         return n_quads();
11826       default:
11827         Assert(false, ExcNotImplemented());
11828     }
11829   return 0;
11830 }
11831 
11832 
11833 template <int dim, int spacedim>
11834 unsigned int
n_raw_faces() const11835 Triangulation<dim, spacedim>::n_raw_faces() const
11836 {
11837   switch (dim)
11838     {
11839       case 1:
11840         return n_vertices();
11841       case 2:
11842         return n_raw_lines();
11843       case 3:
11844         return n_raw_quads();
11845       default:
11846         Assert(false, ExcNotImplemented());
11847     }
11848   return 0;
11849 }
11850 
11851 
11852 template <int dim, int spacedim>
11853 unsigned int
n_active_faces() const11854 Triangulation<dim, spacedim>::n_active_faces() const
11855 {
11856   switch (dim)
11857     {
11858       case 1:
11859         return n_used_vertices();
11860       case 2:
11861         return n_active_lines();
11862       case 3:
11863         return n_active_quads();
11864       default:
11865         Assert(false, ExcNotImplemented());
11866     }
11867   return 0;
11868 }
11869 
11870 
11871 template <int dim, int spacedim>
11872 unsigned int
n_raw_cells(const unsigned int level) const11873 Triangulation<dim, spacedim>::n_raw_cells(const unsigned int level) const
11874 {
11875   switch (dim)
11876     {
11877       case 1:
11878         return n_raw_lines(level);
11879       case 2:
11880         return n_raw_quads(level);
11881       case 3:
11882         return n_raw_hexs(level);
11883       default:
11884         Assert(false, ExcNotImplemented());
11885     }
11886   return 0;
11887 }
11888 
11889 
11890 
11891 template <int dim, int spacedim>
11892 unsigned int
n_cells(const unsigned int level) const11893 Triangulation<dim, spacedim>::n_cells(const unsigned int level) const
11894 {
11895   switch (dim)
11896     {
11897       case 1:
11898         return n_lines(level);
11899       case 2:
11900         return n_quads(level);
11901       case 3:
11902         return n_hexs(level);
11903       default:
11904         Assert(false, ExcNotImplemented());
11905     }
11906   return 0;
11907 }
11908 
11909 
11910 
11911 template <int dim, int spacedim>
11912 unsigned int
n_active_cells(const unsigned int level) const11913 Triangulation<dim, spacedim>::n_active_cells(const unsigned int level) const
11914 {
11915   switch (dim)
11916     {
11917       case 1:
11918         return n_active_lines(level);
11919       case 2:
11920         return n_active_quads(level);
11921       case 3:
11922         return n_active_hexs(level);
11923       default:
11924         Assert(false, ExcNotImplemented());
11925     }
11926   return 0;
11927 }
11928 
11929 
11930 template <int dim, int spacedim>
11931 bool
has_hanging_nodes() const11932 Triangulation<dim, spacedim>::has_hanging_nodes() const
11933 {
11934   for (unsigned int lvl = 0; lvl < n_global_levels() - 1; lvl++)
11935     if (n_active_cells(lvl) != 0)
11936       return true;
11937 
11938   return false;
11939 }
11940 
11941 
11942 template <int dim, int spacedim>
11943 unsigned int
n_lines() const11944 Triangulation<dim, spacedim>::n_lines() const
11945 {
11946   return number_cache.n_lines;
11947 }
11948 
11949 
11950 
11951 template <int dim, int spacedim>
11952 unsigned int
n_raw_lines(const unsigned int level) const11953 Triangulation<dim, spacedim>::n_raw_lines(const unsigned int level) const
11954 {
11955   if (dim == 1)
11956     {
11957       AssertIndexRange(level, n_levels());
11958       return levels[level]->cells.n_objects();
11959     }
11960 
11961   Assert(false, ExcFacesHaveNoLevel());
11962   return 0;
11963 }
11964 
11965 
11966 template <int dim, int spacedim>
11967 unsigned int
n_raw_lines() const11968 Triangulation<dim, spacedim>::n_raw_lines() const
11969 {
11970   if (dim == 1)
11971     {
11972       Assert(false, ExcNotImplemented());
11973       return 0;
11974     }
11975 
11976   return faces->lines.n_objects();
11977 }
11978 
11979 
11980 template <int dim, int spacedim>
11981 unsigned int
n_lines(const unsigned int level) const11982 Triangulation<dim, spacedim>::n_lines(const unsigned int level) const
11983 {
11984   AssertIndexRange(level, number_cache.n_lines_level.size());
11985   Assert(dim == 1, ExcFacesHaveNoLevel());
11986   return number_cache.n_lines_level[level];
11987 }
11988 
11989 
11990 template <int dim, int spacedim>
11991 unsigned int
n_active_lines() const11992 Triangulation<dim, spacedim>::n_active_lines() const
11993 {
11994   return number_cache.n_active_lines;
11995 }
11996 
11997 
11998 template <int dim, int spacedim>
11999 unsigned int
n_active_lines(const unsigned int level) const12000 Triangulation<dim, spacedim>::n_active_lines(const unsigned int level) const
12001 {
12002   AssertIndexRange(level, number_cache.n_lines_level.size());
12003   Assert(dim == 1, ExcFacesHaveNoLevel());
12004 
12005   return number_cache.n_active_lines_level[level];
12006 }
12007 
12008 
12009 template <>
12010 unsigned int
n_quads() const12011 Triangulation<1, 1>::n_quads() const
12012 {
12013   return 0;
12014 }
12015 
12016 
12017 template <>
12018 unsigned int
n_quads(const unsigned int) const12019 Triangulation<1, 1>::n_quads(const unsigned int) const
12020 {
12021   return 0;
12022 }
12023 
12024 
12025 template <>
12026 unsigned int
n_raw_quads(const unsigned int) const12027 Triangulation<1, 1>::n_raw_quads(const unsigned int) const
12028 {
12029   return 0;
12030 }
12031 
12032 
12033 template <>
12034 unsigned int
n_raw_hexs(const unsigned int) const12035 Triangulation<1, 1>::n_raw_hexs(const unsigned int) const
12036 {
12037   return 0;
12038 }
12039 
12040 
12041 template <>
12042 unsigned int
n_active_quads(const unsigned int) const12043 Triangulation<1, 1>::n_active_quads(const unsigned int) const
12044 {
12045   return 0;
12046 }
12047 
12048 
12049 template <>
12050 unsigned int
n_active_quads() const12051 Triangulation<1, 1>::n_active_quads() const
12052 {
12053   return 0;
12054 }
12055 
12056 
12057 
12058 template <>
12059 unsigned int
n_quads() const12060 Triangulation<1, 2>::n_quads() const
12061 {
12062   return 0;
12063 }
12064 
12065 
12066 template <>
12067 unsigned int
n_quads(const unsigned int) const12068 Triangulation<1, 2>::n_quads(const unsigned int) const
12069 {
12070   return 0;
12071 }
12072 
12073 
12074 template <>
12075 unsigned int
n_raw_quads(const unsigned int) const12076 Triangulation<1, 2>::n_raw_quads(const unsigned int) const
12077 {
12078   return 0;
12079 }
12080 
12081 
12082 template <>
12083 unsigned int
n_raw_hexs(const unsigned int) const12084 Triangulation<1, 2>::n_raw_hexs(const unsigned int) const
12085 {
12086   return 0;
12087 }
12088 
12089 
12090 template <>
12091 unsigned int
n_active_quads(const unsigned int) const12092 Triangulation<1, 2>::n_active_quads(const unsigned int) const
12093 {
12094   return 0;
12095 }
12096 
12097 
12098 template <>
12099 unsigned int
n_active_quads() const12100 Triangulation<1, 2>::n_active_quads() const
12101 {
12102   return 0;
12103 }
12104 
12105 
12106 template <>
12107 unsigned int
n_quads() const12108 Triangulation<1, 3>::n_quads() const
12109 {
12110   return 0;
12111 }
12112 
12113 
12114 template <>
12115 unsigned int
n_quads(const unsigned int) const12116 Triangulation<1, 3>::n_quads(const unsigned int) const
12117 {
12118   return 0;
12119 }
12120 
12121 
12122 template <>
12123 unsigned int
n_raw_quads(const unsigned int) const12124 Triangulation<1, 3>::n_raw_quads(const unsigned int) const
12125 {
12126   return 0;
12127 }
12128 
12129 
12130 template <>
12131 unsigned int
n_raw_hexs(const unsigned int) const12132 Triangulation<1, 3>::n_raw_hexs(const unsigned int) const
12133 {
12134   return 0;
12135 }
12136 
12137 
12138 template <>
12139 unsigned int
n_active_quads(const unsigned int) const12140 Triangulation<1, 3>::n_active_quads(const unsigned int) const
12141 {
12142   return 0;
12143 }
12144 
12145 
12146 template <>
12147 unsigned int
n_active_quads() const12148 Triangulation<1, 3>::n_active_quads() const
12149 {
12150   return 0;
12151 }
12152 
12153 
12154 
12155 template <int dim, int spacedim>
12156 unsigned int
n_quads() const12157 Triangulation<dim, spacedim>::n_quads() const
12158 {
12159   return number_cache.n_quads;
12160 }
12161 
12162 
12163 template <int dim, int spacedim>
12164 unsigned int
n_quads(const unsigned int level) const12165 Triangulation<dim, spacedim>::n_quads(const unsigned int level) const
12166 {
12167   Assert(dim == 2, ExcFacesHaveNoLevel());
12168   AssertIndexRange(level, number_cache.n_quads_level.size());
12169   return number_cache.n_quads_level[level];
12170 }
12171 
12172 
12173 
12174 template <>
12175 unsigned int
n_raw_quads(const unsigned int level) const12176 Triangulation<2, 2>::n_raw_quads(const unsigned int level) const
12177 {
12178   AssertIndexRange(level, n_levels());
12179   return levels[level]->cells.n_objects();
12180 }
12181 
12182 
12183 
12184 template <>
12185 unsigned int
n_raw_quads(const unsigned int level) const12186 Triangulation<2, 3>::n_raw_quads(const unsigned int level) const
12187 {
12188   AssertIndexRange(level, n_levels());
12189   return levels[level]->cells.n_objects();
12190 }
12191 
12192 
12193 template <>
12194 unsigned int
n_raw_quads(const unsigned int) const12195 Triangulation<3, 3>::n_raw_quads(const unsigned int) const
12196 {
12197   Assert(false, ExcFacesHaveNoLevel());
12198   return 0;
12199 }
12200 
12201 
12202 
12203 template <int dim, int spacedim>
12204 unsigned int
n_raw_quads() const12205 Triangulation<dim, spacedim>::n_raw_quads() const
12206 {
12207   Assert(false, ExcNotImplemented());
12208   return 0;
12209 }
12210 
12211 
12212 
12213 template <>
12214 unsigned int
n_raw_quads() const12215 Triangulation<3, 3>::n_raw_quads() const
12216 {
12217   return faces->quads.n_objects();
12218 }
12219 
12220 
12221 
12222 template <int dim, int spacedim>
12223 unsigned int
n_active_quads() const12224 Triangulation<dim, spacedim>::n_active_quads() const
12225 {
12226   return number_cache.n_active_quads;
12227 }
12228 
12229 
12230 template <int dim, int spacedim>
12231 unsigned int
n_active_quads(const unsigned int level) const12232 Triangulation<dim, spacedim>::n_active_quads(const unsigned int level) const
12233 {
12234   AssertIndexRange(level, number_cache.n_quads_level.size());
12235   Assert(dim == 2, ExcFacesHaveNoLevel());
12236 
12237   return number_cache.n_active_quads_level[level];
12238 }
12239 
12240 
12241 template <int dim, int spacedim>
12242 unsigned int
n_hexs() const12243 Triangulation<dim, spacedim>::n_hexs() const
12244 {
12245   return 0;
12246 }
12247 
12248 
12249 
12250 template <int dim, int spacedim>
12251 unsigned int
n_hexs(const unsigned int) const12252 Triangulation<dim, spacedim>::n_hexs(const unsigned int) const
12253 {
12254   return 0;
12255 }
12256 
12257 
12258 
12259 template <int dim, int spacedim>
12260 unsigned int
n_raw_hexs(const unsigned int) const12261 Triangulation<dim, spacedim>::n_raw_hexs(const unsigned int) const
12262 {
12263   return 0;
12264 }
12265 
12266 
12267 template <int dim, int spacedim>
12268 unsigned int
n_active_hexs() const12269 Triangulation<dim, spacedim>::n_active_hexs() const
12270 {
12271   return 0;
12272 }
12273 
12274 
12275 
12276 template <int dim, int spacedim>
12277 unsigned int
n_active_hexs(const unsigned int) const12278 Triangulation<dim, spacedim>::n_active_hexs(const unsigned int) const
12279 {
12280   return 0;
12281 }
12282 
12283 
12284 template <>
12285 unsigned int
n_hexs() const12286 Triangulation<3, 3>::n_hexs() const
12287 {
12288   return number_cache.n_hexes;
12289 }
12290 
12291 
12292 
12293 template <>
12294 unsigned int
n_hexs(const unsigned int level) const12295 Triangulation<3, 3>::n_hexs(const unsigned int level) const
12296 {
12297   AssertIndexRange(level, number_cache.n_hexes_level.size());
12298 
12299   return number_cache.n_hexes_level[level];
12300 }
12301 
12302 
12303 
12304 template <>
12305 unsigned int
n_raw_hexs(const unsigned int level) const12306 Triangulation<3, 3>::n_raw_hexs(const unsigned int level) const
12307 {
12308   AssertIndexRange(level, n_levels());
12309   return levels[level]->cells.n_objects();
12310 }
12311 
12312 
12313 template <>
12314 unsigned int
n_active_hexs() const12315 Triangulation<3, 3>::n_active_hexs() const
12316 {
12317   return number_cache.n_active_hexes;
12318 }
12319 
12320 
12321 
12322 template <>
12323 unsigned int
n_active_hexs(const unsigned int level) const12324 Triangulation<3, 3>::n_active_hexs(const unsigned int level) const
12325 {
12326   AssertIndexRange(level, number_cache.n_hexes_level.size());
12327 
12328   return number_cache.n_active_hexes_level[level];
12329 }
12330 
12331 
12332 
12333 template <int dim, int spacedim>
12334 unsigned int
n_used_vertices() const12335 Triangulation<dim, spacedim>::n_used_vertices() const
12336 {
12337   return std::count(vertices_used.begin(), vertices_used.end(), true);
12338 }
12339 
12340 
12341 
12342 template <int dim, int spacedim>
12343 const std::vector<bool> &
get_used_vertices() const12344 Triangulation<dim, spacedim>::get_used_vertices() const
12345 {
12346   return vertices_used;
12347 }
12348 
12349 
12350 
12351 template <>
12352 unsigned int
max_adjacent_cells() const12353 Triangulation<1, 1>::max_adjacent_cells() const
12354 {
12355   return 2;
12356 }
12357 
12358 
12359 
12360 template <>
12361 unsigned int
max_adjacent_cells() const12362 Triangulation<1, 2>::max_adjacent_cells() const
12363 {
12364   return 2;
12365 }
12366 
12367 
12368 template <>
12369 unsigned int
max_adjacent_cells() const12370 Triangulation<1, 3>::max_adjacent_cells() const
12371 {
12372   return 2;
12373 }
12374 
12375 
12376 template <int dim, int spacedim>
12377 unsigned int
max_adjacent_cells() const12378 Triangulation<dim, spacedim>::max_adjacent_cells() const
12379 {
12380   cell_iterator cell = begin(0),
12381                 endc = (n_levels() > 1 ? begin(1) : cell_iterator(end()));
12382   // store the largest index of the
12383   // vertices used on level 0
12384   unsigned int max_vertex_index = 0;
12385   for (; cell != endc; ++cell)
12386     for (const unsigned int vertex : GeometryInfo<dim>::vertex_indices())
12387       if (cell->vertex_index(vertex) > max_vertex_index)
12388         max_vertex_index = cell->vertex_index(vertex);
12389 
12390   // store the number of times a cell
12391   // touches a vertex. An unsigned
12392   // int should suffice, even for
12393   // larger dimensions
12394   std::vector<unsigned short int> usage_count(max_vertex_index + 1, 0);
12395   // touch a vertex's usage count
12396   // every time we find an adjacent
12397   // element
12398   for (cell = begin(); cell != endc; ++cell)
12399     for (const unsigned int vertex : GeometryInfo<dim>::vertex_indices())
12400       ++usage_count[cell->vertex_index(vertex)];
12401 
12402   return std::max(GeometryInfo<dim>::vertices_per_cell,
12403                   static_cast<unsigned int>(
12404                     *std::max_element(usage_count.begin(), usage_count.end())));
12405 }
12406 
12407 
12408 
12409 template <int dim, int spacedim>
12410 types::subdomain_id
locally_owned_subdomain() const12411 Triangulation<dim, spacedim>::locally_owned_subdomain() const
12412 {
12413   return numbers::invalid_subdomain_id;
12414 }
12415 
12416 
12417 
12418 template <int dim, int spacedim>
12419 Triangulation<dim, spacedim> &
get_triangulation()12420 Triangulation<dim, spacedim>::get_triangulation()
12421 {
12422   return *this;
12423 }
12424 
12425 
12426 
12427 template <int dim, int spacedim>
12428 const Triangulation<dim, spacedim> &
get_triangulation() const12429 Triangulation<dim, spacedim>::get_triangulation() const
12430 {
12431   return *this;
12432 }
12433 
12434 
12435 
12436 template <int dim, int spacedim>
12437 void
add_periodicity(const std::vector<GridTools::PeriodicFacePair<cell_iterator>> & periodicity_vector)12438 Triangulation<dim, spacedim>::add_periodicity(
12439   const std::vector<GridTools::PeriodicFacePair<cell_iterator>>
12440     &periodicity_vector)
12441 {
12442   periodic_face_pairs_level_0.insert(periodic_face_pairs_level_0.end(),
12443                                      periodicity_vector.begin(),
12444                                      periodicity_vector.end());
12445 
12446   // Now initialize periodic_face_map
12447   update_periodic_face_map();
12448 }
12449 
12450 
12451 
12452 template <int dim, int spacedim>
12453 const typename std::map<
12454   std::pair<typename Triangulation<dim, spacedim>::cell_iterator, unsigned int>,
12455   std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
12456                       unsigned int>,
12457             std::bitset<3>>> &
get_periodic_face_map() const12458 Triangulation<dim, spacedim>::get_periodic_face_map() const
12459 {
12460   return periodic_face_map;
12461 }
12462 
12463 
12464 
12465 template <int dim, int spacedim>
12466 void
execute_coarsening_and_refinement()12467 Triangulation<dim, spacedim>::execute_coarsening_and_refinement()
12468 {
12469   prepare_coarsening_and_refinement();
12470 
12471   // verify a case with which we have had
12472   // some difficulty in the past (see the
12473   // deal.II/coarsening_* tests)
12474   if (smooth_grid & limit_level_difference_at_vertices)
12475     Assert(satisfies_level1_at_vertex_rule(*this) == true, ExcInternalError());
12476 
12477   // Inform all listeners about beginning of refinement.
12478   signals.pre_refinement();
12479 
12480   execute_coarsening();
12481 
12482   const DistortedCellList cells_with_distorted_children = execute_refinement();
12483 
12484   // verify a case with which we have had
12485   // some difficulty in the past (see the
12486   // deal.II/coarsening_* tests)
12487   if (smooth_grid & limit_level_difference_at_vertices)
12488     Assert(satisfies_level1_at_vertex_rule(*this) == true, ExcInternalError());
12489 
12490   // finally build up neighbor connectivity information, and set
12491   // active cell indices
12492   update_neighbors(*this);
12493   reset_active_cell_indices();
12494 
12495   // Inform all listeners about end of refinement.
12496   signals.post_refinement();
12497 
12498   AssertThrow(cells_with_distorted_children.distorted_cells.size() == 0,
12499               cells_with_distorted_children);
12500 
12501   update_periodic_face_map();
12502 }
12503 
12504 
12505 
12506 template <int dim, int spacedim>
12507 void
reset_active_cell_indices()12508 Triangulation<dim, spacedim>::reset_active_cell_indices()
12509 {
12510   unsigned int active_cell_index = 0;
12511   for (raw_cell_iterator cell = begin_raw(); cell != end(); ++cell)
12512     if ((cell->used() == false) || cell->has_children())
12513       cell->set_active_cell_index(numbers::invalid_unsigned_int);
12514     else
12515       {
12516         cell->set_active_cell_index(active_cell_index);
12517         ++active_cell_index;
12518       }
12519 
12520   Assert(active_cell_index == n_active_cells(), ExcInternalError());
12521 }
12522 
12523 
12524 template <int dim, int spacedim>
12525 void
update_periodic_face_map()12526 Triangulation<dim, spacedim>::update_periodic_face_map()
12527 {
12528   // first empty the currently stored objects
12529   periodic_face_map.clear();
12530 
12531   typename std::vector<
12532     GridTools::PeriodicFacePair<cell_iterator>>::const_iterator it;
12533   for (it = periodic_face_pairs_level_0.begin();
12534        it != periodic_face_pairs_level_0.end();
12535        ++it)
12536     {
12537       update_periodic_face_map_recursively<dim, spacedim>(it->cell[0],
12538                                                           it->cell[1],
12539                                                           it->face_idx[0],
12540                                                           it->face_idx[1],
12541                                                           it->orientation,
12542                                                           periodic_face_map);
12543 
12544       // for the other way, we need to invert the orientation
12545       std::bitset<3> inverted_orientation;
12546       {
12547         bool orientation, flip, rotation;
12548         orientation = it->orientation[0];
12549         rotation    = it->orientation[2];
12550         flip = orientation ? rotation ^ it->orientation[1] : it->orientation[1];
12551         inverted_orientation[0] = orientation;
12552         inverted_orientation[1] = flip;
12553         inverted_orientation[2] = rotation;
12554       }
12555       update_periodic_face_map_recursively<dim, spacedim>(it->cell[1],
12556                                                           it->cell[0],
12557                                                           it->face_idx[1],
12558                                                           it->face_idx[0],
12559                                                           inverted_orientation,
12560                                                           periodic_face_map);
12561     }
12562 
12563   // check consistency
12564   typename std::map<std::pair<cell_iterator, unsigned int>,
12565                     std::pair<std::pair<cell_iterator, unsigned int>,
12566                               std::bitset<3>>>::const_iterator it_test;
12567   for (it_test = periodic_face_map.begin(); it_test != periodic_face_map.end();
12568        ++it_test)
12569     {
12570       const Triangulation<dim, spacedim>::cell_iterator cell_1 =
12571         it_test->first.first;
12572       const Triangulation<dim, spacedim>::cell_iterator cell_2 =
12573         it_test->second.first.first;
12574       if (cell_1->level() == cell_2->level())
12575         {
12576           // if both cells have the same neighbor, then the same pair
12577           // order swapped has to be in the map
12578           Assert(periodic_face_map[it_test->second.first].first ==
12579                    it_test->first,
12580                  ExcInternalError());
12581         }
12582     }
12583 }
12584 
12585 
12586 
12587 template <int dim, int spacedim>
12588 void
clear_despite_subscriptions()12589 Triangulation<dim, spacedim>::clear_despite_subscriptions()
12590 {
12591   levels.clear();
12592   faces.reset();
12593 
12594   vertices.clear();
12595   vertices_used.clear();
12596 
12597   manifold.clear();
12598 
12599   number_cache = internal::TriangulationImplementation::NumberCache<dim>();
12600 }
12601 
12602 
12603 template <int dim, int spacedim>
12604 typename Triangulation<dim, spacedim>::DistortedCellList
execute_refinement()12605 Triangulation<dim, spacedim>::execute_refinement()
12606 {
12607   const DistortedCellList cells_with_distorted_children =
12608     internal::TriangulationImplementation::Implementation::execute_refinement(
12609       *this, check_for_distorted_cells);
12610 
12611 
12612 
12613   // re-compute number of lines
12614   internal::TriangulationImplementation::Implementation::compute_number_cache(
12615     *this, levels.size(), number_cache);
12616 
12617 #ifdef DEBUG
12618   for (const auto &level : levels)
12619     monitor_memory(level->cells, dim);
12620 
12621   // check whether really all refinement flags are reset (also of
12622   // previously non-active cells which we may not have touched. If the
12623   // refinement flag of a non-active cell is set, something went wrong
12624   // since the cell-accessors should have caught this)
12625   for (const auto &cell : this->cell_iterators())
12626     Assert(!cell->refine_flag_set(), ExcInternalError());
12627 #endif
12628 
12629   return cells_with_distorted_children;
12630 }
12631 
12632 
12633 
12634 template <int dim, int spacedim>
12635 void
execute_coarsening()12636 Triangulation<dim, spacedim>::execute_coarsening()
12637 {
12638   // create a vector counting for each line how many cells contain
12639   // this line. in 3D, this is used later on to decide which lines can
12640   // be deleted after coarsening a cell. in other dimensions it will
12641   // be ignored
12642   std::vector<unsigned int> line_cell_count =
12643     count_cells_bounded_by_line(*this);
12644   std::vector<unsigned int> quad_cell_count =
12645     count_cells_bounded_by_quad(*this);
12646 
12647   // loop over all cells. Flag all cells of which all children are
12648   // flagged for coarsening and delete the childrens' flags. In
12649   // effect, only those cells are flagged of which originally all
12650   // children were flagged and for which all children are on the same
12651   // refinement level. For flagging, the user flags are used, to avoid
12652   // confusion and because non-active cells can't be flagged for
12653   // coarsening. Note that because of the effects of
12654   // @p{fix_coarsen_flags}, of a cell either all or no children must
12655   // be flagged for coarsening, so it is ok to only check the first
12656   // child
12657   clear_user_flags();
12658 
12659   for (const auto &cell : this->cell_iterators())
12660     if (!cell->is_active())
12661       if (cell->child(0)->coarsen_flag_set())
12662         {
12663           cell->set_user_flag();
12664           for (unsigned int child = 0; child < cell->n_children(); ++child)
12665             {
12666               Assert(cell->child(child)->coarsen_flag_set(),
12667                      ExcInternalError());
12668               cell->child(child)->clear_coarsen_flag();
12669             }
12670         }
12671 
12672 
12673   // now do the actual coarsening step. Since the loop goes over used
12674   // cells we only need not worry about deleting some cells since the
12675   // ++operator will then just hop over them if we should hit one. Do
12676   // the loop in the reverse way since we may only delete some cells
12677   // if their neighbors have already been deleted (if the latter are
12678   // on a higher level for example)
12679   //
12680   // since we delete the *children* of cells, we can ignore cells
12681   // on the highest level, i.e., level must be less than or equal
12682   // to n_levels()-2.
12683   cell_iterator cell = begin(), endc = end();
12684   if (levels.size() >= 2)
12685     for (cell = last(); cell != endc; --cell)
12686       if (cell->level() <= static_cast<int>(levels.size() - 2) &&
12687           cell->user_flag_set())
12688         {
12689           // inform all listeners that cell coarsening is going to happen
12690           signals.pre_coarsening_on_cell(cell);
12691           // use a separate function, since this is dimension specific
12692           internal::TriangulationImplementation::Implementation::
12693             delete_children(*this, cell, line_cell_count, quad_cell_count);
12694         }
12695 
12696   // re-compute number of lines and quads
12697   internal::TriangulationImplementation::Implementation::compute_number_cache(
12698     *this, levels.size(), number_cache);
12699 
12700   // in principle no user flags should be set any more at this point
12701 #if DEBUG
12702   for (cell = begin(); cell != endc; ++cell)
12703     Assert(cell->user_flag_set() == false, ExcInternalError());
12704 #endif
12705 }
12706 
12707 
12708 
12709 template <int dim, int spacedim>
12710 void
fix_coarsen_flags()12711 Triangulation<dim, spacedim>::fix_coarsen_flags()
12712 {
12713   // copy a piece of code from prepare_coarsening_and_refinement that
12714   // ensures that the level difference at vertices is limited if so
12715   // desired. we need this code here since at least in 1d we don't
12716   // call the dimension-independent version of
12717   // prepare_coarsening_and_refinement function. in 2d and 3d, having
12718   // this hunk here makes our lives a bit easier as well as it takes
12719   // care of these cases earlier than it would otherwise happen.
12720   //
12721   // the main difference to the code in p_c_and_r is that here we
12722   // absolutely have to make sure that we get things right, i.e. that
12723   // in particular we set flags right if
12724   // limit_level_difference_at_vertices is set. to do so we iterate
12725   // until the flags don't change any more
12726   std::vector<bool> previous_coarsen_flags(n_active_cells());
12727   save_coarsen_flags(previous_coarsen_flags);
12728 
12729   std::vector<int> vertex_level(vertices.size(), 0);
12730 
12731   bool continue_iterating = true;
12732 
12733   do
12734     {
12735       if (smooth_grid & limit_level_difference_at_vertices)
12736         {
12737           Assert(!anisotropic_refinement,
12738                  ExcMessage("In case of anisotropic refinement the "
12739                             "limit_level_difference_at_vertices flag for "
12740                             "mesh smoothing must not be set!"));
12741 
12742           // store highest level one of the cells adjacent to a vertex
12743           // belongs to
12744           std::fill(vertex_level.begin(), vertex_level.end(), 0);
12745           for (const auto &cell : this->active_cell_iterators())
12746             {
12747               if (cell->refine_flag_set())
12748                 for (const unsigned int vertex :
12749                      GeometryInfo<dim>::vertex_indices())
12750                   vertex_level[cell->vertex_index(vertex)] =
12751                     std::max(vertex_level[cell->vertex_index(vertex)],
12752                              cell->level() + 1);
12753               else if (!cell->coarsen_flag_set())
12754                 for (const unsigned int vertex :
12755                      GeometryInfo<dim>::vertex_indices())
12756                   vertex_level[cell->vertex_index(vertex)] =
12757                     std::max(vertex_level[cell->vertex_index(vertex)],
12758                              cell->level());
12759               else
12760                 {
12761                   // if coarsen flag is set then tentatively assume
12762                   // that the cell will be coarsened. this isn't
12763                   // always true (the coarsen flag could be removed
12764                   // again) and so we may make an error here. we try
12765                   // to correct this by iterating over the entire
12766                   // process until we are converged
12767                   Assert(cell->coarsen_flag_set(), ExcInternalError());
12768                   for (const unsigned int vertex :
12769                        GeometryInfo<dim>::vertex_indices())
12770                     vertex_level[cell->vertex_index(vertex)] =
12771                       std::max(vertex_level[cell->vertex_index(vertex)],
12772                                cell->level() - 1);
12773                 }
12774             }
12775 
12776 
12777           // loop over all cells in reverse order. do so because we
12778           // can then update the vertex levels on the adjacent
12779           // vertices and maybe already flag additional cells in this
12780           // loop
12781           //
12782           // note that not only may we have to add additional
12783           // refinement flags, but we will also have to remove
12784           // coarsening flags on cells adjacent to vertices that will
12785           // see refinement
12786           active_cell_iterator cell = begin_active(), endc = end();
12787           for (cell = last_active(); cell != endc; --cell)
12788             if (cell->refine_flag_set() == false)
12789               {
12790                 for (const unsigned int vertex :
12791                      GeometryInfo<dim>::vertex_indices())
12792                   if (vertex_level[cell->vertex_index(vertex)] >=
12793                       cell->level() + 1)
12794                     {
12795                       // remove coarsen flag...
12796                       cell->clear_coarsen_flag();
12797 
12798                       // ...and if necessary also refine the current
12799                       // cell, at the same time updating the level
12800                       // information about vertices
12801                       if (vertex_level[cell->vertex_index(vertex)] >
12802                           cell->level() + 1)
12803                         {
12804                           cell->set_refine_flag();
12805 
12806                           for (const unsigned int v :
12807                                GeometryInfo<dim>::vertex_indices())
12808                             vertex_level[cell->vertex_index(v)] =
12809                               std::max(vertex_level[cell->vertex_index(v)],
12810                                        cell->level() + 1);
12811                         }
12812 
12813                       // continue and see whether we may, for example,
12814                       // go into the inner 'if' above based on a
12815                       // different vertex
12816                     }
12817               }
12818         }
12819 
12820       // loop over all cells. Flag all cells of which all children are
12821       // flagged for coarsening and delete the childrens' flags. Also
12822       // delete all flags of cells for which not all children of a
12823       // cell are flagged. In effect, only those cells are flagged of
12824       // which originally all children were flagged and for which all
12825       // children are on the same refinement level. For flagging, the
12826       // user flags are used, to avoid confusion and because
12827       // non-active cells can't be flagged for coarsening
12828       //
12829       // In effect, all coarsen flags are turned into user flags of
12830       // the mother cell if coarsening is possible or deleted
12831       // otherwise.
12832       clear_user_flags();
12833       // Coarsen flags of cells with no mother cell, i.e. on the
12834       // coarsest level are deleted explicitly.
12835       for (const auto &acell : this->active_cell_iterators_on_level(0))
12836         acell->clear_coarsen_flag();
12837 
12838       for (const auto &cell : this->cell_iterators())
12839         {
12840           // nothing to do if we are already on the finest level
12841           if (cell->is_active())
12842             continue;
12843 
12844           const unsigned int n_children       = cell->n_children();
12845           unsigned int       flagged_children = 0;
12846           for (unsigned int child = 0; child < n_children; ++child)
12847             if (cell->child(child)->is_active() &&
12848                 cell->child(child)->coarsen_flag_set())
12849               {
12850                 ++flagged_children;
12851                 // clear flag since we don't need it anymore
12852                 cell->child(child)->clear_coarsen_flag();
12853               }
12854 
12855           // flag this cell for coarsening if all children were
12856           // flagged
12857           if (flagged_children == n_children)
12858             cell->set_user_flag();
12859         }
12860 
12861         // in principle no coarsen flags should be set any more at this
12862         // point
12863 #if DEBUG
12864       for (auto &cell : this->cell_iterators())
12865         Assert(cell->coarsen_flag_set() == false, ExcInternalError());
12866 #endif
12867 
12868       // now loop over all cells which have the user flag set. their
12869       // children were flagged for coarsening. set the coarsen flag
12870       // again if we are sure that none of the neighbors of these
12871       // children are refined, or will be refined, since then we would
12872       // get a two-level jump in refinement. on the other hand, if one
12873       // of the children's neighbors has their user flag set, then we
12874       // know that its children will go away by coarsening, and we
12875       // will be ok.
12876       //
12877       // note on the other hand that we do allow level-2 jumps in
12878       // refinement between neighbors in 1d, so this whole procedure
12879       // is only necessary if we are not in 1d
12880       //
12881       // since we remove some coarsening/user flags in the process, we
12882       // have to work from the finest level to the coarsest one, since
12883       // we occasionally inspect user flags of cells on finer levels
12884       // and need to be sure that these flags are final
12885       cell_iterator cell = begin(), endc = end();
12886       for (cell = last(); cell != endc; --cell)
12887         if (cell->user_flag_set())
12888           // if allowed: flag the
12889           // children for coarsening
12890           if (internal::TriangulationImplementation::Implementation::
12891                 template coarsening_allowed<dim, spacedim>(cell))
12892             for (unsigned int c = 0; c < cell->n_children(); ++c)
12893               {
12894                 Assert(cell->child(c)->refine_flag_set() == false,
12895                        ExcInternalError());
12896 
12897                 cell->child(c)->set_coarsen_flag();
12898               }
12899 
12900       // clear all user flags again, now that we don't need them any
12901       // more
12902       clear_user_flags();
12903 
12904 
12905       // now see if anything has changed in the last iteration of this
12906       // function
12907       std::vector<bool> current_coarsen_flags(n_active_cells());
12908       save_coarsen_flags(current_coarsen_flags);
12909 
12910       continue_iterating = (current_coarsen_flags != previous_coarsen_flags);
12911       previous_coarsen_flags = current_coarsen_flags;
12912     }
12913   while (continue_iterating == true);
12914 }
12915 
12916 
12917 // TODO: merge the following 3 functions since they are the same
12918 template <>
12919 bool
prepare_coarsening_and_refinement()12920 Triangulation<1, 1>::prepare_coarsening_and_refinement()
12921 {
12922   // save the flags to determine whether something was changed in the
12923   // course of this function
12924   std::vector<bool> flags_before;
12925   save_coarsen_flags(flags_before);
12926 
12927   // do nothing in 1d, except setting the coarsening flags correctly
12928   fix_coarsen_flags();
12929 
12930   std::vector<bool> flags_after;
12931   save_coarsen_flags(flags_after);
12932 
12933   return (flags_before != flags_after);
12934 }
12935 
12936 
12937 template <>
12938 bool
prepare_coarsening_and_refinement()12939 Triangulation<1, 2>::prepare_coarsening_and_refinement()
12940 {
12941   // save the flags to determine whether something was changed in the
12942   // course of this function
12943   std::vector<bool> flags_before;
12944   save_coarsen_flags(flags_before);
12945 
12946   // do nothing in 1d, except setting the coarsening flags correctly
12947   fix_coarsen_flags();
12948 
12949   std::vector<bool> flags_after;
12950   save_coarsen_flags(flags_after);
12951 
12952   return (flags_before != flags_after);
12953 }
12954 
12955 
12956 template <>
12957 bool
prepare_coarsening_and_refinement()12958 Triangulation<1, 3>::prepare_coarsening_and_refinement()
12959 {
12960   // save the flags to determine whether something was changed in the
12961   // course of this function
12962   std::vector<bool> flags_before;
12963   save_coarsen_flags(flags_before);
12964 
12965   // do nothing in 1d, except setting the coarsening flags correctly
12966   fix_coarsen_flags();
12967 
12968   std::vector<bool> flags_after;
12969   save_coarsen_flags(flags_after);
12970 
12971   return (flags_before != flags_after);
12972 }
12973 
12974 
12975 
12976 namespace
12977 {
12978   // check if the given @param cell marked for coarsening would
12979   // produce an unrefined island. To break up long chains of these
12980   // cells we recursively check our neighbors in case we change this
12981   // cell. This reduces the number of outer iterations dramatically.
12982   template <int dim, int spacedim>
12983   void
possibly_do_not_produce_unrefined_islands(const typename Triangulation<dim,spacedim>::cell_iterator & cell)12984   possibly_do_not_produce_unrefined_islands(
12985     const typename Triangulation<dim, spacedim>::cell_iterator &cell)
12986   {
12987     Assert(cell->has_children(), ExcInternalError());
12988 
12989     unsigned int n_neighbors = 0;
12990     // count all neighbors that will be refined along the face of our
12991     // cell after the next step
12992     unsigned int count = 0;
12993     for (unsigned int n : GeometryInfo<dim>::face_indices())
12994       {
12995         const typename Triangulation<dim, spacedim>::cell_iterator neighbor =
12996           cell->neighbor(n);
12997         if (neighbor.state() == IteratorState::valid)
12998           {
12999             ++n_neighbors;
13000             if (face_will_be_refined_by_neighbor(cell, n))
13001               ++count;
13002           }
13003       }
13004     // clear coarsen flags if either all existing neighbors will be
13005     // refined or all but one will be and the cell is in the interior
13006     // of the domain
13007     if (count == n_neighbors ||
13008         (count >= n_neighbors - 1 &&
13009          n_neighbors == GeometryInfo<dim>::faces_per_cell))
13010       {
13011         for (unsigned int c = 0; c < cell->n_children(); ++c)
13012           cell->child(c)->clear_coarsen_flag();
13013 
13014         for (const unsigned int face : GeometryInfo<dim>::face_indices())
13015           if (!cell->at_boundary(face) &&
13016               (!cell->neighbor(face)->is_active()) &&
13017               (cell_will_be_coarsened(cell->neighbor(face))))
13018             possibly_do_not_produce_unrefined_islands<dim, spacedim>(
13019               cell->neighbor(face));
13020       }
13021   }
13022 
13023 
13024   // see if the current cell needs to be refined to avoid unrefined
13025   // islands.
13026   //
13027   // there are sometimes chains of cells that induce refinement of
13028   // each other. to avoid running the loop in
13029   // prepare_coarsening_and_refinement over and over again for each
13030   // one of them, at least for the isotropic refinement case we seek
13031   // to flag neighboring elements as well as necessary. this takes
13032   // care of (slightly pathological) cases like
13033   // deal.II/mesh_smoothing_03
13034   template <int dim, int spacedim>
13035   void
possibly_refine_unrefined_island(const typename Triangulation<dim,spacedim>::cell_iterator & cell,const bool allow_anisotropic_smoothing)13036   possibly_refine_unrefined_island(
13037     const typename Triangulation<dim, spacedim>::cell_iterator &cell,
13038     const bool allow_anisotropic_smoothing)
13039   {
13040     Assert(cell->is_active(), ExcInternalError());
13041     Assert(cell->refine_flag_set() == false, ExcInternalError());
13042 
13043 
13044     // now we provide two algorithms. the first one is the standard
13045     // one, coming from the time, where only isotropic refinement was
13046     // possible. it simply counts the neighbors that are or will be
13047     // refined and compares to the number of other ones. the second
13048     // one does this check independently for each direction: if all
13049     // neighbors in one direction (normally two, at the boundary only
13050     // one) are refined, the current cell is flagged to be refined in
13051     // an according direction.
13052 
13053     if (allow_anisotropic_smoothing == false)
13054       {
13055         // use first algorithm
13056         unsigned int refined_neighbors = 0, unrefined_neighbors = 0;
13057         for (const unsigned int face : GeometryInfo<dim>::face_indices())
13058           if (!cell->at_boundary(face))
13059             {
13060               if (face_will_be_refined_by_neighbor(cell, face))
13061                 ++refined_neighbors;
13062               else
13063                 ++unrefined_neighbors;
13064             }
13065 
13066         if (unrefined_neighbors < refined_neighbors)
13067           {
13068             cell->clear_coarsen_flag();
13069             cell->set_refine_flag();
13070 
13071             // ok, so now we have flagged this cell. if we know that
13072             // there were any unrefined neighbors at all, see if any
13073             // of those will have to be refined as well
13074             if (unrefined_neighbors > 0)
13075               for (const unsigned int face : GeometryInfo<dim>::face_indices())
13076                 if (!cell->at_boundary(face) &&
13077                     (face_will_be_refined_by_neighbor(cell, face) == false) &&
13078                     (cell->neighbor(face)->has_children() == false) &&
13079                     (cell->neighbor(face)->refine_flag_set() == false))
13080                   possibly_refine_unrefined_island<dim, spacedim>(
13081                     cell->neighbor(face), allow_anisotropic_smoothing);
13082           }
13083       }
13084     else
13085       {
13086         // variable to store the cell refine case needed to fulfill
13087         // all smoothing requirements
13088         RefinementCase<dim> smoothing_cell_refinement_case =
13089           RefinementCase<dim>::no_refinement;
13090 
13091         // use second algorithm, do the check individually for each
13092         // direction
13093         for (unsigned int face_pair = 0;
13094              face_pair < GeometryInfo<dim>::faces_per_cell / 2;
13095              ++face_pair)
13096           {
13097             // variable to store the cell refine case needed to refine
13098             // at the current face pair in the same way as the
13099             // neighbors do...
13100             RefinementCase<dim> directional_cell_refinement_case =
13101               RefinementCase<dim>::isotropic_refinement;
13102 
13103             for (unsigned int face_index = 0; face_index < 2; ++face_index)
13104               {
13105                 unsigned int face = 2 * face_pair + face_index;
13106                 // variable to store the refine case (to come) of the
13107                 // face under consideration
13108                 RefinementCase<dim - 1> expected_face_ref_case =
13109                   RefinementCase<dim - 1>::no_refinement;
13110 
13111                 if (cell->neighbor(face).state() == IteratorState::valid)
13112                   face_will_be_refined_by_neighbor<dim, spacedim>(
13113                     cell, face, expected_face_ref_case);
13114                 // now extract which refine case would be necessary to
13115                 // achieve the same face refinement. set the
13116                 // intersection with other requirements for the same
13117                 // direction.
13118 
13119                 // note: using the intersection is not an obvious
13120                 // decision, we could also argue that it is more
13121                 // natural to use the union. however, intersection is
13122                 // the less aggressive tactic and favours a smaller
13123                 // number of refined cells over an intensive
13124                 // smoothing. this way we try not to lose too much of
13125                 // the effort we put in anisotropic refinement
13126                 // indicators due to overly aggressive smoothing...
13127                 directional_cell_refinement_case =
13128                   (directional_cell_refinement_case &
13129                    GeometryInfo<dim>::
13130                      min_cell_refinement_case_for_face_refinement(
13131                        expected_face_ref_case,
13132                        face,
13133                        cell->face_orientation(face),
13134                        cell->face_flip(face),
13135                        cell->face_rotation(face)));
13136               } // for both face indices
13137             // if both requirements sum up to something useful, add
13138             // this to the refine case for smoothing. note: if
13139             // directional_cell_refinement_case is isotropic still,
13140             // then something went wrong...
13141             Assert(directional_cell_refinement_case <
13142                      RefinementCase<dim>::isotropic_refinement,
13143                    ExcInternalError());
13144             smoothing_cell_refinement_case =
13145               smoothing_cell_refinement_case | directional_cell_refinement_case;
13146           } // for all face_pairs
13147         // no we collected contributions from all directions. combine
13148         // the new flags with the existing refine case, but only if
13149         // smoothing is required
13150         if (smoothing_cell_refinement_case)
13151           {
13152             cell->clear_coarsen_flag();
13153             cell->set_refine_flag(cell->refine_flag_set() |
13154                                   smoothing_cell_refinement_case);
13155           }
13156       }
13157   }
13158 } // namespace
13159 
13160 
13161 template <int dim, int spacedim>
13162 bool
prepare_coarsening_and_refinement()13163 Triangulation<dim, spacedim>::prepare_coarsening_and_refinement()
13164 {
13165   // save the flags to determine whether something was changed in the
13166   // course of this function
13167   std::vector<bool> flags_before[2];
13168   save_coarsen_flags(flags_before[0]);
13169   save_refine_flags(flags_before[1]);
13170 
13171   // save the flags at the outset of each loop. we do so in order to
13172   // find out whether something was changed in the present loop, in
13173   // which case we would have to re-run the loop. the other
13174   // possibility to find this out would be to set a flag
13175   // @p{something_changed} to true each time we change something.
13176   // however, sometimes one change in one of the parts of the loop is
13177   // undone by another one, so we might end up in an endless loop. we
13178   // could be tempted to break this loop at an arbitrary number of
13179   // runs, but that would not be a clean solution, since we would
13180   // either have to 1/ break the loop too early, in which case the
13181   // promise that a second call to this function immediately after the
13182   // first one does not change anything, would be broken, or 2/ we do
13183   // as many loops as there are levels. we know that information is
13184   // transported over one level in each run of the loop, so this is
13185   // enough. Unfortunately, each loop is rather expensive, so we chose
13186   // the way presented here
13187   std::vector<bool> flags_before_loop[2] = {flags_before[0], flags_before[1]};
13188 
13189   // now for what is done in each loop: we have to fulfill several
13190   // tasks at the same time, namely several mesh smoothing algorithms
13191   // and mesh regularization, by which we mean that the next mesh
13192   // fulfills several requirements such as no double refinement at
13193   // each face or line, etc.
13194   //
13195   // since doing these things at once seems almost impossible (in the
13196   // first year of this library, they were done in two functions, one
13197   // for refinement and one for coarsening, and most things within
13198   // these were done at once, so the code was rather impossible to
13199   // join into this, only, function), we do them one after each
13200   // other. the order in which we do them is such that the important
13201   // tasks, namely regularization, are done last and the least
13202   // important things are done the first. the following order is
13203   // chosen:
13204   //
13205   // 0/ Only if coarsest_level_1 or patch_level_1 is set: clear all
13206   //    coarsen flags on level 1 to avoid level 0 cells being created
13207   //    by coarsening.  As coarsen flags will never be added, this can
13208   //    be done once and for all before the actual loop starts.
13209   //
13210   // 1/ do not coarsen a cell if 'most of the neighbors' will be
13211   //    refined after the step. This is to prevent occurrence of
13212   //    unrefined islands.
13213   //
13214   // 2/ eliminate refined islands in the interior and at the
13215   //    boundary. since they don't do much harm besides increasing the
13216   //    number of degrees of freedom, doing this has a rather low
13217   //    priority.
13218   //
13219   // 3/ limit the level difference of neighboring cells at each
13220   //    vertex.
13221   //
13222   // 4/ eliminate unrefined islands. this has higher priority since
13223   //    this diminishes the approximation properties not only of the
13224   //    unrefined island, but also of the surrounding patch.
13225   //
13226   // 5/ ensure patch level 1. Then the triangulation consists of
13227   //    patches, i.e. of cells that are refined once. It follows that
13228   //    if at least one of the children of a cell is or will be
13229   //    refined than all children need to be refined. This step only
13230   //    sets refinement flags and does not set coarsening flags.  If
13231   //    the patch_level_1 flag is set, then
13232   //    eliminate_unrefined_islands, eliminate_refined_inner_islands
13233   //    and eliminate_refined_boundary_islands will be fulfilled
13234   //    automatically and do not need to be enforced separately.
13235   //
13236   // 6/ take care of the requirement that no double refinement is done
13237   //    at each face
13238   //
13239   // 7/ take care that no double refinement is done at each line in 3d
13240   //    or higher dimensions.
13241   //
13242   // 8/ make sure that all children of each cell are either flagged
13243   //    for coarsening or none of the children is
13244   //
13245   // For some of these steps, it is known that they interact. Namely,
13246   // it is not possible to guarantee that after step 6 another step 5
13247   // would have no effect; the same holds for the opposite order and
13248   // also when taking into account step 7. however, it is important to
13249   // guarantee that step five or six do not undo something that step 5
13250   // did, and step 7 not something of step 6, otherwise the
13251   // requirements will not be satisfied even if the loop
13252   // terminates. this is accomplished by the fact that steps 5 and 6
13253   // only *add* refinement flags and delete coarsening flags
13254   // (therefore, step 6 can't undo something that step 4 already did),
13255   // and step 7 only deletes coarsening flags, never adds some. step 7
13256   // needs also take care that it won't tag cells for refinement for
13257   // which some neighbors are more refined or will be refined.
13258 
13259   //////////////////////////////////////
13260   // STEP 0:
13261   //    Only if coarsest_level_1 or patch_level_1 is set: clear all
13262   //    coarsen flags on level 1 to avoid level 0 cells being created
13263   //    by coarsening.
13264   if (((smooth_grid & coarsest_level_1) || (smooth_grid & patch_level_1)) &&
13265       n_levels() >= 2)
13266     {
13267       for (const auto &cell : active_cell_iterators_on_level(1))
13268         cell->clear_coarsen_flag();
13269     }
13270 
13271   bool mesh_changed_in_this_loop = false;
13272   do
13273     {
13274       //////////////////////////////////////
13275       // STEP 1:
13276       //    do not coarsen a cell if 'most of the neighbors' will be
13277       //    refined after the step. This is to prevent the occurrence
13278       //    of unrefined islands.  If patch_level_1 is set, this will
13279       //    be automatically fulfilled.
13280       if (smooth_grid & do_not_produce_unrefined_islands &&
13281           !(smooth_grid & patch_level_1))
13282         {
13283           for (const auto &cell : cell_iterators())
13284             {
13285               // only do something if this
13286               // cell will be coarsened
13287               if (!cell->is_active() && cell_will_be_coarsened(cell))
13288                 possibly_do_not_produce_unrefined_islands<dim, spacedim>(cell);
13289             }
13290         }
13291 
13292 
13293       //////////////////////////////////////
13294       // STEP 2:
13295       //    eliminate refined islands in the interior and at the
13296       //    boundary. since they don't do much harm besides increasing
13297       //    the number of degrees of freedom, doing this has a rather
13298       //    low priority.  If patch_level_1 is set, this will be
13299       //    automatically fulfilled.
13300       //
13301       //    there is one corner case to consider: if this is a
13302       //    distributed triangulation, there may be refined islands on
13303       //    the boundary of which we own only part (e.g. a single cell
13304       //    in the corner of a domain). the rest of the island is
13305       //    ghost cells and it *looks* like the area around it
13306       //    (artificial cells) are coarser but this is only because
13307       //    they may actually be equally fine on other
13308       //    processors. it's hard to detect this case but we can do
13309       //    the following: only set coarsen flags to remove this
13310       //    refined island if all cells we want to set flags on are
13311       //    locally owned
13312       if (smooth_grid & (eliminate_refined_inner_islands |
13313                          eliminate_refined_boundary_islands) &&
13314           !(smooth_grid & patch_level_1))
13315         {
13316           for (const auto &cell : cell_iterators())
13317             if (!cell->is_active() ||
13318                 (cell->is_active() && cell->refine_flag_set() &&
13319                  cell->is_locally_owned()))
13320               {
13321                 // check whether all children are active, i.e. not
13322                 // refined themselves. This is a precondition that the
13323                 // children may be coarsened away. If the cell is only
13324                 // flagged for refinement, then all future children
13325                 // will be active
13326                 bool all_children_active = true;
13327                 if (!cell->is_active())
13328                   for (unsigned int c = 0; c < cell->n_children(); ++c)
13329                     if (!cell->child(c)->is_active() ||
13330                         cell->child(c)->is_ghost() ||
13331                         cell->child(c)->is_artificial())
13332                       {
13333                         all_children_active = false;
13334                         break;
13335                       }
13336 
13337                 if (all_children_active)
13338                   {
13339                     // count number of refined and unrefined neighbors
13340                     // of cell.  neighbors on lower levels are counted
13341                     // as unrefined since they can only get to the
13342                     // same level as this cell by the next refinement
13343                     // cycle
13344                     unsigned int unrefined_neighbors = 0, total_neighbors = 0;
13345 
13346                     // Keep track if this cell is at a periodic
13347                     // boundary or not.  TODO: We do not currently run
13348                     // the algorithm for inner islands at a periodic
13349                     // boundary (remains to be implemented), but we
13350                     // also don't want to consider them
13351                     // boundary_island cells as this can interfere
13352                     // with 2:1 refinement across periodic faces.
13353                     // Instead: just ignore those cells for this
13354                     // smoothing operation below.
13355                     bool at_periodic_boundary = false;
13356 
13357                     for (const unsigned int n :
13358                          GeometryInfo<dim>::face_indices())
13359                       {
13360                         const cell_iterator neighbor = cell->neighbor(n);
13361                         if (neighbor.state() == IteratorState::valid)
13362                           {
13363                             ++total_neighbors;
13364 
13365                             if (!face_will_be_refined_by_neighbor(cell, n))
13366                               ++unrefined_neighbors;
13367                           }
13368                         else if (cell->has_periodic_neighbor(n))
13369                           {
13370                             ++total_neighbors;
13371                             at_periodic_boundary = true;
13372                           }
13373                       }
13374 
13375                     // if all neighbors unrefined: mark this cell for
13376                     // coarsening or don't refine if marked for that
13377                     //
13378                     // also do the distinction between the two
13379                     // versions of the eliminate_refined_*_islands
13380                     // flag
13381                     //
13382                     // the last check is whether there are any
13383                     // neighbors at all. if not so, then we are (e.g.)
13384                     // on the coarsest grid with one cell, for which,
13385                     // of course, we do not remove the refine flag.
13386                     if ((unrefined_neighbors == total_neighbors) &&
13387                         ((!cell->at_boundary() &&
13388                           (smooth_grid & eliminate_refined_inner_islands)) ||
13389                          (cell->at_boundary() && !at_periodic_boundary &&
13390                           (smooth_grid &
13391                            eliminate_refined_boundary_islands))) &&
13392                         (total_neighbors != 0))
13393                       {
13394                         if (!cell->is_active())
13395                           for (unsigned int c = 0; c < cell->n_children(); ++c)
13396                             {
13397                               cell->child(c)->clear_refine_flag();
13398                               cell->child(c)->set_coarsen_flag();
13399                             }
13400                         else
13401                           cell->clear_refine_flag();
13402                       }
13403                   }
13404               }
13405         }
13406 
13407       //////////////////////////////////////
13408       // STEP 3:
13409       //    limit the level difference of neighboring cells at each
13410       //    vertex.
13411       //
13412       //    in case of anisotropic refinement this does not make
13413       //    sense. as soon as one cell is anisotropically refined, an
13414       //    Assertion is thrown. therefore we can ignore this problem
13415       //    later on
13416       if (smooth_grid & limit_level_difference_at_vertices)
13417         {
13418           Assert(!anisotropic_refinement,
13419                  ExcMessage("In case of anisotropic refinement the "
13420                             "limit_level_difference_at_vertices flag for "
13421                             "mesh smoothing must not be set!"));
13422 
13423           // store highest level one of the cells adjacent to a vertex
13424           // belongs to
13425           std::vector<int> vertex_level(vertices.size(), 0);
13426           for (const auto &cell : active_cell_iterators())
13427             {
13428               if (cell->refine_flag_set())
13429                 for (const unsigned int vertex :
13430                      GeometryInfo<dim>::vertex_indices())
13431                   vertex_level[cell->vertex_index(vertex)] =
13432                     std::max(vertex_level[cell->vertex_index(vertex)],
13433                              cell->level() + 1);
13434               else if (!cell->coarsen_flag_set())
13435                 for (const unsigned int vertex :
13436                      GeometryInfo<dim>::vertex_indices())
13437                   vertex_level[cell->vertex_index(vertex)] =
13438                     std::max(vertex_level[cell->vertex_index(vertex)],
13439                              cell->level());
13440               else
13441                 {
13442                   // if coarsen flag is set then tentatively assume
13443                   // that the cell will be coarsened. this isn't
13444                   // always true (the coarsen flag could be removed
13445                   // again) and so we may make an error here
13446                   Assert(cell->coarsen_flag_set(), ExcInternalError());
13447                   for (const unsigned int vertex :
13448                        GeometryInfo<dim>::vertex_indices())
13449                     vertex_level[cell->vertex_index(vertex)] =
13450                       std::max(vertex_level[cell->vertex_index(vertex)],
13451                                cell->level() - 1);
13452                 }
13453             }
13454 
13455 
13456           // loop over all cells in reverse order. do so because we
13457           // can then update the vertex levels on the adjacent
13458           // vertices and maybe already flag additional cells in this
13459           // loop
13460           //
13461           // note that not only may we have to add additional
13462           // refinement flags, but we will also have to remove
13463           // coarsening flags on cells adjacent to vertices that will
13464           // see refinement
13465           for (active_cell_iterator cell = last_active(); cell != end(); --cell)
13466             if (cell->refine_flag_set() == false)
13467               {
13468                 for (const unsigned int vertex :
13469                      GeometryInfo<dim>::vertex_indices())
13470                   if (vertex_level[cell->vertex_index(vertex)] >=
13471                       cell->level() + 1)
13472                     {
13473                       // remove coarsen flag...
13474                       cell->clear_coarsen_flag();
13475 
13476                       // ...and if necessary also refine the current
13477                       // cell, at the same time updating the level
13478                       // information about vertices
13479                       if (vertex_level[cell->vertex_index(vertex)] >
13480                           cell->level() + 1)
13481                         {
13482                           cell->set_refine_flag();
13483 
13484                           for (const unsigned int v :
13485                                GeometryInfo<dim>::vertex_indices())
13486                             vertex_level[cell->vertex_index(v)] =
13487                               std::max(vertex_level[cell->vertex_index(v)],
13488                                        cell->level() + 1);
13489                         }
13490 
13491                       // continue and see whether we may, for example,
13492                       // go into the inner'if'
13493                       // above based on a
13494                       // different vertex
13495                     }
13496               }
13497         }
13498 
13499       /////////////////////////////////////
13500       // STEP 4:
13501       //    eliminate unrefined islands. this has higher priority
13502       //    since this diminishes the approximation properties not
13503       //    only of the unrefined island, but also of the surrounding
13504       //    patch.
13505       //
13506       //    do the loop from finest to coarsest cells since we may
13507       //    trigger a cascade by marking cells for refinement which
13508       //    may trigger more cells further down below
13509       if (smooth_grid & eliminate_unrefined_islands)
13510         {
13511           for (active_cell_iterator cell = last_active(); cell != end(); --cell)
13512             // only do something if cell is not already flagged for
13513             // (isotropic) refinement
13514             if (cell->refine_flag_set() !=
13515                 RefinementCase<dim>::isotropic_refinement)
13516               possibly_refine_unrefined_island<dim, spacedim>(
13517                 cell, (smooth_grid & allow_anisotropic_smoothing) != 0);
13518         }
13519 
13520       /////////////////////////////////
13521       // STEP 5:
13522       //    ensure patch level 1.
13523       //
13524       //    Introduce some terminology:
13525       //    - a cell that is refined
13526       //      once is a patch of
13527       //      level 1 simply called patch.
13528       //    - a cell that is globally
13529       //      refined twice is called
13530       //      a patch of level 2.
13531       //    - patch level n says that
13532       //      the triangulation consists
13533       //      of patches of level n.
13534       //      This makes sense only
13535       //      if the grid is already at
13536       //      least n times globally
13537       //      refined.
13538       //
13539       //    E.g. from patch level 1 follows: if at least one of the
13540       //    children of a cell is or will be refined than enforce all
13541       //    children to be refined.
13542 
13543       //    This step 4 only sets refinement flags and does not set
13544       //    coarsening flags.
13545       if (smooth_grid & patch_level_1)
13546         {
13547           // An important assumption (A) is that before calling this
13548           // function the grid was already of patch level 1.
13549 
13550           // loop over all cells whose children are all active.  (By
13551           // assumption (A) either all or none of the children are
13552           // active).  If the refine flag of at least one of the
13553           // children is set then set_refine_flag and
13554           // clear_coarsen_flag of all children.
13555           for (const auto &cell : cell_iterators())
13556             if (!cell->is_active())
13557               {
13558                 // ensure the invariant. we can then check whether all
13559                 // of its children are further refined or not by
13560                 // simply looking at the first child
13561                 Assert(cell_is_patch_level_1(cell), ExcInternalError());
13562                 if (cell->child(0)->has_children() == true)
13563                   continue;
13564 
13565                 // cell is found to be a patch.  combine the refine
13566                 // cases of all children
13567                 RefinementCase<dim> combined_ref_case =
13568                   RefinementCase<dim>::no_refinement;
13569                 for (unsigned int i = 0; i < cell->n_children(); ++i)
13570                   combined_ref_case =
13571                     combined_ref_case | cell->child(i)->refine_flag_set();
13572                 if (combined_ref_case != RefinementCase<dim>::no_refinement)
13573                   for (unsigned int i = 0; i < cell->n_children(); ++i)
13574                     {
13575                       cell_iterator child = cell->child(i);
13576 
13577                       child->clear_coarsen_flag();
13578                       child->set_refine_flag(combined_ref_case);
13579                     }
13580               }
13581 
13582           // The code above dealt with the case where we may get a
13583           // non-patch_level_1 mesh from refinement. Now also deal
13584           // with the case where we could get such a mesh by
13585           // coarsening.  Coarsen the children (and remove the
13586           // grandchildren) only if all cell->grandchild(i)
13587           // ->coarsen_flag_set() are set.
13588           //
13589           // for a case where this is a bit tricky, take a look at the
13590           // mesh_smoothing_0[12] testcases
13591           for (const auto &cell : cell_iterators())
13592             {
13593               // check if this cell has active grandchildren. note
13594               // that we know that it is patch_level_1, i.e. if one of
13595               // its children is active then so are all, and it isn't
13596               // going to have any grandchildren at all:
13597               if (cell->is_active() || cell->child(0)->is_active())
13598                 continue;
13599 
13600               // cell is not active, and so are none of its
13601               // children. check the grandchildren. note that the
13602               // children are also patch_level_1, and so we only ever
13603               // need to check their first child
13604               const unsigned int n_children               = cell->n_children();
13605               bool               has_active_grandchildren = false;
13606 
13607               for (unsigned int i = 0; i < n_children; ++i)
13608                 if (cell->child(i)->child(0)->is_active())
13609                   {
13610                     has_active_grandchildren = true;
13611                     break;
13612                   }
13613 
13614               if (has_active_grandchildren == false)
13615                 continue;
13616 
13617 
13618               // ok, there are active grandchildren. see if either all
13619               // or none of them are flagged for coarsening
13620               unsigned int n_grandchildren = 0;
13621 
13622               // count all coarsen flags of the grandchildren.
13623               unsigned int n_coarsen_flags = 0;
13624 
13625               // cell is not a patch (of level 1) as it has a
13626               // grandchild.  Is cell a patch of level 2??  Therefore:
13627               // find out whether all cell->child(i) are patches
13628               for (unsigned int c = 0; c < n_children; ++c)
13629                 {
13630                   // get at the child. by assumption (A), and the
13631                   // check by which we got here, the child is not
13632                   // active
13633                   cell_iterator child = cell->child(c);
13634 
13635                   const unsigned int nn_children = child->n_children();
13636                   n_grandchildren += nn_children;
13637 
13638                   // if child is found to be a patch of active cells
13639                   // itself, then add up how many of its children are
13640                   // supposed to be coarsened
13641                   if (child->child(0)->is_active())
13642                     for (unsigned int cc = 0; cc < nn_children; ++cc)
13643                       if (child->child(cc)->coarsen_flag_set())
13644                         ++n_coarsen_flags;
13645                 }
13646 
13647               // if not all grandchildren are supposed to be coarsened
13648               // (e.g. because some simply don't have the flag set, or
13649               // because they are not active and therefore cannot
13650               // carry the flag), then remove the coarsen flag from
13651               // all of the active grandchildren. note that there may
13652               // be coarsen flags on the grandgrandchildren -- we
13653               // don't clear them here, but we'll get to them in later
13654               // iterations if necessary
13655               //
13656               // there is nothing we have to do if no coarsen flags
13657               // have been set at all
13658               if ((n_coarsen_flags != n_grandchildren) && (n_coarsen_flags > 0))
13659                 for (unsigned int c = 0; c < n_children; ++c)
13660                   {
13661                     const cell_iterator child = cell->child(c);
13662                     if (child->child(0)->is_active())
13663                       for (unsigned int cc = 0; cc < child->n_children(); ++cc)
13664                         child->child(cc)->clear_coarsen_flag();
13665                   }
13666             }
13667         }
13668 
13669       //////////////////////////////////
13670       //
13671       //  at the boundary we could end up with cells with negative
13672       //  volume or at least with a part, that is negative, if the
13673       //  cell is refined anisotropically. we have to check, whether
13674       //  that can happen
13675       internal::TriangulationImplementation::Implementation::
13676         prevent_distorted_boundary_cells(*this);
13677 
13678       /////////////////////////////////
13679       // STEP 6:
13680       //    take care of the requirement that no
13681       //    double refinement is done at each face
13682       //
13683       //    in case of anisotropic refinement it is only likely, but
13684       //    not sure, that the cells, which are more refined along a
13685       //    certain face common to two cells are on a higher
13686       //    level. therefore we cannot be sure, that the requirement
13687       //    of no double refinement is fulfilled after a single pass
13688       //    of the following actions. We could just wait for the next
13689       //    global loop. when this function terminates, the
13690       //    requirement will be fulfilled. However, it might be faster
13691       //    to insert an inner loop here.
13692       bool changed = true;
13693       while (changed)
13694         {
13695           changed                   = false;
13696           active_cell_iterator cell = last_active(), endc = end();
13697 
13698           for (; cell != endc; --cell)
13699             if (cell->refine_flag_set())
13700               {
13701                 // loop over neighbors of cell
13702                 for (const unsigned int i : GeometryInfo<dim>::face_indices())
13703                   {
13704                     // only do something if the face is not at the
13705                     // boundary and if the face will be refined with
13706                     // the RefineCase currently flagged for
13707                     const bool has_periodic_neighbor =
13708                       cell->has_periodic_neighbor(i);
13709                     const bool has_neighbor_or_periodic_neighbor =
13710                       !cell->at_boundary(i) || has_periodic_neighbor;
13711                     if (has_neighbor_or_periodic_neighbor &&
13712                         GeometryInfo<dim>::face_refinement_case(
13713                           cell->refine_flag_set(), i) !=
13714                           RefinementCase<dim - 1>::no_refinement)
13715                       {
13716                         // 1) if the neighbor has children: nothing to
13717                         // worry about.  2) if the neighbor is active
13718                         // and a coarser one, ensure, that its
13719                         // refine_flag is set 3) if the neighbor is
13720                         // active and as refined along the face as our
13721                         // current cell, make sure, that no
13722                         // coarsen_flag is set. if we remove the
13723                         // coarsen flag of our neighbor,
13724                         // fix_coarsen_flags() makes sure, that the
13725                         // mother cell will not be coarsened
13726                         if (cell->neighbor_or_periodic_neighbor(i)->is_active())
13727                           {
13728                             if ((!has_periodic_neighbor &&
13729                                  cell->neighbor_is_coarser(i)) ||
13730                                 (has_periodic_neighbor &&
13731                                  cell->periodic_neighbor_is_coarser(i)))
13732                               {
13733                                 if (cell->neighbor_or_periodic_neighbor(i)
13734                                       ->coarsen_flag_set())
13735                                   cell->neighbor_or_periodic_neighbor(i)
13736                                     ->clear_coarsen_flag();
13737                                 // we'll set the refine flag for this
13738                                 // neighbor below. we note, that we
13739                                 // have changed something by setting
13740                                 // the changed flag to true. We do not
13741                                 // need to do so, if we just removed
13742                                 // the coarsen flag, as the changed
13743                                 // flag only indicates the need to
13744                                 // re-run the inner loop. however, we
13745                                 // only loop over cells flagged for
13746                                 // refinement here, so nothing to
13747                                 // worry about if we remove coarsen
13748                                 // flags
13749 
13750                                 if (dim == 2)
13751                                   {
13752                                     if (smooth_grid &
13753                                         allow_anisotropic_smoothing)
13754                                       changed =
13755                                         has_periodic_neighbor ?
13756                                           cell->periodic_neighbor(i)
13757                                             ->flag_for_face_refinement(
13758                                               cell
13759                                                 ->periodic_neighbor_of_coarser_periodic_neighbor(
13760                                                   i)
13761                                                 .first,
13762                                               RefinementCase<dim - 1>::cut_x) :
13763                                           cell->neighbor(i)
13764                                             ->flag_for_face_refinement(
13765                                               cell
13766                                                 ->neighbor_of_coarser_neighbor(
13767                                                   i)
13768                                                 .first,
13769                                               RefinementCase<dim - 1>::cut_x);
13770                                     else
13771                                       {
13772                                         if (!cell
13773                                                ->neighbor_or_periodic_neighbor(
13774                                                  i)
13775                                                ->refine_flag_set())
13776                                           changed = true;
13777                                         cell->neighbor_or_periodic_neighbor(i)
13778                                           ->set_refine_flag();
13779                                       }
13780                                   }
13781                                 else // i.e. if (dim==3)
13782                                   {
13783                                     // ugly situations might arise here,
13784                                     // consider the following situation, which
13785                                     // shows neighboring cells at the common
13786                                     // face, where the upper right element is
13787                                     // coarser at the given face. Now the upper
13788                                     // child element of the lower left wants to
13789                                     // refine according to cut_z, such that
13790                                     // there is a 'horizontal' refinement of the
13791                                     // face marked with #####
13792                                     //
13793                                     //                            / /
13794                                     //                           / /
13795                                     //                          *---------------*
13796                                     //                          |               |
13797                                     //                          |               |
13798                                     //                          |               |
13799                                     //                          |               |
13800                                     //                          |               |
13801                                     //                          |               | /
13802                                     //                          |               |/
13803                                     //                          *---------------*
13804                                     //
13805                                     //
13806                                     //     *---------------*
13807                                     //    /|              /|
13808                                     //   / |     #####   / |
13809                                     //     |               |
13810                                     //     *---------------*
13811                                     //    /|              /|
13812                                     //   / |             / |
13813                                     //     |               |
13814                                     //     *---------------*
13815                                     //    /               /
13816                                     //   /               /
13817                                     //
13818                                     // this introduces too many hanging nodes
13819                                     // and the neighboring (coarser) cell (upper
13820                                     // right) has to be refined. If it is only
13821                                     // refined according to cut_z, then
13822                                     // everything is ok:
13823                                     //
13824                                     //                            / /
13825                                     //                           / /
13826                                     //                          *---------------*
13827                                     //                          |               |
13828                                     //                          |               | /
13829                                     //                          |               |/
13830                                     //                          *---------------*
13831                                     //                          |               |
13832                                     //                          |               | /
13833                                     //                          |               |/
13834                                     //                          *---------------*
13835                                     //
13836                                     //
13837                                     //     *---------------*
13838                                     //    /|              /|
13839                                     //   / *---------------*
13840                                     //    /|              /|
13841                                     //     *---------------*
13842                                     //    /|              /|
13843                                     //   / |             / |
13844                                     //     |               |
13845                                     //     *---------------*
13846                                     //    /               /
13847                                     //   /               /
13848                                     //
13849                                     // if however the cell wants to refine
13850                                     // itself in an other way, or if we disallow
13851                                     // anisotropic smoothing, then simply
13852                                     // refining the neighbor isotropically is
13853                                     // not going to work, since this introduces
13854                                     // a refinement of face ##### with both
13855                                     // cut_x and cut_y, which is not possible:
13856                                     //
13857                                     //                            /       / /
13858                                     //                           /       / /
13859                                     //                          *-------*-------*
13860                                     //                          |       |       |
13861                                     //                          |       |       | /
13862                                     //                          |       |       |/
13863                                     //                          *-------*-------*
13864                                     //                          |       |       |
13865                                     //                          |       |       | /
13866                                     //                          |       |       |/
13867                                     //                          *-------*-------*
13868                                     //
13869                                     //
13870                                     //     *---------------*
13871                                     //    /|              /|
13872                                     //   / *---------------*
13873                                     //    /|              /|
13874                                     //     *---------------*
13875                                     //    /|              /|
13876                                     //   / |             / |
13877                                     //     |               |
13878                                     //     *---------------*
13879                                     //    /               /
13880                                     //   /               /
13881                                     //
13882                                     // thus, in this case we also need to refine
13883                                     // our current cell in the new direction:
13884                                     //
13885                                     //                            /       / /
13886                                     //                           /       / /
13887                                     //                          *-------*-------*
13888                                     //                          |       |       |
13889                                     //                          |       |       | /
13890                                     //                          |       |       |/
13891                                     //                          *-------*-------*
13892                                     //                          |       |       |
13893                                     //                          |       |       | /
13894                                     //                          |       |       |/
13895                                     //                          *-------*-------*
13896                                     //
13897                                     //
13898                                     //     *-------*-------*
13899                                     //    /|      /|      /|
13900                                     //   / *-------*-------*
13901                                     //    /|      /|      /|
13902                                     //     *-------*-------*
13903                                     //    /|      /       /|
13904                                     //   / |             / |
13905                                     //     |               |
13906                                     //     *---------------*
13907                                     //    /               /
13908                                     //   /               /
13909 
13910                                     std::pair<unsigned int, unsigned int>
13911                                       nb_indices =
13912                                         has_periodic_neighbor ?
13913                                           cell
13914                                             ->periodic_neighbor_of_coarser_periodic_neighbor(
13915                                               i) :
13916                                           cell->neighbor_of_coarser_neighbor(i);
13917                                     unsigned int refined_along_x       = 0,
13918                                                  refined_along_y       = 0,
13919                                                  to_be_refined_along_x = 0,
13920                                                  to_be_refined_along_y = 0;
13921 
13922                                     const int this_face_index =
13923                                       cell->face_index(i);
13924 
13925                                     // step 1: detect, along which axis the face
13926                                     // is currently refined
13927 
13928                                     // first, we need an iterator pointing to
13929                                     // the parent face. This requires a slight
13930                                     // detour in case the neighbor is behind a
13931                                     // periodic face.
13932                                     const auto parent_face = [&]() {
13933                                       if (has_periodic_neighbor)
13934                                         {
13935                                           const auto neighbor =
13936                                             cell->periodic_neighbor(i);
13937                                           const auto parent_face_no =
13938                                             neighbor
13939                                               ->periodic_neighbor_of_periodic_neighbor(
13940                                                 nb_indices.first);
13941                                           auto parent =
13942                                             neighbor->periodic_neighbor(
13943                                               nb_indices.first);
13944                                           return parent->face(parent_face_no);
13945                                         }
13946                                       else
13947                                         return cell->neighbor(i)->face(
13948                                           nb_indices.first);
13949                                     }();
13950 
13951                                     if ((this_face_index ==
13952                                          parent_face->child_index(0)) ||
13953                                         (this_face_index ==
13954                                          parent_face->child_index(1)))
13955                                       {
13956                                         // this might be an
13957                                         // anisotropic child. get the
13958                                         // face refine case of the
13959                                         // neighbors face and count
13960                                         // refinements in x and y
13961                                         // direction.
13962                                         RefinementCase<dim - 1> frc =
13963                                           parent_face->refinement_case();
13964                                         if (frc & RefinementCase<dim>::cut_x)
13965                                           ++refined_along_x;
13966                                         if (frc & RefinementCase<dim>::cut_y)
13967                                           ++refined_along_y;
13968                                       }
13969                                     else
13970                                       // this has to be an isotropic
13971                                       // child
13972                                       {
13973                                         ++refined_along_x;
13974                                         ++refined_along_y;
13975                                       }
13976                                     // step 2: detect, along which axis the face
13977                                     // has to be refined given the current
13978                                     // refine flag
13979                                     RefinementCase<dim - 1> flagged_frc =
13980                                       GeometryInfo<dim>::face_refinement_case(
13981                                         cell->refine_flag_set(),
13982                                         i,
13983                                         cell->face_orientation(i),
13984                                         cell->face_flip(i),
13985                                         cell->face_rotation(i));
13986                                     if (flagged_frc &
13987                                         RefinementCase<dim>::cut_x)
13988                                       ++to_be_refined_along_x;
13989                                     if (flagged_frc &
13990                                         RefinementCase<dim>::cut_y)
13991                                       ++to_be_refined_along_y;
13992 
13993                                     // step 3: set the refine flag of the
13994                                     // (coarser and active) neighbor.
13995                                     if ((smooth_grid &
13996                                          allow_anisotropic_smoothing) ||
13997                                         cell->neighbor_or_periodic_neighbor(i)
13998                                           ->refine_flag_set())
13999                                       {
14000                                         if (refined_along_x +
14001                                               to_be_refined_along_x >
14002                                             1)
14003                                           changed |=
14004                                             cell
14005                                               ->neighbor_or_periodic_neighbor(i)
14006                                               ->flag_for_face_refinement(
14007                                                 nb_indices.first,
14008                                                 RefinementCase<dim -
14009                                                                1>::cut_axis(0));
14010                                         if (refined_along_y +
14011                                               to_be_refined_along_y >
14012                                             1)
14013                                           changed |=
14014                                             cell
14015                                               ->neighbor_or_periodic_neighbor(i)
14016                                               ->flag_for_face_refinement(
14017                                                 nb_indices.first,
14018                                                 RefinementCase<dim -
14019                                                                1>::cut_axis(1));
14020                                       }
14021                                     else
14022                                       {
14023                                         if (cell
14024                                               ->neighbor_or_periodic_neighbor(i)
14025                                               ->refine_flag_set() !=
14026                                             RefinementCase<
14027                                               dim>::isotropic_refinement)
14028                                           changed = true;
14029                                         cell->neighbor_or_periodic_neighbor(i)
14030                                           ->set_refine_flag();
14031                                       }
14032 
14033                                     // step 4: if necessary (see above) add to
14034                                     // the refine flag of the current cell
14035                                     cell_iterator nb =
14036                                       cell->neighbor_or_periodic_neighbor(i);
14037                                     RefinementCase<dim - 1> nb_frc =
14038                                       GeometryInfo<dim>::face_refinement_case(
14039                                         nb->refine_flag_set(),
14040                                         nb_indices.first,
14041                                         nb->face_orientation(nb_indices.first),
14042                                         nb->face_flip(nb_indices.first),
14043                                         nb->face_rotation(nb_indices.first));
14044                                     if ((nb_frc & RefinementCase<dim>::cut_x) &&
14045                                         !(refined_along_x ||
14046                                           to_be_refined_along_x))
14047                                       changed |= cell->flag_for_face_refinement(
14048                                         i,
14049                                         RefinementCase<dim - 1>::cut_axis(0));
14050                                     if ((nb_frc & RefinementCase<dim>::cut_y) &&
14051                                         !(refined_along_y ||
14052                                           to_be_refined_along_y))
14053                                       changed |= cell->flag_for_face_refinement(
14054                                         i,
14055                                         RefinementCase<dim - 1>::cut_axis(1));
14056                                   }
14057                               }  // if neighbor is coarser
14058                             else // -> now the neighbor is not coarser
14059                               {
14060                                 cell->neighbor_or_periodic_neighbor(i)
14061                                   ->clear_coarsen_flag();
14062                                 const unsigned int nb_nb =
14063                                   has_periodic_neighbor ?
14064                                     cell
14065                                       ->periodic_neighbor_of_periodic_neighbor(
14066                                         i) :
14067                                     cell->neighbor_of_neighbor(i);
14068                                 const cell_iterator neighbor =
14069                                   cell->neighbor_or_periodic_neighbor(i);
14070                                 RefinementCase<dim - 1> face_ref_case =
14071                                   GeometryInfo<dim>::face_refinement_case(
14072                                     neighbor->refine_flag_set(),
14073                                     nb_nb,
14074                                     neighbor->face_orientation(nb_nb),
14075                                     neighbor->face_flip(nb_nb),
14076                                     neighbor->face_rotation(nb_nb));
14077                                 RefinementCase<dim - 1> needed_face_ref_case =
14078                                   GeometryInfo<dim>::face_refinement_case(
14079                                     cell->refine_flag_set(),
14080                                     i,
14081                                     cell->face_orientation(i),
14082                                     cell->face_flip(i),
14083                                     cell->face_rotation(i));
14084                                 // if the neighbor wants to refine the
14085                                 // face with cut_x and we want cut_y
14086                                 // or vice versa, we have to refine
14087                                 // isotropically at the given face
14088                                 if ((face_ref_case ==
14089                                        RefinementCase<dim>::cut_x &&
14090                                      needed_face_ref_case ==
14091                                        RefinementCase<dim>::cut_y) ||
14092                                     (face_ref_case ==
14093                                        RefinementCase<dim>::cut_y &&
14094                                      needed_face_ref_case ==
14095                                        RefinementCase<dim>::cut_x))
14096                                   {
14097                                     changed = cell->flag_for_face_refinement(
14098                                       i, face_ref_case);
14099                                     neighbor->flag_for_face_refinement(
14100                                       nb_nb, needed_face_ref_case);
14101                                   }
14102                               }
14103                           }
14104                         else //-> the neighbor is not active
14105                           {
14106                             RefinementCase<dim - 1>
14107                               face_ref_case = cell->face(i)->refinement_case(),
14108                               needed_face_ref_case =
14109                                 GeometryInfo<dim>::face_refinement_case(
14110                                   cell->refine_flag_set(),
14111                                   i,
14112                                   cell->face_orientation(i),
14113                                   cell->face_flip(i),
14114                                   cell->face_rotation(i));
14115                             // if the face is refined with cut_x and
14116                             // we want cut_y or vice versa, we have to
14117                             // refine isotropically at the given face
14118                             if ((face_ref_case == RefinementCase<dim>::cut_x &&
14119                                  needed_face_ref_case ==
14120                                    RefinementCase<dim>::cut_y) ||
14121                                 (face_ref_case == RefinementCase<dim>::cut_y &&
14122                                  needed_face_ref_case ==
14123                                    RefinementCase<dim>::cut_x))
14124                               changed =
14125                                 cell->flag_for_face_refinement(i,
14126                                                                face_ref_case);
14127                           }
14128                       }
14129                   }
14130               }
14131         }
14132 
14133       //////////////////////////////////////
14134       // STEP 7:
14135       //    take care that no double refinement
14136       //    is done at each line in 3d or higher
14137       //    dimensions.
14138       internal::TriangulationImplementation::Implementation::
14139         prepare_refinement_dim_dependent(*this);
14140 
14141       //////////////////////////////////////
14142       // STEP 8:
14143       //    make sure that all children of each
14144       //    cell are either flagged for coarsening
14145       //    or none of the children is
14146       fix_coarsen_flags();
14147       // get the refinement and coarsening
14148       // flags
14149       std::vector<bool> flags_after_loop[2];
14150       save_coarsen_flags(flags_after_loop[0]);
14151       save_refine_flags(flags_after_loop[1]);
14152 
14153       // find out whether something was
14154       // changed in this loop
14155       mesh_changed_in_this_loop =
14156         ((flags_before_loop[0] != flags_after_loop[0]) ||
14157          (flags_before_loop[1] != flags_after_loop[1]));
14158 
14159       // set the flags for the next loop
14160       // already
14161       flags_before_loop[0].swap(flags_after_loop[0]);
14162       flags_before_loop[1].swap(flags_after_loop[1]);
14163     }
14164   while (mesh_changed_in_this_loop);
14165 
14166 
14167   // find out whether something was really changed in this
14168   // function. Note that @p{flags_before_loop} represents the state
14169   // after the last loop, i.e.  the present state
14170   return ((flags_before[0] != flags_before_loop[0]) ||
14171           (flags_before[1] != flags_before_loop[1]));
14172 }
14173 
14174 
14175 
14176 template <int dim, int spacedim>
14177 void
write_bool_vector(const unsigned int magic_number1,const std::vector<bool> & v,const unsigned int magic_number2,std::ostream & out)14178 Triangulation<dim, spacedim>::write_bool_vector(
14179   const unsigned int       magic_number1,
14180   const std::vector<bool> &v,
14181   const unsigned int       magic_number2,
14182   std::ostream &           out)
14183 {
14184   const unsigned int N     = v.size();
14185   unsigned char *    flags = new unsigned char[N / 8 + 1];
14186   for (unsigned int i = 0; i < N / 8 + 1; ++i)
14187     flags[i] = 0;
14188 
14189   for (unsigned int position = 0; position < N; ++position)
14190     flags[position / 8] |= (v[position] ? (1 << (position % 8)) : 0);
14191 
14192   AssertThrow(out, ExcIO());
14193 
14194   // format:
14195   // 0. magic number
14196   // 1. number of flags
14197   // 2. the flags
14198   // 3. magic number
14199   out << magic_number1 << ' ' << N << std::endl;
14200   for (unsigned int i = 0; i < N / 8 + 1; ++i)
14201     out << static_cast<unsigned int>(flags[i]) << ' ';
14202 
14203   out << std::endl << magic_number2 << std::endl;
14204 
14205   delete[] flags;
14206 
14207   AssertThrow(out, ExcIO());
14208 }
14209 
14210 
14211 template <int dim, int spacedim>
14212 void
read_bool_vector(const unsigned int magic_number1,std::vector<bool> & v,const unsigned int magic_number2,std::istream & in)14213 Triangulation<dim, spacedim>::read_bool_vector(const unsigned int magic_number1,
14214                                                std::vector<bool> &v,
14215                                                const unsigned int magic_number2,
14216                                                std::istream &     in)
14217 {
14218   AssertThrow(in, ExcIO());
14219 
14220   unsigned int magic_number;
14221   in >> magic_number;
14222   AssertThrow(magic_number == magic_number1, ExcGridReadError());
14223 
14224   unsigned int N;
14225   in >> N;
14226   v.resize(N);
14227 
14228   unsigned char *    flags = new unsigned char[N / 8 + 1];
14229   unsigned short int tmp;
14230   for (unsigned int i = 0; i < N / 8 + 1; ++i)
14231     {
14232       in >> tmp;
14233       flags[i] = tmp;
14234     }
14235 
14236   for (unsigned int position = 0; position != N; ++position)
14237     v[position] = (flags[position / 8] & (1 << (position % 8)));
14238 
14239   in >> magic_number;
14240   AssertThrow(magic_number == magic_number2, ExcGridReadError());
14241 
14242   delete[] flags;
14243 
14244   AssertThrow(in, ExcIO());
14245 }
14246 
14247 
14248 
14249 template <int dim, int spacedim>
14250 std::size_t
memory_consumption() const14251 Triangulation<dim, spacedim>::memory_consumption() const
14252 {
14253   std::size_t mem = 0;
14254   mem += MemoryConsumption::memory_consumption(levels);
14255   for (const auto &level : levels)
14256     mem += MemoryConsumption::memory_consumption(*level);
14257   mem += MemoryConsumption::memory_consumption(vertices);
14258   mem += MemoryConsumption::memory_consumption(vertices_used);
14259   mem += sizeof(manifold);
14260   mem += sizeof(smooth_grid);
14261   mem += MemoryConsumption::memory_consumption(number_cache);
14262   mem += sizeof(faces);
14263   if (faces)
14264     mem += MemoryConsumption::memory_consumption(*faces);
14265 
14266   return mem;
14267 }
14268 
14269 
14270 // explicit instantiations
14271 #include "tria.inst"
14272 
14273 DEAL_II_NAMESPACE_CLOSE
14274