Reference documentation for deal.II version 9.4.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
tria.cc
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2022 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 
19 
20 #include <deal.II/fe/mapping_q1.h>
21 
25 #include <deal.II/grid/manifold.h>
26 #include <deal.II/grid/tria.h>
31 
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 
46 
47 
48 namespace internal
49 {
50  namespace TriangulationImplementation
51  {
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
64  {
65  return (MemoryConsumption::memory_consumption(n_levels) +
69  MemoryConsumption::memory_consumption(n_active_lines_level));
70  }
71 
72 
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
84  {
89  MemoryConsumption::memory_consumption(n_active_quads_level));
90  }
91 
92 
93 
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
105  {
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
126  cell_is_patch_level_1(
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
149  cell_will_be_coarsened(
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
206  face_will_be_refined_by_neighbor_internal(
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. It 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 =
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  {
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 ==
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
355  face_will_be_refined_by_neighbor(
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
369  face_will_be_refined_by_neighbor(
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
383  satisfies_level1_at_vertex_rule(
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 : cell->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 
417  template <int dim, int spacedim>
418  std::vector<unsigned int>
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 < cell->n_lines(); ++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 
442  template <int dim, int spacedim>
443  std::vector<unsigned int>
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 : cell->face_indices())
452  ++quad_cell_count[cell->quad_index(q)];
453  return quad_cell_count;
454  }
455  else
456  return {};
457  }
458 
459 
460 
472  void
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 
480  void
481  reorder_compatibility(std::vector<CellData<2>> &cells, const SubCellData &)
482  {
483  for (auto &cell : cells)
484  if (cell.vertices.size() == GeometryInfo<2>::vertices_per_cell)
485  std::swap(cell.vertices[2], cell.vertices[3]);
486  }
487 
488 
489  void
490  reorder_compatibility(std::vector<CellData<3>> &cells,
491  SubCellData & subcelldata)
492  {
493  unsigned int tmp[GeometryInfo<3>::vertices_per_cell];
494  for (auto &cell : cells)
495  if (cell.vertices.size() == GeometryInfo<3>::vertices_per_cell)
496  {
497  for (const unsigned int i : GeometryInfo<3>::vertex_indices())
498  tmp[i] = cell.vertices[i];
499  for (const unsigned int i : GeometryInfo<3>::vertex_indices())
500  cell.vertices[GeometryInfo<3>::ucd_to_deal[i]] = tmp[i];
501  }
502 
503  // now points in boundary quads
504  for (auto &boundary_quad : subcelldata.boundary_quads)
505  if (boundary_quad.vertices.size() == GeometryInfo<2>::vertices_per_cell)
506  std::swap(boundary_quad.vertices[2], boundary_quad.vertices[3]);
507  }
508 
509 
510 
528  template <int dim, int spacedim>
529  unsigned int
530  middle_vertex_index(
531  const typename Triangulation<dim, spacedim>::line_iterator &line)
532  {
533  if (line->has_children())
534  return line->child(0)->vertex_index(1);
536  }
537 
538 
539  template <int dim, int spacedim>
540  unsigned int
541  middle_vertex_index(
542  const typename Triangulation<dim, spacedim>::quad_iterator &quad)
543  {
544  switch (static_cast<unsigned char>(quad->refinement_case()))
545  {
547  return middle_vertex_index<dim, spacedim>(quad->child(0)->line(1));
548  break;
550  return middle_vertex_index<dim, spacedim>(quad->child(0)->line(3));
551  break;
553  return quad->child(0)->vertex_index(3);
554  break;
555  default:
556  break;
557  }
559  }
560 
561 
562  template <int dim, int spacedim>
563  unsigned int
564  middle_vertex_index(
565  const typename Triangulation<dim, spacedim>::hex_iterator &hex)
566  {
567  switch (static_cast<unsigned char>(hex->refinement_case()))
568  {
570  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(1));
571  break;
573  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(3));
574  break;
576  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(5));
577  break;
579  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(11));
580  break;
582  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(5));
583  break;
585  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(7));
586  break;
588  return hex->child(0)->vertex_index(7);
589  break;
590  default:
591  break;
592  }
594  }
595 
596 
609  template <class TRIANGULATION>
610  inline typename TRIANGULATION::DistortedCellList
611  collect_distorted_coarse_cells(const TRIANGULATION &)
612  {
613  return typename TRIANGULATION::DistortedCellList();
614  }
615 
616 
617 
626  template <int dim>
628  collect_distorted_coarse_cells(const Triangulation<dim, dim> &triangulation)
629  {
630  typename Triangulation<dim, dim>::DistortedCellList distorted_cells;
631  for (const auto &cell : triangulation.cell_iterators_on_level(0))
632  {
634  for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
635  vertices[i] = cell->vertex(i);
636 
639 
640  for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
641  if (determinants[i] <= 1e-9 * std::pow(cell->diameter(), 1. * dim))
642  {
643  distorted_cells.distorted_cells.push_back(cell);
644  break;
645  }
646  }
647 
648  return distorted_cells;
649  }
650 
651 
658  template <int dim>
659  bool
660  has_distorted_children(
661  const typename Triangulation<dim, dim>::cell_iterator &cell)
662  {
663  Assert(cell->has_children(), ExcInternalError());
664 
665  for (unsigned int c = 0; c < cell->n_children(); ++c)
666  {
668  for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
669  vertices[i] = cell->child(c)->vertex(i);
670 
673 
674  for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
675  if (determinants[i] <=
676  1e-9 * std::pow(cell->child(c)->diameter(), 1. * dim))
677  return true;
678  }
679 
680  return false;
681  }
682 
683 
691  template <int dim, int spacedim>
692  bool
693  has_distorted_children(
695  {
696  return false;
697  }
698 
699 
700  template <int dim, int spacedim>
701  void
702  update_periodic_face_map_recursively(
703  const typename Triangulation<dim, spacedim>::cell_iterator &cell_1,
704  const typename Triangulation<dim, spacedim>::cell_iterator &cell_2,
705  unsigned int n_face_1,
706  unsigned int n_face_2,
707  const std::bitset<3> & orientation,
708  typename std::map<
710  unsigned int>,
711  std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
712  unsigned int>,
713  std::bitset<3>>> &periodic_face_map)
714  {
715  using FaceIterator = typename Triangulation<dim, spacedim>::face_iterator;
716  const FaceIterator face_1 = cell_1->face(n_face_1);
717  const FaceIterator face_2 = cell_2->face(n_face_2);
718 
719  const bool face_orientation = orientation[0];
720  const bool face_flip = orientation[1];
721  const bool face_rotation = orientation[2];
722 
723  Assert((dim != 1) || (face_orientation == true && face_flip == false &&
724  face_rotation == false),
725  ExcMessage("The supplied orientation "
726  "(face_orientation, face_flip, face_rotation) "
727  "is invalid for 1D"));
728 
729  Assert((dim != 2) || (face_orientation == true && face_rotation == false),
730  ExcMessage("The supplied orientation "
731  "(face_orientation, face_flip, face_rotation) "
732  "is invalid for 2D"));
733 
734  Assert(face_1 != face_2, ExcMessage("face_1 and face_2 are equal!"));
735 
736  Assert(face_1->at_boundary() && face_2->at_boundary(),
737  ExcMessage("Periodic faces must be on the boundary"));
738 
739  // Check if the requirement that each edge can only have at most one hanging
740  // node, and as a consequence neighboring cells can differ by at most
741  // one refinement level is enforced. In 1d, there are no hanging nodes and
742  // so neighboring cells can differ by more than one refinement level.
743  Assert(dim == 1 || std::abs(cell_1->level() - cell_2->level()) < 2,
744  ExcInternalError());
745 
746  // insert periodic face pair for both cells
747  using CellFace =
748  std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
749  unsigned int>;
750  const CellFace cell_face_1(cell_1, n_face_1);
751  const CellFace cell_face_2(cell_2, n_face_2);
752  const std::pair<CellFace, std::bitset<3>> cell_face_orientation_2(
753  cell_face_2, orientation);
754 
755  const std::pair<CellFace, std::pair<CellFace, std::bitset<3>>>
756  periodic_faces(cell_face_1, cell_face_orientation_2);
757 
758  // Only one periodic neighbor is allowed
759  Assert(periodic_face_map.count(cell_face_1) == 0, ExcInternalError());
760  periodic_face_map.insert(periodic_faces);
761 
762  if (dim == 1)
763  {
764  if (cell_1->has_children())
765  {
766  if (cell_2->has_children())
767  {
768  update_periodic_face_map_recursively<dim, spacedim>(
769  cell_1->child(n_face_1),
770  cell_2->child(n_face_2),
771  n_face_1,
772  n_face_2,
773  orientation,
774  periodic_face_map);
775  }
776  else // only face_1 has children
777  {
778  update_periodic_face_map_recursively<dim, spacedim>(
779  cell_1->child(n_face_1),
780  cell_2,
781  n_face_1,
782  n_face_2,
783  orientation,
784  periodic_face_map);
785  }
786  }
787  }
788  else // dim == 2 || dim == 3
789  {
790  // A lookup table on how to go through the child cells depending on the
791  // orientation:
792  // see Documentation of GeometryInfo for details
793 
794  static const int lookup_table_2d[2][2] =
795  // flip:
796  {
797  {0, 1}, // false
798  {1, 0} // true
799  };
800 
801  static const int lookup_table_3d[2][2][2][4] =
802  // orientation flip rotation
803  {{{
804  {0, 2, 1, 3}, // false false false
805  {2, 3, 0, 1} // false false true
806  },
807  {
808  {3, 1, 2, 0}, // false true false
809  {1, 0, 3, 2} // false true true
810  }},
811  {{
812  {0, 1, 2, 3}, // true false false
813  {1, 3, 0, 2} // true false true
814  },
815  {
816  {3, 2, 1, 0}, // true true false
817  {2, 0, 3, 1} // true true true
818  }}};
819 
820  if (cell_1->has_children())
821  {
822  if (cell_2->has_children())
823  {
824  // In the case that both faces have children, we loop over all
825  // children and apply update_periodic_face_map_recursively
826  // recursively:
827 
828  Assert(face_1->n_children() ==
830  face_2->n_children() ==
833 
834  for (unsigned int i = 0;
835  i < GeometryInfo<dim>::max_children_per_face;
836  ++i)
837  {
838  // Lookup the index for the second face
839  unsigned int j = 0;
840  switch (dim)
841  {
842  case 2:
843  j = lookup_table_2d[face_flip][i];
844  break;
845  case 3:
846  j = lookup_table_3d[face_orientation][face_flip]
847  [face_rotation][i];
848  break;
849  default:
850  AssertThrow(false, ExcNotImplemented());
851  }
852 
853  // find subcell ids that belong to the subface indices
854  unsigned int child_cell_1 =
856  cell_1->refinement_case(),
857  n_face_1,
858  i,
859  cell_1->face_orientation(n_face_1),
860  cell_1->face_flip(n_face_1),
861  cell_1->face_rotation(n_face_1),
862  face_1->refinement_case());
863  unsigned int child_cell_2 =
865  cell_2->refinement_case(),
866  n_face_2,
867  j,
868  cell_2->face_orientation(n_face_2),
869  cell_2->face_flip(n_face_2),
870  cell_2->face_rotation(n_face_2),
871  face_2->refinement_case());
872 
873  Assert(cell_1->child(child_cell_1)->face(n_face_1) ==
874  face_1->child(i),
875  ExcInternalError());
876  Assert(cell_2->child(child_cell_2)->face(n_face_2) ==
877  face_2->child(j),
878  ExcInternalError());
879 
880  // precondition: subcell has the same orientation as cell
881  // (so that the face numbers coincide) recursive call
882  update_periodic_face_map_recursively<dim, spacedim>(
883  cell_1->child(child_cell_1),
884  cell_2->child(child_cell_2),
885  n_face_1,
886  n_face_2,
887  orientation,
888  periodic_face_map);
889  }
890  }
891  else // only face_1 has children
892  {
893  for (unsigned int i = 0;
894  i < GeometryInfo<dim>::max_children_per_face;
895  ++i)
896  {
897  // find subcell ids that belong to the subface indices
898  unsigned int child_cell_1 =
900  cell_1->refinement_case(),
901  n_face_1,
902  i,
903  cell_1->face_orientation(n_face_1),
904  cell_1->face_flip(n_face_1),
905  cell_1->face_rotation(n_face_1),
906  face_1->refinement_case());
907 
908  // recursive call
909  update_periodic_face_map_recursively<dim, spacedim>(
910  cell_1->child(child_cell_1),
911  cell_2,
912  n_face_1,
913  n_face_2,
914  orientation,
915  periodic_face_map);
916  }
917  }
918  }
919  }
920  }
921 
922 
923 } // end of anonymous namespace
924 
925 
926 namespace internal
927 {
928  namespace TriangulationImplementation
929  {
930  // make sure that if in the following we
931  // write Triangulation<dim,spacedim>
932  // we mean the *class*
933  // ::Triangulation, not the
934  // enclosing namespace
935  // internal::TriangulationImplementation
936  using ::Triangulation;
937 
943  int,
944  << "Something went wrong when making cell " << arg1
945  << ". Read the docs and the source code "
946  << "for more information.");
952  int,
953  << "Something went wrong upon construction of cell "
954  << arg1);
965  int,
966  << "Cell " << arg1
967  << " has negative measure. This typically "
968  << "indicates some distortion in the cell, or a mistakenly "
969  << "swapped pair of vertices in the input to "
970  << "Triangulation::create_triangulation().");
979  int,
980  int,
981  int,
982  << "Error while creating cell " << arg1
983  << ": the vertex index " << arg2 << " must be between 0 and "
984  << arg3 << '.');
990  int,
991  int,
992  << "While trying to assign a boundary indicator to a line: "
993  << "the line with end vertices " << arg1 << " and " << arg2
994  << " does not exist.");
1000  int,
1001  int,
1002  int,
1003  int,
1004  << "While trying to assign a boundary indicator to a quad: "
1005  << "the quad with bounding lines " << arg1 << ", " << arg2
1006  << ", " << arg3 << ", " << arg4 << " does not exist.");
1013  int,
1014  int,
1016  << "The input data for creating a triangulation contained "
1017  << "information about a line with indices " << arg1 << " and " << arg2
1018  << " that is described to have boundary indicator "
1019  << static_cast<int>(arg3)
1020  << ". However, this is an internal line not located on the "
1021  << "boundary. You cannot assign a boundary indicator to it." << std::endl
1022  << std::endl
1023  << "If this happened at a place where you call "
1024  << "Triangulation::create_triangulation() yourself, you need "
1025  << "to check the SubCellData object you pass to this function."
1026  << std::endl
1027  << std::endl
1028  << "If this happened in a place where you are reading a mesh "
1029  << "from a file, then you need to investigate why such a line "
1030  << "ended up in the input file. A typical case is a geometry "
1031  << "that consisted of multiple parts and for which the mesh "
1032  << "generator program assumes that the interface between "
1033  << "two parts is a boundary when that isn't supposed to be "
1034  << "the case, or where the mesh generator simply assigns "
1035  << "'geometry indicators' to lines at the perimeter of "
1036  << "a part that are not supposed to be interpreted as "
1037  << "'boundary indicators'.");
1044  int,
1045  int,
1046  int,
1047  int,
1049  << "The input data for creating a triangulation contained "
1050  << "information about a quad with indices " << arg1 << ", " << arg2
1051  << ", " << arg3 << ", and " << arg4
1052  << " that is described to have boundary indicator "
1053  << static_cast<int>(arg5)
1054  << ". However, this is an internal quad not located on the "
1055  << "boundary. You cannot assign a boundary indicator to it." << std::endl
1056  << std::endl
1057  << "If this happened at a place where you call "
1058  << "Triangulation::create_triangulation() yourself, you need "
1059  << "to check the SubCellData object you pass to this function."
1060  << std::endl
1061  << std::endl
1062  << "If this happened in a place where you are reading a mesh "
1063  << "from a file, then you need to investigate why such a quad "
1064  << "ended up in the input file. A typical case is a geometry "
1065  << "that consisted of multiple parts and for which the mesh "
1066  << "generator program assumes that the interface between "
1067  << "two parts is a boundary when that isn't supposed to be "
1068  << "the case, or where the mesh generator simply assigns "
1069  << "'geometry indicators' to quads at the surface of "
1070  << "a part that are not supposed to be interpreted as "
1071  << "'boundary indicators'.");
1078  int,
1079  int,
1080  << "In SubCellData the line info of the line with vertex indices " << arg1
1081  << " and " << arg2 << " appears more than once. "
1082  << "This is not allowed.");
1089  int,
1090  int,
1091  std::string,
1092  << "In SubCellData the line info of the line with vertex indices " << arg1
1093  << " and " << arg2 << " appears multiple times with different (valid) "
1094  << arg3 << ". This is not allowed.");
1101  int,
1102  int,
1103  int,
1104  int,
1105  std::string,
1106  << "In SubCellData the quad info of the quad with line indices " << arg1
1107  << ", " << arg2 << ", " << arg3 << " and " << arg4
1108  << " appears multiple times with different (valid) " << arg5
1109  << ". This is not allowed.");
1110 
1111  /*
1112  * Reserve space for TriaFaces. Details:
1113  *
1114  * Reserve space for line_orientations.
1115  *
1116  * @note Used only for dim=3.
1117  */
1118  void
1119  reserve_space(TriaFaces & tria_faces,
1120  const unsigned int new_quads_in_pairs,
1121  const unsigned int new_quads_single)
1122  {
1123  AssertDimension(tria_faces.dim, 3);
1124 
1125  Assert(new_quads_in_pairs % 2 == 0, ExcInternalError());
1126 
1127  unsigned int next_free_single = 0;
1128  unsigned int next_free_pair = 0;
1129 
1130  // count the number of objects, of unused single objects and of
1131  // unused pairs of objects
1132  unsigned int n_quads = 0;
1133  unsigned int n_unused_pairs = 0;
1134  unsigned int n_unused_singles = 0;
1135  for (unsigned int i = 0; i < tria_faces.quads.used.size(); ++i)
1136  {
1137  if (tria_faces.quads.used[i])
1138  ++n_quads;
1139  else if (i + 1 < tria_faces.quads.used.size())
1140  {
1141  if (tria_faces.quads.used[i + 1])
1142  {
1143  ++n_unused_singles;
1144  if (next_free_single == 0)
1145  next_free_single = i;
1146  }
1147  else
1148  {
1149  ++n_unused_pairs;
1150  if (next_free_pair == 0)
1151  next_free_pair = i;
1152  ++i;
1153  }
1154  }
1155  else
1156  ++n_unused_singles;
1157  }
1158  Assert(n_quads + 2 * n_unused_pairs + n_unused_singles ==
1159  tria_faces.quads.used.size(),
1160  ExcInternalError());
1161 
1162  // how many single quads are needed in addition to n_unused_quads?
1163  const int additional_single_quads = new_quads_single - n_unused_singles;
1164 
1165  unsigned int new_size =
1166  tria_faces.quads.used.size() + new_quads_in_pairs - 2 * n_unused_pairs;
1167  if (additional_single_quads > 0)
1168  new_size += additional_single_quads;
1169 
1170  // see above...
1171  if (new_size > tria_faces.quads.n_objects())
1172  {
1173  // reserve the field of the derived class
1174  tria_faces.quads_line_orientations.reserve(
1175  new_size * GeometryInfo<2>::lines_per_cell);
1176  tria_faces.quads_line_orientations.insert(
1177  tria_faces.quads_line_orientations.end(),
1178  new_size * GeometryInfo<2>::lines_per_cell -
1179  tria_faces.quads_line_orientations.size(),
1180  1u);
1181 
1182  tria_faces.quad_reference_cell.reserve(new_size);
1183  tria_faces.quad_reference_cell.insert(
1184  tria_faces.quad_reference_cell.end(),
1185  new_size - tria_faces.quad_reference_cell.size(),
1187  }
1188  }
1189 
1190 
1191 
1205  void
1206  reserve_space(TriaLevel & tria_level,
1207  const unsigned int total_cells,
1208  const unsigned int dimension,
1209  const unsigned int space_dimension)
1210  {
1211  // we need space for total_cells cells. Maybe we have more already
1212  // with those cells which are unused, so only allocate new space if
1213  // needed.
1214  //
1215  // note that all arrays should have equal sizes (checked by
1216  // @p{monitor_memory}
1217  if (total_cells > tria_level.refine_flags.size())
1218  {
1219  tria_level.refine_flags.reserve(total_cells);
1220  tria_level.refine_flags.insert(tria_level.refine_flags.end(),
1221  total_cells -
1222  tria_level.refine_flags.size(),
1223  /*RefinementCase::no_refinement=*/0);
1224 
1225  tria_level.coarsen_flags.reserve(total_cells);
1226  tria_level.coarsen_flags.insert(tria_level.coarsen_flags.end(),
1227  total_cells -
1228  tria_level.coarsen_flags.size(),
1229  false);
1230 
1231  tria_level.active_cell_indices.reserve(total_cells);
1232  tria_level.active_cell_indices.insert(
1233  tria_level.active_cell_indices.end(),
1234  total_cells - tria_level.active_cell_indices.size(),
1236 
1237  tria_level.subdomain_ids.reserve(total_cells);
1238  tria_level.subdomain_ids.insert(tria_level.subdomain_ids.end(),
1239  total_cells -
1240  tria_level.subdomain_ids.size(),
1241  0);
1242 
1243  tria_level.level_subdomain_ids.reserve(total_cells);
1244  tria_level.level_subdomain_ids.insert(
1245  tria_level.level_subdomain_ids.end(),
1246  total_cells - tria_level.level_subdomain_ids.size(),
1247  0);
1248 
1249  tria_level.global_active_cell_indices.reserve(total_cells);
1250  tria_level.global_active_cell_indices.insert(
1251  tria_level.global_active_cell_indices.end(),
1252  total_cells - tria_level.global_active_cell_indices.size(),
1254 
1255  tria_level.global_level_cell_indices.reserve(total_cells);
1256  tria_level.global_level_cell_indices.insert(
1257  tria_level.global_level_cell_indices.end(),
1258  total_cells - tria_level.global_level_cell_indices.size(),
1260 
1261  if (dimension < space_dimension)
1262  {
1263  tria_level.direction_flags.reserve(total_cells);
1264  tria_level.direction_flags.insert(
1265  tria_level.direction_flags.end(),
1266  total_cells - tria_level.direction_flags.size(),
1267  true);
1268  }
1269  else
1270  tria_level.direction_flags.clear();
1271 
1272  tria_level.parents.reserve((total_cells + 1) / 2);
1273  tria_level.parents.insert(tria_level.parents.end(),
1274  (total_cells + 1) / 2 -
1275  tria_level.parents.size(),
1276  -1);
1277 
1278  tria_level.neighbors.reserve(total_cells * (2 * dimension));
1279  tria_level.neighbors.insert(tria_level.neighbors.end(),
1280  total_cells * (2 * dimension) -
1281  tria_level.neighbors.size(),
1282  std::make_pair(-1, -1));
1283 
1284  if (tria_level.dim == 2 || tria_level.dim == 3)
1285  {
1286  const unsigned int max_faces_per_cell = 2 * dimension;
1287  tria_level.face_orientations.reserve(total_cells *
1288  max_faces_per_cell);
1289  tria_level.face_orientations.insert(
1290  tria_level.face_orientations.end(),
1291  total_cells * max_faces_per_cell -
1292  tria_level.face_orientations.size(),
1293  1u);
1294 
1295  tria_level.reference_cell.reserve(total_cells);
1296  tria_level.reference_cell.insert(
1297  tria_level.reference_cell.end(),
1298  total_cells - tria_level.reference_cell.size(),
1299  tria_level.dim == 2 ? ::ReferenceCells::Quadrilateral :
1301  }
1302  }
1303  }
1304 
1305 
1306 
1311  int,
1312  int,
1313  << "The containers have sizes " << arg1 << " and " << arg2
1314  << ", which is not as expected.");
1315 
1321  void
1322  monitor_memory(const TriaLevel & tria_level,
1323  const unsigned int true_dimension)
1324  {
1325  (void)tria_level;
1326  (void)true_dimension;
1327  Assert(2 * true_dimension * tria_level.refine_flags.size() ==
1328  tria_level.neighbors.size(),
1329  ExcMemoryInexact(tria_level.refine_flags.size(),
1330  tria_level.neighbors.size()));
1331  Assert(2 * true_dimension * tria_level.coarsen_flags.size() ==
1332  tria_level.neighbors.size(),
1333  ExcMemoryInexact(tria_level.coarsen_flags.size(),
1334  tria_level.neighbors.size()));
1335  }
1336 
1337 
1338 
1351  void
1352  reserve_space(TriaObjects & tria_objects,
1353  const unsigned int new_objects_in_pairs,
1354  const unsigned int new_objects_single = 0)
1355  {
1356  if (tria_objects.structdim <= 2)
1357  {
1358  Assert(new_objects_in_pairs % 2 == 0, ExcInternalError());
1359 
1360  tria_objects.next_free_single = 0;
1361  tria_objects.next_free_pair = 0;
1362  tria_objects.reverse_order_next_free_single = false;
1363 
1364  // count the number of objects, of unused single objects and of
1365  // unused pairs of objects
1366  unsigned int n_objects = 0;
1367  unsigned int n_unused_pairs = 0;
1368  unsigned int n_unused_singles = 0;
1369  for (unsigned int i = 0; i < tria_objects.used.size(); ++i)
1370  {
1371  if (tria_objects.used[i])
1372  ++n_objects;
1373  else if (i + 1 < tria_objects.used.size())
1374  {
1375  if (tria_objects.used[i + 1])
1376  {
1377  ++n_unused_singles;
1378  if (tria_objects.next_free_single == 0)
1379  tria_objects.next_free_single = i;
1380  }
1381  else
1382  {
1383  ++n_unused_pairs;
1384  if (tria_objects.next_free_pair == 0)
1385  tria_objects.next_free_pair = i;
1386  ++i;
1387  }
1388  }
1389  else
1390  ++n_unused_singles;
1391  }
1392  Assert(n_objects + 2 * n_unused_pairs + n_unused_singles ==
1393  tria_objects.used.size(),
1394  ExcInternalError());
1395 
1396  // how many single objects are needed in addition to
1397  // n_unused_objects?
1398  const int additional_single_objects =
1399  new_objects_single - n_unused_singles;
1400 
1401  unsigned int new_size = tria_objects.used.size() +
1402  new_objects_in_pairs - 2 * n_unused_pairs;
1403  if (additional_single_objects > 0)
1404  new_size += additional_single_objects;
1405 
1406  // only allocate space if necessary
1407  if (new_size > tria_objects.n_objects())
1408  {
1409  const unsigned int max_faces_per_cell =
1410  2 * tria_objects.structdim;
1411  const unsigned int max_children_per_cell =
1412  1 << tria_objects.structdim;
1413 
1414  tria_objects.cells.reserve(new_size * max_faces_per_cell);
1415  tria_objects.cells.insert(tria_objects.cells.end(),
1416  (new_size - tria_objects.n_objects()) *
1417  max_faces_per_cell,
1418  -1);
1419 
1420  tria_objects.used.reserve(new_size);
1421  tria_objects.used.insert(tria_objects.used.end(),
1422  new_size - tria_objects.used.size(),
1423  false);
1424 
1425  tria_objects.user_flags.reserve(new_size);
1426  tria_objects.user_flags.insert(tria_objects.user_flags.end(),
1427  new_size -
1428  tria_objects.user_flags.size(),
1429  false);
1430 
1431  const unsigned int factor = max_children_per_cell / 2;
1432  tria_objects.children.reserve(factor * new_size);
1433  tria_objects.children.insert(tria_objects.children.end(),
1434  factor * new_size -
1435  tria_objects.children.size(),
1436  -1);
1437 
1438  if (tria_objects.structdim > 1)
1439  {
1440  tria_objects.refinement_cases.reserve(new_size);
1441  tria_objects.refinement_cases.insert(
1442  tria_objects.refinement_cases.end(),
1443  new_size - tria_objects.refinement_cases.size(),
1444  /*RefinementCase::no_refinement=*/0);
1445  }
1446 
1447  // first reserve, then resize. Otherwise the std library can
1448  // decide to allocate more entries.
1449  tria_objects.boundary_or_material_id.reserve(new_size);
1450  tria_objects.boundary_or_material_id.resize(new_size);
1451 
1452  tria_objects.user_data.reserve(new_size);
1453  tria_objects.user_data.resize(new_size);
1454 
1455  tria_objects.manifold_id.reserve(new_size);
1456  tria_objects.manifold_id.insert(tria_objects.manifold_id.end(),
1457  new_size -
1458  tria_objects.manifold_id.size(),
1460  }
1461 
1462  if (n_unused_singles == 0)
1463  {
1464  tria_objects.next_free_single = new_size - 1;
1465  tria_objects.reverse_order_next_free_single = true;
1466  }
1467  }
1468  else
1469  {
1470  const unsigned int new_hexes = new_objects_in_pairs;
1471 
1472  const unsigned int new_size =
1473  new_hexes + std::count(tria_objects.used.begin(),
1474  tria_objects.used.end(),
1475  true);
1476 
1477  // see above...
1478  if (new_size > tria_objects.n_objects())
1479  {
1480  const unsigned int max_faces_per_cell =
1481  2 * tria_objects.structdim;
1482 
1483  tria_objects.cells.reserve(new_size * max_faces_per_cell);
1484  tria_objects.cells.insert(tria_objects.cells.end(),
1485  (new_size - tria_objects.n_objects()) *
1486  max_faces_per_cell,
1487  -1);
1488 
1489  tria_objects.used.reserve(new_size);
1490  tria_objects.used.insert(tria_objects.used.end(),
1491  new_size - tria_objects.used.size(),
1492  false);
1493 
1494  tria_objects.user_flags.reserve(new_size);
1495  tria_objects.user_flags.insert(tria_objects.user_flags.end(),
1496  new_size -
1497  tria_objects.user_flags.size(),
1498  false);
1499 
1500  tria_objects.children.reserve(4 * new_size);
1501  tria_objects.children.insert(tria_objects.children.end(),
1502  4 * new_size -
1503  tria_objects.children.size(),
1504  -1);
1505 
1506  // for the following fields, we know exactly how many elements
1507  // we need, so first reserve then resize (resize itself, at least
1508  // with some compiler libraries, appears to round up the size it
1509  // actually reserves)
1510  tria_objects.boundary_or_material_id.reserve(new_size);
1511  tria_objects.boundary_or_material_id.resize(new_size);
1512 
1513  tria_objects.manifold_id.reserve(new_size);
1514  tria_objects.manifold_id.insert(tria_objects.manifold_id.end(),
1515  new_size -
1516  tria_objects.manifold_id.size(),
1518 
1519  tria_objects.user_data.reserve(new_size);
1520  tria_objects.user_data.resize(new_size);
1521 
1522  tria_objects.refinement_cases.reserve(new_size);
1523  tria_objects.refinement_cases.insert(
1524  tria_objects.refinement_cases.end(),
1525  new_size - tria_objects.refinement_cases.size(),
1526  /*RefinementCase::no_refinement=*/0);
1527  }
1528  tria_objects.next_free_single = tria_objects.next_free_pair = 0;
1529  }
1530  }
1531 
1532 
1533 
1539  void
1540  monitor_memory(const TriaObjects &tria_object, const unsigned int)
1541  {
1542  Assert(tria_object.n_objects() == tria_object.used.size(),
1543  ExcMemoryInexact(tria_object.n_objects(),
1544  tria_object.used.size()));
1545  Assert(tria_object.n_objects() == tria_object.user_flags.size(),
1546  ExcMemoryInexact(tria_object.n_objects(),
1547  tria_object.user_flags.size()));
1548  Assert(tria_object.n_objects() ==
1549  tria_object.boundary_or_material_id.size(),
1550  ExcMemoryInexact(tria_object.n_objects(),
1551  tria_object.boundary_or_material_id.size()));
1552  Assert(tria_object.n_objects() == tria_object.manifold_id.size(),
1553  ExcMemoryInexact(tria_object.n_objects(),
1554  tria_object.manifold_id.size()));
1555  Assert(tria_object.n_objects() == tria_object.user_data.size(),
1556  ExcMemoryInexact(tria_object.n_objects(),
1557  tria_object.user_data.size()));
1558 
1559  if (tria_object.structdim == 1)
1560  {
1561  Assert(1 * tria_object.n_objects() == tria_object.children.size(),
1562  ExcMemoryInexact(tria_object.n_objects(),
1563  tria_object.children.size()));
1564  }
1565  else if (tria_object.structdim == 2)
1566  {
1567  Assert(2 * tria_object.n_objects() == tria_object.children.size(),
1568  ExcMemoryInexact(tria_object.n_objects(),
1569  tria_object.children.size()));
1570  }
1571  else if (tria_object.structdim == 3)
1572  {
1573  Assert(4 * tria_object.n_objects() == tria_object.children.size(),
1574  ExcMemoryInexact(tria_object.n_objects(),
1575  tria_object.children.size()));
1576  }
1577  }
1578 
1579 
1580 
1585  template <int dim, int spacedim>
1586  class Policy
1587  {
1588  public:
1592  virtual ~Policy() = default;
1593 
1597  virtual void
1599 
1603  virtual void
1607  std::vector<unsigned int> & line_cell_count,
1608  std::vector<unsigned int> &quad_cell_count) = 0;
1609 
1615  const bool check_for_distorted_cells) = 0;
1616 
1620  virtual void
1623 
1627  virtual void
1630 
1634  virtual bool
1636  const typename Triangulation<dim, spacedim>::cell_iterator &cell) = 0;
1637 
1644  virtual std::unique_ptr<Policy<dim, spacedim>>
1645  clone() = 0;
1646  };
1647 
1648 
1649 
1655  template <int dim, int spacedim, typename T>
1656  class PolicyWrapper : public Policy<dim, spacedim>
1657  {
1658  public:
1659  void
1661  {
1662  T::update_neighbors(tria);
1663  }
1664 
1665  void
1669  std::vector<unsigned int> & line_cell_count,
1670  std::vector<unsigned int> &quad_cell_count) override
1671  {
1672  T::delete_children(tria, cell, line_cell_count, quad_cell_count);
1673  }
1674 
1677  const bool check_for_distorted_cells) override
1678  {
1679  return T::execute_refinement(triangulation, check_for_distorted_cells);
1680  }
1681 
1682  void
1685  {
1686  T::prevent_distorted_boundary_cells(triangulation);
1687  }
1688 
1689  void
1692  {
1693  T::prepare_refinement_dim_dependent(triangulation);
1694  }
1695 
1696  bool
1698  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
1699  override
1700  {
1701  return T::template coarsening_allowed<dim, spacedim>(cell);
1702  }
1703 
1704  std::unique_ptr<Policy<dim, spacedim>>
1705  clone() override
1706  {
1707  return std::make_unique<PolicyWrapper<dim, spacedim, T>>();
1708  }
1709  };
1710 
1711 
1712 
1809  {
1821  template <int dim, int spacedim>
1822  static void
1825  const unsigned int level_objects,
1827  {
1828  using line_iterator =
1830 
1831  number_cache.n_levels = 0;
1832  if (level_objects > 0)
1833  // find the last level on which there are used cells
1834  for (unsigned int level = 0; level < level_objects; ++level)
1835  if (triangulation.begin(level) != triangulation.end(level))
1836  number_cache.n_levels = level + 1;
1837 
1838  // no cells at all?
1839  Assert(number_cache.n_levels > 0, ExcInternalError());
1840 
1841  //---------------------------------
1842  // update the number of lines on the different levels in the
1843  // cache
1844  number_cache.n_lines = 0;
1845  number_cache.n_active_lines = 0;
1846 
1847  // for 1d, lines have levels so take count the objects per
1848  // level and globally
1849  if (dim == 1)
1850  {
1851  number_cache.n_lines_level.resize(number_cache.n_levels);
1852  number_cache.n_active_lines_level.resize(number_cache.n_levels);
1853 
1854  for (unsigned int level = 0; level < number_cache.n_levels; ++level)
1855  {
1856  // count lines on this level
1857  number_cache.n_lines_level[level] = 0;
1858  number_cache.n_active_lines_level[level] = 0;
1859 
1860  line_iterator line = triangulation.begin_line(level),
1861  endc =
1862  (level == number_cache.n_levels - 1 ?
1863  line_iterator(triangulation.end_line()) :
1864  triangulation.begin_line(level + 1));
1865  for (; line != endc; ++line)
1866  {
1867  ++number_cache.n_lines_level[level];
1868  if (line->has_children() == false)
1869  ++number_cache.n_active_lines_level[level];
1870  }
1871 
1872  // update total number of lines
1873  number_cache.n_lines += number_cache.n_lines_level[level];
1874  number_cache.n_active_lines +=
1875  number_cache.n_active_lines_level[level];
1876  }
1877  }
1878  else
1879  {
1880  // for dim>1, there are no levels for lines
1881  number_cache.n_lines_level.clear();
1882  number_cache.n_active_lines_level.clear();
1883 
1884  line_iterator line = triangulation.begin_line(),
1885  endc = triangulation.end_line();
1886  for (; line != endc; ++line)
1887  {
1888  ++number_cache.n_lines;
1889  if (line->has_children() == false)
1890  ++number_cache.n_active_lines;
1891  }
1892  }
1893  }
1894 
1909  template <int dim, int spacedim>
1910  static void
1913  const unsigned int level_objects,
1915  {
1916  // update lines and n_levels in number_cache. since we don't
1917  // access any of these numbers, we can do this in the
1918  // background
1919  Threads::Task<void> update_lines = Threads::new_task(
1920  static_cast<
1921  void (*)(const Triangulation<dim, spacedim> &,
1922  const unsigned int,
1924  &compute_number_cache<dim, spacedim>),
1925  triangulation,
1926  level_objects,
1928  number_cache));
1929 
1930  using quad_iterator =
1932 
1933  //---------------------------------
1934  // update the number of quads on the different levels in the
1935  // cache
1936  number_cache.n_quads = 0;
1937  number_cache.n_active_quads = 0;
1938 
1939  // for 2d, quads have levels so take count the objects per
1940  // level and globally
1941  if (dim == 2)
1942  {
1943  // count the number of levels; the function we called above
1944  // on a separate Task for lines also does this and puts it into
1945  // number_cache.n_levels, but this datum may not yet be
1946  // available as we call the function on a separate task
1947  unsigned int n_levels = 0;
1948  if (level_objects > 0)
1949  // find the last level on which there are used cells
1950  for (unsigned int level = 0; level < level_objects; ++level)
1951  if (triangulation.begin(level) != triangulation.end(level))
1952  n_levels = level + 1;
1953 
1954  number_cache.n_quads_level.resize(n_levels);
1955  number_cache.n_active_quads_level.resize(n_levels);
1956 
1957  for (unsigned int level = 0; level < n_levels; ++level)
1958  {
1959  // count quads on this level
1960  number_cache.n_quads_level[level] = 0;
1961  number_cache.n_active_quads_level[level] = 0;
1962 
1963  quad_iterator quad = triangulation.begin_quad(level),
1964  endc =
1965  (level == n_levels - 1 ?
1966  quad_iterator(triangulation.end_quad()) :
1967  triangulation.begin_quad(level + 1));
1968  for (; quad != endc; ++quad)
1969  {
1970  ++number_cache.n_quads_level[level];
1971  if (quad->has_children() == false)
1972  ++number_cache.n_active_quads_level[level];
1973  }
1974 
1975  // update total number of quads
1976  number_cache.n_quads += number_cache.n_quads_level[level];
1977  number_cache.n_active_quads +=
1978  number_cache.n_active_quads_level[level];
1979  }
1980  }
1981  else
1982  {
1983  // for dim>2, there are no levels for quads
1984  number_cache.n_quads_level.clear();
1985  number_cache.n_active_quads_level.clear();
1986 
1987  quad_iterator quad = triangulation.begin_quad(),
1988  endc = triangulation.end_quad();
1989  for (; quad != endc; ++quad)
1990  {
1991  ++number_cache.n_quads;
1992  if (quad->has_children() == false)
1993  ++number_cache.n_active_quads;
1994  }
1995  }
1996 
1997  // wait for the background computation for lines
1998  update_lines.join();
1999  }
2000 
2016  template <int dim, int spacedim>
2017  static void
2020  const unsigned int level_objects,
2022  {
2023  // update quads, lines and n_levels in number_cache. since we
2024  // don't access any of these numbers, we can do this in the
2025  // background
2026  Threads::Task<void> update_quads_and_lines = Threads::new_task(
2027  static_cast<
2028  void (*)(const Triangulation<dim, spacedim> &,
2029  const unsigned int,
2031  &compute_number_cache<dim, spacedim>),
2032  triangulation,
2033  level_objects,
2035  number_cache));
2036 
2037  using hex_iterator =
2039 
2040  //---------------------------------
2041  // update the number of hexes on the different levels in the
2042  // cache
2043  number_cache.n_hexes = 0;
2044  number_cache.n_active_hexes = 0;
2045 
2046  // for 3d, hexes have levels so take count the objects per
2047  // level and globally
2048  if (dim == 3)
2049  {
2050  // count the number of levels; the function we called
2051  // above on a separate Task for quads (recursively, via
2052  // the lines function) also does this and puts it into
2053  // number_cache.n_levels, but this datum may not yet be
2054  // available as we call the function on a separate task
2055  unsigned int n_levels = 0;
2056  if (level_objects > 0)
2057  // find the last level on which there are used cells
2058  for (unsigned int level = 0; level < level_objects; ++level)
2059  if (triangulation.begin(level) != triangulation.end(level))
2060  n_levels = level + 1;
2061 
2062  number_cache.n_hexes_level.resize(n_levels);
2063  number_cache.n_active_hexes_level.resize(n_levels);
2064 
2065  for (unsigned int level = 0; level < n_levels; ++level)
2066  {
2067  // count hexes on this level
2068  number_cache.n_hexes_level[level] = 0;
2069  number_cache.n_active_hexes_level[level] = 0;
2070 
2071  hex_iterator hex = triangulation.begin_hex(level),
2072  endc = (level == n_levels - 1 ?
2073  hex_iterator(triangulation.end_hex()) :
2074  triangulation.begin_hex(level + 1));
2075  for (; hex != endc; ++hex)
2076  {
2077  ++number_cache.n_hexes_level[level];
2078  if (hex->has_children() == false)
2079  ++number_cache.n_active_hexes_level[level];
2080  }
2081 
2082  // update total number of hexes
2083  number_cache.n_hexes += number_cache.n_hexes_level[level];
2084  number_cache.n_active_hexes +=
2085  number_cache.n_active_hexes_level[level];
2086  }
2087  }
2088  else
2089  {
2090  // for dim>3, there are no levels for hexes
2091  number_cache.n_hexes_level.clear();
2092  number_cache.n_active_hexes_level.clear();
2093 
2094  hex_iterator hex = triangulation.begin_hex(),
2095  endc = triangulation.end_hex();
2096  for (; hex != endc; ++hex)
2097  {
2098  ++number_cache.n_hexes;
2099  if (hex->has_children() == false)
2100  ++number_cache.n_active_hexes;
2101  }
2102  }
2103 
2104  // wait for the background computation for quads
2105  update_quads_and_lines.join();
2106  }
2107 
2108 
2109 
2110  template <int spacedim>
2111  static void
2113  {}
2114 
2115 
2116  template <int dim, int spacedim>
2117  static void
2119  {
2120  // each face can be neighbored on two sides
2121  // by cells. according to the face's
2122  // intrinsic normal we define the left
2123  // neighbor as the one for which the face
2124  // normal points outward, and store that
2125  // one first; the second one is then
2126  // the right neighbor for which the
2127  // face normal points inward. This
2128  // information depends on the type of cell
2129  // and local number of face for the
2130  // 'standard ordering and orientation' of
2131  // faces and then on the face_orientation
2132  // information for the real mesh. Set up a
2133  // table to have fast access to those
2134  // offsets (0 for left and 1 for
2135  // right). Some of the values are invalid
2136  // as they reference too large face
2137  // numbers, but we just leave them at a
2138  // zero value.
2139  //
2140  // Note, that in 2d for lines as faces the
2141  // normal direction given in the
2142  // GeometryInfo class is not consistent. We
2143  // thus define here that the normal for a
2144  // line points to the right if the line
2145  // points upwards.
2146  //
2147  // There is one more point to
2148  // consider, however: if we have
2149  // dim<spacedim, then we may have
2150  // cases where cells are
2151  // inverted. In effect, both
2152  // cells think they are the left
2153  // neighbor of an edge, for
2154  // example, which leads us to
2155  // forget neighborship
2156  // information (a case that shows
2157  // this is
2158  // codim_one/hanging_nodes_02). We
2159  // store whether a cell is
2160  // inverted using the
2161  // direction_flag, so if a cell
2162  // has a false direction_flag,
2163  // then we need to invert our
2164  // selection whether we are a
2165  // left or right neighbor in all
2166  // following computations.
2167  //
2168  // first index: dimension (minus 2)
2169  // second index: local face index
2170  // third index: face_orientation (false and true)
2171  static const unsigned int left_right_offset[2][6][2] = {
2172  // quadrilateral
2173  {{0, 1}, // face 0, face_orientation = false and true
2174  {1, 0}, // face 1, face_orientation = false and true
2175  {1, 0}, // face 2, face_orientation = false and true
2176  {0, 1}, // face 3, face_orientation = false and true
2177  {0, 0}, // face 4, invalid face
2178  {0, 0}}, // face 5, invalid face
2179  // hexahedron
2180  {{0, 1}, {1, 0}, {0, 1}, {1, 0}, {0, 1}, {1, 0}}};
2181 
2182  // now create a vector of the two active
2183  // neighbors (left and right) for each face
2184  // and fill it by looping over all cells. For
2185  // cases with anisotropic refinement and more
2186  // then one cell neighboring at a given side
2187  // of the face we will automatically get the
2188  // active one on the highest level as we loop
2189  // over cells from lower levels first.
2190  const typename Triangulation<dim, spacedim>::cell_iterator dummy;
2191  std::vector<typename Triangulation<dim, spacedim>::cell_iterator>
2192  adjacent_cells(2 * triangulation.n_raw_faces(), dummy);
2193 
2194  for (const auto &cell : triangulation.cell_iterators())
2195  for (auto f : cell->face_indices())
2196  {
2197  const typename Triangulation<dim, spacedim>::face_iterator face =
2198  cell->face(f);
2199 
2200  const unsigned int offset =
2201  (cell->direction_flag() ?
2202  left_right_offset[dim - 2][f][cell->face_orientation(f)] :
2203  1 -
2204  left_right_offset[dim - 2][f][cell->face_orientation(f)]);
2205 
2206  adjacent_cells[2 * face->index() + offset] = cell;
2207 
2208  // if this cell is not refined, but the
2209  // face is, then we'll have to set our
2210  // cell as neighbor for the child faces
2211  // as well. Fortunately the normal
2212  // orientation of children will be just
2213  // the same.
2214  if (dim == 2)
2215  {
2216  if (cell->is_active() && face->has_children())
2217  {
2218  adjacent_cells[2 * face->child(0)->index() + offset] =
2219  cell;
2220  adjacent_cells[2 * face->child(1)->index() + offset] =
2221  cell;
2222  }
2223  }
2224  else // -> dim == 3
2225  {
2226  // We need the same as in 2d
2227  // here. Furthermore, if the face is
2228  // refined with cut_x or cut_y then
2229  // those children again in the other
2230  // direction, and if this cell is
2231  // refined isotropically (along the
2232  // face) then the neighbor will
2233  // (probably) be refined as cut_x or
2234  // cut_y along the face. For those
2235  // neighboring children cells, their
2236  // neighbor will be the current,
2237  // inactive cell, as our children are
2238  // too fine to be neighbors. Catch that
2239  // case by also acting on inactive
2240  // cells with isotropic refinement
2241  // along the face. If the situation
2242  // described is not present, the data
2243  // will be overwritten later on when we
2244  // visit cells on finer levels, so no
2245  // harm will be done.
2246  if (face->has_children() &&
2247  (cell->is_active() ||
2249  cell->refinement_case(), f) ==
2250  RefinementCase<dim - 1>::isotropic_refinement))
2251  {
2252  for (unsigned int c = 0; c < face->n_children(); ++c)
2253  adjacent_cells[2 * face->child(c)->index() + offset] =
2254  cell;
2255  if (face->child(0)->has_children())
2256  {
2257  adjacent_cells[2 * face->child(0)->child(0)->index() +
2258  offset] = cell;
2259  adjacent_cells[2 * face->child(0)->child(1)->index() +
2260  offset] = cell;
2261  }
2262  if (face->child(1)->has_children())
2263  {
2264  adjacent_cells[2 * face->child(1)->child(0)->index() +
2265  offset] = cell;
2266  adjacent_cells[2 * face->child(1)->child(1)->index() +
2267  offset] = cell;
2268  }
2269  } // if cell active and face refined
2270  } // else -> dim==3
2271  } // for all faces of all cells
2272 
2273  // now loop again over all cells and set the
2274  // corresponding neighbor cell. Note, that we
2275  // have to use the opposite of the
2276  // left_right_offset in this case as we want
2277  // the offset of the neighbor, not our own.
2278  for (const auto &cell : triangulation.cell_iterators())
2279  for (auto f : cell->face_indices())
2280  {
2281  const unsigned int offset =
2282  (cell->direction_flag() ?
2283  left_right_offset[dim - 2][f][cell->face_orientation(f)] :
2284  1 -
2285  left_right_offset[dim - 2][f][cell->face_orientation(f)]);
2286  cell->set_neighbor(
2287  f, adjacent_cells[2 * cell->face(f)->index() + 1 - offset]);
2288  }
2289  }
2290 
2291 
2295  template <int dim, int spacedim>
2296  static void
2298  const std::vector<CellData<dim>> & cells,
2299  const SubCellData & subcelldata,
2301  {
2302  AssertThrow(vertices.size() > 0, ExcMessage("No vertices given"));
2303  AssertThrow(cells.size() > 0, ExcMessage("No cells given"));
2304 
2305  // Check that all cells have positive volume.
2306 #ifndef _MSC_VER
2307  // TODO: The following code does not compile with MSVC. Find a way
2308  // around it
2309  if (dim == spacedim)
2310  for (unsigned int cell_no = 0; cell_no < cells.size(); ++cell_no)
2311  {
2312  // If we should check for distorted cells, then we permit them
2313  // to exist. If a cell has negative measure, then it must be
2314  // distorted (the converse is not necessarily true); hence
2315  // throw an exception if no such cells should exist.
2317  {
2318  const double cell_measure = GridTools::cell_measure<spacedim>(
2319  vertices,
2320  ArrayView<const unsigned int>(cells[cell_no].vertices));
2322  }
2323  }
2324 #endif
2325 
2326  // clear old content
2327  tria.levels.clear();
2328  tria.levels.push_back(
2329  std::make_unique<
2331 
2332  if (dim > 1)
2333  tria.faces = std::make_unique<
2335 
2336  // copy vertices
2338  tria.vertices_used.assign(vertices.size(), true);
2339 
2340  // compute connectivity
2341  const auto connectivity = build_connectivity<unsigned int>(cells);
2342  const unsigned int n_cell = cells.size();
2343 
2344  // TriaObjects: lines
2345  if (dim >= 2)
2346  {
2347  auto &lines_0 = tria.faces->lines; // data structure to be filled
2348 
2349  // get connectivity between quads and lines
2350  const auto & crs = connectivity.entity_to_entities(1, 0);
2351  const unsigned int n_lines = crs.ptr.size() - 1;
2352 
2353  // allocate memory
2354  reserve_space_(lines_0, n_lines);
2355 
2356  // loop over lines
2357  for (unsigned int line = 0; line < n_lines; ++line)
2358  for (unsigned int i = crs.ptr[line], j = 0; i < crs.ptr[line + 1];
2359  ++i, ++j)
2360  lines_0.cells[line * GeometryInfo<1>::faces_per_cell + j] =
2361  crs.col[i]; // set vertex indices
2362  }
2363 
2364  // TriaObjects: quads
2365  if (dim == 3)
2366  {
2367  auto &quads_0 = tria.faces->quads; // data structures to be filled
2368  auto &faces = *tria.faces;
2369 
2370  // get connectivity between quads and lines
2371  const auto & crs = connectivity.entity_to_entities(2, 1);
2372  const unsigned int n_quads = crs.ptr.size() - 1;
2373 
2374  // allocate memory
2375  reserve_space_(quads_0, n_quads);
2376  reserve_space_(faces, 2 /*structdim*/, n_quads);
2377 
2378  // loop over all quads -> entity type, line indices/orientations
2379  for (unsigned int q = 0, k = 0; q < n_quads; ++q)
2380  {
2381  // set entity type of quads
2382  faces.quad_reference_cell[q] = connectivity.entity_types(2)[q];
2383 
2384  // loop over all its lines
2385  for (unsigned int i = crs.ptr[q], j = 0; i < crs.ptr[q + 1];
2386  ++i, ++j, ++k)
2387  {
2388  // set line index
2389  quads_0.cells[q * GeometryInfo<2>::faces_per_cell + j] =
2390  crs.col[i];
2391 
2392  // set line orientations
2393  faces.quads_line_orientations
2395  connectivity.entity_orientations(1)[k];
2396  }
2397  }
2398  }
2399 
2400  // TriaObjects/TriaLevel: cell
2401  {
2402  auto &cells_0 = tria.levels[0]->cells; // data structure to be filled
2403  auto &level = *tria.levels[0];
2404 
2405  // get connectivity between cells/faces and cells/cells
2406  const auto &crs = connectivity.entity_to_entities(dim, dim - 1);
2407  const auto &nei = connectivity.entity_to_entities(dim, dim);
2408 
2409  // in 2D optional: since in in pure QUAD meshes same line
2410  // orientations can be guaranteed
2411  const bool orientation_needed =
2412  dim == 3 ||
2413  (dim == 2 &&
2414  std::any_of(connectivity.entity_orientations(1).begin(),
2415  connectivity.entity_orientations(1).end(),
2416  [](const auto &i) { return i == 0; }));
2417 
2418  // allocate memory
2419  reserve_space_(cells_0, n_cell);
2420  reserve_space_(level, spacedim, n_cell, orientation_needed);
2421 
2422  // loop over all cells
2423  for (unsigned int cell = 0; cell < n_cell; ++cell)
2424  {
2425  // set material ids
2426  cells_0.boundary_or_material_id[cell].material_id =
2427  cells[cell].material_id;
2428 
2429  // set manifold ids
2430  cells_0.manifold_id[cell] = cells[cell].manifold_id;
2431 
2432  // set entity types
2433  level.reference_cell[cell] = connectivity.entity_types(dim)[cell];
2434 
2435  // loop over faces
2436  for (unsigned int i = crs.ptr[cell], j = 0; i < crs.ptr[cell + 1];
2437  ++i, ++j)
2438  {
2439  // set neighbor if not at boundary
2440  if (nei.col[i] != static_cast<unsigned int>(-1))
2441  level.neighbors[cell * GeometryInfo<dim>::faces_per_cell +
2442  j] = {0, nei.col[i]};
2443 
2444  // set face indices
2445  cells_0.cells[cell * GeometryInfo<dim>::faces_per_cell + j] =
2446  crs.col[i];
2447 
2448  // set face orientation if needed
2449  if (orientation_needed)
2450  {
2451  level.face_orientations
2452  [cell * GeometryInfo<dim>::faces_per_cell + j] =
2453  connectivity.entity_orientations(dim - 1)[i];
2454  }
2455  }
2456  }
2457  }
2458 
2459  // TriaFaces: boundary id of boundary faces
2460  if (dim > 1)
2461  {
2462  auto &bids_face = dim == 3 ?
2463  tria.faces->quads.boundary_or_material_id :
2464  tria.faces->lines.boundary_or_material_id;
2465 
2466  // count number of cells a face is belonging to
2467  std::vector<unsigned int> count(bids_face.size(), 0);
2468 
2469  // get connectivity between cells/faces
2470  const auto &crs = connectivity.entity_to_entities(dim, dim - 1);
2471 
2472  // count how many cells are adjacent to the same face
2473  for (unsigned int cell = 0; cell < cells.size(); ++cell)
2474  for (unsigned int i = crs.ptr[cell]; i < crs.ptr[cell + 1]; ++i)
2475  count[crs.col[i]]++;
2476 
2477  // loop over all faces
2478  for (unsigned int face = 0; face < count.size(); ++face)
2479  {
2480  if (count[face] != 1) // inner face
2481  continue;
2482 
2483  // boundary faces ...
2484  bids_face[face].boundary_id = 0;
2485 
2486  if (dim != 3)
2487  continue;
2488 
2489  // ... and the lines of quads in 3D
2490  const auto &crs = connectivity.entity_to_entities(2, 1);
2491  for (unsigned int i = crs.ptr[face]; i < crs.ptr[face + 1]; ++i)
2492  tria.faces->lines.boundary_or_material_id[crs.col[i]]
2493  .boundary_id = 0;
2494  }
2495  }
2496  else // 1D
2497  {
2498  static const unsigned int t_tba = static_cast<unsigned int>(-1);
2499  static const unsigned int t_inner = static_cast<unsigned int>(-2);
2500 
2501  std::vector<unsigned int> type(vertices.size(), t_tba);
2502 
2503  const auto &crs = connectivity.entity_to_entities(1, 0);
2504 
2505  for (unsigned int cell = 0; cell < cells.size(); ++cell)
2506  for (unsigned int i = crs.ptr[cell], j = 0; i < crs.ptr[cell + 1];
2507  ++i, ++j)
2508  if (type[crs.col[i]] != t_inner)
2509  type[crs.col[i]] = type[crs.col[i]] == t_tba ? j : t_inner;
2510 
2511  for (unsigned int face = 0; face < type.size(); ++face)
2512  {
2513  // note: we also treat manifolds here!?
2516  if (type[face] != t_inner && type[face] != t_tba)
2517  (*tria.vertex_to_boundary_id_map_1d)[face] = type[face];
2518  }
2519  }
2520 
2521  // SubCellData: line
2522  if (dim >= 2)
2523  process_subcelldata(connectivity.entity_to_entities(1, 0),
2524  tria.faces->lines,
2525  subcelldata.boundary_lines,
2526  vertices);
2527 
2528  // SubCellData: quad
2529  if (dim == 3)
2530  process_subcelldata(connectivity.entity_to_entities(2, 0),
2531  tria.faces->quads,
2532  subcelldata.boundary_quads,
2533  vertices);
2534  }
2535 
2536 
2537  template <int structdim, int spacedim, typename T>
2538  static void
2540  const CRS<T> & crs,
2541  TriaObjects & obj,
2542  const std::vector<CellData<structdim>> &boundary_objects_in,
2543  const std::vector<Point<spacedim>> & vertex_locations)
2544  {
2545  AssertDimension(obj.structdim, structdim);
2546 
2547  if (boundary_objects_in.size() == 0)
2548  return; // empty subcelldata -> nothing to do
2549 
2550  // pre-sort subcelldata
2551  auto boundary_objects = boundary_objects_in;
2552 
2553  // ... sort vertices
2554  for (auto &boundary_object : boundary_objects)
2555  std::sort(boundary_object.vertices.begin(),
2556  boundary_object.vertices.end());
2557 
2558  // ... sort cells
2559  std::sort(boundary_objects.begin(),
2560  boundary_objects.end(),
2561  [](const auto &a, const auto &b) {
2562  return a.vertices < b.vertices;
2563  });
2564 
2565  unsigned int counter = 0;
2566 
2567  std::vector<unsigned int> key;
2569 
2570  for (unsigned int o = 0; o < obj.n_objects(); ++o)
2571  {
2572  auto &boundary_id = obj.boundary_or_material_id[o].boundary_id;
2573  auto &manifold_id = obj.manifold_id[o];
2574 
2575  // assert that object has not been visited yet and its value
2576  // has not been modified yet
2577  AssertThrow(boundary_id == 0 ||
2579  ExcNotImplemented());
2581  ExcNotImplemented());
2582 
2583  // create key
2584  key.assign(crs.col.data() + crs.ptr[o],
2585  crs.col.data() + crs.ptr[o + 1]);
2586  std::sort(key.begin(), key.end());
2587 
2588  // is subcelldata provided? -> binary search
2589  const auto subcell_object =
2590  std::lower_bound(boundary_objects.begin(),
2591  boundary_objects.end(),
2592  key,
2593  [&](const auto &cell, const auto &key) {
2594  return cell.vertices < key;
2595  });
2596 
2597  // no subcelldata provided for this object
2598  if (subcell_object == boundary_objects.end() ||
2599  subcell_object->vertices != key)
2600  continue;
2601 
2602  counter++;
2603 
2604  // set manifold id
2605  manifold_id = subcell_object->manifold_id;
2606 
2607  // set boundary id
2608  if (subcell_object->boundary_id !=
2610  {
2611  (void)vertex_locations;
2612  AssertThrow(
2614  ExcMessage(
2615  "The input arguments for creating a triangulation "
2616  "specified a boundary id for an internal face. This "
2617  "is not allowed."
2618  "\n\n"
2619  "The object in question has vertex indices " +
2620  [subcell_object]() {
2621  std::string s;
2622  for (const auto v : subcell_object->vertices)
2623  s += std::to_string(v) + ',';
2624  return s;
2625  }() +
2626  " which are located at positions " +
2627  [vertex_locations, subcell_object]() {
2628  std::ostringstream s;
2629  for (const auto v : subcell_object->vertices)
2630  s << '(' << vertex_locations[v] << ')';
2631  return s.str();
2632  }() +
2633  "."));
2634  boundary_id = subcell_object->boundary_id;
2635  }
2636  }
2637 
2638  // make sure that all subcelldata entries have been processed
2639  // TODO: this is not guaranteed, why?
2640  // AssertDimension(counter, boundary_objects_in.size());
2641  }
2642 
2643 
2644 
2645  static void
2647  const unsigned structdim,
2648  const unsigned int size)
2649  {
2650  const unsigned int dim = faces.dim;
2651 
2652  const unsigned int max_faces_per_cell = 2 * structdim;
2653 
2654  if (dim == 3 && structdim == 2)
2655  {
2656  // quad entity types
2657  faces.quad_reference_cell.assign(size,
2659 
2660  // quad line orientations
2661  faces.quads_line_orientations.assign(size * max_faces_per_cell, -1);
2662  }
2663  }
2664 
2665 
2666 
2667  static void
2669  const unsigned int spacedim,
2670  const unsigned int size,
2671  const bool orientation_needed)
2672  {
2673  const unsigned int dim = level.dim;
2674 
2675  const unsigned int max_faces_per_cell = 2 * dim;
2676 
2677  level.active_cell_indices.assign(size, -1);
2678  level.subdomain_ids.assign(size, 0);
2679  level.level_subdomain_ids.assign(size, 0);
2680 
2681  level.refine_flags.assign(size, 0u);
2682  level.coarsen_flags.assign(size, false);
2683 
2684  level.parents.assign((size + 1) / 2, -1);
2685 
2686  if (dim < spacedim)
2687  level.direction_flags.assign(size, true);
2688 
2689  level.neighbors.assign(size * max_faces_per_cell, {-1, -1});
2690 
2691  level.reference_cell.assign(size, ::ReferenceCells::Invalid);
2692 
2693  if (orientation_needed)
2694  level.face_orientations.assign(size * max_faces_per_cell, -1);
2695 
2696  level.global_active_cell_indices.assign(size,
2698  level.global_level_cell_indices.assign(size,
2700  }
2701 
2702 
2703 
2704  static void
2705  reserve_space_(TriaObjects &obj, const unsigned int size)
2706  {
2707  const unsigned int structdim = obj.structdim;
2708 
2709  const unsigned int max_children_per_cell = 1 << structdim;
2710  const unsigned int max_faces_per_cell = 2 * structdim;
2711 
2712  obj.used.assign(size, true);
2713  obj.boundary_or_material_id.assign(
2714  size,
2716  BoundaryOrMaterialId());
2717  obj.manifold_id.assign(size, -1);
2718  obj.user_flags.assign(size, false);
2719  obj.user_data.resize(size);
2720 
2721  if (structdim > 1) // TODO: why?
2722  obj.refinement_cases.assign(size, 0);
2723 
2724  obj.children.assign(max_children_per_cell / 2 * size, -1);
2725 
2726  obj.cells.assign(max_faces_per_cell * size, -1);
2727 
2728  if (structdim <= 2)
2729  {
2730  obj.next_free_single = size - 1;
2731  obj.next_free_pair = 0;
2732  obj.reverse_order_next_free_single = true;
2733  }
2734  else
2735  {
2736  obj.next_free_single = obj.next_free_pair = 0;
2737  }
2738  }
2739 
2740 
2756  template <int spacedim>
2757  static void
2760  std::vector<unsigned int> &,
2761  std::vector<unsigned int> &)
2762  {
2763  const unsigned int dim = 1;
2764 
2765  // first we need to reset the
2766  // neighbor pointers of the
2767  // neighbors of this cell's
2768  // children to this cell. This is
2769  // different for one dimension,
2770  // since there neighbors can have a
2771  // refinement level differing from
2772  // that of this cell's children by
2773  // more than one level.
2774 
2775  Assert(!cell->child(0)->has_children() &&
2776  !cell->child(1)->has_children(),
2777  ExcInternalError());
2778 
2779  // first do it for the cells to the
2780  // left
2781  if (cell->neighbor(0).state() == IteratorState::valid)
2782  if (cell->neighbor(0)->has_children())
2783  {
2785  cell->neighbor(0);
2786  Assert(neighbor->level() == cell->level(), ExcInternalError());
2787 
2788  // right child
2789  neighbor = neighbor->child(1);
2790  while (true)
2791  {
2792  Assert(neighbor->neighbor(1) == cell->child(0),
2793  ExcInternalError());
2794  neighbor->set_neighbor(1, cell);
2795 
2796  // move on to further
2797  // children on the
2798  // boundary between this
2799  // cell and its neighbor
2800  if (neighbor->has_children())
2801  neighbor = neighbor->child(1);
2802  else
2803  break;
2804  }
2805  }
2806 
2807  // now do it for the cells to the
2808  // left
2809  if (cell->neighbor(1).state() == IteratorState::valid)
2810  if (cell->neighbor(1)->has_children())
2811  {
2813  cell->neighbor(1);
2814  Assert(neighbor->level() == cell->level(), ExcInternalError());
2815 
2816  // left child
2817  neighbor = neighbor->child(0);
2818  while (true)
2819  {
2820  Assert(neighbor->neighbor(0) == cell->child(1),
2821  ExcInternalError());
2822  neighbor->set_neighbor(0, cell);
2823 
2824  // move on to further
2825  // children on the
2826  // boundary between this
2827  // cell and its neighbor
2828  if (neighbor->has_children())
2829  neighbor = neighbor->child(0);
2830  else
2831  break;
2832  }
2833  }
2834 
2835 
2836  // delete the vertex which will not
2837  // be needed anymore. This vertex
2838  // is the second of the first child
2839  triangulation.vertices_used[cell->child(0)->vertex_index(1)] = false;
2840 
2841  // invalidate children. clear user
2842  // pointers, to avoid that they may
2843  // appear at unwanted places later
2844  // on...
2845  for (unsigned int child = 0; child < cell->n_children(); ++child)
2846  {
2847  cell->child(child)->clear_user_data();
2848  cell->child(child)->clear_user_flag();
2849  cell->child(child)->clear_used_flag();
2850  }
2851 
2852 
2853  // delete pointer to children
2854  cell->clear_children();
2855  cell->clear_user_flag();
2856  }
2857 
2858 
2859 
2860  template <int spacedim>
2861  static void
2864  std::vector<unsigned int> &line_cell_count,
2865  std::vector<unsigned int> &)
2866  {
2867  const unsigned int dim = 2;
2868  const RefinementCase<dim> ref_case = cell->refinement_case();
2869 
2870  Assert(line_cell_count.size() == triangulation.n_raw_lines(),
2871  ExcInternalError());
2872 
2873  // vectors to hold all lines which
2874  // may be deleted
2875  std::vector<typename Triangulation<dim, spacedim>::line_iterator>
2876  lines_to_delete(0);
2877 
2878  lines_to_delete.reserve(4 * 2 + 4);
2879 
2880  // now we decrease the counters for
2881  // lines contained in the child
2882  // cells
2883  for (unsigned int c = 0; c < cell->n_children(); ++c)
2884  {
2886  cell->child(c);
2887  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
2888  --line_cell_count[child->line_index(l)];
2889  }
2890 
2891 
2892  // delete the vertex which will not
2893  // be needed anymore. This vertex
2894  // is the second of the second line
2895  // of the first child, if the cell
2896  // is refined with cut_xy, else there
2897  // is no inner vertex.
2898  // additionally delete unneeded inner
2899  // lines
2900  if (ref_case == RefinementCase<dim>::cut_xy)
2901  {
2903  .vertices_used[cell->child(0)->line(1)->vertex_index(1)] = false;
2904 
2905  lines_to_delete.push_back(cell->child(0)->line(1));
2906  lines_to_delete.push_back(cell->child(0)->line(3));
2907  lines_to_delete.push_back(cell->child(3)->line(0));
2908  lines_to_delete.push_back(cell->child(3)->line(2));
2909  }
2910  else
2911  {
2912  unsigned int inner_face_no =
2913  ref_case == RefinementCase<dim>::cut_x ? 1 : 3;
2914 
2915  // the inner line will not be
2916  // used any more
2917  lines_to_delete.push_back(cell->child(0)->line(inner_face_no));
2918  }
2919 
2920  // invalidate children
2921  for (unsigned int child = 0; child < cell->n_children(); ++child)
2922  {
2923  cell->child(child)->clear_user_data();
2924  cell->child(child)->clear_user_flag();
2925  cell->child(child)->clear_used_flag();
2926  }
2927 
2928 
2929  // delete pointer to children
2930  cell->clear_children();
2931  cell->clear_refinement_case();
2932  cell->clear_user_flag();
2933 
2934  // look at the refinement of outer
2935  // lines. if nobody needs those
2936  // anymore we can add them to the
2937  // list of lines to be deleted.
2938  for (unsigned int line_no = 0;
2939  line_no < GeometryInfo<dim>::lines_per_cell;
2940  ++line_no)
2941  {
2943  cell->line(line_no);
2944 
2945  if (line->has_children())
2946  {
2947  // if one of the cell counters is
2948  // zero, the other has to be as well
2949 
2950  Assert((line_cell_count[line->child_index(0)] == 0 &&
2951  line_cell_count[line->child_index(1)] == 0) ||
2952  (line_cell_count[line->child_index(0)] > 0 &&
2953  line_cell_count[line->child_index(1)] > 0),
2954  ExcInternalError());
2955 
2956  if (line_cell_count[line->child_index(0)] == 0)
2957  {
2958  for (unsigned int c = 0; c < 2; ++c)
2959  Assert(!line->child(c)->has_children(),
2960  ExcInternalError());
2961 
2962  // we may delete the line's
2963  // children and the middle vertex
2964  // as no cell references them
2965  // anymore
2967  .vertices_used[line->child(0)->vertex_index(1)] = false;
2968 
2969  lines_to_delete.push_back(line->child(0));
2970  lines_to_delete.push_back(line->child(1));
2971 
2972  line->clear_children();
2973  }
2974  }
2975  }
2976 
2977  // finally, delete unneeded lines
2978 
2979  // clear user pointers, to avoid that
2980  // they may appear at unwanted places
2981  // later on...
2982  // same for user flags, then finally
2983  // delete the lines
2984  typename std::vector<
2986  line = lines_to_delete.begin(),
2987  endline = lines_to_delete.end();
2988  for (; line != endline; ++line)
2989  {
2990  (*line)->clear_user_data();
2991  (*line)->clear_user_flag();
2992  (*line)->clear_used_flag();
2993  }
2994  }
2995 
2996 
2997 
2998  template <int spacedim>
2999  static void
3002  std::vector<unsigned int> &line_cell_count,
3003  std::vector<unsigned int> &quad_cell_count)
3004  {
3005  const unsigned int dim = 3;
3006 
3007  Assert(line_cell_count.size() == triangulation.n_raw_lines(),
3008  ExcInternalError());
3009  Assert(quad_cell_count.size() == triangulation.n_raw_quads(),
3010  ExcInternalError());
3011 
3012  // first of all, we store the RefineCase of
3013  // this cell
3014  const RefinementCase<dim> ref_case = cell->refinement_case();
3015  // vectors to hold all lines and quads which
3016  // may be deleted
3017  std::vector<typename Triangulation<dim, spacedim>::line_iterator>
3018  lines_to_delete(0);
3019  std::vector<typename Triangulation<dim, spacedim>::quad_iterator>
3020  quads_to_delete(0);
3021 
3022  lines_to_delete.reserve(12 * 2 + 6 * 4 + 6);
3023  quads_to_delete.reserve(6 * 4 + 12);
3024 
3025  // now we decrease the counters for lines and
3026  // quads contained in the child cells
3027  for (unsigned int c = 0; c < cell->n_children(); ++c)
3028  {
3030  cell->child(c);
3031  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
3032  --line_cell_count[child->line_index(l)];
3033  for (auto f : GeometryInfo<dim>::face_indices())
3034  --quad_cell_count[child->quad_index(f)];
3035  }
3036 
3037  //-------------------------------------
3038  // delete interior quads and lines and the
3039  // interior vertex, depending on the
3040  // refinement case of the cell
3041  //
3042  // for append quads and lines: only append
3043  // them to the list of objects to be deleted
3044 
3045  switch (ref_case)
3046  {
3048  quads_to_delete.push_back(cell->child(0)->face(1));
3049  break;
3051  quads_to_delete.push_back(cell->child(0)->face(3));
3052  break;
3054  quads_to_delete.push_back(cell->child(0)->face(5));
3055  break;
3057  quads_to_delete.push_back(cell->child(0)->face(1));
3058  quads_to_delete.push_back(cell->child(0)->face(3));
3059  quads_to_delete.push_back(cell->child(3)->face(0));
3060  quads_to_delete.push_back(cell->child(3)->face(2));
3061 
3062  lines_to_delete.push_back(cell->child(0)->line(11));
3063  break;
3065  quads_to_delete.push_back(cell->child(0)->face(1));
3066  quads_to_delete.push_back(cell->child(0)->face(5));
3067  quads_to_delete.push_back(cell->child(3)->face(0));
3068  quads_to_delete.push_back(cell->child(3)->face(4));
3069 
3070  lines_to_delete.push_back(cell->child(0)->line(5));
3071  break;
3073  quads_to_delete.push_back(cell->child(0)->face(3));
3074  quads_to_delete.push_back(cell->child(0)->face(5));
3075  quads_to_delete.push_back(cell->child(3)->face(2));
3076  quads_to_delete.push_back(cell->child(3)->face(4));
3077 
3078  lines_to_delete.push_back(cell->child(0)->line(7));
3079  break;
3081  quads_to_delete.push_back(cell->child(0)->face(1));
3082  quads_to_delete.push_back(cell->child(2)->face(1));
3083  quads_to_delete.push_back(cell->child(4)->face(1));
3084  quads_to_delete.push_back(cell->child(6)->face(1));
3085 
3086  quads_to_delete.push_back(cell->child(0)->face(3));
3087  quads_to_delete.push_back(cell->child(1)->face(3));
3088  quads_to_delete.push_back(cell->child(4)->face(3));
3089  quads_to_delete.push_back(cell->child(5)->face(3));
3090 
3091  quads_to_delete.push_back(cell->child(0)->face(5));
3092  quads_to_delete.push_back(cell->child(1)->face(5));
3093  quads_to_delete.push_back(cell->child(2)->face(5));
3094  quads_to_delete.push_back(cell->child(3)->face(5));
3095 
3096  lines_to_delete.push_back(cell->child(0)->line(5));
3097  lines_to_delete.push_back(cell->child(0)->line(7));
3098  lines_to_delete.push_back(cell->child(0)->line(11));
3099  lines_to_delete.push_back(cell->child(7)->line(0));
3100  lines_to_delete.push_back(cell->child(7)->line(2));
3101  lines_to_delete.push_back(cell->child(7)->line(8));
3102  // delete the vertex which will not
3103  // be needed anymore. This vertex
3104  // is the vertex at the heart of
3105  // this cell, which is the sixth of
3106  // the first child
3107  triangulation.vertices_used[cell->child(0)->vertex_index(7)] =
3108  false;
3109  break;
3110  default:
3111  // only remaining case is
3112  // no_refinement, thus an error
3113  Assert(false, ExcInternalError());
3114  break;
3115  }
3116 
3117 
3118  // invalidate children
3119  for (unsigned int child = 0; child < cell->n_children(); ++child)
3120  {
3121  cell->child(child)->clear_user_data();
3122  cell->child(child)->clear_user_flag();
3123 
3124  for (auto f : GeometryInfo<dim>::face_indices())
3125  {
3126  // set flags denoting deviations from
3127  // standard orientation of faces back
3128  // to initialization values
3129  cell->child(child)->set_face_orientation(f, true);
3130  cell->child(child)->set_face_flip(f, false);
3131  cell->child(child)->set_face_rotation(f, false);
3132  }
3133 
3134  cell->child(child)->clear_used_flag();
3135  }
3136 
3137 
3138  // delete pointer to children
3139  cell->clear_children();
3140  cell->clear_refinement_case();
3141  cell->clear_user_flag();
3142 
3143  // so far we only looked at inner quads,
3144  // lines and vertices. Now we have to
3145  // consider outer ones as well. here, we have
3146  // to check, whether there are other cells
3147  // still needing these objects. otherwise we
3148  // can delete them. first for quads (and
3149  // their inner lines).
3150 
3151  for (const unsigned int quad_no : GeometryInfo<dim>::face_indices())
3152  {
3154  cell->face(quad_no);
3155 
3156  Assert(
3157  (GeometryInfo<dim>::face_refinement_case(ref_case, quad_no) &&
3158  quad->has_children()) ||
3159  GeometryInfo<dim>::face_refinement_case(ref_case, quad_no) ==
3161  ExcInternalError());
3162 
3163  switch (quad->refinement_case())
3164  {
3165  case RefinementCase<dim - 1>::no_refinement:
3166  // nothing to do as the quad
3167  // is not refined
3168  break;
3169  case RefinementCase<dim - 1>::cut_x:
3170  case RefinementCase<dim - 1>::cut_y:
3171  {
3172  // if one of the cell counters is
3173  // zero, the other has to be as
3174  // well
3175  Assert((quad_cell_count[quad->child_index(0)] == 0 &&
3176  quad_cell_count[quad->child_index(1)] == 0) ||
3177  (quad_cell_count[quad->child_index(0)] > 0 &&
3178  quad_cell_count[quad->child_index(1)] > 0),
3179  ExcInternalError());
3180  // it might be, that the quad is
3181  // refined twice anisotropically,
3182  // first check, whether we may
3183  // delete possible grand_children
3184  unsigned int deleted_grandchildren = 0;
3185  unsigned int number_of_child_refinements = 0;
3186 
3187  for (unsigned int c = 0; c < 2; ++c)
3188  if (quad->child(c)->has_children())
3189  {
3190  ++number_of_child_refinements;
3191  // if one of the cell counters is
3192  // zero, the other has to be as
3193  // well
3194  Assert(
3195  (quad_cell_count[quad->child(c)->child_index(0)] ==
3196  0 &&
3197  quad_cell_count[quad->child(c)->child_index(1)] ==
3198  0) ||
3199  (quad_cell_count[quad->child(c)->child_index(0)] >
3200  0 &&
3201  quad_cell_count[quad->child(c)->child_index(1)] >
3202  0),
3203  ExcInternalError());
3204  if (quad_cell_count[quad->child(c)->child_index(0)] ==
3205  0)
3206  {
3207  // Assert, that the two
3208  // anisotropic
3209  // refinements add up to
3210  // isotropic refinement
3211  Assert(quad->refinement_case() +
3212  quad->child(c)->refinement_case() ==
3214  ExcInternalError());
3215  // we may delete the
3216  // quad's children and
3217  // the inner line as no
3218  // cell references them
3219  // anymore
3220  quads_to_delete.push_back(
3221  quad->child(c)->child(0));
3222  quads_to_delete.push_back(
3223  quad->child(c)->child(1));
3224  if (quad->child(c)->refinement_case() ==
3226  lines_to_delete.push_back(
3227  quad->child(c)->child(0)->line(1));
3228  else
3229  lines_to_delete.push_back(
3230  quad->child(c)->child(0)->line(3));
3231  quad->child(c)->clear_children();
3232  quad->child(c)->clear_refinement_case();
3233  ++deleted_grandchildren;
3234  }
3235  }
3236  // if no grandchildren are left, we
3237  // may as well delete the
3238  // refinement of the inner line
3239  // between our children and the
3240  // corresponding vertex
3241  if (number_of_child_refinements > 0 &&
3242  deleted_grandchildren == number_of_child_refinements)
3243  {
3245  middle_line;
3246  if (quad->refinement_case() == RefinementCase<2>::cut_x)
3247  middle_line = quad->child(0)->line(1);
3248  else
3249  middle_line = quad->child(0)->line(3);
3250 
3251  lines_to_delete.push_back(middle_line->child(0));
3252  lines_to_delete.push_back(middle_line->child(1));
3254  .vertices_used[middle_vertex_index<dim, spacedim>(
3255  middle_line)] = false;
3256  middle_line->clear_children();
3257  }
3258 
3259  // now consider the direct children
3260  // of the given quad
3261  if (quad_cell_count[quad->child_index(0)] == 0)
3262  {
3263  // we may delete the quad's
3264  // children and the inner line
3265  // as no cell references them
3266  // anymore
3267  quads_to_delete.push_back(quad->child(0));
3268  quads_to_delete.push_back(quad->child(1));
3269  if (quad->refinement_case() == RefinementCase<2>::cut_x)
3270  lines_to_delete.push_back(quad->child(0)->line(1));
3271  else
3272  lines_to_delete.push_back(quad->child(0)->line(3));
3273 
3274  // if the counters just dropped
3275  // to zero, otherwise the
3276  // children would have been
3277  // deleted earlier, then this
3278  // cell's children must have
3279  // contained the anisotropic
3280  // quad children. thus, if
3281  // those have again anisotropic
3282  // children, which are in
3283  // effect isotropic children of
3284  // the original quad, those are
3285  // still needed by a
3286  // neighboring cell and we
3287  // cannot delete them. instead,
3288  // we have to reset this quad's
3289  // refine case to isotropic and
3290  // set the children
3291  // accordingly.
3292  if (quad->child(0)->has_children())
3293  if (quad->refinement_case() ==
3295  {
3296  // now evereything is
3297  // quite complicated. we
3298  // have the children
3299  // numbered according to
3300  //
3301  // *---*---*
3302  // |n+1|m+1|
3303  // *---*---*
3304  // | n | m |
3305  // *---*---*
3306  //
3307  // from the original
3308  // anisotropic
3309  // refinement. we have to
3310  // reorder them as
3311  //
3312  // *---*---*
3313  // | m |m+1|
3314  // *---*---*
3315  // | n |n+1|
3316  // *---*---*
3317  //
3318  // for isotropic refinement.
3319  //
3320  // this is a bit ugly, of
3321  // course: loop over all
3322  // cells on all levels
3323  // and look for faces n+1
3324  // (switch_1) and m
3325  // (switch_2).
3326  const typename Triangulation<dim, spacedim>::
3327  quad_iterator switch_1 =
3328  quad->child(0)->child(1),
3329  switch_2 =
3330  quad->child(1)->child(0);
3331 
3332  Assert(!switch_1->has_children(),
3333  ExcInternalError());
3334  Assert(!switch_2->has_children(),
3335  ExcInternalError());
3336 
3337  const int switch_1_index = switch_1->index();
3338  const int switch_2_index = switch_2->index();
3339  for (unsigned int l = 0;
3340  l < triangulation.levels.size();
3341  ++l)
3342  for (unsigned int h = 0;
3343  h <
3344  triangulation.levels[l]->cells.n_objects();
3345  ++h)
3346  for (const unsigned int q :
3348  {
3349  const int index =
3350  triangulation.levels[l]
3351  ->cells.get_bounding_object_indices(
3352  h)[q];
3353  if (index == switch_1_index)
3354  triangulation.levels[l]
3355  ->cells.get_bounding_object_indices(
3356  h)[q] = switch_2_index;
3357  else if (index == switch_2_index)
3358  triangulation.levels[l]
3359  ->cells.get_bounding_object_indices(
3360  h)[q] = switch_1_index;
3361  }
3362  // now we have to copy
3363  // all information of the
3364  // two quads
3365  const int switch_1_lines[4] = {
3366  static_cast<signed int>(
3367  switch_1->line_index(0)),
3368  static_cast<signed int>(
3369  switch_1->line_index(1)),
3370  static_cast<signed int>(
3371  switch_1->line_index(2)),
3372  static_cast<signed int>(
3373  switch_1->line_index(3))};
3374  const bool switch_1_line_orientations[4] = {
3375  switch_1->line_orientation(0),
3376  switch_1->line_orientation(1),
3377  switch_1->line_orientation(2),
3378  switch_1->line_orientation(3)};
3379  const types::boundary_id switch_1_boundary_id =
3380  switch_1->boundary_id();
3381  const unsigned int switch_1_user_index =
3382  switch_1->user_index();
3383  const bool switch_1_user_flag =
3384  switch_1->user_flag_set();
3385 
3386  switch_1->set_bounding_object_indices(
3387  {switch_2->line_index(0),
3388  switch_2->line_index(1),
3389  switch_2->line_index(2),
3390  switch_2->line_index(3)});
3391  switch_1->set_line_orientation(
3392  0, switch_2->line_orientation(0));
3393  switch_1->set_line_orientation(
3394  1, switch_2->line_orientation(1));
3395  switch_1->set_line_orientation(
3396  2, switch_2->line_orientation(2));
3397  switch_1->set_line_orientation(
3398  3, switch_2->line_orientation(3));
3399  switch_1->set_boundary_id_internal(
3400  switch_2->boundary_id());
3401  switch_1->set_manifold_id(
3402  switch_2->manifold_id());
3403  switch_1->set_user_index(switch_2->user_index());
3404  if (switch_2->user_flag_set())
3405  switch_1->set_user_flag();
3406  else
3407  switch_1->clear_user_flag();
3408 
3409  switch_2->set_bounding_object_indices(
3410  {switch_1_lines[0],
3411  switch_1_lines[1],
3412  switch_1_lines[2],
3413  switch_1_lines[3]});
3414  switch_2->set_line_orientation(
3415  0, switch_1_line_orientations[0]);
3416  switch_2->set_line_orientation(
3417  1, switch_1_line_orientations[1]);
3418  switch_2->set_line_orientation(
3419  2, switch_1_line_orientations[2]);
3420  switch_2->set_line_orientation(
3421  3, switch_1_line_orientations[3]);
3422  switch_2->set_boundary_id_internal(
3423  switch_1_boundary_id);
3424  switch_2->set_manifold_id(
3425  switch_1->manifold_id());
3426  switch_2->set_user_index(switch_1_user_index);
3427  if (switch_1_user_flag)
3428  switch_2->set_user_flag();
3429  else
3430  switch_2->clear_user_flag();
3431 
3432  const unsigned int child_0 =
3433  quad->child(0)->child_index(0);
3434  const unsigned int child_2 =
3435  quad->child(1)->child_index(0);
3436  quad->clear_children();
3437  quad->clear_refinement_case();
3438  quad->set_refinement_case(
3440  quad->set_children(0, child_0);
3441  quad->set_children(2, child_2);
3442  std::swap(quad_cell_count[child_0 + 1],
3443  quad_cell_count[child_2]);
3444  }
3445  else
3446  {
3447  // the face was refined
3448  // with cut_y, thus the
3449  // children are already
3450  // in correct order. we
3451  // only have to set them
3452  // correctly, deleting
3453  // the indirection of two
3454  // anisotropic refinement
3455  // and going directly
3456  // from the quad to
3457  // isotropic children
3458  const unsigned int child_0 =
3459  quad->child(0)->child_index(0);
3460  const unsigned int child_2 =
3461  quad->child(1)->child_index(0);
3462  quad->clear_children();
3463  quad->clear_refinement_case();
3464  quad->set_refinement_case(
3466  quad->set_children(0, child_0);
3467  quad->set_children(2, child_2);
3468  }
3469  else
3470  {
3471  quad->clear_children();
3472  quad->clear_refinement_case();
3473  }
3474  }
3475  break;
3476  }
3477  case RefinementCase<dim - 1>::cut_xy:
3478  {
3479  // if one of the cell counters is
3480  // zero, the others have to be as
3481  // well
3482 
3483  Assert((quad_cell_count[quad->child_index(0)] == 0 &&
3484  quad_cell_count[quad->child_index(1)] == 0 &&
3485  quad_cell_count[quad->child_index(2)] == 0 &&
3486  quad_cell_count[quad->child_index(3)] == 0) ||
3487  (quad_cell_count[quad->child_index(0)] > 0 &&
3488  quad_cell_count[quad->child_index(1)] > 0 &&
3489  quad_cell_count[quad->child_index(2)] > 0 &&
3490  quad_cell_count[quad->child_index(3)] > 0),
3491  ExcInternalError());
3492 
3493  if (quad_cell_count[quad->child_index(0)] == 0)
3494  {
3495  // we may delete the quad's
3496  // children, the inner lines
3497  // and the middle vertex as no
3498  // cell references them anymore
3499  lines_to_delete.push_back(quad->child(0)->line(1));
3500  lines_to_delete.push_back(quad->child(3)->line(0));
3501  lines_to_delete.push_back(quad->child(0)->line(3));
3502  lines_to_delete.push_back(quad->child(3)->line(2));
3503 
3504  for (unsigned int child = 0; child < quad->n_children();
3505  ++child)
3506  quads_to_delete.push_back(quad->child(child));
3507 
3509  .vertices_used[quad->child(0)->vertex_index(3)] =
3510  false;
3511 
3512  quad->clear_children();
3513  quad->clear_refinement_case();
3514  }
3515  }
3516  break;
3517 
3518  default:
3519  Assert(false, ExcInternalError());
3520  break;
3521  }
3522  }
3523 
3524  // now we repeat a similar procedure
3525  // for the outer lines of this cell.
3526 
3527  // if in debug mode: check that each
3528  // of the lines for which we consider
3529  // deleting the children in fact has
3530  // children (the bits/coarsening_3d
3531  // test tripped over this initially)
3532  for (unsigned int line_no = 0;
3533  line_no < GeometryInfo<dim>::lines_per_cell;
3534  ++line_no)
3535  {
3537  cell->line(line_no);
3538 
3539  Assert(
3540  (GeometryInfo<dim>::line_refinement_case(ref_case, line_no) &&
3541  line->has_children()) ||
3542  GeometryInfo<dim>::line_refinement_case(ref_case, line_no) ==
3544  ExcInternalError());
3545 
3546  if (line->has_children())
3547  {
3548  // if one of the cell counters is
3549  // zero, the other has to be as well
3550 
3551  Assert((line_cell_count[line->child_index(0)] == 0 &&
3552  line_cell_count[line->child_index(1)] == 0) ||
3553  (line_cell_count[line->child_index(0)] > 0 &&
3554  line_cell_count[line->child_index(1)] > 0),
3555  ExcInternalError());
3556 
3557  if (line_cell_count[line->child_index(0)] == 0)
3558  {
3559  for (unsigned int c = 0; c < 2; ++c)
3560  Assert(!line->child(c)->has_children(),
3561  ExcInternalError());
3562 
3563  // we may delete the line's
3564  // children and the middle vertex
3565  // as no cell references them
3566  // anymore
3568  .vertices_used[line->child(0)->vertex_index(1)] = false;
3569 
3570  lines_to_delete.push_back(line->child(0));
3571  lines_to_delete.push_back(line->child(1));
3572 
3573  line->clear_children();
3574  }
3575  }
3576  }
3577 
3578  // finally, delete unneeded quads and lines
3579 
3580  // clear user pointers, to avoid that
3581  // they may appear at unwanted places
3582  // later on...
3583  // same for user flags, then finally
3584  // delete the quads and lines
3585  typename std::vector<
3587  line = lines_to_delete.begin(),
3588  endline = lines_to_delete.end();
3589  for (; line != endline; ++line)
3590  {
3591  (*line)->clear_user_data();
3592  (*line)->clear_user_flag();
3593  (*line)->clear_used_flag();
3594  }
3595 
3596  typename std::vector<
3598  quad = quads_to_delete.begin(),
3599  endquad = quads_to_delete.end();
3600  for (; quad != endquad; ++quad)
3601  {
3602  (*quad)->clear_user_data();
3603  (*quad)->clear_children();
3604  (*quad)->clear_refinement_case();
3605  (*quad)->clear_user_flag();
3606  (*quad)->clear_used_flag();
3607  }
3608  }
3609 
3610 
3628  template <int spacedim>
3629  static void
3632  unsigned int & next_unused_vertex,
3634  &next_unused_line,
3636  &next_unused_cell,
3637  const typename Triangulation<2, spacedim>::cell_iterator &cell)
3638  {
3639  const unsigned int dim = 2;
3640  // clear refinement flag
3641  const RefinementCase<dim> ref_case = cell->refine_flag_set();
3642  cell->clear_refine_flag();
3643 
3644  /* For the refinement process: since we go the levels up from the
3645  lowest, there are (unlike above) only two possibilities: a neighbor
3646  cell is on the same level or one level up (in both cases, it may or
3647  may not be refined later on, but we don't care here).
3648 
3649  First:
3650  Set up an array of the 3x3 vertices, which are distributed on the
3651  cell (the array consists of indices into the @p{vertices} std::vector
3652 
3653  2--7--3
3654  | | |
3655  4--8--5
3656  | | |
3657  0--6--1
3658 
3659  note: in case of cut_x or cut_y not all these vertices are needed for
3660  the new cells
3661 
3662  Second:
3663  Set up an array of the new lines (the array consists of iterator
3664  pointers into the lines arrays)
3665 
3666  .-6-.-7-. The directions are: .->-.->-.
3667  1 9 3 ^ ^ ^
3668  .-10.11-. .->-.->-.
3669  0 8 2 ^ ^ ^
3670  .-4-.-5-. .->-.->-.
3671 
3672  cut_x:
3673  .-4-.-5-.
3674  | | |
3675  0 6 1
3676  | | |
3677  .-2-.-3-.
3678 
3679  cut_y:
3680  .---5---.
3681  1 3
3682  .---6---.
3683  0 2
3684  .---4---.
3685 
3686 
3687  Third:
3688  Set up an array of neighbors:
3689 
3690  6 7
3691  .--.--.
3692  1| | |3
3693  .--.--.
3694  0| | |2
3695  .--.--.
3696  4 5
3697 
3698  We need this array for two reasons: first to get the lines which will
3699  bound the four subcells (if the neighboring cell is refined, these
3700  lines already exist), and second to update neighborship information.
3701  Since if a neighbor is not refined, its neighborship record only
3702  points to the present, unrefined, cell rather than the children we
3703  are presently creating, we only need the neighborship information
3704  if the neighbor cells are refined. In all other cases, we store
3705  the unrefined neighbor address
3706 
3707  We also need for every neighbor (if refined) which number among its
3708  neighbors the present (unrefined) cell has, since that number is to
3709  be replaced and because that also is the number of the subline which
3710  will be the interface between that neighbor and the to be created
3711  cell. We will store this number (between 0 and 3) in the field
3712  @p{neighbors_neighbor}.
3713 
3714  It would be sufficient to use the children of the common line to the
3715  neighbor, if we only wanted to get the new sublines and the new
3716  vertex, but because we need to update the neighborship information of
3717  the two refined subcells of the neighbor, we need to search these
3718  anyway.
3719 
3720  Convention:
3721  The created children are numbered like this:
3722 
3723  .--.--.
3724  |2 . 3|
3725  .--.--.
3726  |0 | 1|
3727  .--.--.
3728  */
3729  // collect the indices of the eight surrounding vertices
3730  // 2--7--3
3731  // | | |
3732  // 4--8--5
3733  // | | |
3734  // 0--6--1
3735  int new_vertices[9];
3736  for (unsigned int vertex_no = 0; vertex_no < 4; ++vertex_no)
3737  new_vertices[vertex_no] = cell->vertex_index(vertex_no);
3738  for (unsigned int line_no = 0; line_no < 4; ++line_no)
3739  if (cell->line(line_no)->has_children())
3740  new_vertices[4 + line_no] =
3741  cell->line(line_no)->child(0)->vertex_index(1);
3742 
3743  if (ref_case == RefinementCase<dim>::cut_xy)
3744  {
3745  // find the next
3746  // unused vertex and
3747  // allocate it for
3748  // the new vertex we
3749  // need here
3750  while (triangulation.vertices_used[next_unused_vertex] == true)
3751  ++next_unused_vertex;
3752  Assert(next_unused_vertex < triangulation.vertices.size(),
3753  ExcMessage(
3754  "Internal error: During refinement, the triangulation "
3755  "wants to access an element of the 'vertices' array "
3756  "but it turns out that the array is not large enough."));
3757  triangulation.vertices_used[next_unused_vertex] = true;
3758 
3759  new_vertices[8] = next_unused_vertex;
3760 
3761  // determine middle vertex by transfinite interpolation to be
3762  // consistent with what happens to quads in a
3763  // Triangulation<3,3> when they are refined
3764  triangulation.vertices[next_unused_vertex] =
3765  cell->center(true, true);
3766  }
3767 
3768 
3769  // Now the lines:
3770  typename Triangulation<dim, spacedim>::raw_line_iterator new_lines[12];
3771  unsigned int lmin = 8;
3772  unsigned int lmax = 12;
3773  if (ref_case != RefinementCase<dim>::cut_xy)
3774  {
3775  lmin = 6;
3776  lmax = 7;
3777  }
3778 
3779  for (unsigned int l = lmin; l < lmax; ++l)
3780  {
3781  while (next_unused_line->used() == true)
3782  ++next_unused_line;
3783  new_lines[l] = next_unused_line;
3784  ++next_unused_line;
3785 
3786  AssertIsNotUsed(new_lines[l]);
3787  }
3788 
3789  if (ref_case == RefinementCase<dim>::cut_xy)
3790  {
3791  // .-6-.-7-.
3792  // 1 9 3
3793  // .-10.11-.
3794  // 0 8 2
3795  // .-4-.-5-.
3796 
3797  // lines 0-7 already exist, create only the four interior
3798  // lines 8-11
3799  unsigned int l = 0;
3800  for (const unsigned int face_no : GeometryInfo<dim>::face_indices())
3801  for (unsigned int c = 0; c < 2; ++c, ++l)
3802  new_lines[l] = cell->line(face_no)->child(c);
3803  Assert(l == 8, ExcInternalError());
3804 
3805  new_lines[8]->set_bounding_object_indices(
3806  {new_vertices[6], new_vertices[8]});
3807  new_lines[9]->set_bounding_object_indices(
3808  {new_vertices[8], new_vertices[7]});
3809  new_lines[10]->set_bounding_object_indices(
3810  {new_vertices[4], new_vertices[8]});
3811  new_lines[11]->set_bounding_object_indices(
3812  {new_vertices[8], new_vertices[5]});
3813  }
3814  else if (ref_case == RefinementCase<dim>::cut_x)
3815  {
3816  // .-4-.-5-.
3817  // | | |
3818  // 0 6 1
3819  // | | |
3820  // .-2-.-3-.
3821  new_lines[0] = cell->line(0);
3822  new_lines[1] = cell->line(1);
3823  new_lines[2] = cell->line(2)->child(0);
3824  new_lines[3] = cell->line(2)->child(1);
3825  new_lines[4] = cell->line(3)->child(0);
3826  new_lines[5] = cell->line(3)->child(1);
3827  new_lines[6]->set_bounding_object_indices(
3828  {new_vertices[6], new_vertices[7]});
3829  }
3830  else
3831  {
3833  // .---5---.
3834  // 1 3
3835  // .---6---.
3836  // 0 2
3837  // .---4---.
3838  new_lines[0] = cell->line(0)->child(0);
3839  new_lines[1] = cell->line(0)->child(1);
3840  new_lines[2] = cell->line(1)->child(0);
3841  new_lines[3] = cell->line(1)->child(1);
3842  new_lines[4] = cell->line(2);
3843  new_lines[5] = cell->line(3);
3844  new_lines[6]->set_bounding_object_indices(
3845  {new_vertices[4], new_vertices[5]});
3846  }
3847 
3848  for (unsigned int l = lmin; l < lmax; ++l)
3849  {
3850  new_lines[l]->set_used_flag();
3851  new_lines[l]->clear_user_flag();
3852  new_lines[l]->clear_user_data();
3853  new_lines[l]->clear_children();
3854  // interior line
3855  new_lines[l]->set_boundary_id_internal(
3857  new_lines[l]->set_manifold_id(cell->manifold_id());
3858  }
3859 
3860  // Now add the four (two)
3861  // new cells!
3864  while (next_unused_cell->used() == true)
3865  ++next_unused_cell;
3866 
3867  const unsigned int n_children = GeometryInfo<dim>::n_children(ref_case);
3868  for (unsigned int i = 0; i < n_children; ++i)
3869  {
3870  AssertIsNotUsed(next_unused_cell);
3871  subcells[i] = next_unused_cell;
3872  ++next_unused_cell;
3873  if (i % 2 == 1 && i < n_children - 1)
3874  while (next_unused_cell->used() == true)
3875  ++next_unused_cell;
3876  }
3877 
3878  if (ref_case == RefinementCase<dim>::cut_xy)
3879  {
3880  // children:
3881  // .--.--.
3882  // |2 . 3|
3883  // .--.--.
3884  // |0 | 1|
3885  // .--.--.
3886  // lines:
3887  // .-6-.-7-.
3888  // 1 9 3
3889  // .-10.11-.
3890  // 0 8 2
3891  // .-4-.-5-.
3892  subcells[0]->set_bounding_object_indices({new_lines[0]->index(),
3893  new_lines[8]->index(),
3894  new_lines[4]->index(),
3895  new_lines[10]->index()});
3896  subcells[1]->set_bounding_object_indices({new_lines[8]->index(),
3897  new_lines[2]->index(),
3898  new_lines[5]->index(),
3899  new_lines[11]->index()});
3900  subcells[2]->set_bounding_object_indices({new_lines[1]->index(),
3901  new_lines[9]->index(),
3902  new_lines[10]->index(),
3903  new_lines[6]->index()});
3904  subcells[3]->set_bounding_object_indices({new_lines[9]->index(),
3905  new_lines[3]->index(),
3906  new_lines[11]->index(),
3907  new_lines[7]->index()});
3908  }
3909  else if (ref_case == RefinementCase<dim>::cut_x)
3910  {
3911  // children:
3912  // .--.--.
3913  // | . |
3914  // .0 . 1.
3915  // | | |
3916  // .--.--.
3917  // lines:
3918  // .-4-.-5-.
3919  // | | |
3920  // 0 6 1
3921  // | | |
3922  // .-2-.-3-.
3923  subcells[0]->set_bounding_object_indices({new_lines[0]->index(),
3924  new_lines[6]->index(),
3925  new_lines[2]->index(),
3926  new_lines[4]->index()});
3927  subcells[1]->set_bounding_object_indices({new_lines[6]->index(),
3928  new_lines[1]->index(),
3929  new_lines[3]->index(),
3930  new_lines[5]->index()});
3931  }
3932  else
3933  {
3935  // children:
3936  // .-----.
3937  // | 1 |
3938  // .-----.
3939  // | 0 |
3940  // .-----.
3941  // lines:
3942  // .---5---.
3943  // 1 3
3944  // .---6---.
3945  // 0 2
3946  // .---4---.
3947  subcells[0]->set_bounding_object_indices({new_lines[0]->index(),
3948  new_lines[2]->index(),
3949  new_lines[4]->index(),
3950  new_lines[6]->index()});
3951  subcells[1]->set_bounding_object_indices({new_lines[1]->index(),
3952  new_lines[3]->index(),
3953  new_lines[6]->index(),
3954  new_lines[5]->index()});
3955  }
3956 
3957  types::subdomain_id subdomainid = cell->subdomain_id();
3958 
3959  for (unsigned int i = 0; i < n_children; ++i)
3960  {
3961  subcells[i]->set_used_flag();
3962  subcells[i]->clear_refine_flag();
3963  subcells[i]->clear_user_flag();
3964  subcells[i]->clear_user_data();
3965  subcells[i]->clear_children();
3966  // inherit material properties
3967  subcells[i]->set_material_id(cell->material_id());
3968  subcells[i]->set_manifold_id(cell->manifold_id());
3969  subcells[i]->set_subdomain_id(subdomainid);
3970 
3971  if (i % 2 == 0)
3972  subcells[i]->set_parent(cell->index());
3973  }
3974 
3975 
3976 
3977  // set child index for even children i=0,2 (0)
3978  for (unsigned int i = 0; i < n_children / 2; ++i)
3979  cell->set_children(2 * i, subcells[2 * i]->index());
3980  // set the refine case
3981  cell->set_refinement_case(ref_case);
3982 
3983  // note that the
3984  // refinement flag was
3985  // already cleared at the
3986  // beginning of this function
3987 
3988  if (dim < spacedim)
3989  for (unsigned int c = 0; c < n_children; ++c)
3990  cell->child(c)->set_direction_flag(cell->direction_flag());
3991  }
3992 
3993 
3994 
3995  template <int dim, int spacedim>
3998  const bool check_for_distorted_cells)
3999  {
4000  AssertDimension(dim, 2);
4001 
4002  // Check whether a new level is needed. We have to check for
4003  // this on the highest level only
4004  for (const auto &cell : triangulation.active_cell_iterators_on_level(
4005  triangulation.levels.size() - 1))
4006  if (cell->refine_flag_set())
4007  {
4008  triangulation.levels.push_back(
4009  std::make_unique<
4011  break;
4012  }
4013 
4014  for (typename Triangulation<dim, spacedim>::line_iterator line =
4015  triangulation.begin_line();
4016  line != triangulation.end_line();
4017  ++line)
4018  {
4019  line->clear_user_flag();
4020  line->clear_user_data();
4021  }
4022 
4023  unsigned int n_single_lines = 0;
4024  unsigned int n_lines_in_pairs = 0;
4025  unsigned int needed_vertices = 0;
4026 
4027  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4028  {
4029  // count number of flagged cells on this level and compute
4030  // how many new vertices and new lines will be needed
4031  unsigned int needed_cells = 0;
4032 
4033  for (const auto &cell :
4034  triangulation.active_cell_iterators_on_level(level))
4035  if (cell->refine_flag_set())
4036  {
4037  if (cell->reference_cell() ==
4039  {
4040  needed_cells += 4;
4041  needed_vertices += 0;
4042  n_single_lines += 3;
4043  }
4044  else if (cell->reference_cell() ==
4046  {
4047  needed_cells += 4;
4048  needed_vertices += 1;
4049  n_single_lines += 4;
4050  }
4051  else
4052  {
4053  AssertThrow(false, ExcNotImplemented());
4054  }
4055 
4056  for (const auto line_no : cell->face_indices())
4057  {
4058  auto line = cell->line(line_no);
4059  if (line->has_children() == false)
4060  line->set_user_flag();
4061  }
4062  }
4063 
4064 
4065  const unsigned int used_cells =
4066  std::count(triangulation.levels[level + 1]->cells.used.begin(),
4067  triangulation.levels[level + 1]->cells.used.end(),
4068  true);
4069 
4070 
4071  reserve_space(*triangulation.levels[level + 1],
4072  used_cells + needed_cells,
4073  2,
4074  spacedim);
4075 
4076  reserve_space(triangulation.levels[level + 1]->cells,
4077  needed_cells,
4078  0);
4079  }
4080 
4081  for (auto line = triangulation.begin_line();
4082  line != triangulation.end_line();
4083  ++line)
4084  if (line->user_flag_set())
4085  {
4086  Assert(line->has_children() == false, ExcInternalError());
4087  n_lines_in_pairs += 2;
4088  needed_vertices += 1;
4089  }
4090 
4091  reserve_space(triangulation.faces->lines, n_lines_in_pairs, 0);
4092 
4093  needed_vertices += std::count(triangulation.vertices_used.begin(),
4094  triangulation.vertices_used.end(),
4095  true);
4096 
4097  if (needed_vertices > triangulation.vertices.size())
4098  {
4099  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
4100  triangulation.vertices_used.resize(needed_vertices, false);
4101  }
4102 
4103  unsigned int next_unused_vertex = 0;
4104 
4105  {
4107  line = triangulation.begin_active_line(),
4108  endl = triangulation.end_line();
4110  next_unused_line = triangulation.begin_raw_line();
4111 
4112  for (; line != endl; ++line)
4113  if (line->user_flag_set())
4114  {
4115  // this line needs to be refined
4116 
4117  // find the next unused vertex and set it
4118  // appropriately
4119  while (triangulation.vertices_used[next_unused_vertex] == true)
4120  ++next_unused_vertex;
4121  Assert(
4122  next_unused_vertex < triangulation.vertices.size(),
4123  ExcMessage(
4124  "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."));
4125  triangulation.vertices_used[next_unused_vertex] = true;
4126 
4127  triangulation.vertices[next_unused_vertex] = line->center(true);
4128 
4129  bool pair_found = false;
4130  (void)pair_found;
4131  for (; next_unused_line != endl; ++next_unused_line)
4132  if (!next_unused_line->used() &&
4133  !(++next_unused_line)->used())
4134  {
4135  --next_unused_line;
4136  pair_found = true;
4137  break;
4138  }
4139  Assert(pair_found, ExcInternalError());
4140 
4141  line->set_children(0, next_unused_line->index());
4142 
4144  children[2] = {next_unused_line, ++next_unused_line};
4145 
4146  AssertIsNotUsed(children[0]);
4147  AssertIsNotUsed(children[1]);
4148 
4149  children[0]->set_bounding_object_indices(
4150  {line->vertex_index(0), next_unused_vertex});
4151  children[1]->set_bounding_object_indices(
4152  {next_unused_vertex, line->vertex_index(1)});
4153 
4154  children[0]->set_used_flag();
4155  children[1]->set_used_flag();
4156  children[0]->clear_children();
4157  children[1]->clear_children();
4158  children[0]->clear_user_data();
4159  children[1]->clear_user_data();
4160  children[0]->clear_user_flag();
4161  children[1]->clear_user_flag();
4162 
4163 
4164  children[0]->set_boundary_id_internal(line->boundary_id());
4165  children[1]->set_boundary_id_internal(line->boundary_id());
4166 
4167  children[0]->set_manifold_id(line->manifold_id());
4168  children[1]->set_manifold_id(line->manifold_id());
4169 
4170  line->clear_user_flag();
4171  }
4172  }
4173 
4174  reserve_space(triangulation.faces->lines, 0, n_single_lines);
4175 
4177  cells_with_distorted_children;
4178 
4180  next_unused_line = triangulation.begin_raw_line();
4181 
4182  const auto create_children = [](auto & triangulation,
4183  unsigned int &next_unused_vertex,
4184  auto & next_unused_line,
4185  auto & next_unused_cell,
4186  const auto & cell) {
4187  const auto ref_case = cell->refine_flag_set();
4188  cell->clear_refine_flag();
4189 
4190  unsigned int n_new_vertices = 0;
4191 
4192  if (cell->reference_cell() == ::ReferenceCells::Triangle)
4193  n_new_vertices = 6;
4194  else if (cell->reference_cell() ==
4196  n_new_vertices = 9;
4197  else
4198  AssertThrow(false, ExcNotImplemented());
4199 
4200  std::vector<int> new_vertices(n_new_vertices);
4201  for (unsigned int vertex_no = 0; vertex_no < cell->n_vertices();
4202  ++vertex_no)
4203  new_vertices[vertex_no] = cell->vertex_index(vertex_no);
4204  for (unsigned int line_no = 0; line_no < cell->n_lines(); ++line_no)
4205  if (cell->line(line_no)->has_children())
4206  new_vertices[cell->n_vertices() + line_no] =
4207  cell->line(line_no)->child(0)->vertex_index(1);
4208 
4209  if (cell->reference_cell() == ::ReferenceCells::Quadrilateral)
4210  {
4211  while (triangulation.vertices_used[next_unused_vertex] == true)
4212  ++next_unused_vertex;
4213  Assert(
4214  next_unused_vertex < triangulation.vertices.size(),
4215  ExcMessage(
4216  "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."));
4217  triangulation.vertices_used[next_unused_vertex] = true;
4218 
4219  new_vertices[8] = next_unused_vertex;
4220 
4221  triangulation.vertices[next_unused_vertex] =
4222  cell->center(true, true);
4223  }
4224 
4225  std::array<typename Triangulation<dim, spacedim>::raw_line_iterator,
4226  12>
4227  new_lines;
4228  unsigned int lmin = 0;
4229  unsigned int lmax = 0;
4230 
4231  if (cell->reference_cell() == ::ReferenceCells::Triangle)
4232  {
4233  lmin = 6;
4234  lmax = 9;
4235  }
4236  else if (cell->reference_cell() ==
4238  {
4239  lmin = 8;
4240  lmax = 12;
4241  }
4242  else
4243  {
4244  AssertThrow(false, ExcNotImplemented());
4245  }
4246 
4247  for (unsigned int l = lmin; l < lmax; ++l)
4248  {
4249  while (next_unused_line->used() == true)
4250  ++next_unused_line;
4251  new_lines[l] = next_unused_line;
4252  ++next_unused_line;
4253 
4254  AssertIsNotUsed(new_lines[l]);
4255  }
4256 
4257  if (true)
4258  {
4259  if (cell->reference_cell() == ::ReferenceCells::Triangle)
4260  {
4261  // add lines in the right order [TODO: clean up]
4262  const auto ref = [&](const unsigned int face_no,
4263  const unsigned int vertex_no) {
4264  if (cell->line(face_no)->child(0)->vertex_index(0) ==
4265  static_cast<unsigned int>(new_vertices[vertex_no]) ||
4266  cell->line(face_no)->child(0)->vertex_index(1) ==
4267  static_cast<unsigned int>(new_vertices[vertex_no]))
4268  {
4269  new_lines[2 * face_no + 0] =
4270  cell->line(face_no)->child(0);
4271  new_lines[2 * face_no + 1] =
4272  cell->line(face_no)->child(1);
4273  }
4274  else
4275  {
4276  new_lines[2 * face_no + 0] =
4277  cell->line(face_no)->child(1);
4278  new_lines[2 * face_no + 1] =
4279  cell->line(face_no)->child(0);
4280  }
4281  };
4282 
4283  ref(0, 0);
4284  ref(1, 1);
4285  ref(2, 2);
4286 
4287  new_lines[6]->set_bounding_object_indices(
4288  {new_vertices[3], new_vertices[4]});
4289  new_lines[7]->set_bounding_object_indices(
4290  {new_vertices[4], new_vertices[5]});
4291  new_lines[8]->set_bounding_object_indices(
4292  {new_vertices[5], new_vertices[3]});
4293  }
4294  else if (cell->reference_cell() ==
4296  {
4297  unsigned int l = 0;
4298  for (const unsigned int face_no : cell->face_indices())
4299  for (unsigned int c = 0; c < 2; ++c, ++l)
4300  new_lines[l] = cell->line(face_no)->child(c);
4301 
4302  new_lines[8]->set_bounding_object_indices(
4303  {new_vertices[6], new_vertices[8]});
4304  new_lines[9]->set_bounding_object_indices(
4305  {new_vertices[8], new_vertices[7]});
4306  new_lines[10]->set_bounding_object_indices(
4307  {new_vertices[4], new_vertices[8]});
4308  new_lines[11]->set_bounding_object_indices(
4309  {new_vertices[8], new_vertices[5]});
4310  }
4311  else
4312  {
4313  AssertThrow(false, ExcNotImplemented());
4314  }
4315  }
4316 
4317 
4318  for (unsigned int l = lmin; l < lmax; ++l)
4319  {
4320  new_lines[l]->set_used_flag();
4321  new_lines[l]->clear_user_flag();
4322  new_lines[l]->clear_user_data();
4323  new_lines[l]->clear_children();
4324  // interior line
4325  new_lines[l]->set_boundary_id_internal(
4327  new_lines[l]->set_manifold_id(cell->manifold_id());
4328  }
4329 
4332  while (next_unused_cell->used() == true)
4333  ++next_unused_cell;
4334 
4335  unsigned int n_children = 0;
4336 
4337  if (cell->reference_cell() == ::ReferenceCells::Triangle)
4338  n_children = 4;
4339  else if (cell->reference_cell() ==
4341  n_children = 4;
4342  else
4343  AssertThrow(false, ExcNotImplemented());
4344 
4345  for (unsigned int i = 0; i < n_children; ++i)
4346  {
4347  AssertIsNotUsed(next_unused_cell);
4348  subcells[i] = next_unused_cell;
4349  ++next_unused_cell;
4350  if (i % 2 == 1 && i < n_children - 1)
4351  while (next_unused_cell->used() == true)
4352  ++next_unused_cell;
4353  }
4354 
4355  if ((dim == 2) &&
4356  (cell->reference_cell() == ::ReferenceCells::Triangle))
4357  {
4358  subcells[0]->set_bounding_object_indices({new_lines[0]->index(),
4359  new_lines[8]->index(),
4360  new_lines[5]->index()});
4361  subcells[1]->set_bounding_object_indices({new_lines[1]->index(),
4362  new_lines[2]->index(),
4363  new_lines[6]->index()});
4364  subcells[2]->set_bounding_object_indices({new_lines[7]->index(),
4365  new_lines[3]->index(),
4366  new_lines[4]->index()});
4367  subcells[3]->set_bounding_object_indices({new_lines[6]->index(),
4368  new_lines[7]->index(),
4369  new_lines[8]->index()});
4370 
4371  // subcell 0
4372 
4373  const auto ref = [&](const unsigned int line_no,
4374  const unsigned int vertex_no,
4375  const unsigned int subcell_no,
4376  const unsigned int subcell_line_no) {
4377  if (new_lines[line_no]->vertex_index(1) !=
4378  static_cast<unsigned int>(new_vertices[vertex_no]))
4379  triangulation.levels[subcells[subcell_no]->level()]
4380  ->face_orientations[subcells[subcell_no]->index() *
4382  subcell_line_no] = 0;
4383  };
4384 
4385  ref(0, 3, 0, 0);
4386  ref(8, 5, 0, 1);
4387  ref(5, 0, 0, 2);
4388 
4389  ref(1, 1, 1, 0);
4390  ref(2, 4, 1, 1);
4391  ref(6, 3, 1, 2);
4392 
4393  ref(7, 4, 2, 0);
4394  ref(3, 2, 2, 1);
4395  ref(4, 5, 2, 2);
4396 
4397  ref(6, 4, 3, 0);
4398  ref(7, 5, 3, 1);
4399  ref(8, 3, 3, 2);
4400 
4401  // triangulation.levels[subcells[1]->level()]->face_orientations[subcells[1]->index()
4402  // * GeometryInfo<2>::faces_per_cell + 2] = 0;
4403  // triangulation.levels[subcells[2]->level()]->face_orientations[subcells[2]->index()
4404  // * GeometryInfo<2>::faces_per_cell + 0] = 0;
4405  }
4406  else if ((dim == 2) && (cell->reference_cell() ==
4408  {
4409  subcells[0]->set_bounding_object_indices(
4410  {new_lines[0]->index(),
4411  new_lines[8]->index(),
4412  new_lines[4]->index(),
4413  new_lines[10]->index()});
4414  subcells[1]->set_bounding_object_indices(
4415  {new_lines[8]->index(),
4416  new_lines[2]->index(),
4417  new_lines[5]->index(),
4418  new_lines[11]->index()});
4419  subcells[2]->set_bounding_object_indices({new_lines[1]->index(),
4420  new_lines[9]->index(),
4421  new_lines[10]->index(),
4422  new_lines[6]->index()});
4423  subcells[3]->set_bounding_object_indices({new_lines[9]->index(),
4424  new_lines[3]->index(),
4425  new_lines[11]->index(),
4426  new_lines[7]->index()});
4427  }
4428  else
4429  {
4430  AssertThrow(false, ExcNotImplemented());
4431  }
4432 
4433  types::subdomain_id subdomainid = cell->subdomain_id();
4434 
4435  for (unsigned int i = 0; i < n_children; ++i)
4436  {
4437  subcells[i]->set_used_flag();
4438  subcells[i]->clear_refine_flag();
4439  subcells[i]->clear_user_flag();
4440  subcells[i]->clear_user_data();
4441  subcells[i]->clear_children();
4442  // inherit material
4443  // properties
4444  subcells[i]->set_material_id(cell->material_id());
4445  subcells[i]->set_manifold_id(cell->manifold_id());
4446  subcells[i]->set_subdomain_id(subdomainid);
4447 
4448  // TODO: here we assume that all children have the same reference
4449  // cell type as the parent! This is justified for 2D.
4450  triangulation.levels[subcells[i]->level()]
4451  ->reference_cell[subcells[i]->index()] = cell->reference_cell();
4452 
4453  if (i % 2 == 0)
4454  subcells[i]->set_parent(cell->index());
4455  }
4456 
4457  for (unsigned int i = 0; i < n_children / 2; ++i)
4458  cell->set_children(2 * i, subcells[2 * i]->index());
4459 
4460  cell->set_refinement_case(ref_case);
4461 
4462  if (dim < spacedim)
4463  for (unsigned int c = 0; c < n_children; ++c)
4464  cell->child(c)->set_direction_flag(cell->direction_flag());
4465  };
4466 
4467  for (int level = 0;
4468  level < static_cast<int>(triangulation.levels.size()) - 1;
4469  ++level)
4470  {
4472  next_unused_cell = triangulation.begin_raw(level + 1);
4473 
4474  for (const auto &cell :
4475  triangulation.active_cell_iterators_on_level(level))
4476  if (cell->refine_flag_set())
4477  {
4479  next_unused_vertex,
4480  next_unused_line,
4481  next_unused_cell,
4482  cell);
4483 
4484  if (cell->reference_cell() ==
4486  check_for_distorted_cells &&
4487  has_distorted_children<dim, spacedim>(cell))
4488  cells_with_distorted_children.distorted_cells.push_back(
4489  cell);
4490 
4491  triangulation.signals.post_refinement_on_cell(cell);
4492  }
4493  }
4494 
4495  return cells_with_distorted_children;
4496  }
4497 
4498 
4499 
4504  template <int spacedim>
4507  const bool /*check_for_distorted_cells*/)
4508  {
4509  const unsigned int dim = 1;
4510 
4511  // Check whether a new level is needed. We have to check for
4512  // this on the highest level only
4513  for (const auto &cell : triangulation.active_cell_iterators_on_level(
4514  triangulation.levels.size() - 1))
4515  if (cell->refine_flag_set())
4516  {
4517  triangulation.levels.push_back(
4518  std::make_unique<
4520  break;
4521  }
4522 
4523 
4524  // check how much space is needed on every level. We need not
4525  // check the highest level since either - on the highest level
4526  // no cells are flagged for refinement - there are, but
4527  // prepare_refinement added another empty level
4528  unsigned int needed_vertices = 0;
4529  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4530  {
4531  // count number of flagged
4532  // cells on this level
4533  unsigned int flagged_cells = 0;
4534 
4535  for (const auto &acell :
4536  triangulation.active_cell_iterators_on_level(level))
4537  if (acell->refine_flag_set())
4538  ++flagged_cells;
4539 
4540  // count number of used cells
4541  // on the next higher level
4542  const unsigned int used_cells =
4543  std::count(triangulation.levels[level + 1]->cells.used.begin(),
4544  triangulation.levels[level + 1]->cells.used.end(),
4545  true);
4546 
4547  // reserve space for the used_cells cells already existing
4548  // on the next higher level as well as for the
4549  // 2*flagged_cells that will be created on that level
4550  reserve_space(*triangulation.levels[level + 1],
4552  flagged_cells,
4553  1,
4554  spacedim);
4555  // reserve space for 2*flagged_cells new lines on the next
4556  // higher level
4557  reserve_space(triangulation.levels[level + 1]->cells,
4559  flagged_cells,
4560  0);
4561 
4562  needed_vertices += flagged_cells;
4563  }
4564 
4565  // add to needed vertices how many
4566  // vertices are already in use
4567  needed_vertices += std::count(triangulation.vertices_used.begin(),
4568  triangulation.vertices_used.end(),
4569  true);
4570  // if we need more vertices: create them, if not: leave the
4571  // array as is, since shrinking is not really possible because
4572  // some of the vertices at the end may be in use
4573  if (needed_vertices > triangulation.vertices.size())
4574  {
4575  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
4576  triangulation.vertices_used.resize(needed_vertices, false);
4577  }
4578 
4579 
4580  // Do REFINEMENT on every level; exclude highest level as
4581  // above
4582 
4583  // index of next unused vertex
4584  unsigned int next_unused_vertex = 0;
4585 
4586  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4587  {
4589  next_unused_cell = triangulation.begin_raw(level + 1);
4590 
4591  for (const auto &cell :
4592  triangulation.active_cell_iterators_on_level(level))
4593  if (cell->refine_flag_set())
4594  {
4595  // clear refinement flag
4596  cell->clear_refine_flag();
4597 
4598  // search for next unused
4599  // vertex
4600  while (triangulation.vertices_used[next_unused_vertex] ==
4601  true)
4602  ++next_unused_vertex;
4603  Assert(
4604  next_unused_vertex < triangulation.vertices.size(),
4605  ExcMessage(
4606  "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."));
4607 
4608  // Now we always ask the cell itself where to put
4609  // the new point. The cell in turn will query the
4610  // manifold object internally.
4611  triangulation.vertices[next_unused_vertex] =
4612  cell->center(true);
4613 
4614  triangulation.vertices_used[next_unused_vertex] = true;
4615 
4616  // search for next two unused cell (++ takes care of
4617  // the end of the vector)
4619  first_child,
4620  second_child;
4621  while (next_unused_cell->used() == true)
4622  ++next_unused_cell;
4623  first_child = next_unused_cell;
4624  first_child->set_used_flag();
4625  first_child->clear_user_data();
4626  ++next_unused_cell;
4627  AssertIsNotUsed(next_unused_cell);
4628  second_child = next_unused_cell;
4629  second_child->set_used_flag();
4630  second_child->clear_user_data();
4631 
4632  types::subdomain_id subdomainid = cell->subdomain_id();
4633 
4634  // insert first child
4635  cell->set_children(0, first_child->index());
4636  first_child->clear_children();
4637  first_child->set_bounding_object_indices(
4638  {cell->vertex_index(0), next_unused_vertex});
4639  first_child->set_material_id(cell->material_id());
4640  first_child->set_manifold_id(cell->manifold_id());
4641  first_child->set_subdomain_id(subdomainid);
4642  first_child->set_direction_flag(cell->direction_flag());
4643 
4644  first_child->set_parent(cell->index());
4645 
4646  // Set manifold id of the right face. Only do this
4647  // on the first child.
4648  first_child->face(1)->set_manifold_id(cell->manifold_id());
4649 
4650  // reset neighborship info (refer to
4651  // internal::TriangulationImplementation::TriaLevel<0> for
4652  // details)
4653  first_child->set_neighbor(1, second_child);
4654  if (cell->neighbor(0).state() != IteratorState::valid)
4655  first_child->set_neighbor(0, cell->neighbor(0));
4656  else if (cell->neighbor(0)->is_active())
4657  {
4658  // since the neighbors level is always <=level,
4659  // if the cell is active, then there are no
4660  // cells to the left which may want to know
4661  // about this new child cell.
4662  Assert(cell->neighbor(0)->level() <= cell->level(),
4663  ExcInternalError());
4664  first_child->set_neighbor(0, cell->neighbor(0));
4665  }
4666  else
4667  // left neighbor is refined
4668  {
4669  // set neighbor to cell on same level
4670  const unsigned int nbnb = cell->neighbor_of_neighbor(0);
4671  first_child->set_neighbor(0,
4672  cell->neighbor(0)->child(nbnb));
4673 
4674  // reset neighbor info of all right descendant
4675  // of the left neighbor of cell
4677  left_neighbor = cell->neighbor(0);
4678  while (left_neighbor->has_children())
4679  {
4680  left_neighbor = left_neighbor->child(nbnb);
4681  left_neighbor->set_neighbor(nbnb, first_child);
4682  }
4683  }
4684 
4685  // insert second child
4686  second_child->clear_children();
4687  second_child->set_bounding_object_indices(
4688  {next_unused_vertex, cell->vertex_index(1)});
4689  second_child->set_neighbor(0, first_child);
4690  second_child->set_material_id(cell->material_id());
4691  second_child->set_manifold_id(cell->manifold_id());
4692  second_child->set_subdomain_id(subdomainid);
4693  second_child->set_direction_flag(cell->direction_flag());
4694 
4695  if (cell->neighbor(1).state() != IteratorState::valid)
4696  second_child->set_neighbor(1, cell->neighbor(1));
4697  else if (cell->neighbor(1)->is_active())
4698  {
4699  Assert(cell->neighbor(1)->level() <= cell->level(),
4700  ExcInternalError());
4701  second_child->set_neighbor(1, cell->neighbor(1));
4702  }
4703  else
4704  // right neighbor is refined same as above
4705  {
4706  const unsigned int nbnb = cell->neighbor_of_neighbor(1);
4707  second_child->set_neighbor(
4708  1, cell->neighbor(1)->child(nbnb));
4709 
4711  right_neighbor = cell->neighbor(1);
4712  while (right_neighbor->has_children())
4713  {
4714  right_neighbor = right_neighbor->child(nbnb);
4715  right_neighbor->set_neighbor(nbnb, second_child);
4716  }
4717  }
4718  // inform all listeners that cell refinement is done
4719  triangulation.signals.post_refinement_on_cell(cell);
4720  }
4721  }
4722 
4723  // in 1d, we can not have distorted children unless the parent
4724  // was already distorted (that is because we don't use
4725  // boundary information for 1d triangulations). so return an
4726  // empty list
4728  }
4729 
4730 
4735  template <int spacedim>
4738  const bool check_for_distorted_cells)
4739  {
4740  const unsigned int dim = 2;
4741 
4742 
4743  // First check whether we can get away with isotropic refinement, or
4744  // whether we need to run through the full anisotropic algorithm
4745  {
4746  bool do_isotropic_refinement = true;
4747  for (const auto &cell : triangulation.active_cell_iterators())
4748  if (cell->refine_flag_set() == RefinementCase<dim>::cut_x ||
4749  cell->refine_flag_set() == RefinementCase<dim>::cut_y)
4750  {
4751  do_isotropic_refinement = false;
4752  break;
4753  }
4754 
4755  if (do_isotropic_refinement)
4757  check_for_distorted_cells);
4758  }
4759 
4760  // Check whether a new level is needed. We have to check for
4761  // this on the highest level only
4762  for (const auto &cell : triangulation.active_cell_iterators_on_level(
4763  triangulation.levels.size() - 1))
4764  if (cell->refine_flag_set())
4765  {
4766  triangulation.levels.push_back(
4767  std::make_unique<
4769  break;
4770  }
4771 
4772  // TODO[WB]: we clear user flags and pointers of lines; we're going
4773  // to use them to flag which lines need refinement
4774  for (typename Triangulation<dim, spacedim>::line_iterator line =
4775  triangulation.begin_line();
4776  line != triangulation.end_line();
4777  ++line)
4778  {
4779  line->clear_user_flag();
4780  line->clear_user_data();
4781  }
4782  // running over all cells and lines count the number
4783  // n_single_lines of lines which can be stored as single
4784  // lines, e.g. inner lines
4785  unsigned int n_single_lines = 0;
4786 
4787  // New lines to be created: number lines which are stored in
4788  // pairs (the children of lines must be stored in pairs)
4789  unsigned int n_lines_in_pairs = 0;
4790 
4791  // check how much space is needed on every level. We need not
4792  // check the highest level since either - on the highest level
4793  // no cells are flagged for refinement - there are, but
4794  // prepare_refinement added another empty level
4795  unsigned int needed_vertices = 0;
4796  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4797  {
4798  // count number of flagged cells on this level and compute
4799  // how many new vertices and new lines will be needed
4800  unsigned int needed_cells = 0;
4801 
4802  for (const auto &cell :
4803  triangulation.active_cell_iterators_on_level(level))
4804  if (cell->refine_flag_set())
4805  {
4806  if (cell->refine_flag_set() == RefinementCase<dim>::cut_xy)
4807  {
4808  needed_cells += 4;
4809 
4810  // new vertex at center of cell is needed in any
4811  // case
4812  ++needed_vertices;
4813 
4814  // the four inner lines can be stored as singles
4815  n_single_lines += 4;
4816  }
4817  else // cut_x || cut_y
4818  {
4819  // set the flag showing that anisotropic
4820  // refinement is used for at least one cell
4821  triangulation.anisotropic_refinement = true;
4822 
4823  needed_cells += 2;
4824  // no vertex at center
4825 
4826  // the inner line can be stored as single
4827  n_single_lines += 1;
4828  }
4829 
4830  // mark all faces (lines) for refinement; checking
4831  // locally whether the neighbor would also like to
4832  // refine them is rather difficult for lines so we
4833  // only flag them and after visiting all cells, we
4834  // decide which lines need refinement;
4835  for (const unsigned int line_no :
4837  {
4839  cell->refine_flag_set(), line_no) ==
4841  {
4843  line = cell->line(line_no);
4844  if (line->has_children() == false)
4845  line->set_user_flag();
4846  }
4847  }
4848  }
4849 
4850 
4851  // count number of used cells on the next higher level
4852  const unsigned int used_cells =
4853  std::count(triangulation.levels[level + 1]->cells.used.begin(),
4854  triangulation.levels[level + 1]->cells.used.end(),
4855  true);
4856 
4857 
4858  // reserve space for the used_cells cells already existing
4859  // on the next higher level as well as for the
4860  // needed_cells that will be created on that level
4861  reserve_space(*triangulation.levels[level + 1],
4862  used_cells + needed_cells,
4863  2,
4864  spacedim);
4865 
4866  // reserve space for needed_cells new quads on the next
4867  // higher level
4868  reserve_space(triangulation.levels[level + 1]->cells,
4869  needed_cells,
4870  0);
4871  }
4872 
4873  // now count the lines which were flagged for refinement
4874  for (typename Triangulation<dim, spacedim>::line_iterator line =
4875  triangulation.begin_line();
4876  line != triangulation.end_line();
4877  ++line)
4878  if (line->user_flag_set())
4879  {
4880  Assert(line->has_children() == false, ExcInternalError());
4881  n_lines_in_pairs += 2;
4882  needed_vertices += 1;
4883  }
4884  // reserve space for n_lines_in_pairs new lines. note, that
4885  // we can't reserve space for the single lines here as well,
4886  // as all the space reserved for lines in pairs would be
4887  // counted as unused and we would end up with too little space
4888  // to store all lines. memory reservation for n_single_lines
4889  // can only be done AFTER we refined the lines of the current
4890  // cells
4891  reserve_space(triangulation.faces->lines, n_lines_in_pairs, 0);
4892 
4893  // add to needed vertices how many vertices are already in use
4894  needed_vertices += std::count(triangulation.vertices_used.begin(),
4895  triangulation.vertices_used.end(),
4896  true);
4897  // if we need more vertices: create them, if not: leave the
4898  // array as is, since shrinking is not really possible because
4899  // some of the vertices at the end may be in use
4900  if (needed_vertices > triangulation.vertices.size())
4901  {
4902  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
4903  triangulation.vertices_used.resize(needed_vertices, false);
4904  }
4905 
4906 
4907  // Do REFINEMENT on every level; exclude highest level as
4908  // above
4909 
4910  // index of next unused vertex
4911  unsigned int next_unused_vertex = 0;
4912 
4913  // first the refinement of lines. children are stored
4914  // pairwise
4915  {
4916  // only active objects can be refined further
4918  line = triangulation.begin_active_line(),
4919  endl = triangulation.end_line();
4921  next_unused_line = triangulation.begin_raw_line();
4922 
4923  for (; line != endl; ++line)
4924  if (line->user_flag_set())
4925  {
4926  // this line needs to be refined
4927 
4928  // find the next unused vertex and set it
4929  // appropriately
4930  while (triangulation.vertices_used[next_unused_vertex] == true)
4931  ++next_unused_vertex;
4932  Assert(
4933  next_unused_vertex < triangulation.vertices.size(),
4934  ExcMessage(
4935  "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."));
4936  triangulation.vertices_used[next_unused_vertex] = true;
4937 
4938  triangulation.vertices[next_unused_vertex] = line->center(true);
4939 
4940  // now that we created the right point, make up the
4941  // two child lines. To this end, find a pair of
4942  // unused lines
4943  bool pair_found = false;
4944  (void)pair_found;
4945  for (; next_unused_line != endl; ++next_unused_line)
4946  if (!next_unused_line->used() &&
4947  !(++next_unused_line)->used())
4948  {
4949  // go back to the first of the two unused
4950  // lines
4951  --next_unused_line;
4952  pair_found = true;
4953  break;
4954  }
4955  Assert(pair_found, ExcInternalError());
4956 
4957  // there are now two consecutive unused lines, such
4958  // that the children of a line will be consecutive.
4959  // then set the child pointer of the present line
4960  line->set_children(0, next_unused_line->index());
4961 
4962  // set the two new lines
4964  children[2] = {next_unused_line, ++next_unused_line};
4965  // some tests; if any of the iterators should be
4966  // invalid, then already dereferencing will fail
4967  AssertIsNotUsed(children[0]);
4968  AssertIsNotUsed(children[1]);
4969 
4970  children[0]->set_bounding_object_indices(
4971  {line->vertex_index(0), next_unused_vertex});
4972  children[1]->set_bounding_object_indices(
4973  {next_unused_vertex, line->vertex_index(1)});
4974 
4975  children[0]->set_used_flag();
4976  children[1]->set_used_flag();
4977  children[0]->clear_children();
4978  children[1]->clear_children();
4979  children[0]->clear_user_data();
4980  children[1]->clear_user_data();
4981  children[0]->clear_user_flag();
4982  children[1]->clear_user_flag();
4983 
4984 
4985  children[0]->set_boundary_id_internal(line->boundary_id());
4986  children[1]->set_boundary_id_internal(line->boundary_id());
4987 
4988  children[0]->set_manifold_id(line->manifold_id());
4989  children[1]->set_manifold_id(line->manifold_id());
4990 
4991  // finally clear flag indicating the need for
4992  // refinement
4993  line->clear_user_flag();
4994  }
4995  }
4996 
4997 
4998  // Now set up the new cells
4999 
5000  // reserve space for inner lines (can be stored as single
5001  // lines)
5002  reserve_space(triangulation.faces->lines, 0, n_single_lines);
5003 
5005  cells_with_distorted_children;
5006 
5007  // reset next_unused_line, as now also single empty places in
5008  // the vector can be used
5010  next_unused_line = triangulation.begin_raw_line();
5011 
5012  for (int level = 0;
5013  level < static_cast<int>(triangulation.levels.size()) - 1;
5014  ++level)
5015  {
5017  next_unused_cell = triangulation.begin_raw(level + 1);
5018 
5019  for (const auto &cell :
5020  triangulation.active_cell_iterators_on_level(level))
5021  if (cell->refine_flag_set())
5022  {
5023  // actually set up the children and update neighbor
5024  // information
5026  next_unused_vertex,
5027  next_unused_line,
5028  next_unused_cell,
5029  cell);
5030 
5031  if (check_for_distorted_cells &&
5032  has_distorted_children<dim, spacedim>(cell))
5033  cells_with_distorted_children.distorted_cells.push_back(
5034  cell);
5035  // inform all listeners that cell refinement is done
5036  triangulation.signals.post_refinement_on_cell(cell);
5037  }
5038  }
5039 
5040  return cells_with_distorted_children;
5041  }
5042 
5043 
5044  template <int spacedim>
5047  const bool check_for_distorted_cells)
5048  {
5049  static const int dim = 3;
5050  static const unsigned int X = numbers::invalid_unsigned_int;
5051 
5052  Assert(spacedim == 3, ExcNotImplemented());
5053 
5054  Assert(triangulation.vertices.size() ==
5055  triangulation.vertices_used.size(),
5056  ExcInternalError());
5057 
5058  // Check whether a new level is needed. We have to check for
5059  // this on the highest level only
5060  for (const auto &cell : triangulation.active_cell_iterators_on_level(
5061  triangulation.levels.size() - 1))
5062  if (cell->refine_flag_set())
5063  {
5064  triangulation.levels.push_back(
5065  std::make_unique<
5067  break;
5068  }
5069 
5070  // first clear user flags for quads and lines; we're going to
5071  // use them to flag which lines and quads need refinement
5072  triangulation.faces->quads.clear_user_data();
5073 
5074  for (typename Triangulation<dim, spacedim>::line_iterator line =
5075  triangulation.begin_line();
5076  line != triangulation.end_line();
5077  ++line)
5078  line->clear_user_flag();
5079 
5080  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
5081  triangulation.begin_quad();
5082  quad != triangulation.end_quad();
5083  ++quad)
5084  quad->clear_user_flag();
5085 
5086  // check how much space is needed on every level. We need not
5087  // check the highest level since either
5088  // - on the highest level no cells are flagged for refinement
5089  // - there are, but prepare_refinement added another empty
5090  // level which then is the highest level
5091 
5092  // variables to hold the number of newly to be created
5093  // vertices, lines and quads. as these are stored globally,
5094  // declare them outside the loop over al levels. we need lines
5095  // and quads in pairs for refinement of old ones and lines and
5096  // quads, that can be stored as single ones, as they are newly
5097  // created in the inside of an existing cell
5098  unsigned int needed_vertices = 0;
5099  unsigned int needed_lines_single = 0;
5100  unsigned int needed_quads_single = 0;
5101  unsigned int needed_lines_pair = 0;
5102  unsigned int needed_quads_pair = 0;
5103  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
5104  {
5105  unsigned int new_cells = 0;
5106 
5107  for (const auto &cell :
5108  triangulation.active_cell_iterators_on_level(level))
5109  if (cell->refine_flag_set())
5110  {
5111  // Only support isotropic refinement
5112  Assert(cell->refine_flag_set() ==
5114  ExcInternalError());
5115 
5116  // Now count up how many new cells, faces, edges, and vertices
5117  // we will need to allocate to do this refinement.
5118  new_cells += cell->reference_cell().n_isotropic_children();
5119 
5120  if (cell->reference_cell() == ReferenceCells::Hexahedron)
5121  {
5122  ++needed_vertices;
5123  needed_lines_single += 6;
5124  needed_quads_single += 12;
5125  }
5126  else if (cell->reference_cell() ==
5128  {
5129  needed_lines_single += 1;
5130  needed_quads_single += 8;
5131  }
5132  else
5133  {
5134  Assert(false, ExcInternalError());
5135  }
5136 
5137  // Also check whether we have to refine any of the faces and
5138  // edges that bound this cell. They may of course already be
5139  // refined, so we only *mark* them for refinement by setting
5140  // the user flags
5141  for (const auto face : cell->face_indices())
5142  if (cell->face(face)->n_children() == 0)
5143  cell->face(face)->set_user_flag();
5144  else
5145  Assert(cell->face(face)->n_children() ==
5146  cell->reference_cell()
5147  .face_reference_cell(face)
5148  .n_isotropic_children(),
5149  ExcInternalError());
5150 
5151  for (const auto line : cell->line_indices())
5152  if (cell->line(line)->has_children() == false)
5153  cell->line(line)->set_user_flag();
5154  else
5155  Assert(cell->line(line)->n_children() == 2,
5156  ExcInternalError());
5157  }
5158 
5159  const unsigned int used_cells =
5160  std::count(triangulation.levels[level + 1]->cells.used.begin(),
5161  triangulation.levels[level + 1]->cells.used.end(),
5162  true);
5163 
5164  reserve_space(*triangulation.levels[level + 1],
5165  used_cells + new_cells,
5166  3,
5167  spacedim);
5168 
5169  reserve_space(triangulation.levels[level + 1]->cells, new_cells);
5170  }
5171 
5172  // now count the quads and lines which were flagged for
5173  // refinement
5174  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
5175  triangulation.begin_quad();
5176  quad != triangulation.end_quad();
5177  ++quad)
5178  {
5179  if (quad->user_flag_set() == false)
5180  continue;
5181 
5182  if (quad->reference_cell() == ReferenceCells::Quadrilateral)
5183  {
5184  needed_quads_pair += 4;
5185  needed_lines_pair += 4;
5186  needed_vertices += 1;
5187  }
5188  else if (quad->reference_cell() == ReferenceCells::Triangle)
5189  {
5190  needed_quads_pair += 4;
5191  needed_lines_single += 3;
5192  }
5193  else
5194  {
5195  Assert(false, ExcInternalError());
5196  }
5197  }
5198 
5199  for (typename Triangulation<dim, spacedim>::line_iterator line =
5200  triangulation.begin_line();
5201  line != triangulation.end_line();
5202  ++line)
5203  {
5204  if (line->user_flag_set() == false)
5205  continue;
5206 
5207  needed_lines_pair += 2;
5208  needed_vertices += 1;
5209  }
5210 
5211  reserve_space(triangulation.faces->lines,
5212  needed_lines_pair,
5213  needed_lines_single);
5215  needed_quads_pair,
5216  needed_quads_single);
5217  reserve_space(triangulation.faces->quads,
5218  needed_quads_pair,
5219  needed_quads_single);
5220 
5221 
5222  // add to needed vertices how many vertices are already in use
5223  needed_vertices += std::count(triangulation.vertices_used.begin(),
5224  triangulation.vertices_used.end(),
5225  true);
5226 
5227  if (needed_vertices > triangulation.vertices.size())
5228  {
5229  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
5230  triangulation.vertices_used.resize(needed_vertices, false);
5231  }
5232 
5233  //-----------------------------------------
5234  // Before we start with the actual refinement, we do some
5235  // sanity checks if in debug mode. especially, we try to catch
5236  // the notorious problem with lines being twice refined,
5237  // i.e. there are cells adjacent at one line ("around the
5238  // edge", but not at a face), with two cells differing by more
5239  // than one refinement level
5240  //
5241  // this check is very simple to implement here, since we have
5242  // all lines flagged if they shall be refined
5243 #ifdef DEBUG
5244  for (const auto &cell : triangulation.active_cell_iterators())
5245  if (!cell->refine_flag_set())
5246  for (unsigned int line_n = 0; line_n < cell->n_lines(); ++line_n)
5247  if (cell->line(line_n)->has_children())
5248  for (unsigned int c = 0; c < 2; ++c)
5249  Assert(cell->line(line_n)->child(c)->user_flag_set() == false,
5250  ExcInternalError());
5251 #endif
5252 
5253  unsigned int current_vertex = 0;
5254 
5255  // helper function - find the next available vertex number and mark it
5256  // as used.
5257  auto get_next_unused_vertex = [](const unsigned int current_vertex,
5258  std::vector<bool> &vertices_used) {
5259  unsigned int next_vertex = current_vertex;
5260  while (next_vertex < vertices_used.size() &&
5261  vertices_used[next_vertex] == true)
5262  ++next_vertex;
5263  Assert(next_vertex < vertices_used.size(), ExcInternalError());
5264  vertices_used[next_vertex] = true;
5265 
5266  return next_vertex;
5267  };
5268 
5269  // LINES
5270  {
5272  line = triangulation.begin_active_line(),
5273  endl = triangulation.end_line();
5275  next_unused_line = triangulation.begin_raw_line();
5276 
5277  for (; line != endl; ++line)
5278  {
5279  if (line->user_flag_set() == false)
5280  continue;
5281 
5282  current_vertex =
5283  get_next_unused_vertex(current_vertex,
5284  triangulation.vertices_used);
5285  triangulation.vertices[current_vertex] = line->center(true);
5286 
5287  next_unused_line =
5288  triangulation.faces->lines.template next_free_pair_object<1>(
5289  triangulation);
5290  Assert(next_unused_line.state() == IteratorState::valid,
5291  ExcInternalError());
5292 
5293  // now we found two consecutive unused lines, such
5294  // that the children of a line will be consecutive.
5295  // then set the child pointer of the present line
5296  line->set_children(0, next_unused_line->index());
5297 
5299  children[2] = {next_unused_line, ++next_unused_line};
5300 
5301  AssertIsNotUsed(children[0]);
5302  AssertIsNotUsed(children[1]);
5303 
5304  children[0]->set_bounding_object_indices(
5305  {line->vertex_index(0), current_vertex});
5306  children[1]->set_bounding_object_indices(
5307  {current_vertex, line->vertex_index(1)});
5308 
5309  children[0]->set_used_flag();
5310  children[1]->set_used_flag();
5311  children[0]->clear_children();
5312  children[1]->clear_children();
5313  children[0]->clear_user_data();
5314  children[1]->clear_user_data();
5315  children[0]->clear_user_flag();
5316  children[1]->clear_user_flag();
5317 
5318  children[0]->set_boundary_id_internal(line->boundary_id());
5319  children[1]->set_boundary_id_internal(line->boundary_id());
5320 
5321  children[0]->set_manifold_id(line->manifold_id());
5322  children[1]->set_manifold_id(line->manifold_id());
5323 
5324  line->clear_user_flag();
5325  }
5326  }
5327 
5328  // QUADS
5329  {
5331  quad = triangulation.begin_quad(),
5332  endq = triangulation.end_quad();
5334  next_unused_line = triangulation.begin_raw_line();
5336  next_unused_quad = triangulation.begin_raw_quad();
5337 
5338  for (; quad != endq; ++quad)
5339  {
5340  if (quad->user_flag_set() == false)
5341  continue;
5342 
5343  const auto reference_face_type = quad->reference_cell();
5344 
5345  // 1) create new vertex (at the center of the face)
5346  if (reference_face_type == ReferenceCells::Quadrilateral)
5347  {
5348  current_vertex =
5349  get_next_unused_vertex(current_vertex,
5350  triangulation.vertices_used);
5351  triangulation.vertices[current_vertex] =
5352  quad->center(true, true);
5353  }
5354 
5355  // 2) create new lines (property is set later)
5356  boost::container::small_vector<
5359  new_lines(quad->n_lines());
5360  {
5361  for (unsigned int i = 0; i < new_lines.size(); ++i)
5362  {
5363  if (reference_face_type == ReferenceCells::Quadrilateral)
5364  {
5365  if (i % 2 == 0)
5366  next_unused_line =
5367  triangulation.faces->lines
5368  .template next_free_pair_object<1>(triangulation);
5369  }
5370  else if (reference_face_type == ReferenceCells::Triangle)
5371  {
5372  next_unused_line =
5373  triangulation.faces->lines
5374  .template next_free_single_object<1>(triangulation);
5375  }
5376  else
5377  {
5378  Assert(false, ExcNotImplemented());
5379  }
5380 
5381  new_lines[i] = next_unused_line;
5382  ++next_unused_line;
5383  AssertIsNotUsed(new_lines[i]);
5384  }
5385  }
5386 
5387  // 3) create new quads (properties are set below). Both triangles
5388  // and quads are divided in four.
5389  std::array<
5391  4>
5392  new_quads;
5393  {
5394  next_unused_quad =
5395  triangulation.faces->quads.template next_free_pair_object<2>(
5396  triangulation);
5397 
5398  new_quads[0] = next_unused_quad;
5399  AssertIsNotUsed(new_quads[0]);
5400 
5401  ++next_unused_quad;
5402  new_quads[1] = next_unused_quad;
5403  AssertIsNotUsed(new_quads[1]);
5404 
5405  next_unused_quad =
5406  triangulation.faces->quads.template next_free_pair_object<2>(
5407  triangulation);
5408  new_quads[2] = next_unused_quad;
5409  AssertIsNotUsed(new_quads[2]);
5410 
5411  ++next_unused_quad;
5412  new_quads[3] = next_unused_quad;
5413  AssertIsNotUsed(new_quads[3]);
5414 
5415  quad->set_children(0, new_quads[0]->index());
5416  quad->set_children(2, new_quads[2]->index());
5417  quad->set_refinement_case(RefinementCase<2>::cut_xy);
5418  }
5419 
5420  // Maximum of 9 vertices per refined quad (9 for Quadrilateral, 6
5421  // for Triangle)
5422  std::array<unsigned int, 9> vertex_indices = {};
5423  {
5424  unsigned int k = 0;
5425  for (const auto i : quad->vertex_indices())
5426  vertex_indices[k++] = quad->vertex_index(i);
5427 
5428  for (const auto i : quad->line_indices())
5429  vertex_indices[k++] =
5430  quad->line(i)->child(0)->vertex_index(1);
5431 
5432  vertex_indices[k++] = current_vertex;
5433  }
5434 
5435  boost::container::small_vector<
5437  12>
5438  lines(reference_face_type == ReferenceCells::Quadrilateral ?
5439  12 :
5440  9);
5441  {
5442  unsigned int k = 0;
5443 
5444  for (unsigned int l = 0; l < quad->n_lines(); ++l)
5445  for (unsigned int c = 0; c < 2; ++c)
5446  {
5447  static constexpr std::array<std::array<unsigned int, 2>,
5448  2>
5449  index = {// child 0, line_orientation=false and true
5450  {{{1, 0}},
5451  // child 1, line_orientation=false and true
5452  {{0, 1}}}};
5453 
5454  lines[k++] = quad->line(l)->child(
5455  index[c][quad->line_orientation(l)]);
5456  }
5457 
5458  for (unsigned int l = 0; l < new_lines.size(); ++l)
5459  lines[k++] = new_lines[l];
5460  }
5461 
5462  boost::container::small_vector<int, 12> line_indices(
5463  lines.size());
5464  for (unsigned int i = 0; i < line_indices.size(); ++i)
5465  line_indices[i] = lines[i]->index();
5466 
5467  static constexpr std::array<std::array<unsigned int, 2>, 12>
5468  line_vertices_quad{{{{0, 4}},
5469  {{4, 2}},
5470  {{1, 5}},
5471  {{5, 3}},
5472  {{0, 6}},
5473  {{6, 1}},
5474  {{2, 7}},
5475  {{7, 3}},
5476  {{6, 8}},
5477  {{8, 7}},
5478  {{4, 8}},
5479  {{8, 5}}}};
5480 
5481  static constexpr std::array<std::array<unsigned int, 4>, 4>
5482  quad_lines_quad{{{{0, 8, 4, 10}},
5483  {{8, 2, 5, 11}},
5484  {{1, 9, 10, 6}},
5485  {{9, 3, 11, 7}}}};
5486 
5487  static constexpr std::
5488  array<std::array<std::array<unsigned int, 2>, 4>, 4>
5489  quad_line_vertices_quad{
5490  {{{{{0, 4}}, {{6, 8}}, {{0, 6}}, {{4, 8}}}},
5491  {{{{6, 8}}, {{1, 5}}, {{6, 1}}, {{8, 5}}}},
5492  {{{{4, 2}}, {{8, 7}}, {{4, 8}}, {{2, 7}}}},
5493  {{{{8, 7}}, {{5, 3}}, {{8, 5}}, {{7, 3}}}}}};
5494 
5495  static constexpr std::array<std::array<unsigned int, 2>, 12>
5496  line_vertices_tri{{{{0, 3}},
5497  {{3, 1}},
5498  {{1, 4}},
5499  {{4, 2}},
5500  {{2, 5}},
5501  {{5, 0}},
5502  {{3, 4}},
5503  {{4, 5}},
5504  {{3, 5}},
5505  {{X, X}},
5506  {{X, X}},
5507  {{X, X}}}};
5508 
5509  static constexpr std::array<std::array<unsigned int, 4>, 4>
5510  quad_lines_tri{{{{0, 8, 5, X}},
5511  {{1, 2, 6, X}},
5512  {{7, 3, 4, X}},
5513  {{6, 7, 8, X}}}};
5514 
5515  static constexpr std::
5516  array<std::array<std::array<unsigned int, 2>, 4>, 4>
5517  quad_line_vertices_tri{
5518  {{{{{0, 3}}, {{3, 5}}, {{5, 0}}, {{X, X}}}},
5519  {{{{3, 1}}, {{1, 4}}, {{4, 3}}, {{X, X}}}},
5520  {{{{5, 4}}, {{4, 2}}, {{2, 5}}, {{X, X}}}},
5521  {{{{3, 4}}, {{4, 5}}, {{5, 3}}, {{X, X}}}}}};
5522 
5523  const auto &line_vertices =
5524  (reference_face_type == ReferenceCells::Quadrilateral) ?
5525  line_vertices_quad :
5526  line_vertices_tri;
5527  const auto &quad_lines =
5528  (reference_face_type == ReferenceCells::Quadrilateral) ?
5529  quad_lines_quad :
5530  quad_lines_tri;
5531  const auto &quad_line_vertices =
5532  (reference_face_type == ReferenceCells::Quadrilateral) ?
5533  quad_line_vertices_quad :
5534  quad_line_vertices_tri;
5535 
5536  // 4) set properties of lines
5537  for (unsigned int i = 0, j = lines.size() - new_lines.size();
5538  i < new_lines.size();
5539  ++i, ++j)
5540  {
5541  auto &new_line = new_lines[i];
5542  new_line->set_bounding_object_indices(
5543  {vertex_indices[line_vertices[j][0]],
5544  vertex_indices[line_vertices[j][1]]});
5545  new_line->set_used_flag();
5546  new_line->clear_user_flag();
5547  new_line->clear_user_data();
5548  new_line->clear_children();
5549  new_line->set_boundary_id_internal(quad->boundary_id());
5550  new_line->set_manifold_id(quad->manifold_id());
5551  }
5552 
5553  // 5) set properties of quads
5554  for (unsigned int i = 0; i < new_quads.size(); ++i)
5555  {
5556  auto &new_quad = new_quads[i];
5557 
5558  // TODO: we assume here that all children have the same type
5559  // as the parent
5560  triangulation.faces->quad_reference_cell[new_quad->index()] =
5561  reference_face_type;
5562 
5563  if (new_quad->n_lines() == 3)
5564  new_quad->set_bounding_object_indices(
5565  {line_indices[quad_lines[i][0]],
5566  line_indices[quad_lines[i][1]],
5567  line_indices[quad_lines[i][2]]});
5568  else if (new_quad->n_lines() == 4)
5569  new_quad->set_bounding_object_indices(
5570  {line_indices[quad_lines[i][0]],
5571  line_indices[quad_lines[i][1]],
5572  line_indices[quad_lines[i][2]],
5573  line_indices[quad_lines[i][3]]});
5574  else
5575  Assert(false, ExcNotImplemented());
5576 
5577  new_quad->set_used_flag();
5578  new_quad->clear_user_flag();
5579  new_quad->clear_user_data();
5580  new_quad->clear_children();
5581  new_quad->set_boundary_id_internal(quad->boundary_id());
5582  new_quad->set_manifold_id(quad->manifold_id());
5583 
5584 #ifdef DEBUG
5585  std::set<unsigned int> s;
5586 #endif
5587 
5588  // ... and fix orientation of faces (lines) of quad
5589  for (const auto f : new_quad->line_indices())
5590  {
5591  std::array<unsigned int, 2> vertices_0, vertices_1;
5592 
5593  for (unsigned int v = 0; v < 2; ++v)
5594  vertices_0[v] =
5595  lines[quad_lines[i][f]]->vertex_index(v);
5596 
5597  for (unsigned int v = 0; v < 2; ++v)
5598  vertices_1[v] =
5599  vertex_indices[quad_line_vertices[i][f][v]];
5600 
5601  const auto orientation =
5603  vertices_1);
5604 
5605 #ifdef DEBUG
5606  for (const auto i : vertices_0)
5607  s.insert(i);
5608  for (const auto i : vertices_1)
5609  s.insert(i);
5610 #endif
5611 
5612  new_quad->set_line_orientation(f, orientation);
5613  }
5614 #ifdef DEBUG
5616  s.size(),
5617  (reference_face_type == ReferenceCells::Quadrilateral ? 4 :
5618  3));
5619 #endif
5620  }
5621 
5622  quad->clear_user_flag();
5623  }
5624  }
5625 
5627  cells_with_distorted_children;
5628 
5629  for (unsigned int level = 0; level != triangulation.levels.size() - 1;
5630  ++level)
5631  {
5633  hex = triangulation.begin_active_hex(level),
5634  endh = triangulation.begin_active_hex(level + 1);
5636  next_unused_hex = triangulation.begin_raw_hex(level + 1);
5637 
5638  for (; hex != endh; ++hex)
5639  {
5640  if (hex->refine_flag_set() ==
5642  continue;
5643 
5644  const auto &reference_cell_type = hex->reference_cell();
5645 
5646  const RefinementCase<dim> ref_case = hex->refine_flag_set();
5647  hex->clear_refine_flag();
5648  hex->set_refinement_case(ref_case);
5649 
5650  unsigned int n_new_lines = 0;
5651  unsigned int n_new_quads = 0;
5652  unsigned int n_new_hexes = 0;
5653 
5654  if (reference_cell_type == ReferenceCells::Hexahedron)
5655  {
5656  n_new_lines = 6;
5657  n_new_quads = 12;
5658  n_new_hexes = 8;
5659  }
5660  else if (reference_cell_type == ReferenceCells::Tetrahedron)
5661  {
5662  n_new_lines = 1;
5663  n_new_quads = 8;
5664  n_new_hexes = 8;
5665  }
5666  else
5667  Assert(false, ExcNotImplemented());
5668 
5669  // Hexes add a single new internal vertex
5670  if (reference_cell_type == ReferenceCells::Hexahedron)
5671  {
5672  current_vertex =
5673  get_next_unused_vertex(current_vertex,
5674  triangulation.vertices_used);
5675  triangulation.vertices[current_vertex] =
5676  hex->center(true, true);
5677  }
5678 
5679  boost::container::small_vector<
5681  6>
5682  new_lines(n_new_lines);
5683  for (unsigned int i = 0; i < n_new_lines; ++i)
5684  {
5685  new_lines[i] =
5686  triangulation.faces->lines
5687  .template next_free_single_object<1>(triangulation);
5688 
5689  AssertIsNotUsed(new_lines[i]);
5690  new_lines[i]->set_used_flag();
5691  new_lines[i]->clear_user_flag();
5692  new_lines[i]->clear_user_data();
5693  new_lines[i]->clear_children();
5694  new_lines[i]->set_boundary_id_internal(
5696  new_lines[i]->set_manifold_id(hex->manifold_id());
5697  }
5698 
5699  boost::container::small_vector<
5701  12>
5702  new_quads(n_new_quads);
5703  for (unsigned int i = 0; i < n_new_quads; ++i)
5704  {
5705  new_quads[i] =
5706  triangulation.faces->quads
5707  .template next_free_single_object<2>(triangulation);
5708 
5709  auto &new_quad = new_quads[i];
5710 
5711  // TODO: faces of children have the same type as the faces
5712  // of the parent
5713  triangulation.faces
5714  ->quad_reference_cell[new_quad->index()] =
5715  (reference_cell_type == ReferenceCells::Hexahedron) ?
5718 
5719  AssertIsNotUsed(new_quad);
5720  new_quad->set_used_flag();
5721  new_quad->clear_user_flag();
5722  new_quad->clear_user_data();
5723  new_quad->clear_children();
5724  new_quad->set_boundary_id_internal(
5726  new_quad->set_manifold_id(hex->manifold_id());
5727  for (const auto j : new_quads[i]->line_indices())
5728  new_quad->set_line_orientation(j, true);
5729  }
5730 
5731  // we always get 8 children per refined cell
5732  std::array<
5734  8>
5735  new_hexes;
5736  {
5737  for (unsigned int i = 0; i < n_new_hexes; ++i)
5738  {
5739  if (i % 2 == 0)
5740  next_unused_hex =
5741  triangulation.levels[level + 1]->cells.next_free_hex(
5742  triangulation, level + 1);
5743  else
5744  ++next_unused_hex;
5745 
5746  new_hexes[i] = next_unused_hex;
5747 
5748  auto &new_hex = new_hexes[i];
5749 
5750  // TODO: children have the same type as the parent
5751  triangulation.levels[new_hex->level()]
5752  ->reference_cell[new_hex->index()] =
5753  reference_cell_type;
5754 
5755  AssertIsNotUsed(new_hex);
5756  new_hex->set_used_flag();
5757  new_hex->clear_user_flag();
5758  new_hex->clear_user_data();
5759  new_hex->clear_children();
5760  new_hex->set_material_id(hex->material_id());
5761  new_hex->set_manifold_id(hex->manifold_id());
5762  new_hex->set_subdomain_id(hex->subdomain_id());
5763 
5764  if (i % 2)
5765  new_hex->set_parent(hex->index());
5766  // set the face_orientation flag to true for all
5767  // faces initially, as this is the default value
5768  // which is true for all faces interior to the
5769  // hex. later on go the other way round and
5770  // reset faces that are at the boundary of the
5771  // mother cube
5772  //
5773  // the same is true for the face_flip and
5774  // face_rotation flags. however, the latter two
5775  // are set to false by default as this is the
5776  // standard value
5777  for (const auto f : new_hex->face_indices())
5778  {
5779  new_hex->set_face_orientation(f, true);
5780  new_hex->set_face_flip(f, false);
5781  new_hex->set_face_rotation(f, false);
5782  }
5783  }
5784  for (unsigned int i = 0; i < n_new_hexes / 2; ++i)
5785  hex->set_children(2 * i, new_hexes[2 * i]->index());
5786  }
5787 
5788  {
5789  // load vertex indices
5790  std::array<unsigned int, 27> vertex_indices = {};
5791 
5792  {
5793  unsigned int k = 0;
5794 
5795  for (const unsigned int i : hex->vertex_indices())
5796  vertex_indices[k++] = hex->vertex_index(i);
5797 
5798  for (const unsigned int i : hex->line_indices())
5799  vertex_indices[k++] =
5800  hex->line(i)->child(0)->vertex_index(1);
5801 
5802  if (reference_cell_type == ReferenceCells::Hexahedron)
5803  {
5804  for (const unsigned int i : hex->face_indices())
5805  vertex_indices[k++] =
5806  middle_vertex_index<dim, spacedim>(hex->face(i));
5807 
5808  vertex_indices[k++] = current_vertex;
5809  }
5810  }
5811 
5812  // set up new lines
5813  {
5814  static constexpr std::array<std::array<unsigned int, 2>, 6>
5815  new_line_vertices_hex = {{{{22, 26}},
5816  {{26, 23}},
5817  {{20, 26}},
5818  {{26, 21}},
5819  {{24, 26}},
5820  {{26, 25}}}};
5821 
5822  static constexpr std::array<std::array<unsigned int, 2>, 6>
5823  new_line_vertices_tet = {{{{6, 8}},
5824  {{X, X}},
5825  {{X, X}},
5826  {{X, X}},
5827  {{X, X}},
5828  {{X, X}}}};
5829 
5830  const auto &new_line_vertices =
5831  (reference_cell_type == ReferenceCells::Hexahedron) ?
5832  new_line_vertices_hex :
5833  new_line_vertices_tet;
5834 
5835  for (unsigned int i = 0; i < new_lines.size(); ++i)
5836  new_lines[i]->set_bounding_object_indices(
5837  {vertex_indices[new_line_vertices[i][0]],
5838  vertex_indices[new_line_vertices[i][1]]});
5839  }
5840 
5841  // set up new quads
5842  {
5843  boost::container::small_vector<
5845  30>
5846  relevant_lines(0);
5847 
5848  if (reference_cell_type == ReferenceCells::Hexahedron)
5849  {
5850  relevant_lines.resize(30);
5851  for (unsigned int f = 0, k = 0; f < 6; ++f)
5852  for (unsigned int c = 0; c < 4; ++c, ++k)
5853  {
5854  static constexpr std::
5855  array<std::array<unsigned int, 2>, 4>
5856  temp = {
5857  {{{0, 1}}, {{3, 0}}, {{0, 3}}, {{3, 2}}}};
5858 
5859  relevant_lines[k] =
5860  hex->face(f)
5861  ->isotropic_child(
5863  standard_to_real_face_vertex(
5864  temp[c][0],
5865  hex->face_orientation(f),
5866  hex->face_flip(f),
5867  hex->face_rotation(f)))
5868  ->line(GeometryInfo<dim>::
5869  standard_to_real_face_line(
5870  temp[c][1],
5871  hex->face_orientation(f),
5872  hex->face_flip(f),
5873  hex->face_rotation(f)));
5874  }
5875 
5876  for (unsigned int i = 0, k = 24; i < 6; ++i, ++k)
5877  relevant_lines[k] = new_lines[i];
5878  }
5879  else if (reference_cell_type == ReferenceCells::Tetrahedron)
5880  {
5881  relevant_lines.resize(13);
5882 
5883  unsigned int k = 0;
5884  for (unsigned int f = 0; f < 4; ++f)
5885  for (unsigned int l = 0; l < 3; ++l, ++k)
5886  {
5887  // TODO: add comment
5888  static const std::
5889  array<std::array<unsigned int, 3>, 6>
5890  table = {{{{1, 0, 2}}, // 0
5891  {{0, 1, 2}},
5892  {{0, 2, 1}}, // 2
5893  {{1, 2, 0}},
5894  {{2, 1, 0}}, // 4
5895  {{2, 0, 1}}}};
5896 
5897  relevant_lines[k] =
5898  hex->face(f)
5899  ->child(3 /*center triangle*/)
5900  ->line(
5901  table[triangulation.levels[hex->level()]
5902  ->face_orientations
5903  [hex->index() *
5904  GeometryInfo<
5905  dim>::faces_per_cell +
5906  f]][l]);
5907  }
5908 
5909  relevant_lines[k++] = new_lines[0];
5910 
5911  AssertDimension(k, 13);
5912  }
5913  else
5914  Assert(false, ExcNotImplemented());
5915 
5916  boost::container::small_vector<unsigned int, 30>
5917  relevant_line_indices(relevant_lines.size());
5918  for (unsigned int i = 0; i < relevant_line_indices.size();
5919  ++i)
5920  relevant_line_indices[i] = relevant_lines[i]->index();
5921 
5922  static constexpr std::array<std::array<unsigned int, 4>, 12>
5923  new_quad_lines_hex = {{{{10, 28, 16, 24}},
5924  {{28, 14, 17, 25}},
5925  {{11, 29, 24, 20}},
5926  {{29, 15, 25, 21}},
5927  {{18, 26, 0, 28}},
5928  {{26, 22, 1, 29}},
5929  {{19, 27, 28, 4}},
5930  {{27, 23, 29, 5}},
5931  {{2, 24, 8, 26}},
5932  {{24, 6, 9, 27}},
5933  {{3, 25, 26, 12}},
5934  {{25, 7, 27, 13}}}};
5935 
5936  static constexpr std::array<std::array<unsigned int, 4>, 12>
5937  new_quad_lines_tet = {{{{2, 3, 8, X}},
5938  {{0, 9, 5, X}},
5939  {{1, 6, 11, X}},
5940  {{4, 10, 7, X}},
5941  {{2, 12, 5, X}},
5942  {{1, 9, 12, X}},
5943  {{4, 8, 12, X}},
5944  {{6, 12, 10, X}},
5945  {{X, X, X, X}},
5946  {{X, X, X, X}},
5947  {{X, X, X, X}},
5948  {{X, X, X, X}}}};
5949 
5950  static constexpr std::
5951  array<std::array<std::array<unsigned int, 2>, 4>, 12>
5952  table_hex = {
5953  {{{{{10, 22}}, {{24, 26}}, {{10, 24}}, {{22, 26}}}},
5954  {{{{24, 26}}, {{11, 23}}, {{24, 11}}, {{26, 23}}}},
5955  {{{{22, 14}}, {{26, 25}}, {{22, 26}}, {{14, 25}}}},
5956  {{{{26, 25}}, {{23, 15}}, {{26, 23}}, {{25, 15}}}},
5957  {{{{8, 24}}, {{20, 26}}, {{8, 20}}, {{24, 26}}}},
5958  {{{{20, 26}}, {{12, 25}}, {{20, 12}}, {{26, 25}}}},
5959  {{{{24, 9}}, {{26, 21}}, {{24, 26}}, {{9, 21}}}},
5960  {{{{26, 21}}, {{25, 13}}, {{26, 25}}, {{21, 13}}}},
5961  {{{{16, 20}}, {{22, 26}}, {{16, 22}}, {{20, 26}}}},
5962  {{{{22, 26}}, {{17, 21}}, {{22, 17}}, {{26, 21}}}},
5963  {{{{20, 18}}, {{26, 23}}, {{20, 26}}, {{18, 23}}}},
5964  {{{{26, 23}}, {{21, 19}}, {{26, 21}}, {{23, 19}}}}}};
5965 
5966  static constexpr std::
5967  array<std::array<std::array<unsigned int, 2>, 4>, 12>
5968  table_tet = {
5969  {{{{{6, 4}}, {{4, 7}}, {{7, 6}}, {{X, X}}}},
5970  {{{{4, 5}}, {{5, 8}}, {{8, 4}}, {{X, X}}}},
5971  {{{{5, 6}}, {{6, 9}}, {{9, 5}}, {{X, X}}}},
5972  {{{{7, 8}}, {{8, 9}}, {{9, 7}}, {{X, X}}}},
5973  {{{{4, 6}}, {{6, 8}}, {{8, 4}}, {{X, X}}}},
5974  {{{{6, 5}}, {{5, 8}}, {{8, 6}}, {{X, X}}}},
5975  {{{{8, 7}}, {{7, 6}}, {{6, 8}}, {{X, X}}}},
5976  {{{{9, 6}}, {{6, 8}}, {{8, 9}}, {{X, X}}}},
5977  {{{{X, X}}, {{X, X}}, {{X, X}}, {{X, X}}}},
5978  {{{{X, X}}, {{X, X}}, {{X, X}}, {{X, X}}}},
5979  {{{{X, X}}, {{X, X}}, {{X, X}}, {{X, X}}}},
5980  {{{{X, X}}, {{X, X}}, {{X, X}}, {{X, X}}}}}};
5981 
5982  const auto &new_quad_lines =
5983  (reference_cell_type == ReferenceCells::Hexahedron) ?
5984  new_quad_lines_hex :
5985  new_quad_lines_tet;
5986 
5987  const auto &table =
5988  (reference_cell_type == ReferenceCells::Hexahedron) ?
5989  table_hex :
5990  table_tet;
5991 
5992  for (unsigned int q = 0; q < new_quads.size(); ++q)
5993  {
5994  for (unsigned int l = 0; l < 3; ++l)
5995  {
5996  std::array<unsigned int, 2> vertices_0, vertices_1;
5997 
5998  for (unsigned int v = 0; v < 2; ++v)
5999  vertices_0[v] =
6000  relevant_lines[new_quad_lines[q][l]]
6001  ->vertex_index(v);
6002 
6003  for (unsigned int v = 0; v < 2; ++v)
6004  vertices_1[v] = vertex_indices[table[q][l][v]];
6005  }
6006  }
6007 
6008  for (unsigned int q = 0; q < new_quads.size(); ++q)
6009  {
6010  auto &new_quad = new_quads[q];
6011 
6012  if (new_quad->n_lines() == 3)
6013  new_quad->set_bounding_object_indices(
6014  {relevant_line_indices[new_quad_lines[q][0]],
6015  relevant_line_indices[new_quad_lines[q][1]],
6016  relevant_line_indices[new_quad_lines[q][2]]});
6017  else if (new_quad->n_lines() == 4)
6018  new_quad->set_bounding_object_indices(
6019  {relevant_line_indices[new_quad_lines[q][0]],
6020  relevant_line_indices[new_quad_lines[q][1]],
6021  relevant_line_indices[new_quad_lines[q][2]],
6022  relevant_line_indices[new_quad_lines[q][3]]});
6023  else
6024  Assert(false, ExcNotImplemented());
6025 
6026  for (const auto l : new_quad->line_indices())
6027  {
6028  std::array<unsigned int, 2> vertices_0, vertices_1;
6029 
6030  for (unsigned int v = 0; v < 2; ++v)
6031  vertices_0[v] =
6032  relevant_lines[new_quad_lines[q][l]]
6033  ->vertex_index(v);
6034 
6035  for (unsigned int v = 0; v < 2; ++v)
6036  vertices_1[v] = vertex_indices[table[q][l][v]];
6037 
6038  const auto orientation =
6040  vertices_0, vertices_1);
6041 
6042  new_quad->set_line_orientation(l, orientation);
6043  }
6044  }
6045  }
6046 
6047  // set up new hex
6048  {
6049  std::array<int, 36> quad_indices;
6050 
6051  if (reference_cell_type == ReferenceCells::Hexahedron)
6052  {
6053  for (unsigned int i = 0; i < new_quads.size(); ++i)
6054  quad_indices[i] = new_quads[i]->index();
6055 
6056  for (unsigned int f = 0, k = new_quads.size(); f < 6;
6057  ++f)
6058  for (unsigned int c = 0; c < 4; ++c, ++k)
6059  quad_indices[k] =
6060  hex->face(f)->isotropic_child_index(
6062  c,
6063  hex->face_orientation(f),
6064  hex->face_flip(f),
6065  hex->face_rotation(f)));
6066  }
6067  else if (reference_cell_type == ReferenceCells::Tetrahedron)
6068  {
6069  for (unsigned int i = 0; i < new_quads.size(); ++i)
6070  quad_indices[i] = new_quads[i]->index();
6071 
6072  for (unsigned int f = 0, k = new_quads.size(); f < 4;
6073  ++f)
6074  for (unsigned int c = 0; c < 4; ++c, ++k)
6075  {
6076  quad_indices[k] = hex->face(f)->child_index(
6077  (c == 3) ?
6078  3 :
6079  reference_cell_type
6080  .standard_to_real_face_vertex(
6081  c,
6082  f,
6083  triangulation.levels[hex->level()]
6084  ->face_orientations
6085  [hex->index() *
6087  f]));
6088  }
6089  }
6090  else
6091  {
6092  Assert(false, ExcNotImplemented());
6093  }
6094 
6095  static constexpr std::array<std::array<unsigned int, 6>, 8>
6096  cell_quads_hex = {{
6097  {{12, 0, 20, 4, 28, 8}}, // bottom children
6098  {{0, 16, 22, 6, 29, 9}}, //
6099  {{13, 1, 4, 24, 30, 10}}, //
6100  {{1, 17, 6, 26, 31, 11}}, //
6101  {{14, 2, 21, 5, 8, 32}}, // top children
6102  {{2, 18, 23, 7, 9, 33}}, //
6103  {{15, 3, 5, 25, 10, 34}}, //
6104  {{3, 19, 7, 27, 11, 35}} //
6105  }};
6106 
6107  static constexpr std::array<std::array<unsigned int, 6>, 8>
6108  cell_quads_tet{{{{8, 13, 16, 0, X, X}},
6109  {{9, 12, 1, 21, X, X}},
6110  {{10, 2, 17, 20, X, X}},
6111  {{3, 14, 18, 22, X, X}},
6112  {{11, 1, 4, 5, X, X}},
6113  {{15, 0, 4, 6, X, X}},
6114  {{19, 7, 6, 3, X, X}},
6115  {{23, 5, 2, 7, X, X}}}};
6116 
6117  static constexpr std::
6118  array<std::array<std::array<unsigned int, 4>, 6>, 8>
6119  cell_face_vertices_hex{{{{{{0, 8, 16, 20}},
6120  {{10, 24, 22, 26}},
6121  {{0, 16, 10, 22}},
6122  {{8, 20, 24, 26}},
6123  {{0, 10, 8, 24}},
6124  {{16, 22, 20, 26}}}},
6125  {{{{10, 24, 22, 26}},
6126  {{1, 9, 17, 21}},
6127  {{10, 22, 1, 17}},
6128  {{24, 26, 9, 21}},
6129  {{10, 1, 24, 9}},
6130  {{22, 17, 26, 21}}}},
6131  {{{{8, 2, 20, 18}},
6132  {{24, 11, 26, 23}},
6133  {{8, 20, 24, 26}},
6134  {{2, 18, 11, 23}},
6135  {{8, 24, 2, 11}},
6136  {{20, 26, 18, 23}}}},
6137  {{{{24, 11, 26, 23}},
6138  {{9, 3, 21, 19}},
6139  {{24, 26, 9, 21}},
6140  {{11, 23, 3, 19}},
6141  {{24, 9, 11, 3}},
6142  {{26, 21, 23, 19}}}},
6143  {{{{16, 20, 4, 12}},
6144  {{22, 26, 14, 25}},
6145  {{16, 4, 22, 14}},
6146  {{20, 12, 26, 25}},
6147  {{16, 22, 20, 26}},
6148  {{4, 14, 12, 25}}}},
6149  {{{{22, 26, 14, 25}},
6150  {{17, 21, 5, 13}},
6151  {{22, 14, 17, 5}},
6152  {{26, 25, 21, 13}},
6153  {{22, 17, 26, 21}},
6154  {{14, 5, 25, 13}}}},
6155  {{{{20, 18, 12, 6}},
6156  {{26, 23, 25, 15}},
6157  {{20, 12, 26, 25}},
6158  {{18, 6, 23, 15}},
6159  {{20, 26, 18, 23}},
6160  {{12, 25, 6, 15}}}},
6161  {{{{26, 23, 25, 15}},
6162  {{21, 19, 13, 7}},
6163  {{26, 25, 21, 13}},
6164  {{23, 15, 19, 7}},
6165  {{26, 21, 23, 19}},
6166  {{25, 13, 15, 7}}}}}};
6167 
6168  static constexpr std::
6169  array<std::array<std::array<unsigned int, 4>, 6>, 8>
6170  cell_face_vertices_tet{{{{{{0, 4, 6, X}},
6171  {{4, 0, 7, X}},
6172  {{0, 6, 7, X}},
6173  {{6, 4, 7, X}},
6174  {{X, X, X, X}},
6175  {{X, X, X, X}}}},
6176  {{{{4, 1, 5, X}},
6177  {{1, 4, 8, X}},
6178  {{4, 5, 8, X}},
6179  {{5, 1, 8, X}},
6180  {{X, X, X, X}},
6181  {{X, X, X, X}}}},
6182  {{{{6, 5, 2, X}},
6183  {{5, 6, 9, X}},
6184  {{6, 2, 9, X}},
6185  {{2, 5, 9, X}},
6186  {{X, X, X, X}},
6187  {{X, X, X, X}}}},
6188  {{{{7, 8, 9, X}},
6189  {{8, 7, 3, X}},
6190  {{7, 9, 3, X}},
6191  {{9, 8, 3, X}},
6192  {{X, X, X, X}},
6193  {{X, X, X, X}}}},
6194  {{{{4, 5, 6, X}},
6195  {{5, 4, 8, X}},
6196  {{4, 6, 8, X}},
6197  {{6, 5, 8, X}},
6198  {{X, X, X, X}},
6199  {{X, X, X, X}}}},
6200  {{{{4, 7, 8, X}},
6201  {{7, 4, 6, X}},
6202  {{4, 8, 6, X}},
6203  {{8, 7, 6, X}},
6204  {{X, X, X, X}},
6205  {{X, X, X, X}}}},
6206  {{{{6, 9, 7, X}},
6207  {{9, 6, 8, X}},
6208  {{6, 7, 8, X}},
6209  {{7, 9, 8, X}},
6210  {{X, X, X, X}},
6211  {{X, X, X, X}}}},
6212  {{{{5, 8, 9, X}},
6213  {{8, 5, 6, X}},
6214  {{5, 9, 6, X}},
6215  {{9, 8, 6, X}},
6216  {{X, X, X, X}},
6217  {{X, X, X, X}}}}}};
6218 
6219  const auto &cell_quads =
6220  (reference_cell_type == ReferenceCells::Hexahedron) ?
6221  cell_quads_hex :
6222  cell_quads_tet;
6223 
6224  const auto &cell_face_vertices =
6225  (reference_cell_type == ReferenceCells::Hexahedron) ?
6226  cell_face_vertices_hex :
6227  cell_face_vertices_tet;
6228 
6229  for (unsigned int c = 0;
6230  c < GeometryInfo<dim>::max_children_per_cell;
6231  ++c)
6232  {
6233  auto &new_hex = new_hexes[c];
6234 
6235  if (new_hex->n_faces() == 4)
6236  new_hex->set_bounding_object_indices(
6237  {quad_indices[cell_quads[c][0]],
6238  quad_indices[cell_quads[c][1]],
6239  quad_indices[cell_quads[c][2]],
6240  quad_indices[cell_quads[c][3]]});
6241  else if (new_hex->n_faces() == 6)
6242  new_hex->set_bounding_object_indices(
6243  {quad_indices[cell_quads[c][0]],
6244  quad_indices[cell_quads[c][1]],
6245  quad_indices[cell_quads[c][2]],
6246  quad_indices[cell_quads[c][3]],
6247  quad_indices[cell_quads[c][4]],
6248  quad_indices[cell_quads[c][5]]});
6249  else
6250  Assert(false, ExcNotImplemented());
6251 
6252  for (const auto f : new_hex->face_indices())
6253  {
6254  std::array<unsigned int, 4> vertices_0, vertices_1;
6255 
6256  const auto &face = new_hex->face(f);
6257 
6258  for (const auto i : face->vertex_indices())
6259  vertices_0[i] = face->vertex_index(i);
6260 
6261  for (const auto i : face->vertex_indices())
6262  vertices_1[i] =
6263  vertex_indices[cell_face_vertices[c][f][i]];
6264 
6265  const auto orientation =
6266  face->reference_cell().compute_orientation(
6267  vertices_1, vertices_0);
6268 
6269  new_hex->set_face_orientation(
6270  f, Utilities::get_bit(orientation, 0));
6271  new_hex->set_face_flip(
6272  f, Utilities::get_bit(orientation, 2));
6273  new_hex->set_face_rotation(
6274  f, Utilities::get_bit(orientation, 1));
6275  }
6276  }
6277  }
6278  }
6279 
6280  if (check_for_distorted_cells &&
6281  has_distorted_children<dim, spacedim>(hex))
6282  cells_with_distorted_children.distorted_cells.push_back(hex);
6283 
6284  triangulation.signals.post_refinement_on_cell(hex);
6285  }
6286  }
6287 
6288  triangulation.faces->quads.clear_user_data();
6289 
6290  return cells_with_distorted_children;
6291  }
6292 
6297  template <int spacedim>
6300  const bool check_for_distorted_cells)
6301  {
6302  const unsigned int dim = 3;
6303 
6304  {
6305  bool flag_isotropic_mesh = true;
6307  cell = triangulation.begin(),
6308  endc = triangulation.end();
6309  for (; cell != endc; ++cell)
6310  if (cell->used())
6311  if (triangulation.get_anisotropic_refinement_flag() ||
6312  cell->refine_flag_set() == RefinementCase<dim>::cut_x ||
6313  cell->refine_flag_set() == RefinementCase<dim>::cut_y ||
6314  cell->refine_flag_set() == RefinementCase<dim>::cut_z ||
6315  cell->refine_flag_set() == RefinementCase<dim>::cut_xy ||
6316  cell->refine_flag_set() == RefinementCase<dim>::cut_xz ||
6317  cell->refine_flag_set() == RefinementCase<dim>::cut_yz)
6318  {
6319  flag_isotropic_mesh = false;
6320  break;
6321  }
6322 
6323  if (flag_isotropic_mesh)
6324  return execute_refinement_isotropic(triangulation,
6325  check_for_distorted_cells);
6326  }
6327 
6328  // this function probably also works for spacedim>3 but it
6329  // isn't tested. it will probably be necessary to pull new
6330  // vertices onto the manifold just as we do for the other
6331  // functions above.
6332  Assert(spacedim == 3, ExcNotImplemented());
6333 
6334  // Check whether a new level is needed. We have to check for
6335  // this on the highest level only
6336  for (const auto &cell : triangulation.active_cell_iterators_on_level(
6337  triangulation.levels.size() - 1))
6338  if (cell->refine_flag_set())
6339  {
6340  triangulation.levels.push_back(
6341  std::make_unique<
6343  break;
6344  }
6345 
6346 
6347  // first clear user flags for quads and lines; we're going to
6348  // use them to flag which lines and quads need refinement
6349  triangulation.faces->quads.clear_user_data();
6350 
6351  for (typename Triangulation<dim, spacedim>::line_iterator line =
6352  triangulation.begin_line();
6353  line != triangulation.end_line();
6354  ++line)
6355  line->clear_user_flag();
6356  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
6357  triangulation.begin_quad();
6358  quad != triangulation.end_quad();
6359  ++quad)
6360  quad->clear_user_flag();
6361 
6362  // create an array of face refine cases. User indices of faces
6363  // will be set to values corresponding with indices in this
6364  // array.
6365  const RefinementCase<dim - 1> face_refinement_cases[4] = {
6366  RefinementCase<dim - 1>::no_refinement,
6367  RefinementCase<dim - 1>::cut_x,
6368  RefinementCase<dim - 1>::cut_y,
6369  RefinementCase<dim - 1>::cut_xy};
6370 
6371  // check how much space is needed on every level. We need not
6372  // check the highest level since either
6373  // - on the highest level no cells are flagged for refinement
6374  // - there are, but prepare_refinement added another empty
6375  // level which then is the highest level
6376 
6377  // variables to hold the number of newly to be created
6378  // vertices, lines and quads. as these are stored globally,
6379  // declare them outside the loop over al levels. we need lines
6380  // and quads in pairs for refinement of old ones and lines and
6381  // quads, that can be stored as single ones, as they are newly
6382  // created in the inside of an existing cell
6383  unsigned int needed_vertices = 0;
6384  unsigned int needed_lines_single = 0;
6385  unsigned int needed_quads_single = 0;
6386  unsigned int needed_lines_pair = 0;
6387  unsigned int needed_quads_pair = 0;
6388  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
6389  {
6390  // count number of flagged cells on this level and compute
6391  // how many new vertices and new lines will be needed
6392  unsigned int new_cells = 0;
6393 
6394  for (const auto &acell :
6395  triangulation.active_cell_iterators_on_level(level))
6396  if (acell->refine_flag_set())
6397  {
6398  RefinementCase<dim> ref_case = acell->refine_flag_set();
6399 
6400  // now for interior vertices, lines and quads, which
6401  // are needed in any case
6402  if (ref_case == RefinementCase<dim>::cut_x ||
6403  ref_case == RefinementCase<dim>::cut_y ||
6404  ref_case == RefinementCase<dim>::cut_z)
6405  {
6406  ++needed_quads_single;
6407  new_cells += 2;
6408  triangulation.anisotropic_refinement = true;
6409  }
6410  else if (ref_case == RefinementCase<dim>::cut_xy ||
6411  ref_case == RefinementCase<dim>::cut_xz ||
6412  ref_case == RefinementCase<dim>::cut_yz)
6413  {
6414  ++needed_lines_single;
6415  needed_quads_single += 4;
6416  new_cells += 4;
6417  triangulation.anisotropic_refinement = true;
6418  }
6419  else if (ref_case == RefinementCase<dim>::cut_xyz)
6420  {
6421  ++needed_vertices;
6422  needed_lines_single += 6;
6423  needed_quads_single += 12;
6424  new_cells += 8;
6425  }
6426  else
6427  {
6428  // we should never get here
6429  Assert(false, ExcInternalError());
6430  }
6431 
6432  // mark all faces for refinement; checking locally
6433  // if and how the neighbor would like to refine
6434  // these is difficult so we only flag them and after
6435  // visiting all cells, we decide which faces need
6436  // which refinement;
6437  for (const unsigned int face :
6439  {
6441  aface = acell->face(face);
6442  // get the RefineCase this faces has for the
6443  // given RefineCase of the cell
6444  RefinementCase<dim - 1> face_ref_case =
6446  ref_case,
6447  face,
6448  acell->face_orientation(face),
6449  acell->face_flip(face),
6450  acell->face_rotation(face));
6451  // only do something, if this face has to be
6452  // refined
6453  if (face_ref_case)
6454  {
6455  if (face_ref_case ==
6457  {
6458  if (aface->n_active_descendants() < 4)
6459  // we use user_flags to denote needed
6460  // isotropic refinement
6461  aface->set_user_flag();
6462  }
6463  else if (aface->refinement_case() != face_ref_case)
6464  // we use user_indices to denote needed
6465  // anisotropic refinement. note, that we
6466  // can have at most one anisotropic
6467  // refinement case for this face, as
6468  // otherwise prepare_refinement() would
6469  // have changed one of the cells to yield
6470  // isotropic refinement at this
6471  // face. therefore we set the user_index
6472  // uniquely
6473  {
6474  Assert(aface->refinement_case() ==
6476  dim - 1>::isotropic_refinement ||
6477  aface->refinement_case() ==
6479  ExcInternalError());
6480  aface->set_user_index(face_ref_case);
6481  }
6482  }
6483  } // for all faces
6484 
6485  // flag all lines, that have to be refined
6486  for (unsigned int line = 0;
6487  line < GeometryInfo<dim>::lines_per_cell;
6488  ++line)
6490  line) &&
6491  !acell->line(line)->has_children())
6492  acell->line(line)->set_user_flag();
6493 
6494  } // if refine_flag set and for all cells on this level
6495 
6496 
6497  // count number of used cells on the next higher level
6498  const unsigned int used_cells =
6499  std::count(triangulation.levels[level + 1]->cells.used.begin(),
6500  triangulation.levels[level + 1]->cells.used.end(),
6501  true);
6502 
6503 
6504  // reserve space for the used_cells cells already existing
6505  // on the next higher level as well as for the
6506  // 8*flagged_cells that will be created on that level
6507  reserve_space(*triangulation.levels[level + 1],
6508  used_cells + new_cells,
6509  3,
6510  spacedim);
6511  // reserve space for 8*flagged_cells new hexes on the next
6512  // higher level
6513  reserve_space(triangulation.levels[level + 1]->cells, new_cells);
6514  } // for all levels
6515  // now count the quads and lines which were flagged for
6516  // refinement
6517  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
6518  triangulation.begin_quad();
6519  quad != triangulation.end_quad();
6520  ++quad)
6521  {
6522  if (quad->user_flag_set())
6523  {
6524  // isotropic refinement: 1 interior vertex, 4 quads
6525  // and 4 interior lines. we store the interior lines
6526  // in pairs in case the face is already or will be
6527  // refined anisotropically
6528  needed_quads_pair += 4;
6529  needed_lines_pair += 4;
6530  needed_vertices += 1;
6531  }
6532  if (quad->user_index())
6533  {
6534  // anisotropic refinement: 1 interior
6535  // line and two quads
6536  needed_quads_pair += 2;
6537  needed_lines_single += 1;
6538  // there is a kind of complicated situation here which
6539  // requires our attention. if the quad is refined
6540  // isotropcally, two of the interior lines will get a
6541  // new mother line - the interior line of our
6542  // anisotropically refined quad. if those two lines
6543  // are not consecutive, we cannot do so and have to
6544  // replace them by two lines that are consecutive. we
6545  // try to avoid that situation, but it may happen
6546  // nevertheless through repeated refinement and
6547  // coarsening. thus we have to check here, as we will
6548  // need some additional space to store those new lines
6549  // in case we need them...
6550  if (quad->has_children())
6551  {
6552  Assert(quad->refinement_case() ==
6554  ExcInternalError());
6555  if ((face_refinement_cases[quad->user_index()] ==
6557  (quad->child(0)->line_index(1) + 1 !=
6558  quad->child(2)->line_index(1))) ||
6559  (face_refinement_cases[quad->user_index()] ==
6561  (quad->child(0)->line_index(3) + 1 !=
6562  quad->child(1)->line_index(3))))
6563  needed_lines_pair += 2;
6564  }
6565  }
6566  }
6567 
6568  for (typename Triangulation<dim, spacedim>::line_iterator line =
6569  triangulation.begin_line();
6570  line != triangulation.end_line();
6571  ++line)
6572  if (line->user_flag_set())
6573  {
6574  needed_lines_pair += 2;
6575  needed_vertices += 1;
6576  }
6577 
6578  // reserve space for needed_lines new lines stored in pairs
6579  reserve_space(triangulation.faces->lines,
6580  needed_lines_pair,
6581  needed_lines_single);
6582  // reserve space for needed_quads new quads stored in pairs
6584  needed_quads_pair,
6585  needed_quads_single);
6586  reserve_space(triangulation.faces->quads,
6587  needed_quads_pair,
6588  needed_quads_single);
6589 
6590 
6591  // add to needed vertices how many vertices are already in use
6592  needed_vertices += std::count(triangulation.vertices_used.begin(),
6593  triangulation.vertices_used.end(),
6594  true);
6595  // if we need more vertices: create them, if not: leave the
6596  // array as is, since shrinking is not really possible because
6597  // some of the vertices at the end may be in use
6598  if (needed_vertices > triangulation.vertices.size())
6599  {
6600  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
6601  triangulation.vertices_used.resize(needed_vertices, false);
6602  }
6603 
6604 
6605  //-----------------------------------------
6606  // Before we start with the actual refinement, we do some
6607  // sanity checks if in debug mode. especially, we try to catch
6608  // the notorious problem with lines being twice refined,
6609  // i.e. there are cells adjacent at one line ("around the
6610  // edge", but not at a face), with two cells differing by more
6611  // than one refinement level
6612  //
6613  // this check is very simple to implement here, since we have
6614  // all lines flagged if they shall be refined
6615 #ifdef DEBUG
6616  for (const auto &cell : triangulation.active_cell_iterators())
6617  if (!cell->refine_flag_set())
6618  for (unsigned int line = 0;
6619  line < GeometryInfo<dim>::lines_per_cell;
6620  ++line)
6621  if (cell->line(line)->has_children())
6622  for (unsigned int c = 0; c < 2; ++c)
6623  Assert(cell->line(line)->child(c)->user_flag_set() == false,
6624  ExcInternalError());
6625 #endif
6626 
6627  //-----------------------------------------
6628  // Do refinement on every level
6629  //
6630  // To make life a bit easier, we first refine those lines and
6631  // quads that were flagged for refinement and then compose the
6632  // newly to be created cells.
6633  //
6634  // index of next unused vertex
6635  unsigned int next_unused_vertex = 0;
6636 
6637  // first for lines
6638  {
6639  // only active objects can be refined further
6641  line = triangulation.begin_active_line(),
6642  endl = triangulation.end_line();
6644  next_unused_line = triangulation.begin_raw_line();
6645 
6646  for (; line != endl; ++line)
6647  if (line->user_flag_set())
6648  {
6649  // this line needs to be refined
6650 
6651  // find the next unused vertex and set it
6652  // appropriately
6653  while (triangulation.vertices_used[next_unused_vertex] == true)
6654  ++next_unused_vertex;
6655  Assert(
6656  next_unused_vertex < triangulation.vertices.size(),
6657  ExcMessage(
6658  "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."));
6659  triangulation.vertices_used[next_unused_vertex] = true;
6660 
6661  triangulation.vertices[next_unused_vertex] = line->center(true);
6662 
6663  // now that we created the right point, make up the
6664  // two child lines (++ takes care of the end of the
6665  // vector)
6666  next_unused_line =
6667  triangulation.faces->lines.template next_free_pair_object<1>(
6668  triangulation);
6669  Assert(next_unused_line.state() == IteratorState::valid,
6670  ExcInternalError());
6671 
6672  // now we found two consecutive unused lines, such
6673  // that the children of a line will be consecutive.
6674  // then set the child pointer of the present line
6675  line->set_children(0, next_unused_line->index());
6676 
6677  // set the two new lines
6679  children[2] = {next_unused_line, ++next_unused_line};
6680 
6681  // some tests; if any of the iterators should be
6682  // invalid, then already dereferencing will fail
6683  AssertIsNotUsed(children[0]);
6684  AssertIsNotUsed(children[1]);
6685 
6686  children[0]->set_bounding_object_indices(
6687  {line->vertex_index(0), next_unused_vertex});
6688  children[1]->set_bounding_object_indices(
6689  {next_unused_vertex, line->vertex_index(1)});
6690 
6691  children[0]->set_used_flag();
6692  children[1]->set_used_flag();
6693  children[0]->clear_children();
6694  children[1]->clear_children();
6695  children[0]->clear_user_data();
6696  children[1]->clear_user_data();
6697  children[0]->clear_user_flag();
6698  children[1]->clear_user_flag();
6699 
6700  children[0]->set_boundary_id_internal(line->boundary_id());
6701  children[1]->set_boundary_id_internal(line->boundary_id());
6702 
6703  children[0]->set_manifold_id(line->manifold_id());
6704  children[1]->set_manifold_id(line->manifold_id());
6705 
6706  // finally clear flag
6707  // indicating the need
6708  // for refinement
6709  line->clear_user_flag();
6710  }
6711  }
6712 
6713 
6714  //-------------------------------------
6715  // now refine marked quads
6716  //-------------------------------------
6717 
6718  // here we encounter several cases:
6719 
6720  // a) the quad is unrefined and shall be refined isotropically
6721 
6722  // b) the quad is unrefined and shall be refined
6723  // anisotropically
6724 
6725  // c) the quad is unrefined and shall be refined both
6726  // anisotropically and isotropically (this is reduced to case
6727  // b) and then case b) for the children again)
6728 
6729  // d) the quad is refined anisotropically and shall be refined
6730  // isotropically (this is reduced to case b) for the
6731  // anisotropic children)
6732 
6733  // e) the quad is refined isotropically and shall be refined
6734  // anisotropically (this is transformed to case c), however we
6735  // might have to renumber/rename children...)
6736 
6737  // we need a loop in cases c) and d), as the anisotropic
6738  // children might have a lower index than the mother quad
6739  for (unsigned int loop = 0; loop < 2; ++loop)
6740  {
6741  // usually, only active objects can be refined
6742  // further. however, in cases d) and e) that is not true,
6743  // so we have to use 'normal' iterators here
6745  quad = triangulation.begin_quad(),
6746  endq = triangulation.end_quad();
6748  next_unused_line = triangulation.begin_raw_line();
6750  next_unused_quad = triangulation.begin_raw_quad();
6751 
6752  for (; quad != endq; ++quad)
6753  {
6754  if (quad->user_index())
6755  {
6756  RefinementCase<dim - 1> aniso_quad_ref_case =
6757  face_refinement_cases[quad->user_index()];
6758  // there is one unlikely event here, where we
6759  // already have refind the face: if the face was
6760  // refined anisotropically and we want to refine
6761  // it isotropically, both children are flagged for
6762  // anisotropic refinement. however, if those
6763  // children were already flagged for anisotropic
6764  // refinement, they might already be processed and
6765  // refined.
6766  if (aniso_quad_ref_case == quad->refinement_case())
6767  continue;
6768 
6769  Assert(quad->refinement_case() ==
6771  quad->refinement_case() ==
6773  ExcInternalError());
6774 
6775  // this quad needs to be refined anisotropically
6776  Assert(quad->user_index() ==
6778  quad->user_index() ==
6780  ExcInternalError());
6781 
6782  // make the new line interior to the quad
6784  new_line;
6785 
6786  new_line =
6787  triangulation.faces->lines
6788  .template next_free_single_object<1>(triangulation);
6789  AssertIsNotUsed(new_line);
6790 
6791  // first collect the
6792  // indices of the vertices:
6793  // *--1--*
6794  // | | |
6795  // | | | cut_x
6796  // | | |
6797  // *--0--*
6798  //
6799  // *-----*
6800  // | |
6801  // 0-----1 cut_y
6802  // | |
6803  // *-----*
6804  unsigned int vertex_indices[2];
6805  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
6806  {
6807  vertex_indices[0] =
6808  quad->line(2)->child(0)->vertex_index(1);
6809  vertex_indices[1] =
6810  quad->line(3)->child(0)->vertex_index(1);
6811  }
6812  else
6813  {
6814  vertex_indices[0] =
6815  quad->line(0)->child(0)->vertex_index(1);
6816  vertex_indices[1] =
6817  quad->line(1)->child(0)->vertex_index(1);
6818  }
6819 
6820  new_line->set_bounding_object_indices(
6821  {vertex_indices[0], vertex_indices[1]});
6822  new_line->set_used_flag();
6823  new_line->clear_user_flag();
6824  new_line->clear_user_data();
6825  new_line->clear_children();
6826  new_line->set_boundary_id_internal(quad->boundary_id());
6827  new_line->set_manifold_id(quad->manifold_id());
6828 
6829  // child 0 and 1 of a line are switched if the
6830  // line orientation is false. set up a miniature
6831  // table, indicating which child to take for line
6832  // orientations false and true. first index: child
6833  // index in standard orientation, second index:
6834  // line orientation
6835  const unsigned int index[2][2] = {
6836  {1, 0}, // child 0, line_orientation=false and true
6837  {0, 1}}; // child 1, line_orientation=false and true
6838 
6839  // find some space (consecutive) for the two newly
6840  // to be created quads.
6842  new_quads[2];
6843 
6844  next_unused_quad =
6845  triangulation.faces->quads
6846  .template next_free_pair_object<2>(triangulation);
6847  new_quads[0] = next_unused_quad;
6848  AssertIsNotUsed(new_quads[0]);
6849 
6850  ++next_unused_quad;
6851  new_quads[1] = next_unused_quad;
6852  AssertIsNotUsed(new_quads[1]);
6853 
6854  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
6855  {
6856  new_quads[0]->set_bounding_object_indices(
6857  {static_cast<int>(quad->line_index(0)),
6858  new_line->index(),
6859  quad->line(2)
6860  ->child(index[0][quad->line_orientation(2)])
6861  ->index(),
6862  quad->line(3)
6863  ->child(index[0][quad->line_orientation(3)])
6864  ->index()});
6865  new_quads[1]->set_bounding_object_indices(
6866  {new_line->index(),
6867  static_cast<int>(quad->line_index(1)),
6868  quad->line(2)
6869  ->child(index[1][quad->line_orientation(2)])
6870  ->index(),
6871  quad->line(3)
6872  ->child(index[1][quad->line_orientation(3)])
6873  ->index()});
6874  }
6875  else
6876  {
6877  new_quads[0]->set_bounding_object_indices(
6878  {quad->line(0)
6879  ->child(index[0][quad->line_orientation(0)])
6880  ->index(),
6881  quad->line(1)
6882  ->child(index[0][quad->line_orientation(1)])
6883  ->index(),
6884  static_cast<int>(quad->line_index(2)),
6885  new_line->index()});
6886  new_quads[1]->set_bounding_object_indices(
6887  {quad->line(0)
6888  ->child(index[1][quad->line_orientation(0)])
6889  ->index(),
6890  quad->line(1)
6891  ->child(index[1][quad->line_orientation(1)])
6892  ->index(),
6893  new_line->index(),
6894  static_cast<int>(quad->line_index(3))});
6895  }
6896 
6897  for (const auto &new_quad : new_quads)
6898  {
6899  new_quad->set_used_flag();
6900  new_quad->clear_user_flag();
6901  new_quad->clear_user_data();
6902  new_quad->clear_children();
6903  new_quad->set_boundary_id_internal(quad->boundary_id());
6904  new_quad->set_manifold_id(quad->manifold_id());
6905  // set all line orientations to true, change
6906  // this after the loop, as we have to consider
6907  // different lines for each child
6908  for (unsigned int j = 0;
6909  j < GeometryInfo<dim>::lines_per_face;
6910  ++j)
6911  new_quad->set_line_orientation(j, true);
6912  }
6913  // now set the line orientation of children of
6914  // outer lines correctly, the lines in the
6915  // interior of the refined quad are automatically
6916  // oriented conforming to the standard
6917  new_quads[0]->set_line_orientation(
6918  0, quad->line_orientation(0));
6919  new_quads[0]->set_line_orientation(
6920  2, quad->line_orientation(2));
6921  new_quads[1]->set_line_orientation(
6922  1, quad->line_orientation(1));
6923  new_quads[1]->set_line_orientation(
6924  3, quad->line_orientation(3));
6925  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
6926  {
6927  new_quads[0]->set_line_orientation(
6928  3, quad->line_orientation(3));
6929  new_quads[1]->set_line_orientation(
6930  2, quad->line_orientation(2));
6931  }
6932  else
6933  {
6934  new_quads[0]->set_line_orientation(
6935  1, quad->line_orientation(1));
6936  new_quads[1]->set_line_orientation(
6937  0, quad->line_orientation(0));
6938  }
6939 
6940  // test, whether this face is refined
6941  // isotropically already. if so, set the correct
6942  // children pointers.
6943  if (quad->refinement_case() ==
6944  RefinementCase<dim - 1>::cut_xy)
6945  {
6946  // we will put a new refinemnt level of
6947  // anisotropic refinement between the
6948  // unrefined and isotropically refined quad
6949  // ending up with the same fine quads but
6950  // introducing anisotropically refined ones as
6951  // children of the unrefined quad and mother
6952  // cells of the original fine ones.
6953 
6954  // this process includes the creation of a new
6955  // middle line which we will assign as the
6956  // mother line of two of the existing inner
6957  // lines. If those inner lines are not
6958  // consecutive in memory, we won't find them
6959  // later on, so we have to create new ones
6960  // instead and replace all occurrences of the
6961  // old ones with those new ones. As this is
6962  // kind of ugly, we hope we don't have to do
6963  // it often...
6965  old_child[2];
6966  if (aniso_quad_ref_case ==
6968  {
6969  old_child[0] = quad->child(0)->line(1);
6970  old_child[1] = quad->child(2)->line(1);
6971  }
6972  else
6973  {
6974  Assert(aniso_quad_ref_case ==
6976  ExcInternalError());
6977 
6978  old_child[0] = quad->child(0)->line(3);
6979  old_child[1] = quad->child(1)->line(3);
6980  }
6981 
6982  if (old_child[0]->index() + 1 != old_child[1]->index())
6983  {
6984  // this is exactly the ugly case we taked
6985  // about. so, no coimplaining, lets get
6986  // two new lines and copy all info
6987  typename Triangulation<dim,
6988  spacedim>::raw_line_iterator
6989  new_child[2];
6990 
6991  new_child[0] = new_child[1] =
6992  triangulation.faces->lines
6993  .template next_free_pair_object<1>(
6994  triangulation);
6995  ++new_child[1];
6996 
6997  new_child[0]->set_used_flag();
6998  new_child[1]->set_used_flag();
6999 
7000  const int old_index_0 = old_child[0]->index(),
7001  old_index_1 = old_child[1]->index(),
7002  new_index_0 = new_child[0]->index(),
7003  new_index_1 = new_child[1]->index();
7004 
7005  // loop over all quads and replace the old
7006  // lines
7007  for (unsigned int q = 0;
7008  q < triangulation.faces->quads.n_objects();
7009  ++q)
7010  for (unsigned int l = 0;
7011  l < GeometryInfo<dim>::lines_per_face;
7012  ++l)
7013  {
7014  const int this_index =
7015  triangulation.faces->quads
7016  .get_bounding_object_indices(q)[l];
7017  if (this_index == old_index_0)
7018  triangulation.faces->quads
7019  .get_bounding_object_indices(q)[l] =
7020  new_index_0;
7021  else if (this_index == old_index_1)
7022  triangulation.faces->quads
7023  .get_bounding_object_indices(q)[l] =
7024  new_index_1;
7025  }
7026  // now we have to copy all information of
7027  // the two lines
7028  for (unsigned int i = 0; i < 2; ++i)
7029  {
7030  Assert(!old_child[i]->has_children(),
7031  ExcInternalError());
7032 
7033  new_child[i]->set_bounding_object_indices(
7034  {old_child[i]->vertex_index(0),
7035  old_child[i]->vertex_index(1)});
7036  new_child[i]->set_boundary_id_internal(
7037  old_child[i]->boundary_id());
7038  new_child[i]->set_manifold_id(
7039  old_child[i]->manifold_id());
7040  new_child[i]->set_user_index(
7041  old_child[i]->user_index());
7042  if (old_child[i]->user_flag_set())
7043  new_child[i]->set_user_flag();
7044  else
7045  new_child[i]->clear_user_flag();
7046 
7047  new_child[i]->clear_children();
7048 
7049  old_child[i]->clear_user_flag();
7050  old_child[i]->clear_user_index();
7051  old_child[i]->clear_used_flag();
7052  }
7053  }
7054  // now that we cared about the lines, go on
7055  // with the quads themselves, where we might
7056  // encounter similar situations...
7057  if (aniso_quad_ref_case ==
7059  {
7060  new_line->set_children(
7061  0, quad->child(0)->line_index(1));
7062  Assert(new_line->child(1) ==
7063  quad->child(2)->line(1),
7064  ExcInternalError());
7065  // now evereything is quite
7066  // complicated. we have the children
7067  // numbered according to
7068  //
7069  // *---*---*
7070  // |n+2|n+3|
7071  // *---*---*
7072  // | n |n+1|
7073  // *---*---*
7074  //
7075  // from the original isotropic
7076  // refinement. we have to reorder them as
7077  //
7078  // *---*---*
7079  // |n+1|n+3|
7080  // *---*---*
7081  // | n |n+2|
7082  // *---*---*
7083  //
7084  // such that n and n+1 are consecutive
7085  // children of m and n+2 and n+3 are
7086  // consecutive children of m+1, where m
7087  // and m+1 are given as in
7088  //
7089  // *---*---*
7090  // | | |
7091  // | m |m+1|
7092  // | | |
7093  // *---*---*
7094  //
7095  // this is a bit ugly, of course: loop
7096  // over all cells on all levels and look
7097  // for faces n+1 (switch_1) and n+2
7098  // (switch_2).
7099  const typename Triangulation<dim, spacedim>::
7100  quad_iterator switch_1 = quad->child(1),
7101  switch_2 = quad->child(2);
7102  const int switch_1_index = switch_1->index();
7103  const int switch_2_index = switch_2->index();
7104  for (unsigned int l = 0;
7105  l < triangulation.levels.size();
7106  ++l)
7107  for (unsigned int h = 0;
7108  h <
7109  triangulation.levels[l]->cells.n_objects();
7110  ++h)
7111  for (const unsigned int q :
7113  {
7114  const int face_index =
7115  triangulation.levels[l]
7116  ->cells.get_bounding_object_indices(
7117  h)[q];
7118  if (face_index == switch_1_index)
7119  triangulation.levels[l]
7120  ->cells.get_bounding_object_indices(
7121  h)[q] = switch_2_index;
7122  else if (face_index == switch_2_index)
7123  triangulation.levels[l]
7124  ->cells.get_bounding_object_indices(
7125  h)[q] = switch_1_index;
7126  }
7127  // now we have to copy all information of
7128  // the two quads
7129  const unsigned int switch_1_lines[4] = {
7130  switch_1->line_index(0),
7131  switch_1->line_index(1),
7132  switch_1->line_index(2),
7133  switch_1->line_index(3)};
7134  const bool switch_1_line_orientations[4] = {
7135  switch_1->line_orientation(0),
7136  switch_1->line_orientation(1),
7137  switch_1->line_orientation(2),
7138  switch_1->line_orientation(3)};
7139  const types::boundary_id switch_1_boundary_id =
7140  switch_1->boundary_id();
7141  const unsigned int switch_1_user_index =
7142  switch_1->user_index();
7143  const bool switch_1_user_flag =
7144  switch_1->user_flag_set();
7145  const RefinementCase<dim - 1>
7146  switch_1_refinement_case =
7147  switch_1->refinement_case();
7148  const int switch_1_first_child_pair =
7149  (switch_1_refinement_case ?
7150  switch_1->child_index(0) :
7151  -1);
7152  const int switch_1_second_child_pair =
7153  (switch_1_refinement_case ==
7154  RefinementCase<dim - 1>::cut_xy ?
7155  switch_1->child_index(2) :
7156  -1);
7157 
7158  switch_1->set_bounding_object_indices(
7159  {switch_2->line_index(0),
7160  switch_2->line_index(1),
7161  switch_2->line_index(2),
7162  switch_2->line_index(3)});
7163  switch_1->set_line_orientation(
7164  0, switch_2->line_orientation(0));
7165  switch_1->set_line_orientation(
7166  1, switch_2->line_orientation(1));
7167  switch_1->set_line_orientation(
7168  2, switch_2->line_orientation(2));
7169  switch_1->set_line_orientation(
7170  3, switch_2->line_orientation(3));
7171  switch_1->set_boundary_id_internal(
7172  switch_2->boundary_id());
7173  switch_1->set_manifold_id(switch_2->manifold_id());
7174  switch_1->set_user_index(switch_2->user_index());
7175  if (switch_2->user_flag_set())
7176  switch_1->set_user_flag();
7177  else
7178  switch_1->clear_user_flag();
7179  switch_1->clear_refinement_case();
7180  switch_1->set_refinement_case(
7181  switch_2->refinement_case());
7182  switch_1->clear_children();
7183  if (switch_2->refinement_case())
7184  switch_1->set_children(0,
7185  switch_2->child_index(0));
7186  if (switch_2->refinement_case() ==
7187  RefinementCase<dim - 1>::cut_xy)
7188  switch_1->set_children(2,
7189  switch_2->child_index(2));
7190 
7191  switch_2->set_bounding_object_indices(
7192  {switch_1_lines[0],
7193  switch_1_lines[1],
7194  switch_1_lines[2],
7195  switch_1_lines[3]});
7196  switch_2->set_line_orientation(
7197  0, switch_1_line_orientations[0]);
7198  switch_2->set_line_orientation(
7199  1, switch_1_line_orientations[1]);
7200  switch_2->set_line_orientation(
7201  2, switch_1_line_orientations[2]);
7202  switch_2->set_line_orientation(
7203  3, switch_1_line_orientations[3]);
7204  switch_2->set_boundary_id_internal(
7205  switch_1_boundary_id);
7206  switch_2->set_manifold_id(switch_1->manifold_id());
7207  switch_2->set_user_index(switch_1_user_index);
7208  if (switch_1_user_flag)
7209  switch_2->set_user_flag();
7210  else
7211  switch_2->clear_user_flag();
7212  switch_2->clear_refinement_case();
7213  switch_2->set_refinement_case(
7214  switch_1_refinement_case);
7215  switch_2->clear_children();
7216  switch_2->set_children(0,
7217  switch_1_first_child_pair);
7218  switch_2->set_children(2,
7219  switch_1_second_child_pair);
7220 
7221  new_quads[0]->set_refinement_case(
7223  new_quads[0]->set_children(0, quad->child_index(0));
7224  new_quads[1]->set_refinement_case(
7226  new_quads[1]->set_children(0, quad->child_index(2));
7227  }
7228  else
7229  {
7230  new_quads[0]->set_refinement_case(
7232  new_quads[0]->set_children(0, quad->child_index(0));
7233  new_quads[1]->set_refinement_case(
7235  new_quads[1]->set_children(0, quad->child_index(2));
7236  new_line->set_children(
7237  0, quad->child(0)->line_index(3));
7238  Assert(new_line->child(1) ==
7239  quad->child(1)->line(3),
7240  ExcInternalError());
7241  }
7242  quad->clear_children();
7243  }
7244 
7245  // note these quads as children to the present one
7246  quad->set_children(0, new_quads[0]->index());
7247 
7248  quad->set_refinement_case(aniso_quad_ref_case);
7249 
7250  // finally clear flag indicating the need for
7251  // refinement
7252  quad->clear_user_data();
7253  } // if (anisotropic refinement)
7254 
7255  if (quad->user_flag_set())
7256  {
7257  // this quad needs to be refined isotropically
7258 
7259  // first of all: we only get here in the first run
7260  // of the loop
7261  Assert(loop == 0, ExcInternalError());
7262 
7263  // find the next unused vertex. we'll need this in
7264  // any case
7265  while (triangulation.vertices_used[next_unused_vertex] ==
7266  true)
7267  ++next_unused_vertex;
7268  Assert(
7269  next_unused_vertex < triangulation.vertices.size(),
7270  ExcMessage(
7271  "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."));
7272 
7273  // now: if the quad is refined anisotropically
7274  // already, set the anisotropic refinement flag
7275  // for both children. Additionally, we have to
7276  // refine the inner line, as it is an outer line
7277  // of the two (anisotropic) children
7278  const RefinementCase<dim - 1> quad_ref_case =
7279  quad->refinement_case();
7280 
7281  if (quad_ref_case == RefinementCase<dim - 1>::cut_x ||
7282  quad_ref_case == RefinementCase<dim - 1>::cut_y)
7283  {
7284  // set the 'opposite' refine case for children
7285  quad->child(0)->set_user_index(
7286  RefinementCase<dim - 1>::cut_xy - quad_ref_case);
7287  quad->child(1)->set_user_index(
7288  RefinementCase<dim - 1>::cut_xy - quad_ref_case);
7289  // refine the inner line
7291  middle_line;
7292  if (quad_ref_case == RefinementCase<dim - 1>::cut_x)
7293  middle_line = quad->child(0)->line(1);
7294  else
7295  middle_line = quad->child(0)->line(3);
7296 
7297  // if the face has been refined
7298  // anisotropically in the last refinement step
7299  // it might be, that it is flagged already and
7300  // that the middle line is thus refined
7301  // already. if not create children.
7302  if (!middle_line->has_children())
7303  {
7304  // set the middle vertex
7305  // appropriately. double refinement of
7306  // quads can only happen in the interior
7307  // of the domain, so we need not care
7308  // about boundary quads here
7309  triangulation.vertices[next_unused_vertex] =
7310  middle_line->center(true);
7311  triangulation.vertices_used[next_unused_vertex] =
7312  true;
7313 
7314  // now search a slot for the two
7315  // child lines
7316  next_unused_line =
7317  triangulation.faces->lines
7318  .template next_free_pair_object<1>(
7319  triangulation);
7320 
7321  // set the child pointer of the present
7322  // line
7323  middle_line->set_children(
7324  0, next_unused_line->index());
7325 
7326  // set the two new lines
7327  const typename Triangulation<dim, spacedim>::
7328  raw_line_iterator children[2] = {
7329  next_unused_line, ++next_unused_line};
7330 
7331  // some tests; if any of the iterators
7332  // should be invalid, then already
7333  // dereferencing will fail
7334  AssertIsNotUsed(children[0]);
7335  AssertIsNotUsed(children[1]);
7336 
7337  children[0]->set_bounding_object_indices(
7338  {middle_line->vertex_index(0),
7339  next_unused_vertex});
7340  children[1]->set_bounding_object_indices(
7341  {next_unused_vertex,
7342  middle_line->vertex_index(1)});
7343 
7344  children[0]->set_used_flag();
7345  children[1]->set_used_flag();
7346  children[0]->clear_children();
7347  children[1]->clear_children();
7348  children[0]->clear_user_data();
7349  children[1]->clear_user_data();
7350  children[0]->clear_user_flag();
7351  children[1]->clear_user_flag();
7352 
7353  children[0]->set_boundary_id_internal(
7354  middle_line->boundary_id());
7355  children[1]->set_boundary_id_internal(
7356  middle_line->boundary_id());
7357 
7358  children[0]->set_manifold_id(
7359  middle_line->manifold_id());
7360  children[1]->set_manifold_id(
7361  middle_line->manifold_id());
7362  }
7363  // now remove the flag from the quad and go to
7364  // the next quad, the actual refinement of the
7365  // quad takes place later on in this pass of
7366  // the loop or in the next one
7367  quad->clear_user_flag();
7368  continue;
7369  } // if (several refinement cases)
7370 
7371  // if we got here, we have an unrefined quad and
7372  // have to do the usual work like in an purely
7373  // isotropic refinement
7374  Assert(quad_ref_case ==
7376  ExcInternalError());
7377 
7378  // set the middle vertex appropriately: it might be that
7379  // the quad itself is not at the boundary, but that one of
7380  // its lines actually is. in this case, the newly created
7381  // vertices at the centers of the lines are not
7382  // necessarily the mean values of the adjacent vertices,
7383  // so do not compute the new vertex as the mean value of
7384  // the 4 vertices of the face, but rather as a weighted
7385  // mean value of the 8 vertices which we already have (the
7386  // four old ones, and the four ones inserted as middle
7387  // points for the four lines). summing up some more points
7388  // is generally cheaper than first asking whether one of
7389  // the lines is at the boundary
7390  //
7391  // note that the exact weights are chosen such as to
7392  // minimize the distortion of the four new quads from the
7393  // optimal shape. their description uses the formulas
7394  // underlying the TransfiniteInterpolationManifold
7395  // implementation
7396  triangulation.vertices[next_unused_vertex] =
7397  quad->center(true, true);
7398  triangulation.vertices_used[next_unused_vertex] = true;
7399 
7400  // now that we created the right point, make up
7401  // the four lines interior to the quad (++ takes
7402  // care of the end of the vector)
7404  new_lines[4];
7405 
7406  for (unsigned int i = 0; i < 4; ++i)
7407  {
7408  if (i % 2 == 0)
7409  // search a free pair of lines for 0. and
7410  // 2. line, so that two of them end up
7411  // together, which is necessary if later on
7412  // we want to refine the quad
7413  // anisotropically and the two lines end up
7414  // as children of new line
7415  next_unused_line =
7416  triangulation.faces->lines
7417  .template next_free_pair_object<1>(triangulation);
7418 
7419  new_lines[i] = next_unused_line;
7420  ++next_unused_line;
7421 
7422  AssertIsNotUsed(new_lines[i]);
7423  }
7424 
7425  // set the data of the four lines. first collect
7426  // the indices of the five vertices:
7427  //
7428  // *--3--*
7429  // | | |
7430  // 0--4--1
7431  // | | |
7432  // *--2--*
7433  //
7434  // the lines are numbered as follows:
7435  //
7436  // *--*--*
7437  // | 1 |
7438  // *2-*-3*
7439  // | 0 |
7440  // *--*--*
7441 
7442  const unsigned int vertex_indices[5] = {
7443  quad->line(0)->child(0)->vertex_index(1),
7444  quad->line(1)->child(0)->vertex_index(1),
7445  quad->line(2)->child(0)->vertex_index(1),
7446  quad->line(3)->child(0)->vertex_index(1),
7447  next_unused_vertex};
7448 
7449  new_lines[0]->set_bounding_object_indices(
7450  {vertex_indices[2], vertex_indices[4]});
7451  new_lines[1]->set_bounding_object_indices(
7452  {vertex_indices[4], vertex_indices[3]});
7453  new_lines[2]->set_bounding_object_indices(
7454  {vertex_indices[0], vertex_indices[4]});
7455  new_lines[3]->set_bounding_object_indices(
7456  {vertex_indices[4], vertex_indices[1]});
7457 
7458  for (const auto &new_line : new_lines)
7459  {
7460  new_line->set_used_flag();
7461  new_line->clear_user_flag();
7462  new_line->clear_user_data();
7463  new_line->clear_children();
7464  new_line->set_boundary_id_internal(quad->boundary_id());
7465  new_line->set_manifold_id(quad->manifold_id());
7466  }
7467 
7468  // now for the quads. again, first collect some
7469  // data about the indices of the lines, with the
7470  // following numbering:
7471  //
7472  // .-6-.-7-.
7473  // 1 9 3
7474  // .-10.11-.
7475  // 0 8 2
7476  // .-4-.-5-.
7477 
7478  // child 0 and 1 of a line are switched if the
7479  // line orientation is false. set up a miniature
7480  // table, indicating which child to take for line
7481  // orientations false and true. first index: child
7482  // index in standard orientation, second index:
7483  // line orientation
7484  const unsigned int index[2][2] = {
7485  {1, 0}, // child 0, line_orientation=false and true
7486  {0, 1}}; // child 1, line_orientation=false and true
7487 
7488  const int line_indices[12] = {
7489  quad->line(0)
7490  ->child(index[0][quad->line_orientation(0)])
7491  ->index(),
7492  quad->line(0)
7493  ->child(index[1][quad->line_orientation(0)])
7494  ->index(),
7495  quad->line(1)
7496  ->child(index[0][quad->line_orientation(1)])
7497  ->index(),
7498  quad->line(1)
7499  ->child(index[1][quad->line_orientation(1)])
7500  ->index(),
7501  quad->line(2)
7502  ->child(index[0][quad->line_orientation(2)])
7503  ->index(),
7504  quad->line(2)
7505  ->child(index[1][quad->line_orientation(2)])
7506  ->index(),
7507  quad->line(3)
7508  ->child(index[0][quad->line_orientation(3)])
7509  ->index(),
7510  quad->line(3)
7511  ->child(index[1][quad->line_orientation(3)])
7512  ->index(),
7513  new_lines[0]->index(),
7514  new_lines[1]->index(),
7515  new_lines[2]->index(),
7516  new_lines[3]->index()};
7517 
7518  // find some space (consecutive)
7519  // for the first two newly to be
7520  // created quads.
7522  new_quads[4];
7523 
7524  next_unused_quad =
7525  triangulation.faces->quads
7526  .template next_free_pair_object<2>(triangulation);
7527 
7528  new_quads[0] = next_unused_quad;
7529  AssertIsNotUsed(new_quads[0]);
7530 
7531  ++next_unused_quad;
7532  new_quads[1] = next_unused_quad;
7533  AssertIsNotUsed(new_quads[1]);
7534 
7535  next_unused_quad =
7536  triangulation.faces->quads
7537  .template next_free_pair_object<2>(triangulation);
7538  new_quads[2] = next_unused_quad;
7539  AssertIsNotUsed(new_quads[2]);
7540 
7541  ++next_unused_quad;
7542  new_quads[3] = next_unused_quad;
7543  AssertIsNotUsed(new_quads[3]);
7544 
7545  // note these quads as children to the present one
7546  quad->set_children(0, new_quads[0]->index());
7547  quad->set_children(2, new_quads[2]->index());
7548  quad->set_refinement_case(RefinementCase<2>::cut_xy);
7549 
7550  new_quads[0]->set_bounding_object_indices(
7551  {line_indices[0],
7552  line_indices[8],
7553  line_indices[4],
7554  line_indices[10]});
7555  new_quads[1]->set_bounding_object_indices(
7556  {line_indices[8],
7557  line_indices[2],
7558  line_indices[5],
7559  line_indices[11]});
7560  new_quads[2]->set_bounding_object_indices(
7561  {line_indices[1],
7562  line_indices[9],
7563  line_indices[10],
7564  line_indices[6]});
7565  new_quads[3]->set_bounding_object_indices(
7566  {line_indices[9],
7567  line_indices[3],
7568  line_indices[11],
7569  line_indices[7]});
7570  for (const auto &new_quad : new_quads)
7571  {
7572  new_quad->set_used_flag();
7573  new_quad->clear_user_flag();
7574  new_quad->clear_user_data();
7575  new_quad->clear_children();
7576  new_quad->set_boundary_id_internal(quad->boundary_id());
7577  new_quad->set_manifold_id(quad->manifold_id());
7578  // set all line orientations to true, change
7579  // this after the loop, as we have to consider
7580  // different lines for each child
7581  for (unsigned int j = 0;
7582  j < GeometryInfo<dim>::lines_per_face;
7583  ++j)
7584  new_quad->set_line_orientation(j, true);
7585  }
7586  // now set the line orientation of children of
7587  // outer lines correctly, the lines in the
7588  // interior of the refined quad are automatically
7589  // oriented conforming to the standard
7590  new_quads[0]->set_line_orientation(
7591  0, quad->line_orientation(0));
7592  new_quads[0]->set_line_orientation(
7593  2, quad->line_orientation(2));
7594  new_quads[1]->set_line_orientation(
7595  1, quad->line_orientation(1));
7596  new_quads[1]->set_line_orientation(
7597  2, quad->line_orientation(2));
7598  new_quads[2]->set_line_orientation(
7599  0, quad->line_orientation(0));
7600  new_quads[2]->set_line_orientation(
7601  3, quad->line_orientation(3));
7602  new_quads[3]->set_line_orientation(
7603  1, quad->line_orientation(1));
7604  new_quads[3]->set_line_orientation(
7605  3, quad->line_orientation(3));
7606 
7607  // finally clear flag indicating the need for
7608  // refinement
7609  quad->clear_user_flag();
7610  } // if (isotropic refinement)
7611  } // for all quads
7612  } // looped two times over all quads, all quads refined now
7613 
7614  //---------------------------------
7615  // Now, finally, set up the new
7616  // cells
7617  //---------------------------------
7618 
7620  cells_with_distorted_children;
7621 
7622  for (unsigned int level = 0; level != triangulation.levels.size() - 1;
7623  ++level)
7624  {
7625  // only active objects can be refined further; remember
7626  // that we won't operate on the finest level, so
7627  // triangulation.begin_*(level+1) is allowed
7629  hex = triangulation.begin_active_hex(level),
7630  endh = triangulation.begin_active_hex(level + 1);
7632  next_unused_hex = triangulation.begin_raw_hex(level + 1);
7633 
7634  for (; hex != endh; ++hex)
7635  if (hex->refine_flag_set())
7636  {
7637  // this hex needs to be refined
7638 
7639  // clear flag indicating the need for refinement. do
7640  // it here already, since we can't do it anymore
7641  // once the cell has children
7642  const RefinementCase<dim> ref_case = hex->refine_flag_set();
7643  hex->clear_refine_flag();
7644  hex->set_refinement_case(ref_case);
7645 
7646  // depending on the refine case we might have to
7647  // create additional vertices, lines and quads
7648  // interior of the hex before the actual children
7649  // can be set up.
7650 
7651  // in a first step: reserve the needed space for
7652  // lines, quads and hexes and initialize them
7653  // correctly
7654 
7655  unsigned int n_new_lines = 0;
7656  unsigned int n_new_quads = 0;
7657  unsigned int n_new_hexes = 0;
7658  switch (ref_case)
7659  {
7663  n_new_lines = 0;
7664  n_new_quads = 1;
7665  n_new_hexes = 2;
7666  break;
7670  n_new_lines = 1;
7671  n_new_quads = 4;
7672  n_new_hexes = 4;
7673  break;
7675  n_new_lines = 6;
7676  n_new_quads = 12;
7677  n_new_hexes = 8;
7678  break;
7679  default:
7680  Assert(false, ExcInternalError());
7681  break;
7682  }
7683 
7684  // find some space for the newly to be created
7685  // interior lines and initialize them.
7686  std::vector<
7688  new_lines(n_new_lines);
7689  for (unsigned int i = 0; i < n_new_lines; ++i)
7690  {
7691  new_lines[i] =
7692  triangulation.faces->lines
7693  .template next_free_single_object<1>(triangulation);
7694 
7695  AssertIsNotUsed(new_lines[i]);
7696  new_lines[i]->set_used_flag();
7697  new_lines[i]->clear_user_flag();
7698  new_lines[i]->clear_user_data();
7699  new_lines[i]->clear_children();
7700  // interior line
7701  new_lines[i]->set_boundary_id_internal(
7703  // they inherit geometry description of the hex they
7704  // belong to
7705  new_lines[i]->set_manifold_id(hex->manifold_id());
7706  }
7707 
7708  // find some space for the newly to be created
7709  // interior quads and initialize them.
7710  std::vector<
7712  new_quads(n_new_quads);
7713  for (unsigned int i = 0; i < n_new_quads; ++i)
7714  {
7715  new_quads[i] =
7716  triangulation.faces->quads
7717  .template next_free_single_object<2>(triangulation);
7718 
7719  AssertIsNotUsed(new_quads[i]);
7720  new_quads[i]->set_used_flag();
7721  new_quads[i]->clear_user_flag();
7722  new_quads[i]->clear_user_data();
7723  new_quads[i]->clear_children();
7724  // interior quad
7725  new_quads[i]->set_boundary_id_internal(
7727  // they inherit geometry description of the hex they
7728  // belong to
7729  new_quads[i]->set_manifold_id(hex->manifold_id());
7730  // set all line orientation flags to true by
7731  // default, change this afterwards, if necessary
7732  for (unsigned int j = 0;
7733  j < GeometryInfo<dim>::lines_per_face;
7734  ++j)
7735  new_quads[i]->set_line_orientation(j, true);
7736  }
7737 
7738  types::subdomain_id subdomainid = hex->subdomain_id();
7739 
7740  // find some space for the newly to be created hexes
7741  // and initialize them.
7742  std::vector<
7744  new_hexes(n_new_hexes);
7745  for (unsigned int i = 0; i < n_new_hexes; ++i)
7746  {
7747  if (i % 2 == 0)
7748  next_unused_hex =
7749  triangulation.levels[level + 1]->cells.next_free_hex(
7750  triangulation, level + 1);
7751  else
7752  ++next_unused_hex;
7753 
7754  new_hexes[i] = next_unused_hex;
7755 
7756  AssertIsNotUsed(new_hexes[i]);
7757  new_hexes[i]->set_used_flag();
7758  new_hexes[i]->clear_user_flag();
7759  new_hexes[i]->clear_user_data();
7760  new_hexes[i]->clear_children();
7761  // inherit material
7762  // properties
7763  new_hexes[i]->set_material_id(hex->material_id());
7764  new_hexes[i]->set_manifold_id(hex->manifold_id());
7765  new_hexes[i]->set_subdomain_id(subdomainid);
7766 
7767  if (i % 2)
7768  new_hexes[i]->set_parent(hex->index());
7769  // set the face_orientation flag to true for all
7770  // faces initially, as this is the default value
7771  // which is true for all faces interior to the
7772  // hex. later on go the other way round and
7773  // reset faces that are at the boundary of the
7774  // mother cube
7775  //
7776  // the same is true for the face_flip and
7777  // face_rotation flags. however, the latter two
7778  // are set to false by default as this is the
7779  // standard value
7780  for (const unsigned int f :
7782  {
7783  new_hexes[i]->set_face_orientation(f, true);
7784  new_hexes[i]->set_face_flip(f, false);
7785  new_hexes[i]->set_face_rotation(f, false);
7786  }
7787  }
7788  // note these hexes as children to the present cell
7789  for (unsigned int i = 0; i < n_new_hexes / 2; ++i)
7790  hex->set_children(2 * i, new_hexes[2 * i]->index());
7791 
7792  // we have to take into account whether the
7793  // different faces are oriented correctly or in the
7794  // opposite direction, so store that up front
7795 
7796  // face_orientation
7797  const bool f_or[6] = {hex->face_orientation(0),
7798  hex->face_orientation(1),
7799  hex->face_orientation(2),
7800  hex->face_orientation(3),
7801  hex->face_orientation(4),
7802  hex->face_orientation(5)};
7803 
7804  // face_flip
7805  const bool f_fl[6] = {hex->face_flip(0),
7806  hex->face_flip(1),
7807  hex->face_flip(2),
7808  hex->face_flip(3),
7809  hex->face_flip(4),
7810  hex->face_flip(5)};
7811 
7812  // face_rotation
7813  const bool f_ro[6] = {hex->face_rotation(0),
7814  hex->face_rotation(1),
7815  hex->face_rotation(2),
7816  hex->face_rotation(3),
7817  hex->face_rotation(4),
7818  hex->face_rotation(5)};
7819 
7820  // little helper table, indicating, whether the
7821  // child with index 0 or with index 1 can be found
7822  // at the standard origin of an anisotropically
7823  // refined quads in real orientation index 1:
7824  // (RefineCase - 1) index 2: face_flip
7825 
7826  // index 3: face rotation
7827  // note: face orientation has no influence
7828  const unsigned int child_at_origin[2][2][2] = {
7829  {{0, 0}, // RefinementCase<dim>::cut_x, face_flip=false,
7830  // face_rotation=false and true
7831  {1, 1}}, // RefinementCase<dim>::cut_x, face_flip=true,
7832  // face_rotation=false and true
7833  {{0, 1}, // RefinementCase<dim>::cut_y, face_flip=false,
7834  // face_rotation=false and true
7835  {1, 0}}}; // RefinementCase<dim>::cut_y, face_flip=true,
7836  // face_rotation=false and true
7837 
7838  //-------------------------------------
7839  //
7840  // in the following we will do the same thing for
7841  // each refinement case: create a new vertex (if
7842  // needed), create new interior lines (if needed),
7843  // create new interior quads and afterwards build
7844  // the children hexes out of these and the existing
7845  // subfaces of the outer quads (which have been
7846  // created above). However, even if the steps are
7847  // quite similar, the actual work strongly depends
7848  // on the actual refinement case. therefore, we use
7849  // separate blocks of code for each of these cases,
7850  // which hopefully increases the readability to some
7851  // extend.
7852 
7853  switch (ref_case)
7854  {
7856  {
7857  //----------------------------
7858  //
7859  // RefinementCase<dim>::cut_x
7860  //
7861  // the refined cube will look
7862  // like this:
7863  //
7864  // *----*----*
7865  // / / /|
7866  // / / / |
7867  // / / / |
7868  // *----*----* |
7869  // | | | |
7870  // | | | *
7871  // | | | /
7872  // | | | /
7873  // | | |/
7874  // *----*----*
7875  //
7876  // again, first collect some data about the
7877  // indices of the lines, with the following
7878  // numbering:
7879 
7880  // face 2: front plane
7881  // (note: x,y exchanged)
7882  // *---*---*
7883  // | | |
7884  // | 0 |
7885  // | | |
7886  // *---*---*
7887  // m0
7888  // face 3: back plane
7889  // (note: x,y exchanged)
7890  // m1
7891  // *---*---*
7892  // | | |
7893  // | 1 |
7894  // | | |
7895  // *---*---*
7896  // face 4: bottom plane
7897  // *---*---*
7898  // / / /
7899  // / 2 /
7900  // / / /
7901  // *---*---*
7902  // m0
7903  // face 5: top plane
7904  // m1
7905  // *---*---*
7906  // / / /
7907  // / 3 /
7908  // / / /
7909  // *---*---*
7910 
7911  // set up a list of line iterators first. from
7912  // this, construct lists of line_indices and
7913  // line orientations later on
7914  const typename Triangulation<dim, spacedim>::
7915  raw_line_iterator lines[4] = {
7916  hex->face(2)->child(0)->line(
7917  (hex->face(2)->refinement_case() ==
7919  1 :
7920  3), // 0
7921  hex->face(3)->child(0)->line(
7922  (hex->face(3)->refinement_case() ==
7924  1 :
7925  3), // 1
7926  hex->face(4)->child(0)->line(
7927  (hex->face(4)->refinement_case() ==
7929  1 :
7930  3), // 2
7931  hex->face(5)->child(0)->line(
7932  (hex->face(5)->refinement_case() ==
7934  1 :
7935  3) // 3
7936  };
7937 
7938  unsigned int line_indices[4];
7939  for (unsigned int i = 0; i < 4; ++i)
7940  line_indices[i] = lines[i]->index();
7941 
7942  // the orientation of lines for the inner quads
7943  // is quite tricky. as these lines are newly
7944  // created ones and thus have no parents, they
7945  // cannot inherit this property. set up an array
7946  // and fill it with the respective values
7947  bool line_orientation[4];
7948 
7949  // the middle vertex marked as m0 above is the
7950  // start vertex for lines 0 and 2 in standard
7951  // orientation, whereas m1 is the end vertex of
7952  // lines 1 and 3 in standard orientation
7953  const unsigned int middle_vertices[2] = {
7954  hex->line(2)->child(0)->vertex_index(1),
7955  hex->line(7)->child(0)->vertex_index(1)};
7956 
7957  for (unsigned int i = 0; i < 4; ++i)
7958  if (lines[i]->vertex_index(i % 2) ==
7959  middle_vertices[i % 2])
7960  line_orientation[i] = true;
7961  else
7962  {
7963  // it must be the other
7964  // way round then
7965  Assert(lines[i]->vertex_index((i + 1) % 2) ==
7966  middle_vertices[i % 2],
7967  ExcInternalError());
7968  line_orientation[i] = false;
7969  }
7970 
7971  // set up the new quad, line numbering is as
7972  // indicated above
7973  new_quads[0]->set_bounding_object_indices(
7974  {line_indices[0],
7975  line_indices[1],
7976  line_indices[2],
7977  line_indices[3]});
7978 
7979  new_quads[0]->set_line_orientation(
7980  0, line_orientation[0]);
7981  new_quads[0]->set_line_orientation(
7982  1, line_orientation[1]);
7983  new_quads[0]->set_line_orientation(
7984  2, line_orientation[2]);
7985  new_quads[0]->set_line_orientation(
7986  3, line_orientation[3]);
7987 
7988  // the quads are numbered as follows:
7989  //
7990  // planes in the interior of the old hex:
7991  //
7992  // *
7993  // /|
7994  // / | x
7995  // / | *-------* *---------*
7996  // * | | | / /
7997  // | 0 | | | / /
7998  // | * | | / /
7999  // | / *-------*y *---------*x
8000  // | /
8001  // |/
8002  // *
8003  //
8004  // children of the faces of the old hex
8005  //
8006  // *---*---* *---*---*
8007  // /| | | / / /|
8008  // / | | | / 9 / 10/ |
8009  // / | 5 | 6 | / / / |
8010  // * | | | *---*---* |
8011  // | 1 *---*---* | | | 2 *
8012  // | / / / | | | /
8013  // | / 7 / 8 / | 3 | 4 | /
8014  // |/ / / | | |/
8015  // *---*---* *---*---*
8016  //
8017  // note that we have to take care of the
8018  // orientation of faces.
8019  const int quad_indices[11] = {
8020  new_quads[0]->index(), // 0
8021 
8022  hex->face(0)->index(), // 1
8023 
8024  hex->face(1)->index(), // 2
8025 
8026  hex->face(2)->child_index(
8027  child_at_origin[hex->face(2)->refinement_case() -
8028  1][f_fl[2]][f_ro[2]]), // 3
8029  hex->face(2)->child_index(
8030  1 -
8031  child_at_origin[hex->face(2)->refinement_case() -
8032  1][f_fl[2]][f_ro[2]]),
8033 
8034  hex->face(3)->child_index(
8035  child_at_origin[hex->face(3)->refinement_case() -
8036  1][f_fl[3]][f_ro[3]]), // 5
8037  hex->face(3)->child_index(
8038  1 -
8039  child_at_origin[hex->face(3)->refinement_case() -
8040  1][f_fl[3]][f_ro[3]]),
8041 
8042  hex->face(4)->child_index(
8043  child_at_origin[hex->face(4)->refinement_case() -
8044  1][f_fl[4]][f_ro[4]]), // 7
8045  hex->face(4)->child_index(
8046  1 -
8047  child_at_origin[hex->face(4)->refinement_case() -
8048  1][f_fl[4]][f_ro[4]]),
8049 
8050  hex->face(5)->child_index(
8051  child_at_origin[hex->face(5)->refinement_case() -
8052  1][f_fl[5]][f_ro[5]]), // 9
8053  hex->face(5)->child_index(
8054  1 -
8055  child_at_origin[hex->face(5)->refinement_case() -
8056  1][f_fl[5]][f_ro[5]])
8057 
8058  };
8059 
8060  new_hexes[0]->set_bounding_object_indices(
8061  {quad_indices[1],
8062  quad_indices[0],
8063  quad_indices[3],
8064  quad_indices[5],
8065  quad_indices[7],
8066  quad_indices[9]});
8067  new_hexes[1]->set_bounding_object_indices(
8068  {quad_indices[0],
8069  quad_indices[2],
8070  quad_indices[4],
8071  quad_indices[6],
8072  quad_indices[8],
8073  quad_indices[10]});
8074  break;
8075  }
8076 
8078  {
8079  //----------------------------
8080  //
8081  // RefinementCase<dim>::cut_y
8082  //
8083  // the refined cube will look like this:
8084  //
8085  // *---------*
8086  // / /|
8087  // *---------* |
8088  // / /| |
8089  // *---------* | |
8090  // | | | |
8091  // | | | *
8092  // | | |/
8093  // | | *
8094  // | |/
8095  // *---------*
8096  //
8097  // again, first collect some data about the
8098  // indices of the lines, with the following
8099  // numbering:
8100 
8101  // face 0: left plane
8102  // *
8103  // /|
8104  // * |
8105  // /| |
8106  // * | |
8107  // | 0 |
8108  // | | *
8109  // | |/
8110  // | *m0
8111  // |/
8112  // *
8113  // face 1: right plane
8114  // *
8115  // /|
8116  // m1* |
8117  // /| |
8118  // * | |
8119  // | 1 |
8120  // | | *
8121  // | |/
8122  // | *
8123  // |/
8124  // *
8125  // face 4: bottom plane
8126  // *-------*
8127  // / /
8128  // m0*---2---*
8129  // / /
8130  // *-------*
8131  // face 5: top plane
8132  // *-------*
8133  // / /
8134  // *---3---*m1
8135  // / /
8136  // *-------*
8137 
8138  // set up a list of line iterators first. from
8139  // this, construct lists of line_indices and
8140  // line orientations later on
8141  const typename Triangulation<dim, spacedim>::
8142  raw_line_iterator lines[4] = {
8143  hex->face(0)->child(0)->line(
8144  (hex->face(0)->refinement_case() ==
8146  1 :
8147  3), // 0
8148  hex->face(1)->child(0)->line(
8149  (hex->face(1)->refinement_case() ==
8151  1 :
8152  3), // 1
8153  hex->face(4)->child(0)->line(
8154  (hex->face(4)->refinement_case() ==
8156  1 :
8157  3), // 2
8158  hex->face(5)->child(0)->line(
8159  (hex->face(5)->refinement_case() ==
8161  1 :
8162  3) // 3
8163  };
8164 
8165  unsigned int line_indices[4];
8166  for (unsigned int i = 0; i < 4; ++i)
8167  line_indices[i] = lines[i]->index();
8168 
8169  // the orientation of lines for the inner quads
8170  // is quite tricky. as these lines are newly
8171  // created ones and thus have no parents, they
8172  // cannot inherit this property. set up an array
8173  // and fill it with the respective values
8174  bool line_orientation[4];
8175 
8176  // the middle vertex marked as m0 above is the
8177  // start vertex for lines 0 and 2 in standard
8178  // orientation, whereas m1 is the end vertex of
8179  // lines 1 and 3 in standard orientation
8180  const unsigned int middle_vertices[2] = {
8181  hex->line(0)->child(0)->vertex_index(1),
8182  hex->line(5)->child(0)->vertex_index(1)};
8183 
8184  for (unsigned int i = 0; i < 4; ++i)
8185  if (lines[i]->vertex_index(i % 2) ==
8186  middle_vertices[i % 2])
8187  line_orientation[i] = true;
8188  else
8189  {
8190  // it must be the other way round then
8191  Assert(lines[i]->vertex_index((i + 1) % 2) ==
8192  middle_vertices[i % 2],
8193  ExcInternalError());
8194  line_orientation[i] = false;
8195  }
8196 
8197  // set up the new quad, line numbering is as
8198  // indicated above
8199  new_quads[0]->set_bounding_object_indices(
8200  {line_indices[2],
8201  line_indices[3],
8202  line_indices[0],
8203  line_indices[1]});
8204 
8205  new_quads[0]->set_line_orientation(
8206  0, line_orientation[2]);
8207  new_quads[0]->set_line_orientation(
8208  1, line_orientation[3]);
8209  new_quads[0]->set_line_orientation(
8210  2, line_orientation[0]);
8211  new_quads[0]->set_line_orientation(
8212  3, line_orientation[1]);
8213 
8214  // the quads are numbered as follows:
8215  //
8216  // planes in the interior of the old hex:
8217  //
8218  // *
8219  // /|
8220  // / | x
8221  // / | *-------* *---------*
8222  // * | | | / /
8223  // | | | 0 | / /
8224  // | * | | / /
8225  // | / *-------*y *---------*x
8226  // | /
8227  // |/
8228  // *
8229  //
8230  // children of the faces of the old hex
8231  //
8232  // *-------* *-------*
8233  // /| | / 10 /|
8234  // * | | *-------* |
8235  // /| | 6 | / 9 /| |
8236  // * |2| | *-------* |4|
8237  // | | *-------* | | | *
8238  // |1|/ 8 / | |3|/
8239  // | *-------* | 5 | *
8240  // |/ 7 / | |/
8241  // *-------* *-------*
8242  //
8243  // note that we have to take care of the
8244  // orientation of faces.
8245  const int quad_indices[11] = {
8246  new_quads[0]->index(), // 0
8247 
8248  hex->face(0)->child_index(
8249  child_at_origin[hex->face(0)->refinement_case() -
8250  1][f_fl[0]][f_ro[0]]), // 1
8251  hex->face(0)->child_index(
8252  1 -
8253  child_at_origin[hex->face(0)->refinement_case() -
8254  1][f_fl[0]][f_ro[0]]),
8255 
8256  hex->face(1)->child_index(
8257  child_at_origin[hex->face(1)->refinement_case() -
8258  1][f_fl[1]][f_ro[1]]), // 3
8259  hex->face(1)->child_index(
8260  1 -
8261  child_at_origin[hex->face(1)->refinement_case() -
8262  1][f_fl[1]][f_ro[1]]),
8263 
8264  hex->face(2)->index(), // 5
8265 
8266  hex->face(3)->index(), // 6
8267 
8268  hex->face(4)->child_index(
8269  child_at_origin[hex->face(4)->refinement_case() -
8270  1][f_fl[4]][f_ro[4]]), // 7
8271  hex->face(4)->child_index(
8272  1 -
8273  child_at_origin[hex->face(4)->refinement_case() -
8274  1][f_fl[4]][f_ro[4]]),
8275 
8276  hex->face(5)->child_index(
8277  child_at_origin[hex->face(5)->refinement_case() -
8278  1][f_fl[5]][f_ro[5]]), // 9
8279  hex->face(5)->child_index(
8280  1 -
8281  child_at_origin[hex->face(5)->refinement_case() -
8282  1][f_fl[5]][f_ro[5]])
8283 
8284  };
8285 
8286  new_hexes[0]->set_bounding_object_indices(
8287  {quad_indices[1],
8288  quad_indices[3],
8289  quad_indices[5],
8290  quad_indices[0],
8291  quad_indices[7],
8292  quad_indices[9]});
8293  new_hexes[1]->set_bounding_object_indices(
8294  {quad_indices[2],
8295  quad_indices[4],
8296  quad_indices[0],
8297  quad_indices[6],
8298  quad_indices[8],
8299  quad_indices[10]});
8300  break;
8301  }
8302 
8304  {
8305  //----------------------------
8306  //
8307  // RefinementCase<dim>::cut_z
8308  //
8309  // the refined cube will look like this:
8310  //
8311  // *---------*
8312  // / /|
8313  // / / |
8314  // / / *
8315  // *---------* /|
8316  // | | / |
8317  // | |/ *
8318  // *---------* /
8319  // | | /
8320  // | |/
8321  // *---------*
8322  //
8323  // again, first collect some data about the
8324  // indices of the lines, with the following
8325  // numbering:
8326 
8327  // face 0: left plane
8328  // *
8329  // /|
8330  // / |
8331  // / *
8332  // * /|
8333  // | 0 |
8334  // |/ *
8335  // m0* /
8336  // | /
8337  // |/
8338  // *
8339  // face 1: right plane
8340  // *
8341  // /|
8342  // / |
8343  // / *m1
8344  // * /|
8345  // | 1 |
8346  // |/ *
8347  // * /
8348  // | /
8349  // |/
8350  // *
8351  // face 2: front plane
8352  // (note: x,y exchanged)
8353  // *-------*
8354  // | |
8355  // m0*---2---*
8356  // | |
8357  // *-------*
8358  // face 3: back plane
8359  // (note: x,y exchanged)
8360  // *-------*
8361  // | |
8362  // *---3---*m1
8363  // | |
8364  // *-------*
8365 
8366  // set up a list of line iterators first. from
8367  // this, construct lists of line_indices and
8368  // line orientations later on
8369  const typename Triangulation<dim, spacedim>::
8370  raw_line_iterator lines[4] = {
8371  hex->face(0)->child(0)->line(
8372  (hex->face(0)->refinement_case() ==
8374  1 :
8375  3), // 0
8376  hex->face(1)->child(0)->line(
8377  (hex->face(1)->refinement_case() ==
8379  1 :
8380  3), // 1
8381  hex->face(2)->child(0)->line(
8382  (hex->face(2)->refinement_case() ==
8384  1 :
8385  3), // 2
8386  hex->face(3)->child(0)->line(
8387  (hex->face(3)->refinement_case() ==
8389  1 :
8390  3) // 3
8391  };
8392 
8393  unsigned int line_indices[4];
8394  for (unsigned int i = 0; i < 4; ++i)
8395  line_indices[i] = lines[i]->index();
8396 
8397  // the orientation of lines for the inner quads
8398  // is quite tricky. as these lines are newly
8399  // created ones and thus have no parents, they
8400  // cannot inherit this property. set up an array
8401  // and fill it with the respective values
8402  bool line_orientation[4];
8403 
8404  // the middle vertex marked as m0 above is the
8405  // start vertex for lines 0 and 2 in standard
8406  // orientation, whereas m1 is the end vertex of
8407  // lines 1 and 3 in standard orientation
8408  const unsigned int middle_vertices[2] = {
8409  middle_vertex_index<dim, spacedim>(hex->line(8)),
8410  middle_vertex_index<dim, spacedim>(hex->line(11))};
8411 
8412  for (unsigned int i = 0; i < 4; ++i)
8413  if (lines[i]->vertex_index(i % 2) ==
8414  middle_vertices[i % 2])
8415  line_orientation[i] = true;
8416  else
8417  {
8418  // it must be the other way round then
8419  Assert(lines[i]->vertex_index((i + 1) % 2) ==
8420  middle_vertices[i % 2],
8421  ExcInternalError());
8422  line_orientation[i] = false;
8423  }
8424 
8425  // set up the new quad, line numbering is as
8426  // indicated above
8427  new_quads[0]->set_bounding_object_indices(
8428  {line_indices[0],
8429  line_indices[1],
8430  line_indices[2],
8431  line_indices[3]});
8432 
8433  new_quads[0]->set_line_orientation(
8434  0, line_orientation[0]);
8435  new_quads[0]->set_line_orientation(
8436  1, line_orientation[1]);
8437  new_quads[0]->set_line_orientation(
8438  2, line_orientation[2]);
8439  new_quads[0]->set_line_orientation(
8440  3, line_orientation[3]);
8441 
8442  // the quads are numbered as follows:
8443  //
8444  // planes in the interior of the old hex:
8445  //
8446  // *
8447  // /|
8448  // / | x
8449  // / | *-------* *---------*
8450  // * | | | / /
8451  // | | | | / 0 /
8452  // | * | | / /
8453  // | / *-------*y *---------*x
8454  // | /
8455  // |/
8456  // *
8457  //
8458  // children of the faces of the old hex
8459  //
8460  // *---*---* *-------*
8461  // /| 8 | / /|
8462  // / | | / 10 / |
8463  // / *-------* / / *
8464  // * 2/| | *-------* 4/|
8465  // | / | 7 | | 6 | / |
8466  // |/1 *-------* | |/3 *
8467  // * / / *-------* /
8468  // | / 9 / | | /
8469  // |/ / | 5 |/
8470  // *-------* *---*---*
8471  //
8472  // note that we have to take care of the
8473  // orientation of faces.
8474  const int quad_indices[11] = {
8475  new_quads[0]->index(), // 0
8476 
8477  hex->face(0)->child_index(
8478  child_at_origin[hex->face(0)->refinement_case() -
8479  1][f_fl[0]][f_ro[0]]), // 1
8480  hex->face(0)->child_index(
8481  1 -
8482  child_at_origin[hex->face(0)->refinement_case() -
8483  1][f_fl[0]][f_ro[0]]),
8484 
8485  hex->face(1)->child_index(
8486  child_at_origin[hex->face(1)->refinement_case() -
8487  1][f_fl[1]][f_ro[1]]), // 3
8488  hex->face(1)->child_index(
8489  1 -
8490  child_at_origin[hex->face(1)->refinement_case() -
8491  1][f_fl[1]][f_ro[1]]),
8492 
8493  hex->face(2)->child_index(
8494  child_at_origin[hex->face(2)->refinement_case() -
8495  1][f_fl[2]][f_ro[2]]), // 5
8496  hex->face(2)->child_index(
8497  1 -
8498  child_at_origin[hex->face(2)->refinement_case() -
8499  1][f_fl[2]][f_ro[2]]),
8500 
8501  hex->face(3)->child_index(
8502  child_at_origin[hex->face(3)->refinement_case() -
8503  1][f_fl[3]][f_ro[3]]), // 7
8504  hex->face(3)->child_index(
8505  1 -
8506  child_at_origin[hex->face(3)->refinement_case() -
8507  1][f_fl[3]][f_ro[3]]),
8508 
8509  hex->face(4)->index(), // 9
8510 
8511  hex->face(5)->index() // 10
8512  };
8513 
8514  new_hexes[0]->set_bounding_object_indices(
8515  {quad_indices[1],
8516  quad_indices[3],
8517  quad_indices[5],
8518  quad_indices[7],
8519  quad_indices[9],
8520  quad_indices[0]});
8521  new_hexes[1]->set_bounding_object_indices(
8522  {quad_indices[2],
8523  quad_indices[4],
8524  quad_indices[6],
8525  quad_indices[8],
8526  quad_indices[0],
8527  quad_indices[10]});
8528  break;
8529  }
8530 
8532  {
8533  //----------------------------
8534  //
8535  // RefinementCase<dim>::cut_xy
8536  //
8537  // the refined cube will look like this:
8538  //
8539  // *----*----*
8540  // / / /|
8541  // *----*----* |
8542  // / / /| |
8543  // *----*----* | |
8544  // | | | | |
8545  // | | | | *
8546  // | | | |/
8547  // | | | *
8548  // | | |/
8549  // *----*----*
8550  //
8551 
8552  // first, create the new internal line
8553  new_lines[0]->set_bounding_object_indices(
8554  {middle_vertex_index<dim, spacedim>(hex->face(4)),
8555  middle_vertex_index<dim, spacedim>(hex->face(5))});
8556 
8557  // again, first collect some data about the
8558  // indices of the lines, with the following
8559  // numbering:
8560 
8561  // face 0: left plane
8562  // *
8563  // /|
8564  // * |
8565  // /| |
8566  // * | |
8567  // | 0 |
8568  // | | *
8569  // | |/
8570  // | *
8571  // |/
8572  // *
8573  // face 1: right plane
8574  // *
8575  // /|
8576  // * |
8577  // /| |
8578  // * | |
8579  // | 1 |
8580  // | | *
8581  // | |/
8582  // | *
8583  // |/
8584  // *
8585  // face 2: front plane
8586  // (note: x,y exchanged)
8587  // *---*---*
8588  // | | |
8589  // | 2 |
8590  // | | |
8591  // *-------*
8592  // face 3: back plane
8593  // (note: x,y exchanged)
8594  // *---*---*
8595  // | | |
8596  // | 3 |
8597  // | | |
8598  // *---*---*
8599  // face 4: bottom plane
8600  // *---*---*
8601  // / 5 /
8602  // *-6-*-7-*
8603  // / 4 /
8604  // *---*---*
8605  // face 5: top plane
8606  // *---*---*
8607  // / 9 /
8608  // *10-*-11*
8609  // / 8 /
8610  // *---*---*
8611  // middle planes
8612  // *-------* *---*---*
8613  // / / | | |
8614  // / / | 12 |
8615  // / / | | |
8616  // *-------* *---*---*
8617 
8618  // set up a list of line iterators first. from
8619  // this, construct lists of line_indices and
8620  // line orientations later on
8621  const typename Triangulation<
8622  dim,
8623  spacedim>::raw_line_iterator lines[13] = {
8624  hex->face(0)->child(0)->line(
8625  (hex->face(0)->refinement_case() ==
8627  1 :
8628  3), // 0
8629  hex->face(1)->child(0)->line(
8630  (hex->face(1)->refinement_case() ==
8632  1 :
8633  3), // 1
8634  hex->face(2)->child(0)->line(
8635  (hex->face(2)->refinement_case() ==
8637  1 :
8638  3), // 2
8639  hex->face(3)->child(0)->line(
8640  (hex->face(3)->refinement_case() ==
8642  1 :
8643  3), // 3
8644 
8645  hex->face(4)
8646  ->isotropic_child(
8648  0, f_or[4], f_fl[4], f_ro[4]))
8649  ->line(
8651  1, f_or[4], f_fl[4], f_ro[4])), // 4
8652  hex->face(4)
8653  ->isotropic_child(
8655  3, f_or[4], f_fl[4], f_ro[4]))
8656  ->line(
8658  0, f_or[4], f_fl[4], f_ro[4])), // 5
8659  hex->face(4)
8660  ->isotropic_child(
8662  0, f_or[4], f_fl[4], f_ro[4]))
8663  ->line(
8665  3, f_or[4], f_fl[4], f_ro[4])), // 6
8666  hex->face(4)
8667  ->isotropic_child(
8669  3, f_or[4], f_fl[4], f_ro[4]))
8670  ->line(
8672  2, f_or[4], f_fl[4], f_ro[4])), // 7
8673 
8674  hex->face(5)
8675  ->isotropic_child(
8677  0, f_or[5], f_fl[5], f_ro[5]))
8678  ->line(
8680  1, f_or[5], f_fl[5], f_ro[5])), // 8
8681  hex->face(5)
8682  ->isotropic_child(
8684  3, f_or[5], f_fl[5], f_ro[5]))
8685  ->line(
8687  0, f_or[5], f_fl[5], f_ro[5])), // 9
8688  hex->face(5)
8689  ->isotropic_child(
8691  0, f_or[5], f_fl[5], f_ro[5]))
8692  ->line(
8694  3, f_or[5], f_fl[5], f_ro[5])), // 10
8695  hex->face(5)
8696  ->isotropic_child(
8698  3, f_or[5], f_fl[5], f_ro[5]))
8699  ->line(
8701  2, f_or[5], f_fl[5], f_ro[5])), // 11
8702 
8703  new_lines[0] // 12
8704  };
8705 
8706  unsigned int line_indices[13];
8707  for (unsigned int i = 0; i < 13; ++i)
8708  line_indices[i] = lines[i]->index();
8709 
8710  // the orientation of lines for the inner quads
8711  // is quite tricky. as these lines are newly
8712  // created ones and thus have no parents, they
8713  // cannot inherit this property. set up an array
8714  // and fill it with the respective values
8715  bool line_orientation[13];
8716 
8717  // the middle vertices of the lines of our
8718  // bottom face
8719  const unsigned int middle_vertices[4] = {
8720  hex->line(0)->child(0)->vertex_index(1),
8721  hex->line(1)->child(0)->vertex_index(1),
8722  hex->line(2)->child(0)->vertex_index(1),
8723  hex->line(3)->child(0)->vertex_index(1),
8724  };
8725 
8726  // note: for lines 0 to 3 the orientation of the
8727  // line is 'true', if vertex 0 is on the bottom
8728  // face
8729  for (unsigned int i = 0; i < 4; ++i)
8730  if (lines[i]->vertex_index(0) == middle_vertices[i])
8731  line_orientation[i] = true;
8732  else
8733  {
8734  // it must be the other way round then
8735  Assert(lines[i]->vertex_index(1) ==
8736  middle_vertices[i],
8737  ExcInternalError());
8738  line_orientation[i] = false;
8739  }
8740 
8741  // note: for lines 4 to 11 (inner lines of the
8742  // outer quads) the following holds: the second
8743  // vertex of the even lines in standard
8744  // orientation is the vertex in the middle of
8745  // the quad, whereas for odd lines the first
8746  // vertex is the same middle vertex.
8747  for (unsigned int i = 4; i < 12; ++i)
8748  if (lines[i]->vertex_index((i + 1) % 2) ==
8749  middle_vertex_index<dim, spacedim>(
8750  hex->face(3 + i / 4)))
8751  line_orientation[i] = true;
8752  else
8753  {
8754  // it must be the other way
8755  // round then
8756  Assert(lines[i]->vertex_index(i % 2) ==
8757  (middle_vertex_index<dim, spacedim>(
8758  hex->face(3 + i / 4))),
8759  ExcInternalError());
8760  line_orientation[i] = false;
8761  }
8762  // for the last line the line orientation is
8763  // always true, since it was just constructed
8764  // that way
8765  line_orientation[12] = true;
8766 
8767  // set up the 4 quads, numbered as follows (left
8768  // quad numbering, right line numbering
8769  // extracted from above)
8770  //
8771  // * *
8772  // /| 9|
8773  // * | * |
8774  // y/| | 8| 3
8775  // * |1| * | |
8776  // | | |x | 12|
8777  // |0| * | | *
8778  // | |/ 2 |5
8779  // | * | *
8780  // |/ |4
8781  // * *
8782  //
8783  // x
8784  // *---*---* *10-*-11*
8785  // | | | | | |
8786  // | 2 | 3 | 0 12 1
8787  // | | | | | |
8788  // *---*---*y *-6-*-7-*
8789 
8790  new_quads[0]->set_bounding_object_indices(
8791  {line_indices[2],
8792  line_indices[12],
8793  line_indices[4],
8794  line_indices[8]});
8795  new_quads[1]->set_bounding_object_indices(
8796  {line_indices[12],
8797  line_indices[3],
8798  line_indices[5],
8799  line_indices[9]});
8800  new_quads[2]->set_bounding_object_indices(
8801  {line_indices[6],
8802  line_indices[10],
8803  line_indices[0],
8804  line_indices[12]});
8805  new_quads[3]->set_bounding_object_indices(
8806  {line_indices[7],
8807  line_indices[11],
8808  line_indices[12],
8809  line_indices[1]});
8810 
8811  new_quads[0]->set_line_orientation(
8812  0, line_orientation[2]);
8813  new_quads[0]->set_line_orientation(
8814  2, line_orientation[4]);
8815  new_quads[0]->set_line_orientation(
8816  3, line_orientation[8]);
8817 
8818  new_quads[1]->set_line_orientation(
8819  1, line_orientation[3]);
8820  new_quads[1]->set_line_orientation(
8821  2, line_orientation[5]);
8822  new_quads[1]->set_line_orientation(
8823  3, line_orientation[9]);
8824 
8825  new_quads[2]->set_line_orientation(
8826  0, line_orientation[6]);
8827  new_quads[2]->set_line_orientation(
8828  1, line_orientation[10]);
8829  new_quads[2]->set_line_orientation(
8830  2, line_orientation[0]);
8831 
8832  new_quads[3]->set_line_orientation(
8833  0, line_orientation[7]);
8834  new_quads[3]->set_line_orientation(
8835  1, line_orientation[11]);
8836  new_quads[3]->set_line_orientation(
8837  3, line_orientation[1]);
8838 
8839  // the quads are numbered as follows:
8840  //
8841  // planes in the interior of the old hex:
8842  //
8843  // *
8844  // /|
8845  // * | x
8846  // /| | *---*---* *---------*
8847  // * |1| | | | / /
8848  // | | | | 2 | 3 | / /
8849  // |0| * | | | / /
8850  // | |/ *---*---*y *---------*x
8851  // | *
8852  // |/
8853  // *
8854  //
8855  // children of the faces of the old hex
8856  //
8857  // *---*---* *---*---*
8858  // /| | | /18 / 19/|
8859  // * |10 | 11| /---/---* |
8860  // /| | | | /16 / 17/| |
8861  // * |5| | | *---*---* |7|
8862  // | | *---*---* | | | | *
8863  // |4|/14 / 15/ | | |6|/
8864  // | *---/---/ | 8 | 9 | *
8865  // |/12 / 13/ | | |/
8866  // *---*---* *---*---*
8867  //
8868  // note that we have to take care of the
8869  // orientation of faces.
8870  const int quad_indices[20] = {
8871  new_quads[0]->index(), // 0
8872  new_quads[1]->index(),
8873  new_quads[2]->index(),
8874  new_quads[3]->index(),
8875 
8876  hex->face(0)->child_index(
8877  child_at_origin[hex->face(0)->refinement_case() -
8878  1][f_fl[0]][f_ro[0]]), // 4
8879  hex->face(0)->child_index(
8880  1 -
8881  child_at_origin[hex->face(0)->refinement_case() -
8882  1][f_fl[0]][f_ro[0]]),
8883 
8884  hex->face(1)->child_index(
8885  child_at_origin[hex->face(1)->refinement_case() -
8886  1][f_fl[1]][f_ro[1]]), // 6
8887  hex->face(1)->child_index(
8888  1 -
8889  child_at_origin[hex->face(1)->refinement_case() -
8890  1][f_fl[1]][f_ro[1]]),
8891 
8892  hex->face(2)->child_index(
8893  child_at_origin[hex->face(2)->refinement_case() -
8894  1][f_fl[2]][f_ro[2]]), // 8
8895  hex->face(2)->child_index(
8896  1 -
8897  child_at_origin[hex->face(2)->refinement_case() -
8898  1][f_fl[2]][f_ro[2]]),
8899 
8900  hex->face(3)->child_index(
8901  child_at_origin[hex->face(3)->refinement_case() -
8902  1][f_fl[3]][f_ro[3]]), // 10
8903  hex->face(3)->child_index(
8904  1 -
8905  child_at_origin[hex->face(3)->refinement_case() -
8906  1][f_fl[3]][f_ro[3]]),
8907 
8908  hex->face(4)->isotropic_child_index(
8910  0, f_or[4], f_fl[4], f_ro[4])), // 12
8911  hex->face(4)->isotropic_child_index(
8913  1, f_or[4], f_fl[4], f_ro[4])),
8914  hex->face(4)->isotropic_child_index(
8916  2, f_or[4], f_fl[4], f_ro[4])),
8917  hex->face(4)->isotropic_child_index(
8919  3, f_or[4], f_fl[4], f_ro[4])),
8920 
8921  hex->face(5)->isotropic_child_index(
8923  0, f_or[5], f_fl[5], f_ro[5])), // 16
8924  hex->face(5)->isotropic_child_index(
8926  1, f_or[5], f_fl[5], f_ro[5])),
8927  hex->face(5)->isotropic_child_index(
8929  2, f_or[5], f_fl[5], f_ro[5])),
8930  hex->face(5)->isotropic_child_index(
8932  3, f_or[5], f_fl[5], f_ro[5]))};
8933 
8934  new_hexes[0]->set_bounding_object_indices(
8935  {quad_indices[4],
8936  quad_indices[0],
8937  quad_indices[8],
8938  quad_indices[2],
8939  quad_indices[12],
8940  quad_indices[16]});
8941  new_hexes[1]->set_bounding_object_indices(
8942  {quad_indices[0],
8943  quad_indices[6],
8944  quad_indices[9],
8945  quad_indices[3],
8946  quad_indices[13],
8947  quad_indices[17]});
8948  new_hexes[2]->set_bounding_object_indices(
8949  {quad_indices[5],
8950  quad_indices[1],
8951  quad_indices[2],
8952  quad_indices[10],
8953  quad_indices[14],
8954  quad_indices[18]});
8955  new_hexes[3]->set_bounding_object_indices(
8956  {quad_indices[1],
8957  quad_indices[7],
8958  quad_indices[3],
8959  quad_indices[11],
8960  quad_indices[15],
8961  quad_indices[19]});
8962  break;
8963  }
8964 
8966  {
8967  //----------------------------
8968  //
8969  // RefinementCase<dim>::cut_xz
8970  //
8971  // the refined cube will look like this:
8972  //
8973  // *----*----*
8974  // / / /|
8975  // / / / |
8976  // / / / *
8977  // *----*----* /|
8978  // | | | / |
8979  // | | |/ *
8980  // *----*----* /
8981  // | | | /
8982  // | | |/
8983  // *----*----*
8984  //
8985 
8986  // first, create the new internal line
8987  new_lines[0]->set_bounding_object_indices(
8988  {middle_vertex_index<dim, spacedim>(hex->face(2)),
8989  middle_vertex_index<dim, spacedim>(hex->face(3))});
8990 
8991  // again, first collect some data about the
8992  // indices of the lines, with the following
8993  // numbering:
8994 
8995  // face 0: left plane
8996  // *
8997  // /|
8998  // / |
8999  // / *
9000  // * /|
9001  // | 0 |
9002  // |/ *
9003  // * /
9004  // | /
9005  // |/
9006  // *
9007  // face 1: right plane
9008  // *
9009  // /|
9010  // / |
9011  // / *
9012  // * /|
9013  // | 1 |
9014  // |/ *
9015  // * /
9016  // | /
9017  // |/
9018  // *
9019  // face 2: front plane
9020  // (note: x,y exchanged)
9021  // *---*---*
9022  // | 5 |
9023  // *-6-*-7-*
9024  // | 4 |
9025  // *---*---*
9026  // face 3: back plane
9027  // (note: x,y exchanged)
9028  // *---*---*
9029  // | 9 |
9030  // *10-*-11*
9031  // | 8 |
9032  // *---*---*
9033  // face 4: bottom plane
9034  // *---*---*
9035  // / / /
9036  // / 2 /
9037  // / / /
9038  // *---*---*
9039  // face 5: top plane
9040  // *---*---*
9041  // / / /
9042  // / 3 /
9043  // / / /
9044  // *---*---*
9045  // middle planes
9046  // *---*---* *-------*
9047  // / / / | |
9048  // / 12 / | |
9049  // / / / | |
9050  // *---*---* *-------*
9051 
9052  // set up a list of line iterators first. from
9053  // this, construct lists of line_indices and
9054  // line orientations later on
9055  const typename Triangulation<
9056  dim,
9057  spacedim>::raw_line_iterator lines[13] = {
9058  hex->face(0)->child(0)->line(
9059  (hex->face(0)->refinement_case() ==
9061  1 :
9062  3), // 0
9063  hex->face(1)->child(0)->line(
9064  (hex->face(1)->refinement_case() ==
9066  1 :
9067  3), // 1
9068  hex->face(4)->child(0)->line(
9069  (hex->face(4)->refinement_case() ==
9071  1 :
9072  3), // 2
9073  hex->face(5)->child(0)->line(
9074  (hex->face(5)->refinement_case() ==
9076  1 :
9077  3), // 3
9078 
9079  hex->face(2)
9080  ->isotropic_child(
9082  0, f_or[2], f_fl[2], f_ro[2]))
9083  ->line(
9085  3, f_or[2], f_fl[2], f_ro[2])), // 4
9086  hex->face(2)
9087  ->isotropic_child(
9089  3, f_or[2], f_fl[2], f_ro[2]))
9090  ->line(
9092  2, f_or[2], f_fl[2], f_ro[2])), // 5
9093  hex->face(2)
9094  ->isotropic_child(
9096  0, f_or[2], f_fl[2], f_ro[2]))
9097  ->line(
9099  1, f_or[2], f_fl[2], f_ro[2])), // 6
9100  hex->face(2)
9101  ->isotropic_child(
9103  3, f_or[2], f_fl[2], f_ro[2]))
9104  ->line(
9106  0, f_or[2], f_fl[2], f_ro[2])), // 7
9107 
9108  hex->face(3)
9109  ->isotropic_child(
9111  0, f_or[3], f_fl[3], f_ro[3]))
9112  ->line(
9114  3, f_or[3], f_fl[3], f_ro[3])), // 8
9115  hex->face(3)
9116  ->isotropic_child(
9118  3, f_or[3], f_fl[3], f_ro[3]))
9119  ->line(
9121  2, f_or[3], f_fl[3], f_ro[3])), // 9
9122  hex->face(3)
9123  ->isotropic_child(
9125  0, f_or[3], f_fl[3], f_ro[3]))
9126  ->line(
9128  1, f_or[3], f_fl[3], f_ro[3])), // 10
9129  hex->face(3)
9130  ->isotropic_child(
9132  3, f_or[3], f_fl[3], f_ro[3]))
9133  ->line(
9135  0, f_or[3], f_fl[3], f_ro[3])), // 11
9136 
9137  new_lines[0] // 12
9138  };
9139 
9140  unsigned int line_indices[13];
9141  for (unsigned int i = 0; i < 13; ++i)
9142  line_indices[i] = lines[i]->index();
9143 
9144  // the orientation of lines for the inner quads
9145  // is quite tricky. as these lines are newly
9146  // created ones and thus have no parents, they
9147  // cannot inherit this property. set up an array
9148  // and fill it with the respective values
9149  bool line_orientation[13];
9150 
9151  // the middle vertices of the
9152  // lines of our front face
9153  const unsigned int middle_vertices[4] = {
9154  hex->line(8)->child(0)->vertex_index(1),
9155  hex->line(9)->child(0)->vertex_index(1),
9156  hex->line(2)->child(0)->vertex_index(1),
9157  hex->line(6)->child(0)->vertex_index(1),
9158  };
9159 
9160  // note: for lines 0 to 3 the orientation of the
9161  // line is 'true', if vertex 0 is on the front
9162  for (unsigned int i = 0; i < 4; ++i)
9163  if (lines[i]->vertex_index(0) == middle_vertices[i])
9164  line_orientation[i] = true;
9165  else
9166  {
9167  // it must be the other way round then
9168  Assert(lines[i]->vertex_index(1) ==
9169  middle_vertices[i],
9170  ExcInternalError());
9171  line_orientation[i] = false;
9172  }
9173 
9174  // note: for lines 4 to 11 (inner lines of the
9175  // outer quads) the following holds: the second
9176  // vertex of the even lines in standard
9177  // orientation is the vertex in the middle of
9178  // the quad, whereas for odd lines the first
9179  // vertex is the same middle vertex.
9180  for (unsigned int i = 4; i < 12; ++i)
9181  if (lines[i]->vertex_index((i + 1) % 2) ==
9182  middle_vertex_index<dim, spacedim>(
9183  hex->face(1 + i / 4)))
9184  line_orientation[i] = true;
9185  else
9186  {
9187  // it must be the other way
9188  // round then
9189  Assert(lines[i]->vertex_index(i % 2) ==
9190  (middle_vertex_index<dim, spacedim>(
9191  hex->face(1 + i / 4))),
9192  ExcInternalError());
9193  line_orientation[i] = false;
9194  }
9195  // for the last line the line orientation is
9196  // always true, since it was just constructed
9197  // that way
9198  line_orientation[12] = true;
9199 
9200  // set up the 4 quads, numbered as follows (left
9201  // quad numbering, right line numbering
9202  // extracted from above), the drawings denote
9203  // middle planes
9204  //
9205  // * *
9206  // /| /|
9207  // / | 3 9
9208  // y/ * / *
9209  // * 3/| * /|
9210  // | / |x 5 12|8
9211  // |/ * |/ *
9212  // * 2/ * /
9213  // | / 4 2
9214  // |/ |/
9215  // * *
9216  //
9217  // y
9218  // *----*----* *-10-*-11-*
9219  // / / / / / /
9220  // / 0 / 1 / 0 12 1
9221  // / / / / / /
9222  // *----*----*x *--6-*--7-*
9223 
9224  new_quads[0]->set_bounding_object_indices(
9225  {line_indices[0],
9226  line_indices[12],
9227  line_indices[6],
9228  line_indices[10]});
9229  new_quads[1]->set_bounding_object_indices(
9230  {line_indices[12],
9231  line_indices[1],
9232  line_indices[7],
9233  line_indices[11]});
9234  new_quads[2]->set_bounding_object_indices(
9235  {line_indices[4],
9236  line_indices[8],
9237  line_indices[2],
9238  line_indices[12]});
9239  new_quads[3]->set_bounding_object_indices(
9240  {line_indices[5],
9241  line_indices[9],
9242  line_indices[12],
9243  line_indices[3]});
9244 
9245  new_quads[0]->set_line_orientation(
9246  0, line_orientation[0]);
9247  new_quads[0]->set_line_orientation(
9248  2, line_orientation[6]);
9249  new_quads[0]->set_line_orientation(
9250  3, line_orientation[10]);
9251 
9252  new_quads[1]->set_line_orientation(
9253  1, line_orientation[1]);
9254  new_quads[1]->set_line_orientation(
9255  2, line_orientation[7]);
9256  new_quads[1]->set_line_orientation(
9257  3, line_orientation[11]);
9258 
9259  new_quads[2]->set_line_orientation(
9260  0, line_orientation[4]);
9261  new_quads[2]->set_line_orientation(
9262  1, line_orientation[8]);
9263  new_quads[2]->set_line_orientation(
9264  2, line_orientation[2]);
9265 
9266  new_quads[3]->set_line_orientation(
9267  0, line_orientation[5]);
9268  new_quads[3]->set_line_orientation(
9269  1, line_orientation[9]);
9270  new_quads[3]->set_line_orientation(
9271  3, line_orientation[3]);
9272 
9273  // the quads are numbered as follows:
9274  //
9275  // planes in the interior of the old hex:
9276  //
9277  // *
9278  // /|
9279  // / | x
9280  // /3 * *-------* *----*----*
9281  // * /| | | / / /
9282  // | / | | | / 0 / 1 /
9283  // |/ * | | / / /
9284  // * 2/ *-------*y *----*----*x
9285  // | /
9286  // |/
9287  // *
9288  //
9289  // children of the faces
9290  // of the old hex
9291  // *---*---* *---*---*
9292  // /|13 | 15| / / /|
9293  // / | | | /18 / 19/ |
9294  // / *---*---* / / / *
9295  // * 5/| | | *---*---* 7/|
9296  // | / |12 | 14| | 9 | 11| / |
9297  // |/4 *---*---* | | |/6 *
9298  // * / / / *---*---* /
9299  // | /16 / 17/ | | | /
9300  // |/ / / | 8 | 10|/
9301  // *---*---* *---*---*
9302  //
9303  // note that we have to take care of the
9304  // orientation of faces.
9305  const int quad_indices[20] = {
9306  new_quads[0]->index(), // 0
9307  new_quads[1]->index(),
9308  new_quads[2]->index(),
9309  new_quads[3]->index(),
9310 
9311  hex->face(0)->child_index(
9312  child_at_origin[hex->face(0)->refinement_case() -
9313  1][f_fl[0]][f_ro[0]]), // 4
9314  hex->face(0)->child_index(
9315  1 -
9316  child_at_origin[hex->face(0)->refinement_case() -
9317  1][f_fl[0]][f_ro[0]]),
9318 
9319  hex->face(1)->child_index(
9320  child_at_origin[hex->face(1)->refinement_case() -
9321  1][f_fl[1]][f_ro[1]]), // 6
9322  hex->face(1)->child_index(
9323  1 -
9324  child_at_origin[hex->face(1)->refinement_case() -
9325  1][f_fl[1]][f_ro[1]]),
9326 
9327  hex->face(2)->isotropic_child_index(
9329  0, f_or[2], f_fl[2], f_ro[2])), // 8
9330  hex->face(2)->isotropic_child_index(
9332  1, f_or[2], f_fl[2], f_ro[2])),
9333  hex->face(2)->isotropic_child_index(
9335  2, f_or[2], f_fl[2], f_ro[2])),
9336  hex->face(2)->isotropic_child_index(
9338  3, f_or[2], f_fl[2], f_ro[2])),
9339 
9340  hex->face(3)->isotropic_child_index(
9342  0, f_or[3], f_fl[3], f_ro[3])), // 12
9343  hex->face(3)->isotropic_child_index(
9345  1, f_or[3], f_fl[3], f_ro[3])),
9346  hex->face(3)->isotropic_child_index(
9348  2, f_or[3], f_fl[3], f_ro[3])),
9349  hex->face(3)->isotropic_child_index(
9351  3, f_or[3], f_fl[3], f_ro[3])),
9352 
9353  hex->face(4)->child_index(
9354  child_at_origin[hex->face(4)->refinement_case() -
9355  1][f_fl[4]][f_ro[4]]), // 16
9356  hex->face(4)->child_index(
9357  1 -
9358  child_at_origin[hex->face(4)->refinement_case() -
9359  1][f_fl[4]][f_ro[4]]),
9360 
9361  hex->face(5)->child_index(
9362  child_at_origin[hex->face(5)->refinement_case() -
9363  1][f_fl[5]][f_ro[5]]), // 18
9364  hex->face(5)->child_index(
9365  1 -
9366  child_at_origin[hex->face(5)->refinement_case() -
9367  1][f_fl[5]][f_ro[5]])};
9368 
9369  // due to the exchange of x and y for the front
9370  // and back face, we order the children
9371  // according to
9372  //
9373  // *---*---*
9374  // | 1 | 3 |
9375  // *---*---*
9376  // | 0 | 2 |
9377  // *---*---*
9378  new_hexes[0]->set_bounding_object_indices(
9379  {quad_indices[4],
9380  quad_indices[2],
9381  quad_indices[8],
9382  quad_indices[12],
9383  quad_indices[16],
9384  quad_indices[0]});
9385  new_hexes[1]->set_bounding_object_indices(
9386  {quad_indices[5],
9387  quad_indices[3],
9388  quad_indices[9],
9389  quad_indices[13],
9390  quad_indices[0],
9391  quad_indices[18]});
9392  new_hexes[2]->set_bounding_object_indices(
9393  {quad_indices[2],
9394  quad_indices[6],
9395  quad_indices[10],
9396  quad_indices[14],
9397  quad_indices[17],
9398  quad_indices[1]});
9399  new_hexes[3]->set_bounding_object_indices(
9400  {quad_indices[3],
9401  quad_indices[7],
9402  quad_indices[11],
9403  quad_indices[15],
9404  quad_indices[1],
9405  quad_indices[19]});
9406  break;
9407  }
9408 
9410  {
9411  //----------------------------
9412  //
9413  // RefinementCase<dim>::cut_yz
9414  //
9415  // the refined cube will look like this:
9416  //
9417  // *---------*
9418  // / /|
9419  // *---------* |
9420  // / /| |
9421  // *---------* |/|
9422  // | | * |
9423  // | |/| *
9424  // *---------* |/
9425  // | | *
9426  // | |/
9427  // *---------*
9428  //
9429 
9430  // first, create the new
9431  // internal line
9432  new_lines[0]->set_bounding_object_indices(
9433 
9434  {middle_vertex_index<dim, spacedim>(hex->face(0)),
9435  middle_vertex_index<dim, spacedim>(hex->face(1))});
9436 
9437  // again, first collect some data about the
9438  // indices of the lines, with the following
9439  // numbering: (note that face 0 and 1 each are
9440  // shown twice for better readability)
9441 
9442  // face 0: left plane
9443  // * *
9444  // /| /|
9445  // * | * |
9446  // /| * /| *
9447  // * 5/| * |7|
9448  // | * | | * |
9449  // |/| * |6| *
9450  // * 4/ * |/
9451  // | * | *
9452  // |/ |/
9453  // * *
9454  // face 1: right plane
9455  // * *
9456  // /| /|
9457  // * | * |
9458  // /| * /| *
9459  // * 9/| * |11
9460  // | * | | * |
9461  // |/| * |10 *
9462  // * 8/ * |/
9463  // | * | *
9464  // |/ |/
9465  // * *
9466  // face 2: front plane
9467  // (note: x,y exchanged)
9468  // *-------*
9469  // | |
9470  // *---0---*
9471  // | |
9472  // *-------*
9473  // face 3: back plane
9474  // (note: x,y exchanged)
9475  // *-------*
9476  // | |
9477  // *---1---*
9478  // | |
9479  // *-------*
9480  // face 4: bottom plane
9481  // *-------*
9482  // / /
9483  // *---2---*
9484  // / /
9485  // *-------*
9486  // face 5: top plane
9487  // *-------*
9488  // / /
9489  // *---3---*
9490  // / /
9491  // *-------*
9492  // middle planes
9493  // *-------* *-------*
9494  // / / | |
9495  // *---12--* | |
9496  // / / | |
9497  // *-------* *-------*
9498 
9499  // set up a list of line iterators first. from
9500  // this, construct lists of line_indices and
9501  // line orientations later on
9502  const typename Triangulation<
9503  dim,
9504  spacedim>::raw_line_iterator lines[13] = {
9505  hex->face(2)->child(0)->line(
9506  (hex->face(2)->refinement_case() ==
9508  1 :
9509  3), // 0
9510  hex->face(3)->child(0)->line(
9511  (hex->face(3)->refinement_case() ==
9513  1 :
9514  3), // 1
9515  hex->face(4)->child(0)->line(
9516  (hex->face(4)->refinement_case() ==
9518  1 :
9519  3), // 2
9520  hex->face(5)->child(0)->line(
9521  (hex->face(5)->refinement_case() ==
9523  1 :
9524  3), // 3
9525 
9526  hex->face(0)
9527  ->isotropic_child(
9529  0, f_or[0], f_fl[0], f_ro[0]))
9530  ->line(
9532  1, f_or[0], f_fl[0], f_ro[0])), // 4
9533  hex->face(0)
9534  ->isotropic_child(
9536  3, f_or[0], f_fl[0], f_ro[0]))
9537  ->line(
9539  0, f_or[0], f_fl[0], f_ro[0])), // 5
9540  hex->face(0)
9541  ->isotropic_child(
9543  0, f_or[0], f_fl[0], f_ro[0]))
9544  ->line(
9546  3, f_or[0], f_fl[0], f_ro[0])), // 6
9547  hex->face(0)
9548  ->isotropic_child(
9550  3, f_or[0], f_fl[0], f_ro[0]))
9551  ->line(
9553  2, f_or[0], f_fl[0], f_ro[0])), // 7
9554 
9555  hex->face(1)
9556  ->isotropic_child(
9558  0, f_or[1], f_fl[1], f_ro[1]))
9559  ->line(
9561  1, f_or[1], f_fl[1], f_ro[1])), // 8
9562  hex->face(1)
9563  ->isotropic_child(
9565  3, f_or[1], f_fl[1], f_ro[1]))
9566  ->line(
9568  0, f_or[1], f_fl[1], f_ro[1])), // 9
9569  hex->face(1)
9570  ->isotropic_child(
9572  0, f_or[1], f_fl[1], f_ro[1]))
9573  ->line(
9575  3, f_or[1], f_fl[1], f_ro[1])), // 10
9576  hex->face(1)
9577  ->isotropic_child(
9579  3, f_or[1], f_fl[1], f_ro[1]))
9580  ->line(
9582  2, f_or[1], f_fl[1], f_ro[1])), // 11
9583 
9584  new_lines[0] // 12
9585  };
9586 
9587  unsigned int line_indices[13];
9588 
9589  for (unsigned int i = 0; i < 13; ++i)
9590  line_indices[i] = lines[i]->index();
9591 
9592  // the orientation of lines for the inner quads
9593  // is quite tricky. as these lines are newly
9594  // created ones and thus have no parents, they
9595  // cannot inherit this property. set up an array
9596  // and fill it with the respective values
9597  bool line_orientation[13];
9598 
9599  // the middle vertices of the lines of our front
9600  // face
9601  const unsigned int middle_vertices[4] = {
9602  hex->line(8)->child(0)->vertex_index(1),
9603  hex->line(10)->child(0)->vertex_index(1),
9604  hex->line(0)->child(0)->vertex_index(1),
9605  hex->line(4)->child(0)->vertex_index(1),
9606  };
9607 
9608  // note: for lines 0 to 3 the orientation of the
9609  // line is 'true', if vertex 0 is on the front
9610  for (unsigned int i = 0; i < 4; ++i)
9611  if (lines[i]->vertex_index(0) == middle_vertices[i])
9612  line_orientation[i] = true;
9613  else
9614  {
9615  // it must be the other way round then
9616  Assert(lines[i]->vertex_index(1) ==
9617  middle_vertices[i],
9618  ExcInternalError());
9619  line_orientation[i] = false;
9620  }
9621 
9622  // note: for lines 4 to 11 (inner lines of the
9623  // outer quads) the following holds: the second
9624  // vertex of the even lines in standard
9625  // orientation is the vertex in the middle of
9626  // the quad, whereas for odd lines the first
9627  // vertex is the same middle vertex.
9628  for (unsigned int i = 4; i < 12; ++i)
9629  if (lines[i]->vertex_index((i + 1) % 2) ==
9630  middle_vertex_index<dim, spacedim>(
9631  hex->face(i / 4 - 1)))
9632  line_orientation[i] = true;
9633  else
9634  {
9635  // it must be the other way
9636  // round then
9637  Assert(lines[i]->vertex_index(i % 2) ==
9638  (middle_vertex_index<dim, spacedim>(
9639  hex->face(i / 4 - 1))),
9640  ExcInternalError());
9641  line_orientation[i] = false;
9642  }
9643  // for the last line the line orientation is
9644  // always true, since it was just constructed
9645  // that way
9646  line_orientation[12] = true;
9647 
9648  // set up the 4 quads, numbered as follows (left
9649  // quad numbering, right line numbering
9650  // extracted from above)
9651  //
9652  // x
9653  // *-------* *---3---*
9654  // | 3 | 5 9
9655  // *-------* *---12--*
9656  // | 2 | 4 8
9657  // *-------*y *---2---*
9658  //
9659  // y
9660  // *---------* *----1----*
9661  // / 1 / 7 11
9662  // *---------* *----12---*
9663  // / 0 / 6 10
9664  // *---------*x *----0----*
9665 
9666  new_quads[0]->set_bounding_object_indices(
9667  {line_indices[6],
9668  line_indices[10],
9669  line_indices[0],
9670  line_indices[12]});
9671  new_quads[1]->set_bounding_object_indices(
9672  {line_indices[7],
9673  line_indices[11],
9674  line_indices[12],
9675  line_indices[1]});
9676  new_quads[2]->set_bounding_object_indices(
9677  {line_indices[2],
9678  line_indices[12],
9679  line_indices[4],
9680  line_indices[8]});
9681  new_quads[3]->set_bounding_object_indices(
9682  {line_indices[12],
9683  line_indices[3],
9684  line_indices[5],
9685  line_indices[9]});
9686 
9687  new_quads[0]->set_line_orientation(
9688  0, line_orientation[6]);
9689  new_quads[0]->set_line_orientation(
9690  1, line_orientation[10]);
9691  new_quads[0]->set_line_orientation(
9692  2, line_orientation[0]);
9693 
9694  new_quads[1]->set_line_orientation(
9695  0, line_orientation[7]);
9696  new_quads[1]->set_line_orientation(
9697  1, line_orientation[11]);
9698  new_quads[1]->set_line_orientation(
9699  3, line_orientation[1]);
9700 
9701  new_quads[2]->set_line_orientation(
9702  0, line_orientation[2]);
9703  new_quads[2]->set_line_orientation(
9704  2, line_orientation[4]);
9705  new_quads[2]->set_line_orientation(
9706  3, line_orientation[8]);
9707 
9708  new_quads[3]->set_line_orientation(
9709  1, line_orientation[3]);
9710  new_quads[3]->set_line_orientation(
9711  2, line_orientation[5]);
9712  new_quads[3]->set_line_orientation(
9713  3, line_orientation[9]);
9714 
9715  // the quads are numbered as follows:
9716  //
9717  // planes in the interior of the old hex:
9718  //
9719  // *
9720  // /|
9721  // / | x
9722  // / | *-------* *---------*
9723  // * | | 3 | / 1 /
9724  // | | *-------* *---------*
9725  // | * | 2 | / 0 /
9726  // | / *-------*y *---------*x
9727  // | /
9728  // |/
9729  // *
9730  //
9731  // children of the faces
9732  // of the old hex
9733  // *-------* *-------*
9734  // /| | / 19 /|
9735  // * | 15 | *-------* |
9736  // /|7*-------* / 18 /|11
9737  // * |/| | *-------* |/|
9738  // |6* | 14 | | 10* |
9739  // |/|5*-------* | 13 |/|9*
9740  // * |/ 17 / *-------* |/
9741  // |4*-------* | |8*
9742  // |/ 16 / | 12 |/
9743  // *-------* *-------*
9744  //
9745  // note that we have to take care of the
9746  // orientation of faces.
9747  const int quad_indices[20] = {
9748  new_quads[0]->index(), // 0
9749  new_quads[1]->index(),
9750  new_quads[2]->index(),
9751  new_quads[3]->index(),
9752 
9753  hex->face(0)->isotropic_child_index(
9755  0, f_or[0], f_fl[0], f_ro[0])), // 4
9756  hex->face(0)->isotropic_child_index(
9758  1, f_or[0], f_fl[0], f_ro[0])),
9759  hex->face(0)->isotropic_child_index(
9761  2, f_or[0], f_fl[0], f_ro[0])),
9762  hex->face(0)->isotropic_child_index(
9764  3, f_or[0], f_fl[0], f_ro[0])),
9765 
9766  hex->face(1)->isotropic_child_index(
9768  0, f_or[1], f_fl[1], f_ro[1])), // 8
9769  hex->face(1)->isotropic_child_index(
9771  1, f_or[1], f_fl[1], f_ro[1])),
9772  hex->face(1)->isotropic_child_index(
9774  2, f_or[1], f_fl[1], f_ro[1])),
9775  hex->face(1)->isotropic_child_index(
9777  3, f_or[1], f_fl[1], f_ro[1])),
9778 
9779  hex->face(2)->child_index(
9780  child_at_origin[hex->face(2)->refinement_case() -
9781  1][f_fl[2]][f_ro[2]]), // 12
9782  hex->face(2)->child_index(
9783  1 -
9784  child_at_origin[hex->face(2)->refinement_case() -
9785  1][f_fl[2]][f_ro[2]]),
9786 
9787  hex->face(3)->child_index(
9788  child_at_origin[hex->face(3)->refinement_case() -
9789  1][f_fl[3]][f_ro[3]]), // 14
9790  hex->face(3)->child_index(
9791  1 -
9792  child_at_origin[hex->face(3)->refinement_case() -
9793  1][f_fl[3]][f_ro[3]]),
9794 
9795  hex->face(4)->child_index(
9796  child_at_origin[hex->face(4)->refinement_case() -
9797  1][f_fl[4]][f_ro[4]]), // 16
9798  hex->face(4)->child_index(
9799  1 -
9800  child_at_origin[hex->face(4)->refinement_case() -
9801  1][f_fl[4]][f_ro[4]]),
9802 
9803  hex->face(5)->child_index(
9804  child_at_origin[hex->face(5)->refinement_case() -
9805  1][f_fl[5]][f_ro[5]]), // 18
9806  hex->face(5)->child_index(
9807  1 -
9808  child_at_origin[hex->face(5)->refinement_case() -
9809  1][f_fl[5]][f_ro[5]])};
9810 
9811  new_hexes[0]->set_bounding_object_indices(
9812  {quad_indices[4],
9813  quad_indices[8],
9814  quad_indices[12],
9815  quad_indices[2],
9816  quad_indices[16],
9817  quad_indices[0]});
9818  new_hexes[1]->set_bounding_object_indices(
9819  {quad_indices[5],
9820  quad_indices[9],
9821  quad_indices[2],
9822  quad_indices[14],
9823  quad_indices[17],
9824  quad_indices[1]});
9825  new_hexes[2]->set_bounding_object_indices(
9826  {quad_indices[6],
9827  quad_indices[10],
9828  quad_indices[13],
9829  quad_indices[3],
9830  quad_indices[0],
9831  quad_indices[18]});
9832  new_hexes[3]->set_bounding_object_indices(
9833  {quad_indices[7],
9834  quad_indices[11],
9835  quad_indices[3],
9836  quad_indices[15],
9837  quad_indices[1],
9838  quad_indices[19]});
9839  break;
9840  }
9841 
9843  {
9844  //----------------------------
9845  //
9846  // RefinementCase<dim>::cut_xyz
9847  // isotropic refinement
9848  //
9849  // the refined cube will look
9850  // like this:
9851  //
9852  // *----*----*
9853  // / / /|
9854  // *----*----* |
9855  // / / /| *
9856  // *----*----* |/|
9857  // | | | * |
9858  // | | |/| *
9859  // *----*----* |/
9860  // | | | *
9861  // | | |/
9862  // *----*----*
9863  //
9864 
9865  // find the next unused vertex and set it
9866  // appropriately
9867  while (
9868  triangulation.vertices_used[next_unused_vertex] ==
9869  true)
9870  ++next_unused_vertex;
9871  Assert(
9872  next_unused_vertex < triangulation.vertices.size(),
9873  ExcMessage(
9874  "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."));
9875  triangulation.vertices_used[next_unused_vertex] =
9876  true;
9877 
9878  // the new vertex is definitely in the interior,
9879  // so we need not worry about the
9880  // boundary. However we need to worry about
9881  // Manifolds. Let the cell compute its own
9882  // center, by querying the underlying manifold
9883  // object.
9884  triangulation.vertices[next_unused_vertex] =
9885  hex->center(true, true);
9886 
9887  // set the data of the six lines. first collect
9888  // the indices of the seven vertices (consider
9889  // the two planes to be crossed to form the
9890  // planes cutting the hex in two vertically and
9891  // horizontally)
9892  //
9893  // *--3--* *--5--*
9894  // / / / | | |
9895  // 0--6--1 0--6--1
9896  // / / / | | |
9897  // *--2--* *--4--*
9898  // the lines are numbered
9899  // as follows:
9900  // *--*--* *--*--*
9901  // / 1 / | 5 |
9902  // *2-*-3* *2-*-3*
9903  // / 0 / | 4 |
9904  // *--*--* *--*--*
9905  //
9906  const unsigned int vertex_indices[7] = {
9907  middle_vertex_index<dim, spacedim>(hex->face(0)),
9908  middle_vertex_index<dim, spacedim>(hex->face(1)),
9909  middle_vertex_index<dim, spacedim>(hex->face(2)),
9910  middle_vertex_index<dim, spacedim>(hex->face(3)),
9911  middle_vertex_index<dim, spacedim>(hex->face(4)),
9912  middle_vertex_index<dim, spacedim>(hex->face(5)),
9913  next_unused_vertex};
9914 
9915  new_lines[0]->set_bounding_object_indices(
9916  {vertex_indices[2], vertex_indices[6]});
9917  new_lines[1]->set_bounding_object_indices(
9918  {vertex_indices[6], vertex_indices[3]});
9919  new_lines[2]->set_bounding_object_indices(
9920  {vertex_indices[0], vertex_indices[6]});
9921  new_lines[3]->set_bounding_object_indices(
9922  {vertex_indices[6], vertex_indices[1]});
9923  new_lines[4]->set_bounding_object_indices(
9924  {vertex_indices[4], vertex_indices[6]});
9925  new_lines[5]->set_bounding_object_indices(
9926  {vertex_indices[6], vertex_indices[5]});
9927 
9928  // again, first collect some data about the
9929  // indices of the lines, with the following
9930  // numbering: (note that face 0 and 1 each are
9931  // shown twice for better readability)
9932 
9933  // face 0: left plane
9934  // * *
9935  // /| /|
9936  // * | * |
9937  // /| * /| *
9938  // * 1/| * |3|
9939  // | * | | * |
9940  // |/| * |2| *
9941  // * 0/ * |/
9942  // | * | *
9943  // |/ |/
9944  // * *
9945  // face 1: right plane
9946  // * *
9947  // /| /|
9948  // * | * |
9949  // /| * /| *
9950  // * 5/| * |7|
9951  // | * | | * |
9952  // |/| * |6| *
9953  // * 4/ * |/
9954  // | * | *
9955  // |/ |/
9956  // * *
9957  // face 2: front plane
9958  // (note: x,y exchanged)
9959  // *---*---*
9960  // | 11 |
9961  // *-8-*-9-*
9962  // | 10 |
9963  // *---*---*
9964  // face 3: back plane
9965  // (note: x,y exchanged)
9966  // *---*---*
9967  // | 15 |
9968  // *12-*-13*
9969  // | 14 |
9970  // *---*---*
9971  // face 4: bottom plane
9972  // *---*---*
9973  // / 17 /
9974  // *18-*-19*
9975  // / 16 /
9976  // *---*---*
9977  // face 5: top plane
9978  // *---*---*
9979  // / 21 /
9980  // *22-*-23*
9981  // / 20 /
9982  // *---*---*
9983  // middle planes
9984  // *---*---* *---*---*
9985  // / 25 / | 29 |
9986  // *26-*-27* *26-*-27*
9987  // / 24 / | 28 |
9988  // *---*---* *---*---*
9989 
9990  // set up a list of line iterators first. from
9991  // this, construct lists of line_indices and
9992  // line orientations later on
9993  const typename Triangulation<
9994  dim,
9995  spacedim>::raw_line_iterator lines[30] = {
9996  hex->face(0)
9997  ->isotropic_child(
9999  0, f_or[0], f_fl[0], f_ro[0]))
10000  ->line(
10002  1, f_or[0], f_fl[0], f_ro[0])), // 0
10003  hex->face(0)
10004  ->isotropic_child(
10006  3, f_or[0], f_fl[0], f_ro[0]))
10007  ->line(
10009  0, f_or[0], f_fl[0], f_ro[0])), // 1
10010  hex->face(0)
10011  ->isotropic_child(
10013  0, f_or[0], f_fl[0], f_ro[0]))
10014  ->line(
10016  3, f_or[0], f_fl[0], f_ro[0])), // 2
10017  hex->face(0)
10018  ->isotropic_child(
10020  3, f_or[0], f_fl[0], f_ro[0]))
10021  ->line(
10023  2, f_or[0], f_fl[0], f_ro[0])), // 3
10024 
10025  hex->face(1)
10026  ->isotropic_child(
10028  0, f_or[1], f_fl[1], f_ro[1]))
10029  ->line(
10031  1, f_or[1], f_fl[1], f_ro[1])), // 4
10032  hex->face(1)
10033  ->isotropic_child(
10035  3, f_or[1], f_fl[1], f_ro[1]))
10036  ->line(
10038  0, f_or[1], f_fl[1], f_ro[1])), // 5
10039  hex->face(1)
10040  ->isotropic_child(
10042  0, f_or[1], f_fl[1], f_ro[1]))
10043  ->line(
10045  3, f_or[1], f_fl[1], f_ro[1])), // 6
10046  hex->face(1)
10047  ->isotropic_child(
10049  3, f_or[1], f_fl[1], f_ro[1]))
10050  ->line(
10052  2, f_or[1], f_fl[1], f_ro[1])), // 7
10053 
10054  hex->face(2)
10055  ->isotropic_child(
10057  0, f_or[2], f_fl[2], f_ro[2]))
10058  ->line(
10060  1, f_or[2], f_fl[2], f_ro[2])), // 8
10061  hex->face(2)
10062  ->isotropic_child(
10064  3, f_or[2], f_fl[2], f_ro[2]))
10065  ->line(
10067  0, f_or[2], f_fl[2], f_ro[2])), // 9
10068  hex->face(2)
10069  ->isotropic_child(
10071  0, f_or[2], f_fl[2], f_ro[2]))
10072  ->line(
10074  3, f_or[2], f_fl[2], f_ro[2])), // 10
10075  hex->face(2)
10076  ->isotropic_child(
10078  3, f_or[2], f_fl[2], f_ro[2]))
10079  ->line(
10081  2, f_or[2], f_fl[2], f_ro[2])), // 11
10082 
10083  hex->face(3)
10084  ->isotropic_child(
10086  0, f_or[3], f_fl[3], f_ro[3]))
10087  ->line(
10089  1, f_or[3], f_fl[3], f_ro[3])), // 12
10090  hex->face(3)
10091  ->isotropic_child(
10093  3, f_or[3], f_fl[3], f_ro[3]))
10094  ->line(
10096  0, f_or[3], f_fl[3], f_ro[3])), // 13
10097  hex->face(3)
10098  ->isotropic_child(
10100  0, f_or[3], f_fl[3], f_ro[3]))
10101  ->line(
10103  3, f_or[3], f_fl[3], f_ro[3])), // 14
10104  hex->face(3)
10105  ->isotropic_child(
10107  3, f_or[3], f_fl[3], f_ro[3]))
10108  ->line(
10110  2, f_or[3], f_fl[3], f_ro[3])), // 15
10111 
10112  hex->face(4)
10113  ->isotropic_child(
10115  0, f_or[4], f_fl[4], f_ro[4]))
10116  ->line(
10118  1, f_or[4], f_fl[4], f_ro[4])), // 16
10119  hex->face(4)
10120  ->isotropic_child(
10122  3, f_or[4], f_fl[4], f_ro[4]))
10123  ->line(
10125  0, f_or[4], f_fl[4], f_ro[4])), // 17
10126  hex->face(4)
10127  ->isotropic_child(
10129  0, f_or[4], f_fl[4], f_ro[4]))
10130  ->line(
10132  3, f_or[4], f_fl[4], f_ro[4])), // 18
10133  hex->face(4)
10134  ->isotropic_child(
10136  3, f_or[4], f_fl[4], f_ro[4]))
10137  ->line(
10139  2, f_or[4], f_fl[4], f_ro[4])), // 19
10140 
10141  hex->face(5)
10142  ->isotropic_child(
10144  0, f_or[5], f_fl[5], f_ro[5]))
10145  ->line(
10147  1, f_or[5], f_fl[5], f_ro[5])), // 20
10148  hex->face(5)
10149  ->isotropic_child(
10151  3, f_or[5], f_fl[5], f_ro[5]))
10152  ->line(
10154  0, f_or[5], f_fl[5], f_ro[5])), // 21
10155  hex->face(5)
10156  ->isotropic_child(
10158  0, f_or[5], f_fl[5], f_ro[5]))
10159  ->line(
10161  3, f_or[5], f_fl[5], f_ro[5])), // 22
10162  hex->face(5)
10163  ->isotropic_child(
10165  3, f_or[5], f_fl[5], f_ro[5]))
10166  ->line(
10168  2, f_or[5], f_fl[5], f_ro[5])), // 23
10169 
10170  new_lines[0], // 24
10171  new_lines[1], // 25
10172  new_lines[2], // 26
10173  new_lines[3], // 27
10174  new_lines[4], // 28
10175  new_lines[5] // 29
10176  };
10177 
10178  unsigned int line_indices[30];
10179  for (unsigned int i = 0; i < 30; ++i)
10180  line_indices[i] = lines[i]->index();
10181 
10182  // the orientation of lines for the inner quads
10183  // is quite tricky. as these lines are newly
10184  // created ones and thus have no parents, they
10185  // cannot inherit this property. set up an array
10186  // and fill it with the respective values
10187  bool line_orientation[30];
10188 
10189  // note: for the first 24 lines (inner lines of
10190  // the outer quads) the following holds: the
10191  // second vertex of the even lines in standard
10192  // orientation is the vertex in the middle of
10193  // the quad, whereas for odd lines the first
10194  // vertex is the same middle vertex.
10195  for (unsigned int i = 0; i < 24; ++i)
10196  if (lines[i]->vertex_index((i + 1) % 2) ==
10197  vertex_indices[i / 4])
10198  line_orientation[i] = true;
10199  else
10200  {
10201  // it must be the other way
10202  // round then
10203  Assert(lines[i]->vertex_index(i % 2) ==
10204  vertex_indices[i / 4],
10205  ExcInternalError());
10206  line_orientation[i] = false;
10207  }
10208  // for the last 6 lines the line orientation is
10209  // always true, since they were just constructed
10210  // that way
10211  for (unsigned int i = 24; i < 30; ++i)
10212  line_orientation[i] = true;
10213 
10214  // set up the 12 quads, numbered as follows
10215  // (left quad numbering, right line numbering
10216  // extracted from above)
10217  //
10218  // * *
10219  // /| 21|
10220  // * | * 15
10221  // y/|3* 20| *
10222  // * |/| * |/|
10223  // |2* |x 11 * 14
10224  // |/|1* |/| *
10225  // * |/ * |17
10226  // |0* 10 *
10227  // |/ |16
10228  // * *
10229  //
10230  // x
10231  // *---*---* *22-*-23*
10232  // | 5 | 7 | 1 29 5
10233  // *---*---* *26-*-27*
10234  // | 4 | 6 | 0 28 4
10235  // *---*---*y *18-*-19*
10236  //
10237  // y
10238  // *----*----* *-12-*-13-*
10239  // / 10 / 11 / 3 25 7
10240  // *----*----* *-26-*-27-*
10241  // / 8 / 9 / 2 24 6
10242  // *----*----*x *--8-*--9-*
10243 
10244  new_quads[0]->set_bounding_object_indices(
10245  {line_indices[10],
10246  line_indices[28],
10247  line_indices[16],
10248  line_indices[24]});
10249  new_quads[1]->set_bounding_object_indices(
10250  {line_indices[28],
10251  line_indices[14],
10252  line_indices[17],
10253  line_indices[25]});
10254  new_quads[2]->set_bounding_object_indices(
10255  {line_indices[11],
10256  line_indices[29],
10257  line_indices[24],
10258  line_indices[20]});
10259  new_quads[3]->set_bounding_object_indices(
10260  {line_indices[29],
10261  line_indices[15],
10262  line_indices[25],
10263  line_indices[21]});
10264  new_quads[4]->set_bounding_object_indices(
10265  {line_indices[18],
10266  line_indices[26],
10267  line_indices[0],
10268  line_indices[28]});
10269  new_quads[5]->set_bounding_object_indices(
10270  {line_indices[26],
10271  line_indices[22],
10272  line_indices[1],
10273  line_indices[29]});
10274  new_quads[6]->set_bounding_object_indices(
10275  {line_indices[19],
10276  line_indices[27],
10277  line_indices[28],
10278  line_indices[4]});
10279  new_quads[7]->set_bounding_object_indices(
10280  {line_indices[27],
10281  line_indices[23],
10282  line_indices[29],
10283  line_indices[5]});
10284  new_quads[8]->set_bounding_object_indices(
10285  {line_indices[2],
10286  line_indices[24],
10287  line_indices[8],
10288  line_indices[26]});
10289  new_quads[9]->set_bounding_object_indices(
10290  {line_indices[24],
10291  line_indices[6],
10292  line_indices[9],
10293  line_indices[27]});
10294  new_quads[10]->set_bounding_object_indices(
10295  {line_indices[3],
10296  line_indices[25],
10297  line_indices[26],
10298  line_indices[12]});
10299  new_quads[11]->set_bounding_object_indices(
10300  {line_indices[25],
10301  line_indices[7],
10302  line_indices[27],
10303  line_indices[13]});
10304 
10305  // now reset the line_orientation flags of outer
10306  // lines as they cannot be set in a loop (at
10307  // least not easily)
10308  new_quads[0]->set_line_orientation(
10309  0, line_orientation[10]);
10310  new_quads[0]->set_line_orientation(
10311  2, line_orientation[16]);
10312 
10313  new_quads[1]->set_line_orientation(
10314  1, line_orientation[14]);
10315  new_quads[1]->set_line_orientation(
10316  2, line_orientation[17]);
10317 
10318  new_quads[2]->set_line_orientation(
10319  0, line_orientation[11]);
10320  new_quads[2]->set_line_orientation(
10321  3, line_orientation[20]);
10322 
10323  new_quads[3]->set_line_orientation(
10324  1, line_orientation[15]);
10325  new_quads[3]->set_line_orientation(
10326  3, line_orientation[21]);
10327 
10328  new_quads[4]->set_line_orientation(
10329  0, line_orientation[18]);
10330  new_quads[4]->set_line_orientation(
10331  2, line_orientation[0]);
10332 
10333  new_quads[5]->set_line_orientation(
10334  1, line_orientation[22]);
10335  new_quads[5]->set_line_orientation(
10336  2, line_orientation[1]);
10337 
10338  new_quads[6]->set_line_orientation(
10339  0, line_orientation[19]);
10340  new_quads[6]->set_line_orientation(
10341  3, line_orientation[4]);
10342 
10343  new_quads[7]->set_line_orientation(
10344  1, line_orientation[23]);
10345  new_quads[7]->set_line_orientation(
10346  3, line_orientation[5]);
10347 
10348  new_quads[8]->set_line_orientation(
10349  0, line_orientation[2]);
10350  new_quads[8]->set_line_orientation(
10351  2, line_orientation[8]);
10352 
10353  new_quads[9]->set_line_orientation(
10354  1, line_orientation[6]);
10355  new_quads[9]->set_line_orientation(
10356  2, line_orientation[9]);
10357 
10358  new_quads[10]->set_line_orientation(
10359  0, line_orientation[3]);
10360  new_quads[10]->set_line_orientation(
10361  3, line_orientation[12]);
10362 
10363  new_quads[11]->set_line_orientation(
10364  1, line_orientation[7]);
10365  new_quads[11]->set_line_orientation(
10366  3, line_orientation[13]);
10367 
10368  //-------------------------------
10369  // create the eight new hexes
10370  //
10371  // again first collect some data. here, we need
10372  // the indices of a whole lotta quads.
10373 
10374  // the quads are numbered as follows:
10375  //
10376  // planes in the interior of the old hex:
10377  //
10378  // *
10379  // /|
10380  // * |
10381  // /|3* *---*---* *----*----*
10382  // * |/| | 5 | 7 | / 10 / 11 /
10383  // |2* | *---*---* *----*----*
10384  // |/|1* | 4 | 6 | / 8 / 9 /
10385  // * |/ *---*---*y *----*----*x
10386  // |0*
10387  // |/
10388  // *
10389  //
10390  // children of the faces
10391  // of the old hex
10392  // *-------* *-------*
10393  // /|25 27| /34 35/|
10394  // 15| | / /19
10395  // / | | /32 33/ |
10396  // * |24 26| *-------*18 |
10397  // 1413*-------* |21 23| 17*
10398  // | /30 31/ | | /
10399  // 12/ / | |16
10400  // |/28 29/ |20 22|/
10401  // *-------* *-------*
10402  //
10403  // note that we have to
10404  // take care of the
10405  // orientation of
10406  // faces.
10407  const int quad_indices[36] = {
10408  new_quads[0]->index(), // 0
10409  new_quads[1]->index(),
10410  new_quads[2]->index(),
10411  new_quads[3]->index(),
10412  new_quads[4]->index(),
10413  new_quads[5]->index(),
10414  new_quads[6]->index(),
10415  new_quads[7]->index(),
10416  new_quads[8]->index(),
10417  new_quads[9]->index(),
10418  new_quads[10]->index(),
10419  new_quads[11]->index(), // 11
10420 
10421  hex->face(0)->isotropic_child_index(
10423  0, f_or[0], f_fl[0], f_ro[0])), // 12
10424  hex->face(0)->isotropic_child_index(
10426  1, f_or[0], f_fl[0], f_ro[0])),
10427  hex->face(0)->isotropic_child_index(
10429  2, f_or[0], f_fl[0], f_ro[0])),
10430  hex->face(0)->isotropic_child_index(
10432  3, f_or[0], f_fl[0], f_ro[0])),
10433 
10434  hex->face(1)->isotropic_child_index(
10436  0, f_or[1], f_fl[1], f_ro[1])), // 16
10437  hex->face(1)->isotropic_child_index(
10439  1, f_or[1], f_fl[1], f_ro[1])),
10440  hex->face(1)->isotropic_child_index(
10442  2, f_or[1], f_fl[1], f_ro[1])),
10443  hex->face(1)->isotropic_child_index(
10445  3, f_or[1], f_fl[1], f_ro[1])),
10446 
10447  hex->face(2)->isotropic_child_index(
10449  0, f_or[2], f_fl[2], f_ro[2])), // 20
10450  hex->face(2)->isotropic_child_index(
10452  1, f_or[2], f_fl[2], f_ro[2])),
10453  hex->face(2)->isotropic_child_index(
10455  2, f_or[2], f_fl[2], f_ro[2])),
10456  hex->face(2)->isotropic_child_index(
10458  3, f_or[2], f_fl[2], f_ro[2])),
10459 
10460  hex->face(3)->isotropic_child_index(
10462  0, f_or[3], f_fl[3], f_ro[3])), // 24
10463  hex->face(3)->isotropic_child_index(
10465  1, f_or[3], f_fl[3], f_ro[3])),
10466  hex->face(3)->isotropic_child_index(
10468  2, f_or[3], f_fl[3], f_ro[3])),
10469  hex->face(3)->isotropic_child_index(
10471  3, f_or[3], f_fl[3], f_ro[3])),
10472 
10473  hex->face(4)->isotropic_child_index(
10475  0, f_or[4], f_fl[4], f_ro[4])), // 28
10476  hex->face(4)->isotropic_child_index(
10478  1, f_or[4], f_fl[4], f_ro[4])),
10479  hex->face(4)->isotropic_child_index(
10481  2, f_or[4], f_fl[4], f_ro[4])),
10482  hex->face(4)->isotropic_child_index(
10484  3, f_or[4], f_fl[4], f_ro[4])),
10485 
10486  hex->face(5)->isotropic_child_index(
10488  0, f_or[5], f_fl[5], f_ro[5])), // 32
10489  hex->face(5)->isotropic_child_index(
10491  1, f_or[5], f_fl[5], f_ro[5])),
10492  hex->face(5)->isotropic_child_index(
10494  2, f_or[5], f_fl[5], f_ro[5])),
10495  hex->face(5)->isotropic_child_index(
10497  3, f_or[5], f_fl[5], f_ro[5]))};
10498 
10499  // bottom children
10500  new_hexes[0]->set_bounding_object_indices(
10501  {quad_indices[12],
10502  quad_indices[0],
10503  quad_indices[20],
10504  quad_indices[4],
10505  quad_indices[28],
10506  quad_indices[8]});
10507  new_hexes[1]->set_bounding_object_indices(
10508  {quad_indices[0],
10509  quad_indices[16],
10510  quad_indices[22],
10511  quad_indices[6],
10512  quad_indices[29],
10513  quad_indices[9]});
10514  new_hexes[2]->set_bounding_object_indices(
10515  {quad_indices[13],
10516  quad_indices[1],
10517  quad_indices[4],
10518  quad_indices[24],
10519  quad_indices[30],
10520  quad_indices[10]});
10521  new_hexes[3]->set_bounding_object_indices(
10522  {quad_indices[1],
10523  quad_indices[17],
10524  quad_indices[6],
10525  quad_indices[26],
10526  quad_indices[31],
10527  quad_indices[11]});
10528 
10529  // top children
10530  new_hexes[4]->set_bounding_object_indices(
10531  {quad_indices[14],
10532  quad_indices[2],
10533  quad_indices[21],
10534  quad_indices[5],
10535  quad_indices[8],
10536  quad_indices[32]});
10537  new_hexes[5]->set_bounding_object_indices(
10538  {quad_indices[2],
10539  quad_indices[18],
10540  quad_indices[23],
10541  quad_indices[7],
10542  quad_indices[9],
10543  quad_indices[33]});
10544  new_hexes[6]->set_bounding_object_indices(
10545  {quad_indices[15],
10546  quad_indices[3],
10547  quad_indices[5],
10548  quad_indices[25],
10549  quad_indices[10],
10550  quad_indices[34]});
10551  new_hexes[7]->set_bounding_object_indices(
10552  {quad_indices[3],
10553  quad_indices[19],
10554  quad_indices[7],
10555  quad_indices[27],
10556  quad_indices[11],
10557  quad_indices[35]});
10558  break;
10559  }
10560  default:
10561  // all refinement cases have been treated, there
10562  // only remains
10563  // RefinementCase<dim>::no_refinement as
10564  // untreated enumeration value. However, in that
10565  // case we should have aborted much
10566  // earlier. thus we should never get here
10567  Assert(false, ExcInternalError());
10568  break;
10569  } // switch (ref_case)
10570 
10571  // and set face orientation flags. note that new
10572  // faces in the interior of the mother cell always
10573  // have a correctly oriented face, but the ones on
10574  // the outer faces will inherit this flag
10575  //
10576  // the flag have been set to true for all faces
10577  // initially, now go the other way round and reset
10578  // faces that are at the boundary of the mother cube
10579  //
10580  // the same is true for the face_flip and
10581  // face_rotation flags. however, the latter two are
10582  // set to false by default as this is the standard
10583  // value
10584 
10585  // loop over all faces and all (relevant) subfaces
10586  // of that in order to set the correct values for
10587  // face_orientation, face_flip and face_rotation,
10588  // which are inherited from the corresponding face
10589  // of the mother cube
10590  for (const unsigned int f : GeometryInfo<dim>::face_indices())
10591  for (unsigned int s = 0;
10594  ref_case, f)),
10595  1U);
10596  ++s)
10597  {
10598  const unsigned int current_child =
10600  ref_case,
10601  f,
10602  s,
10603  f_or[f],
10604  f_fl[f],
10605  f_ro[f],
10607  ref_case, f, f_or[f], f_fl[f], f_ro[f]));
10608  new_hexes[current_child]->set_face_orientation(f,
10609  f_or[f]);
10610  new_hexes[current_child]->set_face_flip(f, f_fl[f]);
10611  new_hexes[current_child]->set_face_rotation(f, f_ro[f]);
10612  }
10613 
10614  // now see if we have created cells that are
10615  // distorted and if so add them to our list
10616  if (check_for_distorted_cells &&
10617  has_distorted_children<dim, spacedim>(hex))
10618  cells_with_distorted_children.distorted_cells.push_back(
10619  hex);
10620 
10621  // note that the refinement flag was already cleared
10622  // at the beginning of this loop
10623 
10624  // inform all listeners that cell refinement is done
10625  triangulation.signals.post_refinement_on_cell(hex);
10626  }
10627  }
10628 
10629  // clear user data on quads. we used some of this data to
10630  // indicate anisotropic refinemnt cases on faces. all data
10631  // should be cleared by now, but the information whether we
10632  // used indices or pointers is still present. reset it now to
10633  // enable the user to use whichever they like later on.
10634  triangulation.faces->quads.clear_user_data();
10635 
10636  // return the list with distorted children
10637  return cells_with_distorted_children;
10638  }
10639 
10640 
10653  template <int spacedim>
10654  static void
10656  {}
10657 
10658 
10659 
10660  template <int dim, int spacedim>
10661  static void
10664  {
10665  // If the codimension is one, we cannot perform this check
10666  // yet.
10667  if (spacedim > dim)
10668  return;
10669 
10670  for (const auto &cell : triangulation.cell_iterators())
10671  if (cell->at_boundary() && cell->refine_flag_set() &&
10672  cell->refine_flag_set() !=
10674  {
10675  // The cell is at the boundary and it is flagged for
10676  // anisotropic refinement. Therefore, we have a closer
10677  // look
10678  const RefinementCase<dim> ref_case = cell->refine_flag_set();
10679  for (const unsigned int face_no :
10681  if (cell->face(face_no)->at_boundary())
10682  {
10683  // this is the critical face at the boundary.
10685  face_no) !=
10687  {
10688  // up to now, we do not want to refine this
10689  // cell along the face under consideration
10690  // here.
10691  const typename Triangulation<dim,
10692  spacedim>::face_iterator
10693  face = cell->face(face_no);
10694  // the new point on the boundary would be this
10695  // one.
10696  const Point<spacedim> new_bound = face->center(true);
10697  // to check it, transform to the unit cell
10698  // with a linear mapping
10699  const Point<dim> new_unit =
10700  cell->reference_cell()
10701  .template get_default_linear_mapping<dim,
10702  spacedim>()
10703  .transform_real_to_unit_cell(cell, new_bound);
10704 
10705  // Now, we have to calculate the distance from
10706  // the face in the unit cell.
10707 
10708  // take the correct coordinate direction (0
10709  // for faces 0 and 1, 1 for faces 2 and 3, 2
10710  // for faces 4 and 5) and subtract the correct
10711  // boundary value of the face (0 for faces 0,
10712  // 2, and 4; 1 for faces 1, 3 and 5)
10713  const double dist =
10714  std::fabs(new_unit[face_no / 2] - face_no % 2);
10715 
10716  // compare this with the empirical value
10717  // allowed. if it is too big, flag the face
10718  // for isotropic refinement
10719  const double allowed = 0.25;
10720 
10721  if (dist > allowed)
10722  cell->flag_for_face_refinement(face_no);
10723  } // if flagged for anistropic refinement
10724  } // if (cell->face(face)->at_boundary())
10725  } // for all cells
10726  }
10727 
10728 
10741  template <int dim, int spacedim>
10742  static void
10744  {
10745  Assert(dim < 3,
10746  ExcMessage("Wrong function called -- there should "
10747  "be a specialization."));
10748  }
10749 
10750 
10751  template <int spacedim>
10752  static void
10755  {
10756  const unsigned int dim = 3;
10757 
10758  // first clear flags on lines, since we need them to determine
10759  // which lines will be refined
10760  triangulation.clear_user_flags_line();
10761 
10762  // also clear flags on hexes, since we need them to mark those
10763  // cells which are to be coarsened
10764  triangulation.clear_user_flags_hex();
10765 
10766  // variable to store whether the mesh was changed in the
10767  // present loop and in the whole process
10768  bool mesh_changed = false;
10769 
10770  do
10771  {
10772  mesh_changed = false;
10773 
10774  // for this following, we need to know which cells are
10775  // going to be coarsened, if we had to make a
10776  // decision. the following function sets these flags:
10777  triangulation.fix_coarsen_flags();
10778 
10779 
10780  // flag those lines that are refined and will not be
10781  // coarsened and those that will be refined
10782  for (const auto &cell : triangulation.cell_iterators())
10783  if (cell->refine_flag_set())
10784  {
10785  for (unsigned int line = 0; line < cell->n_lines(); ++line)
10787  cell->refine_flag_set(), line) ==
10789  // flag a line, that will be
10790  // refined
10791  cell->line(line)->set_user_flag();
10792  }
10793  else if (cell->has_children() &&
10794  !cell->child(0)->coarsen_flag_set())
10795  {
10796  for (unsigned int line = 0; line < cell->n_lines(); ++line)
10798  cell->refinement_case(), line) ==
10800  // flag a line, that is refined
10801  // and will stay so
10802  cell->line(line)->set_user_flag();
10803  }
10804  else if (cell->has_children() &&
10805  cell->child(0)->coarsen_flag_set())
10806  cell->set_user_flag();
10807 
10808 
10809  // now check whether there are cells with lines that are
10810  // more than once refined or that will be more than once
10811  // refined. The first thing should never be the case, in
10812  // the second case we flag the cell for refinement
10814  cell = triangulation.last_active();
10815  cell != triangulation.end();
10816  --cell)
10817  for (unsigned int line = 0; line < cell->n_lines(); ++line)
10818  {
10819  if (cell->line(line)->has_children())
10820  {
10821  // if this line is refined, its children should
10822  // not have further children
10823  //
10824  // however, if any of the children is flagged
10825  // for further refinement, we need to refine
10826  // this cell also (at least, if the cell is not
10827  // already flagged)
10828  bool offending_line_found = false;
10829 
10830  for (unsigned int c = 0; c < 2; ++c)
10831  {
10832  Assert(cell->line(line)->child(c)->has_children() ==
10833  false,
10834  ExcInternalError());
10835 
10836  if (cell->line(line)->child(c)->user_flag_set() &&
10838  cell->refine_flag_set(), line) ==
10840  {
10841  // tag this cell for refinement
10842  cell->clear_coarsen_flag();
10843  // if anisotropic coarsening is allowed:
10844  // extend the refine_flag in the needed
10845  // direction, else set refine_flag
10846  // (isotropic)
10847  if (triangulation.smooth_grid &
10849  allow_anisotropic_smoothing)
10850  cell->flag_for_line_refinement(line);
10851  else
10852  cell->set_refine_flag();
10853 
10854  for (unsigned int l = 0; l < cell->n_lines(); ++l)
10856  cell->refine_flag_set(), line) ==
10858  // flag a line, that will be refined
10859  cell->line(l)->set_user_flag();
10860 
10861  // note that we have changed the grid
10862  offending_line_found = true;
10863 
10864  // it may save us several loop
10865  // iterations if we flag all lines of
10866  // this cell now (and not at the outset
10867  // of the next iteration) for refinement
10868  for (unsigned int l = 0; l < cell->n_lines(); ++l)
10869  if (!cell->line(l)->has_children() &&
10871  cell->refine_flag_set(), l) !=
10873  cell->line(l)->set_user_flag();
10874 
10875  break;
10876  }
10877  }
10878 
10879  if (offending_line_found)
10880  {
10881  mesh_changed = true;
10882  break;
10883  }
10884  }
10885  }
10886 
10887 
10888  // there is another thing here: if any of the lines will
10889  // be refined, then we may not coarsen the present cell
10890  // similarly, if any of the lines *is* already refined, we
10891  // may not coarsen the current cell. however, there's a
10892  // catch: if the line is refined, but the cell behind it
10893  // is going to be coarsened, then the situation
10894  // changes. if we forget this second condition, the
10895  // refine_and_coarsen_3d test will start to fail. note
10896  // that to know which cells are going to be coarsened, the
10897  // call for fix_coarsen_flags above is necessary
10898  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
10899  triangulation.last();
10900  cell != triangulation.end();
10901  --cell)
10902  {
10903  if (cell->user_flag_set())
10904  for (unsigned int line = 0; line < cell->n_lines(); ++line)
10905  if (cell->line(line)->has_children() &&
10906  (cell->line(line)->child(0)->user_flag_set() ||
10907  cell->line(line)->child(1)->user_flag_set()))
10908  {
10909  for (unsigned int c = 0; c < cell->n_children(); ++c)
10910  cell->child(c)->clear_coarsen_flag();
10911  cell->clear_user_flag();
10912  for (unsigned int l = 0; l < cell->n_lines(); ++l)
10914  cell->refinement_case(), l) ==
10916  // flag a line, that is refined
10917  // and will stay so
10918  cell->line(l)->set_user_flag();
10919  mesh_changed = true;
10920  break;
10921  }
10922  }
10923  }
10924  while (mesh_changed == true);
10925  }
10926 
10927 
10928 
10935  template <int dim, int spacedim>
10936  static bool
10938  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
10939  {
10940  // in 1d, coarsening is always allowed since we don't enforce
10941  // the 2:1 constraint there
10942  if (dim == 1)
10943  return true;
10944 
10945  const RefinementCase<dim> ref_case = cell->refinement_case();
10946  for (unsigned int n : GeometryInfo<dim>::face_indices())
10947  {
10948  // if the cell is not refined along that face, coarsening
10949  // will not change anything, so do nothing. the same
10950  // applies, if the face is at the boandary
10951  const RefinementCase<dim - 1> face_ref_case =
10952  GeometryInfo<dim>::face_refinement_case(cell->refinement_case(),
10953  n);
10954 
10955  const unsigned int n_subfaces =
10956  GeometryInfo<dim - 1>::n_children(face_ref_case);
10957 
10958  if (n_subfaces == 0 || cell->at_boundary(n))
10959  continue;
10960  for (unsigned int c = 0; c < n_subfaces; ++c)
10961  {
10963  child = cell->child(
10964  GeometryInfo<dim>::child_cell_on_face(ref_case, n, c));
10965 
10967  child_neighbor = child->neighbor(n);
10968  if (!child->neighbor_is_coarser(n))
10969  // in 2d, if the child's neighbor is coarser, then
10970  // it has no children. however, in 3d it might be
10971  // otherwise. consider for example, that our face
10972  // might be refined with cut_x, but the neighbor is
10973  // refined with cut_xy at that face. then the
10974  // neighbor pointers of the children of our cell
10975  // will point to the common neighbor cell, not to
10976  // its children. what we really want to know in the
10977  // following is, whether the neighbor cell is
10978  // refined twice with reference to our cell. that
10979  // only has to be asked, if the child's neighbor is
10980  // not a coarser one.
10981  if ((child_neighbor->has_children() &&
10982  !child_neighbor->user_flag_set()) ||
10983  // neighbor has children, which are further
10984  // refined along the face, otherwise something
10985  // went wrong in the construction of neighbor
10986  // pointers. then only allow coarsening if this
10987  // neighbor will be coarsened as well
10988  // (user_pointer is set). the same applies, if
10989  // the neighbors children are not refined but
10990  // will be after refinement
10991  child_neighbor->refine_flag_set())
10992  return false;
10993  }
10994  }
10995  return true;
10996  }
10997  };
10998 
10999 
11004  {
11005  template <int spacedim>
11006  static void
11008  {}
11009 
11010  template <int dim, int spacedim>
11012  {
11013  std::vector<std::pair<unsigned int, unsigned int>> adjacent_cells(
11014  2 * triangulation.n_raw_faces(),
11015  {numbers::invalid_unsigned_int, numbers::invalid_unsigned_int});
11016 
11017  const auto set_entry = [&](const auto &face_index, const auto &cell) {
11018  const std::pair<unsigned int, unsigned int> cell_pair = {
11019  cell->level(), cell->index()};
11020  unsigned int index;
11021 
11022  if (adjacent_cells[2 * face_index].first ==
11024  adjacent_cells[2 * face_index].second ==
11026  {
11027  index = 2 * face_index + 0;
11028  }
11029  else
11030  {
11031  Assert(((adjacent_cells[2 * face_index + 1].first ==
11033  (adjacent_cells[2 * face_index + 1].second ==
11035  ExcNotImplemented());
11036  index = 2 * face_index + 1;
11037  }
11038 
11039  adjacent_cells[index] = cell_pair;
11040  };
11041 
11042  const auto get_entry =
11043  [&](const auto &face_index,
11044  const auto &cell) -> TriaIterator<CellAccessor<dim, spacedim>> {
11045  auto test = adjacent_cells[2 * face_index];
11046 
11047  if (test == std::pair<unsigned int, unsigned int>(cell->level(),
11048  cell->index()))
11049  test = adjacent_cells[2 * face_index + 1];
11050 
11051  if ((test.first != numbers::invalid_unsigned_int) &&
11052  (test.second != numbers::invalid_unsigned_int))
11054  test.first,
11055  test.second);
11056  else
11058  };
11059 
11060  for (const auto &cell : triangulation.cell_iterators())
11061  for (const auto &face : cell->face_iterators())
11062  {
11063  set_entry(face->index(), cell);
11064 
11065  if (cell->is_active() && face->has_children())
11066  for (unsigned int c = 0; c < face->n_children(); ++c)
11067  set_entry(face->child(c)->index(), cell);
11068  }
11069 
11070  for (const auto &cell : triangulation.cell_iterators())
11071  for (auto f : cell->face_indices())
11072  cell->set_neighbor(f, get_entry(cell->face(f)->index(), cell));
11073  }
11074 
11075  template <int dim, int spacedim>
11076  static void
11080  std::vector<unsigned int> & line_cell_count,
11081  std::vector<unsigned int> & quad_cell_count)
11082  {
11083  AssertThrow(false, ExcNotImplemented());
11084  (void)triangulation;
11085  (void)cell;
11086  (void)line_cell_count;
11087  (void)quad_cell_count;
11088  }
11089 
11090  template <int dim, int spacedim>
11093  const bool check_for_distorted_cells)
11094  {
11095  return Implementation::execute_refinement_isotropic(
11096  triangulation, check_for_distorted_cells);
11097  }
11098 
11099  template <int dim, int spacedim>
11100  static void
11103  {
11104  // nothing to do since anisotropy is not supported
11105  (void)triangulation;
11106  }
11107 
11108  template <int dim, int spacedim>
11109  static void
11112  {
11113  Implementation::prepare_refinement_dim_dependent(triangulation);
11114  }
11115 
11116  template <int dim, int spacedim>
11117  static bool
11119  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
11120  {
11121  AssertThrow(false, ExcNotImplemented());
11122  (void)cell;
11123 
11124  return false;
11125  }
11126  };
11127 
11128 
11129  template <int dim, int spacedim>
11130  const Manifold<dim, spacedim> &
11132  {
11133  static const FlatManifold<dim, spacedim> flat_manifold;
11134  return flat_manifold;
11135  }
11136  } // namespace TriangulationImplementation
11137 } // namespace internal
11138 
11139 
11140 
11141 template <int dim, int spacedim>
11142 const unsigned int Triangulation<dim, spacedim>::dimension;
11143 
11144 
11145 
11146 template <int dim, int spacedim>
11148  const MeshSmoothing smooth_grid,
11149  const bool check_for_distorted_cells)
11150  : smooth_grid(smooth_grid)
11151  , anisotropic_refinement(false)
11152  , check_for_distorted_cells(check_for_distorted_cells)
11153 {
11154  if (dim == 1)
11155  {
11156  vertex_to_boundary_id_map_1d =
11157  std::make_unique<std::map<unsigned int, types::boundary_id>>();
11158  vertex_to_manifold_id_map_1d =
11159  std::make_unique<std::map<unsigned int, types::manifold_id>>();
11160  }
11161 
11162  // connect the any_change signal to the other top level signals
11163  signals.create.connect(signals.any_change);
11164  signals.post_refinement.connect(signals.any_change);
11165  signals.clear.connect(signals.any_change);
11166  signals.mesh_movement.connect(signals.any_change);
11167 }
11168 
11169 
11170 
11171 template <int dim, int spacedim>
11174  : Subscriptor(std::move(tria))
11175  , smooth_grid(tria.smooth_grid)
11176  , reference_cells(std::move(tria.reference_cells))
11177  , periodic_face_pairs_level_0(std::move(tria.periodic_face_pairs_level_0))
11178  , periodic_face_map(std::move(tria.periodic_face_map))
11179  , levels(std::move(tria.levels))
11180  , faces(std::move(tria.faces))
11181  , vertices(std::move(tria.vertices))
11182  , vertices_used(std::move(tria.vertices_used))
11183  , manifolds(std::move(tria.manifolds))
11184  , anisotropic_refinement(tria.anisotropic_refinement)
11185  , check_for_distorted_cells(tria.check_for_distorted_cells)
11186  , number_cache(std::move(tria.number_cache))
11187  , vertex_to_boundary_id_map_1d(std::move(tria.vertex_to_boundary_id_map_1d))
11188  , vertex_to_manifold_id_map_1d(std::move(tria.vertex_to_manifold_id_map_1d))
11189 {
11191 
11192  if (tria.policy)
11193  this->policy = tria.policy->clone();
11194 }
11195 
11196 
11197 template <int dim, int spacedim>
11201 {
11202  Subscriptor::operator=(std::move(tria));
11203 
11204  smooth_grid = tria.smooth_grid;
11205  reference_cells = std::move(tria.reference_cells);
11206  periodic_face_pairs_level_0 = std::move(tria.periodic_face_pairs_level_0);
11207  periodic_face_map = std::move(tria.periodic_face_map);
11208  levels = std::move(tria.levels);
11209  faces = std::move(tria.faces);
11210  vertices = std::move(tria.vertices);
11211  vertices_used = std::move(tria.vertices_used);
11212  manifolds = std::move(tria.manifolds);
11213  anisotropic_refinement = tria.anisotropic_refinement;
11214  number_cache = tria.number_cache;
11215  vertex_to_boundary_id_map_1d = std::move(tria.vertex_to_boundary_id_map_1d);
11216  vertex_to_manifold_id_map_1d = std::move(tria.vertex_to_manifold_id_map_1d);
11217 
11219 
11220  if (tria.policy)
11221  this->policy = tria.policy->clone();
11222 
11223  return *this;
11224 }
11225 
11226 
11227 
11228 template <int dim, int spacedim>
11230 {
11231  // notify listeners that the triangulation is going down...
11232  try
11233  {
11234  signals.clear();
11235  }
11236  catch (...)
11237  {}
11238 
11239  levels.clear();
11240 
11241  // the vertex_to_boundary_id_map_1d field should be unused except in
11242  // 1d. double check this here, as destruction is a good place to
11243  // ensure that what we've done over the course of the lifetime of
11244  // this object makes sense
11245  AssertNothrow((dim == 1) || (vertex_to_boundary_id_map_1d == nullptr),
11246  ExcInternalError());
11247 
11248  // the vertex_to_manifold_id_map_1d field should be also unused
11249  // except in 1d. check this as well
11250  AssertNothrow((dim == 1) || (vertex_to_manifold_id_map_1d == nullptr),
11251  ExcInternalError());
11252 }
11253 
11254 
11255 
11256 template <int dim, int spacedim>
11257 void
11259 {
11260  // notify listeners that the triangulation is going down...
11261  signals.clear();
11262 
11263  // ...and then actually clear all content of it
11264  clear_despite_subscriptions();
11265  periodic_face_pairs_level_0.clear();
11266  periodic_face_map.clear();
11267  reference_cells.clear();
11268 }
11269 
11270 
11271 template <int dim, int spacedim>
11272 MPI_Comm
11274 {
11275  return MPI_COMM_SELF;
11276 }
11277 
11278 
11279 
11280 template <int dim, int spacedim>
11281 void
11283  const MeshSmoothing mesh_smoothing)
11284 {
11285  Assert(n_levels() == 0,
11286  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
11287  smooth_grid = mesh_smoothing;
11288 }
11289 
11290 
11291 
11292 template <int dim, int spacedim>
11295 {
11296  return smooth_grid;
11297 }
11298 
11299 
11300 
11301 template <int dim, int spacedim>
11302 void
11304  const types::manifold_id m_number,
11305  const Manifold<dim, spacedim> &manifold_object)
11306 {
11308 
11309  manifolds[m_number] = manifold_object.clone();
11310 }
11311 
11312 
11313 
11314 template <int dim, int spacedim>
11315 void
11317 {
11319 
11320  // delete the entry located at number.
11321  manifolds.erase(m_number);
11322 }
11323 
11324 
11325 template <int dim, int spacedim>
11326 void
11328 {
11329  manifolds.clear();
11330 }
11331 
11332 
11333 template <int dim, int spacedim>
11334 void
11336  const types::manifold_id m_number)
11337 {
11338  Assert(
11339  n_cells() > 0,
11340  ExcMessage(
11341  "Error: set_all_manifold_ids() can not be called on an empty Triangulation."));
11342 
11343  for (const auto &cell : this->active_cell_iterators())
11344  cell->set_all_manifold_ids(m_number);
11345 }
11346 
11347 
11348 template <int dim, int spacedim>
11349 void
11351  const types::manifold_id m_number)
11352 {
11353  Assert(
11354  n_cells() > 0,
11355  ExcMessage(
11356  "Error: set_all_manifold_ids_on_boundary() can not be called on an empty Triangulation."));
11357 
11358  for (const auto &cell : this->active_cell_iterators())
11359  for (auto f : GeometryInfo<dim>::face_indices())
11360  if (cell->face(f)->at_boundary())
11361  cell->face(f)->set_all_manifold_ids(m_number);
11362 }
11363 
11364 
11365 template <int dim, int spacedim>
11366 void
11368  const types::boundary_id b_id,
11369  const types::manifold_id m_number)
11370 {
11371  Assert(
11372  n_cells() > 0,
11373  ExcMessage(
11374  "Error: set_all_manifold_ids_on_boundary() can not be called on an empty Triangulation."));
11375 
11376  bool boundary_found = false;
11377 
11378  for (const auto &cell : this->active_cell_iterators())
11379  {
11380  // loop on faces
11381  for (auto f : GeometryInfo<dim>::face_indices())
11382  if (cell->face(f)->at_boundary() &&
11383  cell->face(f)->boundary_id() == b_id)
11384  {
11385  boundary_found = true;
11386  cell->face(f)->set_manifold_id(m_number);
11387  }
11388 
11389  // loop on edges if dim >= 3
11390  if (dim >= 3)
11391  for (unsigned int e = 0; e < GeometryInfo<dim>::lines_per_cell; ++e)
11392  if (cell->line(e)->at_boundary() &&
11393  cell->line(e)->boundary_id() == b_id)
11394  {
11395  boundary_found = true;
11396  cell->line(e)->set_manifold_id(m_number);
11397  }
11398  }
11399 
11400  (void)boundary_found;
11401  Assert(boundary_found, ExcBoundaryIdNotFound(b_id));
11402 }
11403 
11404 
11405 
11406 template <int dim, int spacedim>
11409  const types::manifold_id m_number) const
11410 {
11411  // look, if there is a manifold stored at
11412  // manifold_id number.
11413  const auto it = manifolds.find(m_number);
11414 
11415  if (it != manifolds.end())
11416  {
11417  // if we have found an entry, return it
11418  return *(it->second);
11419  }
11420 
11421  // if we have not found an entry connected with number, we return
11422  // the default (flat) manifold
11423  return internal::TriangulationImplementation::
11424  get_default_flat_manifold<dim, spacedim>();
11425 }
11426 
11427 
11428 
11429 template <int dim, int spacedim>
11430 std::vector<types::boundary_id>
11432 {
11433  // in 1d, we store a map of all used boundary indicators. use it for
11434  // our purposes
11435  if (dim == 1)
11436  {
11437  std::vector<types::boundary_id> boundary_ids;
11438  for (std::map<unsigned int, types::boundary_id>::const_iterator p =
11439  vertex_to_boundary_id_map_1d->begin();
11440  p != vertex_to_boundary_id_map_1d->end();
11441  ++p)
11442  boundary_ids.push_back(p->second);
11443 
11444  return boundary_ids;
11445  }
11446  else
11447  {
11448  std::set<types::boundary_id> b_ids;
11449  for (auto cell : active_cell_iterators())
11450  if (cell->is_locally_owned())
11451  for (const unsigned int face : cell->face_indices())
11452  if (cell->at_boundary(face))
11453  b_ids.insert(cell->face(face)->boundary_id());
11454  std::vector<types::boundary_id> boundary_ids(b_ids.begin(), b_ids.end());
11455  return boundary_ids;
11456  }
11457 }
11458 
11459 
11460 
11461 template <int dim, int spacedim>
11462 std::vector<types::manifold_id>
11464 {
11465  std::set<types::manifold_id> m_ids;
11466  for (auto cell : active_cell_iterators())
11467  if (cell->is_locally_owned())
11468  {
11469  m_ids.insert(cell->manifold_id());
11470  for (const auto &face : cell->face_iterators())
11471  m_ids.insert(face->manifold_id());
11472  if (dim == 3)
11473  for (const unsigned int l : cell->line_indices())
11474  m_ids.insert(cell->line(l)->manifold_id());
11475  }
11476  return {m_ids.begin(), m_ids.end()};
11477 }
11478 
11479 /*-----------------------------------------------------------------*/
11480 
11481 
11482 template <int dim, int spacedim>
11483 void
11485  const Triangulation<dim, spacedim> &other_tria)
11486 {
11487  Assert((vertices.size() == 0) && (levels.size() == 0) && (faces == nullptr),
11488  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
11489  Assert((other_tria.levels.size() != 0) && (other_tria.vertices.size() != 0) &&
11490  (dim == 1 || other_tria.faces != nullptr),
11491  ExcMessage(
11492  "When calling Triangulation::copy_triangulation(), "
11493  "the target triangulation must be empty but the source "
11494  "triangulation (the argument to this function) must contain "
11495  "something. Here, it seems like the source does not "
11496  "contain anything at all."));
11497 
11498 
11499  // copy normal elements
11500  vertices = other_tria.vertices;
11501  vertices_used = other_tria.vertices_used;
11502  anisotropic_refinement = other_tria.anisotropic_refinement;
11503  smooth_grid = other_tria.smooth_grid;
11504  reference_cells = other_tria.reference_cells;
11505 
11506  if (dim > 1)
11507  faces = std::make_unique<internal::TriangulationImplementation::TriaFaces>(
11508  *other_tria.faces);
11509 
11510  for (const auto &p : other_tria.manifolds)
11511  set_manifold(p.first, *p.second);
11512 
11513 
11514  levels.reserve(other_tria.levels.size());
11515  for (unsigned int level = 0; level < other_tria.levels.size(); ++level)
11516  levels.push_back(
11517  std::make_unique<internal::TriangulationImplementation::TriaLevel>(
11518  *other_tria.levels[level]));
11519 
11520  number_cache = other_tria.number_cache;
11521 
11522  if (dim == 1)
11523  {
11524  vertex_to_boundary_id_map_1d =
11525  std::make_unique<std::map<unsigned int, types::boundary_id>>(
11526  *other_tria.vertex_to_boundary_id_map_1d);
11527 
11528  vertex_to_manifold_id_map_1d =
11529  std::make_unique<std::map<unsigned int, types::manifold_id>>(
11530  *other_tria.vertex_to_manifold_id_map_1d);
11531  }
11532 
11533  if (other_tria.policy)
11534  this->policy = other_tria.policy->clone();
11535 
11536  // inform those who are listening on other_tria of the copy operation
11537  other_tria.signals.copy(*this);
11538  // also inform all listeners of the current triangulation that the
11539  // triangulation has been created
11540  signals.create();
11541 
11542  // note that we need not copy the
11543  // subscriptor!
11544 }
11545 
11546 
11547 
11548 template <int dim, int spacedim>
11549 void
11551  const std::vector<Point<spacedim>> &v,
11552  const std::vector<CellData<dim>> & cells,
11553  const SubCellData & subcelldata)
11554 {
11555  std::vector<CellData<dim>> reordered_cells(cells); // NOLINT
11556  SubCellData reordered_subcelldata(subcelldata); // NOLINT
11557 
11558  // in-place reordering of data
11559  reorder_compatibility(reordered_cells, reordered_subcelldata);
11560 
11561  // now create triangulation from
11562  // reordered data
11563  create_triangulation(v, reordered_cells, reordered_subcelldata);
11564 }
11565 
11566 
11567 template <int dim, int spacedim>
11568 void
11570 {
11571  this->update_reference_cells();
11572 
11573  if (this->all_reference_cells_are_hyper_cube())
11574  {
11575  this->policy =
11577  dim,
11578  spacedim,
11580  }
11581  else
11582  {
11583  this->policy =
11585  dim,
11586  spacedim,
11588  }
11589 }
11590 
11591 
11592 
11593 template <int dim, int spacedim>
11594 void
11596  const std::vector<Point<spacedim>> &v,
11597  const std::vector<CellData<dim>> & cells,
11598  const SubCellData & subcelldata)
11599 {
11600  Assert((vertices.size() == 0) && (levels.size() == 0) && (faces == nullptr),
11601  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
11602  // check that no forbidden arrays
11603  // are used
11604  Assert(subcelldata.check_consistency(dim), ExcInternalError());
11605 
11606  // try to create a triangulation; if this fails, we still want to
11607  // throw an exception but if we just do so we'll get into trouble
11608  // because sometimes other objects are already attached to it:
11609  try
11610  {
11612  create_triangulation(v, cells, subcelldata, *this);
11613  }
11614  catch (...)
11615  {
11616  clear_despite_subscriptions();
11617  throw;
11618  }
11619 
11620  reset_policy();
11621 
11622  // update our counts of the various elements of a triangulation, and set
11623  // active_cell_indices of all cells
11624  reset_cell_vertex_indices_cache();
11626  *this, levels.size(), number_cache);
11627  reset_active_cell_indices();
11628  reset_global_cell_indices();
11629 
11630  // now verify that there are indeed no distorted cells. as per the
11631  // documentation of this class, we first collect all distorted cells
11632  // and then throw an exception if there are any
11633  if (check_for_distorted_cells)
11634  {
11635  DistortedCellList distorted_cells = collect_distorted_coarse_cells(*this);
11636  // throw the array (and fill the various location fields) if
11637  // there are distorted cells. otherwise, just fall off the end
11638  // of the function
11639  AssertThrow(distorted_cells.distorted_cells.size() == 0, distorted_cells);
11640  }
11641 
11642 
11643  /*
11644  When the triangulation is a manifold (dim < spacedim) and made of
11645  quadrilaterals, the normal field provided from the map class depends on
11646  the order of the vertices. It may happen that this normal field is
11647  discontinuous. The following code takes care that this is not the case by
11648  setting the cell direction flag on those cell that produce the wrong
11649  orientation.
11650 
11651  To determine if 2 neighbours have the same or opposite orientation we use
11652  a table of truth. Its entries are indexes by the local indices of the
11653  common face. For example if two elements share a face, and this face is
11654  face 0 for element 0 and face 1 for element 1, then table(0,1) will tell
11655  whether the orientation are the same (true) or opposite (false).
11656 
11657  Even though there may be a combinatorial/graph theory argument to get this
11658  table in any dimension, I tested by hand all the different possible cases
11659  in 1D and 2D to generate the table.
11660 
11661  Assuming that a surface respects the standard orientation for 2d meshes,
11662  the tables of truth are symmetric and their true values are the following
11663 
11664  - 1D curves: (0,1)
11665  - 2D surface: (0,1),(0,2),(1,3),(2,3)
11666 
11667  We store this data using an n_faces x n_faces full matrix, which is
11668  actually much bigger than the minimal data required, but it makes the code
11669  more readable.
11670 
11671  */
11672  if (dim < spacedim && all_reference_cells_are_hyper_cube())
11673  {
11676  switch (dim)
11677  {
11678  case 1:
11679  {
11680  bool values[][2] = {{false, true}, {true, false}};
11681  for (const unsigned int i : GeometryInfo<dim>::face_indices())
11682  for (const unsigned int j : GeometryInfo<dim>::face_indices())
11683  correct(i, j) = (values[i][j]);
11684  break;
11685  }
11686  case 2:
11687  {
11688  bool values[][4] = {{false, true, true, false},
11689  {true, false, false, true},
11690  {true, false, false, true},
11691  {false, true, true, false}};
11692  for (const unsigned int i : GeometryInfo<dim>::face_indices())
11693  for (const unsigned int j : GeometryInfo<dim>::face_indices())
11694  correct(i, j) = (values[i][j]);
11695  break;
11696  }
11697  default:
11698  Assert(false, ExcNotImplemented());
11699  }
11700 
11701 
11702  std::list<active_cell_iterator> this_round, next_round;
11703  active_cell_iterator neighbor;
11704 
11705  this_round.push_back(begin_active());
11706  begin_active()->set_direction_flag(true);
11707  begin_active()->set_user_flag();
11708 
11709  while (this_round.size() > 0)
11710  {
11711  for (typename std::list<active_cell_iterator>::iterator cell =
11712  this_round.begin();
11713  cell != this_round.end();
11714  ++cell)
11715  {
11716  for (const unsigned int i : (*cell)->face_indices())
11717  {
11718  if (!((*cell)->face(i)->at_boundary()))
11719  {
11720  neighbor = (*cell)->neighbor(i);
11721 
11722  unsigned int cf = (*cell)->face_index(i);
11723  unsigned int j = 0;
11724  while (neighbor->face_index(j) != cf)
11725  {
11726  ++j;
11727  }
11728 
11729 
11730  // If we already saw this guy, check that everything is
11731  // fine
11732  if (neighbor->user_flag_set())
11733  {
11734  // If we have visited this guy, then the ordering and
11735  // the orientation should agree
11736  Assert(!(correct(i, j) ^
11737  (neighbor->direction_flag() ==
11738  (*cell)->direction_flag())),
11739  ExcNonOrientableTriangulation());
11740  }
11741  else
11742  {
11743  next_round.push_back(neighbor);
11744  neighbor->set_user_flag();
11745  if ((correct(i, j) ^ (neighbor->direction_flag() ==
11746  (*cell)->direction_flag())))
11747  neighbor->set_direction_flag(
11748  !neighbor->direction_flag());
11749  }
11750  }
11751  }
11752  }
11753 
11754  // Before we quit let's check
11755  // that if the triangulation
11756  // is disconnected that we
11757  // still get all cells
11758  if (next_round.size() == 0)
11759  for (const auto &cell : this->active_cell_iterators())
11760  if (cell->user_flag_set() == false)
11761  {
11762  next_round.push_back(cell);
11763  cell->set_direction_flag(true);
11764  cell->set_user_flag();
11765  break;
11766  }
11767 
11768  this_round = next_round;
11769  next_round.clear();
11770  }
11771  }
11772 
11773  // inform all listeners that the triangulation has been created
11774  signals.create();
11775 }
11776 
11777 
11778 
11779 template <int dim, int spacedim>
11780 void
11783 {
11784  // 1) create coarse grid
11785  create_triangulation(construction_data.coarse_cell_vertices,
11786  construction_data.coarse_cells,
11787  SubCellData());
11788 
11789  // create a copy of cell_infos such that we can sort them
11790  auto cell_infos = construction_data.cell_infos;
11791 
11792  // sort cell_infos on each level separately
11793  for (auto &cell_info : cell_infos)
11794  std::sort(
11795  cell_info.begin(),
11796  cell_info.end(),
11799  const CellId a_id(a.id);
11800  const CellId b_id(b.id);
11801 
11802  const auto a_coarse_cell_index =
11803  this->coarse_cell_id_to_coarse_cell_index(a_id.get_coarse_cell_id());
11804  const auto b_coarse_cell_index =
11805  this->coarse_cell_id_to_coarse_cell_index(b_id.get_coarse_cell_id());
11806 
11807  // according to their coarse-cell index and if that is
11808  // same according to their cell id (the result is that
11809  // cells on each level are sorted according to their
11810  // index on that level - what we need in the following
11811  // operations)
11812  if (a_coarse_cell_index != b_coarse_cell_index)
11813  return a_coarse_cell_index < b_coarse_cell_index;
11814  else
11815  return a_id < b_id;
11816  });
11817 
11818  // 2) create all levels via a sequence of refinements. note that
11819  // we must make sure that we actually have cells on this level,
11820  // which is not clear in a parallel context for some processes
11821  for (unsigned int level = 0;
11822  level < cell_infos.size() && !cell_infos[level].empty();
11823  ++level)
11824  {
11825  // a) set manifold ids here (because new vertices have to be
11826  // positioned correctly during each refinement step)
11827  {
11828  auto cell = this->begin(level);
11829  auto cell_info = cell_infos[level].begin();
11830  for (; cell_info != cell_infos[level].end(); ++cell_info)
11831  {
11832  while (cell_info->id != cell->id().template to_binary<dim>())
11833  ++cell;
11834  if (dim == 3)
11835  for (const auto quad : cell->face_indices())
11836  cell->quad(quad)->set_manifold_id(
11837  cell_info->manifold_quad_ids[quad]);
11838 
11839  if (dim >= 2)
11840  for (const auto line : cell->line_indices())
11841  cell->line(line)->set_manifold_id(
11842  cell_info->manifold_line_ids[line]);
11843 
11844  cell->set_manifold_id(cell_info->manifold_id);
11845  }
11846  }
11847 
11848  // b) perform refinement on all levels but on the finest
11849  if (level + 1 != cell_infos.size())
11850  {
11851  // find cells that should have children and mark them for
11852  // refinement
11853  auto coarse_cell = this->begin(level);
11854  auto fine_cell_info = cell_infos[level + 1].begin();
11855 
11856  // loop over all cells on the next level
11857  for (; fine_cell_info != cell_infos[level + 1].end();
11858  ++fine_cell_info)
11859  {
11860  // find the parent of that cell
11861  while (
11862  !coarse_cell->id().is_parent_of(CellId(fine_cell_info->id)))
11863  ++coarse_cell;
11864 
11865  // set parent for refinement
11866  coarse_cell->set_refine_flag();
11867  }
11868 
11869  // execute refinement
11870  ::Triangulation<dim,
11871  spacedim>::execute_coarsening_and_refinement();
11872  }
11873  }
11874 
11875  // 3) set boundary ids
11876  for (unsigned int level = 0;
11877  level < cell_infos.size() && !cell_infos[level].empty();
11878  ++level)
11879  {
11880  auto cell = this->begin(level);
11881  auto cell_info = cell_infos[level].begin();
11882  for (; cell_info != cell_infos[level].end(); ++cell_info)
11883  {
11884  // find cell that has the correct cell
11885  while (cell_info->id != cell->id().template to_binary<dim>())
11886  ++cell;
11887 
11888  // boundary ids
11889  for (auto pair : cell_info->boundary_ids)
11890  if (cell->face(pair.first)->at_boundary())
11891  cell->face(pair.first)->set_boundary_id(pair.second);
11892  }
11893  }
11894 }
11895 
11896 
11897 template <int dim, int spacedim>
11898 void
11900 {
11901  AssertThrow(dim + 1 == spacedim,
11902  ExcMessage("Only works for dim == spacedim-1"));
11903  for (const auto &cell : this->active_cell_iterators())
11904  cell->set_direction_flag(!cell->direction_flag());
11905 }
11906 
11907 
11908 
11909 template <int dim, int spacedim>
11910 void
11912 {
11913  Assert(n_cells() > 0,
11914  ExcMessage("Error: An empty Triangulation can not be refined."));
11915 
11916  for (const auto &cell : this->active_cell_iterators())
11917  {
11918  cell->clear_coarsen_flag();
11919  cell->set_refine_flag();
11920  }
11921 }
11922 
11923 
11924 
11925 template <int dim, int spacedim>
11926 void
11927 Triangulation<dim, spacedim>::refine_global(const unsigned int times)
11928 {
11929  for (unsigned int i = 0; i < times; ++i)
11930  {
11931  set_all_refine_flags();
11932  execute_coarsening_and_refinement();
11933  }
11934 }
11935 
11936 
11937 
11938 template <int dim, int spacedim>
11939 void
11940 Triangulation<dim, spacedim>::coarsen_global(const unsigned int times)
11941 {
11942  for (unsigned int i = 0; i < times; ++i)
11943  {
11944  for (const auto &cell : this->active_cell_iterators())
11945  {
11946  cell->clear_refine_flag();
11947  cell->set_coarsen_flag();
11948  }
11949  execute_coarsening_and_refinement();
11950  }
11951 }
11952 
11953 
11954 /*-------------------- refine/coarsen flags -------------------------*/
11955 
11956 
11957 
11958 template <int dim, int spacedim>
11959 void
11960 Triangulation<dim, spacedim>::save_refine_flags(std::vector<bool> &v) const
11961 {
11962  v.resize(dim * n_active_cells(), false);
11963  std::vector<bool>::iterator i = v.begin();
11964 
11965  for (const auto &cell : this->active_cell_iterators())
11966  for (unsigned int j = 0; j < dim; ++j, ++i)
11967  if (cell->refine_flag_set() & (1 << j))
11968  *i = true;
11969 
11970  Assert(i == v.end(), ExcInternalError());
11971 }
11972 
11973 
11974 
11975 template <int dim, int spacedim>
11976 void
11977 Triangulation<dim, spacedim>::save_refine_flags(std::ostream &out) const
11978 {
11979  std::vector<bool> v;
11980  save_refine_flags(v);
11981  write_bool_vector(mn_tria_refine_flags_begin,
11982  v,
11984  out);
11985 }
11986 
11987 
11988 
11989 template <int dim, int spacedim>
11990 void
11992 {
11993  std::vector<bool> v;
11994  read_bool_vector(mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end, in);
11995  load_refine_flags(v);
11996 }
11997 
11998 
11999 
12000 template <int dim, int spacedim>
12001 void
12002 Triangulation<dim, spacedim>::load_refine_flags(const std::vector<bool> &v)
12003 {
12004  AssertThrow(v.size() == dim * n_active_cells(), ExcGridReadError());
12005 
12006  std::vector<bool>::const_iterator i = v.begin();
12007  for (const auto &cell : this->active_cell_iterators())
12008  {
12009  unsigned int ref_case = 0;
12010 
12011  for (unsigned int j = 0; j < dim; ++j, ++i)
12012  if (*i == true)
12013  ref_case += 1 << j;
12015  ExcGridReadError());
12016  if (ref_case > 0)
12017  cell->set_refine_flag(RefinementCase<dim>(ref_case));
12018  else
12019  cell->clear_refine_flag();
12020  }
12021 
12022  Assert(i == v.end(), ExcInternalError());
12023 }
12024 
12025 
12026 
12027 template <int dim, int spacedim>
12028 void
12029 Triangulation<dim, spacedim>::save_coarsen_flags(std::vector<bool> &v) const
12030 {
12031  v.resize(n_active_cells(), false);
12032  std::vector<bool>::iterator i = v.begin();
12033  for (const auto &cell : this->active_cell_iterators())
12034  {
12035  *i = cell->coarsen_flag_set();
12036  ++i;
12037  }
12038 
12039  Assert(i == v.end(), ExcInternalError());
12040 }
12041 
12042 
12043 
12044 template <int dim, int spacedim>
12045 void
12046 Triangulation<dim, spacedim>::save_coarsen_flags(std::ostream &out) const
12047 {
12048  std::vector<bool> v;
12049  save_coarsen_flags(v);
12050  write_bool_vector(mn_tria_coarsen_flags_begin,
12051  v,
12053  out);
12054 }
12055 
12056 
12057 
12058 template <int dim, int spacedim>
12059 void
12061 {
12062  std::vector<bool> v;
12063  read_bool_vector(mn_tria_coarsen_flags_begin,
12064  v,
12066  in);
12067  load_coarsen_flags(v);
12068 }
12069 
12070 
12071 
12072 template <int dim, int spacedim>
12073 void
12074 Triangulation<dim, spacedim>::load_coarsen_flags(const std::vector<bool> &v)
12075 {
12076  Assert(v.size() == n_active_cells(), ExcGridReadError());
12077 
12078  std::vector<bool>::const_iterator i = v.begin();
12079  for (const auto &cell : this->active_cell_iterators())
12080  {
12081  if (*i == true)
12082  cell->set_coarsen_flag();
12083  else
12084  cell->clear_coarsen_flag();
12085  ++i;
12086  }
12087 
12088  Assert(i == v.end(), ExcInternalError());
12089 }
12090 
12091 
12092 template <int dim, int spacedim>
12093 bool
12095 {
12096  return anisotropic_refinement;
12097 }
12098 
12099 
12100 
12101 /*-------------------- user data/flags -------------------------*/
12102 
12103 
12104 namespace
12105 {
12106  // clear user data of cells
12107  void
12108  clear_user_data(std::vector<std::unique_ptr<
12110  {
12111  for (auto &level : levels)
12112  level->cells.clear_user_data();
12113  }
12114 
12115 
12116  // clear user data of faces
12117  void
12118  clear_user_data(internal::TriangulationImplementation::TriaFaces *faces)
12119  {
12120  if (faces->dim == 2)
12121  {
12122  faces->lines.clear_user_data();
12123  }
12124 
12125 
12126  if (faces->dim == 3)
12127  {
12128  faces->lines.clear_user_data();
12129  faces->quads.clear_user_data();
12130  }
12131  }
12132 } // namespace
12133 
12134 
12135 template <int dim, int spacedim>
12136 void
12138 {
12139  // let functions in anonymous namespace do their work
12140  ::clear_user_data(levels);
12141  if (dim > 1)
12142  ::clear_user_data(faces.get());
12143 }
12144 
12145 
12146 
12147 namespace
12148 {
12149  void
12150  clear_user_flags_line(
12151  unsigned int dim,
12152  std::vector<
12153  std::unique_ptr<internal::TriangulationImplementation::TriaLevel>>
12154  & levels,
12156  {
12157  if (dim == 1)
12158  {
12159  for (const auto &level : levels)
12160  level->cells.clear_user_flags();
12161  }
12162  else if (dim == 2 || dim == 3)
12163  {
12164  faces->lines.clear_user_flags();
12165  }
12166  else
12167  {
12168  Assert(false, ExcNotImplemented())
12169  }
12170  }
12171 } // namespace
12172 
12173 
12174 template <int dim, int spacedim>
12175 void
12177 {
12178  ::clear_user_flags_line(dim, levels, faces.get());
12179 }
12180 
12181 
12182 
12183 namespace
12184 {
12185  void
12186  clear_user_flags_quad(
12187  unsigned int dim,
12188  std::vector<
12189  std::unique_ptr<internal::TriangulationImplementation::TriaLevel>>
12190  & levels,
12192  {
12193  if (dim == 1)
12194  {
12195  // nothing to do in 1d
12196  }
12197  else if (dim == 2)
12198  {
12199  for (const auto &level : levels)
12200  level->cells.clear_user_flags();
12201  }
12202  else if (dim == 3)
12203  {
12204  faces->quads.clear_user_flags();
12205  }
12206  else
12207  {
12208  Assert(false, ExcNotImplemented())
12209  }
12210  }
12211 } // namespace
12212 
12213 
12214 template <int dim, int spacedim>
12215 void
12217 {
12218  ::clear_user_flags_quad(dim, levels, faces.get());
12219 }
12220 
12221 
12222 
12223 namespace
12224 {
12225  void
12226  clear_user_flags_hex(
12227  unsigned int dim,
12228  std::vector<
12229  std::unique_ptr<internal::TriangulationImplementation::TriaLevel>>
12230  &levels,
12232  {
12233  if (dim == 1)
12234  {
12235  // nothing to do in 1d
12236  }
12237  else if (dim == 2)
12238  {
12239  // nothing to do in 2d
12240  }
12241  else if (dim == 3)
12242  {
12243  for (const auto &level : levels)
12244  level->cells.clear_user_flags();
12245  }
12246  else
12247  {
12248  Assert(false, ExcNotImplemented())
12249  }
12250  }
12251 } // namespace
12252 
12253 
12254 template <int dim, int spacedim>
12255 void
12257 {
12258  ::clear_user_flags_hex(dim, levels, faces.get());
12259 }
12260 
12261 
12262 
12263 template <int dim, int spacedim>
12264 void
12266 {
12267  clear_user_flags_line();
12268  clear_user_flags_quad();
12269  clear_user_flags_hex();
12270 }
12271 
12272 
12273 
12274 template <int dim, int spacedim>
12275 void
12276 Triangulation<dim, spacedim>::save_user_flags(std::ostream &out) const
12277 {
12278  save_user_flags_line(out);
12279 
12280  if (dim >= 2)
12281  save_user_flags_quad(out);
12282 
12283  if (dim >= 3)
12284  save_user_flags_hex(out);
12285 
12286  if (dim >= 4)
12287  Assert(false, ExcNotImplemented());
12288 }
12289 
12290 
12291 
12292 template <int dim, int spacedim>
12293 void
12294 Triangulation<dim, spacedim>::save_user_flags(std::vector<bool> &v) const
12295 {
12296  // clear vector and append
12297  // all the stuff later on
12298  v.clear();
12299 
12300  std::vector<bool> tmp;
12301 
12302  save_user_flags_line(tmp);
12303  v.insert(v.end(), tmp.begin(), tmp.end());
12304 
12305  if (dim >= 2)
12306  {
12307  save_user_flags_quad(tmp);
12308  v.insert(v.end(), tmp.begin(), tmp.end());
12309  }
12310 
12311  if (dim >= 3)
12312  {
12313  save_user_flags_hex(tmp);
12314  v.insert(v.end(), tmp.begin(), tmp.end());
12315  }
12316 
12317  if (dim >= 4)
12318  Assert(false, ExcNotImplemented());
12319 }
12320 
12321 
12322 
12323 template <int dim, int spacedim>
12324 void
12326 {
12327  load_user_flags_line(in);
12328 
12329  if (dim >= 2)
12330  load_user_flags_quad(in);
12331 
12332  if (dim >= 3)
12333  load_user_flags_hex(in);
12334 
12335  if (dim >= 4)
12336  Assert(false, ExcNotImplemented());
12337 }
12338 
12339 
12340 
12341 template <int dim, int spacedim>
12342 void
12343 Triangulation<dim, spacedim>::load_user_flags(const std::vector<bool> &v)
12344 {
12345  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
12346  std::vector<bool> tmp;
12347 
12348  // first extract the flags
12349  // belonging to lines
12350  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
12351  // and set the lines
12352  load_user_flags_line(tmp);
12353 
12354  if (dim >= 2)
12355  {
12356  tmp.clear();
12357  tmp.insert(tmp.end(),
12358  v.begin() + n_lines(),
12359  v.begin() + n_lines() + n_quads());
12360  load_user_flags_quad(tmp);
12361  }
12362 
12363  if (dim >= 3)
12364  {
12365  tmp.clear();
12366  tmp.insert(tmp.end(),
12367  v.begin() + n_lines() + n_quads(),
12368  v.begin() + n_lines() + n_quads() + n_hexs());
12369  load_user_flags_hex(tmp);
12370  }
12371 
12372  if (dim >= 4)
12373  Assert(false, ExcNotImplemented());
12374 }
12375 
12376 
12377 
12378 template <int dim, int spacedim>
12379 void
12380 Triangulation<dim, spacedim>::save_user_flags_line(std::vector<bool> &v) const
12381 {
12382  v.resize(n_lines(), false);
12383  std::vector<bool>::iterator i = v.begin();
12384  line_iterator line = begin_line(), endl = end_line();
12385  for (; line != endl; ++line, ++i)
12386  *i = line->user_flag_set();
12387 
12388  Assert(i == v.end(), ExcInternalError());
12389 }
12390 
12391 
12392 
12393 template <int dim, int spacedim>
12394 void
12396 {
12397  std::vector<bool> v;
12398  save_user_flags_line(v);
12399  write_bool_vector(mn_tria_line_user_flags_begin,
12400  v,
12402  out);
12403 }
12404 
12405 
12406 
12407 template <int dim, int spacedim>
12408 void
12410 {
12411  std::vector<bool> v;
12412  read_bool_vector(mn_tria_line_user_flags_begin,
12413  v,
12415  in);
12416  load_user_flags_line(v);
12417 }
12418 
12419 
12420 
12421 template <int dim, int spacedim>
12422 void
12423 Triangulation<dim, spacedim>::load_user_flags_line(const std::vector<bool> &v)
12424 {
12425  Assert(v.size() == n_lines(), ExcGridReadError());
12426 
12427  line_iterator line = begin_line(), endl = end_line();
12428  std::vector<bool>::const_iterator i = v.begin();
12429  for (; line != endl; ++line, ++i)
12430  if (*i == true)
12431  line->set_user_flag();
12432  else
12433  line->clear_user_flag();
12434 
12435  Assert(i == v.end(), ExcInternalError());
12436 }
12437 
12438 
12439 namespace
12440 {
12441  template <typename Iterator>
12442  bool
12443  get_user_flag(const Iterator &i)
12444  {
12445  return i->user_flag_set();
12446  }
12447 
12448 
12449 
12450  template <int structdim, int dim, int spacedim>
12451  bool
12453  {
12454  Assert(false, ExcInternalError());
12455  return false;
12456  }
12457 
12458 
12459 
12460  template <typename Iterator>
12461  void
12462  set_user_flag(const Iterator &i)
12463  {
12464  i->set_user_flag();
12465  }
12466 
12467 
12468 
12469  template <int structdim, int dim, int spacedim>
12470  void
12472  {
12473  Assert(false, ExcInternalError());
12474  }
12475 
12476 
12477 
12478  template <typename Iterator>
12479  void
12480  clear_user_flag(const Iterator &i)
12481  {
12482  i->clear_user_flag();
12483  }
12484 
12485 
12486 
12487  template <int structdim, int dim, int spacedim>
12488  void
12489  clear_user_flag(
12491  {
12492  Assert(false, ExcInternalError());
12493  }
12494 } // namespace
12495 
12496 
12497 template <int dim, int spacedim>
12498 void
12499 Triangulation<dim, spacedim>::save_user_flags_quad(std::vector<bool> &v) const
12500 {
12501  v.resize(n_quads(), false);
12502 
12503  if (dim >= 2)
12504  {
12505  std::vector<bool>::iterator i = v.begin();
12506  quad_iterator quad = begin_quad(), endq = end_quad();
12507  for (; quad != endq; ++quad, ++i)
12508  *i = get_user_flag(quad);
12509 
12510  Assert(i == v.end(), ExcInternalError());
12511  }
12512 }
12513 
12514 
12515 
12516 template <int dim, int spacedim>
12517 void
12519 {
12520  std::vector<bool> v;
12521  save_user_flags_quad(v);
12522  write_bool_vector(mn_tria_quad_user_flags_begin,
12523  v,
12525  out);
12526 }
12527 
12528 
12529 
12530 template <int dim, int spacedim>
12531 void
12533 {
12534  std::vector<bool> v;
12535  read_bool_vector(mn_tria_quad_user_flags_begin,
12536  v,
12538  in);
12539  load_user_flags_quad(v);
12540 }
12541 
12542 
12543 
12544 template <int dim, int spacedim>
12545 void
12546 Triangulation<dim, spacedim>::load_user_flags_quad(const std::vector<bool> &v)
12547 {
12548  Assert(v.size() == n_quads(), ExcGridReadError());
12549 
12550  if (dim >= 2)
12551  {
12552  quad_iterator quad = begin_quad(), endq = end_quad();
12553  std::vector<bool>::const_iterator i = v.begin();
12554  for (; quad != endq; ++quad, ++i)
12555  if (*i == true)
12556  set_user_flag(quad);
12557  else
12558  clear_user_flag(quad);
12559 
12560  Assert(i == v.end(), ExcInternalError());
12561  }
12562 }
12563 
12564 
12565 
12566 template <int dim, int spacedim>
12567 void
12568 Triangulation<dim, spacedim>::save_user_flags_hex(std::vector<bool> &v) const
12569 {
12570  v.resize(n_hexs(), false);
12571 
12572  if (dim >= 3)
12573  {
12574  std::vector<bool>::iterator i = v.begin();
12575  hex_iterator hex = begin_hex(), endh = end_hex();
12576  for (; hex != endh; ++hex, ++i)
12577  *i = get_user_flag(hex);
12578 
12579  Assert(i == v.end(), ExcInternalError());
12580  }
12581 }
12582 
12583 
12584 
12585 template <int dim, int spacedim>
12586 void
12588 {
12589  std::vector<bool> v;
12590  save_user_flags_hex(v);
12591  write_bool_vector(mn_tria_hex_user_flags_begin,
12592  v,
12594  out);
12595 }
12596 
12597 
12598 
12599 template <int dim, int spacedim>
12600 void
12602 {
12603  std::vector<bool> v;
12604  read_bool_vector(mn_tria_hex_user_flags_begin,
12605  v,
12607  in);
12608  load_user_flags_hex(v);
12609 }
12610 
12611 
12612 
12613 template <int dim, int spacedim>
12614 void
12615 Triangulation<dim, spacedim>::load_user_flags_hex(const std::vector<bool> &v)
12616 {
12617  Assert(v.size() == n_hexs(), ExcGridReadError());
12618 
12619  if (dim >= 3)
12620  {
12621  hex_iterator hex = begin_hex(), endh = end_hex();
12622  std::vector<bool>::const_iterator i = v.begin();
12623  for (; hex != endh; ++hex, ++i)
12624  if (*i == true)
12625  set_user_flag(hex);
12626  else
12627  clear_user_flag(hex);
12628 
12629  Assert(i == v.end(), ExcInternalError());
12630  }
12631 }
12632 
12633 
12634 
12635 template <int dim, int spacedim>
12636 void
12638  std::vector<unsigned int> &v) const
12639 {
12640  // clear vector and append all the
12641  // stuff later on
12642  v.clear();
12643 
12644  std::vector<unsigned int> tmp;
12645 
12646  save_user_indices_line(tmp);
12647  v.insert(v.end(), tmp.begin(), tmp.end());
12648 
12649  if (dim >= 2)
12650  {
12651  save_user_indices_quad(tmp);
12652  v.insert(v.end(), tmp.begin(), tmp.end());
12653  }
12654 
12655  if (dim >= 3)
12656  {
12657  save_user_indices_hex(tmp);
12658  v.insert(v.end(), tmp.begin(), tmp.end());
12659  }
12660 
12661  if (dim >= 4)
12662  Assert(false, ExcNotImplemented());
12663 }
12664 
12665 
12666 
12667 template <int dim, int spacedim>
12668 void
12670  const std::vector<unsigned int> &v)
12671 {
12672  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
12673  std::vector<unsigned int> tmp;
12674 
12675  // first extract the indices
12676  // belonging to lines
12677  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
12678  // and set the lines
12679  load_user_indices_line(tmp);
12680 
12681  if (dim >= 2)
12682  {
12683  tmp.clear();
12684  tmp.insert(tmp.end(),
12685  v.begin() + n_lines(),
12686  v.begin() + n_lines() + n_quads());
12687  load_user_indices_quad(tmp);
12688  }
12689 
12690  if (dim >= 3)
12691  {
12692  tmp.clear();
12693  tmp.insert(tmp.end(),
12694  v.begin() + n_lines() + n_quads(),
12695  v.begin() + n_lines() + n_quads() + n_hexs());
12696  load_user_indices_hex(tmp);
12697  }
12698 
12699  if (dim >= 4)
12700  Assert(false, ExcNotImplemented());
12701 }
12702 
12703 
12704 
12705 namespace
12706 {
12707  template <typename Iterator>
12708  unsigned int
12709  get_user_index(const Iterator &i)
12710  {
12711  return i->user_index();
12712  }
12713 
12714 
12715 
12716  template <int structdim, int dim, int spacedim>
12717  unsigned int
12718  get_user_index(
12720  {
12721  Assert(false, ExcInternalError());
12723  }
12724 
12725 
12726 
12727  template <typename Iterator>
12728  void
12729  set_user_index(const Iterator &i, const unsigned int x)
12730  {
12731  i->set_user_index(x);
12732  }
12733 
12734 
12735 
12736  template <int structdim, int dim, int spacedim>
12737  void
12738  set_user_index(
12740  const unsigned int)
12741  {
12742  Assert(false, ExcInternalError());
12743  }
12744 } // namespace
12745 
12746 
12747 template <int dim, int spacedim>
12748 void
12750  std::vector<unsigned int> &v) const
12751 {
12752  v.resize(n_lines(), 0);
12753  std::vector<unsigned int>::iterator i = v.begin();
12754  line_iterator line = begin_line(), endl = end_line();
12755  for (; line != endl; ++line, ++i)
12756  *i = line->user_index();
12757 }
12758 
12759 
12760 
12761 template <int dim, int spacedim>
12762 void
12764  const std::vector<unsigned int> &v)
12765 {
12766  Assert(v.size() == n_lines(), ExcGridReadError());
12767 
12768  line_iterator line = begin_line(), endl = end_line();
12769  std::vector<unsigned int>::const_iterator i = v.begin();
12770  for (; line != endl; ++line, ++i)
12771  line->set_user_index(*i);
12772 }
12773 
12774 
12775 template <int dim, int spacedim>
12776 void
12778  std::vector<unsigned int> &v) const
12779 {
12780  v.resize(n_quads(), 0);
12781 
12782  if (dim >= 2)
12783  {
12784  std::vector<unsigned int>::iterator i = v.begin();
12785  quad_iterator quad = begin_quad(), endq = end_quad();
12786  for (; quad != endq; ++quad, ++i)
12787  *i = get_user_index(quad);
12788  }
12789 }
12790 
12791 
12792 
12793 template <int dim, int spacedim>
12794 void
12796  const std::vector<unsigned int> &v)
12797 {
12798  Assert(v.size() == n_quads(), ExcGridReadError());
12799 
12800  if (dim >= 2)
12801  {
12802  quad_iterator quad = begin_quad(), endq = end_quad();
12803  std::vector<unsigned int>::const_iterator i = v.begin();
12804  for (; quad != endq; ++quad, ++i)
12805  set_user_index(quad, *i);
12806  }
12807 }
12808 
12809 
12810 template <int dim, int spacedim>
12811 void
12813  std::vector<unsigned int> &v) const
12814 {
12815  v.resize(n_hexs(), 0);
12816 
12817  if (dim >= 3)
12818  {
12819  std::vector<unsigned int>::iterator i = v.begin();
12820  hex_iterator hex = begin_hex(), endh = end_hex();
12821  for (; hex != endh; ++hex, ++i)
12822  *i = get_user_index(hex);
12823  }
12824 }
12825 
12826 
12827 
12828 template <int dim, int spacedim>
12829 void
12831  const std::vector<unsigned int> &v)
12832 {
12833  Assert(v.size() == n_hexs(), ExcGridReadError());
12834 
12835  if (dim >= 3)
12836  {
12837  hex_iterator hex = begin_hex(), endh = end_hex();
12838  std::vector<unsigned int>::const_iterator i = v.begin();
12839  for (; hex != endh; ++hex, ++i)
12840  set_user_index(hex, *i);
12841  }
12842 }
12843 
12844 
12845 
12846 //---------------- user pointers ----------------------------------------//
12847 
12848 
12849 namespace
12850 {
12851  template <typename Iterator>
12852  void *
12853  get_user_pointer(const Iterator &i)
12854  {
12855  return i->user_pointer();
12856  }
12857 
12858 
12859 
12860  template <int structdim, int dim, int spacedim>
12861  void *
12862  get_user_pointer(
12864  {
12865  Assert(false, ExcInternalError());
12866  return nullptr;
12867  }
12868 
12869 
12870 
12871  template <typename Iterator>
12872  void
12873  set_user_pointer(const Iterator &i, void *x)
12874  {
12875  i->set_user_pointer(x);
12876  }
12877 
12878 
12879 
12880  template <int structdim, int dim, int spacedim>
12881  void
12882  set_user_pointer(
12884  void *)
12885  {
12886  Assert(false, ExcInternalError());
12887  }
12888 } // namespace
12889 
12890 
12891 template <int dim, int spacedim>
12892 void
12893 Triangulation<dim, spacedim>::save_user_pointers(std::vector<void *> &v) const
12894 {
12895  // clear vector and append all the
12896  // stuff later on
12897  v.clear();
12898 
12899  std::vector<void *> tmp;
12900 
12901  save_user_pointers_line(tmp);
12902  v.insert(v.end(), tmp.begin(), tmp.end());
12903 
12904  if (dim >= 2)
12905  {
12906  save_user_pointers_quad(tmp);
12907  v.insert(v.end(), tmp.begin(), tmp.end());
12908  }
12909 
12910  if (dim >= 3)
12911  {
12912  save_user_pointers_hex(tmp);
12913  v.insert(v.end(), tmp.begin(), tmp.end());
12914  }
12915 
12916  if (dim >= 4)
12917  Assert(false, ExcNotImplemented());
12918 }
12919 
12920 
12921 
12922 template <int dim, int spacedim>
12923 void
12924 Triangulation<dim, spacedim>::load_user_pointers(const std::vector<void *> &v)
12925 {
12926  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
12927  std::vector<void *> tmp;
12928 
12929  // first extract the pointers
12930  // belonging to lines
12931  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
12932  // and set the lines
12933  load_user_pointers_line(tmp);
12934 
12935  if (dim >= 2)
12936  {
12937  tmp.clear();
12938  tmp.insert(tmp.end(),
12939  v.begin() + n_lines(),
12940  v.begin() + n_lines() + n_quads());
12941  load_user_pointers_quad(tmp);
12942  }
12943 
12944  if (dim >= 3)
12945  {
12946  tmp.clear();
12947  tmp.insert(tmp.end(),
12948  v.begin() + n_lines() + n_quads(),
12949  v.begin() + n_lines() + n_quads() + n_hexs());
12950  load_user_pointers_hex(tmp);
12951  }
12952 
12953  if (dim >= 4)
12954  Assert(false, ExcNotImplemented());
12955 }
12956 
12957 
12958 
12959 template <int dim, int spacedim>
12960 void
12962  std::vector<void *> &v) const
12963 {
12964  v.resize(n_lines(), nullptr);
12965  std::vector<void *>::iterator i = v.begin();
12966  line_iterator line = begin_line(), endl = end_line();
12967  for (; line != endl; ++line, ++i)
12968  *i = line->user_pointer();
12969 }
12970 
12971 
12972 
12973 template <int dim, int spacedim>
12974 void
12976  const std::vector<void *> &v)
12977 {
12978  Assert(v.size() == n_lines(), ExcGridReadError());
12979 
12980  line_iterator line = begin_line(), endl = end_line();
12981  std::vector<void *>::const_iterator i = v.begin();
12982  for (; line != endl; ++line, ++i)
12983  line->set_user_pointer(*i);
12984 }
12985 
12986 
12987 
12988 template <int dim, int spacedim>
12989 void
12991  std::vector<void *> &v) const
12992 {
12993  v.resize(n_quads(), nullptr);
12994 
12995  if (dim >= 2)
12996  {
12997  std::vector<void *>::iterator i = v.begin();
12998  quad_iterator quad = begin_quad(), endq = end_quad();
12999  for (; quad != endq; ++quad, ++i)
13000  *i = get_user_pointer(quad);
13001  }
13002 }
13003 
13004 
13005 
13006 template <int dim, int spacedim>
13007 void
13009  const std::vector<void *> &v)
13010 {
13011  Assert(v.size() == n_quads(), ExcGridReadError());
13012 
13013  if (dim >= 2)
13014  {
13015  quad_iterator quad = begin_quad(), endq = end_quad();
13016  std::vector<void *>::const_iterator i = v.begin();
13017  for (; quad != endq; ++quad, ++i)
13018  set_user_pointer(quad, *i);
13019  }
13020 }
13021 
13022 
13023 template <int dim, int spacedim>
13024 void
13026  std::vector<void *> &v) const
13027 {
13028  v.resize(n_hexs(), nullptr);
13029 
13030  if (dim >= 3)
13031  {
13032  std::vector<void *>::iterator i = v.begin();
13033  hex_iterator hex = begin_hex(), endh = end_hex();
13034  for (; hex != endh; ++hex, ++i)
13035  *i = get_user_pointer(hex);
13036  }
13037 }
13038 
13039 
13040 
13041 template <int dim, int spacedim>
13042 void
13044  const std::vector<void *> &v)
13045 {
13046  Assert(v.size() == n_hexs(), ExcGridReadError());
13047 
13048  if (dim >= 3)
13049  {
13050  hex_iterator hex = begin_hex(), endh = end_hex();
13051  std::vector<void *>::const_iterator i = v.begin();
13052  for (; hex != endh; ++hex, ++i)
13053  set_user_pointer(hex, *i);
13054  }
13055 }
13056 
13057 
13058 
13059 /*------------------------ Cell iterator functions ------------------------*/
13060 
13061 
13062 template <int dim, int spacedim>
13064 Triangulation<dim, spacedim>::begin_raw(const unsigned int level) const
13065 {
13066  switch (dim)
13067  {
13068  case 1:
13069  return begin_raw_line(level);
13070  case 2:
13071  return begin_raw_quad(level);
13072  case 3:
13073  return begin_raw_hex(level);
13074  default:
13075  Assert(false, ExcNotImplemented());
13076  return raw_cell_iterator();
13077  }
13078 }
13079 
13080 
13081 
13082 template <int dim, int spacedim>
13084 Triangulation<dim, spacedim>::begin(const unsigned int level) const
13085 {
13086  switch (dim)
13087  {
13088  case 1:
13089  return begin_line(level);
13090  case 2:
13091  return begin_quad(level);
13092  case 3:
13093  return begin_hex(level);
13094  default:
13095  Assert(false, ExcImpossibleInDim(dim));
13096  return cell_iterator();
13097  }
13098 }
13099 
13100 
13101 
13102 template <int dim, int spacedim>
13104 Triangulation<dim, spacedim>::begin_active(const unsigned int level) const
13105 {
13106  switch (dim)
13107  {
13108  case 1:
13109  return begin_active_line(level);
13110  case 2:
13111  return begin_active_quad(level);
13112  case 3:
13113  return begin_active_hex(level);
13114  default:
13115  Assert(false, ExcNotImplemented());
13116  return active_cell_iterator();
13117  }
13118 }
13119 
13120 
13121 
13122 template <int dim, int spacedim>
13125 {
13126  const unsigned int level = levels.size() - 1;
13127  if (levels[level]->cells.n_objects() == 0)
13128  return end(level);
13129 
13130  // find the last raw iterator on
13131  // this level
13132  raw_cell_iterator ri(const_cast<Triangulation<dim, spacedim> *>(this),
13133  level,
13134  levels[level]->cells.n_objects() - 1);
13135 
13136  // then move to the last used one
13137  if (ri->used() == true)
13138  return ri;
13139  while ((--ri).state() == IteratorState::valid)
13140  if (ri->used() == true)
13141  return ri;
13142  return ri;
13143 }
13144 
13145 
13146 
13147 template <int dim, int spacedim>
13150 {
13151  // get the last used cell
13152  cell_iterator cell = last();
13153 
13154  if (cell != end())
13155  {
13156  // then move to the last active one
13157  if (cell->is_active() == true)
13158  return cell;
13159  while ((--cell).state() == IteratorState::valid)
13160  if (cell->is_active() == true)
13161  return cell;
13162  }
13163  return cell;
13164 }
13165 
13166 
13167 
13168 template <int dim, int spacedim>
13171 {
13172  cell_iterator cell(
13173  this, 0, coarse_cell_id_to_coarse_cell_index(cell_id.get_coarse_cell_id()));
13174 
13175  for (const auto &child_index : cell_id.get_child_indices())
13176  {
13177  Assert(
13178  cell->has_children(),
13179  ExcMessage(
13180  "CellId is invalid for this triangulation.\n"
13181  "Either the provided CellId does not correspond to a cell in this "
13182  "triangulation object, or, in case you are using a parallel "
13183  "triangulation, may correspond to an artificial cell that is less "
13184  "refined on this processor."));
13185  cell = cell->child(static_cast<unsigned int>(child_index));
13186  }
13187 
13188  return cell;
13189 }
13190 
13191 
13192 
13193 template <int dim, int spacedim>
13196 {
13197  return cell_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
13198  -1,
13199  -1);
13200 }
13201 
13202 
13203 
13204 template <int dim, int spacedim>
13206 Triangulation<dim, spacedim>::end_raw(const unsigned int level) const
13207 {
13208  // This function may be called on parallel triangulations on levels
13209  // that exist globally, but not on the local portion of the
13210  // triangulation. In that case, just return the end iterator.
13211  //
13212  // We need to use levels.size() instead of n_levels() because the
13213  // latter function uses the cache, but we need to be able to call
13214  // this function at a time when the cache is not currently up to
13215  // date.
13216  if (level >= levels.size())
13217  {
13218  Assert(level < n_global_levels(),
13219  ExcInvalidLevel(level, n_global_levels()));
13220  return end();
13221  }
13222 
13223  // Query whether the given level is valid for the local portion of the
13224  // triangulation.
13225  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
13226  if (level < levels.size() - 1)
13227  return begin_raw(level + 1);
13228  else
13229  return end();
13230 }
13231 
13232 
13233 template <int dim, int spacedim>
13235 Triangulation<dim, spacedim>::end(const unsigned int level) const
13236 {
13237  // This function may be called on parallel triangulations on levels
13238  // that exist globally, but not on the local portion of the
13239  // triangulation. In that case, just retrn the end iterator.
13240  //
13241  // We need to use levels.size() instead of n_levels() because the
13242  // latter function uses the cache, but we need to be able to call
13243  // this function at a time when the cache is not currently up to
13244  // date.
13245  if (level >= levels.size())
13246  {
13247  Assert(level < n_global_levels(),
13248  ExcInvalidLevel(level, n_global_levels()));
13249  return end();
13250  }
13251 
13252  // Query whether the given level is valid for the local portion of the
13253  // triangulation.
13254  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
13255  if (level < levels.size() - 1)
13256  return begin(level + 1);
13257  else
13258  return end();
13259 }
13260 
13261 
13262 template <int dim, int spacedim>
13264 Triangulation<dim, spacedim>::end_active(const unsigned int level) const
13265 {
13266  // This function may be called on parallel triangulations on levels
13267  // that exist globally, but not on the local portion of the
13268  // triangulation. In that case, just return the end iterator.
13269  //
13270  // We need to use levels.size() instead of n_levels() because the
13271  // latter function uses the cache, but we need to be able to call
13272  // this function at a time when the cache is not currently up to
13273  // date.
13274  if (level >= levels.size())
13275  {
13276  Assert(level < n_global_levels(),
13277  ExcInvalidLevel(level, n_global_levels()));
13278  return end();
13279  }
13280 
13281  // Query whether the given level is valid for the local portion of the
13282  // triangulation.
13283  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
13284  return (level >= levels.size() - 1 ? active_cell_iterator(end()) :
13285  begin_active(level + 1));
13286 }
13287 
13288 
13289 
13290 template <int dim, int spacedim>
13293 {
13295  begin(), end());
13296 }
13297 
13298 
13299 template <int dim, int spacedim>
13302 {
13303  return IteratorRange<
13304  typename Triangulation<dim, spacedim>::active_cell_iterator>(begin_active(),
13305  end());
13306 }
13307 
13308 
13309 
13310 template <int dim, int spacedim>
13313  const unsigned int level) const
13314 {
13316  begin(level), end(level));
13317 }
13318 
13319 
13320 
13321 template <int dim, int spacedim>
13324  const unsigned int level) const
13325 {
13326  return IteratorRange<
13328  begin_active(level), end_active(level));
13329 }
13330 
13331 
13332 /*------------------------ Face iterator functions ------------------------*/
13333 
13334 
13335 template <int dim, int spacedim>
13338 {
13339  switch (dim)
13340  {
13341  case 1:
13342  Assert(false, ExcImpossibleInDim(1));
13343  return raw_face_iterator();
13344  case 2:
13345  return begin_line();
13346  case 3:
13347  return begin_quad();
13348  default:
13349  Assert(false, ExcNotImplemented());
13350  return face_iterator();
13351  }
13352 }
13353 
13354 
13355 
13356 template <int dim, int spacedim>
13359 {
13360  switch (dim)
13361  {
13362  case 1:
13363  Assert(false, ExcImpossibleInDim(1));
13364  return raw_face_iterator();
13365  case 2:
13366  return begin_active_line();
13367  case 3:
13368  return begin_active_quad();
13369  default:
13370  Assert(false, ExcNotImplemented());
13371  return active_face_iterator();
13372  }
13373 }
13374 
13375 
13376 
13377 template <int dim, int spacedim>
13380 {
13381  switch (dim)
13382  {
13383  case 1:
13384  Assert(false, ExcImpossibleInDim(1));
13385  return raw_face_iterator();
13386  case 2:
13387  return end_line();
13388  case 3:
13389  return end_quad();
13390  default:
13391  Assert(false, ExcNotImplemented());
13392  return raw_face_iterator();
13393  }
13394 }
13395 
13396 
13397 
13398 template <int dim, int spacedim>
13401 {
13402  return IteratorRange<
13404  begin_active_face(), end_face());
13405 }
13406 
13407 /*------------------------ Vertex iterator functions ------------------------*/
13408 
13409 
13410 template <int dim, int spacedim>
13413 {
13414  vertex_iterator i =
13415  raw_vertex_iterator(const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
13416  if (i.state() != IteratorState::valid)
13417  return i;
13418  // This loop will end because every triangulation has used vertices.
13419  while (i->used() == false)
13420  if ((++i).state() != IteratorState::valid)
13421  return i;
13422  return i;
13423 }
13424 
13425 
13426 
13427 template <int dim, int spacedim>
13430 {
13431  // every vertex is active
13432  return begin_vertex();
13433 }
13434 
13435 
13436 
13437 template <int dim, int spacedim>
13440 {
13441  return raw_vertex_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
13442  -1,
13444 }
13445 
13446 
13447 
13448 /*------------------------ Line iterator functions ------------------------*/
13449 
13450 
13451 
13452 template <int dim, int spacedim>
13454 Triangulation<dim, spacedim>::begin_raw_line(const unsigned int level) const
13455 {
13456  // This function may be called on parallel triangulations on levels
13457  // that exist globally, but not on the local portion of the
13458  // triangulation. In that case, just return the end iterator.
13459  //
13460  // We need to use levels.size() instead of n_levels() because the
13461  // latter function uses the cache, but we need to be able to call
13462  // this function at a time when the cache is not currently up to
13463  // date.
13464  if (level >= levels.size())
13465  {
13466  Assert(level < n_global_levels(),
13467  ExcInvalidLevel(level, n_global_levels()));
13468  return end_line();
13469  }
13470 
13471  switch (dim)
13472  {
13473  case 1:
13474  // Query whether the given level is valid for the local portion of the
13475  // triangulation.
13476  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
13477 
13478  if (level >= levels.size() || levels[level]->cells.n_objects() == 0)
13479  return end_line();
13480 
13481  return raw_line_iterator(
13482  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
13483 
13484  default:
13485  Assert(level == 0, ExcFacesHaveNoLevel());
13486  return raw_line_iterator(
13487  const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
13488  }
13489 }
13490 
13491 
13492 template <int dim, int spacedim>
13494 Triangulation<dim, spacedim>::begin_line(const unsigned int level) const
13495 {
13496  // level is checked in begin_raw
13497  raw_line_iterator ri = begin_raw_line(level);
13498  if (ri.state() != IteratorState::valid)
13499  return ri;
13500  while (ri->used() == false)
13501  if ((++ri).state() != IteratorState::valid)
13502  return ri;
13503  return ri;
13504 }
13505 
13506 
13507 
13508 template <int dim, int spacedim>
13511 {
13512  // level is checked in begin_raw
13513  line_iterator i = begin_line(level);
13514  if (i.state() != IteratorState::valid)
13515  return i;
13516  while (i->has_children())
13517  if ((++i).state() != IteratorState::valid)
13518  return i;
13519  return i;
13520 }
13521 
13522 
13523 
13524 template <int dim, int spacedim>
13527 {
13528  return raw_line_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
13529  -1,
13530  -1);
13531 }
13532 
13533 
13534 
13535 /*------------------------ Quad iterator functions ------------------------*/
13536 
13537 
13538 template <int dim, int spacedim>
13540 Triangulation<dim, spacedim>::begin_raw_quad(const unsigned int level) const
13541 {
13542  // This function may be called on parallel triangulations on levels
13543  // that exist globally, but not on the local portion of the
13544  // triangulation. In that case, just return the end iterator.
13545  //
13546  // We need to use levels.size() instead of n_levels() because the
13547  // latter function uses the cache, but we need to be able to call
13548  // this function at a time when the cache is not currently up to
13549  // date.
13550  if (level >= levels.size())
13551  {
13552  Assert(level < n_global_levels(),
13553  ExcInvalidLevel(level, n_global_levels()));
13554  return end_quad();
13555  }
13556 
13557  switch (dim)
13558  {
13559  case 1:
13560  Assert(false, ExcImpossibleInDim(1));
13561  return raw_hex_iterator();
13562  case 2:
13563  {
13564  // Query whether the given level is valid for the local portion of the
13565  // triangulation.
13566  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
13567 
13568  if (level >= levels.size() || levels[level]->cells.n_objects() == 0)
13569  return end_quad();
13570 
13571  return raw_quad_iterator(
13572  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
13573  }
13574 
13575  case 3:
13576  {
13577  Assert(level == 0, ExcFacesHaveNoLevel());
13578 
13579  return raw_quad_iterator(
13580  const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
13581  }
13582 
13583 
13584  default:
13585  Assert(false, ExcNotImplemented());
13586  return raw_hex_iterator();
13587  }
13588 }
13589 
13590 
13591 
13592 template <int dim, int spacedim>
13594 Triangulation<dim, spacedim>::begin_quad(const unsigned int level) const
13595 {
13596  // level is checked in begin_raw
13597  raw_quad_iterator ri = begin_raw_quad(level);
13598  if (ri.state() != IteratorState::valid)
13599  return ri;
13600  while (ri->used() == false)
13601  if ((++ri).state() != IteratorState::valid)
13602  return ri;
13603  return ri;
13604 }
13605 
13606 
13607 
13608 template <int dim, int spacedim>
13611 {
13612  // level is checked in begin_raw
13613  quad_iterator i = begin_quad(level);
13614  if (i.state() != IteratorState::valid)
13615  return i;
13616  while (i->has_children())
13617  if ((++i).state() != IteratorState::valid)
13618  return i;
13619  return i;
13620 }
13621 
13622 
13623 
13624 template <int dim, int spacedim>
13627 {
13628  return raw_quad_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
13629  -1,
13630  -1);
13631 }
13632 
13633 
13634 /*------------------------ Hex iterator functions ------------------------*/
13635 
13636 
13637 template <int dim, int spacedim>
13639 Triangulation<dim, spacedim>::begin_raw_hex(const unsigned int level) const
13640 {
13641  // This function may be called on parallel triangulations on levels
13642  // that exist globally, but not on the local portion of the
13643  // triangulation. In that case, just return the end iterator.
13644  //
13645  // We need to use levels.size() instead of n_levels() because the
13646  // latter function uses the cache, but we need to be able to call
13647  // this function at a time when the cache is not currently up to
13648  // date.
13649  if (level >= levels.size())
13650  {
13651  Assert(level < n_global_levels(),
13652  ExcInvalidLevel(level, n_global_levels()));
13653  return end_hex();
13654  }
13655 
13656  switch (dim)
13657  {
13658  case 1:
13659  case 2:
13660  Assert(false, ExcImpossibleInDim(1));
13661  return raw_hex_iterator();
13662  case 3:
13663  {
13664  // Query whether the given level is valid for the local portion of the
13665  // triangulation.
13666  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
13667 
13668  if (level >= levels.size() || levels[level]->cells.n_objects() == 0)
13669  return end_hex();
13670 
13671  return raw_hex_iterator(
13672  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
13673  }
13674 
13675  default:
13676  Assert(false, ExcNotImplemented());
13677  return raw_hex_iterator();
13678  }
13679 }
13680 
13681 
13682 
13683 template <int dim, int spacedim>
13685 Triangulation<dim, spacedim>::begin_hex(const unsigned int level) const
13686 {
13687  // level is checked in begin_raw
13688  raw_hex_iterator ri = begin_raw_hex(level);
13689  if (ri.state() != IteratorState::valid)
13690  return ri;
13691  while (ri->used() == false)
13692  if ((++ri).state() != IteratorState::valid)
13693  return ri;
13694  return ri;
13695 }
13696 
13697 
13698 
13699 template <int dim, int spacedim>
13701 Triangulation<dim, spacedim>::begin_active_hex(const unsigned int level) const
13702 {
13703  // level is checked in begin_raw
13704  hex_iterator i = begin_hex(level);
13705  if (i.state() != IteratorState::valid)
13706  return i;
13707  while (i->has_children())
13708  if ((++i).state() != IteratorState::valid)
13709  return i;
13710  return i;
13711 }
13712 
13713 
13714 
13715 template <int dim, int spacedim>
13718 {
13719  return raw_hex_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
13720  -1,
13721  -1);
13722 }
13723 
13724 
13725 
13726 // -------------------------------- number of cells etc ---------------
13727 
13728 
13729 namespace internal
13730 {
13731  namespace TriangulationImplementation
13732  {
13733  inline unsigned int
13735  {
13736  return c.n_lines;
13737  }
13738 
13739 
13740  inline unsigned int
13743  {
13744  return c.n_active_lines;
13745  }
13746 
13747 
13748  inline unsigned int
13750  {
13751  return c.n_quads;
13752  }
13753 
13754 
13755  inline unsigned int
13758  {
13759  return c.n_active_quads;
13760  }
13761 
13762 
13763  inline unsigned int
13765  {
13766  return c.n_hexes;
13767  }
13768 
13769 
13770  inline unsigned int
13773  {
13774  return c.n_active_hexes;
13775  }
13776  } // namespace TriangulationImplementation
13777 } // namespace internal
13778 
13779 
13780 
13781 template <int dim, int spacedim>
13782 unsigned int
13784 {
13786 }
13787 
13788 
13789 template <int dim, int spacedim>
13790 unsigned int
13792 {
13794 }
13795 
13796 template <int dim, int spacedim>
13799 {
13800  return n_active_cells();
13801 }
13802 
13803 template <int dim, int spacedim>
13806 {
13807  return n_cells(0);
13808 }
13809 
13810 template <int dim, int spacedim>
13811 unsigned int
13813 {
13814  switch (dim)
13815  {
13816  case 1:
13817  return n_used_vertices();
13818  case 2:
13819  return n_lines();
13820  case 3:
13821  return n_quads();
13822  default:
13823  Assert(false, ExcNotImplemented());
13824  }
13825  return 0;
13826 }
13827 
13828 
13829 template <int dim, int spacedim>
13830 unsigned int
13832 {
13833  switch (dim)
13834  {
13835  case 1:
13836  return n_vertices();
13837  case 2:
13838  return n_raw_lines();
13839  case 3:
13840  return n_raw_quads();
13841  default:
13842  Assert(false, ExcNotImplemented());
13843  }
13844  return 0;
13845 }
13846 
13847 
13848 template <int dim, int spacedim>
13849 unsigned int
13851 {
13852  switch (dim)
13853  {
13854  case 1:
13855  return n_used_vertices();
13856  case 2:
13857  return n_active_lines();
13858  case 3:
13859  return n_active_quads();
13860  default:
13861  Assert(false, ExcNotImplemented());
13862  }
13863  return 0;
13864 }
13865 
13866 
13867 template <int dim, int spacedim>
13868 unsigned int
13869 Triangulation<dim, spacedim>::n_raw_cells(const unsigned int level) const
13870 {
13871  switch (dim)
13872  {
13873  case 1:
13874  return n_raw_lines(level);
13875  case 2:
13876  return n_raw_quads(level);
13877  case 3:
13878  return n_raw_hexs(level);
13879  default:
13880  Assert(false, ExcNotImplemented());
13881  }
13882  return 0;
13883 }
13884 
13885 
13886 
13887 template <int dim, int spacedim>
13888 unsigned int
13889 Triangulation<dim, spacedim>::n_cells(const unsigned int level) const
13890 {
13891  switch (dim)
13892  {
13893  case 1:
13894  return n_lines(level);
13895  case 2:
13896  return n_quads(level);
13897  case 3:
13898  return n_hexs(level);
13899  default:
13900  Assert(false, ExcNotImplemented());
13901  }
13902  return 0;
13903 }
13904 
13905 
13906 
13907 template <int dim, int spacedim>
13908 unsigned int
13909 Triangulation<dim, spacedim>::n_active_cells(const unsigned int level) const
13910 {
13911  switch (dim)
13912  {
13913  case 1:
13914  return n_active_lines(level);
13915  case 2:
13916  return n_active_quads(level);
13917  case 3:
13918  return n_active_hexs(level);
13919  default:
13920  Assert(false, ExcNotImplemented());
13921  }
13922  return 0;
13923 }
13924 
13925 
13926 template <int dim, int spacedim>
13927 bool
13929 {
13930  for (unsigned int lvl = 0; lvl < n_global_levels() - 1; ++lvl)
13931  if (n_active_cells(lvl) != 0)
13932  return true;
13933 
13934  return false;
13935 }
13936 
13937 
13938 template <int dim, int spacedim>
13939 unsigned int
13941 {
13942  return number_cache.n_lines;
13943 }
13944 
13945 
13946 
13947 template <int dim, int spacedim>
13948 unsigned int
13949 Triangulation<dim, spacedim>::n_raw_lines(const unsigned int level) const
13950 {
13951  if (dim == 1)
13952  {
13953  AssertIndexRange(level, n_levels());
13954  return levels[level]->cells.n_objects();
13955  }
13956 
13957  Assert(false, ExcFacesHaveNoLevel());
13958  return 0;
13959 }
13960 
13961 
13962 template <int dim, int spacedim>
13963 unsigned int
13965 {
13966  if (dim == 1)
13967  {
13968  Assert(false, ExcNotImplemented());
13969  return 0;
13970  }
13971 
13972  return faces->lines.n_objects();
13973 }
13974 
13975 
13976 template <int dim, int spacedim>
13977 unsigned int
13978 Triangulation<dim, spacedim>::n_lines(const unsigned int level) const
13979 {
13980  AssertIndexRange(level, number_cache.n_lines_level.size());
13981  Assert(dim == 1, ExcFacesHaveNoLevel());
13982  return number_cache.n_lines_level[level];
13983 }
13984 
13985 
13986 template <int dim, int spacedim>
13987 unsigned int
13989 {
13990  return number_cache.n_active_lines;
13991 }
13992 
13993 
13994 template <int dim, int spacedim>
13995 unsigned int
13996 Triangulation<dim, spacedim>::n_active_lines(const unsigned int level) const
13997 {
13998  AssertIndexRange(level, number_cache.n_lines_level.size());
13999  Assert(dim == 1, ExcFacesHaveNoLevel());
14000 
14001  return number_cache.n_active_lines_level[level];
14002 }
14003 
14004 
14005 template <>
14006 unsigned int
14008 {
14009  return 0;
14010 }
14011 
14012 
14013 template <>
14014 unsigned int
14015 Triangulation<1, 1>::n_quads(const unsigned int) const
14016 {
14017  return 0;
14018 }
14019 
14020 
14021 template <>
14022 unsigned int
14023 Triangulation<1, 1>::n_raw_quads(const unsigned int) const
14024 {
14025  return 0;
14026 }
14027 
14028 
14029 template <>
14030 unsigned int
14031 Triangulation<1, 1>::n_raw_hexs(const unsigned int) const
14032 {
14033  return 0;
14034 }
14035 
14036 
14037 template <>
14038 unsigned int
14039 Triangulation<1, 1>::n_active_quads(const unsigned int) const
14040 {
14041  return 0;
14042 }
14043 
14044 
14045 template <>
14046 unsigned int
14048 {
14049  return 0;
14050 }
14051 
14052 
14053 
14054 template <>
14055 unsigned int
14057 {
14058  return 0;
14059 }
14060 
14061 
14062 template <>
14063 unsigned int
14064 Triangulation<1, 2>::n_quads(const unsigned int) const
14065 {
14066  return 0;
14067 }
14068 
14069 
14070 template <>
14071 unsigned int
14072 Triangulation<1, 2>::n_raw_quads(const unsigned int) const
14073 {
14074  return 0;
14075 }
14076 
14077 
14078 template <>
14079 unsigned int
14080 Triangulation<1, 2>::n_raw_hexs(const unsigned int) const
14081 {
14082  return 0;
14083 }
14084 
14085 
14086 template <>
14087 unsigned int
14088 Triangulation<1, 2>::n_active_quads(const unsigned int) const
14089 {
14090  return 0;
14091 }
14092 
14093 
14094 template <>
14095 unsigned int
14097 {
14098  return 0;
14099 }
14100 
14101 
14102 template <>
14103 unsigned int
14105 {
14106  return 0;
14107 }
14108 
14109 
14110 template <>
14111 unsigned int
14112 Triangulation<1, 3>::n_quads(const unsigned int) const
14113 {
14114  return 0;
14115 }
14116 
14117 
14118 template <>
14119 unsigned int
14120 Triangulation<1, 3>::n_raw_quads(const unsigned int) const
14121 {
14122  return 0;
14123 }
14124 
14125 
14126 template <>
14127 unsigned int
14128 Triangulation<1, 3>::n_raw_hexs(const unsigned int) const
14129 {
14130  return 0;
14131 }
14132 
14133 
14134 template <>
14135 unsigned int
14136 Triangulation<1, 3>::n_active_quads(const unsigned int) const
14137 {
14138  return 0;
14139 }
14140 
14141 
14142 template <>
14143 unsigned int
14145 {
14146  return 0;
14147 }
14148 
14149 
14150 
14151 template <int dim, int spacedim>
14152 unsigned int
14154 {
14155  return number_cache.n_quads;
14156 }
14157 
14158 
14159 template <int dim, int spacedim>
14160 unsigned int
14161 Triangulation<dim, spacedim>::n_quads(const unsigned int level) const
14162 {
14163  Assert(dim == 2, ExcFacesHaveNoLevel());
14164  AssertIndexRange(level, number_cache.n_quads_level.size());
14165  return number_cache.n_quads_level[level];
14166 }
14167 
14168 
14169 
14170 template <>
14171 unsigned int
14172 Triangulation<2, 2>::n_raw_quads(const unsigned int level) const
14173 {
14174  AssertIndexRange(level, n_levels());
14175  return levels[level]->cells.n_objects();
14176 }
14177 
14178 
14179 
14180 template <>
14181 unsigned int
14182 Triangulation<2, 3>::n_raw_quads(const unsigned int level) const
14183 {
14184  AssertIndexRange(level, n_levels());
14185  return levels[level]->cells.n_objects();
14186 }
14187 
14188 
14189 template <>
14190 unsigned int
14191 Triangulation<3, 3>::n_raw_quads(const unsigned int) const
14192 {
14193  Assert(false, ExcFacesHaveNoLevel());
14194  return 0;
14195 }
14196 
14197 
14198 
14199 template <int dim, int spacedim>
14200 unsigned int
14202 {
14203  Assert(false, ExcNotImplemented());
14204  return 0;
14205 }
14206 
14207 
14208 
14209 template <>
14210 unsigned int
14212 {
14213  return faces->quads.n_objects();
14214 }
14215 
14216 
14217 
14218 template <int dim, int spacedim>
14219 unsigned int
14221 {
14222  return number_cache.n_active_quads;
14223 }
14224 
14225 
14226 template <int dim, int spacedim>
14227 unsigned int
14228 Triangulation<dim, spacedim>::n_active_quads(const unsigned int level) const
14229 {
14230  AssertIndexRange(level, number_cache.n_quads_level.size());
14231  Assert(dim == 2, ExcFacesHaveNoLevel());
14232 
14233  return number_cache.n_active_quads_level[level];
14234 }
14235 
14236 
14237 template <int dim, int spacedim>
14238 unsigned int
14240 {
14241  return 0;
14242 }
14243 
14244 
14245 
14246 template <int dim, int spacedim>
14247 unsigned int
14248 Triangulation<dim, spacedim>::n_hexs(const unsigned int) const
14249 {
14250  return 0;
14251 }
14252 
14253 
14254 
14255 template <int dim, int spacedim>
14256 unsigned int
14257 Triangulation<dim, spacedim>::n_raw_hexs(const unsigned int) const
14258 {
14259  return 0;
14260 }
14261 
14262 
14263 template <int dim, int spacedim>
14264 unsigned int
14266 {
14267  return 0;
14268 }
14269 
14270 
14271 
14272 template <int dim, int spacedim>
14273 unsigned int
14274 Triangulation<dim, spacedim>::n_active_hexs(const unsigned int) const
14275 {
14276  return 0;
14277 }
14278 
14279 
14280 template <>
14281 unsigned int
14283 {
14284  return number_cache.n_hexes;
14285 }
14286 
14287 
14288 
14289 template <>
14290 unsigned int
14291 Triangulation<3, 3>::n_hexs(const unsigned int level) const
14292 {
14293  AssertIndexRange(level, number_cache.n_hexes_level.size());
14294 
14295  return number_cache.n_hexes_level[level];
14296 }
14297 
14298 
14299 
14300 template <>
14301 unsigned int
14302 Triangulation<3, 3>::n_raw_hexs(const unsigned int level) const
14303 {
14304  AssertIndexRange(level, n_levels());
14305  return levels[level]->cells.n_objects();
14306 }
14307 
14308 
14309 template <>
14310 unsigned int
14312 {
14313  return number_cache.n_active_hexes;
14314 }
14315 
14316 
14317 
14318 template <>
14319 unsigned int
14321 {
14322  AssertIndexRange(level, number_cache.n_hexes_level.size());
14323 
14324  return number_cache.n_active_hexes_level[level];
14325 }
14326 
14327 
14328 
14329 template <int dim, int spacedim>
14330 unsigned int
14332 {
14333  return std::count(vertices_used.begin(), vertices_used.end(), true);
14334 }
14335 
14336 
14337 
14338 template <int dim, int spacedim>
14339 const std::vector<bool> &
14341 {
14342  return vertices_used;
14343 }
14344 
14345 
14346 
14347 template <>
14348 unsigned int
14350 {
14351  return 2;
14352 }
14353 
14354 
14355 
14356 template <>
14357 unsigned int
14359 {
14360  return 2;
14361 }
14362 
14363 
14364 template <>
14365 unsigned int
14367 {
14368  return 2;
14369 }
14370 
14371 
14372 template <int dim, int spacedim>
14373 unsigned int
14375 {
14376  cell_iterator cell = begin(0),
14377  endc = (n_levels() > 1 ? begin(1) : cell_iterator(end()));
14378  // store the largest index of the
14379  // vertices used on level 0
14380  unsigned int max_vertex_index = 0;
14381  for (; cell != endc; ++cell)
14382  for (const unsigned int vertex : GeometryInfo<dim>::vertex_indices())
14383  if (cell->vertex_index(vertex) > max_vertex_index)
14384  max_vertex_index = cell->vertex_index(vertex);
14385 
14386  // store the number of times a cell
14387  // touches a vertex. An unsigned
14388  // int should suffice, even for
14389  // larger dimensions
14390  std::vector<unsigned short int> usage_count(max_vertex_index + 1, 0);
14391  // touch a vertex's usage count
14392  // every time we find an adjacent
14393  // element
14394  for (cell = begin(); cell != endc; ++cell)
14395  for (const unsigned int vertex : GeometryInfo<dim>::vertex_indices())
14396  ++usage_count[cell->vertex_index(vertex)];
14397 
14399  static_cast<unsigned int>(
14400  *std::max_element(usage_count.begin(), usage_count.end())));
14401 }
14402 
14403 
14404 
14405 template <int dim, int spacedim>
14408 {
14410 }
14411 
14412 
14413 
14414 template <int dim, int spacedim>
14417 {
14418  return *this;
14419 }
14420 
14421 
14422 
14423 template <int dim, int spacedim>
14426 {
14427  return *this;
14428 }
14429 
14430 
14431 
14432 template <int dim, int spacedim>
14433 void
14436  &periodicity_vector)
14437 {
14438  periodic_face_pairs_level_0.insert(periodic_face_pairs_level_0.end(),
14439  periodicity_vector.begin(),
14440  periodicity_vector.end());
14441 
14442  // Now initialize periodic_face_map
14443  update_periodic_face_map();
14444 }
14445 
14446 
14447 
14448 template <int dim, int spacedim>
14449 const typename std::map<
14450  std::pair<typename Triangulation<dim, spacedim>::cell_iterator, unsigned int>,
14451  std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
14452  unsigned int>,
14453  std::bitset<3>>> &
14455 {
14456  return periodic_face_map;
14457 }
14458 
14459 
14460 
14461 template <int dim, int spacedim>
14462 void
14464 {
14465  // Call our version of prepare_coarsening_and_refinement() even if a derived
14466  // class like parallel::distributed::Triangulation overrides it. Their
14467  // function will be called in their execute_coarsening_and_refinement()
14468  // function. Even in a distributed computation our job here is to reconstruct
14469  // the local part of the mesh and as such checking our flags is enough.
14471 
14472  // verify a case with which we have had
14473  // some difficulty in the past (see the
14474  // deal.II/coarsening_* tests)
14475  if (smooth_grid & limit_level_difference_at_vertices)
14476  Assert(satisfies_level1_at_vertex_rule(*this) == true, ExcInternalError());
14477 
14478  // Inform all listeners about beginning of refinement.
14479  signals.pre_refinement();
14480 
14481  execute_coarsening();
14482 
14483  const DistortedCellList cells_with_distorted_children = execute_refinement();
14484 
14485  reset_cell_vertex_indices_cache();
14486 
14487  // verify a case with which we have had
14488  // some difficulty in the past (see the
14489  // deal.II/coarsening_* tests)
14490  if (smooth_grid & limit_level_difference_at_vertices)
14491  Assert(satisfies_level1_at_vertex_rule(*this) == true, ExcInternalError());
14492 
14493  // finally build up neighbor connectivity information, and set
14494  // active cell indices
14495  this->policy->update_neighbors(*this);
14496  reset_active_cell_indices();
14497 
14498  reset_global_cell_indices(); // TODO: better place?
14499 
14500  // Inform all listeners about end of refinement.
14501  signals.post_refinement();
14502 
14503  AssertThrow(cells_with_distorted_children.distorted_cells.size() == 0,
14504  cells_with_distorted_children);
14505 
14506  update_periodic_face_map();
14507 }
14508 
14509 
14510 
14511 template <int dim, int spacedim>
14512 void
14514 {
14515  unsigned int active_cell_index = 0;
14516  for (raw_cell_iterator cell = begin_raw(); cell != end(); ++cell)
14517  if ((cell->used() == false) || cell->has_children())
14518  cell->set_active_cell_index(numbers::invalid_unsigned_int);
14519  else
14520  {
14521  cell->set_active_cell_index(active_cell_index);
14522  ++active_cell_index;
14523  }
14524 
14525  Assert(active_cell_index == n_active_cells(), ExcInternalError());
14526 }
14527 
14528 
14529 
14530 template <int dim, int spacedim>
14531 void
14533 {
14534  {
14536  for (const auto &cell : active_cell_iterators())
14537  cell->set_global_active_cell_index(cell_index++);
14538  }
14539 
14540  for (unsigned int l = 0; l < levels.size(); ++l)
14541  {
14543  for (const auto &cell : cell_iterators_on_level(l))
14544  cell->set_global_level_cell_index(cell_index++);
14545  }
14546 }
14547 
14548 
14549 
14550 template <int dim, int spacedim>
14551 void
14553 {
14554  for (unsigned int l = 0; l < levels.size(); ++l)
14555  {
14556  constexpr unsigned int max_vertices_per_cell = 1 << dim;
14557  std::vector<unsigned int> &cache = levels[l]->cell_vertex_indices_cache;
14558  cache.clear();
14559  cache.resize(levels[l]->refine_flags.size() * max_vertices_per_cell,
14561  for (const auto &cell : cell_iterators_on_level(l))
14562  {
14563  const unsigned int my_index = cell->index() * max_vertices_per_cell;
14564  for (const unsigned int i : cell->vertex_indices())
14565  cache[my_index + i] = internal::TriaAccessorImplementation::
14566  Implementation::vertex_index(*cell, i);
14567  }
14568  }
14569 }
14570 
14571 
14572 
14573 template <int dim, int spacedim>
14574 void
14576 {
14577  // first empty the currently stored objects
14578  periodic_face_map.clear();
14579 
14580  typename std::vector<
14581  GridTools::PeriodicFacePair<cell_iterator>>::const_iterator it;
14582  for (it = periodic_face_pairs_level_0.begin();
14583  it != periodic_face_pairs_level_0.end();
14584  ++it)
14585  {
14586  update_periodic_face_map_recursively<dim, spacedim>(it->cell[0],
14587  it->cell[1],
14588  it->face_idx[0],
14589  it->face_idx[1],
14590  it->orientation,
14591  periodic_face_map);
14592 
14593  // for the other way, we need to invert the orientation
14594  std::bitset<3> inverted_orientation;
14595  {
14596  bool orientation, flip, rotation;
14597  orientation = it->orientation[0];
14598  rotation = it->orientation[2];
14599  flip = orientation ? rotation ^ it->orientation[1] : it->orientation[1];
14600  inverted_orientation[0] = orientation;
14601  inverted_orientation[1] = flip;
14602  inverted_orientation[2] = rotation;
14603  }
14604  update_periodic_face_map_recursively<dim, spacedim>(it->cell[1],
14605  it->cell[0],
14606  it->face_idx[1],
14607  it->face_idx[0],
14608  inverted_orientation,
14609  periodic_face_map);
14610  }
14611 
14612  // check consistency
14613  typename std::map<std::pair<cell_iterator, unsigned int>,
14614  std::pair<std::pair<cell_iterator, unsigned int>,
14615  std::bitset<3>>>::const_iterator it_test;
14616  for (it_test = periodic_face_map.begin(); it_test != periodic_face_map.end();
14617  ++it_test)
14618  {
14620  it_test->first.first;
14622  it_test->second.first.first;
14623  if (cell_1->level() == cell_2->level())
14624  {
14625  // if both cells have the same neighbor, then the same pair
14626  // order swapped has to be in the map
14627  Assert(periodic_face_map[it_test->second.first].first ==
14628  it_test->first,
14629  ExcInternalError());
14630  }
14631  }
14632 }
14633 
14634 
14635 
14636 template <int dim, int spacedim>
14637 void
14639 {
14640  std::set<ReferenceCell> reference_cells_set;
14641  for (auto cell : active_cell_iterators())
14642  if (cell->is_locally_owned())
14643  reference_cells_set.insert(cell->reference_cell());
14644 
14645  this->reference_cells =
14646  std::vector<ReferenceCell>(reference_cells_set.begin(),
14647  reference_cells_set.end());
14648 }
14649 
14650 
14651 
14652 template <int dim, int spacedim>
14653 const std::vector<ReferenceCell> &
14655 {
14656  return this->reference_cells;
14657 }
14658 
14659 
14660 
14661 template <int dim, int spacedim>
14662 bool
14664 {
14665  Assert(this->reference_cells.size() > 0,
14666  ExcMessage("You can't ask about the kinds of reference "
14667  "cells used by this triangulation if the "
14668  "triangulation doesn't yet have any cells in it."));
14669  return (this->reference_cells.size() == 1 &&
14670  this->reference_cells[0].is_hyper_cube());
14671 }
14672 
14673 
14674 
14675 template <int dim, int spacedim>
14676 bool
14678 {
14679  Assert(this->reference_cells.size() > 0,
14680  ExcMessage("You can't ask about the kinds of reference "
14681  "cells used by this triangulation if the "
14682  "triangulation doesn't yet have any cells in it."));
14683  return (this->reference_cells.size() == 1 &&
14684  this->reference_cells[0].is_simplex());
14685 }
14686 
14687 
14688 
14689 template <int dim, int spacedim>
14690 bool
14692 {
14693  Assert(this->reference_cells.size() > 0,
14694  ExcMessage("You can't ask about the kinds of reference "
14695  "cells used by this triangulation if the "
14696  "triangulation doesn't yet have any cells in it."));
14697  return reference_cells.size() > 1 ||
14698  ((reference_cells[0].is_hyper_cube() == false) &&
14699  (reference_cells[0].is_simplex() == false));
14700 }
14701 
14702 
14703 
14704 template <int dim, int spacedim>
14705 void
14707 {
14708  levels.clear();
14709  faces.reset();
14710 
14711  vertices.clear();
14712  vertices_used.clear();
14713 
14714  manifolds.clear();
14715 
14717 }
14718 
14719 
14720 
14721 template <int dim, int spacedim>
14724 {
14725  const DistortedCellList cells_with_distorted_children =
14726  this->policy->execute_refinement(*this, check_for_distorted_cells);
14727 
14728 
14729 
14730  // re-compute number of lines
14732  *this, levels.size(), number_cache);
14733 
14734 #ifdef DEBUG
14735  for (const auto &level : levels)
14736  monitor_memory(level->cells, dim);
14737 
14738  // check whether really all refinement flags are reset (also of
14739  // previously non-active cells which we may not have touched. If the
14740  // refinement flag of a non-active cell is set, something went wrong
14741  // since the cell-accessors should have caught this)
14742  for (const auto &cell : this->cell_iterators())
14743  Assert(!cell->refine_flag_set(), ExcInternalError());
14744 #endif
14745 
14746  return cells_with_distorted_children;
14747 }
14748 
14749 
14750 
14751 template <int dim, int spacedim>
14752 void
14754 {
14755  // create a vector counting for each line how many cells contain
14756  // this line. in 3D, this is used later on to decide which lines can
14757  // be deleted after coarsening a cell. in other dimensions it will
14758  // be ignored
14759  std::vector<unsigned int> line_cell_count =
14760  count_cells_bounded_by_line(*this);
14761  std::vector<unsigned int> quad_cell_count =
14762  count_cells_bounded_by_quad(*this);
14763 
14764  // loop over all cells. Flag all cells of which all children are
14765  // flagged for coarsening and delete the childrens' flags. In
14766  // effect, only those cells are flagged of which originally all
14767  // children were flagged and for which all children are on the same
14768  // refinement level. For flagging, the user flags are used, to avoid
14769  // confusion and because non-active cells can't be flagged for
14770  // coarsening. Note that because of the effects of
14771  // @p{fix_coarsen_flags}, of a cell either all or no children must
14772  // be flagged for coarsening, so it is ok to only check the first
14773  // child
14774  clear_user_flags();
14775 
14776  for (const auto &cell : this->cell_iterators())
14777  if (!cell->is_active())
14778  if (cell->child(0)->coarsen_flag_set())
14779  {
14780  cell->set_user_flag();
14781  for (unsigned int child = 0; child < cell->n_children(); ++child)
14782  {
14783  Assert(cell->child(child)->coarsen_flag_set(),
14784  ExcInternalError());
14785  cell->child(child)->clear_coarsen_flag();
14786  }
14787  }
14788 
14789 
14790  // now do the actual coarsening step. Since the loop goes over used
14791  // cells we only need not worry about deleting some cells since the
14792  // ++operator will then just hop over them if we should hit one. Do
14793  // the loop in the reverse way since we may only delete some cells
14794  // if their neighbors have already been deleted (if the latter are
14795  // on a higher level for example)
14796  //
14797  // since we delete the *children* of cells, we can ignore cells
14798  // on the highest level, i.e., level must be less than or equal
14799  // to n_levels()-2.
14800  cell_iterator cell = begin(), endc = end();
14801  if (levels.size() >= 2)
14802  for (cell = last(); cell != endc; --cell)
14803  if (cell->level() <= static_cast<int>(levels.size() - 2) &&
14804  cell->user_flag_set())
14805  {
14806  // inform all listeners that cell coarsening is going to happen
14807  signals.pre_coarsening_on_cell(cell);
14808  // use a separate function, since this is dimension specific
14809  this->policy->delete_children(*this,
14810  cell,
14811  line_cell_count,
14812  quad_cell_count);
14813  }
14814 
14815  // re-compute number of lines and quads
14817  *this, levels.size(), number_cache);
14818 
14819  // in principle no user flags should be set any more at this point
14820 #if DEBUG
14821  for (cell = begin(); cell != endc; ++cell)
14822  Assert(cell->user_flag_set() == false, ExcInternalError());
14823 #endif
14824 }
14825 
14826 
14827 
14828 template <int dim, int spacedim>
14829 void
14831 {
14832  // copy a piece of code from prepare_coarsening_and_refinement that
14833  // ensures that the level difference at vertices is limited if so
14834  // desired. we need this code here since at least in 1d we don't
14835  // call the dimension-independent version of
14836  // prepare_coarsening_and_refinement function. in 2d and 3d, having
14837  // this hunk here makes our lives a bit easier as well as it takes
14838  // care of these cases earlier than it would otherwise happen.
14839  //
14840  // the main difference to the code in p_c_and_r is that here we
14841  // absolutely have to make sure that we get things right, i.e. that
14842  // in particular we set flags right if
14843  // limit_level_difference_at_vertices is set. to do so we iterate
14844  // until the flags don't change any more
14845  std::vector<bool> previous_coarsen_flags(n_active_cells());
14846  save_coarsen_flags(previous_coarsen_flags);
14847 
14848  std::vector<int> vertex_level(vertices.size(), 0);
14849 
14850  bool continue_iterating = true;
14851 
14852  do
14853  {
14854  if (smooth_grid & limit_level_difference_at_vertices)
14855  {
14856  Assert(!anisotropic_refinement,
14857  ExcMessage("In case of anisotropic refinement the "
14858  "limit_level_difference_at_vertices flag for "
14859  "mesh smoothing must not be set!"));
14860 
14861  // store highest level one of the cells adjacent to a vertex
14862  // belongs to
14863  std::fill(vertex_level.begin(), vertex_level.end(), 0);
14864  for (const auto &cell : this->active_cell_iterators())
14865  {
14866  if (cell->refine_flag_set())
14867  for (const unsigned int vertex :
14869  vertex_level[cell->vertex_index(vertex)] =
14870  std::max(vertex_level[cell->vertex_index(vertex)],
14871  cell->level() + 1);
14872  else if (!cell->coarsen_flag_set())
14873  for (const unsigned int vertex :
14875  vertex_level[cell->vertex_index(vertex)] =
14876  std::max(vertex_level[cell->vertex_index(vertex)],
14877  cell->level());
14878  else
14879  {
14880  // if coarsen flag is set then tentatively assume
14881  // that the cell will be coarsened. this isn't
14882  // always true (the coarsen flag could be removed
14883  // again) and so we may make an error here. we try
14884  // to correct this by iterating over the entire
14885  // process until we are converged
14886  Assert(cell->coarsen_flag_set(), ExcInternalError());
14887  for (const unsigned int vertex :
14889  vertex_level[cell->vertex_index(vertex)] =
14890  std::max(vertex_level[cell->vertex_index(vertex)],
14891  cell->level() - 1);
14892  }
14893  }
14894 
14895 
14896  // loop over all cells in reverse order. do so because we
14897  // can then update the vertex levels on the adjacent
14898  // vertices and maybe already flag additional cells in this
14899  // loop
14900  //
14901  // note that not only may we have to add additional
14902  // refinement flags, but we will also have to remove
14903  // coarsening flags on cells adjacent to vertices that will
14904  // see refinement
14905  active_cell_iterator cell = begin_active(), endc = end();
14906  for (cell = last_active(); cell != endc; --cell)
14907  if (cell->refine_flag_set() == false)
14908  {
14909  for (const unsigned int vertex :
14911  if (vertex_level[cell->vertex_index(vertex)] >=
14912  cell->level() + 1)
14913  {
14914  // remove coarsen flag...
14915  cell->clear_coarsen_flag();
14916 
14917  // ...and if necessary also refine the current
14918  // cell, at the same time updating the level
14919  // information about vertices
14920  if (vertex_level[cell->vertex_index(vertex)] >
14921  cell->level() + 1)
14922  {
14923  cell->set_refine_flag();
14924 
14925  for (const unsigned int v :
14927  vertex_level[cell->vertex_index(v)] =
14928  std::max(vertex_level[cell->vertex_index(v)],
14929  cell->level() + 1);
14930  }
14931 
14932  // continue and see whether we may, for example,
14933  // go into the inner 'if' above based on a
14934  // different vertex
14935  }
14936  }
14937  }
14938 
14939  // loop over all cells. Flag all cells of which all children are
14940  // flagged for coarsening and delete the childrens' flags. Also
14941  // delete all flags of cells for which not all children of a
14942  // cell are flagged. In effect, only those cells are flagged of
14943  // which originally all children were flagged and for which all
14944  // children are on the same refinement level. For flagging, the
14945  // user flags are used, to avoid confusion and because
14946  // non-active cells can't be flagged for coarsening
14947  //
14948  // In effect, all coarsen flags are turned into user flags of
14949  // the mother cell if coarsening is possible or deleted
14950  // otherwise.
14951  clear_user_flags();
14952  // Coarsen flags of cells with no mother cell, i.e. on the
14953  // coarsest level are deleted explicitly.
14954  for (const auto &acell : this->active_cell_iterators_on_level(0))
14955  acell->clear_coarsen_flag();
14956 
14957  for (const auto &cell : this->cell_iterators())
14958  {
14959  // nothing to do if we are already on the finest level
14960  if (cell->is_active())
14961  continue;
14962 
14963  const unsigned int n_children = cell->n_children();
14964  unsigned int flagged_children = 0;
14965  for (unsigned int child = 0; child < n_children; ++child)
14966  if (cell->child(child)->is_active() &&
14967  cell->child(child)->coarsen_flag_set())
14968  {
14969  ++flagged_children;
14970  // clear flag since we don't need it anymore
14971  cell->child(child)->clear_coarsen_flag();
14972  }
14973 
14974  // flag this cell for coarsening if all children were
14975  // flagged
14976  if (flagged_children == n_children)
14977  cell->set_user_flag();
14978  }
14979 
14980  // in principle no coarsen flags should be set any more at this
14981  // point
14982 #if DEBUG
14983  for (auto &cell : this->cell_iterators())
14984  Assert(cell->coarsen_flag_set() == false, ExcInternalError());
14985 #endif
14986 
14987  // now loop over all cells which have the user flag set. their
14988  // children were flagged for coarsening. set the coarsen flag
14989  // again if we are sure that none of the neighbors of these
14990  // children are refined, or will be refined, since then we would
14991  // get a two-level jump in refinement. on the other hand, if one
14992  // of the children's neighbors has their user flag set, then we
14993  // know that its children will go away by coarsening, and we
14994  // will be ok.
14995  //
14996  // note on the other hand that we do allow level-2 jumps in
14997  // refinement between neighbors in 1d, so this whole procedure
14998  // is only necessary if we are not in 1d
14999  //
15000  // since we remove some coarsening/user flags in the process, we
15001  // have to work from the finest level to the coarsest one, since
15002  // we occasionally inspect user flags of cells on finer levels
15003  // and need to be sure that these flags are final
15004  cell_iterator cell = begin(), endc = end();
15005  for (cell = last(); cell != endc; --cell)
15006  if (cell->user_flag_set())
15007  // if allowed: flag the
15008  // children for coarsening
15009  if (this->policy->coarsening_allowed(cell))
15010  for (unsigned int c = 0; c < cell->n_children(); ++c)
15011  {
15012  Assert(cell->child(c)->refine_flag_set() == false,
15013  ExcInternalError());
15014 
15015  cell->child(c)->set_coarsen_flag();
15016  }
15017 
15018  // clear all user flags again, now that we don't need them any
15019  // more
15020  clear_user_flags();
15021 
15022 
15023  // now see if anything has changed in the last iteration of this
15024  // function
15025  std::vector<bool> current_coarsen_flags(n_active_cells());
15026  save_coarsen_flags(current_coarsen_flags);
15027 
15028  continue_iterating = (current_coarsen_flags != previous_coarsen_flags);
15029  previous_coarsen_flags = current_coarsen_flags;
15030  }
15031  while (continue_iterating == true);
15032 }
15033 
15034 
15035 // TODO: merge the following 3 functions since they are the same
15036 template <>
15037 bool
15039 {
15040  // save the flags to determine whether something was changed in the
15041  // course of this function
15042  std::vector<bool> flags_before;
15043  save_coarsen_flags(flags_before);
15044 
15045  // do nothing in 1d, except setting the coarsening flags correctly
15046  fix_coarsen_flags();
15047 
15048  std::vector<bool> flags_after;
15049  save_coarsen_flags(flags_after);
15050 
15051  return (flags_before != flags_after);
15052 }
15053 
15054 
15055 template <>
15056 bool
15058 {
15059  // save the flags to determine whether something was changed in the
15060  // course of this function
15061  std::vector<bool> flags_before;
15062  save_coarsen_flags(flags_before);
15063 
15064  // do nothing in 1d, except setting the coarsening flags correctly
15065  fix_coarsen_flags();
15066 
15067  std::vector<bool> flags_after;
15068  save_coarsen_flags(flags_after);
15069 
15070  return (flags_before != flags_after);
15071 }
15072 
15073 
15074 template <>
15075 bool
15077 {
15078  // save the flags to determine whether something was changed in the
15079  // course of this function
15080  std::vector<bool> flags_before;
15081  save_coarsen_flags(flags_before);
15082 
15083  // do nothing in 1d, except setting the coarsening flags correctly
15084  fix_coarsen_flags();
15085 
15086  std::vector<bool> flags_after;
15087  save_coarsen_flags(flags_after);
15088 
15089  return (flags_before != flags_after);
15090 }
15091 
15092 
15093 
15094 namespace
15095 {
15096  // check if the given @param cell marked for coarsening would
15097  // produce an unrefined island. To break up long chains of these
15098  // cells we recursively check our neighbors in case we change this
15099  // cell. This reduces the number of outer iterations dramatically.
15100  template <int dim, int spacedim>
15101  void
15102  possibly_do_not_produce_unrefined_islands(
15103  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
15104  {
15105  Assert(cell->has_children(), ExcInternalError());
15106 
15107  unsigned int n_neighbors = 0;
15108  // count all neighbors that will be refined along the face of our
15109  // cell after the next step
15110  unsigned int count = 0;
15111  for (unsigned int n : GeometryInfo<dim>::face_indices())
15112  {
15113  const typename Triangulation<dim, spacedim>::cell_iterator neighbor =
15114  cell->neighbor(n);
15115  if (neighbor.state() == IteratorState::valid)
15116  {
15117  ++n_neighbors;
15118  if (face_will_be_refined_by_neighbor(cell, n))
15119  ++count;
15120  }
15121  }
15122  // clear coarsen flags if either all existing neighbors will be
15123  // refined or all but one will be and the cell is in the interior
15124  // of the domain
15125  if (count == n_neighbors ||
15126  (count >= n_neighbors - 1 &&
15127  n_neighbors == GeometryInfo<dim>::faces_per_cell))
15128  {
15129  for (unsigned int c = 0; c < cell->n_children(); ++c)
15130  cell->child(c)->clear_coarsen_flag();
15131 
15132  for (const unsigned int face : GeometryInfo<dim>::face_indices())
15133  if (!cell->at_boundary(face) &&
15134  (!cell->neighbor(face)->is_active()) &&
15135  (cell_will_be_coarsened(cell->neighbor(face))))
15136  possibly_do_not_produce_unrefined_islands<dim, spacedim>(
15137  cell->neighbor(face));
15138  }
15139  }
15140 
15141 
15142  // see if the current cell needs to be refined to avoid unrefined
15143  // islands.
15144  //
15145  // there are sometimes chains of cells that induce refinement of
15146  // each other. to avoid running the loop in
15147  // prepare_coarsening_and_refinement over and over again for each
15148  // one of them, at least for the isotropic refinement case we seek
15149  // to flag neighboring elements as well as necessary. this takes
15150  // care of (slightly pathological) cases like
15151  // deal.II/mesh_smoothing_03
15152  template <int dim, int spacedim>
15153  void
15154  possibly_refine_unrefined_island(
15155  const typename Triangulation<dim, spacedim>::cell_iterator &cell,
15156  const bool allow_anisotropic_smoothing)
15157  {
15158  Assert(cell->is_active(), ExcInternalError());
15159  Assert(cell->refine_flag_set() == false, ExcInternalError());
15160 
15161 
15162  // now we provide two algorithms. the first one is the standard
15163  // one, coming from the time, where only isotropic refinement was
15164  // possible. it simply counts the neighbors that are or will be
15165  // refined and compares to the number of other ones. the second
15166  // one does this check independently for each direction: if all
15167  // neighbors in one direction (normally two, at the boundary only
15168  // one) are refined, the current cell is flagged to be refined in
15169  // an according direction.
15170 
15171  if (allow_anisotropic_smoothing == false)
15172  {
15173  // use first algorithm
15174  unsigned int refined_neighbors = 0, unrefined_neighbors = 0;
15175  for (const unsigned int face : GeometryInfo<dim>::face_indices())
15176  if (!cell->at_boundary(face))
15177  {
15178  if (face_will_be_refined_by_neighbor(cell, face))
15179  ++refined_neighbors;
15180  else
15181  ++unrefined_neighbors;
15182  }
15183 
15184  if (unrefined_neighbors < refined_neighbors)
15185  {
15186  cell->clear_coarsen_flag();
15187  cell->set_refine_flag();
15188 
15189  // ok, so now we have flagged this cell. if we know that
15190  // there were any unrefined neighbors at all, see if any
15191  // of those will have to be refined as well
15192  if (unrefined_neighbors > 0)
15193  for (const unsigned int face : GeometryInfo<dim>::face_indices())
15194  if (!cell->at_boundary(face) &&
15195  (face_will_be_refined_by_neighbor(cell, face) == false) &&
15196  (cell->neighbor(face)->has_children() == false) &&
15197  (cell->neighbor(face)->refine_flag_set() == false))
15198  possibly_refine_unrefined_island<dim, spacedim>(
15199  cell->neighbor(face), allow_anisotropic_smoothing);
15200  }
15201  }
15202  else
15203  {
15204  // variable to store the cell refine case needed to fulfill
15205  // all smoothing requirements
15206  RefinementCase<dim> smoothing_cell_refinement_case =
15208 
15209  // use second algorithm, do the check individually for each
15210  // direction
15211  for (unsigned int face_pair = 0;
15212  face_pair < GeometryInfo<dim>::faces_per_cell / 2;
15213  ++face_pair)
15214  {
15215  // variable to store the cell refine case needed to refine
15216  // at the current face pair in the same way as the
15217  // neighbors do...
15218  RefinementCase<dim> directional_cell_refinement_case =
15220 
15221  for (unsigned int face_index = 0; face_index < 2; ++face_index)
15222  {
15223  unsigned int face = 2 * face_pair + face_index;
15224  // variable to store the refine case (to come) of the
15225  // face under consideration
15226  RefinementCase<dim - 1> expected_face_ref_case =
15227  RefinementCase<dim - 1>::no_refinement;
15228 
15229  if (cell->neighbor(face).state() == IteratorState::valid)
15230  face_will_be_refined_by_neighbor<dim, spacedim>(
15231  cell, face, expected_face_ref_case);
15232  // now extract which refine case would be necessary to
15233  // achieve the same face refinement. set the
15234  // intersection with other requirements for the same
15235  // direction.
15236 
15237  // note: using the intersection is not an obvious
15238  // decision, we could also argue that it is more
15239  // natural to use the union. however, intersection is
15240  // the less aggressive tactic and favours a smaller
15241  // number of refined cells over an intensive
15242  // smoothing. this way we try not to lose too much of
15243  // the effort we put in anisotropic refinement
15244  // indicators due to overly aggressive smoothing...
15245  directional_cell_refinement_case =
15246  (directional_cell_refinement_case &
15249  expected_face_ref_case,
15250  face,
15251  cell->face_orientation(face),
15252  cell->face_flip(face),
15253  cell->face_rotation(face)));
15254  } // for both face indices
15255  // if both requirements sum up to something useful, add
15256  // this to the refine case for smoothing. note: if
15257  // directional_cell_refinement_case is isotropic still,
15258  // then something went wrong...
15259  Assert(directional_cell_refinement_case <
15261  ExcInternalError());
15262  smoothing_cell_refinement_case =
15263  smoothing_cell_refinement_case | directional_cell_refinement_case;
15264  } // for all face_pairs
15265  // no we collected contributions from all directions. combine
15266  // the new flags with the existing refine case, but only if
15267  // smoothing is required
15268  if (smoothing_cell_refinement_case)
15269  {
15270  cell->clear_coarsen_flag();
15271  cell->set_refine_flag(cell->refine_flag_set() |
15272  smoothing_cell_refinement_case);
15273  }
15274  }
15275  }
15276 } // namespace
15277 
15278 
15279 template <int dim, int spacedim>
15280 bool
15282 {
15283  // save the flags to determine whether something was changed in the
15284  // course of this function
15285  std::vector<bool> flags_before[2];
15286  save_coarsen_flags(flags_before[0]);
15287  save_refine_flags(flags_before[1]);
15288 
15289  // save the flags at the outset of each loop. we do so in order to
15290  // find out whether something was changed in the present loop, in
15291  // which case we would have to re-run the loop. the other
15292  // possibility to find this out would be to set a flag
15293  // @p{something_changed} to true each time we change something.
15294  // however, sometimes one change in one of the parts of the loop is
15295  // undone by another one, so we might end up in an endless loop. we
15296  // could be tempted to break this loop at an arbitrary number of
15297  // runs, but that would not be a clean solution, since we would
15298  // either have to 1/ break the loop too early, in which case the
15299  // promise that a second call to this function immediately after the
15300  // first one does not change anything, would be broken, or 2/ we do
15301  // as many loops as there are levels. we know that information is
15302  // transported over one level in each run of the loop, so this is
15303  // enough. Unfortunately, each loop is rather expensive, so we chose
15304  // the way presented here
15305  std::vector<bool> flags_before_loop[2] = {flags_before[0], flags_before[1]};
15306 
15307  // now for what is done in each loop: we have to fulfill several
15308  // tasks at the same time, namely several mesh smoothing algorithms
15309  // and mesh regularization, by which we mean that the next mesh
15310  // fulfills several requirements such as no double refinement at
15311  // each face or line, etc.
15312  //
15313  // since doing these things at once seems almost impossible (in the
15314  // first year of this library, they were done in two functions, one
15315  // for refinement and one for coarsening, and most things within
15316  // these were done at once, so the code was rather impossible to
15317  // join into this, only, function), we do them one after each
15318  // other. the order in which we do them is such that the important
15319  // tasks, namely regularization, are done last and the least
15320  // important things are done the first. the following order is
15321  // chosen:
15322  //
15323  // 0/ Only if coarsest_level_1 or patch_level_1 is set: clear all
15324  // coarsen flags on level 1 to avoid level 0 cells being created
15325  // by coarsening. As coarsen flags will never be added, this can
15326  // be done once and for all before the actual loop starts.
15327  //
15328  // 1/ do not coarsen a cell if 'most of the neighbors' will be
15329  // refined after the step. This is to prevent occurrence of
15330  // unrefined islands.
15331  //
15332  // 2/ eliminate refined islands in the interior and at the
15333  // boundary. since they don't do much harm besides increasing the
15334  // number of degrees of freedom, doing this has a rather low
15335  // priority.
15336  //
15337  // 3/ limit the level difference of neighboring cells at each
15338  // vertex.
15339  //
15340  // 4/ eliminate unrefined islands. this has higher priority since
15341  // this diminishes the approximation properties not only of the
15342  // unrefined island, but also of the surrounding patch.
15343  //
15344  // 5/ ensure patch level 1. Then the triangulation consists of
15345  // patches, i.e. of cells that are refined once. It follows that
15346  // if at least one of the children of a cell is or will be
15347  // refined than all children need to be refined. This step only
15348  // sets refinement flags and does not set coarsening flags. If
15349  // the patch_level_1 flag is set, then
15350  // eliminate_unrefined_islands, eliminate_refined_inner_islands
15351  // and eliminate_refined_boundary_islands will be fulfilled
15352  // automatically and do not need to be enforced separately.
15353  //
15354  // 6/ take care of the requirement that no double refinement is done
15355  // at each face
15356  //
15357  // 7/ take care that no double refinement is done at each line in 3d
15358  // or higher dimensions.
15359  //
15360  // 8/ make sure that all children of each cell are either flagged
15361  // for coarsening or none of the children is
15362  //
15363  // For some of these steps, it is known that they interact. Namely,
15364  // it is not possible to guarantee that after step 6 another step 5
15365  // would have no effect; the same holds for the opposite order and
15366  // also when taking into account step 7. however, it is important to
15367  // guarantee that step five or six do not undo something that step 5
15368  // did, and step 7 not something of step 6, otherwise the
15369  // requirements will not be satisfied even if the loop
15370  // terminates. this is accomplished by the fact that steps 5 and 6
15371  // only *add* refinement flags and delete coarsening flags
15372  // (therefore, step 6 can't undo something that step 4 already did),
15373  // and step 7 only deletes coarsening flags, never adds some. step 7
15374  // needs also take care that it won't tag cells for refinement for
15375  // which some neighbors are more refined or will be refined.
15376 
15377  //------------------------------------
15378  // STEP 0:
15379  // Only if coarsest_level_1 or patch_level_1 is set: clear all
15380  // coarsen flags on level 1 to avoid level 0 cells being created
15381  // by coarsening.
15382  if (((smooth_grid & coarsest_level_1) || (smooth_grid & patch_level_1)) &&
15383  n_levels() >= 2)
15384  {
15385  for (const auto &cell : active_cell_iterators_on_level(1))
15386  cell->clear_coarsen_flag();
15387  }
15388 
15389  bool mesh_changed_in_this_loop = false;
15390  do
15391  {
15392  //------------------------------------
15393  // STEP 1:
15394  // do not coarsen a cell if 'most of the neighbors' will be
15395  // refined after the step. This is to prevent the occurrence
15396  // of unrefined islands. If patch_level_1 is set, this will
15397  // be automatically fulfilled.
15398  if (smooth_grid & do_not_produce_unrefined_islands &&
15399  !(smooth_grid & patch_level_1))
15400  {
15401  for (const auto &cell : cell_iterators())
15402  {
15403  // only do something if this
15404  // cell will be coarsened
15405  if (!cell->is_active() && cell_will_be_coarsened(cell))
15406  possibly_do_not_produce_unrefined_islands<dim, spacedim>(cell);
15407  }
15408  }
15409 
15410 
15411  //------------------------------------
15412  // STEP 2:
15413  // eliminate refined islands in the interior and at the
15414  // boundary. since they don't do much harm besides increasing
15415  // the number of degrees of freedom, doing this has a rather
15416  // low priority. If patch_level_1 is set, this will be
15417  // automatically fulfilled.
15418  //
15419  // there is one corner case to consider: if this is a
15420  // distributed triangulation, there may be refined islands on
15421  // the boundary of which we own only part (e.g. a single cell
15422  // in the corner of a domain). the rest of the island is
15423  // ghost cells and it *looks* like the area around it
15424  // (artificial cells) are coarser but this is only because
15425  // they may actually be equally fine on other
15426  // processors. it's hard to detect this case but we can do
15427  // the following: only set coarsen flags to remove this
15428  // refined island if all cells we want to set flags on are
15429  // locally owned
15430  if (smooth_grid & (eliminate_refined_inner_islands |
15431  eliminate_refined_boundary_islands) &&
15432  !(smooth_grid & patch_level_1))
15433  {
15434  for (const auto &cell : cell_iterators())
15435  if (!cell->is_active() ||
15436  (cell->is_active() && cell->refine_flag_set() &&
15437  cell->is_locally_owned()))
15438  {
15439  // check whether all children are active, i.e. not
15440  // refined themselves. This is a precondition that the
15441  // children may be coarsened away. If the cell is only
15442  // flagged for refinement, then all future children
15443  // will be active
15444  bool all_children_active = true;
15445  if (!cell->is_active())
15446  for (unsigned int c = 0; c < cell->n_children(); ++c)
15447  if (!cell->child(c)->is_active() ||
15448  cell->child(c)->is_ghost() ||
15449  cell->child(c)->is_artificial())
15450  {
15451  all_children_active = false;
15452  break;
15453  }
15454 
15455  if (all_children_active)
15456  {
15457  // count number of refined and unrefined neighbors
15458  // of cell. neighbors on lower levels are counted
15459  // as unrefined since they can only get to the
15460  // same level as this cell by the next refinement
15461  // cycle
15462  unsigned int unrefined_neighbors = 0, total_neighbors = 0;
15463 
15464  // Keep track if this cell is at a periodic
15465  // boundary or not. TODO: We do not currently run
15466  // the algorithm for inner islands at a periodic
15467  // boundary (remains to be implemented), but we
15468  // also don't want to consider them
15469  // boundary_island cells as this can interfere
15470  // with 2:1 refinement across periodic faces.
15471  // Instead: just ignore those cells for this
15472  // smoothing operation below.
15473  bool at_periodic_boundary = false;
15474 
15475  for (const unsigned int n :
15477  {
15478  const cell_iterator neighbor = cell->neighbor(n);
15479  if (neighbor.state() == IteratorState::valid)
15480  {
15481  ++total_neighbors;
15482 
15483  if (!face_will_be_refined_by_neighbor(cell, n))
15484  ++unrefined_neighbors;
15485  }
15486  else if (cell->has_periodic_neighbor(n))
15487  {
15488  ++total_neighbors;
15489  at_periodic_boundary = true;
15490  }
15491  }
15492 
15493  // if all neighbors unrefined: mark this cell for
15494  // coarsening or don't refine if marked for that
15495  //
15496  // also do the distinction between the two
15497  // versions of the eliminate_refined_*_islands
15498  // flag
15499  //
15500  // the last check is whether there are any
15501  // neighbors at all. if not so, then we are (e.g.)
15502  // on the coarsest grid with one cell, for which,
15503  // of course, we do not remove the refine flag.
15504  if ((unrefined_neighbors == total_neighbors) &&
15505  ((!cell->at_boundary() &&
15506  (smooth_grid & eliminate_refined_inner_islands)) ||
15507  (cell->at_boundary() && !at_periodic_boundary &&
15508  (smooth_grid &
15509  eliminate_refined_boundary_islands))) &&
15510  (total_neighbors != 0))
15511  {
15512  if (!cell->is_active())
15513  for (unsigned int c = 0; c < cell->n_children(); ++c)
15514  {
15515  cell->child(c)->clear_refine_flag();
15516  cell->child(c)->set_coarsen_flag();
15517  }
15518  else
15519  cell->clear_refine_flag();
15520  }
15521  }
15522  }
15523  }
15524 
15525  //------------------------------------
15526  // STEP 3:
15527  // limit the level difference of neighboring cells at each
15528  // vertex.
15529  //
15530  // in case of anisotropic refinement this does not make
15531  // sense. as soon as one cell is anisotropically refined, an
15532  // Assertion is thrown. therefore we can ignore this problem
15533  // later on
15534  if (smooth_grid & limit_level_difference_at_vertices)
15535  {
15536  Assert(!anisotropic_refinement,
15537  ExcMessage("In case of anisotropic refinement the "
15538  "limit_level_difference_at_vertices flag for "
15539  "mesh smoothing must not be set!"));
15540 
15541  // store highest level one of the cells adjacent to a vertex
15542  // belongs to
15543  std::vector<int> vertex_level(vertices.size(), 0);
15544  for (const auto &cell : active_cell_iterators())
15545  {
15546  if (cell->refine_flag_set())
15547  for (const unsigned int vertex :
15549  vertex_level[cell->vertex_index(vertex)] =
15550  std::max(vertex_level[cell->vertex_index(vertex)],
15551  cell->level() + 1);
15552  else if (!cell->coarsen_flag_set())
15553  for (const unsigned int vertex :
15555  vertex_level[cell->vertex_index(vertex)] =
15556  std::max(vertex_level[cell->vertex_index(vertex)],
15557  cell->level());
15558  else
15559  {
15560  // if coarsen flag is set then tentatively assume
15561  // that the cell will be coarsened. this isn't
15562  // always true (the coarsen flag could be removed
15563  // again) and so we may make an error here
15564  Assert(cell->coarsen_flag_set(), ExcInternalError());
15565  for (const unsigned int vertex :
15567  vertex_level[cell->vertex_index(vertex)] =
15568  std::max(vertex_level[cell->vertex_index(vertex)],
15569  cell->level() - 1);
15570  }
15571  }
15572 
15573 
15574  // loop over all cells in reverse order. do so because we
15575  // can then update the vertex levels on the adjacent
15576  // vertices and maybe already flag additional cells in this
15577  // loop
15578  //
15579  // note that not only may we have to add additional
15580  // refinement flags, but we will also have to remove
15581  // coarsening flags on cells adjacent to vertices that will
15582  // see refinement
15583  for (active_cell_iterator cell = last_active(); cell != end(); --cell)
15584  if (cell->refine_flag_set() == false)
15585  {
15586  for (const unsigned int vertex :
15588  if (vertex_level[cell->vertex_index(vertex)] >=
15589  cell->level() + 1)
15590  {
15591  // remove coarsen flag...
15592  cell->clear_coarsen_flag();
15593 
15594  // ...and if necessary also refine the current
15595  // cell, at the same time updating the level
15596  // information about vertices
15597  if (vertex_level[cell->vertex_index(vertex)] >
15598  cell->level() + 1)
15599  {
15600  cell->set_refine_flag();
15601 
15602  for (const unsigned int v :
15604  vertex_level[cell->vertex_index(v)] =
15605  std::max(vertex_level[cell->vertex_index(v)],
15606  cell->level() + 1);
15607  }
15608 
15609  // continue and see whether we may, for example,
15610  // go into the inner'if'
15611  // above based on a
15612  // different vertex
15613  }
15614  }
15615  }
15616 
15617  //-----------------------------------
15618  // STEP 4:
15619  // eliminate unrefined islands. this has higher priority
15620  // since this diminishes the approximation properties not
15621  // only of the unrefined island, but also of the surrounding
15622  // patch.
15623  //
15624  // do the loop from finest to coarsest cells since we may
15625  // trigger a cascade by marking cells for refinement which
15626  // may trigger more cells further down below
15627  if (smooth_grid & eliminate_unrefined_islands)
15628  {
15629  for (active_cell_iterator cell = last_active(); cell != end(); --cell)
15630  // only do something if cell is not already flagged for
15631  // (isotropic) refinement
15632  if (cell->refine_flag_set() !=
15634  possibly_refine_unrefined_island<dim, spacedim>(
15635  cell, (smooth_grid & allow_anisotropic_smoothing) != 0);
15636  }
15637 
15638  //-------------------------------
15639  // STEP 5:
15640  // ensure patch level 1.
15641  //
15642  // Introduce some terminology:
15643  // - a cell that is refined
15644  // once is a patch of
15645  // level 1 simply called patch.
15646  // - a cell that is globally
15647  // refined twice is called
15648  // a patch of level 2.
15649  // - patch level n says that
15650  // the triangulation consists
15651  // of patches of level n.
15652  // This makes sense only
15653  // if the grid is already at
15654  // least n times globally
15655  // refined.
15656  //
15657  // E.g. from patch level 1 follows: if at least one of the
15658  // children of a cell is or will be refined than enforce all
15659  // children to be refined.
15660 
15661  // This step 4 only sets refinement flags and does not set
15662  // coarsening flags.
15663  if (smooth_grid & patch_level_1)
15664  {
15665  // An important assumption (A) is that before calling this
15666  // function the grid was already of patch level 1.
15667 
15668  // loop over all cells whose children are all active. (By
15669  // assumption (A) either all or none of the children are
15670  // active). If the refine flag of at least one of the
15671  // children is set then set_refine_flag and
15672  // clear_coarsen_flag of all children.
15673  for (const auto &cell : cell_iterators())
15674  if (!cell->is_active())
15675  {
15676  // ensure the invariant. we can then check whether all
15677  // of its children are further refined or not by
15678  // simply looking at the first child
15679  Assert(cell_is_patch_level_1(cell), ExcInternalError());
15680  if (cell->child(0)->has_children() == true)
15681  continue;
15682 
15683  // cell is found to be a patch. combine the refine
15684  // cases of all children
15685  RefinementCase<dim> combined_ref_case =
15687  for (unsigned int i = 0; i < cell->n_children(); ++i)
15688  combined_ref_case =
15689  combined_ref_case | cell->child(i)->refine_flag_set();
15690  if (combined_ref_case != RefinementCase<dim>::no_refinement)
15691  for (unsigned int i = 0; i < cell->n_children(); ++i)
15692  {
15693  cell_iterator child = cell->child(i);
15694 
15695  child->clear_coarsen_flag();
15696  child->set_refine_flag(combined_ref_case);
15697  }
15698  }
15699 
15700  // The code above dealt with the case where we may get a
15701  // non-patch_level_1 mesh from refinement. Now also deal
15702  // with the case where we could get such a mesh by
15703  // coarsening. Coarsen the children (and remove the
15704  // grandchildren) only if all cell->grandchild(i)
15705  // ->coarsen_flag_set() are set.
15706  //
15707  // for a case where this is a bit tricky, take a look at the
15708  // mesh_smoothing_0[12] testcases
15709  for (const auto &cell : cell_iterators())
15710  {
15711  // check if this cell has active grandchildren. note
15712  // that we know that it is patch_level_1, i.e. if one of
15713  // its children is active then so are all, and it isn't
15714  // going to have any grandchildren at all:
15715  if (cell->is_active() || cell->child(0)->is_active())
15716  continue;
15717 
15718  // cell is not active, and so are none of its
15719  // children. check the grandchildren. note that the
15720  // children are also patch_level_1, and so we only ever
15721  // need to check their first child
15722  const unsigned int n_children = cell->n_children();
15723  bool has_active_grandchildren = false;
15724 
15725  for (unsigned int i = 0; i < n_children; ++i)
15726  if (cell->child(i)->child(0)->is_active())
15727  {
15728  has_active_grandchildren = true;
15729  break;
15730  }
15731 
15732  if (has_active_grandchildren == false)
15733  continue;
15734 
15735 
15736  // ok, there are active grandchildren. see if either all
15737  // or none of them are flagged for coarsening
15738  unsigned int n_grandchildren = 0;
15739 
15740  // count all coarsen flags of the grandchildren.
15741  unsigned int n_coarsen_flags = 0;
15742 
15743  // cell is not a patch (of level 1) as it has a
15744  // grandchild. Is cell a patch of level 2?? Therefore:
15745  // find out whether all cell->child(i) are patches
15746  for (unsigned int c = 0; c < n_children; ++c)
15747  {
15748  // get at the child. by assumption (A), and the
15749  // check by which we got here, the child is not
15750  // active
15751  cell_iterator child = cell->child(c);
15752 
15753  const unsigned int nn_children = child->n_children();
15754  n_grandchildren += nn_children;
15755 
15756  // if child is found to be a patch of active cells
15757  // itself, then add up how many of its children are
15758  // supposed to be coarsened
15759  if (child->child(0)->is_active())
15760  for (unsigned int cc = 0; cc < nn_children; ++cc)
15761  if (child->child(cc)->coarsen_flag_set())
15762  ++n_coarsen_flags;
15763  }
15764 
15765  // if not all grandchildren are supposed to be coarsened
15766  // (e.g. because some simply don't have the flag set, or
15767  // because they are not active and therefore cannot
15768  // carry the flag), then remove the coarsen flag from
15769  // all of the active grandchildren. note that there may
15770  // be coarsen flags on the grandgrandchildren -- we
15771  // don't clear them here, but we'll get to them in later
15772  // iterations if necessary
15773  //
15774  // there is nothing we have to do if no coarsen flags
15775  // have been set at all
15776  if ((n_coarsen_flags != n_grandchildren) && (n_coarsen_flags > 0))
15777  for (unsigned int c = 0; c < n_children; ++c)
15778  {
15779  const cell_iterator child = cell->child(c);
15780  if (child->child(0)->is_active())
15781  for (unsigned int cc = 0; cc < child->n_children(); ++cc)
15782  child->child(cc)->clear_coarsen_flag();
15783  }
15784  }
15785  }
15786 
15787  //--------------------------------
15788  //
15789  // at the boundary we could end up with cells with negative
15790  // volume or at least with a part, that is negative, if the
15791  // cell is refined anisotropically. we have to check, whether
15792  // that can happen
15793  this->policy->prevent_distorted_boundary_cells(*this);
15794 
15795  //-------------------------------
15796  // STEP 6:
15797  // take care of the requirement that no
15798  // double refinement is done at each face
15799  //
15800  // in case of anisotropic refinement it is only likely, but
15801  // not sure, that the cells, which are more refined along a
15802  // certain face common to two cells are on a higher
15803  // level. therefore we cannot be sure, that the requirement
15804  // of no double refinement is fulfilled after a single pass
15805  // of the following actions. We could just wait for the next
15806  // global loop. when this function terminates, the
15807  // requirement will be fulfilled. However, it might be faster
15808  // to insert an inner loop here.
15809  bool changed = true;
15810  while (changed)
15811  {
15812  changed = false;
15813  active_cell_iterator cell = last_active(), endc = end();
15814 
15815  for (; cell != endc; --cell)
15816  if (cell->refine_flag_set())
15817  {
15818  // loop over neighbors of cell
15819  for (const auto i : cell->face_indices())
15820  {
15821  // only do something if the face is not at the
15822  // boundary and if the face will be refined with
15823  // the RefineCase currently flagged for
15824  const bool has_periodic_neighbor =
15825  cell->has_periodic_neighbor(i);
15826  const bool has_neighbor_or_periodic_neighbor =
15827  !cell->at_boundary(i) || has_periodic_neighbor;
15828  if (has_neighbor_or_periodic_neighbor &&
15830  cell->refine_flag_set(), i) !=
15832  {
15833  // 1) if the neighbor has children: nothing to
15834  // worry about. 2) if the neighbor is active
15835  // and a coarser one, ensure, that its
15836  // refine_flag is set 3) if the neighbor is
15837  // active and as refined along the face as our
15838  // current cell, make sure, that no
15839  // coarsen_flag is set. if we remove the
15840  // coarsen flag of our neighbor,
15841  // fix_coarsen_flags() makes sure, that the
15842  // mother cell will not be coarsened
15843  if (cell->neighbor_or_periodic_neighbor(i)->is_active())
15844  {
15845  if ((!has_periodic_neighbor &&
15846  cell->neighbor_is_coarser(i)) ||
15847  (has_periodic_neighbor &&
15848  cell->periodic_neighbor_is_coarser(i)))
15849  {
15850  if (cell->neighbor_or_periodic_neighbor(i)
15851  ->coarsen_flag_set())
15852  cell->neighbor_or_periodic_neighbor(i)
15853  ->clear_coarsen_flag();
15854  // we'll set the refine flag for this
15855  // neighbor below. we note, that we
15856  // have changed something by setting
15857  // the changed flag to true. We do not
15858  // need to do so, if we just removed
15859  // the coarsen flag, as the changed
15860  // flag only indicates the need to
15861  // re-run the inner loop. however, we
15862  // only loop over cells flagged for
15863  // refinement here, so nothing to
15864  // worry about if we remove coarsen
15865  // flags
15866 
15867  if (dim == 2)
15868  {
15869  if (smooth_grid &
15870  allow_anisotropic_smoothing)
15871  changed =
15872  has_periodic_neighbor ?
15873  cell->periodic_neighbor(i)
15874  ->flag_for_face_refinement(
15875  cell
15876  ->periodic_neighbor_of_coarser_periodic_neighbor(
15877  i)
15878  .first,
15880  cell->neighbor(i)
15881  ->flag_for_face_refinement(
15882  cell
15883  ->neighbor_of_coarser_neighbor(
15884  i)
15885  .first,
15887  else
15888  {
15889  if (!cell
15890  ->neighbor_or_periodic_neighbor(
15891  i)
15892  ->refine_flag_set())
15893  changed = true;
15894  cell->neighbor_or_periodic_neighbor(i)
15895  ->set_refine_flag();
15896  }
15897  }
15898  else // i.e. if (dim==3)
15899  {
15900  // ugly situations might arise here,
15901  // consider the following situation, which
15902  // shows neighboring cells at the common
15903  // face, where the upper right element is
15904  // coarser at the given face. Now the upper
15905  // child element of the lower left wants to
15906  // refine according to cut_z, such that
15907  // there is a 'horizontal' refinement of the
15908  // face marked with #####
15909  //
15910  // / /
15911  // / /
15912  // *---------------*
15913  // | |
15914  // | |
15915  // | |
15916  // | |
15917  // | |
15918  // | | /
15919  // | |/
15920  // *---------------*
15921  //
15922  //
15923  // *---------------*
15924  // /| /|
15925  // / | ##### / |
15926  // | |
15927  // *---------------*
15928  // /| /|
15929  // / | / |
15930  // | |
15931  // *---------------*
15932  // / /
15933  // / /
15934  //
15935  // this introduces too many hanging nodes
15936  // and the neighboring (coarser) cell (upper
15937  // right) has to be refined. If it is only
15938  // refined according to cut_z, then
15939  // everything is ok:
15940  //
15941  // / /
15942  // / /
15943  // *---------------*
15944  // | |
15945  // | | /
15946  // | |/
15947  // *---------------*
15948  // | |
15949  // | | /
15950  // | |/
15951  // *---------------*
15952  //
15953  //
15954  // *---------------*
15955  // /| /|
15956  // / *---------------*
15957  // /| /|
15958  // *---------------*
15959  // /| /|
15960  // / | / |
15961  // | |
15962  // *---------------*
15963  // / /
15964  // / /
15965  //
15966  // if however the cell wants to refine
15967  // itself in an other way, or if we disallow
15968  // anisotropic smoothing, then simply
15969  // refining the neighbor isotropically is
15970  // not going to work, since this introduces
15971  // a refinement of face ##### with both
15972  // cut_x and cut_y, which is not possible:
15973  //
15974  // / / /
15975  // / / /
15976  // *-------*-------*
15977  // | | |
15978  // | | | /
15979  // | | |/
15980  // *-------*-------*
15981  // | | |
15982  // | | | /
15983  // | | |/
15984  // *-------*-------*
15985  //
15986  //
15987  // *---------------*
15988  // /| /|
15989  // / *---------------*
15990  // /| /|
15991  // *---------------*
15992  // /| /|
15993  // / | / |
15994  // | |
15995  // *---------------*
15996  // / /
15997  // / /
15998  //
15999  // thus, in this case we also need to refine
16000  // our current cell in the new direction:
16001  //
16002  // / / /
16003  // / / /
16004  // *-------*-------*
16005  // | | |
16006  // | | | /
16007  // | | |/
16008  // *-------*-------*
16009  // | | |
16010  // | | | /
16011  // | | |/
16012  // *-------*-------*
16013  //
16014  //
16015  // *-------*-------*
16016  // /| /| /|
16017  // / *-------*-------*
16018  // /| /| /|
16019  // *-------*-------*
16020  // /| / /|
16021  // / | / |
16022  // | |
16023  // *---------------*
16024  // / /
16025  // / /
16026 
16027  std::pair<unsigned int, unsigned int>
16028  nb_indices =
16029  has_periodic_neighbor ?
16030  cell
16031  ->periodic_neighbor_of_coarser_periodic_neighbor(
16032  i) :
16033  cell->neighbor_of_coarser_neighbor(i);
16034  unsigned int refined_along_x = 0,
16035  refined_along_y = 0,
16036  to_be_refined_along_x = 0,
16037  to_be_refined_along_y = 0;
16038 
16039  const int this_face_index =
16040  cell->face_index(i);
16041 
16042  // step 1: detect, along which axis the face
16043  // is currently refined
16044 
16045  // first, we need an iterator pointing to
16046  // the parent face. This requires a slight
16047  // detour in case the neighbor is behind a
16048  // periodic face.
16049  const auto parent_face = [&]() {
16050  if (has_periodic_neighbor)
16051  {
16052  const auto neighbor =
16053  cell->periodic_neighbor(i);
16054  const auto parent_face_no =
16055  neighbor
16056  ->periodic_neighbor_of_periodic_neighbor(
16057  nb_indices.first);
16058  auto parent =
16059  neighbor->periodic_neighbor(
16060  nb_indices.first);
16061  return parent->face(parent_face_no);
16062  }
16063  else
16064  return cell->neighbor(i)->face(
16065  nb_indices.first);
16066  }();
16067 
16068  if ((this_face_index ==
16069  parent_face->child_index(0)) ||
16070  (this_face_index ==
16071  parent_face->child_index(1)))
16072  {
16073  // this might be an
16074  // anisotropic child. get the
16075  // face refine case of the
16076  // neighbors face and count
16077  // refinements in x and y
16078  // direction.
16079  RefinementCase<dim - 1> frc =
16080  parent_face->refinement_case();
16081  if (frc & RefinementCase<dim>::cut_x)
16082  ++refined_along_x;
16083  if (frc & RefinementCase<dim>::cut_y)
16084  ++refined_along_y;
16085  }
16086  else
16087  // this has to be an isotropic
16088  // child
16089  {
16090  ++refined_along_x;
16091  ++refined_along_y;
16092  }
16093  // step 2: detect, along which axis the face
16094  // has to be refined given the current
16095  // refine flag
16096  RefinementCase<dim - 1> flagged_frc =
16098  cell->refine_flag_set(),
16099  i,
16100  cell->face_orientation(i),
16101  cell->face_flip(i),
16102  cell->face_rotation(i));
16103  if (flagged_frc &
16105  ++to_be_refined_along_x;
16106  if (flagged_frc &
16108  ++to_be_refined_along_y;
16109 
16110  // step 3: set the refine flag of the
16111  // (coarser and active) neighbor.
16112  if ((smooth_grid &
16113  allow_anisotropic_smoothing) ||
16114  cell->neighbor_or_periodic_neighbor(i)
16115  ->refine_flag_set())
16116  {
16117  if (refined_along_x +
16118  to_be_refined_along_x >
16119  1)
16120  changed |=
16121  cell
16122  ->neighbor_or_periodic_neighbor(i)
16123  ->flag_for_face_refinement(
16124  nb_indices.first,
16125  RefinementCase<dim -
16126  1>::cut_axis(0));
16127  if (refined_along_y +
16128  to_be_refined_along_y >
16129  1)
16130  changed |=
16131  cell
16132  ->neighbor_or_periodic_neighbor(i)
16133  ->flag_for_face_refinement(
16134  nb_indices.first,
16135  RefinementCase<dim -
16136  1>::cut_axis(1));
16137  }
16138  else
16139  {
16140  if (cell
16141  ->neighbor_or_periodic_neighbor(i)
16142  ->refine_flag_set() !=
16144  dim>::isotropic_refinement)
16145  changed = true;
16146  cell->neighbor_or_periodic_neighbor(i)
16147  ->set_refine_flag();
16148  }
16149 
16150  // step 4: if necessary (see above) add to
16151  // the refine flag of the current cell
16152  cell_iterator nb =
16153  cell->neighbor_or_periodic_neighbor(i);
16154  RefinementCase<dim - 1> nb_frc =
16156  nb->refine_flag_set(),
16157  nb_indices.first,
16158  nb->face_orientation(nb_indices.first),
16159  nb->face_flip(nb_indices.first),
16160  nb->face_rotation(nb_indices.first));
16161  if ((nb_frc & RefinementCase<dim>::cut_x) &&
16162  !((refined_along_x != 0u) ||
16163  (to_be_refined_along_x != 0u)))
16164  changed |= cell->flag_for_face_refinement(
16165  i,
16167  if ((nb_frc & RefinementCase<dim>::cut_y) &&
16168  !((refined_along_y != 0u) ||
16169  (to_be_refined_along_y != 0u)))
16170  changed |= cell->flag_for_face_refinement(
16171  i,
16173  }
16174  } // if neighbor is coarser
16175  else // -> now the neighbor is not coarser
16176  {
16177  cell->neighbor_or_periodic_neighbor(i)
16178  ->clear_coarsen_flag();
16179  const unsigned int nb_nb =
16180  has_periodic_neighbor ?
16181  cell
16182  ->periodic_neighbor_of_periodic_neighbor(
16183  i) :
16184  cell->neighbor_of_neighbor(i);
16185  const cell_iterator neighbor =
16186  cell->neighbor_or_periodic_neighbor(i);
16187  RefinementCase<dim - 1> face_ref_case =
16189  neighbor->refine_flag_set(),
16190  nb_nb,
16191  neighbor->face_orientation(nb_nb),
16192  neighbor->face_flip(nb_nb),
16193  neighbor->face_rotation(nb_nb));
16194  RefinementCase<dim - 1> needed_face_ref_case =
16196  cell->refine_flag_set(),
16197  i,
16198  cell->face_orientation(i),
16199  cell->face_flip(i),
16200  cell->face_rotation(i));
16201  // if the neighbor wants to refine the
16202  // face with cut_x and we want cut_y
16203  // or vice versa, we have to refine
16204  // isotropically at the given face
16205  if ((face_ref_case ==
16207  needed_face_ref_case ==
16209  (face_ref_case ==
16211  needed_face_ref_case ==
16213  {
16214  changed = cell->flag_for_face_refinement(
16215  i, face_ref_case);
16216  neighbor->flag_for_face_refinement(
16217  nb_nb, needed_face_ref_case);
16218  }
16219  }
16220  }
16221  else //-> the neighbor is not active
16222  {
16223  RefinementCase<dim - 1>
16224  face_ref_case = cell->face(i)->refinement_case(),
16225  needed_face_ref_case =
16227  cell->refine_flag_set(),
16228  i,
16229  cell->face_orientation(i),
16230  cell->face_flip(i),
16231  cell->face_rotation(i));
16232  // if the face is refined with cut_x and
16233  // we want cut_y or vice versa, we have to
16234  // refine isotropically at the given face
16235  if ((face_ref_case == RefinementCase<dim>::cut_x &&
16236  needed_face_ref_case ==
16238  (face_ref_case == RefinementCase<dim>::cut_y &&
16239  needed_face_ref_case ==
16241  changed =
16242  cell->flag_for_face_refinement(i,
16243  face_ref_case);
16244  }
16245  }
16246  }
16247  }
16248  }
16249 
16250  //------------------------------------
16251  // STEP 7:
16252  // take care that no double refinement
16253  // is done at each line in 3d or higher
16254  // dimensions.
16255  this->policy->prepare_refinement_dim_dependent(*this);
16256 
16257  //------------------------------------
16258  // STEP 8:
16259  // make sure that all children of each
16260  // cell are either flagged for coarsening
16261  // or none of the children is
16262  fix_coarsen_flags();
16263  // get the refinement and coarsening
16264  // flags
16265  std::vector<bool> flags_after_loop[2];
16266  save_coarsen_flags(flags_after_loop[0]);
16267  save_refine_flags(flags_after_loop[1]);
16268 
16269  // find out whether something was
16270  // changed in this loop
16271  mesh_changed_in_this_loop =
16272  ((flags_before_loop[0] != flags_after_loop[0]) ||
16273  (flags_before_loop[1] != flags_after_loop[1]));
16274 
16275  // set the flags for the next loop
16276  // already
16277  flags_before_loop[0].swap(flags_after_loop[0]);
16278  flags_before_loop[1].swap(flags_after_loop[1]);
16279  }
16280  while (mesh_changed_in_this_loop);
16281 
16282 
16283  // find out whether something was really changed in this
16284  // function. Note that @p{flags_before_loop} represents the state
16285  // after the last loop, i.e. the present state
16286  return ((flags_before[0] != flags_before_loop[0]) ||
16287  (flags_before[1] != flags_before_loop[1]));
16288 }
16289 
16290 
16291 
16292 template <int dim, int spacedim>
16293 void
16295  const unsigned int magic_number1,
16296  const std::vector<bool> &v,
16297  const unsigned int magic_number2,
16298  std::ostream & out)
16299 {
16300  const unsigned int N = v.size();
16301  unsigned char * flags = new unsigned char[N / 8 + 1];
16302  for (unsigned int i = 0; i < N / 8 + 1; ++i)
16303  flags[i] = 0;
16304 
16305  for (unsigned int position = 0; position < N; ++position)
16306  flags[position / 8] |= (v[position] ? (1 << (position % 8)) : 0);
16307 
16308  AssertThrow(out.fail() == false, ExcIO());
16309 
16310  // format:
16311  // 0. magic number
16312  // 1. number of flags
16313  // 2. the flags
16314  // 3. magic number
16315  out << magic_number1 << ' ' << N << std::endl;
16316  for (unsigned int i = 0; i < N / 8 + 1; ++i)
16317  out << static_cast<unsigned int>(flags[i]) << ' ';
16318 
16319  out << std::endl << magic_number2 << std::endl;
16320 
16321  delete[] flags;
16322 
16323  AssertThrow(out.fail() == false, ExcIO());
16324 }
16325 
16326 
16327 template <int dim, int spacedim>
16328 void
16329 Triangulation<dim, spacedim>::read_bool_vector(const unsigned int magic_number1,
16330  std::vector<bool> &v,
16331  const unsigned int magic_number2,
16332  std::istream & in)
16333 {
16334  AssertThrow(in.fail() == false, ExcIO());
16335 
16336  unsigned int magic_number;
16337  in >> magic_number;
16338  AssertThrow(magic_number == magic_number1, ExcGridReadError());
16339 
16340  unsigned int N;
16341  in >> N;
16342  v.resize(N);
16343 
16344  unsigned char * flags = new unsigned char[N / 8 + 1];
16345  unsigned short int tmp;
16346  for (unsigned int i = 0; i < N / 8 + 1; ++i)
16347  {
16348  in >> tmp;
16349  flags[i] = tmp;
16350  }
16351 
16352  for (unsigned int position = 0; position != N; ++position)
16353  v[position] = ((flags[position / 8] & (1 << (position % 8))) != 0);
16354 
16355  in >> magic_number;
16356  AssertThrow(magic_number == magic_number2, ExcGridReadError());
16357 
16358  delete[] flags;
16359 
16360  AssertThrow(in.fail() == false, ExcIO());
16361 }
16362 
16363 
16364 
16365 template <int dim, int spacedim>
16366 std::size_t
16368 {
16369  std::size_t mem = 0;
16371  for (const auto &level : levels)
16374  mem += MemoryConsumption::memory_consumption(vertices_used);
16375  mem += sizeof(manifolds);
16376  mem += sizeof(smooth_grid);
16377  mem += MemoryConsumption::memory_consumption(number_cache);
16378  mem += sizeof(faces);
16379  if (faces)
16381 
16382  return mem;
16383 }
16384 
16385 
16386 
16387 template <int dim, int spacedim>
16389  default;
16390 
16391 
16392 // explicit instantiations
16393 #include "tria.inst"
16394 
Definition: cell_id.h:71
ArrayView< const std::uint8_t > get_child_indices() const
Definition: cell_id.h:410
types::coarse_cell_id get_coarse_cell_id() const
Definition: cell_id.h:402
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const =0
Definition: point.h:111
unsigned char compute_orientation(const std::array< T, N > &vertices_0, const std::array< T, N > &vertices_1) const
Subscriptor & operator=(const Subscriptor &)
Definition: subscriptor.h:291
Definition: tensor.h:503
constexpr void clear()
void join() const
virtual types::global_cell_index n_global_active_cells() const
virtual std::vector< types::boundary_id > get_boundary_ids() const
virtual const MeshSmoothing & get_mesh_smoothing() const
const std::vector< bool > & get_used_vertices() const
quad_iterator begin_quad(const unsigned int level=0) const
typename IteratorSelector::raw_line_iterator raw_line_iterator
Definition: tria.h:3795
active_vertex_iterator begin_active_vertex() const
virtual MPI_Comm get_communicator() const
void load_user_indices_quad(const std::vector< unsigned int > &v)
unsigned int n_quads() const
void load_user_indices(const std::vector< unsigned int > &v)
std::vector< bool > vertices_used
Definition: tria.h:4172
virtual void clear()
bool anisotropic_refinement
Definition: tria.h:4184
active_quad_iterator begin_active_quad(const unsigned int level=0) const
bool get_anisotropic_refinement_flag() const
virtual void create_triangulation(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
virtual void copy_triangulation(const Triangulation< dim, spacedim > &other_tria)
virtual types::coarse_cell_id n_global_coarse_cells() const
std::unique_ptr< std::map< unsigned int, types::manifold_id > > vertex_to_manifold_id_map_1d
Definition: tria.h:4242
void save_user_pointers_quad(std::vector< void * > &v) const
void save_user_flags_hex(std::ostream &out) const
void clear_user_flags_quad()
unsigned int n_faces() const
active_hex_iterator begin_active_hex(const unsigned int level=0) const
static void read_bool_vector(const unsigned int magic_number1, std::vector< bool > &v, const unsigned int magic_number2, std::istream &in)
bool all_reference_cells_are_hyper_cube() const
void load_user_flags_line(std::istream &in)
void clear_user_data()
raw_hex_iterator begin_raw_hex(const unsigned int level=0) const
void save_user_flags_line(std::ostream &out) const
active_cell_iterator last_active() const
void reset_global_cell_indices()
face_iterator end_face() const
void reset_active_cell_indices()
cell_iterator create_cell_iterator(const CellId &cell_id) const
cell_iterator begin(const unsigned int level=0) const
std::map< std::pair< cell_iterator, unsigned int >, std::pair< std::pair< cell_iterator, unsigned int >, std::bitset< 3 > > > periodic_face_map
Definition: tria.h:3775
void fix_coarsen_flags()
void save_user_pointers_line(std::vector< void * > &v) const
void load_refine_flags(std::istream &in)
void save_user_indices_line(std::vector< unsigned int > &v) const
raw_cell_iterator begin_raw(const unsigned int level=0) const
unsigned int n_lines() const
virtual void set_mesh_smoothing(const MeshSmoothing mesh_smoothing)
unsigned int n_raw_lines() const
virtual std::size_t memory_consumption() const
std::vector< Point< spacedim > > vertices
Definition: tria.h:4167
Triangulation & operator=(Triangulation< dim, spacedim > &&tria) noexcept
raw_quad_iterator begin_raw_quad(const unsigned int level=0) const
virtual types::subdomain_id locally_owned_subdomain() const
unsigned int n_raw_faces() const
unsigned int n_active_faces() const
const bool check_for_distorted_cells
Definition: tria.h:4191
raw_cell_iterator end_raw(const unsigned int level) const
line_iterator end_line() const
std::unique_ptr< std::map< unsigned int, types::boundary_id > > vertex_to_boundary_id_map_1d
Definition: tria.h:4219
void load_user_flags_quad(std::istream &in)
unsigned int n_active_cells() const
virtual void update_reference_cells()
std::vector< ReferenceCell > reference_cells
Definition: tria.h:3706
void update_periodic_face_map()
void clear_despite_subscriptions()
void coarsen_global(const unsigned int times=1)
Triangulation(const MeshSmoothing smooth_grid=none, const bool check_for_distorted_cells=false)
void save_user_flags(std::ostream &out) const
void refine_global(const unsigned int times=1)
void load_user_flags_hex(std::istream &in)
void load_user_pointers_quad(const std::vector< void * > &v)
std::unique_ptr<::internal::TriangulationImplementation::TriaFaces > faces
Definition: tria.h:4161
virtual void add_periodicity(const std::vector< GridTools::PeriodicFacePair< cell_iterator >> &)
unsigned int n_used_vertices() const
void reset_cell_vertex_indices_cache()
unsigned int n_active_lines() const
void load_user_indices_line(const std::vector< unsigned int > &v)
void clear_user_flags_hex()
void save_user_pointers_hex(std::vector< void * > &v) const
void load_user_pointers(const std::vector< void * > &v)
::internal::TriangulationImplementation::NumberCache< dim > number_cache
Definition: tria.h:4202
void save_user_indices_hex(std::vector< unsigned int > &v) const
DistortedCellList execute_refinement()
active_line_iterator begin_active_line(const unsigned int level=0) const
void save_user_indices_quad(std::vector< unsigned int > &v) const
void load_user_pointers_hex(const std::vector< void * > &v)
cell_iterator end() const
virtual bool has_hanging_nodes() const
std::vector< GridTools::PeriodicFacePair< cell_iterator > > periodic_face_pairs_level_0
Definition: tria.h:3767
unsigned int n_raw_cells(const unsigned int level) const
void load_coarsen_flags(std::istream &out)
quad_iterator end_quad() const
line_iterator begin_line(const unsigned int level=0) const
unsigned int max_adjacent_cells() const
vertex_iterator begin_vertex() const
void clear_user_flags()
unsigned int n_hexs() const
vertex_iterator end_vertex() const
void load_user_pointers_line(const std::vector< void * > &v)
hex_iterator end_hex() const
hex_iterator begin_hex(const unsigned int level=0) const
virtual void execute_coarsening_and_refinement()
active_cell_iterator end_active(const unsigned int level) const
bool is_mixed_mesh() const
cell_iterator last() const
unsigned int n_active_quads() const
void load_user_indices_hex(const std::vector< unsigned int > &v)
virtual void create_triangulation_compatibility(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
unsigned int n_raw_quads() const
void save_user_pointers(std::vector< void * > &v) const
face_iterator begin_face() const
unsigned int n_cells() const
virtual bool prepare_coarsening_and_refinement()
const std::map< std::pair< cell_iterator, unsigned int >, std::pair< std::pair< cell_iterator, unsigned int >, std::bitset< 3 > > > & get_periodic_face_map() const
std::map< types::manifold_id, std::unique_ptr< const Manifold< dim, spacedim > > > manifolds
Definition: tria.h:4179
MeshSmoothing smooth_grid
Definition: tria.h:3700
void save_refine_flags(std::ostream &out) const
std::unique_ptr< ::internal::TriangulationImplementation::Policy< dim, spacedim > > policy
Definition: tria.h:3758
Triangulation< dim, spacedim > & get_triangulation()
void save_user_flags_quad(std::ostream &out) const
Signals signals
Definition: tria.h:2448
virtual ~Triangulation() override
unsigned int n_vertices() const
void save_user_indices(std::vector< unsigned int > &v) const
bool all_reference_cells_are_simplex() const
std::vector< std::unique_ptr<::internal::TriangulationImplementation::TriaLevel > > levels
Definition: tria.h:4153
unsigned int n_raw_hexs(const unsigned int level) const
void set_all_refine_flags()
unsigned int n_active_hexs() const
void load_user_flags(std::istream &in)
void reset_policy()
const std::vector< ReferenceCell > & get_reference_cells() const
void save_coarsen_flags(std::ostream &out) const
active_face_iterator begin_active_face() const
void clear_user_flags_line()
raw_line_iterator begin_raw_line(const unsigned int level=0) const
static void write_bool_vector(const unsigned int magic_number1, const std::vector< bool > &v, const unsigned int magic_number2, std::ostream &out)
void flip_all_direction_flags()
active_cell_iterator begin_active(const unsigned int level=0) const
void execute_coarsening()
void prevent_distorted_boundary_cells(Triangulation< dim, spacedim > &triangulation) override
Definition: tria.cc:1683
void prepare_refinement_dim_dependent(Triangulation< dim, spacedim > &triangulation) override
Definition: tria.cc:1690
void delete_children(Triangulation< dim, spacedim > &tria, typename Triangulation< dim, spacedim >::cell_iterator &cell, std::vector< unsigned int > &line_cell_count, std::vector< unsigned int > &quad_cell_count) override
Definition: tria.cc:1666
void update_neighbors(Triangulation< dim, spacedim > &tria) override
Definition: tria.cc:1660
Triangulation< dim, spacedim >::DistortedCellList execute_refinement(Triangulation< dim, spacedim > &triangulation, const bool check_for_distorted_cells) override
Definition: tria.cc:1676
bool coarsening_allowed(const typename Triangulation< dim, spacedim >::cell_iterator &cell) override
Definition: tria.cc:1697
std::unique_ptr< Policy< dim, spacedim > > clone() override
Definition: tria.cc:1705
virtual std::unique_ptr< Policy< dim, spacedim > > clone()=0
virtual void update_neighbors(Triangulation< dim, spacedim > &tria)=0
virtual void prepare_refinement_dim_dependent(Triangulation< dim, spacedim > &triangulation)=0
virtual void prevent_distorted_boundary_cells(Triangulation< dim, spacedim > &triangulation)=0
virtual bool coarsening_allowed(const typename Triangulation< dim, spacedim >::cell_iterator &cell)=0
virtual void delete_children(Triangulation< dim, spacedim > &triangulation, typename Triangulation< dim, spacedim >::cell_iterator &cell, std::vector< unsigned int > &line_cell_count, std::vector< unsigned int > &quad_cell_count)=0
virtual Triangulation< dim, spacedim >::DistortedCellList execute_refinement(Triangulation< dim, spacedim > &triangulation, const bool check_for_distorted_cells)=0
std::vector<::ReferenceCell > quad_reference_cell
Definition: tria_faces.h:80
std::vector< unsigned char > quads_line_orientations
Definition: tria_faces.h:73
std::vector<::ReferenceCell > reference_cell
Definition: tria_levels.h:225
std::vector< std::pair< int, int > > neighbors
Definition: tria_levels.h:148
std::vector< types::global_cell_index > global_active_cell_indices
Definition: tria_levels.h:108
std::vector< types::global_cell_index > global_level_cell_indices
Definition: tria_levels.h:113
std::vector< unsigned char > face_orientations
Definition: tria_levels.h:218
std::vector< types::subdomain_id > level_subdomain_ids
Definition: tria_levels.h:167
std::vector< std::uint8_t > refine_flags
Definition: tria_levels.h:89
std::vector< types::subdomain_id > subdomain_ids
Definition: tria_levels.h:158
std::vector< unsigned int > active_cell_indices
Definition: tria_levels.h:103
std::vector< types::manifold_id > manifold_id
Definition: tria_objects.h:185
std::vector< BoundaryOrMaterialId > boundary_or_material_id
Definition: tria_objects.h:179
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:442
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:443
Point< 3 > vertices[4]
Point< 2 > second
Definition: grid_out.cc:4604
Point< 2 > first
Definition: grid_out.cc:4603
unsigned int level
Definition: grid_out.cc:4606
AdjacentCell adjacent_cells[2]
Definition: grid_tools.cc:1213
unsigned int vertex_indices[2]
Definition: grid_tools.cc:1293
unsigned int cell_index
Definition: grid_tools.cc:1129
IteratorRange< active_cell_iterator > active_cell_iterators() const
IteratorRange< active_face_iterator > active_face_iterators() const
IteratorRange< active_cell_iterator > active_cell_iterators_on_level(const unsigned int level) const
IteratorRange< cell_iterator > cell_iterators() const
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
static ::ExceptionBase & ExcInteriorLineCantBeBoundary(int arg1, int arg2, types::boundary_id arg3)
static ::ExceptionBase & ExcGridHasInvalidCell(int arg1)
static ::ExceptionBase & ExcInternalError()
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:578
static ::ExceptionBase & ExcInteriorQuadCantBeBoundary(int arg1, int arg2, int arg3, int arg4, types::boundary_id arg5)
static ::ExceptionBase & ExcMultiplySetLineInfoOfLine(int arg1, int arg2)
#define Assert(cond, exc)
Definition: exceptions.h:1473
std::string to_string(const T &t)
Definition: patterns.h:2403
static ::ExceptionBase & ExcInconsistentLineInfoOfLine(int arg1, int arg2, std::string arg3)
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcMemoryInexact(int arg1, int arg2)
static ::ExceptionBase & ExcCellHasNegativeMeasure(int arg1)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
static ::ExceptionBase & ExcInconsistentQuadInfoOfQuad(int arg1, int arg2, int arg3, int arg4, std::string arg5)
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:532
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1667
static ::ExceptionBase & ExcInternalErrorOnCell(int arg1)
static ::ExceptionBase & ExcQuadInexistant(int arg1, int arg2, int arg3, int arg4)
#define AssertNothrow(cond, exc)
Definition: exceptions.h:1536
#define AssertIndexRange(index, range)
Definition: exceptions.h:1732
static ::ExceptionBase & ExcInvalidVertexIndex(int arg1, int arg2, int arg3)
static ::ExceptionBase & ExcIO()
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:555
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:509
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcLineInexistant(int arg1, int arg2)
static ::ExceptionBase & ExcFacesHaveNoLevel()
#define DeclException5( Exception5, type1, type2, type3, type4, type5, outsequence)
Definition: exceptions.h:604
#define AssertThrow(cond, exc)
Definition: exceptions.h:1583
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
Definition: tria.h:1355
void loop(ITERATOR begin, typename identity< ITERATOR >::type end, DOFINFO &dinfo, INFOBOX &info, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker, const std::function< void(DOFINFO &, DOFINFO &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, ASSEMBLER &assembler, const LoopControl &lctrl=LoopControl())
Definition: loop.h:439
virtual std::vector< types::manifold_id > get_manifold_ids() const
void set_all_manifold_ids_on_boundary(const types::manifold_id number)
void reset_manifold(const types::manifold_id manifold_number)
void set_manifold(const types::manifold_id number, const Manifold< dim, spacedim > &manifold_object)
const Manifold< dim, spacedim > & get_manifold(const types::manifold_id number) const
void reset_all_manifolds()
void set_all_manifold_ids(const types::manifold_id number)
Task< RT > new_task(const std::function< RT()> &function)
#define AssertIsNotUsed(obj)
Definition: exceptions.h:1767
const unsigned int mn_tria_refine_flags_end
Definition: magic_numbers.h:30
const unsigned int mn_tria_coarsen_flags_end
Definition: magic_numbers.h:32
const unsigned int mn_tria_refine_flags_begin
Definition: magic_numbers.h:29
const unsigned int mn_tria_hex_user_flags_end
Definition: magic_numbers.h:38
const unsigned int mn_tria_line_user_flags_begin
Definition: magic_numbers.h:33
const unsigned int mn_tria_line_user_flags_end
Definition: magic_numbers.h:34
const unsigned int mn_tria_quad_user_flags_end
Definition: magic_numbers.h:36
const unsigned int mn_tria_coarsen_flags_begin
Definition: magic_numbers.h:31
const unsigned int mn_tria_hex_user_flags_begin
Definition: magic_numbers.h:37
const unsigned int mn_tria_quad_user_flags_begin
Definition: magic_numbers.h:35
const Mapping< dim, spacedim > & get_default_linear_mapping(const Triangulation< dim, spacedim > &triangulation)
Definition: mapping.cc:260
Expression fabs(const Expression &x)
void create_triangulation(Triangulation< dim, dim > &tria, const AdditionalData &additional_data=AdditionalData())
double cell_measure(const std::vector< Point< dim >> &all_vertices, const unsigned int(&vertex_indices)[GeometryInfo< dim >::vertices_per_cell])
@ valid
Iterator points to a valid object.
static const char N
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
void swap(MemorySpaceData< Number, MemorySpace > &, MemorySpaceData< Number, MemorySpace > &)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
constexpr const ReferenceCell Tetrahedron
constexpr const ReferenceCell Quadrilateral
constexpr const ReferenceCell Invalid
constexpr const ReferenceCell Triangle
constexpr const ReferenceCell Hexahedron
constexpr const ReferenceCell Line
VectorType::value_type * begin(VectorType &V)
VectorType::value_type * end(VectorType &V)
bool get_bit(const unsigned char number, const unsigned int n)
Definition: utilities.h:1707
Iterator lower_bound(Iterator first, Iterator last, const T &val)
Definition: utilities.h:1153
Point< 1 > transform_real_to_unit_cell(const std::array< Point< spacedim >, GeometryInfo< 1 >::vertices_per_cell > &vertices, const Point< spacedim > &p)
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 3 > &c)
Definition: tria.cc:13764
unsigned int n_active_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
Definition: tria.cc:13741
const Manifold< dim, spacedim > & get_default_flat_manifold()
Definition: tria.cc:11131
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
Definition: tria.cc:13734
void reserve_space(TriaFaces &tria_faces, const unsigned int new_quads_in_pairs, const unsigned int new_quads_single)
Definition: tria.cc:1119
void reserve_space(TriaObjects &tria_objects, const unsigned int new_objects_in_pairs, const unsigned int new_objects_single=0)
Definition: tria.cc:1352
void monitor_memory(const TriaObjects &tria_object, const unsigned int)
Definition: tria.cc:1540
unsigned int n_active_cells(const internal::TriangulationImplementation::NumberCache< 3 > &c)
Definition: tria.cc:13771
void monitor_memory(const TriaLevel &tria_level, const unsigned int true_dimension)
Definition: tria.cc:1322
const types::boundary_id internal_face_boundary_id
Definition: types.h:260
const types::subdomain_id invalid_subdomain_id
Definition: types.h:281
static const unsigned int invalid_unsigned_int
Definition: types.h:201
const types::manifold_id flat_manifold_id
Definition: types.h:269
const types::global_dof_index invalid_dof_index
Definition: types.h:216
unsigned int manifold_id
Definition: types.h:141
global_cell_index coarse_cell_id
Definition: types.h:114
unsigned int subdomain_id
Definition: types.h:43
unsigned int global_cell_index
Definition: types.h:105
unsigned int boundary_id
Definition: types.h:129
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
static RefinementCase< dim > min_cell_refinement_case_for_face_refinement(const RefinementCase< dim - 1 > &face_refinement_case, const unsigned int face_no, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static unsigned int child_cell_on_face(const RefinementCase< dim > &ref_case, const unsigned int face, const unsigned int subface, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false, const RefinementCase< dim - 1 > &face_refinement_case=RefinementCase< dim - 1 >::isotropic_refinement)
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
static void alternating_form_at_vertices(const Point< spacedim >(&vertices)[vertices_per_cell], Tensor< spacedim - dim, spacedim >(&forms)[vertices_per_cell])
static RefinementCase< dim - 1 > face_refinement_case(const RefinementCase< dim > &cell_refinement_case, const unsigned int face_no, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
std::vector< CellData< 2 > > boundary_quads
bool check_consistency(const unsigned int dim) const
std::vector< CellData< 1 > > boundary_lines
std::vector< std::vector< CellData< dim > > > cell_infos
std::vector<::CellData< dim > > coarse_cells
std::vector< Point< spacedim > > coarse_cell_vertices
virtual ~DistortedCellList() noexcept override
std::list< typename Triangulation< dim, spacedim >::cell_iterator > distorted_cells
Definition: tria.h:1536
static Triangulation< dim, spacedim >::DistortedCellList execute_refinement(Triangulation< dim, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:11092
static void update_neighbors(Triangulation< 1, spacedim > &)
Definition: tria.cc:11007
static bool coarsening_allowed(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
Definition: tria.cc:11118
static void update_neighbors(Triangulation< dim, spacedim > &triangulation)
Definition: tria.cc:11011
static void delete_children(Triangulation< dim, spacedim > &triangulation, typename Triangulation< dim, spacedim >::cell_iterator &cell, std::vector< unsigned int > &line_cell_count, std::vector< unsigned int > &quad_cell_count)
Definition: tria.cc:11077
static void prepare_refinement_dim_dependent(Triangulation< dim, spacedim > &triangulation)
Definition: tria.cc:11110
static void prevent_distorted_boundary_cells(Triangulation< dim, spacedim > &triangulation)
Definition: tria.cc:11101
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 3 > &number_cache)
Definition: tria.cc:2018
static void reserve_space_(TriaObjects &obj, const unsigned int size)
Definition: tria.cc:2705
static Triangulation< 1, spacedim >::DistortedCellList execute_refinement(Triangulation< 1, spacedim > &triangulation, const bool)
Definition: tria.cc:4506
static void reserve_space_(TriaFaces &faces, const unsigned structdim, const unsigned int size)
Definition: tria.cc:2646
static void prevent_distorted_boundary_cells(Triangulation< 1, spacedim > &)
Definition: tria.cc:10655
static void update_neighbors(Triangulation< dim, spacedim > &triangulation)
Definition: tria.cc:2118
static void prepare_refinement_dim_dependent(const Triangulation< dim, spacedim > &)
Definition: tria.cc:10743
static void delete_children(Triangulation< 3, spacedim > &triangulation, typename Triangulation< 3, spacedim >::cell_iterator &cell, std::vector< unsigned int > &line_cell_count, std::vector< unsigned int > &quad_cell_count)
Definition: tria.cc:3000
static void reserve_space_(TriaLevel &level, const unsigned int spacedim, const unsigned int size, const bool orientation_needed)
Definition: tria.cc:2668
static void update_neighbors(Triangulation< 1, spacedim > &)
Definition: tria.cc:2112
static Triangulation< dim, spacedim >::DistortedCellList execute_refinement_isotropic(Triangulation< dim, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:3997
static void create_triangulation(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata, Triangulation< dim, spacedim > &tria)
Definition: tria.cc:2297
static void create_children(Triangulation< 2, spacedim > &triangulation, unsigned int &next_unused_vertex, typename Triangulation< 2, spacedim >::raw_line_iterator &next_unused_line, typename Triangulation< 2, spacedim >::raw_cell_iterator &next_unused_cell, const typename Triangulation< 2, spacedim >::cell_iterator &cell)
Definition: tria.cc:3630
static void process_subcelldata(const CRS< T > &crs, TriaObjects &obj, const std::vector< CellData< structdim >> &boundary_objects_in, const std::vector< Point< spacedim >> &vertex_locations)
Definition: tria.cc:2539
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 2 > &number_cache)
Definition: tria.cc:1911
static void prevent_distorted_boundary_cells(Triangulation< dim, spacedim > &triangulation)
Definition: tria.cc:10662
static Triangulation< 3, spacedim >::DistortedCellList execute_refinement_isotropic(Triangulation< 3, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:5046
static Triangulation< 2, spacedim >::DistortedCellList execute_refinement(Triangulation< 2, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:4737
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 1 > &number_cache)
Definition: tria.cc:1823
static bool coarsening_allowed(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
Definition: tria.cc:10937
static Triangulation< 3, spacedim >::DistortedCellList execute_refinement(Triangulation< 3, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:6299
static void delete_children(Triangulation< 1, spacedim > &triangulation, typename Triangulation< 1, spacedim >::cell_iterator &cell, std::vector< unsigned int > &, std::vector< unsigned int > &)
Definition: tria.cc:2758
static void prepare_refinement_dim_dependent(Triangulation< 3, spacedim > &triangulation)
Definition: tria.cc:10753
static void delete_children(Triangulation< 2, spacedim > &triangulation, typename Triangulation< 2, spacedim >::cell_iterator &cell, std::vector< unsigned int > &line_cell_count, std::vector< unsigned int > &)
Definition: tria.cc:2862
std::vector< unsigned int > n_active_lines_level
Definition: tria.h:177
std::vector< unsigned int > n_active_quads_level
Definition: tria.h:235
std::vector< unsigned int > n_active_hexes_level
Definition: tria.h:294
std::vector< std::vector< CellData< dim > > > cell_infos
const ::Triangulation< dim, spacedim > & tria