Reference documentation for deal.II version 9.3.2
\(\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 - 2021 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 reorder_compatibility(std::vector<CellData<2>> &cells,
481  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 reorder_compatibility(std::vector<CellData<3>> &cells,
490  SubCellData & subcelldata)
491  {
492  unsigned int tmp[GeometryInfo<3>::vertices_per_cell];
493  for (auto &cell : cells)
494  if (cell.vertices.size() == GeometryInfo<3>::vertices_per_cell)
495  {
496  for (const unsigned int i : GeometryInfo<3>::vertex_indices())
497  tmp[i] = cell.vertices[i];
498  for (const unsigned int i : GeometryInfo<3>::vertex_indices())
499  cell.vertices[GeometryInfo<3>::ucd_to_deal[i]] = tmp[i];
500  }
501 
502  // now points in boundary quads
503  for (auto &boundary_quad : subcelldata.boundary_quads)
504  if (boundary_quad.vertices.size() == GeometryInfo<2>::vertices_per_cell)
505  std::swap(boundary_quad.vertices[2], boundary_quad.vertices[3]);
506  }
507 
508 
509 
527  template <int dim, int spacedim>
528  unsigned int
529  middle_vertex_index(
530  const typename Triangulation<dim, spacedim>::line_iterator &line)
531  {
532  if (line->has_children())
533  return line->child(0)->vertex_index(1);
535  }
536 
537 
538  template <int dim, int spacedim>
539  unsigned int
540  middle_vertex_index(
541  const typename Triangulation<dim, spacedim>::quad_iterator &quad)
542  {
543  switch (static_cast<unsigned char>(quad->refinement_case()))
544  {
546  return middle_vertex_index<dim, spacedim>(quad->child(0)->line(1));
547  break;
549  return middle_vertex_index<dim, spacedim>(quad->child(0)->line(3));
550  break;
552  return quad->child(0)->vertex_index(3);
553  break;
554  default:
555  break;
556  }
558  }
559 
560 
561  template <int dim, int spacedim>
562  unsigned int
563  middle_vertex_index(
564  const typename Triangulation<dim, spacedim>::hex_iterator &hex)
565  {
566  switch (static_cast<unsigned char>(hex->refinement_case()))
567  {
569  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(1));
570  break;
572  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(3));
573  break;
575  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(5));
576  break;
578  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(11));
579  break;
581  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(5));
582  break;
584  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(7));
585  break;
587  return hex->child(0)->vertex_index(7);
588  break;
589  default:
590  break;
591  }
593  }
594 
595 
608  template <class TRIANGULATION>
609  inline typename TRIANGULATION::DistortedCellList
610  collect_distorted_coarse_cells(const TRIANGULATION &)
611  {
612  return typename TRIANGULATION::DistortedCellList();
613  }
614 
615 
616 
625  template <int dim>
627  collect_distorted_coarse_cells(const Triangulation<dim, dim> &triangulation)
628  {
629  typename Triangulation<dim, dim>::DistortedCellList distorted_cells;
630  for (const auto &cell : triangulation.cell_iterators_on_level(0))
631  {
633  for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
634  vertices[i] = cell->vertex(i);
635 
638 
639  for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
640  if (determinants[i] <= 1e-9 * std::pow(cell->diameter(), 1. * dim))
641  {
642  distorted_cells.distorted_cells.push_back(cell);
643  break;
644  }
645  }
646 
647  return distorted_cells;
648  }
649 
650 
657  template <int dim>
658  bool
659  has_distorted_children(
660  const typename Triangulation<dim, dim>::cell_iterator &cell)
661  {
662  Assert(cell->has_children(), ExcInternalError());
663 
664  for (unsigned int c = 0; c < cell->n_children(); ++c)
665  {
667  for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
668  vertices[i] = cell->child(c)->vertex(i);
669 
672 
673  for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
674  if (determinants[i] <=
675  1e-9 * std::pow(cell->child(c)->diameter(), 1. * dim))
676  return true;
677  }
678 
679  return false;
680  }
681 
682 
690  template <int dim, int spacedim>
691  bool
692  has_distorted_children(
694  {
695  return false;
696  }
697 
698 
699  template <int dim, int spacedim>
700  void
701  update_periodic_face_map_recursively(
702  const typename Triangulation<dim, spacedim>::cell_iterator &cell_1,
703  const typename Triangulation<dim, spacedim>::cell_iterator &cell_2,
704  unsigned int n_face_1,
705  unsigned int n_face_2,
706  const std::bitset<3> & orientation,
707  typename std::map<
709  unsigned int>,
710  std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
711  unsigned int>,
712  std::bitset<3>>> &periodic_face_map)
713  {
714  using FaceIterator = typename Triangulation<dim, spacedim>::face_iterator;
715  const FaceIterator face_1 = cell_1->face(n_face_1);
716  const FaceIterator face_2 = cell_2->face(n_face_2);
717 
718  const bool face_orientation = orientation[0];
719  const bool face_flip = orientation[1];
720  const bool face_rotation = orientation[2];
721 
722  Assert((dim != 1) || (face_orientation == true && face_flip == false &&
723  face_rotation == false),
724  ExcMessage("The supplied orientation "
725  "(face_orientation, face_flip, face_rotation) "
726  "is invalid for 1D"));
727 
728  Assert((dim != 2) || (face_orientation == true && face_rotation == false),
729  ExcMessage("The supplied orientation "
730  "(face_orientation, face_flip, face_rotation) "
731  "is invalid for 2D"));
732 
733  Assert(face_1 != face_2, ExcMessage("face_1 and face_2 are equal!"));
734 
735  Assert(face_1->at_boundary() && face_2->at_boundary(),
736  ExcMessage("Periodic faces must be on the boundary"));
737 
738  // Check if the requirement that each edge can only have at most one hanging
739  // node, and as a consequence neighboring cells can differ by at most
740  // one refinement level is enforced. In 1d, there are no hanging nodes and
741  // so neighboring cells can differ by more than one refinement level.
742  Assert(dim == 1 || std::abs(cell_1->level() - cell_2->level()) < 2,
743  ExcInternalError());
744 
745  // insert periodic face pair for both cells
746  using CellFace =
747  std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
748  unsigned int>;
749  const CellFace cell_face_1(cell_1, n_face_1);
750  const CellFace cell_face_2(cell_2, n_face_2);
751  const std::pair<CellFace, std::bitset<3>> cell_face_orientation_2(
752  cell_face_2, orientation);
753 
754  const std::pair<CellFace, std::pair<CellFace, std::bitset<3>>>
755  periodic_faces(cell_face_1, cell_face_orientation_2);
756 
757  // Only one periodic neighbor is allowed
758  Assert(periodic_face_map.count(cell_face_1) == 0, ExcInternalError());
759  periodic_face_map.insert(periodic_faces);
760 
761  if (dim == 1)
762  {
763  if (cell_1->has_children())
764  {
765  if (cell_2->has_children())
766  {
767  update_periodic_face_map_recursively<dim, spacedim>(
768  cell_1->child(n_face_1),
769  cell_2->child(n_face_2),
770  n_face_1,
771  n_face_2,
772  orientation,
773  periodic_face_map);
774  }
775  else // only face_1 has children
776  {
777  update_periodic_face_map_recursively<dim, spacedim>(
778  cell_1->child(n_face_1),
779  cell_2,
780  n_face_1,
781  n_face_2,
782  orientation,
783  periodic_face_map);
784  }
785  }
786  }
787  else // dim == 2 || dim == 3
788  {
789  // A lookup table on how to go through the child cells depending on the
790  // orientation:
791  // see Documentation of GeometryInfo for details
792 
793  static const int lookup_table_2d[2][2] =
794  // flip:
795  {
796  {0, 1}, // false
797  {1, 0} // true
798  };
799 
800  static const int lookup_table_3d[2][2][2][4] =
801  // orientation flip rotation
802  {{{
803  {0, 2, 1, 3}, // false false false
804  {2, 3, 0, 1} // false false true
805  },
806  {
807  {3, 1, 2, 0}, // false true false
808  {1, 0, 3, 2} // false true true
809  }},
810  {{
811  {0, 1, 2, 3}, // true false false
812  {1, 3, 0, 2} // true false true
813  },
814  {
815  {3, 2, 1, 0}, // true true false
816  {2, 0, 3, 1} // true true true
817  }}};
818 
819  if (cell_1->has_children())
820  {
821  if (cell_2->has_children())
822  {
823  // In the case that both faces have children, we loop over all
824  // children and apply update_periodic_face_map_recursively
825  // recursively:
826 
827  Assert(face_1->n_children() ==
829  face_2->n_children() ==
832 
833  for (unsigned int i = 0;
834  i < GeometryInfo<dim>::max_children_per_face;
835  ++i)
836  {
837  // Lookup the index for the second face
838  unsigned int j = 0;
839  switch (dim)
840  {
841  case 2:
842  j = lookup_table_2d[face_flip][i];
843  break;
844  case 3:
845  j = lookup_table_3d[face_orientation][face_flip]
846  [face_rotation][i];
847  break;
848  default:
849  AssertThrow(false, ExcNotImplemented());
850  }
851 
852  // find subcell ids that belong to the subface indices
853  unsigned int child_cell_1 =
855  cell_1->refinement_case(),
856  n_face_1,
857  i,
858  cell_1->face_orientation(n_face_1),
859  cell_1->face_flip(n_face_1),
860  cell_1->face_rotation(n_face_1),
861  face_1->refinement_case());
862  unsigned int child_cell_2 =
864  cell_2->refinement_case(),
865  n_face_2,
866  j,
867  cell_2->face_orientation(n_face_2),
868  cell_2->face_flip(n_face_2),
869  cell_2->face_rotation(n_face_2),
870  face_2->refinement_case());
871 
872  Assert(cell_1->child(child_cell_1)->face(n_face_1) ==
873  face_1->child(i),
874  ExcInternalError());
875  Assert(cell_2->child(child_cell_2)->face(n_face_2) ==
876  face_2->child(j),
877  ExcInternalError());
878 
879  // precondition: subcell has the same orientation as cell
880  // (so that the face numbers coincide) recursive call
881  update_periodic_face_map_recursively<dim, spacedim>(
882  cell_1->child(child_cell_1),
883  cell_2->child(child_cell_2),
884  n_face_1,
885  n_face_2,
886  orientation,
887  periodic_face_map);
888  }
889  }
890  else // only face_1 has children
891  {
892  for (unsigned int i = 0;
893  i < GeometryInfo<dim>::max_children_per_face;
894  ++i)
895  {
896  // find subcell ids that belong to the subface indices
897  unsigned int child_cell_1 =
899  cell_1->refinement_case(),
900  n_face_1,
901  i,
902  cell_1->face_orientation(n_face_1),
903  cell_1->face_flip(n_face_1),
904  cell_1->face_rotation(n_face_1),
905  face_1->refinement_case());
906 
907  // recursive call
908  update_periodic_face_map_recursively<dim, spacedim>(
909  cell_1->child(child_cell_1),
910  cell_2,
911  n_face_1,
912  n_face_2,
913  orientation,
914  periodic_face_map);
915  }
916  }
917  }
918  }
919  }
920 
921 
922 } // end of anonymous namespace
923 
924 
925 namespace internal
926 {
927  namespace TriangulationImplementation
928  {
929  // make sure that if in the following we
930  // write Triangulation<dim,spacedim>
931  // we mean the *class*
932  // ::Triangulation, not the
933  // enclosing namespace
934  // internal::TriangulationImplementation
936 
942  int,
943  << "Something went wrong when making cell " << arg1
944  << ". Read the docs and the source code "
945  << "for more information.");
951  int,
952  << "Something went wrong upon construction of cell "
953  << arg1);
964  int,
965  << "Cell " << arg1
966  << " has negative measure. This typically "
967  << "indicates some distortion in the cell, or a mistakenly "
968  << "swapped pair of vertices in the input to "
969  << "Triangulation::create_triangulation().");
978  int,
979  int,
980  int,
981  << "Error while creating cell " << arg1
982  << ": the vertex index " << arg2 << " must be between 0 and "
983  << arg3 << ".");
989  int,
990  int,
991  << "While trying to assign a boundary indicator to a line: "
992  << "the line with end vertices " << arg1 << " and " << arg2
993  << " does not exist.");
999  int,
1000  int,
1001  int,
1002  int,
1003  << "While trying to assign a boundary indicator to a quad: "
1004  << "the quad with bounding lines " << arg1 << ", " << arg2
1005  << ", " << arg3 << ", " << arg4 << " does not exist.");
1012  int,
1013  int,
1015  << "The input data for creating a triangulation contained "
1016  << "information about a line with indices " << arg1 << " and " << arg2
1017  << " that is described to have boundary indicator "
1018  << static_cast<int>(arg3)
1019  << ". However, this is an internal line not located on the "
1020  << "boundary. You cannot assign a boundary indicator to it." << std::endl
1021  << std::endl
1022  << "If this happened at a place where you call "
1023  << "Triangulation::create_triangulation() yourself, you need "
1024  << "to check the SubCellData object you pass to this function."
1025  << std::endl
1026  << std::endl
1027  << "If this happened in a place where you are reading a mesh "
1028  << "from a file, then you need to investigate why such a line "
1029  << "ended up in the input file. A typical case is a geometry "
1030  << "that consisted of multiple parts and for which the mesh "
1031  << "generator program assumes that the interface between "
1032  << "two parts is a boundary when that isn't supposed to be "
1033  << "the case, or where the mesh generator simply assigns "
1034  << "'geometry indicators' to lines at the perimeter of "
1035  << "a part that are not supposed to be interpreted as "
1036  << "'boundary indicators'.");
1043  int,
1044  int,
1045  int,
1046  int,
1048  << "The input data for creating a triangulation contained "
1049  << "information about a quad with indices " << arg1 << ", " << arg2
1050  << ", " << arg3 << ", and " << arg4
1051  << " that is described to have boundary indicator "
1052  << static_cast<int>(arg5)
1053  << ". However, this is an internal quad not located on the "
1054  << "boundary. You cannot assign a boundary indicator to it." << std::endl
1055  << std::endl
1056  << "If this happened at a place where you call "
1057  << "Triangulation::create_triangulation() yourself, you need "
1058  << "to check the SubCellData object you pass to this function."
1059  << std::endl
1060  << std::endl
1061  << "If this happened in a place where you are reading a mesh "
1062  << "from a file, then you need to investigate why such a quad "
1063  << "ended up in the input file. A typical case is a geometry "
1064  << "that consisted of multiple parts and for which the mesh "
1065  << "generator program assumes that the interface between "
1066  << "two parts is a boundary when that isn't supposed to be "
1067  << "the case, or where the mesh generator simply assigns "
1068  << "'geometry indicators' to quads at the surface of "
1069  << "a part that are not supposed to be interpreted as "
1070  << "'boundary indicators'.");
1077  int,
1078  int,
1079  << "In SubCellData the line info of the line with vertex indices " << arg1
1080  << " and " << arg2 << " appears more than once. "
1081  << "This is not allowed.");
1088  int,
1089  int,
1090  std::string,
1091  << "In SubCellData the line info of the line with vertex indices " << arg1
1092  << " and " << arg2 << " appears multiple times with different (valid) "
1093  << arg3 << ". This is not allowed.");
1100  int,
1101  int,
1102  int,
1103  int,
1104  std::string,
1105  << "In SubCellData the quad info of the quad with line indices " << arg1
1106  << ", " << arg2 << ", " << arg3 << " and " << arg4
1107  << " appears multiple times with different (valid) " << arg5
1108  << ". This is not allowed.");
1109 
1110  /*
1111  * Reserve space for TriaFaces. Details:
1112  *
1113  * Reserve space for line_orientations.
1114  *
1115  * @note Used only for dim=3.
1116  */
1117  void
1118  reserve_space(TriaFaces & tria_faces,
1119  const unsigned int new_quads_in_pairs,
1120  const unsigned int new_quads_single)
1121  {
1122  AssertDimension(tria_faces.dim, 3);
1123 
1124  Assert(new_quads_in_pairs % 2 == 0, ExcInternalError());
1125 
1126  unsigned int next_free_single = 0;
1127  unsigned int next_free_pair = 0;
1128 
1129  // count the number of objects, of unused single objects and of
1130  // unused pairs of objects
1131  unsigned int n_quads = 0;
1132  unsigned int n_unused_pairs = 0;
1133  unsigned int n_unused_singles = 0;
1134  for (unsigned int i = 0; i < tria_faces.quads.used.size(); ++i)
1135  {
1136  if (tria_faces.quads.used[i])
1137  ++n_quads;
1138  else if (i + 1 < tria_faces.quads.used.size())
1139  {
1140  if (tria_faces.quads.used[i + 1])
1141  {
1142  ++n_unused_singles;
1143  if (next_free_single == 0)
1144  next_free_single = i;
1145  }
1146  else
1147  {
1148  ++n_unused_pairs;
1149  if (next_free_pair == 0)
1150  next_free_pair = i;
1151  ++i;
1152  }
1153  }
1154  else
1155  ++n_unused_singles;
1156  }
1157  Assert(n_quads + 2 * n_unused_pairs + n_unused_singles ==
1158  tria_faces.quads.used.size(),
1159  ExcInternalError());
1160 
1161  // how many single quads are needed in addition to n_unused_quads?
1162  const int additional_single_quads = new_quads_single - n_unused_singles;
1163 
1164  unsigned int new_size =
1165  tria_faces.quads.used.size() + new_quads_in_pairs - 2 * n_unused_pairs;
1166  if (additional_single_quads > 0)
1167  new_size += additional_single_quads;
1168 
1169  // see above...
1170  if (new_size > tria_faces.quads.n_objects())
1171  {
1172  // reserve the field of the derived class
1173  tria_faces.quads_line_orientations.reserve(
1174  new_size * GeometryInfo<2>::lines_per_cell);
1175  tria_faces.quads_line_orientations.insert(
1176  tria_faces.quads_line_orientations.end(),
1177  new_size * GeometryInfo<2>::lines_per_cell -
1178  tria_faces.quads_line_orientations.size(),
1179  true);
1180 
1181  tria_faces.quad_reference_cell.reserve(new_size);
1182  tria_faces.quad_reference_cell.insert(
1183  tria_faces.quad_reference_cell.end(),
1184  new_size - tria_faces.quad_reference_cell.size(),
1186  }
1187  }
1188 
1189 
1190 
1204  void
1205  reserve_space(TriaLevel & tria_level,
1206  const unsigned int total_cells,
1207  const unsigned int dimension,
1208  const unsigned int space_dimension)
1209  {
1210  // we need space for total_cells cells. Maybe we have more already
1211  // with those cells which are unused, so only allocate new space if
1212  // needed.
1213  //
1214  // note that all arrays should have equal sizes (checked by
1215  // @p{monitor_memory}
1216  if (total_cells > tria_level.refine_flags.size())
1217  {
1218  tria_level.refine_flags.reserve(total_cells);
1219  tria_level.refine_flags.insert(tria_level.refine_flags.end(),
1220  total_cells -
1221  tria_level.refine_flags.size(),
1222  /*RefinementCase::no_refinement=*/0);
1223 
1224  tria_level.coarsen_flags.reserve(total_cells);
1225  tria_level.coarsen_flags.insert(tria_level.coarsen_flags.end(),
1226  total_cells -
1227  tria_level.coarsen_flags.size(),
1228  false);
1229 
1230  tria_level.active_cell_indices.reserve(total_cells);
1231  tria_level.active_cell_indices.insert(
1232  tria_level.active_cell_indices.end(),
1233  total_cells - tria_level.active_cell_indices.size(),
1235 
1236  tria_level.subdomain_ids.reserve(total_cells);
1237  tria_level.subdomain_ids.insert(tria_level.subdomain_ids.end(),
1238  total_cells -
1239  tria_level.subdomain_ids.size(),
1240  0);
1241 
1242  tria_level.level_subdomain_ids.reserve(total_cells);
1243  tria_level.level_subdomain_ids.insert(
1244  tria_level.level_subdomain_ids.end(),
1245  total_cells - tria_level.level_subdomain_ids.size(),
1246  0);
1247 
1248  tria_level.global_active_cell_indices.reserve(total_cells);
1249  tria_level.global_active_cell_indices.insert(
1250  tria_level.global_active_cell_indices.end(),
1251  total_cells - tria_level.global_active_cell_indices.size(),
1253 
1254  tria_level.global_level_cell_indices.reserve(total_cells);
1255  tria_level.global_level_cell_indices.insert(
1256  tria_level.global_level_cell_indices.end(),
1257  total_cells - tria_level.global_level_cell_indices.size(),
1259 
1260  if (dimension < space_dimension)
1261  {
1262  tria_level.direction_flags.reserve(total_cells);
1263  tria_level.direction_flags.insert(
1264  tria_level.direction_flags.end(),
1265  total_cells - tria_level.direction_flags.size(),
1266  true);
1267  }
1268  else
1269  tria_level.direction_flags.clear();
1270 
1271  tria_level.parents.reserve((total_cells + 1) / 2);
1272  tria_level.parents.insert(tria_level.parents.end(),
1273  (total_cells + 1) / 2 -
1274  tria_level.parents.size(),
1275  -1);
1276 
1277  tria_level.neighbors.reserve(total_cells * (2 * dimension));
1278  tria_level.neighbors.insert(tria_level.neighbors.end(),
1279  total_cells * (2 * dimension) -
1280  tria_level.neighbors.size(),
1281  std::make_pair(-1, -1));
1282 
1283  if (tria_level.dim == 2 || tria_level.dim == 3)
1284  {
1285  const unsigned int max_faces_per_cell = 2 * dimension;
1286  tria_level.face_orientations.reserve(total_cells *
1287  max_faces_per_cell);
1288  tria_level.face_orientations.insert(
1289  tria_level.face_orientations.end(),
1290  total_cells * max_faces_per_cell -
1291  tria_level.face_orientations.size(),
1292  true);
1293 
1294  tria_level.reference_cell.reserve(total_cells);
1295  tria_level.reference_cell.insert(
1296  tria_level.reference_cell.end(),
1297  total_cells - tria_level.reference_cell.size(),
1298  tria_level.dim == 2 ? ::ReferenceCells::Quadrilateral :
1300  }
1301  }
1302  }
1303 
1304 
1305 
1310  int,
1311  int,
1312  << "The containers have sizes " << arg1 << " and " << arg2
1313  << ", which is not as expected.");
1314 
1320  void
1321  monitor_memory(const TriaLevel & tria_level,
1322  const unsigned int true_dimension)
1323  {
1324  (void)tria_level;
1325  (void)true_dimension;
1326  Assert(2 * true_dimension * tria_level.refine_flags.size() ==
1327  tria_level.neighbors.size(),
1328  ExcMemoryInexact(tria_level.refine_flags.size(),
1329  tria_level.neighbors.size()));
1330  Assert(2 * true_dimension * tria_level.coarsen_flags.size() ==
1331  tria_level.neighbors.size(),
1332  ExcMemoryInexact(tria_level.coarsen_flags.size(),
1333  tria_level.neighbors.size()));
1334  }
1335 
1336 
1337 
1350  void
1351  reserve_space(TriaObjects & tria_objects,
1352  const unsigned int new_objects_in_pairs,
1353  const unsigned int new_objects_single = 0)
1354  {
1355  if (tria_objects.structdim <= 2)
1356  {
1357  Assert(new_objects_in_pairs % 2 == 0, ExcInternalError());
1358 
1359  tria_objects.next_free_single = 0;
1360  tria_objects.next_free_pair = 0;
1361  tria_objects.reverse_order_next_free_single = false;
1362 
1363  // count the number of objects, of unused single objects and of
1364  // unused pairs of objects
1365  unsigned int n_objects = 0;
1366  unsigned int n_unused_pairs = 0;
1367  unsigned int n_unused_singles = 0;
1368  for (unsigned int i = 0; i < tria_objects.used.size(); ++i)
1369  {
1370  if (tria_objects.used[i])
1371  ++n_objects;
1372  else if (i + 1 < tria_objects.used.size())
1373  {
1374  if (tria_objects.used[i + 1])
1375  {
1376  ++n_unused_singles;
1377  if (tria_objects.next_free_single == 0)
1378  tria_objects.next_free_single = i;
1379  }
1380  else
1381  {
1382  ++n_unused_pairs;
1383  if (tria_objects.next_free_pair == 0)
1384  tria_objects.next_free_pair = i;
1385  ++i;
1386  }
1387  }
1388  else
1389  ++n_unused_singles;
1390  }
1391  Assert(n_objects + 2 * n_unused_pairs + n_unused_singles ==
1392  tria_objects.used.size(),
1393  ExcInternalError());
1394 
1395  // how many single objects are needed in addition to
1396  // n_unused_objects?
1397  const int additional_single_objects =
1398  new_objects_single - n_unused_singles;
1399 
1400  unsigned int new_size = tria_objects.used.size() +
1401  new_objects_in_pairs - 2 * n_unused_pairs;
1402  if (additional_single_objects > 0)
1403  new_size += additional_single_objects;
1404 
1405  // only allocate space if necessary
1406  if (new_size > tria_objects.n_objects())
1407  {
1408  const unsigned int max_faces_per_cell =
1409  2 * tria_objects.structdim;
1410  const unsigned int max_children_per_cell =
1411  1 << tria_objects.structdim;
1412 
1413  tria_objects.cells.reserve(new_size * max_faces_per_cell);
1414  tria_objects.cells.insert(tria_objects.cells.end(),
1415  (new_size - tria_objects.n_objects()) *
1416  max_faces_per_cell,
1417  -1);
1418 
1419  tria_objects.used.reserve(new_size);
1420  tria_objects.used.insert(tria_objects.used.end(),
1421  new_size - tria_objects.used.size(),
1422  false);
1423 
1424  tria_objects.user_flags.reserve(new_size);
1425  tria_objects.user_flags.insert(tria_objects.user_flags.end(),
1426  new_size -
1427  tria_objects.user_flags.size(),
1428  false);
1429 
1430  const unsigned int factor = max_children_per_cell / 2;
1431  tria_objects.children.reserve(factor * new_size);
1432  tria_objects.children.insert(tria_objects.children.end(),
1433  factor * new_size -
1434  tria_objects.children.size(),
1435  -1);
1436 
1437  if (tria_objects.structdim > 1)
1438  {
1439  tria_objects.refinement_cases.reserve(new_size);
1440  tria_objects.refinement_cases.insert(
1441  tria_objects.refinement_cases.end(),
1442  new_size - tria_objects.refinement_cases.size(),
1443  /*RefinementCase::no_refinement=*/0);
1444  }
1445 
1446  // first reserve, then resize. Otherwise the std library can
1447  // decide to allocate more entries.
1448  tria_objects.boundary_or_material_id.reserve(new_size);
1449  tria_objects.boundary_or_material_id.resize(new_size);
1450 
1451  tria_objects.user_data.reserve(new_size);
1452  tria_objects.user_data.resize(new_size);
1453 
1454  tria_objects.manifold_id.reserve(new_size);
1455  tria_objects.manifold_id.insert(tria_objects.manifold_id.end(),
1456  new_size -
1457  tria_objects.manifold_id.size(),
1459  }
1460 
1461  if (n_unused_singles == 0)
1462  {
1463  tria_objects.next_free_single = new_size - 1;
1464  tria_objects.reverse_order_next_free_single = true;
1465  }
1466  }
1467  else
1468  {
1469  const unsigned int new_hexes = new_objects_in_pairs;
1470 
1471  const unsigned int new_size =
1472  new_hexes + std::count(tria_objects.used.begin(),
1473  tria_objects.used.end(),
1474  true);
1475 
1476  // see above...
1477  if (new_size > tria_objects.n_objects())
1478  {
1479  const unsigned int max_faces_per_cell =
1480  2 * tria_objects.structdim;
1481 
1482  tria_objects.cells.reserve(new_size * max_faces_per_cell);
1483  tria_objects.cells.insert(tria_objects.cells.end(),
1484  (new_size - tria_objects.n_objects()) *
1485  max_faces_per_cell,
1486  -1);
1487 
1488  tria_objects.used.reserve(new_size);
1489  tria_objects.used.insert(tria_objects.used.end(),
1490  new_size - tria_objects.used.size(),
1491  false);
1492 
1493  tria_objects.user_flags.reserve(new_size);
1494  tria_objects.user_flags.insert(tria_objects.user_flags.end(),
1495  new_size -
1496  tria_objects.user_flags.size(),
1497  false);
1498 
1499  tria_objects.children.reserve(4 * new_size);
1500  tria_objects.children.insert(tria_objects.children.end(),
1501  4 * new_size -
1502  tria_objects.children.size(),
1503  -1);
1504 
1505  // for the following fields, we know exactly how many elements
1506  // we need, so first reserve then resize (resize itself, at least
1507  // with some compiler libraries, appears to round up the size it
1508  // actually reserves)
1509  tria_objects.boundary_or_material_id.reserve(new_size);
1510  tria_objects.boundary_or_material_id.resize(new_size);
1511 
1512  tria_objects.manifold_id.reserve(new_size);
1513  tria_objects.manifold_id.insert(tria_objects.manifold_id.end(),
1514  new_size -
1515  tria_objects.manifold_id.size(),
1517 
1518  tria_objects.user_data.reserve(new_size);
1519  tria_objects.user_data.resize(new_size);
1520 
1521  tria_objects.refinement_cases.reserve(new_size);
1522  tria_objects.refinement_cases.insert(
1523  tria_objects.refinement_cases.end(),
1524  new_size - tria_objects.refinement_cases.size(),
1525  /*RefinementCase::no_refinement=*/0);
1526  }
1527  tria_objects.next_free_single = tria_objects.next_free_pair = 0;
1528  }
1529  }
1530 
1531 
1532 
1538  void
1539  monitor_memory(const TriaObjects &tria_object, const unsigned int)
1540  {
1541  Assert(tria_object.n_objects() == tria_object.used.size(),
1542  ExcMemoryInexact(tria_object.n_objects(),
1543  tria_object.used.size()));
1544  Assert(tria_object.n_objects() == tria_object.user_flags.size(),
1545  ExcMemoryInexact(tria_object.n_objects(),
1546  tria_object.user_flags.size()));
1547  Assert(tria_object.n_objects() ==
1548  tria_object.boundary_or_material_id.size(),
1549  ExcMemoryInexact(tria_object.n_objects(),
1550  tria_object.boundary_or_material_id.size()));
1551  Assert(tria_object.n_objects() == tria_object.manifold_id.size(),
1552  ExcMemoryInexact(tria_object.n_objects(),
1553  tria_object.manifold_id.size()));
1554  Assert(tria_object.n_objects() == tria_object.user_data.size(),
1555  ExcMemoryInexact(tria_object.n_objects(),
1556  tria_object.user_data.size()));
1557 
1558  if (tria_object.structdim == 1)
1559  {
1560  Assert(1 * tria_object.n_objects() == tria_object.children.size(),
1561  ExcMemoryInexact(tria_object.n_objects(),
1562  tria_object.children.size()));
1563  }
1564  else if (tria_object.structdim == 2)
1565  {
1566  Assert(2 * tria_object.n_objects() == tria_object.children.size(),
1567  ExcMemoryInexact(tria_object.n_objects(),
1568  tria_object.children.size()));
1569  }
1570  else if (tria_object.structdim == 3)
1571  {
1572  Assert(4 * tria_object.n_objects() == tria_object.children.size(),
1573  ExcMemoryInexact(tria_object.n_objects(),
1574  tria_object.children.size()));
1575  }
1576  }
1577 
1578 
1579 
1584  template <int dim, int spacedim>
1585  class Policy
1586  {
1587  public:
1591  virtual ~Policy() = default;
1592 
1596  virtual void
1598 
1602  virtual void
1606  std::vector<unsigned int> & line_cell_count,
1607  std::vector<unsigned int> &quad_cell_count) = 0;
1608 
1614  const bool check_for_distorted_cells) = 0;
1615 
1619  virtual void
1622 
1626  virtual void
1629 
1633  virtual bool
1635  const typename Triangulation<dim, spacedim>::cell_iterator &cell) = 0;
1636 
1643  virtual std::unique_ptr<Policy<dim, spacedim>>
1644  clone() = 0;
1645  };
1646 
1647 
1648 
1654  template <int dim, int spacedim, typename T>
1655  class PolicyWrapper : public Policy<dim, spacedim>
1656  {
1657  public:
1658  void
1660  {
1661  T::update_neighbors(tria);
1662  }
1663 
1664  void
1668  std::vector<unsigned int> & line_cell_count,
1669  std::vector<unsigned int> &quad_cell_count) override
1670  {
1671  T::delete_children(tria, cell, line_cell_count, quad_cell_count);
1672  }
1673 
1676  const bool check_for_distorted_cells) override
1677  {
1678  return T::execute_refinement(triangulation, check_for_distorted_cells);
1679  }
1680 
1681  void
1684  {
1685  T::prevent_distorted_boundary_cells(triangulation);
1686  }
1687 
1688  void
1691  {
1692  T::prepare_refinement_dim_dependent(triangulation);
1693  }
1694 
1695  bool
1697  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
1698  override
1699  {
1700  return T::template coarsening_allowed<dim, spacedim>(cell);
1701  }
1702 
1703  std::unique_ptr<Policy<dim, spacedim>>
1704  clone() override
1705  {
1706  return std::make_unique<PolicyWrapper<dim, spacedim, T>>();
1707  }
1708  };
1709 
1710 
1711 
1808  {
1820  template <int dim, int spacedim>
1821  static void
1824  const unsigned int level_objects,
1826  {
1827  using line_iterator =
1829 
1830  number_cache.n_levels = 0;
1831  if (level_objects > 0)
1832  // find the last level on which there are used cells
1833  for (unsigned int level = 0; level < level_objects; ++level)
1834  if (triangulation.begin(level) != triangulation.end(level))
1835  number_cache.n_levels = level + 1;
1836 
1837  // no cells at all?
1838  Assert(number_cache.n_levels > 0, ExcInternalError());
1839 
1841  // update the number of lines on the different levels in the
1842  // cache
1843  number_cache.n_lines = 0;
1844  number_cache.n_active_lines = 0;
1845 
1846  // for 1d, lines have levels so take count the objects per
1847  // level and globally
1848  if (dim == 1)
1849  {
1850  number_cache.n_lines_level.resize(number_cache.n_levels);
1851  number_cache.n_active_lines_level.resize(number_cache.n_levels);
1852 
1853  for (unsigned int level = 0; level < number_cache.n_levels; ++level)
1854  {
1855  // count lines on this level
1856  number_cache.n_lines_level[level] = 0;
1857  number_cache.n_active_lines_level[level] = 0;
1858 
1859  line_iterator line = triangulation.begin_line(level),
1860  endc =
1861  (level == number_cache.n_levels - 1 ?
1862  line_iterator(triangulation.end_line()) :
1863  triangulation.begin_line(level + 1));
1864  for (; line != endc; ++line)
1865  {
1866  ++number_cache.n_lines_level[level];
1867  if (line->has_children() == false)
1868  ++number_cache.n_active_lines_level[level];
1869  }
1870 
1871  // update total number of lines
1872  number_cache.n_lines += number_cache.n_lines_level[level];
1873  number_cache.n_active_lines +=
1874  number_cache.n_active_lines_level[level];
1875  }
1876  }
1877  else
1878  {
1879  // for dim>1, there are no levels for lines
1880  number_cache.n_lines_level.clear();
1881  number_cache.n_active_lines_level.clear();
1882 
1883  line_iterator line = triangulation.begin_line(),
1884  endc = triangulation.end_line();
1885  for (; line != endc; ++line)
1886  {
1887  ++number_cache.n_lines;
1888  if (line->has_children() == false)
1889  ++number_cache.n_active_lines;
1890  }
1891  }
1892  }
1893 
1908  template <int dim, int spacedim>
1909  static void
1912  const unsigned int level_objects,
1914  {
1915  // update lines and n_levels in number_cache. since we don't
1916  // access any of these numbers, we can do this in the
1917  // background
1918  Threads::Task<void> update_lines = Threads::new_task(
1919  static_cast<
1920  void (*)(const Triangulation<dim, spacedim> &,
1921  const unsigned int,
1923  &compute_number_cache<dim, spacedim>),
1924  triangulation,
1925  level_objects,
1927  number_cache));
1928 
1929  using quad_iterator =
1931 
1933  // update the number of quads on the different levels in the
1934  // cache
1935  number_cache.n_quads = 0;
1936  number_cache.n_active_quads = 0;
1937 
1938  // for 2d, quads have levels so take count the objects per
1939  // level and globally
1940  if (dim == 2)
1941  {
1942  // count the number of levels; the function we called above
1943  // on a separate Task for lines also does this and puts it into
1944  // number_cache.n_levels, but this datum may not yet be
1945  // available as we call the function on a separate task
1946  unsigned int n_levels = 0;
1947  if (level_objects > 0)
1948  // find the last level on which there are used cells
1949  for (unsigned int level = 0; level < level_objects; ++level)
1950  if (triangulation.begin(level) != triangulation.end(level))
1951  n_levels = level + 1;
1952 
1953  number_cache.n_quads_level.resize(n_levels);
1954  number_cache.n_active_quads_level.resize(n_levels);
1955 
1956  for (unsigned int level = 0; level < n_levels; ++level)
1957  {
1958  // count quads on this level
1959  number_cache.n_quads_level[level] = 0;
1960  number_cache.n_active_quads_level[level] = 0;
1961 
1962  quad_iterator quad = triangulation.begin_quad(level),
1963  endc =
1964  (level == n_levels - 1 ?
1965  quad_iterator(triangulation.end_quad()) :
1966  triangulation.begin_quad(level + 1));
1967  for (; quad != endc; ++quad)
1968  {
1969  ++number_cache.n_quads_level[level];
1970  if (quad->has_children() == false)
1971  ++number_cache.n_active_quads_level[level];
1972  }
1973 
1974  // update total number of quads
1975  number_cache.n_quads += number_cache.n_quads_level[level];
1976  number_cache.n_active_quads +=
1977  number_cache.n_active_quads_level[level];
1978  }
1979  }
1980  else
1981  {
1982  // for dim>2, there are no levels for quads
1983  number_cache.n_quads_level.clear();
1984  number_cache.n_active_quads_level.clear();
1985 
1986  quad_iterator quad = triangulation.begin_quad(),
1987  endc = triangulation.end_quad();
1988  for (; quad != endc; ++quad)
1989  {
1990  ++number_cache.n_quads;
1991  if (quad->has_children() == false)
1992  ++number_cache.n_active_quads;
1993  }
1994  }
1995 
1996  // wait for the background computation for lines
1997  update_lines.join();
1998  }
1999 
2015  template <int dim, int spacedim>
2016  static void
2019  const unsigned int level_objects,
2021  {
2022  // update quads, lines and n_levels in number_cache. since we
2023  // don't access any of these numbers, we can do this in the
2024  // background
2025  Threads::Task<void> update_quads_and_lines = Threads::new_task(
2026  static_cast<
2027  void (*)(const Triangulation<dim, spacedim> &,
2028  const unsigned int,
2030  &compute_number_cache<dim, spacedim>),
2031  triangulation,
2032  level_objects,
2034  number_cache));
2035 
2036  using hex_iterator =
2038 
2040  // update the number of hexes on the different levels in the
2041  // cache
2042  number_cache.n_hexes = 0;
2043  number_cache.n_active_hexes = 0;
2044 
2045  // for 3d, hexes have levels so take count the objects per
2046  // level and globally
2047  if (dim == 3)
2048  {
2049  // count the number of levels; the function we called
2050  // above on a separate Task for quads (recursively, via
2051  // the lines function) also does this and puts it into
2052  // number_cache.n_levels, but this datum may not yet be
2053  // available as we call the function on a separate task
2054  unsigned int n_levels = 0;
2055  if (level_objects > 0)
2056  // find the last level on which there are used cells
2057  for (unsigned int level = 0; level < level_objects; ++level)
2058  if (triangulation.begin(level) != triangulation.end(level))
2059  n_levels = level + 1;
2060 
2061  number_cache.n_hexes_level.resize(n_levels);
2062  number_cache.n_active_hexes_level.resize(n_levels);
2063 
2064  for (unsigned int level = 0; level < n_levels; ++level)
2065  {
2066  // count hexes on this level
2067  number_cache.n_hexes_level[level] = 0;
2068  number_cache.n_active_hexes_level[level] = 0;
2069 
2070  hex_iterator hex = triangulation.begin_hex(level),
2071  endc = (level == n_levels - 1 ?
2072  hex_iterator(triangulation.end_hex()) :
2073  triangulation.begin_hex(level + 1));
2074  for (; hex != endc; ++hex)
2075  {
2076  ++number_cache.n_hexes_level[level];
2077  if (hex->has_children() == false)
2078  ++number_cache.n_active_hexes_level[level];
2079  }
2080 
2081  // update total number of hexes
2082  number_cache.n_hexes += number_cache.n_hexes_level[level];
2083  number_cache.n_active_hexes +=
2084  number_cache.n_active_hexes_level[level];
2085  }
2086  }
2087  else
2088  {
2089  // for dim>3, there are no levels for hexes
2090  number_cache.n_hexes_level.clear();
2091  number_cache.n_active_hexes_level.clear();
2092 
2093  hex_iterator hex = triangulation.begin_hex(),
2094  endc = triangulation.end_hex();
2095  for (; hex != endc; ++hex)
2096  {
2097  ++number_cache.n_hexes;
2098  if (hex->has_children() == false)
2099  ++number_cache.n_active_hexes;
2100  }
2101  }
2102 
2103  // wait for the background computation for quads
2104  update_quads_and_lines.join();
2105  }
2106 
2107 
2108 
2109  template <int spacedim>
2111  {}
2112 
2113 
2114  template <int dim, int spacedim>
2115  static void
2117  {
2118  // each face can be neighbored on two sides
2119  // by cells. according to the face's
2120  // intrinsic normal we define the left
2121  // neighbor as the one for which the face
2122  // normal points outward, and store that
2123  // one first; the second one is then
2124  // the right neighbor for which the
2125  // face normal points inward. This
2126  // information depends on the type of cell
2127  // and local number of face for the
2128  // 'standard ordering and orientation' of
2129  // faces and then on the face_orientation
2130  // information for the real mesh. Set up a
2131  // table to have fast access to those
2132  // offsets (0 for left and 1 for
2133  // right). Some of the values are invalid
2134  // as they reference too large face
2135  // numbers, but we just leave them at a
2136  // zero value.
2137  //
2138  // Note, that in 2d for lines as faces the
2139  // normal direction given in the
2140  // GeometryInfo class is not consistent. We
2141  // thus define here that the normal for a
2142  // line points to the right if the line
2143  // points upwards.
2144  //
2145  // There is one more point to
2146  // consider, however: if we have
2147  // dim<spacedim, then we may have
2148  // cases where cells are
2149  // inverted. In effect, both
2150  // cells think they are the left
2151  // neighbor of an edge, for
2152  // example, which leads us to
2153  // forget neighborship
2154  // information (a case that shows
2155  // this is
2156  // codim_one/hanging_nodes_02). We
2157  // store whether a cell is
2158  // inverted using the
2159  // direction_flag, so if a cell
2160  // has a false direction_flag,
2161  // then we need to invert our
2162  // selection whether we are a
2163  // left or right neighbor in all
2164  // following computations.
2165  //
2166  // first index: dimension (minus 2)
2167  // second index: local face index
2168  // third index: face_orientation (false and true)
2169  static const unsigned int left_right_offset[2][6][2] = {
2170  // quadrilateral
2171  {{0, 1}, // face 0, face_orientation = false and true
2172  {1, 0}, // face 1, face_orientation = false and true
2173  {1, 0}, // face 2, face_orientation = false and true
2174  {0, 1}, // face 3, face_orientation = false and true
2175  {0, 0}, // face 4, invalid face
2176  {0, 0}}, // face 5, invalid face
2177  // hexahedron
2178  {{0, 1}, {1, 0}, {0, 1}, {1, 0}, {0, 1}, {1, 0}}};
2179 
2180  // now create a vector of the two active
2181  // neighbors (left and right) for each face
2182  // and fill it by looping over all cells. For
2183  // cases with anisotropic refinement and more
2184  // then one cell neighboring at a given side
2185  // of the face we will automatically get the
2186  // active one on the highest level as we loop
2187  // over cells from lower levels first.
2188  const typename Triangulation<dim, spacedim>::cell_iterator dummy;
2189  std::vector<typename Triangulation<dim, spacedim>::cell_iterator>
2190  adjacent_cells(2 * triangulation.n_raw_faces(), dummy);
2191 
2192  for (const auto &cell : triangulation.cell_iterators())
2193  for (auto f : cell->face_indices())
2194  {
2195  const typename Triangulation<dim, spacedim>::face_iterator face =
2196  cell->face(f);
2197 
2198  const unsigned int offset =
2199  (cell->direction_flag() ?
2200  left_right_offset[dim - 2][f][cell->face_orientation(f)] :
2201  1 -
2202  left_right_offset[dim - 2][f][cell->face_orientation(f)]);
2203 
2204  adjacent_cells[2 * face->index() + offset] = cell;
2205 
2206  // if this cell is not refined, but the
2207  // face is, then we'll have to set our
2208  // cell as neighbor for the child faces
2209  // as well. Fortunately the normal
2210  // orientation of children will be just
2211  // the same.
2212  if (dim == 2)
2213  {
2214  if (cell->is_active() && face->has_children())
2215  {
2216  adjacent_cells[2 * face->child(0)->index() + offset] =
2217  cell;
2218  adjacent_cells[2 * face->child(1)->index() + offset] =
2219  cell;
2220  }
2221  }
2222  else // -> dim == 3
2223  {
2224  // We need the same as in 2d
2225  // here. Furthermore, if the face is
2226  // refined with cut_x or cut_y then
2227  // those children again in the other
2228  // direction, and if this cell is
2229  // refined isotropically (along the
2230  // face) then the neighbor will
2231  // (probably) be refined as cut_x or
2232  // cut_y along the face. For those
2233  // neighboring children cells, their
2234  // neighbor will be the current,
2235  // inactive cell, as our children are
2236  // too fine to be neighbors. Catch that
2237  // case by also acting on inactive
2238  // cells with isotropic refinement
2239  // along the face. If the situation
2240  // described is not present, the data
2241  // will be overwritten later on when we
2242  // visit cells on finer levels, so no
2243  // harm will be done.
2244  if (face->has_children() &&
2245  (cell->is_active() ||
2247  cell->refinement_case(), f) ==
2248  RefinementCase<dim - 1>::isotropic_refinement))
2249  {
2250  for (unsigned int c = 0; c < face->n_children(); ++c)
2251  adjacent_cells[2 * face->child(c)->index() + offset] =
2252  cell;
2253  if (face->child(0)->has_children())
2254  {
2255  adjacent_cells[2 * face->child(0)->child(0)->index() +
2256  offset] = cell;
2257  adjacent_cells[2 * face->child(0)->child(1)->index() +
2258  offset] = cell;
2259  }
2260  if (face->child(1)->has_children())
2261  {
2262  adjacent_cells[2 * face->child(1)->child(0)->index() +
2263  offset] = cell;
2264  adjacent_cells[2 * face->child(1)->child(1)->index() +
2265  offset] = cell;
2266  }
2267  } // if cell active and face refined
2268  } // else -> dim==3
2269  } // for all faces of all cells
2270 
2271  // now loop again over all cells and set the
2272  // corresponding neighbor cell. Note, that we
2273  // have to use the opposite of the
2274  // left_right_offset in this case as we want
2275  // the offset of the neighbor, not our own.
2276  for (const auto &cell : triangulation.cell_iterators())
2277  for (auto f : cell->face_indices())
2278  {
2279  const unsigned int offset =
2280  (cell->direction_flag() ?
2281  left_right_offset[dim - 2][f][cell->face_orientation(f)] :
2282  1 -
2283  left_right_offset[dim - 2][f][cell->face_orientation(f)]);
2284  cell->set_neighbor(
2285  f, adjacent_cells[2 * cell->face(f)->index() + 1 - offset]);
2286  }
2287  }
2288 
2289 
2293  template <int dim, int spacedim>
2294  static void
2296  const std::vector<CellData<dim>> & cells,
2297  const SubCellData & subcelldata,
2299  {
2300  AssertThrow(vertices.size() > 0, ExcMessage("No vertices given"));
2301  AssertThrow(cells.size() > 0, ExcMessage("No cells given"));
2302 
2303  // Check that all cells have positive volume.
2304 #ifndef _MSC_VER
2305  // TODO: The following code does not compile with MSVC. Find a way
2306  // around it
2307  if (dim == spacedim)
2308  for (unsigned int cell_no = 0; cell_no < cells.size(); ++cell_no)
2309  {
2310  // If we should check for distorted cells, then we permit them
2311  // to exist. If a cell has negative measure, then it must be
2312  // distorted (the converse is not necessarily true); hence
2313  // throw an exception if no such cells should exist.
2314  if (tria.check_for_distorted_cells)
2315  {
2316  const double cell_measure = GridTools::cell_measure<spacedim>(
2317  vertices,
2318  ArrayView<const unsigned int>(cells[cell_no].vertices));
2320  }
2321  }
2322 #endif
2323 
2324  // clear old content
2325  tria.levels.clear();
2326  tria.levels.push_back(
2327  std::make_unique<
2329 
2330  if (dim > 1)
2331  tria.faces = std::make_unique<
2333 
2334  // copy vertices
2335  tria.vertices = vertices;
2336  tria.vertices_used.assign(vertices.size(), true);
2337 
2338  // compute connectivity
2339  const auto connectivity = build_connectivity<unsigned int>(cells);
2340  const unsigned int n_cell = cells.size();
2341 
2342  // TriaObjects: lines
2343  if (dim >= 2)
2344  {
2345  auto &lines_0 = tria.faces->lines; // data structure to be filled
2346 
2347  // get connectivity between quads and lines
2348  const auto & crs = connectivity.entity_to_entities(1, 0);
2349  const unsigned int n_lines = crs.ptr.size() - 1;
2350 
2351  // allocate memory
2352  reserve_space_(lines_0, n_lines);
2353 
2354  // loop over lines
2355  for (unsigned int line = 0; line < n_lines; ++line)
2356  for (unsigned int i = crs.ptr[line], j = 0; i < crs.ptr[line + 1];
2357  ++i, ++j)
2358  lines_0.cells[line * GeometryInfo<1>::faces_per_cell + j] =
2359  crs.col[i]; // set vertex indices
2360  }
2361 
2362  // TriaObjects: quads
2363  if (dim == 3)
2364  {
2365  auto &quads_0 = tria.faces->quads; // data structures to be filled
2366  auto &faces = *tria.faces;
2367 
2368  // get connectivity between quads and lines
2369  const auto & crs = connectivity.entity_to_entities(2, 1);
2370  const unsigned int n_quads = crs.ptr.size() - 1;
2371 
2372  // allocate memory
2373  reserve_space_(quads_0, n_quads);
2374  reserve_space_(faces, 2 /*structdim*/, n_quads);
2375 
2376  // loop over all quads -> entity type, line indices/orientations
2377  for (unsigned int q = 0, k = 0; q < n_quads; ++q)
2378  {
2379  // set entity type of quads
2380  faces.quad_reference_cell[q] = connectivity.entity_types(2)[q];
2381 
2382  // loop over all its lines
2383  for (unsigned int i = crs.ptr[q], j = 0; i < crs.ptr[q + 1];
2384  ++i, ++j, ++k)
2385  {
2386  // set line index
2387  quads_0.cells[q * GeometryInfo<2>::faces_per_cell + j] =
2388  crs.col[i];
2389 
2390  // set line orientations
2391  faces.quads_line_orientations
2393  connectivity.entity_orientations(1)[k];
2394  }
2395  }
2396  }
2397 
2398  // TriaObjects/TriaLevel: cell
2399  {
2400  auto &cells_0 = tria.levels[0]->cells; // data structure to be filled
2401  auto &level = *tria.levels[0];
2402 
2403  // get connectivity between cells/faces and cells/cells
2404  const auto &crs = connectivity.entity_to_entities(dim, dim - 1);
2405  const auto &nei = connectivity.entity_to_entities(dim, dim);
2406 
2407  // in 2D optional: since in in pure QUAD meshes same line
2408  // orientations can be guaranteed
2409  const bool orientation_needed =
2410  dim == 3 ||
2411  (dim == 2 &&
2412  std::any_of(connectivity.entity_orientations(1).begin(),
2413  connectivity.entity_orientations(1).end(),
2414  [](const auto &i) { return i == 0; }));
2415 
2416  // allocate memory
2417  reserve_space_(cells_0, n_cell);
2418  reserve_space_(level, spacedim, n_cell, orientation_needed);
2419 
2420  // loop over all cells
2421  for (unsigned int cell = 0; cell < n_cell; ++cell)
2422  {
2423  // set material ids
2424  cells_0.boundary_or_material_id[cell].material_id =
2425  cells[cell].material_id;
2426 
2427  // set manifold ids
2428  cells_0.manifold_id[cell] = cells[cell].manifold_id;
2429 
2430  // set entity types
2431  level.reference_cell[cell] = connectivity.entity_types(dim)[cell];
2432 
2433  // loop over faces
2434  for (unsigned int i = crs.ptr[cell], j = 0; i < crs.ptr[cell + 1];
2435  ++i, ++j)
2436  {
2437  // set neighbor if not at boundary
2438  if (nei.col[i] != static_cast<unsigned int>(-1))
2439  level.neighbors[cell * GeometryInfo<dim>::faces_per_cell +
2440  j] = {0, nei.col[i]};
2441 
2442  // set face indices
2443  cells_0.cells[cell * GeometryInfo<dim>::faces_per_cell + j] =
2444  crs.col[i];
2445 
2446  // set face orientation if needed
2447  if (orientation_needed)
2448  level.face_orientations
2449  [cell * GeometryInfo<dim>::faces_per_cell + j] =
2450  connectivity.entity_orientations(dim - 1)[i];
2451  }
2452  }
2453  }
2454 
2455  // TriaFaces: boundary id of boundary faces
2456  if (dim > 1)
2457  {
2458  auto &bids_face = dim == 3 ?
2459  tria.faces->quads.boundary_or_material_id :
2460  tria.faces->lines.boundary_or_material_id;
2461 
2462  // count number of cells a face is belonging to
2463  std::vector<unsigned int> count(bids_face.size(), 0);
2464 
2465  // get connectivity between cells/faces
2466  const auto &crs = connectivity.entity_to_entities(dim, dim - 1);
2467 
2468  // count how many cells are adjacent to the same face
2469  for (unsigned int cell = 0; cell < cells.size(); ++cell)
2470  for (unsigned int i = crs.ptr[cell]; i < crs.ptr[cell + 1]; ++i)
2471  count[crs.col[i]]++;
2472 
2473  // loop over all faces
2474  for (unsigned int face = 0; face < count.size(); ++face)
2475  {
2476  if (count[face] != 1) // inner face
2477  continue;
2478 
2479  // boundary faces ...
2480  bids_face[face].boundary_id = 0;
2481 
2482  if (dim != 3)
2483  continue;
2484 
2485  // ... and the lines of quads in 3D
2486  const auto &crs = connectivity.entity_to_entities(2, 1);
2487  for (unsigned int i = crs.ptr[face]; i < crs.ptr[face + 1]; ++i)
2488  tria.faces->lines.boundary_or_material_id[crs.col[i]]
2489  .boundary_id = 0;
2490  }
2491  }
2492  else // 1D
2493  {
2494  static const unsigned int t_tba = static_cast<unsigned int>(-1);
2495  static const unsigned int t_inner = static_cast<unsigned int>(-2);
2496 
2497  std::vector<unsigned int> type(vertices.size(), t_tba);
2498 
2499  const auto &crs = connectivity.entity_to_entities(1, 0);
2500 
2501  for (unsigned int cell = 0; cell < cells.size(); ++cell)
2502  for (unsigned int i = crs.ptr[cell], j = 0; i < crs.ptr[cell + 1];
2503  ++i, ++j)
2504  if (type[crs.col[i]] != t_inner)
2505  type[crs.col[i]] = type[crs.col[i]] == t_tba ? j : t_inner;
2506 
2507  for (unsigned int face = 0; face < type.size(); ++face)
2508  {
2509  // note: we also treat manifolds here!?
2510  (*tria.vertex_to_manifold_id_map_1d)[face] =
2512  if (type[face] != t_inner && type[face] != t_tba)
2513  (*tria.vertex_to_boundary_id_map_1d)[face] = type[face];
2514  }
2515  }
2516 
2517  // SubCellData: line
2518  if (dim >= 2)
2519  process_subcelldata(connectivity.entity_to_entities(1, 0),
2520  tria.faces->lines,
2521  subcelldata.boundary_lines);
2522 
2523  // SubCellData: quad
2524  if (dim == 3)
2525  process_subcelldata(connectivity.entity_to_entities(2, 0),
2526  tria.faces->quads,
2527  subcelldata.boundary_quads);
2528  }
2529 
2530 
2531  template <int structdim, typename T>
2532  static void
2534  const CRS<T> & crs,
2535  TriaObjects & obj,
2536  const std::vector<CellData<structdim>> &boundary_objects_in)
2537  {
2538  AssertDimension(obj.structdim, structdim);
2539 
2540  if (boundary_objects_in.size() == 0)
2541  return; // empty subcelldata -> nothing to do
2542 
2543  // pre-sort subcelldata
2544  auto boundary_objects = boundary_objects_in;
2545 
2546  // ... sort vertices
2547  for (auto &boundary_object : boundary_objects)
2548  std::sort(boundary_object.vertices.begin(),
2549  boundary_object.vertices.end());
2550 
2551  // ... sort cells
2552  std::sort(boundary_objects.begin(),
2553  boundary_objects.end(),
2554  [](const auto &a, const auto &b) {
2555  return a.vertices < b.vertices;
2556  });
2557 
2558  unsigned int counter = 0;
2559 
2560  std::vector<unsigned int> key;
2562 
2563  for (unsigned int o = 0; o < obj.n_objects(); ++o)
2564  {
2565  auto &boundary_id = obj.boundary_or_material_id[o].boundary_id;
2566  auto &manifold_id = obj.manifold_id[o];
2567 
2568  // assert that object has not been visited yet and its value
2569  // has not been modified yet
2570  AssertThrow(boundary_id == 0 ||
2572  ExcNotImplemented());
2574  ExcNotImplemented());
2575 
2576  // create key
2577  key.assign(crs.col.data() + crs.ptr[o],
2578  crs.col.data() + crs.ptr[o + 1]);
2579  std::sort(key.begin(), key.end());
2580 
2581  // is subcelldata provided? -> binary search
2582  const auto subcell_object =
2583  std::lower_bound(boundary_objects.begin(),
2584  boundary_objects.end(),
2585  key,
2586  [&](const auto &cell, const auto &key) {
2587  return cell.vertices < key;
2588  });
2589 
2590  // no subcelldata provided for this object
2591  if (subcell_object == boundary_objects.end() ||
2592  subcell_object->vertices != key)
2593  continue;
2594 
2595  counter++;
2596 
2597  // set manifold id
2598  manifold_id = subcell_object->manifold_id;
2599 
2600  // set boundary id
2601  if (subcell_object->boundary_id !=
2603  {
2605  ExcNotImplemented());
2606  boundary_id = subcell_object->boundary_id;
2607  }
2608  }
2609 
2610  // make sure that all subcelldata entries have been processed
2611  // TODO: this is not guaranteed, why?
2612  // AssertDimension(counter, boundary_objects_in.size());
2613  }
2614 
2615 
2616 
2617  static void
2619  const unsigned structdim,
2620  const unsigned int size)
2621  {
2622  const unsigned int dim = faces.dim;
2623 
2624  const unsigned int max_faces_per_cell = 2 * structdim;
2625 
2626  if (dim == 3 && structdim == 2)
2627  {
2628  // quad entity types
2629  faces.quad_reference_cell.assign(size,
2631 
2632  // quad line orientations
2633  faces.quads_line_orientations.assign(size * max_faces_per_cell, -1);
2634  }
2635  }
2636 
2637 
2638 
2639  static void
2641  const unsigned int spacedim,
2642  const unsigned int size,
2643  const bool orientation_needed)
2644  {
2645  const unsigned int dim = level.dim;
2646 
2647  const unsigned int max_faces_per_cell = 2 * dim;
2648 
2649  level.active_cell_indices.assign(size, -1);
2650  level.subdomain_ids.assign(size, 0);
2651  level.level_subdomain_ids.assign(size, 0);
2652 
2653  level.refine_flags.assign(size, false);
2654  level.coarsen_flags.assign(size, false);
2655 
2656  level.parents.assign((size + 1) / 2, -1);
2657 
2658  if (dim < spacedim)
2659  level.direction_flags.assign(size, true);
2660 
2661  level.neighbors.assign(size * max_faces_per_cell, {-1, -1});
2662 
2663  level.reference_cell.assign(size, ::ReferenceCells::Invalid);
2664 
2665  if (orientation_needed)
2666  level.face_orientations.assign(size * max_faces_per_cell, -1);
2667 
2668  level.global_active_cell_indices.assign(size,
2670  level.global_level_cell_indices.assign(size,
2672  }
2673 
2674 
2675 
2676  static void
2677  reserve_space_(TriaObjects &obj, const unsigned int size)
2678  {
2679  const unsigned int structdim = obj.structdim;
2680 
2681  const unsigned int max_children_per_cell = 1 << structdim;
2682  const unsigned int max_faces_per_cell = 2 * structdim;
2683 
2684  obj.used.assign(size, true);
2685  obj.boundary_or_material_id.assign(
2686  size,
2688  BoundaryOrMaterialId());
2689  obj.manifold_id.assign(size, -1);
2690  obj.user_flags.assign(size, false);
2691  obj.user_data.resize(size);
2692 
2693  if (structdim > 1) // TODO: why?
2694  obj.refinement_cases.assign(size, 0);
2695 
2696  obj.children.assign(max_children_per_cell / 2 * size, -1);
2697 
2698  obj.cells.assign(max_faces_per_cell * size, -1);
2699 
2700  if (structdim <= 2)
2701  {
2702  obj.next_free_single = size - 1;
2703  obj.next_free_pair = 0;
2704  obj.reverse_order_next_free_single = true;
2705  }
2706  else
2707  {
2708  obj.next_free_single = obj.next_free_pair = 0;
2709  }
2710  }
2711 
2712 
2728  template <int spacedim>
2729  static void delete_children(
2732  std::vector<unsigned int> &,
2733  std::vector<unsigned int> &)
2734  {
2735  const unsigned int dim = 1;
2736 
2737  // first we need to reset the
2738  // neighbor pointers of the
2739  // neighbors of this cell's
2740  // children to this cell. This is
2741  // different for one dimension,
2742  // since there neighbors can have a
2743  // refinement level differing from
2744  // that of this cell's children by
2745  // more than one level.
2746 
2747  Assert(!cell->child(0)->has_children() &&
2748  !cell->child(1)->has_children(),
2749  ExcInternalError());
2750 
2751  // first do it for the cells to the
2752  // left
2753  if (cell->neighbor(0).state() == IteratorState::valid)
2754  if (cell->neighbor(0)->has_children())
2755  {
2757  cell->neighbor(0);
2758  Assert(neighbor->level() == cell->level(), ExcInternalError());
2759 
2760  // right child
2761  neighbor = neighbor->child(1);
2762  while (true)
2763  {
2764  Assert(neighbor->neighbor(1) == cell->child(0),
2765  ExcInternalError());
2766  neighbor->set_neighbor(1, cell);
2767 
2768  // move on to further
2769  // children on the
2770  // boundary between this
2771  // cell and its neighbor
2772  if (neighbor->has_children())
2773  neighbor = neighbor->child(1);
2774  else
2775  break;
2776  }
2777  }
2778 
2779  // now do it for the cells to the
2780  // left
2781  if (cell->neighbor(1).state() == IteratorState::valid)
2782  if (cell->neighbor(1)->has_children())
2783  {
2785  cell->neighbor(1);
2786  Assert(neighbor->level() == cell->level(), ExcInternalError());
2787 
2788  // left child
2789  neighbor = neighbor->child(0);
2790  while (true)
2791  {
2792  Assert(neighbor->neighbor(0) == cell->child(1),
2793  ExcInternalError());
2794  neighbor->set_neighbor(0, 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(0);
2802  else
2803  break;
2804  }
2805  }
2806 
2807 
2808  // delete the vertex which will not
2809  // be needed anymore. This vertex
2810  // is the second of the first child
2811  triangulation.vertices_used[cell->child(0)->vertex_index(1)] = false;
2812 
2813  // invalidate children. clear user
2814  // pointers, to avoid that they may
2815  // appear at unwanted places later
2816  // on...
2817  for (unsigned int child = 0; child < cell->n_children(); ++child)
2818  {
2819  cell->child(child)->clear_user_data();
2820  cell->child(child)->clear_user_flag();
2821  cell->child(child)->clear_used_flag();
2822  }
2823 
2824 
2825  // delete pointer to children
2826  cell->clear_children();
2827  cell->clear_user_flag();
2828  }
2829 
2830 
2831 
2832  template <int spacedim>
2833  static void delete_children(
2836  std::vector<unsigned int> & line_cell_count,
2837  std::vector<unsigned int> &)
2838  {
2839  const unsigned int dim = 2;
2840  const RefinementCase<dim> ref_case = cell->refinement_case();
2841 
2842  Assert(line_cell_count.size() == triangulation.n_raw_lines(),
2843  ExcInternalError());
2844 
2845  // vectors to hold all lines which
2846  // may be deleted
2847  std::vector<typename Triangulation<dim, spacedim>::line_iterator>
2848  lines_to_delete(0);
2849 
2850  lines_to_delete.reserve(4 * 2 + 4);
2851 
2852  // now we decrease the counters for
2853  // lines contained in the child
2854  // cells
2855  for (unsigned int c = 0; c < cell->n_children(); ++c)
2856  {
2858  cell->child(c);
2859  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
2860  --line_cell_count[child->line_index(l)];
2861  }
2862 
2863 
2864  // delete the vertex which will not
2865  // be needed anymore. This vertex
2866  // is the second of the second line
2867  // of the first child, if the cell
2868  // is refined with cut_xy, else there
2869  // is no inner vertex.
2870  // additionally delete unneeded inner
2871  // lines
2872  if (ref_case == RefinementCase<dim>::cut_xy)
2873  {
2875  .vertices_used[cell->child(0)->line(1)->vertex_index(1)] = false;
2876 
2877  lines_to_delete.push_back(cell->child(0)->line(1));
2878  lines_to_delete.push_back(cell->child(0)->line(3));
2879  lines_to_delete.push_back(cell->child(3)->line(0));
2880  lines_to_delete.push_back(cell->child(3)->line(2));
2881  }
2882  else
2883  {
2884  unsigned int inner_face_no =
2885  ref_case == RefinementCase<dim>::cut_x ? 1 : 3;
2886 
2887  // the inner line will not be
2888  // used any more
2889  lines_to_delete.push_back(cell->child(0)->line(inner_face_no));
2890  }
2891 
2892  // invalidate children
2893  for (unsigned int child = 0; child < cell->n_children(); ++child)
2894  {
2895  cell->child(child)->clear_user_data();
2896  cell->child(child)->clear_user_flag();
2897  cell->child(child)->clear_used_flag();
2898  }
2899 
2900 
2901  // delete pointer to children
2902  cell->clear_children();
2903  cell->clear_refinement_case();
2904  cell->clear_user_flag();
2905 
2906  // look at the refinement of outer
2907  // lines. if nobody needs those
2908  // anymore we can add them to the
2909  // list of lines to be deleted.
2910  for (unsigned int line_no = 0;
2911  line_no < GeometryInfo<dim>::lines_per_cell;
2912  ++line_no)
2913  {
2915  cell->line(line_no);
2916 
2917  if (line->has_children())
2918  {
2919  // if one of the cell counters is
2920  // zero, the other has to be as well
2921 
2922  Assert((line_cell_count[line->child_index(0)] == 0 &&
2923  line_cell_count[line->child_index(1)] == 0) ||
2924  (line_cell_count[line->child_index(0)] > 0 &&
2925  line_cell_count[line->child_index(1)] > 0),
2926  ExcInternalError());
2927 
2928  if (line_cell_count[line->child_index(0)] == 0)
2929  {
2930  for (unsigned int c = 0; c < 2; ++c)
2931  Assert(!line->child(c)->has_children(),
2932  ExcInternalError());
2933 
2934  // we may delete the line's
2935  // children and the middle vertex
2936  // as no cell references them
2937  // anymore
2939  .vertices_used[line->child(0)->vertex_index(1)] = false;
2940 
2941  lines_to_delete.push_back(line->child(0));
2942  lines_to_delete.push_back(line->child(1));
2943 
2944  line->clear_children();
2945  }
2946  }
2947  }
2948 
2949  // finally, delete unneeded lines
2950 
2951  // clear user pointers, to avoid that
2952  // they may appear at unwanted places
2953  // later on...
2954  // same for user flags, then finally
2955  // delete the lines
2956  typename std::vector<
2958  line = lines_to_delete.begin(),
2959  endline = lines_to_delete.end();
2960  for (; line != endline; ++line)
2961  {
2962  (*line)->clear_user_data();
2963  (*line)->clear_user_flag();
2964  (*line)->clear_used_flag();
2965  }
2966  }
2967 
2968 
2969 
2970  template <int spacedim>
2971  static void delete_children(
2974  std::vector<unsigned int> & line_cell_count,
2975  std::vector<unsigned int> & quad_cell_count)
2976  {
2977  const unsigned int dim = 3;
2978 
2979  Assert(line_cell_count.size() == triangulation.n_raw_lines(),
2980  ExcInternalError());
2981  Assert(quad_cell_count.size() == triangulation.n_raw_quads(),
2982  ExcInternalError());
2983 
2984  // first of all, we store the RefineCase of
2985  // this cell
2986  const RefinementCase<dim> ref_case = cell->refinement_case();
2987  // vectors to hold all lines and quads which
2988  // may be deleted
2989  std::vector<typename Triangulation<dim, spacedim>::line_iterator>
2990  lines_to_delete(0);
2991  std::vector<typename Triangulation<dim, spacedim>::quad_iterator>
2992  quads_to_delete(0);
2993 
2994  lines_to_delete.reserve(12 * 2 + 6 * 4 + 6);
2995  quads_to_delete.reserve(6 * 4 + 12);
2996 
2997  // now we decrease the counters for lines and
2998  // quads contained in the child cells
2999  for (unsigned int c = 0; c < cell->n_children(); ++c)
3000  {
3002  cell->child(c);
3003  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
3004  --line_cell_count[child->line_index(l)];
3005  for (auto f : GeometryInfo<dim>::face_indices())
3006  --quad_cell_count[child->quad_index(f)];
3007  }
3008 
3010  // delete interior quads and lines and the
3011  // interior vertex, depending on the
3012  // refinement case of the cell
3013  //
3014  // for append quads and lines: only append
3015  // them to the list of objects to be deleted
3016 
3017  switch (ref_case)
3018  {
3020  quads_to_delete.push_back(cell->child(0)->face(1));
3021  break;
3023  quads_to_delete.push_back(cell->child(0)->face(3));
3024  break;
3026  quads_to_delete.push_back(cell->child(0)->face(5));
3027  break;
3029  quads_to_delete.push_back(cell->child(0)->face(1));
3030  quads_to_delete.push_back(cell->child(0)->face(3));
3031  quads_to_delete.push_back(cell->child(3)->face(0));
3032  quads_to_delete.push_back(cell->child(3)->face(2));
3033 
3034  lines_to_delete.push_back(cell->child(0)->line(11));
3035  break;
3037  quads_to_delete.push_back(cell->child(0)->face(1));
3038  quads_to_delete.push_back(cell->child(0)->face(5));
3039  quads_to_delete.push_back(cell->child(3)->face(0));
3040  quads_to_delete.push_back(cell->child(3)->face(4));
3041 
3042  lines_to_delete.push_back(cell->child(0)->line(5));
3043  break;
3045  quads_to_delete.push_back(cell->child(0)->face(3));
3046  quads_to_delete.push_back(cell->child(0)->face(5));
3047  quads_to_delete.push_back(cell->child(3)->face(2));
3048  quads_to_delete.push_back(cell->child(3)->face(4));
3049 
3050  lines_to_delete.push_back(cell->child(0)->line(7));
3051  break;
3053  quads_to_delete.push_back(cell->child(0)->face(1));
3054  quads_to_delete.push_back(cell->child(2)->face(1));
3055  quads_to_delete.push_back(cell->child(4)->face(1));
3056  quads_to_delete.push_back(cell->child(6)->face(1));
3057 
3058  quads_to_delete.push_back(cell->child(0)->face(3));
3059  quads_to_delete.push_back(cell->child(1)->face(3));
3060  quads_to_delete.push_back(cell->child(4)->face(3));
3061  quads_to_delete.push_back(cell->child(5)->face(3));
3062 
3063  quads_to_delete.push_back(cell->child(0)->face(5));
3064  quads_to_delete.push_back(cell->child(1)->face(5));
3065  quads_to_delete.push_back(cell->child(2)->face(5));
3066  quads_to_delete.push_back(cell->child(3)->face(5));
3067 
3068  lines_to_delete.push_back(cell->child(0)->line(5));
3069  lines_to_delete.push_back(cell->child(0)->line(7));
3070  lines_to_delete.push_back(cell->child(0)->line(11));
3071  lines_to_delete.push_back(cell->child(7)->line(0));
3072  lines_to_delete.push_back(cell->child(7)->line(2));
3073  lines_to_delete.push_back(cell->child(7)->line(8));
3074  // delete the vertex which will not
3075  // be needed anymore. This vertex
3076  // is the vertex at the heart of
3077  // this cell, which is the sixth of
3078  // the first child
3079  triangulation.vertices_used[cell->child(0)->vertex_index(7)] =
3080  false;
3081  break;
3082  default:
3083  // only remaining case is
3084  // no_refinement, thus an error
3085  Assert(false, ExcInternalError());
3086  break;
3087  }
3088 
3089 
3090  // invalidate children
3091  for (unsigned int child = 0; child < cell->n_children(); ++child)
3092  {
3093  cell->child(child)->clear_user_data();
3094  cell->child(child)->clear_user_flag();
3095 
3096  for (auto f : GeometryInfo<dim>::face_indices())
3097  {
3098  // set flags denoting deviations from
3099  // standard orientation of faces back
3100  // to initialization values
3101  cell->child(child)->set_face_orientation(f, true);
3102  cell->child(child)->set_face_flip(f, false);
3103  cell->child(child)->set_face_rotation(f, false);
3104  }
3105 
3106  cell->child(child)->clear_used_flag();
3107  }
3108 
3109 
3110  // delete pointer to children
3111  cell->clear_children();
3112  cell->clear_refinement_case();
3113  cell->clear_user_flag();
3114 
3115  // so far we only looked at inner quads,
3116  // lines and vertices. Now we have to
3117  // consider outer ones as well. here, we have
3118  // to check, whether there are other cells
3119  // still needing these objects. otherwise we
3120  // can delete them. first for quads (and
3121  // their inner lines).
3122 
3123  for (const unsigned int quad_no : GeometryInfo<dim>::face_indices())
3124  {
3126  cell->face(quad_no);
3127 
3128  Assert(
3129  (GeometryInfo<dim>::face_refinement_case(ref_case, quad_no) &&
3130  quad->has_children()) ||
3131  GeometryInfo<dim>::face_refinement_case(ref_case, quad_no) ==
3133  ExcInternalError());
3134 
3135  switch (quad->refinement_case())
3136  {
3137  case RefinementCase<dim - 1>::no_refinement:
3138  // nothing to do as the quad
3139  // is not refined
3140  break;
3141  case RefinementCase<dim - 1>::cut_x:
3142  case RefinementCase<dim - 1>::cut_y:
3143  {
3144  // if one of the cell counters is
3145  // zero, the other has to be as
3146  // well
3147  Assert((quad_cell_count[quad->child_index(0)] == 0 &&
3148  quad_cell_count[quad->child_index(1)] == 0) ||
3149  (quad_cell_count[quad->child_index(0)] > 0 &&
3150  quad_cell_count[quad->child_index(1)] > 0),
3151  ExcInternalError());
3152  // it might be, that the quad is
3153  // refined twice anisotropically,
3154  // first check, whether we may
3155  // delete possible grand_children
3156  unsigned int deleted_grandchildren = 0;
3157  unsigned int number_of_child_refinements = 0;
3158 
3159  for (unsigned int c = 0; c < 2; ++c)
3160  if (quad->child(c)->has_children())
3161  {
3162  ++number_of_child_refinements;
3163  // if one of the cell counters is
3164  // zero, the other has to be as
3165  // well
3166  Assert(
3167  (quad_cell_count[quad->child(c)->child_index(0)] ==
3168  0 &&
3169  quad_cell_count[quad->child(c)->child_index(1)] ==
3170  0) ||
3171  (quad_cell_count[quad->child(c)->child_index(0)] >
3172  0 &&
3173  quad_cell_count[quad->child(c)->child_index(1)] >
3174  0),
3175  ExcInternalError());
3176  if (quad_cell_count[quad->child(c)->child_index(0)] ==
3177  0)
3178  {
3179  // Assert, that the two
3180  // anisotropic
3181  // refinements add up to
3182  // isotropic refinement
3183  Assert(quad->refinement_case() +
3184  quad->child(c)->refinement_case() ==
3186  ExcInternalError());
3187  // we may delete the
3188  // quad's children and
3189  // the inner line as no
3190  // cell references them
3191  // anymore
3192  quads_to_delete.push_back(
3193  quad->child(c)->child(0));
3194  quads_to_delete.push_back(
3195  quad->child(c)->child(1));
3196  if (quad->child(c)->refinement_case() ==
3198  lines_to_delete.push_back(
3199  quad->child(c)->child(0)->line(1));
3200  else
3201  lines_to_delete.push_back(
3202  quad->child(c)->child(0)->line(3));
3203  quad->child(c)->clear_children();
3204  quad->child(c)->clear_refinement_case();
3205  ++deleted_grandchildren;
3206  }
3207  }
3208  // if no grandchildren are left, we
3209  // may as well delete the
3210  // refinement of the inner line
3211  // between our children and the
3212  // corresponding vertex
3213  if (number_of_child_refinements > 0 &&
3214  deleted_grandchildren == number_of_child_refinements)
3215  {
3217  middle_line;
3218  if (quad->refinement_case() == RefinementCase<2>::cut_x)
3219  middle_line = quad->child(0)->line(1);
3220  else
3221  middle_line = quad->child(0)->line(3);
3222 
3223  lines_to_delete.push_back(middle_line->child(0));
3224  lines_to_delete.push_back(middle_line->child(1));
3226  .vertices_used[middle_vertex_index<dim, spacedim>(
3227  middle_line)] = false;
3228  middle_line->clear_children();
3229  }
3230 
3231  // now consider the direct children
3232  // of the given quad
3233  if (quad_cell_count[quad->child_index(0)] == 0)
3234  {
3235  // we may delete the quad's
3236  // children and the inner line
3237  // as no cell references them
3238  // anymore
3239  quads_to_delete.push_back(quad->child(0));
3240  quads_to_delete.push_back(quad->child(1));
3241  if (quad->refinement_case() == RefinementCase<2>::cut_x)
3242  lines_to_delete.push_back(quad->child(0)->line(1));
3243  else
3244  lines_to_delete.push_back(quad->child(0)->line(3));
3245 
3246  // if the counters just dropped
3247  // to zero, otherwise the
3248  // children would have been
3249  // deleted earlier, then this
3250  // cell's children must have
3251  // contained the anisotropic
3252  // quad children. thus, if
3253  // those have again anisotropic
3254  // children, which are in
3255  // effect isotropic children of
3256  // the original quad, those are
3257  // still needed by a
3258  // neighboring cell and we
3259  // cannot delete them. instead,
3260  // we have to reset this quad's
3261  // refine case to isotropic and
3262  // set the children
3263  // accordingly.
3264  if (quad->child(0)->has_children())
3265  if (quad->refinement_case() ==
3267  {
3268  // now evereything is
3269  // quite complicated. we
3270  // have the children
3271  // numbered according to
3272  //
3273  // *---*---*
3274  // |n+1|m+1|
3275  // *---*---*
3276  // | n | m |
3277  // *---*---*
3278  //
3279  // from the original
3280  // anisotropic
3281  // refinement. we have to
3282  // reorder them as
3283  //
3284  // *---*---*
3285  // | m |m+1|
3286  // *---*---*
3287  // | n |n+1|
3288  // *---*---*
3289  //
3290  // for isotropic refinement.
3291  //
3292  // this is a bit ugly, of
3293  // course: loop over all
3294  // cells on all levels
3295  // and look for faces n+1
3296  // (switch_1) and m
3297  // (switch_2).
3298  const typename Triangulation<dim, spacedim>::
3299  quad_iterator switch_1 =
3300  quad->child(0)->child(1),
3301  switch_2 =
3302  quad->child(1)->child(0);
3303 
3304  Assert(!switch_1->has_children(),
3305  ExcInternalError());
3306  Assert(!switch_2->has_children(),
3307  ExcInternalError());
3308 
3309  const int switch_1_index = switch_1->index();
3310  const int switch_2_index = switch_2->index();
3311  for (unsigned int l = 0;
3312  l < triangulation.levels.size();
3313  ++l)
3314  for (unsigned int h = 0;
3315  h <
3316  triangulation.levels[l]->cells.n_objects();
3317  ++h)
3318  for (const unsigned int q :
3320  {
3321  const int index =
3322  triangulation.levels[l]
3323  ->cells.get_bounding_object_indices(
3324  h)[q];
3325  if (index == switch_1_index)
3326  triangulation.levels[l]
3327  ->cells.get_bounding_object_indices(
3328  h)[q] = switch_2_index;
3329  else if (index == switch_2_index)
3330  triangulation.levels[l]
3331  ->cells.get_bounding_object_indices(
3332  h)[q] = switch_1_index;
3333  }
3334  // now we have to copy
3335  // all information of the
3336  // two quads
3337  const int switch_1_lines[4] = {
3338  static_cast<signed int>(
3339  switch_1->line_index(0)),
3340  static_cast<signed int>(
3341  switch_1->line_index(1)),
3342  static_cast<signed int>(
3343  switch_1->line_index(2)),
3344  static_cast<signed int>(
3345  switch_1->line_index(3))};
3346  const bool switch_1_line_orientations[4] = {
3347  switch_1->line_orientation(0),
3348  switch_1->line_orientation(1),
3349  switch_1->line_orientation(2),
3350  switch_1->line_orientation(3)};
3351  const types::boundary_id switch_1_boundary_id =
3352  switch_1->boundary_id();
3353  const unsigned int switch_1_user_index =
3354  switch_1->user_index();
3355  const bool switch_1_user_flag =
3356  switch_1->user_flag_set();
3357 
3358  switch_1->set_bounding_object_indices(
3359  {switch_2->line_index(0),
3360  switch_2->line_index(1),
3361  switch_2->line_index(2),
3362  switch_2->line_index(3)});
3363  switch_1->set_line_orientation(
3364  0, switch_2->line_orientation(0));
3365  switch_1->set_line_orientation(
3366  1, switch_2->line_orientation(1));
3367  switch_1->set_line_orientation(
3368  2, switch_2->line_orientation(2));
3369  switch_1->set_line_orientation(
3370  3, switch_2->line_orientation(3));
3371  switch_1->set_boundary_id_internal(
3372  switch_2->boundary_id());
3373  switch_1->set_manifold_id(
3374  switch_2->manifold_id());
3375  switch_1->set_user_index(switch_2->user_index());
3376  if (switch_2->user_flag_set())
3377  switch_1->set_user_flag();
3378  else
3379  switch_1->clear_user_flag();
3380 
3381  switch_2->set_bounding_object_indices(
3382  {switch_1_lines[0],
3383  switch_1_lines[1],
3384  switch_1_lines[2],
3385  switch_1_lines[3]});
3386  switch_2->set_line_orientation(
3387  0, switch_1_line_orientations[0]);
3388  switch_2->set_line_orientation(
3389  1, switch_1_line_orientations[1]);
3390  switch_2->set_line_orientation(
3391  2, switch_1_line_orientations[2]);
3392  switch_2->set_line_orientation(
3393  3, switch_1_line_orientations[3]);
3394  switch_2->set_boundary_id_internal(
3395  switch_1_boundary_id);
3396  switch_2->set_manifold_id(
3397  switch_1->manifold_id());
3398  switch_2->set_user_index(switch_1_user_index);
3399  if (switch_1_user_flag)
3400  switch_2->set_user_flag();
3401  else
3402  switch_2->clear_user_flag();
3403 
3404  const unsigned int child_0 =
3405  quad->child(0)->child_index(0);
3406  const unsigned int child_2 =
3407  quad->child(1)->child_index(0);
3408  quad->clear_children();
3409  quad->clear_refinement_case();
3410  quad->set_refinement_case(
3412  quad->set_children(0, child_0);
3413  quad->set_children(2, child_2);
3414  std::swap(quad_cell_count[child_0 + 1],
3415  quad_cell_count[child_2]);
3416  }
3417  else
3418  {
3419  // the face was refined
3420  // with cut_y, thus the
3421  // children are already
3422  // in correct order. we
3423  // only have to set them
3424  // correctly, deleting
3425  // the indirection of two
3426  // anisotropic refinement
3427  // and going directly
3428  // from the quad to
3429  // isotropic children
3430  const unsigned int child_0 =
3431  quad->child(0)->child_index(0);
3432  const unsigned int child_2 =
3433  quad->child(1)->child_index(0);
3434  quad->clear_children();
3435  quad->clear_refinement_case();
3436  quad->set_refinement_case(
3438  quad->set_children(0, child_0);
3439  quad->set_children(2, child_2);
3440  }
3441  else
3442  {
3443  quad->clear_children();
3444  quad->clear_refinement_case();
3445  }
3446  }
3447  break;
3448  }
3449  case RefinementCase<dim - 1>::cut_xy:
3450  {
3451  // if one of the cell counters is
3452  // zero, the others have to be as
3453  // well
3454 
3455  Assert((quad_cell_count[quad->child_index(0)] == 0 &&
3456  quad_cell_count[quad->child_index(1)] == 0 &&
3457  quad_cell_count[quad->child_index(2)] == 0 &&
3458  quad_cell_count[quad->child_index(3)] == 0) ||
3459  (quad_cell_count[quad->child_index(0)] > 0 &&
3460  quad_cell_count[quad->child_index(1)] > 0 &&
3461  quad_cell_count[quad->child_index(2)] > 0 &&
3462  quad_cell_count[quad->child_index(3)] > 0),
3463  ExcInternalError());
3464 
3465  if (quad_cell_count[quad->child_index(0)] == 0)
3466  {
3467  // we may delete the quad's
3468  // children, the inner lines
3469  // and the middle vertex as no
3470  // cell references them anymore
3471  lines_to_delete.push_back(quad->child(0)->line(1));
3472  lines_to_delete.push_back(quad->child(3)->line(0));
3473  lines_to_delete.push_back(quad->child(0)->line(3));
3474  lines_to_delete.push_back(quad->child(3)->line(2));
3475 
3476  for (unsigned int child = 0; child < quad->n_children();
3477  ++child)
3478  quads_to_delete.push_back(quad->child(child));
3479 
3481  .vertices_used[quad->child(0)->vertex_index(3)] =
3482  false;
3483 
3484  quad->clear_children();
3485  quad->clear_refinement_case();
3486  }
3487  }
3488  break;
3489 
3490  default:
3491  Assert(false, ExcInternalError());
3492  break;
3493  }
3494  }
3495 
3496  // now we repeat a similar procedure
3497  // for the outer lines of this cell.
3498 
3499  // if in debug mode: check that each
3500  // of the lines for which we consider
3501  // deleting the children in fact has
3502  // children (the bits/coarsening_3d
3503  // test tripped over this initially)
3504  for (unsigned int line_no = 0;
3505  line_no < GeometryInfo<dim>::lines_per_cell;
3506  ++line_no)
3507  {
3509  cell->line(line_no);
3510 
3511  Assert(
3512  (GeometryInfo<dim>::line_refinement_case(ref_case, line_no) &&
3513  line->has_children()) ||
3514  GeometryInfo<dim>::line_refinement_case(ref_case, line_no) ==
3516  ExcInternalError());
3517 
3518  if (line->has_children())
3519  {
3520  // if one of the cell counters is
3521  // zero, the other has to be as well
3522 
3523  Assert((line_cell_count[line->child_index(0)] == 0 &&
3524  line_cell_count[line->child_index(1)] == 0) ||
3525  (line_cell_count[line->child_index(0)] > 0 &&
3526  line_cell_count[line->child_index(1)] > 0),
3527  ExcInternalError());
3528 
3529  if (line_cell_count[line->child_index(0)] == 0)
3530  {
3531  for (unsigned int c = 0; c < 2; ++c)
3532  Assert(!line->child(c)->has_children(),
3533  ExcInternalError());
3534 
3535  // we may delete the line's
3536  // children and the middle vertex
3537  // as no cell references them
3538  // anymore
3540  .vertices_used[line->child(0)->vertex_index(1)] = false;
3541 
3542  lines_to_delete.push_back(line->child(0));
3543  lines_to_delete.push_back(line->child(1));
3544 
3545  line->clear_children();
3546  }
3547  }
3548  }
3549 
3550  // finally, delete unneeded quads and lines
3551 
3552  // clear user pointers, to avoid that
3553  // they may appear at unwanted places
3554  // later on...
3555  // same for user flags, then finally
3556  // delete the quads and lines
3557  typename std::vector<
3559  line = lines_to_delete.begin(),
3560  endline = lines_to_delete.end();
3561  for (; line != endline; ++line)
3562  {
3563  (*line)->clear_user_data();
3564  (*line)->clear_user_flag();
3565  (*line)->clear_used_flag();
3566  }
3567 
3568  typename std::vector<
3570  quad = quads_to_delete.begin(),
3571  endquad = quads_to_delete.end();
3572  for (; quad != endquad; ++quad)
3573  {
3574  (*quad)->clear_user_data();
3575  (*quad)->clear_children();
3576  (*quad)->clear_refinement_case();
3577  (*quad)->clear_user_flag();
3578  (*quad)->clear_used_flag();
3579  }
3580  }
3581 
3582 
3600  template <int spacedim>
3601  static void create_children(
3603  unsigned int & next_unused_vertex,
3605  &next_unused_line,
3607  &next_unused_cell,
3608  const typename Triangulation<2, spacedim>::cell_iterator &cell)
3609  {
3610  const unsigned int dim = 2;
3611  // clear refinement flag
3612  const RefinementCase<dim> ref_case = cell->refine_flag_set();
3613  cell->clear_refine_flag();
3614 
3615  /* For the refinement process: since we go the levels up from the
3616  lowest, there are (unlike above) only two possibilities: a neighbor
3617  cell is on the same level or one level up (in both cases, it may or
3618  may not be refined later on, but we don't care here).
3619 
3620  First:
3621  Set up an array of the 3x3 vertices, which are distributed on the
3622  cell (the array consists of indices into the @p{vertices} std::vector
3623 
3624  2--7--3
3625  | | |
3626  4--8--5
3627  | | |
3628  0--6--1
3629 
3630  note: in case of cut_x or cut_y not all these vertices are needed for
3631  the new cells
3632 
3633  Second:
3634  Set up an array of the new lines (the array consists of iterator
3635  pointers into the lines arrays)
3636 
3637  .-6-.-7-. The directions are: .->-.->-.
3638  1 9 3 ^ ^ ^
3639  .-10.11-. .->-.->-.
3640  0 8 2 ^ ^ ^
3641  .-4-.-5-. .->-.->-.
3642 
3643  cut_x:
3644  .-4-.-5-.
3645  | | |
3646  0 6 1
3647  | | |
3648  .-2-.-3-.
3649 
3650  cut_y:
3651  .---5---.
3652  1 3
3653  .---6---.
3654  0 2
3655  .---4---.
3656 
3657 
3658  Third:
3659  Set up an array of neighbors:
3660 
3661  6 7
3662  .--.--.
3663  1| | |3
3664  .--.--.
3665  0| | |2
3666  .--.--.
3667  4 5
3668 
3669  We need this array for two reasons: first to get the lines which will
3670  bound the four subcells (if the neighboring cell is refined, these
3671  lines already exist), and second to update neighborship information.
3672  Since if a neighbor is not refined, its neighborship record only
3673  points to the present, unrefined, cell rather than the children we
3674  are presently creating, we only need the neighborship information
3675  if the neighbor cells are refined. In all other cases, we store
3676  the unrefined neighbor address
3677 
3678  We also need for every neighbor (if refined) which number among its
3679  neighbors the present (unrefined) cell has, since that number is to
3680  be replaced and because that also is the number of the subline which
3681  will be the interface between that neighbor and the to be created
3682  cell. We will store this number (between 0 and 3) in the field
3683  @p{neighbors_neighbor}.
3684 
3685  It would be sufficient to use the children of the common line to the
3686  neighbor, if we only wanted to get the new sublines and the new
3687  vertex, but because we need to update the neighborship information of
3688  the two refined subcells of the neighbor, we need to search these
3689  anyway.
3690 
3691  Convention:
3692  The created children are numbered like this:
3693 
3694  .--.--.
3695  |2 . 3|
3696  .--.--.
3697  |0 | 1|
3698  .--.--.
3699  */
3700  // collect the
3701  // indices of the
3702  // eight
3703  // surrounding
3704  // vertices
3705  // 2--7--3
3706  // | | |
3707  // 4--9--5
3708  // | | |
3709  // 0--6--1
3710  int new_vertices[9];
3711  for (unsigned int vertex_no = 0; vertex_no < 4; ++vertex_no)
3712  new_vertices[vertex_no] = cell->vertex_index(vertex_no);
3713  for (unsigned int line_no = 0; line_no < 4; ++line_no)
3714  if (cell->line(line_no)->has_children())
3715  new_vertices[4 + line_no] =
3716  cell->line(line_no)->child(0)->vertex_index(1);
3717 
3718  if (ref_case == RefinementCase<dim>::cut_xy)
3719  {
3720  // find the next
3721  // unused vertex and
3722  // allocate it for
3723  // the new vertex we
3724  // need here
3725  while (triangulation.vertices_used[next_unused_vertex] == true)
3726  ++next_unused_vertex;
3727  Assert(
3728  next_unused_vertex < triangulation.vertices.size(),
3729  ExcMessage(
3730  "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."));
3731  triangulation.vertices_used[next_unused_vertex] = true;
3732 
3733  new_vertices[8] = next_unused_vertex;
3734 
3735  // if this quad lives
3736  // in 2d, then we can
3737  // compute the new
3738  // central vertex
3739  // location just from
3740  // the surrounding
3741  // ones. If this is
3742  // not the case, then
3743  // we need to ask a
3744  // boundary object
3745  if (dim == spacedim)
3746  {
3747  // triangulation.vertices[next_unused_vertex] = new_point;
3748  triangulation.vertices[next_unused_vertex] = cell->center(true);
3749 
3750  // if the user_flag is set, i.e. if the cell is at the
3751  // boundary, use a different calculation of the middle vertex
3752  // here. this is of advantage if the boundary is strongly
3753  // curved (whereas the cell is not) and the cell has a high
3754  // aspect ratio.
3755  if (cell->user_flag_set())
3756  {
3757  // first reset the user_flag and then refine
3758  cell->clear_user_flag();
3759  triangulation.vertices[next_unused_vertex] =
3760  cell->center(true, true);
3761  }
3762  }
3763  else
3764  {
3765  // if this quad lives in a higher dimensional space
3766  // then we don't need to worry if it is at the
3767  // boundary of the manifold -- we always have to use
3768  // the boundary object anyway; so ignore whether the
3769  // user flag is set or not
3770  cell->clear_user_flag();
3771 
3772  // determine middle vertex by transfinite interpolation to be
3773  // consistent with what happens to quads in a Triangulation<3,
3774  // 3> when they are refined
3775  triangulation.vertices[next_unused_vertex] =
3776  cell->center(true, true);
3777  }
3778  }
3779 
3780 
3781  // Now the lines:
3782  typename Triangulation<dim, spacedim>::raw_line_iterator new_lines[12];
3783  unsigned int lmin = 8;
3784  unsigned int lmax = 12;
3785  if (ref_case != RefinementCase<dim>::cut_xy)
3786  {
3787  lmin = 6;
3788  lmax = 7;
3789  }
3790 
3791  for (unsigned int l = lmin; l < lmax; ++l)
3792  {
3793  while (next_unused_line->used() == true)
3794  ++next_unused_line;
3795  new_lines[l] = next_unused_line;
3796  ++next_unused_line;
3797 
3798  Assert(
3799  new_lines[l]->used() == false,
3800  ExcMessage(
3801  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
3802  }
3803 
3804  if (ref_case == RefinementCase<dim>::cut_xy)
3805  {
3806  // .-6-.-7-.
3807  // 1 9 3
3808  // .-10.11-.
3809  // 0 8 2
3810  // .-4-.-5-.
3811 
3812  // lines 0-7 already exist, create only the four interior
3813  // lines 8-11
3814  unsigned int l = 0;
3815  for (const unsigned int face_no : GeometryInfo<dim>::face_indices())
3816  for (unsigned int c = 0; c < 2; ++c, ++l)
3817  new_lines[l] = cell->line(face_no)->child(c);
3818  Assert(l == 8, ExcInternalError());
3819 
3820  new_lines[8]->set_bounding_object_indices(
3821  {new_vertices[6], new_vertices[8]});
3822  new_lines[9]->set_bounding_object_indices(
3823  {new_vertices[8], new_vertices[7]});
3824  new_lines[10]->set_bounding_object_indices(
3825  {new_vertices[4], new_vertices[8]});
3826  new_lines[11]->set_bounding_object_indices(
3827  {new_vertices[8], new_vertices[5]});
3828  }
3829  else if (ref_case == RefinementCase<dim>::cut_x)
3830  {
3831  // .-4-.-5-.
3832  // | | |
3833  // 0 6 1
3834  // | | |
3835  // .-2-.-3-.
3836  new_lines[0] = cell->line(0);
3837  new_lines[1] = cell->line(1);
3838  new_lines[2] = cell->line(2)->child(0);
3839  new_lines[3] = cell->line(2)->child(1);
3840  new_lines[4] = cell->line(3)->child(0);
3841  new_lines[5] = cell->line(3)->child(1);
3842  new_lines[6]->set_bounding_object_indices(
3843  {new_vertices[6], new_vertices[7]});
3844  }
3845  else
3846  {
3848  // .---5---.
3849  // 1 3
3850  // .---6---.
3851  // 0 2
3852  // .---4---.
3853  new_lines[0] = cell->line(0)->child(0);
3854  new_lines[1] = cell->line(0)->child(1);
3855  new_lines[2] = cell->line(1)->child(0);
3856  new_lines[3] = cell->line(1)->child(1);
3857  new_lines[4] = cell->line(2);
3858  new_lines[5] = cell->line(3);
3859  new_lines[6]->set_bounding_object_indices(
3860  {new_vertices[4], new_vertices[5]});
3861  }
3862 
3863  for (unsigned int l = lmin; l < lmax; ++l)
3864  {
3865  new_lines[l]->set_used_flag();
3866  new_lines[l]->clear_user_flag();
3867  new_lines[l]->clear_user_data();
3868  new_lines[l]->clear_children();
3869  // interior line
3870  new_lines[l]->set_boundary_id_internal(
3872  new_lines[l]->set_manifold_id(cell->manifold_id());
3873  }
3874 
3875  // Now add the four (two)
3876  // new cells!
3879  while (next_unused_cell->used() == true)
3880  ++next_unused_cell;
3881 
3882  const unsigned int n_children = GeometryInfo<dim>::n_children(ref_case);
3883  for (unsigned int i = 0; i < n_children; ++i)
3884  {
3885  Assert(
3886  next_unused_cell->used() == false,
3887  ExcMessage(
3888  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
3889  subcells[i] = next_unused_cell;
3890  ++next_unused_cell;
3891  if (i % 2 == 1 && i < n_children - 1)
3892  while (next_unused_cell->used() == true)
3893  ++next_unused_cell;
3894  }
3895 
3896  if (ref_case == RefinementCase<dim>::cut_xy)
3897  {
3898  // children:
3899  // .--.--.
3900  // |2 . 3|
3901  // .--.--.
3902  // |0 | 1|
3903  // .--.--.
3904  // lines:
3905  // .-6-.-7-.
3906  // 1 9 3
3907  // .-10.11-.
3908  // 0 8 2
3909  // .-4-.-5-.
3910  subcells[0]->set_bounding_object_indices({new_lines[0]->index(),
3911  new_lines[8]->index(),
3912  new_lines[4]->index(),
3913  new_lines[10]->index()});
3914  subcells[1]->set_bounding_object_indices({new_lines[8]->index(),
3915  new_lines[2]->index(),
3916  new_lines[5]->index(),
3917  new_lines[11]->index()});
3918  subcells[2]->set_bounding_object_indices({new_lines[1]->index(),
3919  new_lines[9]->index(),
3920  new_lines[10]->index(),
3921  new_lines[6]->index()});
3922  subcells[3]->set_bounding_object_indices({new_lines[9]->index(),
3923  new_lines[3]->index(),
3924  new_lines[11]->index(),
3925  new_lines[7]->index()});
3926  }
3927  else if (ref_case == RefinementCase<dim>::cut_x)
3928  {
3929  // children:
3930  // .--.--.
3931  // | . |
3932  // .0 . 1.
3933  // | | |
3934  // .--.--.
3935  // lines:
3936  // .-4-.-5-.
3937  // | | |
3938  // 0 6 1
3939  // | | |
3940  // .-2-.-3-.
3941  subcells[0]->set_bounding_object_indices({new_lines[0]->index(),
3942  new_lines[6]->index(),
3943  new_lines[2]->index(),
3944  new_lines[4]->index()});
3945  subcells[1]->set_bounding_object_indices({new_lines[6]->index(),
3946  new_lines[1]->index(),
3947  new_lines[3]->index(),
3948  new_lines[5]->index()});
3949  }
3950  else
3951  {
3953  // children:
3954  // .-----.
3955  // | 1 |
3956  // .-----.
3957  // | 0 |
3958  // .-----.
3959  // lines:
3960  // .---5---.
3961  // 1 3
3962  // .---6---.
3963  // 0 2
3964  // .---4---.
3965  subcells[0]->set_bounding_object_indices({new_lines[0]->index(),
3966  new_lines[2]->index(),
3967  new_lines[4]->index(),
3968  new_lines[6]->index()});
3969  subcells[1]->set_bounding_object_indices({new_lines[1]->index(),
3970  new_lines[3]->index(),
3971  new_lines[6]->index(),
3972  new_lines[5]->index()});
3973  }
3974 
3975  types::subdomain_id subdomainid = cell->subdomain_id();
3976 
3977  for (unsigned int i = 0; i < n_children; ++i)
3978  {
3979  subcells[i]->set_used_flag();
3980  subcells[i]->clear_refine_flag();
3981  subcells[i]->clear_user_flag();
3982  subcells[i]->clear_user_data();
3983  subcells[i]->clear_children();
3984  // inherit material
3985  // properties
3986  subcells[i]->set_material_id(cell->material_id());
3987  subcells[i]->set_manifold_id(cell->manifold_id());
3988  subcells[i]->set_subdomain_id(subdomainid);
3989 
3990  if (i % 2 == 0)
3991  subcells[i]->set_parent(cell->index());
3992  }
3993 
3994 
3995 
3996  // set child index for
3997  // even children children
3998  // i=0,2 (0)
3999  for (unsigned int i = 0; i < n_children / 2; ++i)
4000  cell->set_children(2 * i, subcells[2 * i]->index());
4001  // set the refine case
4002  cell->set_refinement_case(ref_case);
4003 
4004  // note that the
4005  // refinement flag was
4006  // already cleared at the
4007  // beginning of this function
4008 
4009  if (dim < spacedim)
4010  for (unsigned int c = 0; c < n_children; ++c)
4011  cell->child(c)->set_direction_flag(cell->direction_flag());
4012  }
4013 
4014 
4015 
4016  template <int dim, int spacedim>
4019  const bool check_for_distorted_cells)
4020  {
4021  AssertDimension(dim, 2);
4022 
4023  // Check whether a new level is needed. We have to check for
4024  // this on the highest level only
4025  for (const auto &cell : triangulation.active_cell_iterators_on_level(
4026  triangulation.levels.size() - 1))
4027  if (cell->refine_flag_set())
4028  {
4029  triangulation.levels.push_back(
4030  std::make_unique<
4032  break;
4033  }
4034 
4035  for (typename Triangulation<dim, spacedim>::line_iterator line =
4036  triangulation.begin_line();
4037  line != triangulation.end_line();
4038  ++line)
4039  {
4040  line->clear_user_flag();
4041  line->clear_user_data();
4042  }
4043 
4044  unsigned int n_single_lines = 0;
4045  unsigned int n_lines_in_pairs = 0;
4046  unsigned int needed_vertices = 0;
4047 
4048  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4049  {
4050  // count number of flagged cells on this level and compute
4051  // how many new vertices and new lines will be needed
4052  unsigned int needed_cells = 0;
4053 
4054  for (const auto &cell :
4055  triangulation.active_cell_iterators_on_level(level))
4056  if (cell->refine_flag_set())
4057  {
4058  if (cell->reference_cell() ==
4060  {
4061  needed_cells += 4;
4062  needed_vertices += 0;
4063  n_single_lines += 3;
4064  }
4065  else if (cell->reference_cell() ==
4067  {
4068  needed_cells += 4;
4069  needed_vertices += 1;
4070  n_single_lines += 4;
4071  }
4072  else
4073  {
4074  AssertThrow(false, ExcNotImplemented());
4075  }
4076 
4077  for (const auto line_no : cell->face_indices())
4078  {
4079  auto line = cell->line(line_no);
4080  if (line->has_children() == false)
4081  line->set_user_flag();
4082  }
4083  }
4084 
4085 
4086  const unsigned int used_cells =
4087  std::count(triangulation.levels[level + 1]->cells.used.begin(),
4088  triangulation.levels[level + 1]->cells.used.end(),
4089  true);
4090 
4091 
4092  reserve_space(*triangulation.levels[level + 1],
4093  used_cells + needed_cells,
4094  2,
4095  spacedim);
4096 
4097  reserve_space(triangulation.levels[level + 1]->cells,
4098  needed_cells,
4099  0);
4100  }
4101 
4102  for (auto line = triangulation.begin_line();
4103  line != triangulation.end_line();
4104  ++line)
4105  if (line->user_flag_set())
4106  {
4107  Assert(line->has_children() == false, ExcInternalError());
4108  n_lines_in_pairs += 2;
4109  needed_vertices += 1;
4110  }
4111 
4112  reserve_space(triangulation.faces->lines, n_lines_in_pairs, 0);
4113 
4114  needed_vertices += std::count(triangulation.vertices_used.begin(),
4115  triangulation.vertices_used.end(),
4116  true);
4117 
4118  if (needed_vertices > triangulation.vertices.size())
4119  {
4120  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
4121  triangulation.vertices_used.resize(needed_vertices, false);
4122  }
4123 
4124  unsigned int next_unused_vertex = 0;
4125 
4126  {
4128  line = triangulation.begin_active_line(),
4129  endl = triangulation.end_line();
4131  next_unused_line = triangulation.begin_raw_line();
4132 
4133  for (; line != endl; ++line)
4134  if (line->user_flag_set())
4135  {
4136  // this line needs to be refined
4137 
4138  // find the next unused vertex and set it
4139  // appropriately
4140  while (triangulation.vertices_used[next_unused_vertex] == true)
4141  ++next_unused_vertex;
4142  Assert(
4143  next_unused_vertex < triangulation.vertices.size(),
4144  ExcMessage(
4145  "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."));
4146  triangulation.vertices_used[next_unused_vertex] = true;
4147 
4148  triangulation.vertices[next_unused_vertex] = line->center(true);
4149 
4150  bool pair_found = false;
4151  (void)pair_found;
4152  for (; next_unused_line != endl; ++next_unused_line)
4153  if (!next_unused_line->used() &&
4154  !(++next_unused_line)->used())
4155  {
4156  --next_unused_line;
4157  pair_found = true;
4158  break;
4159  }
4160  Assert(pair_found, ExcInternalError());
4161 
4162  line->set_children(0, next_unused_line->index());
4163 
4165  children[2] = {next_unused_line, ++next_unused_line};
4166 
4167  Assert(
4168  children[0]->used() == false,
4169  ExcMessage(
4170  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4171  Assert(
4172  children[1]->used() == false,
4173  ExcMessage(
4174  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4175 
4176  children[0]->set_bounding_object_indices(
4177  {line->vertex_index(0), next_unused_vertex});
4178  children[1]->set_bounding_object_indices(
4179  {next_unused_vertex, line->vertex_index(1)});
4180 
4181  children[0]->set_used_flag();
4182  children[1]->set_used_flag();
4183  children[0]->clear_children();
4184  children[1]->clear_children();
4185  children[0]->clear_user_data();
4186  children[1]->clear_user_data();
4187  children[0]->clear_user_flag();
4188  children[1]->clear_user_flag();
4189 
4190 
4191  children[0]->set_boundary_id_internal(line->boundary_id());
4192  children[1]->set_boundary_id_internal(line->boundary_id());
4193 
4194  children[0]->set_manifold_id(line->manifold_id());
4195  children[1]->set_manifold_id(line->manifold_id());
4196 
4197  line->clear_user_flag();
4198  }
4199  }
4200 
4201  reserve_space(triangulation.faces->lines, 0, n_single_lines);
4202 
4204  cells_with_distorted_children;
4205 
4207  next_unused_line = triangulation.begin_raw_line();
4208 
4209  const auto create_children = [](auto & triangulation,
4210  unsigned int &next_unused_vertex,
4211  auto & next_unused_line,
4212  auto & next_unused_cell,
4213  const auto & cell) {
4214  const auto ref_case = cell->refine_flag_set();
4215  cell->clear_refine_flag();
4216 
4217  unsigned int n_new_vertices = 0;
4218 
4219  if (cell->reference_cell() == ::ReferenceCells::Triangle)
4220  n_new_vertices = 6;
4221  else if (cell->reference_cell() ==
4223  n_new_vertices = 9;
4224  else
4225  AssertThrow(false, ExcNotImplemented());
4226 
4227  std::vector<int> new_vertices(n_new_vertices);
4228  for (unsigned int vertex_no = 0; vertex_no < cell->n_vertices();
4229  ++vertex_no)
4230  new_vertices[vertex_no] = cell->vertex_index(vertex_no);
4231  for (unsigned int line_no = 0; line_no < cell->n_lines(); ++line_no)
4232  if (cell->line(line_no)->has_children())
4233  new_vertices[cell->n_vertices() + line_no] =
4234  cell->line(line_no)->child(0)->vertex_index(1);
4235 
4236  if (cell->reference_cell() == ::ReferenceCells::Quadrilateral)
4237  {
4238  while (triangulation.vertices_used[next_unused_vertex] == true)
4239  ++next_unused_vertex;
4240  Assert(
4241  next_unused_vertex < triangulation.vertices.size(),
4242  ExcMessage(
4243  "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."));
4244  triangulation.vertices_used[next_unused_vertex] = true;
4245 
4246  new_vertices[8] = next_unused_vertex;
4247 
4248  if (dim == spacedim)
4249  {
4250  triangulation.vertices[next_unused_vertex] =
4251  cell->center(true);
4252 
4253  if (cell->user_flag_set())
4254  {
4255  cell->clear_user_flag();
4256  triangulation.vertices[next_unused_vertex] =
4257  cell->center(true, true);
4258  }
4259  }
4260  else
4261  {
4262  cell->clear_user_flag();
4263 
4264  triangulation.vertices[next_unused_vertex] =
4265  cell->center(true, true);
4266  }
4267  }
4268 
4269  std::array<typename Triangulation<dim, spacedim>::raw_line_iterator,
4270  12>
4271  new_lines;
4272  unsigned int lmin = 0;
4273  unsigned int lmax = 0;
4274 
4275  if (cell->reference_cell() == ::ReferenceCells::Triangle)
4276  {
4277  lmin = 6;
4278  lmax = 9;
4279  }
4280  else if (cell->reference_cell() ==
4282  {
4283  lmin = 8;
4284  lmax = 12;
4285  }
4286  else
4287  {
4288  AssertThrow(false, ExcNotImplemented());
4289  }
4290 
4291  for (unsigned int l = lmin; l < lmax; ++l)
4292  {
4293  while (next_unused_line->used() == true)
4294  ++next_unused_line;
4295  new_lines[l] = next_unused_line;
4296  ++next_unused_line;
4297 
4298  Assert(
4299  new_lines[l]->used() == false,
4300  ExcMessage(
4301  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4302  }
4303 
4304  if (true)
4305  {
4306  if (cell->reference_cell() == ::ReferenceCells::Triangle)
4307  {
4308  // add lines in the right order [TODO: clean up]
4309  const auto ref = [&](const unsigned int face_no,
4310  const unsigned int vertex_no) {
4311  if (cell->line(face_no)->child(0)->vertex_index(0) ==
4312  static_cast<unsigned int>(new_vertices[vertex_no]) ||
4313  cell->line(face_no)->child(0)->vertex_index(1) ==
4314  static_cast<unsigned int>(new_vertices[vertex_no]))
4315  {
4316  new_lines[2 * face_no + 0] =
4317  cell->line(face_no)->child(0);
4318  new_lines[2 * face_no + 1] =
4319  cell->line(face_no)->child(1);
4320  }
4321  else
4322  {
4323  new_lines[2 * face_no + 0] =
4324  cell->line(face_no)->child(1);
4325  new_lines[2 * face_no + 1] =
4326  cell->line(face_no)->child(0);
4327  }
4328  };
4329 
4330  ref(0, 0);
4331  ref(1, 1);
4332  ref(2, 2);
4333 
4334  new_lines[6]->set_bounding_object_indices(
4335  {new_vertices[3], new_vertices[4]});
4336  new_lines[7]->set_bounding_object_indices(
4337  {new_vertices[4], new_vertices[5]});
4338  new_lines[8]->set_bounding_object_indices(
4339  {new_vertices[5], new_vertices[3]});
4340  }
4341  else if (cell->reference_cell() ==
4343  {
4344  unsigned int l = 0;
4345  for (const unsigned int face_no : cell->face_indices())
4346  for (unsigned int c = 0; c < 2; ++c, ++l)
4347  new_lines[l] = cell->line(face_no)->child(c);
4348 
4349  new_lines[8]->set_bounding_object_indices(
4350  {new_vertices[6], new_vertices[8]});
4351  new_lines[9]->set_bounding_object_indices(
4352  {new_vertices[8], new_vertices[7]});
4353  new_lines[10]->set_bounding_object_indices(
4354  {new_vertices[4], new_vertices[8]});
4355  new_lines[11]->set_bounding_object_indices(
4356  {new_vertices[8], new_vertices[5]});
4357  }
4358  else
4359  {
4360  AssertThrow(false, ExcNotImplemented());
4361  }
4362  }
4363 
4364 
4365  for (unsigned int l = lmin; l < lmax; ++l)
4366  {
4367  new_lines[l]->set_used_flag();
4368  new_lines[l]->clear_user_flag();
4369  new_lines[l]->clear_user_data();
4370  new_lines[l]->clear_children();
4371  // interior line
4372  new_lines[l]->set_boundary_id_internal(
4374  new_lines[l]->set_manifold_id(cell->manifold_id());
4375  }
4376 
4379  while (next_unused_cell->used() == true)
4380  ++next_unused_cell;
4381 
4382  unsigned int n_children = 0;
4383 
4384  if (cell->reference_cell() == ::ReferenceCells::Triangle)
4385  n_children = 4;
4386  else if (cell->reference_cell() ==
4388  n_children = 4;
4389  else
4390  AssertThrow(false, ExcNotImplemented());
4391 
4392  for (unsigned int i = 0; i < n_children; ++i)
4393  {
4394  Assert(
4395  next_unused_cell->used() == false,
4396  ExcMessage(
4397  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4398  subcells[i] = next_unused_cell;
4399  ++next_unused_cell;
4400  if (i % 2 == 1 && i < n_children - 1)
4401  while (next_unused_cell->used() == true)
4402  ++next_unused_cell;
4403  }
4404 
4405  if ((dim == 2) &&
4406  (cell->reference_cell() == ::ReferenceCells::Triangle))
4407  {
4408  subcells[0]->set_bounding_object_indices({new_lines[0]->index(),
4409  new_lines[8]->index(),
4410  new_lines[5]->index()});
4411  subcells[1]->set_bounding_object_indices({new_lines[1]->index(),
4412  new_lines[2]->index(),
4413  new_lines[6]->index()});
4414  subcells[2]->set_bounding_object_indices({new_lines[7]->index(),
4415  new_lines[3]->index(),
4416  new_lines[4]->index()});
4417  subcells[3]->set_bounding_object_indices({new_lines[6]->index(),
4418  new_lines[7]->index(),
4419  new_lines[8]->index()});
4420 
4421  // subcell 0
4422 
4423  const auto ref = [&](const unsigned int line_no,
4424  const unsigned int vertex_no,
4425  const unsigned int subcell_no,
4426  const unsigned int subcell_line_no) {
4427  if (new_lines[line_no]->vertex_index(1) !=
4428  static_cast<unsigned int>(new_vertices[vertex_no]))
4429  triangulation.levels[subcells[subcell_no]->level()]
4430  ->face_orientations[subcells[subcell_no]->index() *
4432  subcell_line_no] = 0;
4433  };
4434 
4435  ref(0, 3, 0, 0);
4436  ref(8, 5, 0, 1);
4437  ref(5, 0, 0, 2);
4438 
4439  ref(1, 1, 1, 0);
4440  ref(2, 4, 1, 1);
4441  ref(6, 3, 1, 2);
4442 
4443  ref(7, 4, 2, 0);
4444  ref(3, 2, 2, 1);
4445  ref(4, 5, 2, 2);
4446 
4447  ref(6, 4, 3, 0);
4448  ref(7, 5, 3, 1);
4449  ref(8, 3, 3, 2);
4450 
4451  // triangulation.levels[subcells[1]->level()]->face_orientations[subcells[1]->index()
4452  // * GeometryInfo<2>::faces_per_cell + 2] = 0;
4453  // triangulation.levels[subcells[2]->level()]->face_orientations[subcells[2]->index()
4454  // * GeometryInfo<2>::faces_per_cell + 0] = 0;
4455  }
4456  else if ((dim == 2) && (cell->reference_cell() ==
4458  {
4459  subcells[0]->set_bounding_object_indices(
4460  {new_lines[0]->index(),
4461  new_lines[8]->index(),
4462  new_lines[4]->index(),
4463  new_lines[10]->index()});
4464  subcells[1]->set_bounding_object_indices(
4465  {new_lines[8]->index(),
4466  new_lines[2]->index(),
4467  new_lines[5]->index(),
4468  new_lines[11]->index()});
4469  subcells[2]->set_bounding_object_indices({new_lines[1]->index(),
4470  new_lines[9]->index(),
4471  new_lines[10]->index(),
4472  new_lines[6]->index()});
4473  subcells[3]->set_bounding_object_indices({new_lines[9]->index(),
4474  new_lines[3]->index(),
4475  new_lines[11]->index(),
4476  new_lines[7]->index()});
4477  }
4478  else
4479  {
4480  AssertThrow(false, ExcNotImplemented());
4481  }
4482 
4483  types::subdomain_id subdomainid = cell->subdomain_id();
4484 
4485  for (unsigned int i = 0; i < n_children; ++i)
4486  {
4487  subcells[i]->set_used_flag();
4488  subcells[i]->clear_refine_flag();
4489  subcells[i]->clear_user_flag();
4490  subcells[i]->clear_user_data();
4491  subcells[i]->clear_children();
4492  // inherit material
4493  // properties
4494  subcells[i]->set_material_id(cell->material_id());
4495  subcells[i]->set_manifold_id(cell->manifold_id());
4496  subcells[i]->set_subdomain_id(subdomainid);
4497 
4498  // TODO: here we assume that all children have the same reference
4499  // cell type as the parent! This is justified for 2D.
4500  triangulation.levels[subcells[i]->level()]
4501  ->reference_cell[subcells[i]->index()] = cell->reference_cell();
4502 
4503  if (i % 2 == 0)
4504  subcells[i]->set_parent(cell->index());
4505  }
4506 
4507  for (unsigned int i = 0; i < n_children / 2; ++i)
4508  cell->set_children(2 * i, subcells[2 * i]->index());
4509 
4510  cell->set_refinement_case(ref_case);
4511 
4512  if (dim < spacedim)
4513  for (unsigned int c = 0; c < n_children; ++c)
4514  cell->child(c)->set_direction_flag(cell->direction_flag());
4515  };
4516 
4517  for (int level = 0;
4518  level < static_cast<int>(triangulation.levels.size()) - 1;
4519  ++level)
4520  {
4522  next_unused_cell = triangulation.begin_raw(level + 1);
4523 
4524  for (const auto &cell :
4525  triangulation.active_cell_iterators_on_level(level))
4526  if (cell->refine_flag_set())
4527  {
4528  if (cell->at_boundary())
4529  cell->set_user_flag();
4530 
4532  next_unused_vertex,
4533  next_unused_line,
4534  next_unused_cell,
4535  cell);
4536 
4537  if (cell->reference_cell() ==
4539  check_for_distorted_cells &&
4540  has_distorted_children<dim, spacedim>(cell))
4541  cells_with_distorted_children.distorted_cells.push_back(
4542  cell);
4543 
4544  triangulation.signals.post_refinement_on_cell(cell);
4545  }
4546  }
4547 
4548  return cells_with_distorted_children;
4549  }
4550 
4551 
4552 
4557  template <int spacedim>
4560  const bool /*check_for_distorted_cells*/)
4561  {
4562  const unsigned int dim = 1;
4563 
4564  // Check whether a new level is needed. We have to check for
4565  // this on the highest level only
4566  for (const auto &cell : triangulation.active_cell_iterators_on_level(
4567  triangulation.levels.size() - 1))
4568  if (cell->refine_flag_set())
4569  {
4570  triangulation.levels.push_back(
4571  std::make_unique<
4573  break;
4574  }
4575 
4576 
4577  // check how much space is needed on every level we need not
4578  // check the highest level since either - on the highest level
4579  // no cells are flagged for refinement - there are, but
4580  // prepare_refinement added another empty level
4581  unsigned int needed_vertices = 0;
4582  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4583  {
4584  // count number of flagged
4585  // cells on this level
4586  unsigned int flagged_cells = 0;
4587 
4588  for (const auto &acell :
4589  triangulation.active_cell_iterators_on_level(level))
4590  if (acell->refine_flag_set())
4591  ++flagged_cells;
4592 
4593  // count number of used cells
4594  // on the next higher level
4595  const unsigned int used_cells =
4596  std::count(triangulation.levels[level + 1]->cells.used.begin(),
4597  triangulation.levels[level + 1]->cells.used.end(),
4598  true);
4599 
4600  // reserve space for the used_cells cells already existing
4601  // on the next higher level as well as for the
4602  // 2*flagged_cells that will be created on that level
4603  reserve_space(*triangulation.levels[level + 1],
4605  flagged_cells,
4606  1,
4607  spacedim);
4608  // reserve space for 2*flagged_cells new lines on the next
4609  // higher level
4610  reserve_space(triangulation.levels[level + 1]->cells,
4612  flagged_cells,
4613  0);
4614 
4615  needed_vertices += flagged_cells;
4616  }
4617 
4618  // add to needed vertices how many
4619  // vertices are already in use
4620  needed_vertices += std::count(triangulation.vertices_used.begin(),
4621  triangulation.vertices_used.end(),
4622  true);
4623  // if we need more vertices: create them, if not: leave the
4624  // array as is, since shrinking is not really possible because
4625  // some of the vertices at the end may be in use
4626  if (needed_vertices > triangulation.vertices.size())
4627  {
4628  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
4629  triangulation.vertices_used.resize(needed_vertices, false);
4630  }
4631 
4632 
4633  // Do REFINEMENT on every level; exclude highest level as
4634  // above
4635 
4636  // index of next unused vertex
4637  unsigned int next_unused_vertex = 0;
4638 
4639  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4640  {
4642  next_unused_cell = triangulation.begin_raw(level + 1);
4643 
4644  for (const auto &cell :
4645  triangulation.active_cell_iterators_on_level(level))
4646  if (cell->refine_flag_set())
4647  {
4648  // clear refinement flag
4649  cell->clear_refine_flag();
4650 
4651  // search for next unused
4652  // vertex
4653  while (triangulation.vertices_used[next_unused_vertex] ==
4654  true)
4655  ++next_unused_vertex;
4656  Assert(
4657  next_unused_vertex < triangulation.vertices.size(),
4658  ExcMessage(
4659  "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."));
4660 
4661  // Now we always ask the cell itself where to put
4662  // the new point. The cell in turn will query the
4663  // manifold object internally.
4664  triangulation.vertices[next_unused_vertex] =
4665  cell->center(true);
4666 
4667  triangulation.vertices_used[next_unused_vertex] = true;
4668 
4669  // search for next two unused cell (++ takes care of
4670  // the end of the vector)
4672  first_child,
4673  second_child;
4674  while (next_unused_cell->used() == true)
4675  ++next_unused_cell;
4676  first_child = next_unused_cell;
4677  first_child->set_used_flag();
4678  first_child->clear_user_data();
4679  ++next_unused_cell;
4680  Assert(
4681  next_unused_cell->used() == false,
4682  ExcMessage(
4683  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4684  second_child = next_unused_cell;
4685  second_child->set_used_flag();
4686  second_child->clear_user_data();
4687 
4688  types::subdomain_id subdomainid = cell->subdomain_id();
4689 
4690  // insert first child
4691  cell->set_children(0, first_child->index());
4692  first_child->clear_children();
4693  first_child->set_bounding_object_indices(
4694  {cell->vertex_index(0), next_unused_vertex});
4695  first_child->set_material_id(cell->material_id());
4696  first_child->set_manifold_id(cell->manifold_id());
4697  first_child->set_subdomain_id(subdomainid);
4698  first_child->set_direction_flag(cell->direction_flag());
4699 
4700  first_child->set_parent(cell->index());
4701 
4702  // Set manifold id of the right face. Only do this
4703  // on the first child.
4704  first_child->face(1)->set_manifold_id(cell->manifold_id());
4705 
4706  // reset neighborship info (refer to
4707  // internal::TriangulationImplementation::TriaLevel<0> for
4708  // details)
4709  first_child->set_neighbor(1, second_child);
4710  if (cell->neighbor(0).state() != IteratorState::valid)
4711  first_child->set_neighbor(0, cell->neighbor(0));
4712  else if (cell->neighbor(0)->is_active())
4713  {
4714  // since the neighbors level is always <=level,
4715  // if the cell is active, then there are no
4716  // cells to the left which may want to know
4717  // about this new child cell.
4718  Assert(cell->neighbor(0)->level() <= cell->level(),
4719  ExcInternalError());
4720  first_child->set_neighbor(0, cell->neighbor(0));
4721  }
4722  else
4723  // left neighbor is refined
4724  {
4725  // set neighbor to cell on same level
4726  const unsigned int nbnb = cell->neighbor_of_neighbor(0);
4727  first_child->set_neighbor(0,
4728  cell->neighbor(0)->child(nbnb));
4729 
4730  // reset neighbor info of all right descendant
4731  // of the left neighbor of cell
4733  left_neighbor = cell->neighbor(0);
4734  while (left_neighbor->has_children())
4735  {
4736  left_neighbor = left_neighbor->child(nbnb);
4737  left_neighbor->set_neighbor(nbnb, first_child);
4738  }
4739  }
4740 
4741  // insert second child
4742  second_child->clear_children();
4743  second_child->set_bounding_object_indices(
4744  {next_unused_vertex, cell->vertex_index(1)});
4745  second_child->set_neighbor(0, first_child);
4746  second_child->set_material_id(cell->material_id());
4747  second_child->set_manifold_id(cell->manifold_id());
4748  second_child->set_subdomain_id(subdomainid);
4749  second_child->set_direction_flag(cell->direction_flag());
4750 
4751  if (cell->neighbor(1).state() != IteratorState::valid)
4752  second_child->set_neighbor(1, cell->neighbor(1));
4753  else if (cell->neighbor(1)->is_active())
4754  {
4755  Assert(cell->neighbor(1)->level() <= cell->level(),
4756  ExcInternalError());
4757  second_child->set_neighbor(1, cell->neighbor(1));
4758  }
4759  else
4760  // right neighbor is refined same as above
4761  {
4762  const unsigned int nbnb = cell->neighbor_of_neighbor(1);
4763  second_child->set_neighbor(
4764  1, cell->neighbor(1)->child(nbnb));
4765 
4767  right_neighbor = cell->neighbor(1);
4768  while (right_neighbor->has_children())
4769  {
4770  right_neighbor = right_neighbor->child(nbnb);
4771  right_neighbor->set_neighbor(nbnb, second_child);
4772  }
4773  }
4774  // inform all listeners that cell refinement is done
4775  triangulation.signals.post_refinement_on_cell(cell);
4776  }
4777  }
4778 
4779  // in 1d, we can not have distorted children unless the parent
4780  // was already distorted (that is because we don't use
4781  // boundary information for 1d triangulations). so return an
4782  // empty list
4784  }
4785 
4786 
4791  template <int spacedim>
4794  const bool check_for_distorted_cells)
4795  {
4796  const unsigned int dim = 2;
4797 
4798 
4799  // First check whether we can get away with isotropic refinement, or
4800  // whether we need to run through the full anisotropic algorithm
4801  {
4802  bool do_isotropic_refinement = true;
4803  for (const auto &cell : triangulation.active_cell_iterators())
4804  if (cell->refine_flag_set() == RefinementCase<dim>::cut_x ||
4805  cell->refine_flag_set() == RefinementCase<dim>::cut_y)
4806  {
4807  do_isotropic_refinement = false;
4808  break;
4809  }
4810 
4811  if (do_isotropic_refinement)
4813  check_for_distorted_cells);
4814  }
4815 
4816  // Check whether a new level is needed. We have to check for
4817  // this on the highest level only
4818  for (const auto &cell : triangulation.active_cell_iterators_on_level(
4819  triangulation.levels.size() - 1))
4820  if (cell->refine_flag_set())
4821  {
4822  triangulation.levels.push_back(
4823  std::make_unique<
4825  break;
4826  }
4827 
4828  // TODO[WB]: we clear user flags and pointers of lines; we're going
4829  // to use them to flag which lines need refinement
4830  for (typename Triangulation<dim, spacedim>::line_iterator line =
4831  triangulation.begin_line();
4832  line != triangulation.end_line();
4833  ++line)
4834  {
4835  line->clear_user_flag();
4836  line->clear_user_data();
4837  }
4838  // running over all cells and lines count the number
4839  // n_single_lines of lines which can be stored as single
4840  // lines, e.g. inner lines
4841  unsigned int n_single_lines = 0;
4842 
4843  // New lines to be created: number lines which are stored in
4844  // pairs (the children of lines must be stored in pairs)
4845  unsigned int n_lines_in_pairs = 0;
4846 
4847  // check how much space is needed on every level we need not
4848  // check the highest level since either - on the highest level
4849  // no cells are flagged for refinement - there are, but
4850  // prepare_refinement added another empty level
4851  unsigned int needed_vertices = 0;
4852  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4853  {
4854  // count number of flagged cells on this level and compute
4855  // how many new vertices and new lines will be needed
4856  unsigned int needed_cells = 0;
4857 
4858  for (const auto &cell :
4859  triangulation.active_cell_iterators_on_level(level))
4860  if (cell->refine_flag_set())
4861  {
4862  if (cell->refine_flag_set() == RefinementCase<dim>::cut_xy)
4863  {
4864  needed_cells += 4;
4865 
4866  // new vertex at center of cell is needed in any
4867  // case
4868  ++needed_vertices;
4869 
4870  // the four inner lines can be stored as singles
4871  n_single_lines += 4;
4872  }
4873  else // cut_x || cut_y
4874  {
4875  // set the flag showing that anisotropic
4876  // refinement is used for at least one cell
4877  triangulation.anisotropic_refinement = true;
4878 
4879  needed_cells += 2;
4880  // no vertex at center
4881 
4882  // the inner line can be stored as single
4883  n_single_lines += 1;
4884  }
4885 
4886  // mark all faces (lines) for refinement; checking
4887  // locally whether the neighbor would also like to
4888  // refine them is rather difficult for lines so we
4889  // only flag them and after visiting all cells, we
4890  // decide which lines need refinement;
4891  for (const unsigned int line_no :
4893  {
4895  cell->refine_flag_set(), line_no) ==
4897  {
4899  line = cell->line(line_no);
4900  if (line->has_children() == false)
4901  line->set_user_flag();
4902  }
4903  }
4904  }
4905 
4906 
4907  // count number of used cells on the next higher level
4908  const unsigned int used_cells =
4909  std::count(triangulation.levels[level + 1]->cells.used.begin(),
4910  triangulation.levels[level + 1]->cells.used.end(),
4911  true);
4912 
4913 
4914  // reserve space for the used_cells cells already existing
4915  // on the next higher level as well as for the
4916  // needed_cells that will be created on that level
4917  reserve_space(*triangulation.levels[level + 1],
4918  used_cells + needed_cells,
4919  2,
4920  spacedim);
4921 
4922  // reserve space for needed_cells new quads on the next
4923  // higher level
4924  reserve_space(triangulation.levels[level + 1]->cells,
4925  needed_cells,
4926  0);
4927  }
4928 
4929  // now count the lines which were flagged for refinement
4930  for (typename Triangulation<dim, spacedim>::line_iterator line =
4931  triangulation.begin_line();
4932  line != triangulation.end_line();
4933  ++line)
4934  if (line->user_flag_set())
4935  {
4936  Assert(line->has_children() == false, ExcInternalError());
4937  n_lines_in_pairs += 2;
4938  needed_vertices += 1;
4939  }
4940  // reserve space for n_lines_in_pairs new lines. note, that
4941  // we can't reserve space for the single lines here as well,
4942  // as all the space reserved for lines in pairs would be
4943  // counted as unused and we would end up with too little space
4944  // to store all lines. memory reservation for n_single_lines
4945  // can only be done AFTER we refined the lines of the current
4946  // cells
4947  reserve_space(triangulation.faces->lines, n_lines_in_pairs, 0);
4948 
4949  // add to needed vertices how many vertices are already in use
4950  needed_vertices += std::count(triangulation.vertices_used.begin(),
4951  triangulation.vertices_used.end(),
4952  true);
4953  // if we need more vertices: create them, if not: leave the
4954  // array as is, since shrinking is not really possible because
4955  // some of the vertices at the end may be in use
4956  if (needed_vertices > triangulation.vertices.size())
4957  {
4958  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
4959  triangulation.vertices_used.resize(needed_vertices, false);
4960  }
4961 
4962 
4963  // Do REFINEMENT on every level; exclude highest level as
4964  // above
4965 
4966  // index of next unused vertex
4967  unsigned int next_unused_vertex = 0;
4968 
4969  // first the refinement of lines. children are stored
4970  // pairwise
4971  {
4972  // only active objects can be refined further
4974  line = triangulation.begin_active_line(),
4975  endl = triangulation.end_line();
4977  next_unused_line = triangulation.begin_raw_line();
4978 
4979  for (; line != endl; ++line)
4980  if (line->user_flag_set())
4981  {
4982  // this line needs to be refined
4983 
4984  // find the next unused vertex and set it
4985  // appropriately
4986  while (triangulation.vertices_used[next_unused_vertex] == true)
4987  ++next_unused_vertex;
4988  Assert(
4989  next_unused_vertex < triangulation.vertices.size(),
4990  ExcMessage(
4991  "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."));
4992  triangulation.vertices_used[next_unused_vertex] = true;
4993 
4994  triangulation.vertices[next_unused_vertex] = line->center(true);
4995 
4996  // now that we created the right point, make up the
4997  // two child lines. To this end, find a pair of
4998  // unused lines
4999  bool pair_found = false;
5000  (void)pair_found;
5001  for (; next_unused_line != endl; ++next_unused_line)
5002  if (!next_unused_line->used() &&
5003  !(++next_unused_line)->used())
5004  {
5005  // go back to the first of the two unused
5006  // lines
5007  --next_unused_line;
5008  pair_found = true;
5009  break;
5010  }
5011  Assert(pair_found, ExcInternalError());
5012 
5013  // there are now two consecutive unused lines, such
5014  // that the children of a line will be consecutive.
5015  // then set the child pointer of the present line
5016  line->set_children(0, next_unused_line->index());
5017 
5018  // set the two new lines
5020  children[2] = {next_unused_line, ++next_unused_line};
5021  // some tests; if any of the iterators should be
5022  // invalid, then already dereferencing will fail
5023  Assert(
5024  children[0]->used() == false,
5025  ExcMessage(
5026  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5027  Assert(
5028  children[1]->used() == false,
5029  ExcMessage(
5030  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5031 
5032  children[0]->set_bounding_object_indices(
5033  {line->vertex_index(0), next_unused_vertex});
5034  children[1]->set_bounding_object_indices(
5035  {next_unused_vertex, line->vertex_index(1)});
5036 
5037  children[0]->set_used_flag();
5038  children[1]->set_used_flag();
5039  children[0]->clear_children();
5040  children[1]->clear_children();
5041  children[0]->clear_user_data();
5042  children[1]->clear_user_data();
5043  children[0]->clear_user_flag();
5044  children[1]->clear_user_flag();
5045 
5046 
5047  children[0]->set_boundary_id_internal(line->boundary_id());
5048  children[1]->set_boundary_id_internal(line->boundary_id());
5049 
5050  children[0]->set_manifold_id(line->manifold_id());
5051  children[1]->set_manifold_id(line->manifold_id());
5052 
5053  // finally clear flag indicating the need for
5054  // refinement
5055  line->clear_user_flag();
5056  }
5057  }
5058 
5059 
5060  // Now set up the new cells
5061 
5062  // reserve space for inner lines (can be stored as single
5063  // lines)
5064  reserve_space(triangulation.faces->lines, 0, n_single_lines);
5065 
5067  cells_with_distorted_children;
5068 
5069  // reset next_unused_line, as now also single empty places in
5070  // the vector can be used
5072  next_unused_line = triangulation.begin_raw_line();
5073 
5074  for (int level = 0;
5075  level < static_cast<int>(triangulation.levels.size()) - 1;
5076  ++level)
5077  {
5079  next_unused_cell = triangulation.begin_raw(level + 1);
5080 
5081  for (const auto &cell :
5082  triangulation.active_cell_iterators_on_level(level))
5083  if (cell->refine_flag_set())
5084  {
5085  // set the user flag to indicate, that at least one
5086  // line is at the boundary
5087 
5088  // TODO[Tobias Leicht] find a better place to set
5089  // this flag, so that we do not need so much time to
5090  // check each cell here
5091  if (cell->at_boundary())
5092  cell->set_user_flag();
5093 
5094  // actually set up the children and update neighbor
5095  // information
5097  next_unused_vertex,
5098  next_unused_line,
5099  next_unused_cell,
5100  cell);
5101 
5102  if (check_for_distorted_cells &&
5103  has_distorted_children<dim, spacedim>(cell))
5104  cells_with_distorted_children.distorted_cells.push_back(
5105  cell);
5106  // inform all listeners that cell refinement is done
5107  triangulation.signals.post_refinement_on_cell(cell);
5108  }
5109  }
5110 
5111  return cells_with_distorted_children;
5112  }
5113 
5114 
5119  template <int spacedim>
5122  const bool check_for_distorted_cells)
5123  {
5124  const unsigned int dim = 3;
5125 
5126  // this function probably also works for spacedim>3 but it
5127  // isn't tested. it will probably be necessary to pull new
5128  // vertices onto the manifold just as we do for the other
5129  // functions above.
5130  Assert(spacedim == 3, ExcNotImplemented());
5131 
5132  // Check whether a new level is needed. We have to check for
5133  // this on the highest level only
5134  for (const auto &cell : triangulation.active_cell_iterators_on_level(
5135  triangulation.levels.size() - 1))
5136  if (cell->refine_flag_set())
5137  {
5138  triangulation.levels.push_back(
5139  std::make_unique<
5141  break;
5142  }
5143 
5144 
5145  // first clear user flags for quads and lines; we're going to
5146  // use them to flag which lines and quads need refinement
5147  triangulation.faces->quads.clear_user_data();
5148 
5149  for (typename Triangulation<dim, spacedim>::line_iterator line =
5150  triangulation.begin_line();
5151  line != triangulation.end_line();
5152  ++line)
5153  line->clear_user_flag();
5154  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
5155  triangulation.begin_quad();
5156  quad != triangulation.end_quad();
5157  ++quad)
5158  quad->clear_user_flag();
5159 
5160  // create an array of face refine cases. User indices of faces
5161  // will be set to values corresponding with indices in this
5162  // array.
5163  const RefinementCase<dim - 1> face_refinement_cases[4] = {
5164  RefinementCase<dim - 1>::no_refinement,
5165  RefinementCase<dim - 1>::cut_x,
5166  RefinementCase<dim - 1>::cut_y,
5167  RefinementCase<dim - 1>::cut_xy};
5168 
5169  // check how much space is needed on every level we need not
5170  // check the highest level since either
5171  // - on the highest level no cells are flagged for refinement
5172  // - there are, but prepare_refinement added another empty
5173  // level which then is the highest level
5174 
5175  // variables to hold the number of newly to be created
5176  // vertices, lines and quads. as these are stored globally,
5177  // declare them outside the loop over al levels. we need lines
5178  // and quads in pairs for refinement of old ones and lines and
5179  // quads, that can be stored as single ones, as they are newly
5180  // created in the inside of an existing cell
5181  unsigned int needed_vertices = 0;
5182  unsigned int needed_lines_single = 0;
5183  unsigned int needed_quads_single = 0;
5184  unsigned int needed_lines_pair = 0;
5185  unsigned int needed_quads_pair = 0;
5186  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
5187  {
5188  // count number of flagged cells on this level and compute
5189  // how many new vertices and new lines will be needed
5190  unsigned int new_cells = 0;
5191 
5192  for (const auto &acell :
5193  triangulation.active_cell_iterators_on_level(level))
5194  if (acell->refine_flag_set())
5195  {
5196  RefinementCase<dim> ref_case = acell->refine_flag_set();
5197 
5198  // now for interior vertices, lines and quads, which
5199  // are needed in any case
5200  if (ref_case == RefinementCase<dim>::cut_x ||
5201  ref_case == RefinementCase<dim>::cut_y ||
5202  ref_case == RefinementCase<dim>::cut_z)
5203  {
5204  ++needed_quads_single;
5205  new_cells += 2;
5206  triangulation.anisotropic_refinement = true;
5207  }
5208  else if (ref_case == RefinementCase<dim>::cut_xy ||
5209  ref_case == RefinementCase<dim>::cut_xz ||
5210  ref_case == RefinementCase<dim>::cut_yz)
5211  {
5212  ++needed_lines_single;
5213  needed_quads_single += 4;
5214  new_cells += 4;
5215  triangulation.anisotropic_refinement = true;
5216  }
5217  else if (ref_case == RefinementCase<dim>::cut_xyz)
5218  {
5219  ++needed_vertices;
5220  needed_lines_single += 6;
5221  needed_quads_single += 12;
5222  new_cells += 8;
5223  }
5224  else
5225  {
5226  // we should never get here
5227  Assert(false, ExcInternalError());
5228  }
5229 
5230  // mark all faces for refinement; checking locally
5231  // if and how the neighbor would like to refine
5232  // these is difficult so we only flag them and after
5233  // visiting all cells, we decide which faces need
5234  // which refinement;
5235  for (const unsigned int face :
5237  {
5239  aface = acell->face(face);
5240  // get the RefineCase this faces has for the
5241  // given RefineCase of the cell
5242  RefinementCase<dim - 1> face_ref_case =
5244  ref_case,
5245  face,
5246  acell->face_orientation(face),
5247  acell->face_flip(face),
5248  acell->face_rotation(face));
5249  // only do something, if this face has to be
5250  // refined
5251  if (face_ref_case)
5252  {
5253  if (face_ref_case ==
5255  {
5256  if (aface->n_active_descendants() < 4)
5257  // we use user_flags to denote needed
5258  // isotropic refinement
5259  aface->set_user_flag();
5260  }
5261  else if (aface->refinement_case() != face_ref_case)
5262  // we use user_indices to denote needed
5263  // anisotropic refinement. note, that we
5264  // can have at most one anisotropic
5265  // refinement case for this face, as
5266  // otherwise prepare_refinement() would
5267  // have changed one of the cells to yield
5268  // isotropic refinement at this
5269  // face. therefore we set the user_index
5270  // uniquely
5271  {
5272  Assert(aface->refinement_case() ==
5274  dim - 1>::isotropic_refinement ||
5275  aface->refinement_case() ==
5277  ExcInternalError());
5278  aface->set_user_index(face_ref_case);
5279  }
5280  }
5281  } // for all faces
5282 
5283  // flag all lines, that have to be refined
5284  for (unsigned int line = 0;
5285  line < GeometryInfo<dim>::lines_per_cell;
5286  ++line)
5288  line) &&
5289  !acell->line(line)->has_children())
5290  acell->line(line)->set_user_flag();
5291 
5292  } // if refine_flag set and for all cells on this level
5293 
5294 
5295  // count number of used cells on the next higher level
5296  const unsigned int used_cells =
5297  std::count(triangulation.levels[level + 1]->cells.used.begin(),
5298  triangulation.levels[level + 1]->cells.used.end(),
5299  true);
5300 
5301 
5302  // reserve space for the used_cells cells already existing
5303  // on the next higher level as well as for the
5304  // 8*flagged_cells that will be created on that level
5305  reserve_space(*triangulation.levels[level + 1],
5306  used_cells + new_cells,
5307  3,
5308  spacedim);
5309  // reserve space for 8*flagged_cells new hexes on the next
5310  // higher level
5311  reserve_space(triangulation.levels[level + 1]->cells, new_cells);
5312  } // for all levels
5313  // now count the quads and lines which were flagged for
5314  // refinement
5315  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
5316  triangulation.begin_quad();
5317  quad != triangulation.end_quad();
5318  ++quad)
5319  {
5320  if (quad->user_flag_set())
5321  {
5322  // isotropic refinement: 1 interior vertex, 4 quads
5323  // and 4 interior lines. we store the interior lines
5324  // in pairs in case the face is already or will be
5325  // refined anisotropically
5326  needed_quads_pair += 4;
5327  needed_lines_pair += 4;
5328  needed_vertices += 1;
5329  }
5330  if (quad->user_index())
5331  {
5332  // anisotropic refinement: 1 interior
5333  // line and two quads
5334  needed_quads_pair += 2;
5335  needed_lines_single += 1;
5336  // there is a kind of complicated situation here which
5337  // requires our attention. if the quad is refined
5338  // isotropcally, two of the interior lines will get a
5339  // new mother line - the interior line of our
5340  // anisotropically refined quad. if those two lines
5341  // are not consecutive, we cannot do so and have to
5342  // replace them by two lines that are consecutive. we
5343  // try to avoid that situation, but it may happen
5344  // nevertheless through repeated refinement and
5345  // coarsening. thus we have to check here, as we will
5346  // need some additional space to store those new lines
5347  // in case we need them...
5348  if (quad->has_children())
5349  {
5350  Assert(quad->refinement_case() ==
5352  ExcInternalError());
5353  if ((face_refinement_cases[quad->user_index()] ==
5355  (quad->child(0)->line_index(1) + 1 !=
5356  quad->child(2)->line_index(1))) ||
5357  (face_refinement_cases[quad->user_index()] ==
5359  (quad->child(0)->line_index(3) + 1 !=
5360  quad->child(1)->line_index(3))))
5361  needed_lines_pair += 2;
5362  }
5363  }
5364  }
5365 
5366  for (typename Triangulation<dim, spacedim>::line_iterator line =
5367  triangulation.begin_line();
5368  line != triangulation.end_line();
5369  ++line)
5370  if (line->user_flag_set())
5371  {
5372  needed_lines_pair += 2;
5373  needed_vertices += 1;
5374  }
5375 
5376  // reserve space for needed_lines new lines stored in pairs
5377  reserve_space(triangulation.faces->lines,
5378  needed_lines_pair,
5379  needed_lines_single);
5380  // reserve space for needed_quads new quads stored in pairs
5382  needed_quads_pair,
5383  needed_quads_single);
5384  reserve_space(triangulation.faces->quads,
5385  needed_quads_pair,
5386  needed_quads_single);
5387 
5388 
5389  // add to needed vertices how many vertices are already in use
5390  needed_vertices += std::count(triangulation.vertices_used.begin(),
5391  triangulation.vertices_used.end(),
5392  true);
5393  // if we need more vertices: create them, if not: leave the
5394  // array as is, since shrinking is not really possible because
5395  // some of the vertices at the end may be in use
5396  if (needed_vertices > triangulation.vertices.size())
5397  {
5398  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
5399  triangulation.vertices_used.resize(needed_vertices, false);
5400  }
5401 
5402 
5404  // Before we start with the actual refinement, we do some
5405  // sanity checks if in debug mode. especially, we try to catch
5406  // the notorious problem with lines being twice refined,
5407  // i.e. there are cells adjacent at one line ("around the
5408  // edge", but not at a face), with two cells differing by more
5409  // than one refinement level
5410  //
5411  // this check is very simple to implement here, since we have
5412  // all lines flagged if they shall be refined
5413 #ifdef DEBUG
5414  for (const auto &cell : triangulation.active_cell_iterators())
5415  if (!cell->refine_flag_set())
5416  for (unsigned int line = 0;
5417  line < GeometryInfo<dim>::lines_per_cell;
5418  ++line)
5419  if (cell->line(line)->has_children())
5420  for (unsigned int c = 0; c < 2; ++c)
5421  Assert(cell->line(line)->child(c)->user_flag_set() == false,
5422  ExcInternalError());
5423 #endif
5424 
5426  // Do refinement on every level
5427  //
5428  // To make life a bit easier, we first refine those lines and
5429  // quads that were flagged for refinement and then compose the
5430  // newly to be created cells.
5431  //
5432  // index of next unused vertex
5433  unsigned int next_unused_vertex = 0;
5434 
5435  // first for lines
5436  {
5437  // only active objects can be refined further
5439  line = triangulation.begin_active_line(),
5440  endl = triangulation.end_line();
5442  next_unused_line = triangulation.begin_raw_line();
5443 
5444  for (; line != endl; ++line)
5445  if (line->user_flag_set())
5446  {
5447  // this line needs to be refined
5448 
5449  // find the next unused vertex and set it
5450  // appropriately
5451  while (triangulation.vertices_used[next_unused_vertex] == true)
5452  ++next_unused_vertex;
5453  Assert(
5454  next_unused_vertex < triangulation.vertices.size(),
5455  ExcMessage(
5456  "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."));
5457  triangulation.vertices_used[next_unused_vertex] = true;
5458 
5459  triangulation.vertices[next_unused_vertex] = line->center(true);
5460 
5461  // now that we created the right point, make up the
5462  // two child lines (++ takes care of the end of the
5463  // vector)
5464  next_unused_line =
5465  triangulation.faces->lines.template next_free_pair_object<1>(
5466  triangulation);
5467  Assert(next_unused_line.state() == IteratorState::valid,
5468  ExcInternalError());
5469 
5470  // now we found two consecutive unused lines, such
5471  // that the children of a line will be consecutive.
5472  // then set the child pointer of the present line
5473  line->set_children(0, next_unused_line->index());
5474 
5475  // set the two new lines
5477  children[2] = {next_unused_line, ++next_unused_line};
5478 
5479  // some tests; if any of the iterators should be
5480  // invalid, then already dereferencing will fail
5481  Assert(
5482  children[0]->used() == false,
5483  ExcMessage(
5484  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5485  Assert(
5486  children[1]->used() == false,
5487  ExcMessage(
5488  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5489 
5490  children[0]->set_bounding_object_indices(
5491  {line->vertex_index(0), next_unused_vertex});
5492  children[1]->set_bounding_object_indices(
5493  {next_unused_vertex, line->vertex_index(1)});
5494 
5495  children[0]->set_used_flag();
5496  children[1]->set_used_flag();
5497  children[0]->clear_children();
5498  children[1]->clear_children();
5499  children[0]->clear_user_data();
5500  children[1]->clear_user_data();
5501  children[0]->clear_user_flag();
5502  children[1]->clear_user_flag();
5503 
5504  children[0]->set_boundary_id_internal(line->boundary_id());
5505  children[1]->set_boundary_id_internal(line->boundary_id());
5506 
5507  children[0]->set_manifold_id(line->manifold_id());
5508  children[1]->set_manifold_id(line->manifold_id());
5509 
5510  // finally clear flag
5511  // indicating the need
5512  // for refinement
5513  line->clear_user_flag();
5514  }
5515  }
5516 
5517 
5519  // now refine marked quads
5521 
5522  // here we encounter several cases:
5523 
5524  // a) the quad is unrefined and shall be refined isotropically
5525 
5526  // b) the quad is unrefined and shall be refined
5527  // anisotropically
5528 
5529  // c) the quad is unrefined and shall be refined both
5530  // anisotropically and isotropically (this is reduced to case
5531  // b) and then case b) for the children again)
5532 
5533  // d) the quad is refined anisotropically and shall be refined
5534  // isotropically (this is reduced to case b) for the
5535  // anisotropic children)
5536 
5537  // e) the quad is refined isotropically and shall be refined
5538  // anisotropically (this is transformed to case c), however we
5539  // might have to renumber/rename children...)
5540 
5541  // we need a loop in cases c) and d), as the anisotropic
5542  // children migt have a lower index than the mother quad
5543  for (unsigned int loop = 0; loop < 2; ++loop)
5544  {
5545  // usually, only active objects can be refined
5546  // further. however, in cases d) and e) that is not true,
5547  // so we have to use 'normal' iterators here
5549  quad = triangulation.begin_quad(),
5550  endq = triangulation.end_quad();
5552  next_unused_line = triangulation.begin_raw_line();
5554  next_unused_quad = triangulation.begin_raw_quad();
5555 
5556  for (; quad != endq; ++quad)
5557  {
5558  if (quad->user_index())
5559  {
5560  RefinementCase<dim - 1> aniso_quad_ref_case =
5561  face_refinement_cases[quad->user_index()];
5562  // there is one unlikely event here, where we
5563  // already have refind the face: if the face was
5564  // refined anisotropically and we want to refine
5565  // it isotropically, both children are flagged for
5566  // anisotropic refinement. however, if those
5567  // children were already flagged for anisotropic
5568  // refinement, they might already be processed and
5569  // refined.
5570  if (aniso_quad_ref_case == quad->refinement_case())
5571  continue;
5572 
5573  Assert(quad->refinement_case() ==
5575  quad->refinement_case() ==
5577  ExcInternalError());
5578 
5579  // this quad needs to be refined anisotropically
5580  Assert(quad->user_index() ==
5582  quad->user_index() ==
5584  ExcInternalError());
5585 
5586  // make the new line interior to the quad
5588  new_line;
5589 
5590  new_line =
5591  triangulation.faces->lines
5592  .template next_free_single_object<1>(triangulation);
5593  Assert(
5594  new_line->used() == false,
5595  ExcMessage(
5596  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5597 
5598  // first collect the
5599  // indices of the vertices:
5600  // *--1--*
5601  // | | |
5602  // | | | cut_x
5603  // | | |
5604  // *--0--*
5605  //
5606  // *-----*
5607  // | |
5608  // 0-----1 cut_y
5609  // | |
5610  // *-----*
5611  unsigned int vertex_indices[2];
5612  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5613  {
5614  vertex_indices[0] =
5615  quad->line(2)->child(0)->vertex_index(1);
5616  vertex_indices[1] =
5617  quad->line(3)->child(0)->vertex_index(1);
5618  }
5619  else
5620  {
5621  vertex_indices[0] =
5622  quad->line(0)->child(0)->vertex_index(1);
5623  vertex_indices[1] =
5624  quad->line(1)->child(0)->vertex_index(1);
5625  }
5626 
5627  new_line->set_bounding_object_indices(
5628  {vertex_indices[0], vertex_indices[1]});
5629  new_line->set_used_flag();
5630  new_line->clear_user_flag();
5631  new_line->clear_user_data();
5632  new_line->clear_children();
5633  new_line->set_boundary_id_internal(quad->boundary_id());
5634  new_line->set_manifold_id(quad->manifold_id());
5635 
5636  // child 0 and 1 of a line are switched if the
5637  // line orientation is false. set up a miniature
5638  // table, indicating which child to take for line
5639  // orientations false and true. first index: child
5640  // index in standard orientation, second index:
5641  // line orientation
5642  const unsigned int index[2][2] = {
5643  {1, 0}, // child 0, line_orientation=false and true
5644  {0, 1}}; // child 1, line_orientation=false and true
5645 
5646  // find some space (consecutive) for the two newly
5647  // to be created quads.
5649  new_quads[2];
5650 
5651  next_unused_quad =
5652  triangulation.faces->quads
5653  .template next_free_pair_object<2>(triangulation);
5654  new_quads[0] = next_unused_quad;
5655  Assert(
5656  new_quads[0]->used() == false,
5657  ExcMessage(
5658  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5659 
5660  ++next_unused_quad;
5661  new_quads[1] = next_unused_quad;
5662  Assert(
5663  new_quads[1]->used() == false,
5664  ExcMessage(
5665  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5666 
5667 
5668  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5669  {
5670  new_quads[0]->set_bounding_object_indices(
5671  {static_cast<int>(quad->line_index(0)),
5672  new_line->index(),
5673  quad->line(2)
5674  ->child(index[0][quad->line_orientation(2)])
5675  ->index(),
5676  quad->line(3)
5677  ->child(index[0][quad->line_orientation(3)])
5678  ->index()});
5679  new_quads[1]->set_bounding_object_indices(
5680  {new_line->index(),
5681  static_cast<int>(quad->line_index(1)),
5682  quad->line(2)
5683  ->child(index[1][quad->line_orientation(2)])
5684  ->index(),
5685  quad->line(3)
5686  ->child(index[1][quad->line_orientation(3)])
5687  ->index()});
5688  }
5689  else
5690  {
5691  new_quads[0]->set_bounding_object_indices(
5692  {quad->line(0)
5693  ->child(index[0][quad->line_orientation(0)])
5694  ->index(),
5695  quad->line(1)
5696  ->child(index[0][quad->line_orientation(1)])
5697  ->index(),
5698  static_cast<int>(quad->line_index(2)),
5699  new_line->index()});
5700  new_quads[1]->set_bounding_object_indices(
5701  {quad->line(0)
5702  ->child(index[1][quad->line_orientation(0)])
5703  ->index(),
5704  quad->line(1)
5705  ->child(index[1][quad->line_orientation(1)])
5706  ->index(),
5707  new_line->index(),
5708  static_cast<int>(quad->line_index(3))});
5709  }
5710 
5711  for (const auto &new_quad : new_quads)
5712  {
5713  new_quad->set_used_flag();
5714  new_quad->clear_user_flag();
5715  new_quad->clear_user_data();
5716  new_quad->clear_children();
5717  new_quad->set_boundary_id_internal(quad->boundary_id());
5718  new_quad->set_manifold_id(quad->manifold_id());
5719  // set all line orientations to true, change
5720  // this after the loop, as we have to consider
5721  // different lines for each child
5722  for (unsigned int j = 0;
5723  j < GeometryInfo<dim>::lines_per_face;
5724  ++j)
5725  new_quad->set_line_orientation(j, true);
5726  }
5727  // now set the line orientation of children of
5728  // outer lines correctly, the lines in the
5729  // interior of the refined quad are automatically
5730  // oriented conforming to the standard
5731  new_quads[0]->set_line_orientation(
5732  0, quad->line_orientation(0));
5733  new_quads[0]->set_line_orientation(
5734  2, quad->line_orientation(2));
5735  new_quads[1]->set_line_orientation(
5736  1, quad->line_orientation(1));
5737  new_quads[1]->set_line_orientation(
5738  3, quad->line_orientation(3));
5739  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5740  {
5741  new_quads[0]->set_line_orientation(
5742  3, quad->line_orientation(3));
5743  new_quads[1]->set_line_orientation(
5744  2, quad->line_orientation(2));
5745  }
5746  else
5747  {
5748  new_quads[0]->set_line_orientation(
5749  1, quad->line_orientation(1));
5750  new_quads[1]->set_line_orientation(
5751  0, quad->line_orientation(0));
5752  }
5753 
5754  // test, whether this face is refined
5755  // isotropically already. if so, set the correct
5756  // children pointers.
5757  if (quad->refinement_case() ==
5758  RefinementCase<dim - 1>::cut_xy)
5759  {
5760  // we will put a new refinemnt level of
5761  // anisotropic refinement between the
5762  // unrefined and isotropically refined quad
5763  // ending up with the same fine quads but
5764  // introducing anisotropically refined ones as
5765  // children of the unrefined quad and mother
5766  // cells of the original fine ones.
5767 
5768  // this process includes the creation of a new
5769  // middle line which we will assign as the
5770  // mother line of two of the existing inner
5771  // lines. If those inner lines are not
5772  // consecutive in memory, we won't find them
5773  // later on, so we have to create new ones
5774  // instead and replace all occurrences of the
5775  // old ones with those new ones. As this is
5776  // kind of ugly, we hope we don't have to do
5777  // it often...
5779  old_child[2];
5780  if (aniso_quad_ref_case ==
5782  {
5783  old_child[0] = quad->child(0)->line(1);
5784  old_child[1] = quad->child(2)->line(1);
5785  }
5786  else
5787  {
5788  Assert(aniso_quad_ref_case ==
5790  ExcInternalError());
5791 
5792  old_child[0] = quad->child(0)->line(3);
5793  old_child[1] = quad->child(1)->line(3);
5794  }
5795 
5796  if (old_child[0]->index() + 1 != old_child[1]->index())
5797  {
5798  // this is exactly the ugly case we taked
5799  // about. so, no coimplaining, lets get
5800  // two new lines and copy all info
5801  typename Triangulation<dim,
5802  spacedim>::raw_line_iterator
5803  new_child[2];
5804 
5805  new_child[0] = new_child[1] =
5806  triangulation.faces->lines
5807  .template next_free_pair_object<1>(
5808  triangulation);
5809  ++new_child[1];
5810 
5811  new_child[0]->set_used_flag();
5812  new_child[1]->set_used_flag();
5813 
5814  const int old_index_0 = old_child[0]->index(),
5815  old_index_1 = old_child[1]->index(),
5816  new_index_0 = new_child[0]->index(),
5817  new_index_1 = new_child[1]->index();
5818 
5819  // loop over all quads and replace the old
5820  // lines
5821  for (unsigned int q = 0;
5822  q < triangulation.faces->quads.n_objects();
5823  ++q)
5824  for (unsigned int l = 0;
5825  l < GeometryInfo<dim>::lines_per_face;
5826  ++l)
5827  {
5828  const int this_index =
5829  triangulation.faces->quads
5830  .get_bounding_object_indices(q)[l];
5831  if (this_index == old_index_0)
5832  triangulation.faces->quads
5833  .get_bounding_object_indices(q)[l] =
5834  new_index_0;
5835  else if (this_index == old_index_1)
5836  triangulation.faces->quads
5837  .get_bounding_object_indices(q)[l] =
5838  new_index_1;
5839  }
5840  // now we have to copy all information of
5841  // the two lines
5842  for (unsigned int i = 0; i < 2; ++i)
5843  {
5844  Assert(!old_child[i]->has_children(),
5845  ExcInternalError());
5846 
5847  new_child[i]->set_bounding_object_indices(
5848  {old_child[i]->vertex_index(0),
5849  old_child[i]->vertex_index(1)});
5850  new_child[i]->set_boundary_id_internal(
5851  old_child[i]->boundary_id());
5852  new_child[i]->set_manifold_id(
5853  old_child[i]->manifold_id());
5854  new_child[i]->set_user_index(
5855  old_child[i]->user_index());
5856  if (old_child[i]->user_flag_set())
5857  new_child[i]->set_user_flag();
5858  else
5859  new_child[i]->clear_user_flag();
5860 
5861  new_child[i]->clear_children();
5862 
5863  old_child[i]->clear_user_flag();
5864  old_child[i]->clear_user_index();
5865  old_child[i]->clear_used_flag();
5866  }
5867  }
5868  // now that we cared about the lines, go on
5869  // with the quads themselves, where we might
5870  // encounter similar situations...
5871  if (aniso_quad_ref_case ==
5873  {
5874  new_line->set_children(
5875  0, quad->child(0)->line_index(1));
5876  Assert(new_line->child(1) ==
5877  quad->child(2)->line(1),
5878  ExcInternalError());
5879  // now evereything is quite
5880  // complicated. we have the children
5881  // numbered according to
5882  //
5883  // *---*---*
5884  // |n+2|n+3|
5885  // *---*---*
5886  // | n |n+1|
5887  // *---*---*
5888  //
5889  // from the original isotropic
5890  // refinement. we have to reorder them as
5891  //
5892  // *---*---*
5893  // |n+1|n+3|
5894  // *---*---*
5895  // | n |n+2|
5896  // *---*---*
5897  //
5898  // such that n and n+1 are consecutive
5899  // children of m and n+2 and n+3 are
5900  // consecutive children of m+1, where m
5901  // and m+1 are given as in
5902  //
5903  // *---*---*
5904  // | | |
5905  // | m |m+1|
5906  // | | |
5907  // *---*---*
5908  //
5909  // this is a bit ugly, of course: loop
5910  // over all cells on all levels and look
5911  // for faces n+1 (switch_1) and n+2
5912  // (switch_2).
5913  const typename Triangulation<dim, spacedim>::
5914  quad_iterator switch_1 = quad->child(1),
5915  switch_2 = quad->child(2);
5916  const int switch_1_index = switch_1->index();
5917  const int switch_2_index = switch_2->index();
5918  for (unsigned int l = 0;
5919  l < triangulation.levels.size();
5920  ++l)
5921  for (unsigned int h = 0;
5922  h <
5923  triangulation.levels[l]->cells.n_objects();
5924  ++h)
5925  for (const unsigned int q :
5927  {
5928  const int face_index =
5929  triangulation.levels[l]
5930  ->cells.get_bounding_object_indices(
5931  h)[q];
5932  if (face_index == switch_1_index)
5933  triangulation.levels[l]
5934  ->cells.get_bounding_object_indices(
5935  h)[q] = switch_2_index;
5936  else if (face_index == switch_2_index)
5937  triangulation.levels[l]
5938  ->cells.get_bounding_object_indices(
5939  h)[q] = switch_1_index;
5940  }
5941  // now we have to copy all information of
5942  // the two quads
5943  const unsigned int switch_1_lines[4] = {
5944  switch_1->line_index(0),
5945  switch_1->line_index(1),
5946  switch_1->line_index(2),
5947  switch_1->line_index(3)};
5948  const bool switch_1_line_orientations[4] = {
5949  switch_1->line_orientation(0),
5950  switch_1->line_orientation(1),
5951  switch_1->line_orientation(2),
5952  switch_1->line_orientation(3)};
5953  const types::boundary_id switch_1_boundary_id =
5954  switch_1->boundary_id();
5955  const unsigned int switch_1_user_index =
5956  switch_1->user_index();
5957  const bool switch_1_user_flag =
5958  switch_1->user_flag_set();
5959  const RefinementCase<dim - 1>
5960  switch_1_refinement_case =
5961  switch_1->refinement_case();
5962  const int switch_1_first_child_pair =
5963  (switch_1_refinement_case ?
5964  switch_1->child_index(0) :
5965  -1);
5966  const int switch_1_second_child_pair =
5967  (switch_1_refinement_case ==
5968  RefinementCase<dim - 1>::cut_xy ?
5969  switch_1->child_index(2) :
5970  -1);
5971 
5972  switch_1->set_bounding_object_indices(
5973  {switch_2->line_index(0),
5974  switch_2->line_index(1),
5975  switch_2->line_index(2),
5976  switch_2->line_index(3)});
5977  switch_1->set_line_orientation(
5978  0, switch_2->line_orientation(0));
5979  switch_1->set_line_orientation(
5980  1, switch_2->line_orientation(1));
5981  switch_1->set_line_orientation(
5982  2, switch_2->line_orientation(2));
5983  switch_1->set_line_orientation(
5984  3, switch_2->line_orientation(3));
5985  switch_1->set_boundary_id_internal(
5986  switch_2->boundary_id());
5987  switch_1->set_manifold_id(switch_2->manifold_id());
5988  switch_1->set_user_index(switch_2->user_index());
5989  if (switch_2->user_flag_set())
5990  switch_1->set_user_flag();
5991  else
5992  switch_1->clear_user_flag();
5993  switch_1->clear_refinement_case();
5994  switch_1->set_refinement_case(
5995  switch_2->refinement_case());
5996  switch_1->clear_children();
5997  if (switch_2->refinement_case())
5998  switch_1->set_children(0,
5999  switch_2->child_index(0));
6000  if (switch_2->refinement_case() ==
6001  RefinementCase<dim - 1>::cut_xy)
6002  switch_1->set_children(2,
6003  switch_2->child_index(2));
6004 
6005  switch_2->set_bounding_object_indices(
6006  {switch_1_lines[0],
6007  switch_1_lines[1],
6008  switch_1_lines[2],
6009  switch_1_lines[3]});
6010  switch_2->set_line_orientation(
6011  0, switch_1_line_orientations[0]);
6012  switch_2->set_line_orientation(
6013  1, switch_1_line_orientations[1]);
6014  switch_2->set_line_orientation(
6015  2, switch_1_line_orientations[2]);
6016  switch_2->set_line_orientation(
6017  3, switch_1_line_orientations[3]);
6018  switch_2->set_boundary_id_internal(
6019  switch_1_boundary_id);
6020  switch_2->set_manifold_id(switch_1->manifold_id());
6021  switch_2->set_user_index(switch_1_user_index);
6022  if (switch_1_user_flag)
6023  switch_2->set_user_flag();
6024  else
6025  switch_2->clear_user_flag();
6026  switch_2->clear_refinement_case();
6027  switch_2->set_refinement_case(
6028  switch_1_refinement_case);
6029  switch_2->clear_children();
6030  switch_2->set_children(0,
6031  switch_1_first_child_pair);
6032  switch_2->set_children(2,
6033  switch_1_second_child_pair);
6034 
6035  new_quads[0]->set_refinement_case(
6037  new_quads[0]->set_children(0, quad->child_index(0));
6038  new_quads[1]->set_refinement_case(
6040  new_quads[1]->set_children(0, quad->child_index(2));
6041  }
6042  else
6043  {
6044  new_quads[0]->set_refinement_case(
6046  new_quads[0]->set_children(0, quad->child_index(0));
6047  new_quads[1]->set_refinement_case(
6049  new_quads[1]->set_children(0, quad->child_index(2));
6050  new_line->set_children(
6051  0, quad->child(0)->line_index(3));
6052  Assert(new_line->child(1) ==
6053  quad->child(1)->line(3),
6054  ExcInternalError());
6055  }
6056  quad->clear_children();
6057  }
6058 
6059  // note these quads as children to the present one
6060  quad->set_children(0, new_quads[0]->index());
6061 
6062  quad->set_refinement_case(aniso_quad_ref_case);
6063 
6064  // finally clear flag indicating the need for
6065  // refinement
6066  quad->clear_user_data();
6067  } // if (anisotropic refinement)
6068 
6069  if (quad->user_flag_set())
6070  {
6071  // this quad needs to be refined isotropically
6072 
6073  // first of all: we only get here in the first run
6074  // of the loop
6075  Assert(loop == 0, ExcInternalError());
6076 
6077  // find the next unused vertex. we'll need this in
6078  // any case
6079  while (triangulation.vertices_used[next_unused_vertex] ==
6080  true)
6081  ++next_unused_vertex;
6082  Assert(
6083  next_unused_vertex < triangulation.vertices.size(),
6084  ExcMessage(
6085  "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."));
6086 
6087  // now: if the quad is refined anisotropically
6088  // already, set the anisotropic refinement flag
6089  // for both children. Additionally, we have to
6090  // refine the inner line, as it is an outer line
6091  // of the two (anisotropic) children
6092  const RefinementCase<dim - 1> quad_ref_case =
6093  quad->refinement_case();
6094 
6095  if (quad_ref_case == RefinementCase<dim - 1>::cut_x ||
6096  quad_ref_case == RefinementCase<dim - 1>::cut_y)
6097  {
6098  // set the 'opposite' refine case for children
6099  quad->child(0)->set_user_index(
6100  RefinementCase<dim - 1>::cut_xy - quad_ref_case);
6101  quad->child(1)->set_user_index(
6102  RefinementCase<dim - 1>::cut_xy - quad_ref_case);
6103  // refine the inner line
6105  middle_line;
6106  if (quad_ref_case == RefinementCase<dim - 1>::cut_x)
6107  middle_line = quad->child(0)->line(1);
6108  else
6109  middle_line = quad->child(0)->line(3);
6110 
6111  // if the face has been refined
6112  // anisotropically in the last refinement step
6113  // it might be, that it is flagged already and
6114  // that the middle line is thus refined
6115  // already. if not create children.
6116  if (!middle_line->has_children())
6117  {
6118  // set the middle vertex
6119  // appropriately. double refinement of
6120  // quads can only happen in the interior
6121  // of the domain, so we need not care
6122  // about boundary quads here
6123  triangulation.vertices[next_unused_vertex] =
6124  middle_line->center(true);
6125  triangulation.vertices_used[next_unused_vertex] =
6126  true;
6127 
6128  // now search a slot for the two
6129  // child lines
6130  next_unused_line =
6131  triangulation.faces->lines
6132  .template next_free_pair_object<1>(
6133  triangulation);
6134 
6135  // set the child pointer of the present
6136  // line
6137  middle_line->set_children(
6138  0, next_unused_line->index());
6139 
6140  // set the two new lines
6141  const typename Triangulation<dim, spacedim>::
6142  raw_line_iterator children[2] = {
6143  next_unused_line, ++next_unused_line};
6144 
6145  // some tests; if any of the iterators
6146  // should be invalid, then already
6147  // dereferencing will fail
6148  Assert(
6149  children[0]->used() == false,
6150  ExcMessage(
6151  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6152  Assert(
6153  children[1]->used() == false,
6154  ExcMessage(
6155  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6156 
6157  children[0]->set_bounding_object_indices(
6158  {middle_line->vertex_index(0),
6159  next_unused_vertex});
6160  children[1]->set_bounding_object_indices(
6161  {next_unused_vertex,
6162  middle_line->vertex_index(1)});
6163 
6164  children[0]->set_used_flag();
6165  children[1]->set_used_flag();
6166  children[0]->clear_children();
6167  children[1]->clear_children();
6168  children[0]->clear_user_data();
6169  children[1]->clear_user_data();
6170  children[0]->clear_user_flag();
6171  children[1]->clear_user_flag();
6172 
6173  children[0]->set_boundary_id_internal(
6174  middle_line->boundary_id());
6175  children[1]->set_boundary_id_internal(
6176  middle_line->boundary_id());
6177 
6178  children[0]->set_manifold_id(
6179  middle_line->manifold_id());
6180  children[1]->set_manifold_id(
6181  middle_line->manifold_id());
6182  }
6183  // now remove the flag from the quad and go to
6184  // the next quad, the actual refinement of the
6185  // quad takes place later on in this pass of
6186  // the loop or in the next one
6187  quad->clear_user_flag();
6188  continue;
6189  } // if (several refinement cases)
6190 
6191  // if we got here, we have an unrefined quad and
6192  // have to do the usual work like in an purely
6193  // isotropic refinement
6194  Assert(quad_ref_case ==
6196  ExcInternalError());
6197 
6198  // set the middle vertex appropriately: it might be that
6199  // the quad itself is not at the boundary, but that one of
6200  // its lines actually is. in this case, the newly created
6201  // vertices at the centers of the lines are not
6202  // necessarily the mean values of the adjacent vertices,
6203  // so do not compute the new vertex as the mean value of
6204  // the 4 vertices of the face, but rather as a weighted
6205  // mean value of the 8 vertices which we already have (the
6206  // four old ones, and the four ones inserted as middle
6207  // points for the four lines). summing up some more points
6208  // is generally cheaper than first asking whether one of
6209  // the lines is at the boundary
6210  //
6211  // note that the exact weights are chosen such as to
6212  // minimize the distortion of the four new quads from the
6213  // optimal shape. their description uses the formulas
6214  // underlying the TransfiniteInterpolationManifold
6215  // implementation
6216  triangulation.vertices[next_unused_vertex] =
6217  quad->center(true, true);
6218  triangulation.vertices_used[next_unused_vertex] = true;
6219 
6220  // now that we created the right point, make up
6221  // the four lines interior to the quad (++ takes
6222  // care of the end of the vector)
6224  new_lines[4];
6225 
6226  for (unsigned int i = 0; i < 4; ++i)
6227  {
6228  if (i % 2 == 0)
6229  // search a free pair of lines for 0. and
6230  // 2. line, so that two of them end up
6231  // together, which is necessary if later on
6232  // we want to refine the quad
6233  // anisotropically and the two lines end up
6234  // as children of new line
6235  next_unused_line =
6236  triangulation.faces->lines
6237  .template next_free_pair_object<1>(triangulation);
6238 
6239  new_lines[i] = next_unused_line;
6240  ++next_unused_line;
6241 
6242  Assert(
6243  new_lines[i]->used() == false,
6244  ExcMessage(
6245  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6246  }
6247 
6248  // set the data of the four lines. first collect
6249  // the indices of the five vertices:
6250  //
6251  // *--3--*
6252  // | | |
6253  // 0--4--1
6254  // | | |
6255  // *--2--*
6256  //
6257  // the lines are numbered as follows:
6258  //
6259  // *--*--*
6260  // | 1 |
6261  // *2-*-3*
6262  // | 0 |
6263  // *--*--*
6264 
6265  const unsigned int vertex_indices[5] = {
6266  quad->line(0)->child(0)->vertex_index(1),
6267  quad->line(1)->child(0)->vertex_index(1),
6268  quad->line(2)->child(0)->vertex_index(1),
6269  quad->line(3)->child(0)->vertex_index(1),
6270  next_unused_vertex};
6271 
6272  new_lines[0]->set_bounding_object_indices(
6273  {vertex_indices[2], vertex_indices[4]});
6274  new_lines[1]->set_bounding_object_indices(
6275  {vertex_indices[4], vertex_indices[3]});
6276  new_lines[2]->set_bounding_object_indices(
6277  {vertex_indices[0], vertex_indices[4]});
6278  new_lines[3]->set_bounding_object_indices(
6279  {vertex_indices[4], vertex_indices[1]});
6280 
6281  for (const auto &new_line : new_lines)
6282  {
6283  new_line->set_used_flag();
6284  new_line->clear_user_flag();
6285  new_line->clear_user_data();
6286  new_line->clear_children();
6287  new_line->set_boundary_id_internal(quad->boundary_id());
6288  new_line->set_manifold_id(quad->manifold_id());
6289  }
6290 
6291  // now for the quads. again, first collect some
6292  // data about the indices of the lines, with the
6293  // following numbering:
6294  //
6295  // .-6-.-7-.
6296  // 1 9 3
6297  // .-10.11-.
6298  // 0 8 2
6299  // .-4-.-5-.
6300 
6301  // child 0 and 1 of a line are switched if the
6302  // line orientation is false. set up a miniature
6303  // table, indicating which child to take for line
6304  // orientations false and true. first index: child
6305  // index in standard orientation, second index:
6306  // line orientation
6307  const unsigned int index[2][2] = {
6308  {1, 0}, // child 0, line_orientation=false and true
6309  {0, 1}}; // child 1, line_orientation=false and true
6310 
6311  const int line_indices[12] = {
6312  quad->line(0)
6313  ->child(index[0][quad->line_orientation(0)])
6314  ->index(),
6315  quad->line(0)
6316  ->child(index[1][quad->line_orientation(0)])
6317  ->index(),
6318  quad->line(1)
6319  ->child(index[0][quad->line_orientation(1)])
6320  ->index(),
6321  quad->line(1)
6322  ->child(index[1][quad->line_orientation(1)])
6323  ->index(),
6324  quad->line(2)
6325  ->child(index[0][quad->line_orientation(2)])
6326  ->index(),
6327  quad->line(2)
6328  ->child(index[1][quad->line_orientation(2)])
6329  ->index(),
6330  quad->line(3)
6331  ->child(index[0][quad->line_orientation(3)])
6332  ->index(),
6333  quad->line(3)
6334  ->child(index[1][quad->line_orientation(3)])
6335  ->index(),
6336  new_lines[0]->index(),
6337  new_lines[1]->index(),
6338  new_lines[2]->index(),
6339  new_lines[3]->index()};
6340 
6341  // find some space (consecutive)
6342  // for the first two newly to be
6343  // created quads.
6345  new_quads[4];
6346 
6347  next_unused_quad =
6348  triangulation.faces->quads
6349  .template next_free_pair_object<2>(triangulation);
6350 
6351  new_quads[0] = next_unused_quad;
6352  Assert(
6353  new_quads[0]->used() == false,
6354  ExcMessage(
6355  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6356 
6357  ++next_unused_quad;
6358  new_quads[1] = next_unused_quad;
6359  Assert(
6360  new_quads[1]->used() == false,
6361  ExcMessage(
6362  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6363 
6364  next_unused_quad =
6365  triangulation.faces->quads
6366  .template next_free_pair_object<2>(triangulation);
6367  new_quads[2] = next_unused_quad;
6368  Assert(
6369  new_quads[2]->used() == false,
6370  ExcMessage(
6371  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6372 
6373  ++next_unused_quad;
6374  new_quads[3] = next_unused_quad;
6375  Assert(
6376  new_quads[3]->used() == false,
6377  ExcMessage(
6378  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6379 
6380  // note these quads as children to the present one
6381  quad->set_children(0, new_quads[0]->index());
6382  quad->set_children(2, new_quads[2]->index());
6383  quad->set_refinement_case(RefinementCase<2>::cut_xy);
6384 
6385  new_quads[0]->set_bounding_object_indices(
6386  {line_indices[0],
6387  line_indices[8],
6388  line_indices[4],
6389  line_indices[10]});
6390  new_quads[1]->set_bounding_object_indices(
6391  {line_indices[8],
6392  line_indices[2],
6393  line_indices[5],
6394  line_indices[11]});
6395  new_quads[2]->set_bounding_object_indices(
6396  {line_indices[1],
6397  line_indices[9],
6398  line_indices[10],
6399  line_indices[6]});
6400  new_quads[3]->set_bounding_object_indices(
6401  {line_indices[9],
6402  line_indices[3],
6403  line_indices[11],
6404  line_indices[7]});
6405  for (const auto &new_quad : new_quads)
6406  {
6407  new_quad->set_used_flag();
6408  new_quad->clear_user_flag();
6409  new_quad->clear_user_data();
6410  new_quad->clear_children();
6411  new_quad->set_boundary_id_internal(quad->boundary_id());
6412  new_quad->set_manifold_id(quad->manifold_id());
6413  // set all line orientations to true, change
6414  // this after the loop, as we have to consider
6415  // different lines for each child
6416  for (unsigned int j = 0;
6417  j < GeometryInfo<dim>::lines_per_face;
6418  ++j)
6419  new_quad->set_line_orientation(j, true);
6420  }
6421  // now set the line orientation of children of
6422  // outer lines correctly, the lines in the
6423  // interior of the refined quad are automatically
6424  // oriented conforming to the standard
6425  new_quads[0]->set_line_orientation(
6426  0, quad->line_orientation(0));
6427  new_quads[0]->set_line_orientation(
6428  2, quad->line_orientation(2));
6429  new_quads[1]->set_line_orientation(
6430  1, quad->line_orientation(1));
6431  new_quads[1]->set_line_orientation(
6432  2, quad->line_orientation(2));
6433  new_quads[2]->set_line_orientation(
6434  0, quad->line_orientation(0));
6435  new_quads[2]->set_line_orientation(
6436  3, quad->line_orientation(3));
6437  new_quads[3]->set_line_orientation(
6438  1, quad->line_orientation(1));
6439  new_quads[3]->set_line_orientation(
6440  3, quad->line_orientation(3));
6441 
6442  // finally clear flag indicating the need for
6443  // refinement
6444  quad->clear_user_flag();
6445  } // if (isotropic refinement)
6446  } // for all quads
6447  } // looped two times over all quads, all quads refined now
6448 
6450  // Now, finally, set up the new
6451  // cells
6453 
6455  cells_with_distorted_children;
6456 
6457  for (unsigned int level = 0; level != triangulation.levels.size() - 1;
6458  ++level)
6459  {
6460  // only active objects can be refined further; remember
6461  // that we won't operate on the finest level, so
6462  // triangulation.begin_*(level+1) is allowed
6464  hex = triangulation.begin_active_hex(level),
6465  endh = triangulation.begin_active_hex(level + 1);
6467  next_unused_hex = triangulation.begin_raw_hex(level + 1);
6468 
6469  for (; hex != endh; ++hex)
6470  if (hex->refine_flag_set())
6471  {
6472  // this hex needs to be refined
6473 
6474  // clear flag indicating the need for refinement. do
6475  // it here already, since we can't do it anymore
6476  // once the cell has children
6477  const RefinementCase<dim> ref_case = hex->refine_flag_set();
6478  hex->clear_refine_flag();
6479  hex->set_refinement_case(ref_case);
6480 
6481  // depending on the refine case we might have to
6482  // create additional vertices, lines and quads
6483  // interior of the hex before the actual children
6484  // can be set up.
6485 
6486  // in a first step: reserve the needed space for
6487  // lines, quads and hexes and initialize them
6488  // correctly
6489 
6490  unsigned int n_new_lines = 0;
6491  unsigned int n_new_quads = 0;
6492  unsigned int n_new_hexes = 0;
6493  switch (ref_case)
6494  {
6498  n_new_lines = 0;
6499  n_new_quads = 1;
6500  n_new_hexes = 2;
6501  break;
6505  n_new_lines = 1;
6506  n_new_quads = 4;
6507  n_new_hexes = 4;
6508  break;
6510  n_new_lines = 6;
6511  n_new_quads = 12;
6512  n_new_hexes = 8;
6513  break;
6514  default:
6515  Assert(false, ExcInternalError());
6516  break;
6517  }
6518 
6519  // find some space for the newly to be created
6520  // interior lines and initialize them.
6521  std::vector<
6523  new_lines(n_new_lines);
6524  for (unsigned int i = 0; i < n_new_lines; ++i)
6525  {
6526  new_lines[i] =
6527  triangulation.faces->lines
6528  .template next_free_single_object<1>(triangulation);
6529 
6530  Assert(
6531  new_lines[i]->used() == false,
6532  ExcMessage(
6533  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6534  new_lines[i]->set_used_flag();
6535  new_lines[i]->clear_user_flag();
6536  new_lines[i]->clear_user_data();
6537  new_lines[i]->clear_children();
6538  // interior line
6539  new_lines[i]->set_boundary_id_internal(
6541  // they inherit geometry description of the hex they
6542  // belong to
6543  new_lines[i]->set_manifold_id(hex->manifold_id());
6544  }
6545 
6546  // find some space for the newly to be created
6547  // interior quads and initialize them.
6548  std::vector<
6550  new_quads(n_new_quads);
6551  for (unsigned int i = 0; i < n_new_quads; ++i)
6552  {
6553  new_quads[i] =
6554  triangulation.faces->quads
6555  .template next_free_single_object<2>(triangulation);
6556 
6557  Assert(
6558  new_quads[i]->used() == false,
6559  ExcMessage(
6560  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6561  new_quads[i]->set_used_flag();
6562  new_quads[i]->clear_user_flag();
6563  new_quads[i]->clear_user_data();
6564  new_quads[i]->clear_children();
6565  // interior quad
6566  new_quads[i]->set_boundary_id_internal(
6568  // they inherit geometry description of the hex they
6569  // belong to
6570  new_quads[i]->set_manifold_id(hex->manifold_id());
6571  // set all line orientation flags to true by
6572  // default, change this afterwards, if necessary
6573  for (unsigned int j = 0;
6574  j < GeometryInfo<dim>::lines_per_face;
6575  ++j)
6576  new_quads[i]->set_line_orientation(j, true);
6577  }
6578 
6579  types::subdomain_id subdomainid = hex->subdomain_id();
6580 
6581  // find some space for the newly to be created hexes
6582  // and initialize them.
6583  std::vector<
6585  new_hexes(n_new_hexes);
6586  for (unsigned int i = 0; i < n_new_hexes; ++i)
6587  {
6588  if (i % 2 == 0)
6589  next_unused_hex =
6590  triangulation.levels[level + 1]->cells.next_free_hex(
6591  triangulation, level + 1);
6592  else
6593  ++next_unused_hex;
6594 
6595  new_hexes[i] = next_unused_hex;
6596 
6597  Assert(
6598  new_hexes[i]->used() == false,
6599  ExcMessage(
6600  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6601  new_hexes[i]->set_used_flag();
6602  new_hexes[i]->clear_user_flag();
6603  new_hexes[i]->clear_user_data();
6604  new_hexes[i]->clear_children();
6605  // inherit material
6606  // properties
6607  new_hexes[i]->set_material_id(hex->material_id());
6608  new_hexes[i]->set_manifold_id(hex->manifold_id());
6609  new_hexes[i]->set_subdomain_id(subdomainid);
6610 
6611  if (i % 2)
6612  new_hexes[i]->set_parent(hex->index());
6613  // set the face_orientation flag to true for all
6614  // faces initially, as this is the default value
6615  // which is true for all faces interior to the
6616  // hex. later on go the other way round and
6617  // reset faces that are at the boundary of the
6618  // mother cube
6619  //
6620  // the same is true for the face_flip and
6621  // face_rotation flags. however, the latter two
6622  // are set to false by default as this is the
6623  // standard value
6624  for (const unsigned int f :
6626  {
6627  new_hexes[i]->set_face_orientation(f, true);
6628  new_hexes[i]->set_face_flip(f, false);
6629  new_hexes[i]->set_face_rotation(f, false);
6630  }
6631  }
6632  // note these hexes as children to the present cell
6633  for (unsigned int i = 0; i < n_new_hexes / 2; ++i)
6634  hex->set_children(2 * i, new_hexes[2 * i]->index());
6635 
6636  // we have to take into account whether the
6637  // different faces are oriented correctly or in the
6638  // opposite direction, so store that up front
6639 
6640  // face_orientation
6641  const bool f_or[6] = {hex->face_orientation(0),
6642  hex->face_orientation(1),
6643  hex->face_orientation(2),
6644  hex->face_orientation(3),
6645  hex->face_orientation(4),
6646  hex->face_orientation(5)};
6647 
6648  // face_flip
6649  const bool f_fl[6] = {hex->face_flip(0),
6650  hex->face_flip(1),
6651  hex->face_flip(2),
6652  hex->face_flip(3),
6653  hex->face_flip(4),
6654  hex->face_flip(5)};
6655 
6656  // face_rotation
6657  const bool f_ro[6] = {hex->face_rotation(0),
6658  hex->face_rotation(1),
6659  hex->face_rotation(2),
6660  hex->face_rotation(3),
6661  hex->face_rotation(4),
6662  hex->face_rotation(5)};
6663 
6664  // little helper table, indicating, whether the
6665  // child with index 0 or with index 1 can be found
6666  // at the standard origin of an anisotropically
6667  // refined quads in real orientation index 1:
6668  // (RefineCase - 1) index 2: face_flip
6669 
6670  // index 3: face rotation
6671  // note: face orientation has no influence
6672  const unsigned int child_at_origin[2][2][2] = {
6673  {{0, 0}, // RefinementCase<dim>::cut_x, face_flip=false,
6674  // face_rotation=false and true
6675  {1, 1}}, // RefinementCase<dim>::cut_x, face_flip=true,
6676  // face_rotation=false and true
6677  {{0, 1}, // RefinementCase<dim>::cut_y, face_flip=false,
6678  // face_rotation=false and true
6679  {1, 0}}}; // RefinementCase<dim>::cut_y, face_flip=true,
6680  // face_rotation=false and true
6681 
6683  //
6684  // in the following we will do the same thing for
6685  // each refinement case: create a new vertex (if
6686  // needed), create new interior lines (if needed),
6687  // create new interior quads and afterwards build
6688  // the children hexes out of these and the existing
6689  // subfaces of the outer quads (which have been
6690  // created above). However, even if the steps are
6691  // quite similar, the actual work strongly depends
6692  // on the actual refinement case. therefore, we use
6693  // separate blocks of code for each of these cases,
6694  // which hopefully increases the readability to some
6695  // extend.
6696 
6697  switch (ref_case)
6698  {
6700  {
6702  //
6703  // RefinementCase<dim>::cut_x
6704  //
6705  // the refined cube will look
6706  // like this:
6707  //
6708  // *----*----*
6709  // / / /|
6710  // / / / |
6711  // / / / |
6712  // *----*----* |
6713  // | | | |
6714  // | | | *
6715  // | | | /
6716  // | | | /
6717  // | | |/
6718  // *----*----*
6719  //
6720  // again, first collect some data about the
6721  // indices of the lines, with the following
6722  // numbering:
6723 
6724  // face 2: front plane
6725  // (note: x,y exchanged)
6726  // *---*---*
6727  // | | |
6728  // | 0 |
6729  // | | |
6730  // *---*---*
6731  // m0
6732  // face 3: back plane
6733  // (note: x,y exchanged)
6734  // m1
6735  // *---*---*
6736  // | | |
6737  // | 1 |
6738  // | | |
6739  // *---*---*
6740  // face 4: bottom plane
6741  // *---*---*
6742  // / / /
6743  // / 2 /
6744  // / / /
6745  // *---*---*
6746  // m0
6747  // face 5: top plane
6748  // m1
6749  // *---*---*
6750  // / / /
6751  // / 3 /
6752  // / / /
6753  // *---*---*
6754 
6755  // set up a list of line iterators first. from
6756  // this, construct lists of line_indices and
6757  // line orientations later on
6758  const typename Triangulation<dim, spacedim>::
6759  raw_line_iterator lines[4] = {
6760  hex->face(2)->child(0)->line(
6761  (hex->face(2)->refinement_case() ==
6763  1 :
6764  3), // 0
6765  hex->face(3)->child(0)->line(
6766  (hex->face(3)->refinement_case() ==
6768  1 :
6769  3), // 1
6770  hex->face(4)->child(0)->line(
6771  (hex->face(4)->refinement_case() ==
6773  1 :
6774  3), // 2
6775  hex->face(5)->child(0)->line(
6776  (hex->face(5)->refinement_case() ==
6778  1 :
6779  3) // 3
6780  };
6781 
6782  unsigned int line_indices[4];
6783  for (unsigned int i = 0; i < 4; ++i)
6784  line_indices[i] = lines[i]->index();
6785 
6786  // the orientation of lines for the inner quads
6787  // is quite tricky. as these lines are newly
6788  // created ones and thus have no parents, they
6789  // cannot inherit this property. set up an array
6790  // and fill it with the respective values
6791  bool line_orientation[4];
6792 
6793  // the middle vertex marked as m0 above is the
6794  // start vertex for lines 0 and 2 in standard
6795  // orientation, whereas m1 is the end vertex of
6796  // lines 1 and 3 in standard orientation
6797  const unsigned int middle_vertices[2] = {
6798  hex->line(2)->child(0)->vertex_index(1),
6799  hex->line(7)->child(0)->vertex_index(1)};
6800 
6801  for (unsigned int i = 0; i < 4; ++i)
6802  if (lines[i]->vertex_index(i % 2) ==
6803  middle_vertices[i % 2])
6804  line_orientation[i] = true;
6805  else
6806  {
6807  // it must be the other
6808  // way round then
6809  Assert(lines[i]->vertex_index((i + 1) % 2) ==
6810  middle_vertices[i % 2],
6811  ExcInternalError());
6812  line_orientation[i] = false;
6813  }
6814 
6815  // set up the new quad, line numbering is as
6816  // indicated above
6817  new_quads[0]->set_bounding_object_indices(
6818  {line_indices[0],
6819  line_indices[1],
6820  line_indices[2],
6821  line_indices[3]});
6822 
6823  new_quads[0]->set_line_orientation(
6824  0, line_orientation[0]);
6825  new_quads[0]->set_line_orientation(
6826  1, line_orientation[1]);
6827  new_quads[0]->set_line_orientation(
6828  2, line_orientation[2]);
6829  new_quads[0]->set_line_orientation(
6830  3, line_orientation[3]);
6831 
6832  // the quads are numbered as follows:
6833  //
6834  // planes in the interior of the old hex:
6835  //
6836  // *
6837  // /|
6838  // / | x
6839  // / | *-------* *---------*
6840  // * | | | / /
6841  // | 0 | | | / /
6842  // | * | | / /
6843  // | / *-------*y *---------*x
6844  // | /
6845  // |/
6846  // *
6847  //
6848  // children of the faces of the old hex
6849  //
6850  // *---*---* *---*---*
6851  // /| | | / / /|
6852  // / | | | / 9 / 10/ |
6853  // / | 5 | 6 | / / / |
6854  // * | | | *---*---* |
6855  // | 1 *---*---* | | | 2 *
6856  // | / / / | | | /
6857  // | / 7 / 8 / | 3 | 4 | /
6858  // |/ / / | | |/
6859  // *---*---* *---*---*
6860  //
6861  // note that we have to take care of the
6862  // orientation of faces.
6863  const int quad_indices[11] = {
6864  new_quads[0]->index(), // 0
6865 
6866  hex->face(0)->index(), // 1
6867 
6868  hex->face(1)->index(), // 2
6869 
6870  hex->face(2)->child_index(
6871  child_at_origin[hex->face(2)->refinement_case() -
6872  1][f_fl[2]][f_ro[2]]), // 3
6873  hex->face(2)->child_index(
6874  1 -
6875  child_at_origin[hex->face(2)->refinement_case() -
6876  1][f_fl[2]][f_ro[2]]),
6877 
6878  hex->face(3)->child_index(
6879  child_at_origin[hex->face(3)->refinement_case() -
6880  1][f_fl[3]][f_ro[3]]), // 5
6881  hex->face(3)->child_index(
6882  1 -
6883  child_at_origin[hex->face(3)->refinement_case() -
6884  1][f_fl[3]][f_ro[3]]),
6885 
6886  hex->face(4)->child_index(
6887  child_at_origin[hex->face(4)->refinement_case() -
6888  1][f_fl[4]][f_ro[4]]), // 7
6889  hex->face(4)->child_index(
6890  1 -
6891  child_at_origin[hex->face(4)->refinement_case() -
6892  1][f_fl[4]][f_ro[4]]),
6893 
6894  hex->face(5)->child_index(
6895  child_at_origin[hex->face(5)->refinement_case() -
6896  1][f_fl[5]][f_ro[5]]), // 9
6897  hex->face(5)->child_index(
6898  1 -
6899  child_at_origin[hex->face(5)->refinement_case() -
6900  1][f_fl[5]][f_ro[5]])
6901 
6902  };
6903 
6904  new_hexes[0]->set_bounding_object_indices(
6905  {quad_indices[1],
6906  quad_indices[0],
6907  quad_indices[3],
6908  quad_indices[5],
6909  quad_indices[7],
6910  quad_indices[9]});
6911  new_hexes[1]->set_bounding_object_indices(
6912  {quad_indices[0],
6913  quad_indices[2],
6914  quad_indices[4],
6915  quad_indices[6],
6916  quad_indices[8],
6917  quad_indices[10]});
6918  break;
6919  }
6920 
6922  {
6924  //
6925  // RefinementCase<dim>::cut_y
6926  //
6927  // the refined cube will look like this:
6928  //
6929  // *---------*
6930  // / /|
6931  // *---------* |
6932  // / /| |
6933  // *---------* | |
6934  // | | | |
6935  // | | | *
6936  // | | |/
6937  // | | *
6938  // | |/
6939  // *---------*
6940  //
6941  // again, first collect some data about the
6942  // indices of the lines, with the following
6943  // numbering:
6944 
6945  // face 0: left plane
6946  // *
6947  // /|
6948  // * |
6949  // /| |
6950  // * | |
6951  // | 0 |
6952  // | | *
6953  // | |/
6954  // | *m0
6955  // |/
6956  // *
6957  // face 1: right plane
6958  // *
6959  // /|
6960  // m1* |
6961  // /| |
6962  // * | |
6963  // | 1 |
6964  // | | *
6965  // | |/
6966  // | *
6967  // |/
6968  // *
6969  // face 4: bottom plane
6970  // *-------*
6971  // / /
6972  // m0*---2---*
6973  // / /
6974  // *-------*
6975  // face 5: top plane
6976  // *-------*
6977  // / /
6978  // *---3---*m1
6979  // / /
6980  // *-------*
6981 
6982  // set up a list of line iterators first. from
6983  // this, construct lists of line_indices and
6984  // line orientations later on
6985  const typename Triangulation<dim, spacedim>::
6986  raw_line_iterator lines[4] = {
6987  hex->face(0)->child(0)->line(
6988  (hex->face(0)->refinement_case() ==
6990  1 :
6991  3), // 0
6992  hex->face(1)->child(0)->line(
6993  (hex->face(1)->refinement_case() ==
6995  1 :
6996  3), // 1
6997  hex->face(4)->child(0)->line(
6998  (hex->face(4)->refinement_case() ==
7000  1 :
7001  3), // 2
7002  hex->face(5)->child(0)->line(
7003  (hex->face(5)->refinement_case() ==
7005  1 :
7006  3) // 3
7007  };
7008 
7009  unsigned int line_indices[4];
7010  for (unsigned int i = 0; i < 4; ++i)
7011  line_indices[i] = lines[i]->index();
7012 
7013  // the orientation of lines for the inner quads
7014  // is quite tricky. as these lines are newly
7015  // created ones and thus have no parents, they
7016  // cannot inherit this property. set up an array
7017  // and fill it with the respective values
7018  bool line_orientation[4];
7019 
7020  // the middle vertex marked as m0 above is the
7021  // start vertex for lines 0 and 2 in standard
7022  // orientation, whereas m1 is the end vertex of
7023  // lines 1 and 3 in standard orientation
7024  const unsigned int middle_vertices[2] = {
7025  hex->line(0)->child(0)->vertex_index(1),
7026  hex->line(5)->child(0)->vertex_index(1)};
7027 
7028  for (unsigned int i = 0; i < 4; ++i)
7029  if (lines[i]->vertex_index(i % 2) ==
7030  middle_vertices[i % 2])
7031  line_orientation[i] = true;
7032  else
7033  {
7034  // it must be the other way round then
7035  Assert(lines[i]->vertex_index((i + 1) % 2) ==
7036  middle_vertices[i % 2],
7037  ExcInternalError());
7038  line_orientation[i] = false;
7039  }
7040 
7041  // set up the new quad, line numbering is as
7042  // indicated above
7043  new_quads[0]->set_bounding_object_indices(
7044  {line_indices[2],
7045  line_indices[3],
7046  line_indices[0],
7047  line_indices[1]});
7048 
7049  new_quads[0]->set_line_orientation(
7050  0, line_orientation[2]);
7051  new_quads[0]->set_line_orientation(
7052  1, line_orientation[3]);
7053  new_quads[0]->set_line_orientation(
7054  2, line_orientation[0]);
7055  new_quads[0]->set_line_orientation(
7056  3, line_orientation[1]);
7057 
7058  // the quads are numbered as follows:
7059  //
7060  // planes in the interior of the old hex:
7061  //
7062  // *
7063  // /|
7064  // / | x
7065  // / | *-------* *---------*
7066  // * | | | / /
7067  // | | | 0 | / /
7068  // | * | | / /
7069  // | / *-------*y *---------*x
7070  // | /
7071  // |/
7072  // *
7073  //
7074  // children of the faces of the old hex
7075  //
7076  // *-------* *-------*
7077  // /| | / 10 /|
7078  // * | | *-------* |
7079  // /| | 6 | / 9 /| |
7080  // * |2| | *-------* |4|
7081  // | | *-------* | | | *
7082  // |1|/ 8 / | |3|/
7083  // | *-------* | 5 | *
7084  // |/ 7 / | |/
7085  // *-------* *-------*
7086  //
7087  // note that we have to take care of the
7088  // orientation of faces.
7089  const int quad_indices[11] = {
7090  new_quads[0]->index(), // 0
7091 
7092  hex->face(0)->child_index(
7093  child_at_origin[hex->face(0)->refinement_case() -
7094  1][f_fl[0]][f_ro[0]]), // 1
7095  hex->face(0)->child_index(
7096  1 -
7097  child_at_origin[hex->face(0)->refinement_case() -
7098  1][f_fl[0]][f_ro[0]]),
7099 
7100  hex->face(1)->child_index(
7101  child_at_origin[hex->face(1)->refinement_case() -
7102  1][f_fl[1]][f_ro[1]]), // 3
7103  hex->face(1)->child_index(
7104  1 -
7105  child_at_origin[hex->face(1)->refinement_case() -
7106  1][f_fl[1]][f_ro[1]]),
7107 
7108  hex->face(2)->index(), // 5
7109 
7110  hex->face(3)->index(), // 6
7111 
7112  hex->face(4)->child_index(
7113  child_at_origin[hex->face(4)->refinement_case() -
7114  1][f_fl[4]][f_ro[4]]), // 7
7115  hex->face(4)->child_index(
7116  1 -
7117  child_at_origin[hex->face(4)->refinement_case() -
7118  1][f_fl[4]][f_ro[4]]),
7119 
7120  hex->face(5)->child_index(
7121  child_at_origin[hex->face(5)->refinement_case() -
7122  1][f_fl[5]][f_ro[5]]), // 9
7123  hex->face(5)->child_index(
7124  1 -
7125  child_at_origin[hex->face(5)->refinement_case() -
7126  1][f_fl[5]][f_ro[5]])
7127 
7128  };
7129 
7130  new_hexes[0]->set_bounding_object_indices(
7131  {quad_indices[1],
7132  quad_indices[3],
7133  quad_indices[5],
7134  quad_indices[0],
7135  quad_indices[7],
7136  quad_indices[9]});
7137  new_hexes[1]->set_bounding_object_indices(
7138  {quad_indices[2],
7139  quad_indices[4],
7140  quad_indices[0],
7141  quad_indices[6],
7142  quad_indices[8],
7143  quad_indices[10]});
7144  break;
7145  }
7146 
7148  {
7150  //
7151  // RefinementCase<dim>::cut_z
7152  //
7153  // the refined cube will look like this:
7154  //
7155  // *---------*
7156  // / /|
7157  // / / |
7158  // / / *
7159  // *---------* /|
7160  // | | / |
7161  // | |/ *
7162  // *---------* /
7163  // | | /
7164  // | |/
7165  // *---------*
7166  //
7167  // again, first collect some data about the
7168  // indices of the lines, with the following
7169  // numbering:
7170 
7171  // face 0: left plane
7172  // *
7173  // /|
7174  // / |
7175  // / *
7176  // * /|
7177  // | 0 |
7178  // |/ *
7179  // m0* /
7180  // | /
7181  // |/
7182  // *
7183  // face 1: right plane
7184  // *
7185  // /|
7186  // / |
7187  // / *m1
7188  // * /|
7189  // | 1 |
7190  // |/ *
7191  // * /
7192  // | /
7193  // |/
7194  // *
7195  // face 2: front plane
7196  // (note: x,y exchanged)
7197  // *-------*
7198  // | |
7199  // m0*---2---*
7200  // | |
7201  // *-------*
7202  // face 3: back plane
7203  // (note: x,y exchanged)
7204  // *-------*
7205  // | |
7206  // *---3---*m1
7207  // | |
7208  // *-------*
7209 
7210  // set up a list of line iterators first. from
7211  // this, construct lists of line_indices and
7212  // line orientations later on
7213  const typename Triangulation<dim, spacedim>::
7214  raw_line_iterator lines[4] = {
7215  hex->face(0)->child(0)->line(
7216  (hex->face(0)->refinement_case() ==
7218  1 :
7219  3), // 0
7220  hex->face(1)->child(0)->line(
7221  (hex->face(1)->refinement_case() ==
7223  1 :
7224  3), // 1
7225  hex->face(2)->child(0)->line(
7226  (hex->face(2)->refinement_case() ==
7228  1 :
7229  3), // 2
7230  hex->face(3)->child(0)->line(
7231  (hex->face(3)->refinement_case() ==
7233  1 :
7234  3) // 3
7235  };
7236 
7237  unsigned int line_indices[4];
7238  for (unsigned int i = 0; i < 4; ++i)
7239  line_indices[i] = lines[i]->index();
7240 
7241  // the orientation of lines for the inner quads
7242  // is quite tricky. as these lines are newly
7243  // created ones and thus have no parents, they
7244  // cannot inherit this property. set up an array
7245  // and fill it with the respective values
7246  bool line_orientation[4];
7247 
7248  // the middle vertex marked as m0 above is the
7249  // start vertex for lines 0 and 2 in standard
7250  // orientation, whereas m1 is the end vertex of
7251  // lines 1 and 3 in standard orientation
7252  const unsigned int middle_vertices[2] = {
7253  middle_vertex_index<dim, spacedim>(hex->line(8)),
7254  middle_vertex_index<dim, spacedim>(hex->line(11))};
7255 
7256  for (unsigned int i = 0; i < 4; ++i)
7257  if (lines[i]->vertex_index(i % 2) ==
7258  middle_vertices[i % 2])
7259  line_orientation[i] = true;
7260  else
7261  {
7262  // it must be the other way round then
7263  Assert(lines[i]->vertex_index((i + 1) % 2) ==
7264  middle_vertices[i % 2],
7265  ExcInternalError());
7266  line_orientation[i] = false;
7267  }
7268 
7269  // set up the new quad, line numbering is as
7270  // indicated above
7271  new_quads[0]->set_bounding_object_indices(
7272  {line_indices[0],
7273  line_indices[1],
7274  line_indices[2],
7275  line_indices[3]});
7276 
7277  new_quads[0]->set_line_orientation(
7278  0, line_orientation[0]);
7279  new_quads[0]->set_line_orientation(
7280  1, line_orientation[1]);
7281  new_quads[0]->set_line_orientation(
7282  2, line_orientation[2]);
7283  new_quads[0]->set_line_orientation(
7284  3, line_orientation[3]);
7285 
7286  // the quads are numbered as follows:
7287  //
7288  // planes in the interior of the old hex:
7289  //
7290  // *
7291  // /|
7292  // / | x
7293  // / | *-------* *---------*
7294  // * | | | / /
7295  // | | | | / 0 /
7296  // | * | | / /
7297  // | / *-------*y *---------*x
7298  // | /
7299  // |/
7300  // *
7301  //
7302  // children of the faces of the old hex
7303  //
7304  // *---*---* *-------*
7305  // /| 8 | / /|
7306  // / | | / 10 / |
7307  // / *-------* / / *
7308  // * 2/| | *-------* 4/|
7309  // | / | 7 | | 6 | / |
7310  // |/1 *-------* | |/3 *
7311  // * / / *-------* /
7312  // | / 9 / | | /
7313  // |/ / | 5 |/
7314  // *-------* *---*---*
7315  //
7316  // note that we have to take care of the
7317  // orientation of faces.
7318  const int quad_indices[11] = {
7319  new_quads[0]->index(), // 0
7320 
7321  hex->face(0)->child_index(
7322  child_at_origin[hex->face(0)->refinement_case() -
7323  1][f_fl[0]][f_ro[0]]), // 1
7324  hex->face(0)->child_index(
7325  1 -
7326  child_at_origin[hex->face(0)->refinement_case() -
7327  1][f_fl[0]][f_ro[0]]),
7328 
7329  hex->face(1)->child_index(
7330  child_at_origin[hex->face(1)->refinement_case() -
7331  1][f_fl[1]][f_ro[1]]), // 3
7332  hex->face(1)->child_index(
7333  1 -
7334  child_at_origin[hex->face(1)->refinement_case() -
7335  1][f_fl[1]][f_ro[1]]),
7336 
7337  hex->face(2)->child_index(
7338  child_at_origin[hex->face(2)->refinement_case() -
7339  1][f_fl[2]][f_ro[2]]), // 5
7340  hex->face(2)->child_index(
7341  1 -
7342  child_at_origin[hex->face(2)->refinement_case() -
7343  1][f_fl[2]][f_ro[2]]),
7344 
7345  hex->face(3)->child_index(
7346  child_at_origin[hex->face(3)->refinement_case() -
7347  1][f_fl[3]][f_ro[3]]), // 7
7348  hex->face(3)->child_index(
7349  1 -
7350  child_at_origin[hex->face(3)->refinement_case() -
7351  1][f_fl[3]][f_ro[3]]),
7352 
7353  hex->face(4)->index(), // 9
7354 
7355  hex->face(5)->index() // 10
7356  };
7357 
7358  new_hexes[0]->set_bounding_object_indices(
7359  {quad_indices[1],
7360  quad_indices[3],
7361  quad_indices[5],
7362  quad_indices[7],
7363  quad_indices[9],
7364  quad_indices[0]});
7365  new_hexes[1]->set_bounding_object_indices(
7366  {quad_indices[2],
7367  quad_indices[4],
7368  quad_indices[6],
7369  quad_indices[8],
7370  quad_indices[0],
7371  quad_indices[10]});
7372  break;
7373  }
7374 
7376  {
7378  //
7379  // RefinementCase<dim>::cut_xy
7380  //
7381  // the refined cube will look like this:
7382  //
7383  // *----*----*
7384  // / / /|
7385  // *----*----* |
7386  // / / /| |
7387  // *----*----* | |
7388  // | | | | |
7389  // | | | | *
7390  // | | | |/
7391  // | | | *
7392  // | | |/
7393  // *----*----*
7394  //
7395 
7396  // first, create the new internal line
7397  new_lines[0]->set_bounding_object_indices(
7398  {middle_vertex_index<dim, spacedim>(hex->face(4)),
7399  middle_vertex_index<dim, spacedim>(hex->face(5))});
7400 
7401  // again, first collect some data about the
7402  // indices of the lines, with the following
7403  // numbering:
7404 
7405  // face 0: left plane
7406  // *
7407  // /|
7408  // * |
7409  // /| |
7410  // * | |
7411  // | 0 |
7412  // | | *
7413  // | |/
7414  // | *
7415  // |/
7416  // *
7417  // face 1: right plane
7418  // *
7419  // /|
7420  // * |
7421  // /| |
7422  // * | |
7423  // | 1 |
7424  // | | *
7425  // | |/
7426  // | *
7427  // |/
7428  // *
7429  // face 2: front plane
7430  // (note: x,y exchanged)
7431  // *---*---*
7432  // | | |
7433  // | 2 |
7434  // | | |
7435  // *-------*
7436  // face 3: back plane
7437  // (note: x,y exchanged)
7438  // *---*---*
7439  // | | |
7440  // | 3 |
7441  // | | |
7442  // *---*---*
7443  // face 4: bottom plane
7444  // *---*---*
7445  // / 5 /
7446  // *-6-*-7-*
7447  // / 4 /
7448  // *---*---*
7449  // face 5: top plane
7450  // *---*---*
7451  // / 9 /
7452  // *10-*-11*
7453  // / 8 /
7454  // *---*---*
7455  // middle planes
7456  // *-------* *---*---*
7457  // / / | | |
7458  // / / | 12 |
7459  // / / | | |
7460  // *-------* *---*---*
7461 
7462  // set up a list of line iterators first. from
7463  // this, construct lists of line_indices and
7464  // line orientations later on
7465  const typename Triangulation<
7466  dim,
7467  spacedim>::raw_line_iterator lines[13] = {
7468  hex->face(0)->child(0)->line(
7469  (hex->face(0)->refinement_case() ==
7471  1 :
7472  3), // 0
7473  hex->face(1)->child(0)->line(
7474  (hex->face(1)->refinement_case() ==
7476  1 :
7477  3), // 1
7478  hex->face(2)->child(0)->line(
7479  (hex->face(2)->refinement_case() ==
7481  1 :
7482  3), // 2
7483  hex->face(3)->child(0)->line(
7484  (hex->face(3)->refinement_case() ==
7486  1 :
7487  3), // 3
7488 
7489  hex->face(4)
7490  ->isotropic_child(
7492  0, f_or[4], f_fl[4], f_ro[4]))
7493  ->line(
7495  1, f_or[4], f_fl[4], f_ro[4])), // 4
7496  hex->face(4)
7497  ->isotropic_child(
7499  3, f_or[4], f_fl[4], f_ro[4]))
7500  ->line(
7502  0, f_or[4], f_fl[4], f_ro[4])), // 5
7503  hex->face(4)
7504  ->isotropic_child(
7506  0, f_or[4], f_fl[4], f_ro[4]))
7507  ->line(
7509  3, f_or[4], f_fl[4], f_ro[4])), // 6
7510  hex->face(4)
7511  ->isotropic_child(
7513  3, f_or[4], f_fl[4], f_ro[4]))
7514  ->line(
7516  2, f_or[4], f_fl[4], f_ro[4])), // 7
7517 
7518  hex->face(5)
7519  ->isotropic_child(
7521  0, f_or[5], f_fl[5], f_ro[5]))
7522  ->line(
7524  1, f_or[5], f_fl[5], f_ro[5])), // 8
7525  hex->face(5)
7526  ->isotropic_child(
7528  3, f_or[5], f_fl[5], f_ro[5]))
7529  ->line(
7531  0, f_or[5], f_fl[5], f_ro[5])), // 9
7532  hex->face(5)
7533  ->isotropic_child(
7535  0, f_or[5], f_fl[5], f_ro[5]))
7536  ->line(
7538  3, f_or[5], f_fl[5], f_ro[5])), // 10
7539  hex->face(5)
7540  ->isotropic_child(
7542  3, f_or[5], f_fl[5], f_ro[5]))
7543  ->line(
7545  2, f_or[5], f_fl[5], f_ro[5])), // 11
7546 
7547  new_lines[0] // 12
7548  };
7549 
7550  unsigned int line_indices[13];
7551  for (unsigned int i = 0; i < 13; ++i)
7552  line_indices[i] = lines[i]->index();
7553 
7554  // the orientation of lines for the inner quads
7555  // is quite tricky. as these lines are newly
7556  // created ones and thus have no parents, they
7557  // cannot inherit this property. set up an array
7558  // and fill it with the respective values
7559  bool line_orientation[13];
7560 
7561  // the middle vertices of the lines of our
7562  // bottom face
7563  const unsigned int middle_vertices[4] = {
7564  hex->line(0)->child(0)->vertex_index(1),
7565  hex->line(1)->child(0)->vertex_index(1),
7566  hex->line(2)->child(0)->vertex_index(1),
7567  hex->line(3)->child(0)->vertex_index(1),
7568  };
7569 
7570  // note: for lines 0 to 3 the orientation of the
7571  // line is 'true', if vertex 0 is on the bottom
7572  // face
7573  for (unsigned int i = 0; i < 4; ++i)
7574  if (lines[i]->vertex_index(0) == middle_vertices[i])
7575  line_orientation[i] = true;
7576  else
7577  {
7578  // it must be the other way round then
7579  Assert(lines[i]->vertex_index(1) ==
7580  middle_vertices[i],
7581  ExcInternalError());
7582  line_orientation[i] = false;
7583  }
7584 
7585  // note: for lines 4 to 11 (inner lines of the
7586  // outer quads) the following holds: the second
7587  // vertex of the even lines in standard
7588  // orientation is the vertex in the middle of
7589  // the quad, whereas for odd lines the first
7590  // vertex is the same middle vertex.
7591  for (unsigned int i = 4; i < 12; ++i)
7592  if (lines[i]->vertex_index((i + 1) % 2) ==
7593  middle_vertex_index<dim, spacedim>(
7594  hex->face(3 + i / 4)))
7595  line_orientation[i] = true;
7596  else
7597  {
7598  // it must be the other way
7599  // round then
7600  Assert(lines[i]->vertex_index(i % 2) ==
7601  (middle_vertex_index<dim, spacedim>(
7602  hex->face(3 + i / 4))),
7603  ExcInternalError());
7604  line_orientation[i] = false;
7605  }
7606  // for the last line the line orientation is
7607  // always true, since it was just constructed
7608  // that way
7609  line_orientation[12] = true;
7610 
7611  // set up the 4 quads, numbered as follows (left
7612  // quad numbering, right line numbering
7613  // extracted from above)
7614  //
7615  // * *
7616  // /| 9|
7617  // * | * |
7618  // y/| | 8| 3
7619  // * |1| * | |
7620  // | | |x | 12|
7621  // |0| * | | *
7622  // | |/ 2 |5
7623  // | * | *
7624  // |/ |4
7625  // * *
7626  //
7627  // x
7628  // *---*---* *10-*-11*
7629  // | | | | | |
7630  // | 2 | 3 | 0 12 1
7631  // | | | | | |
7632  // *---*---*y *-6-*-7-*
7633 
7634  new_quads[0]->set_bounding_object_indices(
7635  {line_indices[2],
7636  line_indices[12],
7637  line_indices[4],
7638  line_indices[8]});
7639  new_quads[1]->set_bounding_object_indices(
7640  {line_indices[12],
7641  line_indices[3],
7642  line_indices[5],
7643  line_indices[9]});
7644  new_quads[2]->set_bounding_object_indices(
7645  {line_indices[6],
7646  line_indices[10],
7647  line_indices[0],
7648  line_indices[12]});
7649  new_quads[3]->set_bounding_object_indices(
7650  {line_indices[7],
7651  line_indices[11],
7652  line_indices[12],
7653  line_indices[1]});
7654 
7655  new_quads[0]->set_line_orientation(
7656  0, line_orientation[2]);
7657  new_quads[0]->set_line_orientation(
7658  2, line_orientation[4]);
7659  new_quads[0]->set_line_orientation(
7660  3, line_orientation[8]);
7661 
7662  new_quads[1]->set_line_orientation(
7663  1, line_orientation[3]);
7664  new_quads[1]->set_line_orientation(
7665  2, line_orientation[5]);
7666  new_quads[1]->set_line_orientation(
7667  3, line_orientation[9]);
7668 
7669  new_quads[2]->set_line_orientation(
7670  0, line_orientation[6]);
7671  new_quads[2]->set_line_orientation(
7672  1, line_orientation[10]);
7673  new_quads[2]->set_line_orientation(
7674  2, line_orientation[0]);
7675 
7676  new_quads[3]->set_line_orientation(
7677  0, line_orientation[7]);
7678  new_quads[3]->set_line_orientation(
7679  1, line_orientation[11]);
7680  new_quads[3]->set_line_orientation(
7681  3, line_orientation[1]);
7682 
7683  // the quads are numbered as follows:
7684  //
7685  // planes in the interior of the old hex:
7686  //
7687  // *
7688  // /|
7689  // * | x
7690  // /| | *---*---* *---------*
7691  // * |1| | | | / /
7692  // | | | | 2 | 3 | / /
7693  // |0| * | | | / /
7694  // | |/ *---*---*y *---------*x
7695  // | *
7696  // |/
7697  // *
7698  //
7699  // children of the faces of the old hex
7700  //
7701  // *---*---* *---*---*
7702  // /| | | /18 / 19/|
7703  // * |10 | 11| /---/---* |
7704  // /| | | | /16 / 17/| |
7705  // * |5| | | *---*---* |7|
7706  // | | *---*---* | | | | *
7707  // |4|/14 / 15/ | | |6|/
7708  // | *---/---/ | 8 | 9 | *
7709  // |/12 / 13/ | | |/
7710  // *---*---* *---*---*
7711  //
7712  // note that we have to take care of the
7713  // orientation of faces.
7714  const int quad_indices[20] = {
7715  new_quads[0]->index(), // 0
7716  new_quads[1]->index(),
7717  new_quads[2]->index(),
7718  new_quads[3]->index(),
7719 
7720  hex->face(0)->child_index(
7721  child_at_origin[hex->face(0)->refinement_case() -
7722  1][f_fl[0]][f_ro[0]]), // 4
7723  hex->face(0)->child_index(
7724  1 -
7725  child_at_origin[hex->face(0)->refinement_case() -
7726  1][f_fl[0]][f_ro[0]]),
7727 
7728  hex->face(1)->child_index(
7729  child_at_origin[hex->face(1)->refinement_case() -
7730  1][f_fl[1]][f_ro[1]]), // 6
7731  hex->face(1)->child_index(
7732  1 -
7733  child_at_origin[hex->face(1)->refinement_case() -
7734  1][f_fl[1]][f_ro[1]]),
7735 
7736  hex->face(2)->child_index(
7737  child_at_origin[hex->face(2)->refinement_case() -
7738  1][f_fl[2]][f_ro[2]]), // 8
7739  hex->face(2)->child_index(
7740  1 -
7741  child_at_origin[hex->face(2)->refinement_case() -
7742  1][f_fl[2]][f_ro[2]]),
7743 
7744  hex->face(3)->child_index(
7745  child_at_origin[hex->face(3)->refinement_case() -
7746  1][f_fl[3]][f_ro[3]]), // 10
7747  hex->face(3)->child_index(
7748  1 -
7749  child_at_origin[hex->face(3)->refinement_case() -
7750  1][f_fl[3]][f_ro[3]]),
7751 
7752  hex->face(4)->isotropic_child_index(
7754  0, f_or[4], f_fl[4], f_ro[4])), // 12
7755  hex->face(4)->isotropic_child_index(
7757  1, f_or[4], f_fl[4], f_ro[4])),
7758  hex->face(4)->isotropic_child_index(
7760  2, f_or[4], f_fl[4], f_ro[4])),
7761  hex->face(4)->isotropic_child_index(
7763  3, f_or[4], f_fl[4], f_ro[4])),
7764 
7765  hex->face(5)->isotropic_child_index(
7767  0, f_or[5], f_fl[5], f_ro[5])), // 16
7768  hex->face(5)->isotropic_child_index(
7770  1, f_or[5], f_fl[5], f_ro[5])),
7771  hex->face(5)->isotropic_child_index(
7773  2, f_or[5], f_fl[5], f_ro[5])),
7774  hex->face(5)->isotropic_child_index(
7776  3, f_or[5], f_fl[5], f_ro[5]))};
7777 
7778  new_hexes[0]->set_bounding_object_indices(
7779  {quad_indices[4],
7780  quad_indices[0],
7781  quad_indices[8],
7782  quad_indices[2],
7783  quad_indices[12],
7784  quad_indices[16]});
7785  new_hexes[1]->set_bounding_object_indices(
7786  {quad_indices[0],
7787  quad_indices[6],
7788  quad_indices[9],
7789  quad_indices[3],
7790  quad_indices[13],
7791  quad_indices[17]});
7792  new_hexes[2]->set_bounding_object_indices(
7793  {quad_indices[5],
7794  quad_indices[1],
7795  quad_indices[2],
7796  quad_indices[10],
7797  quad_indices[14],
7798  quad_indices[18]});
7799  new_hexes[3]->set_bounding_object_indices(
7800  {quad_indices[1],
7801  quad_indices[7],
7802  quad_indices[3],
7803  quad_indices[11],
7804  quad_indices[15],
7805  quad_indices[19]});
7806  break;
7807  }
7808 
7810  {
7812  //
7813  // RefinementCase<dim>::cut_xz
7814  //
7815  // the refined cube will look like this:
7816  //
7817  // *----*----*
7818  // / / /|
7819  // / / / |
7820  // / / / *
7821  // *----*----* /|
7822  // | | | / |
7823  // | | |/ *
7824  // *----*----* /
7825  // | | | /
7826  // | | |/
7827  // *----*----*
7828  //
7829 
7830  // first, create the new internal line
7831  new_lines[0]->set_bounding_object_indices(
7832  {middle_vertex_index<dim, spacedim>(hex->face(2)),
7833  middle_vertex_index<dim, spacedim>(hex->face(3))});
7834 
7835  // again, first collect some data about the
7836  // indices of the lines, with the following
7837  // numbering:
7838 
7839  // face 0: left plane
7840  // *
7841  // /|
7842  // / |
7843  // / *
7844  // * /|
7845  // | 0 |
7846  // |/ *
7847  // * /
7848  // | /
7849  // |/
7850  // *
7851  // face 1: right plane
7852  // *
7853  // /|
7854  // / |
7855  // / *
7856  // * /|
7857  // | 1 |
7858  // |/ *
7859  // * /
7860  // | /
7861  // |/
7862  // *
7863  // face 2: front plane
7864  // (note: x,y exchanged)
7865  // *---*---*
7866  // | 5 |
7867  // *-6-*-7-*
7868  // | 4 |
7869  // *---*---*
7870  // face 3: back plane
7871  // (note: x,y exchanged)
7872  // *---*---*
7873  // | 9 |
7874  // *10-*-11*
7875  // | 8 |
7876  // *---*---*
7877  // face 4: bottom plane
7878  // *---*---*
7879  // / / /
7880  // / 2 /
7881  // / / /
7882  // *---*---*
7883  // face 5: top plane
7884  // *---*---*
7885  // / / /
7886  // / 3 /
7887  // / / /
7888  // *---*---*
7889  // middle planes
7890  // *---*---* *-------*
7891  // / / / | |
7892  // / 12 / | |
7893  // / / / | |
7894  // *---*---* *-------*
7895 
7896  // set up a list of line iterators first. from
7897  // this, construct lists of line_indices and
7898  // line orientations later on
7899  const typename Triangulation<
7900  dim,
7901  spacedim>::raw_line_iterator lines[13] = {
7902  hex->face(0)->child(0)->line(
7903  (hex->face(0)->refinement_case() ==
7905  1 :
7906  3), // 0
7907  hex->face(1)->child(0)->line(
7908  (hex->face(1)->refinement_case() ==
7910  1 :
7911  3), // 1
7912  hex->face(4)->child(0)->line(
7913  (hex->face(4)->refinement_case() ==
7915  1 :
7916  3), // 2
7917  hex->face(5)->child(0)->line(
7918  (hex->face(5)->refinement_case() ==
7920  1 :
7921  3), // 3
7922 
7923  hex->face(2)
7924  ->isotropic_child(
7926  0, f_or[2], f_fl[2], f_ro[2]))
7927  ->line(
7929  3, f_or[2], f_fl[2], f_ro[2])), // 4
7930  hex->face(2)
7931  ->isotropic_child(
7933  3, f_or[2], f_fl[2], f_ro[2]))
7934  ->line(
7936  2, f_or[2], f_fl[2], f_ro[2])), // 5
7937  hex->face(2)
7938  ->isotropic_child(
7940  0, f_or[2], f_fl[2], f_ro[2]))
7941  ->line(
7943  1, f_or[2], f_fl[2], f_ro[2])), // 6
7944  hex->face(2)
7945  ->isotropic_child(
7947  3, f_or[2], f_fl[2], f_ro[2]))
7948  ->line(
7950  0, f_or[2], f_fl[2], f_ro[2])), // 7
7951 
7952  hex->face(3)
7953  ->isotropic_child(
7955  0, f_or[3], f_fl[3], f_ro[3]))
7956  ->line(
7958  3, f_or[3], f_fl[3], f_ro[3])), // 8
7959  hex->face(3)
7960  ->isotropic_child(
7962  3, f_or[3], f_fl[3], f_ro[3]))
7963  ->line(
7965  2, f_or[3], f_fl[3], f_ro[3])), // 9
7966  hex->face(3)
7967  ->isotropic_child(
7969  0, f_or[3], f_fl[3], f_ro[3]))
7970  ->line(
7972  1, f_or[3], f_fl[3], f_ro[3])), // 10
7973  hex->face(3)
7974  ->isotropic_child(
7976  3, f_or[3], f_fl[3], f_ro[3]))
7977  ->line(
7979  0, f_or[3], f_fl[3], f_ro[3])), // 11
7980 
7981  new_lines[0] // 12
7982  };
7983 
7984  unsigned int line_indices[13];
7985  for (unsigned int i = 0; i < 13; ++i)
7986  line_indices[i] = lines[i]->index();
7987 
7988  // the orientation of lines for the inner quads
7989  // is quite tricky. as these lines are newly
7990  // created ones and thus have no parents, they
7991  // cannot inherit this property. set up an array
7992  // and fill it with the respective values
7993  bool line_orientation[13];
7994 
7995  // the middle vertices of the
7996  // lines of our front face
7997  const unsigned int middle_vertices[4] = {
7998  hex->line(8)->child(0)->vertex_index(1),
7999  hex->line(9)->child(0)->vertex_index(1),
8000  hex->line(2)->child(0)->vertex_index(1),
8001  hex->line(6)->child(0)->vertex_index(1),
8002  };
8003 
8004  // note: for lines 0 to 3 the orientation of the
8005  // line is 'true', if vertex 0 is on the front
8006  for (unsigned int i = 0; i < 4; ++i)
8007  if (lines[i]->vertex_index(0) == middle_vertices[i])
8008  line_orientation[i] = true;
8009  else
8010  {
8011  // it must be the other way round then
8012  Assert(lines[i]->vertex_index(1) ==
8013  middle_vertices[i],
8014  ExcInternalError());
8015  line_orientation[i] = false;
8016  }
8017 
8018  // note: for lines 4 to 11 (inner lines of the
8019  // outer quads) the following holds: the second
8020  // vertex of the even lines in standard
8021  // orientation is the vertex in the middle of
8022  // the quad, whereas for odd lines the first
8023  // vertex is the same middle vertex.
8024  for (unsigned int i = 4; i < 12; ++i)
8025  if (lines[i]->vertex_index((i + 1) % 2) ==
8026  middle_vertex_index<dim, spacedim>(
8027  hex->face(1 + i / 4)))
8028  line_orientation[i] = true;
8029  else
8030  {
8031  // it must be the other way
8032  // round then
8033  Assert(lines[i]->vertex_index(i % 2) ==
8034  (middle_vertex_index<dim, spacedim>(
8035  hex->face(1 + i / 4))),
8036  ExcInternalError());
8037  line_orientation[i] = false;
8038  }
8039  // for the last line the line orientation is
8040  // always true, since it was just constructed
8041  // that way
8042  line_orientation[12] = true;
8043 
8044  // set up the 4 quads, numbered as follows (left
8045  // quad numbering, right line numbering
8046  // extracted from above), the drawings denote
8047  // middle planes
8048  //
8049  // * *
8050  // /| /|
8051  // / | 3 9
8052  // y/ * / *
8053  // * 3/| * /|
8054  // | / |x 5 12|8
8055  // |/ * |/ *
8056  // * 2/ * /
8057  // | / 4 2
8058  // |/ |/
8059  // * *
8060  //
8061  // y
8062  // *----*----* *-10-*-11-*
8063  // / / / / / /
8064  // / 0 / 1 / 0 12 1
8065  // / / / / / /
8066  // *----*----*x *--6-*--7-*
8067 
8068  new_quads[0]->set_bounding_object_indices(
8069  {line_indices[0],
8070  line_indices[12],
8071  line_indices[6],
8072  line_indices[10]});
8073  new_quads[1]->set_bounding_object_indices(
8074  {line_indices[12],
8075  line_indices[1],
8076  line_indices[7],
8077  line_indices[11]});
8078  new_quads[2]->set_bounding_object_indices(
8079  {line_indices[4],
8080  line_indices[8],
8081  line_indices[2],
8082  line_indices[12]});
8083  new_quads[3]->set_bounding_object_indices(
8084  {line_indices[5],
8085  line_indices[9],
8086  line_indices[12],
8087  line_indices[3]});
8088 
8089  new_quads[0]->set_line_orientation(
8090  0, line_orientation[0]);
8091  new_quads[0]->set_line_orientation(
8092  2, line_orientation[6]);
8093  new_quads[0]->set_line_orientation(
8094  3, line_orientation[10]);
8095 
8096  new_quads[1]->set_line_orientation(
8097  1, line_orientation[1]);
8098  new_quads[1]->set_line_orientation(
8099  2, line_orientation[7]);
8100  new_quads[1]->set_line_orientation(
8101  3, line_orientation[11]);
8102 
8103  new_quads[2]->set_line_orientation(
8104  0, line_orientation[4]);
8105  new_quads[2]->set_line_orientation(
8106  1, line_orientation[8]);
8107  new_quads[2]->set_line_orientation(
8108  2, line_orientation[2]);
8109 
8110  new_quads[3]->set_line_orientation(
8111  0, line_orientation[5]);
8112  new_quads[3]->set_line_orientation(
8113  1, line_orientation[9]);
8114  new_quads[3]->set_line_orientation(
8115  3, line_orientation[3]);
8116 
8117  // the quads are numbered as follows:
8118  //
8119  // planes in the interior of the old hex:
8120  //
8121  // *
8122  // /|
8123  // / | x
8124  // /3 * *-------* *----*----*
8125  // * /| | | / / /
8126  // | / | | | / 0 / 1 /
8127  // |/ * | | / / /
8128  // * 2/ *-------*y *----*----*x
8129  // | /
8130  // |/
8131  // *
8132  //
8133  // children of the faces
8134  // of the old hex
8135  // *---*---* *---*---*
8136  // /|13 | 15| / / /|
8137  // / | | | /18 / 19/ |
8138  // / *---*---* / / / *
8139  // * 5/| | | *---*---* 7/|
8140  // | / |12 | 14| | 9 | 11| / |
8141  // |/4 *---*---* | | |/6 *
8142  // * / / / *---*---* /
8143  // | /16 / 17/ | | | /
8144  // |/ / / | 8 | 10|/
8145  // *---*---* *---*---*
8146  //
8147  // note that we have to take care of the
8148  // orientation of faces.
8149  const int quad_indices[20] = {
8150  new_quads[0]->index(), // 0
8151  new_quads[1]->index(),
8152  new_quads[2]->index(),
8153  new_quads[3]->index(),
8154 
8155  hex->face(0)->child_index(
8156  child_at_origin[hex->face(0)->refinement_case() -
8157  1][f_fl[0]][f_ro[0]]), // 4
8158  hex->face(0)->child_index(
8159  1 -
8160  child_at_origin[hex->face(0)->refinement_case() -
8161  1][f_fl[0]][f_ro[0]]),
8162 
8163  hex->face(1)->child_index(
8164  child_at_origin[hex->face(1)->refinement_case() -
8165  1][f_fl[1]][f_ro[1]]), // 6
8166  hex->face(1)->child_index(
8167  1 -
8168  child_at_origin[hex->face(1)->refinement_case() -
8169  1][f_fl[1]][f_ro[1]]),
8170 
8171  hex->face(2)->isotropic_child_index(
8173  0, f_or[2], f_fl[2], f_ro[2])), // 8
8174  hex->face(2)->isotropic_child_index(
8176  1, f_or[2], f_fl[2], f_ro[2])),
8177  hex->face(2)->isotropic_child_index(
8179  2, f_or[2], f_fl[2], f_ro[2])),
8180  hex->face(2)->isotropic_child_index(
8182  3, f_or[2], f_fl[2], f_ro[2])),
8183 
8184  hex->face(3)->isotropic_child_index(
8186  0, f_or[3], f_fl[3], f_ro[3])), // 12
8187  hex->face(3)->isotropic_child_index(
8189  1, f_or[3], f_fl[3], f_ro[3])),
8190  hex->face(3)->isotropic_child_index(
8192  2, f_or[3], f_fl[3], f_ro[3])),
8193  hex->face(3)->isotropic_child_index(
8195  3, f_or[3], f_fl[3], f_ro[3])),
8196 
8197  hex->face(4)->child_index(
8198  child_at_origin[hex->face(4)->refinement_case() -
8199  1][f_fl[4]][f_ro[4]]), // 16
8200  hex->face(4)->child_index(
8201  1 -
8202  child_at_origin[hex->face(4)->refinement_case() -
8203  1][f_fl[4]][f_ro[4]]),
8204 
8205  hex->face(5)->child_index(
8206  child_at_origin[hex->face(5)->refinement_case() -
8207  1][f_fl[5]][f_ro[5]]), // 18
8208  hex->face(5)->child_index(
8209  1 -
8210  child_at_origin[hex->face(5)->refinement_case() -
8211  1][f_fl[5]][f_ro[5]])};
8212 
8213  // due to the exchange of x and y for the front
8214  // and back face, we order the children
8215  // according to
8216  //
8217  // *---*---*
8218  // | 1 | 3 |
8219  // *---*---*
8220  // | 0 | 2 |
8221  // *---*---*
8222  new_hexes[0]->set_bounding_object_indices(
8223  {quad_indices[4],
8224  quad_indices[2],
8225  quad_indices[8],
8226  quad_indices[12],
8227  quad_indices[16],
8228  quad_indices[0]});
8229  new_hexes[1]->set_bounding_object_indices(
8230  {quad_indices[5],
8231  quad_indices[3],
8232  quad_indices[9],
8233  quad_indices[13],
8234  quad_indices[0],
8235  quad_indices[18]});
8236  new_hexes[2]->set_bounding_object_indices(
8237  {quad_indices[2],
8238  quad_indices[6],
8239  quad_indices[10],
8240  quad_indices[14],
8241  quad_indices[17],
8242  quad_indices[1]});
8243  new_hexes[3]->set_bounding_object_indices(
8244  {quad_indices[3],
8245  quad_indices[7],
8246  quad_indices[11],
8247  quad_indices[15],
8248  quad_indices[1],
8249  quad_indices[19]});
8250  break;
8251  }
8252 
8254  {
8256  //
8257  // RefinementCase<dim>::cut_yz
8258  //
8259  // the refined cube will look like this:
8260  //
8261  // *---------*
8262  // / /|
8263  // *---------* |
8264  // / /| |
8265  // *---------* |/|
8266  // | | * |
8267  // | |/| *
8268  // *---------* |/
8269  // | | *
8270  // | |/
8271  // *---------*
8272  //
8273 
8274  // first, create the new
8275  // internal line
8276  new_lines[0]->set_bounding_object_indices(
8277 
8278  {middle_vertex_index<dim, spacedim>(hex->face(0)),
8279  middle_vertex_index<dim, spacedim>(hex->face(1))});
8280 
8281  // again, first collect some data about the
8282  // indices of the lines, with the following
8283  // numbering: (note that face 0 and 1 each are
8284  // shown twice for better readability)
8285 
8286  // face 0: left plane
8287  // * *
8288  // /| /|
8289  // * | * |
8290  // /| * /| *
8291  // * 5/| * |7|
8292  // | * | | * |
8293  // |/| * |6| *
8294  // * 4/ * |/
8295  // | * | *
8296  // |/ |/
8297  // * *
8298  // face 1: right plane
8299  // * *
8300  // /| /|
8301  // * | * |
8302  // /| * /| *
8303  // * 9/| * |11
8304  // | * | | * |
8305  // |/| * |10 *
8306  // * 8/ * |/
8307  // | * | *
8308  // |/ |/
8309  // * *
8310  // face 2: front plane
8311  // (note: x,y exchanged)
8312  // *-------*
8313  // | |
8314  // *---0---*
8315  // | |
8316  // *-------*
8317  // face 3: back plane
8318  // (note: x,y exchanged)
8319  // *-------*
8320  // | |
8321  // *---1---*
8322  // | |
8323  // *-------*
8324  // face 4: bottom plane
8325  // *-------*
8326  // / /
8327  // *---2---*
8328  // / /
8329  // *-------*
8330  // face 5: top plane
8331  // *-------*
8332  // / /
8333  // *---3---*
8334  // / /
8335  // *-------*
8336  // middle planes
8337  // *-------* *-------*
8338  // / / | |
8339  // *---12--* | |
8340  // / / | |
8341  // *-------* *-------*
8342 
8343  // set up a list of line iterators first. from
8344  // this, construct lists of line_indices and
8345  // line orientations later on
8346  const typename Triangulation<
8347  dim,
8348  spacedim>::raw_line_iterator lines[13] = {
8349  hex->face(2)->child(0)->line(
8350  (hex->face(2)->refinement_case() ==
8352  1 :
8353  3), // 0
8354  hex->face(3)->child(0)->line(
8355  (hex->face(3)->refinement_case() ==
8357  1 :
8358  3), // 1
8359  hex->face(4)->child(0)->line(
8360  (hex->face(4)->refinement_case() ==
8362  1 :
8363  3), // 2
8364  hex->face(5)->child(0)->line(
8365  (hex->face(5)->refinement_case() ==
8367  1 :
8368  3), // 3
8369 
8370  hex->face(0)
8371  ->isotropic_child(
8373  0, f_or[0], f_fl[0], f_ro[0]))
8374  ->line(
8376  1, f_or[0], f_fl[0], f_ro[0])), // 4
8377  hex->face(0)
8378  ->isotropic_child(
8380  3, f_or[0], f_fl[0], f_ro[0]))
8381  ->line(
8383  0, f_or[0], f_fl[0], f_ro[0])), // 5
8384  hex->face(0)
8385  ->isotropic_child(
8387  0, f_or[0], f_fl[0], f_ro[0]))
8388  ->line(
8390  3, f_or[0], f_fl[0], f_ro[0])), // 6
8391  hex->face(0)
8392  ->isotropic_child(
8394  3, f_or[0], f_fl[0], f_ro[0]))
8395  ->line(
8397  2, f_or[0], f_fl[0], f_ro[0])), // 7
8398 
8399  hex->face(1)
8400  ->isotropic_child(
8402  0, f_or[1], f_fl[1], f_ro[1]))
8403  ->line(
8405  1, f_or[1], f_fl[1], f_ro[1])), // 8
8406  hex->face(1)
8407  ->isotropic_child(
8409  3, f_or[1], f_fl[1], f_ro[1]))
8410  ->line(
8412  0, f_or[1], f_fl[1], f_ro[1])), // 9
8413  hex->face(1)
8414  ->isotropic_child(
8416  0, f_or[1], f_fl[1], f_ro[1]))
8417  ->line(
8419  3, f_or[1], f_fl[1], f_ro[1])), // 10
8420  hex->face(1)
8421  ->isotropic_child(
8423  3, f_or[1], f_fl[1], f_ro[1]))
8424  ->line(
8426  2, f_or[1], f_fl[1], f_ro[1])), // 11
8427 
8428  new_lines[0] // 12
8429  };
8430 
8431  unsigned int line_indices[13];
8432 
8433  for (unsigned int i = 0; i < 13; ++i)
8434  line_indices[i] = lines[i]->index();
8435 
8436  // the orientation of lines for the inner quads
8437  // is quite tricky. as these lines are newly
8438  // created ones and thus have no parents, they
8439  // cannot inherit this property. set up an array
8440  // and fill it with the respective values
8441  bool line_orientation[13];
8442 
8443  // the middle vertices of the lines of our front
8444  // face
8445  const unsigned int middle_vertices[4] = {
8446  hex->line(8)->child(0)->vertex_index(1),
8447  hex->line(10)->child(0)->vertex_index(1),
8448  hex->line(0)->child(0)->vertex_index(1),
8449  hex->line(4)->child(0)->vertex_index(1),
8450  };
8451 
8452  // note: for lines 0 to 3 the orientation of the
8453  // line is 'true', if vertex 0 is on the front
8454  for (unsigned int i = 0; i < 4; ++i)
8455  if (lines[i]->vertex_index(0) == middle_vertices[i])
8456  line_orientation[i] = true;
8457  else
8458  {
8459  // it must be the other way round then
8460  Assert(lines[i]->vertex_index(1) ==
8461  middle_vertices[i],
8462  ExcInternalError());
8463  line_orientation[i] = false;
8464  }
8465 
8466  // note: for lines 4 to 11 (inner lines of the
8467  // outer quads) the following holds: the second
8468  // vertex of the even lines in standard
8469  // orientation is the vertex in the middle of
8470  // the quad, whereas for odd lines the first
8471  // vertex is the same middle vertex.
8472  for (unsigned int i = 4; i < 12; ++i)
8473  if (lines[i]->vertex_index((i + 1) % 2) ==
8474  middle_vertex_index<dim, spacedim>(
8475  hex->face(i / 4 - 1)))
8476  line_orientation[i] = true;
8477  else
8478  {
8479  // it must be the other way
8480  // round then
8481  Assert(lines[i]->vertex_index(i % 2) ==
8482  (middle_vertex_index<dim, spacedim>(
8483  hex->face(i / 4 - 1))),
8484  ExcInternalError());
8485  line_orientation[i] = false;
8486  }
8487  // for the last line the line orientation is
8488  // always true, since it was just constructed
8489  // that way
8490  line_orientation[12] = true;
8491 
8492  // set up the 4 quads, numbered as follows (left
8493  // quad numbering, right line numbering
8494  // extracted from above)
8495  //
8496  // x
8497  // *-------* *---3---*
8498  // | 3 | 5 9
8499  // *-------* *---12--*
8500  // | 2 | 4 8
8501  // *-------*y *---2---*
8502  //
8503  // y
8504  // *---------* *----1----*
8505  // / 1 / 7 11
8506  // *---------* *----12---*
8507  // / 0 / 6 10
8508  // *---------*x *----0----*
8509 
8510  new_quads[0]->set_bounding_object_indices(
8511  {line_indices[6],
8512  line_indices[10],
8513  line_indices[0],
8514  line_indices[12]});
8515  new_quads[1]->set_bounding_object_indices(
8516  {line_indices[7],
8517  line_indices[11],
8518  line_indices[12],
8519  line_indices[1]});
8520  new_quads[2]->set_bounding_object_indices(
8521  {line_indices[2],
8522  line_indices[12],
8523  line_indices[4],
8524  line_indices[8]});
8525  new_quads[3]->set_bounding_object_indices(
8526  {line_indices[12],
8527  line_indices[3],
8528  line_indices[5],
8529  line_indices[9]});
8530 
8531  new_quads[0]->set_line_orientation(
8532  0, line_orientation[6]);
8533  new_quads[0]->set_line_orientation(
8534  1, line_orientation[10]);
8535  new_quads[0]->set_line_orientation(
8536  2, line_orientation[0]);
8537 
8538  new_quads[1]->set_line_orientation(
8539  0, line_orientation[7]);
8540  new_quads[1]->set_line_orientation(
8541  1, line_orientation[11]);
8542  new_quads[1]->set_line_orientation(
8543  3, line_orientation[1]);
8544 
8545  new_quads[2]->set_line_orientation(
8546  0, line_orientation[2]);
8547  new_quads[2]->set_line_orientation(
8548  2, line_orientation[4]);
8549  new_quads[2]->set_line_orientation(
8550  3, line_orientation[8]);
8551 
8552  new_quads[3]->set_line_orientation(
8553  1, line_orientation[3]);
8554  new_quads[3]->set_line_orientation(
8555  2, line_orientation[5]);
8556  new_quads[3]->set_line_orientation(
8557  3, line_orientation[9]);
8558 
8559  // the quads are numbered as follows:
8560  //
8561  // planes in the interior of the old hex:
8562  //
8563  // *
8564  // /|
8565  // / | x
8566  // / | *-------* *---------*
8567  // * | | 3 | / 1 /
8568  // | | *-------* *---------*
8569  // | * | 2 | / 0 /
8570  // | / *-------*y *---------*x
8571  // | /
8572  // |/
8573  // *
8574  //
8575  // children of the faces
8576  // of the old hex
8577  // *-------* *-------*
8578  // /| | / 19 /|
8579  // * | 15 | *-------* |
8580  // /|7*-------* / 18 /|11
8581  // * |/| | *-------* |/|
8582  // |6* | 14 | | 10* |
8583  // |/|5*-------* | 13 |/|9*
8584  // * |/ 17 / *-------* |/
8585  // |4*-------* | |8*
8586  // |/ 16 / | 12 |/
8587  // *-------* *-------*
8588  //
8589  // note that we have to take care of the
8590  // orientation of faces.
8591  const int quad_indices[20] = {
8592  new_quads[0]->index(), // 0
8593  new_quads[1]->index(),
8594  new_quads[2]->index(),
8595  new_quads[3]->index(),
8596 
8597  hex->face(0)->isotropic_child_index(
8599  0, f_or[0], f_fl[0], f_ro[0])), // 4
8600  hex->face(0)->isotropic_child_index(
8602  1, f_or[0], f_fl[0], f_ro[0])),
8603  hex->face(0)->isotropic_child_index(
8605  2, f_or[0], f_fl[0], f_ro[0])),
8606  hex->face(0)->isotropic_child_index(
8608  3, f_or[0], f_fl[0], f_ro[0])),
8609 
8610  hex->face(1)->isotropic_child_index(
8612  0, f_or[1], f_fl[1], f_ro[1])), // 8
8613  hex->face(1)->isotropic_child_index(
8615  1, f_or[1], f_fl[1], f_ro[1])),
8616  hex->face(1)->isotropic_child_index(
8618  2, f_or[1], f_fl[1], f_ro[1])),
8619  hex->face(1)->isotropic_child_index(
8621  3, f_or[1], f_fl[1], f_ro[1])),
8622 
8623  hex->face(2)->child_index(
8624  child_at_origin[hex->face(2)->refinement_case() -
8625  1][f_fl[2]][f_ro[2]]), // 12
8626  hex->face(2)->child_index(
8627  1 -
8628  child_at_origin[hex->face(2)->refinement_case() -
8629  1][f_fl[2]][f_ro[2]]),
8630 
8631  hex->face(3)->child_index(
8632  child_at_origin[hex->face(3)->refinement_case() -
8633  1][f_fl[3]][f_ro[3]]), // 14
8634  hex->face(3)->child_index(
8635  1 -
8636  child_at_origin[hex->face(3)->refinement_case() -
8637  1][f_fl[3]][f_ro[3]]),
8638 
8639  hex->face(4)->child_index(
8640  child_at_origin[hex->face(4)->refinement_case() -
8641  1][f_fl[4]][f_ro[4]]), // 16
8642  hex->face(4)->child_index(
8643  1 -
8644  child_at_origin[hex->face(4)->refinement_case() -
8645  1][f_fl[4]][f_ro[4]]),
8646 
8647  hex->face(5)->child_index(
8648  child_at_origin[hex->face(5)->refinement_case() -
8649  1][f_fl[5]][f_ro[5]]), // 18
8650  hex->face(5)->child_index(
8651  1 -
8652  child_at_origin[hex->face(5)->refinement_case() -
8653  1][f_fl[5]][f_ro[5]])};
8654 
8655  new_hexes[0]->set_bounding_object_indices(
8656  {quad_indices[4],
8657  quad_indices[8],
8658  quad_indices[12],
8659  quad_indices[2],
8660  quad_indices[16],
8661  quad_indices[0]});
8662  new_hexes[1]->set_bounding_object_indices(
8663  {quad_indices[5],
8664  quad_indices[9],
8665  quad_indices[2],
8666  quad_indices[14],
8667  quad_indices[17],
8668  quad_indices[1]});
8669  new_hexes[2]->set_bounding_object_indices(
8670  {quad_indices[6],
8671  quad_indices[10],
8672  quad_indices[13],
8673  quad_indices[3],
8674  quad_indices[0],
8675  quad_indices[18]});
8676  new_hexes[3]->set_bounding_object_indices(
8677  {quad_indices[7],
8678  quad_indices[11],
8679  quad_indices[3],
8680  quad_indices[15],
8681  quad_indices[1],
8682  quad_indices[19]});
8683  break;
8684  }
8685 
8687  {
8689  //
8690  // RefinementCase<dim>::cut_xyz
8691  // isotropic refinement
8692  //
8693  // the refined cube will look
8694  // like this:
8695  //
8696  // *----*----*
8697  // / / /|
8698  // *----*----* |
8699  // / / /| *
8700  // *----*----* |/|
8701  // | | | * |
8702  // | | |/| *
8703  // *----*----* |/
8704  // | | | *
8705  // | | |/
8706  // *----*----*
8707  //
8708 
8709  // find the next unused vertex and set it
8710  // appropriately
8711  while (
8712  triangulation.vertices_used[next_unused_vertex] ==
8713  true)
8714  ++next_unused_vertex;
8715  Assert(
8716  next_unused_vertex < triangulation.vertices.size(),
8717  ExcMessage(
8718  "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."));
8719  triangulation.vertices_used[next_unused_vertex] =
8720  true;
8721 
8722  // the new vertex is definitely in the interior,
8723  // so we need not worry about the
8724  // boundary. However we need to worry about
8725  // Manifolds. Let the cell compute its own
8726  // center, by querying the underlying manifold
8727  // object.
8728  triangulation.vertices[next_unused_vertex] =
8729  hex->center(true, true);
8730 
8731  // set the data of the six lines. first collect
8732  // the indices of the seven vertices (consider
8733  // the two planes to be crossed to form the
8734  // planes cutting the hex in two vertically and
8735  // horizontally)
8736  //
8737  // *--3--* *--5--*
8738  // / / / | | |
8739  // 0--6--1 0--6--1
8740  // / / / | | |
8741  // *--2--* *--4--*
8742  // the lines are numbered
8743  // as follows:
8744  // *--*--* *--*--*
8745  // / 1 / | 5 |
8746  // *2-*-3* *2-*-3*
8747  // / 0 / | 4 |
8748  // *--*--* *--*--*
8749  //
8750  const unsigned int vertex_indices[7] = {
8751  middle_vertex_index<dim, spacedim>(hex->face(0)),
8752  middle_vertex_index<dim, spacedim>(hex->face(1)),
8753  middle_vertex_index<dim, spacedim>(hex->face(2)),
8754  middle_vertex_index<dim, spacedim>(hex->face(3)),
8755  middle_vertex_index<dim, spacedim>(hex->face(4)),
8756  middle_vertex_index<dim, spacedim>(hex->face(5)),
8757  next_unused_vertex};
8758 
8759  new_lines[0]->set_bounding_object_indices(
8760  {vertex_indices[2], vertex_indices[6]});
8761  new_lines[1]->set_bounding_object_indices(
8762  {vertex_indices[6], vertex_indices[3]});
8763  new_lines[2]->set_bounding_object_indices(
8764  {vertex_indices[0], vertex_indices[6]});
8765  new_lines[3]->set_bounding_object_indices(
8766  {vertex_indices[6], vertex_indices[1]});
8767  new_lines[4]->set_bounding_object_indices(
8768  {vertex_indices[4], vertex_indices[6]});
8769  new_lines[5]->set_bounding_object_indices(
8770  {vertex_indices[6], vertex_indices[5]});
8771 
8772  // again, first collect some data about the
8773  // indices of the lines, with the following
8774  // numbering: (note that face 0 and 1 each are
8775  // shown twice for better readability)
8776 
8777  // face 0: left plane
8778  // * *
8779  // /| /|
8780  // * | * |
8781  // /| * /| *
8782  // * 1/| * |3|
8783  // | * | | * |
8784  // |/| * |2| *
8785  // * 0/ * |/
8786  // | * | *
8787  // |/ |/
8788  // * *
8789  // face 1: right plane
8790  // * *
8791  // /| /|
8792  // * | * |
8793  // /| * /| *
8794  // * 5/| * |7|
8795  // | * | | * |
8796  // |/| * |6| *
8797  // * 4/ * |/
8798  // | * | *
8799  // |/ |/
8800  // * *
8801  // face 2: front plane
8802  // (note: x,y exchanged)
8803  // *---*---*
8804  // | 11 |
8805  // *-8-*-9-*
8806  // | 10 |
8807  // *---*---*
8808  // face 3: back plane
8809  // (note: x,y exchanged)
8810  // *---*---*
8811  // | 15 |
8812  // *12-*-13*
8813  // | 14 |
8814  // *---*---*
8815  // face 4: bottom plane
8816  // *---*---*
8817  // / 17 /
8818  // *18-*-19*
8819  // / 16 /
8820  // *---*---*
8821  // face 5: top plane
8822  // *---*---*
8823  // / 21 /
8824  // *22-*-23*
8825  // / 20 /
8826  // *---*---*
8827  // middle planes
8828  // *---*---* *---*---*
8829  // / 25 / | 29 |
8830  // *26-*-27* *26-*-27*
8831  // / 24 / | 28 |
8832  // *---*---* *---*---*
8833 
8834  // set up a list of line iterators first. from
8835  // this, construct lists of line_indices and
8836  // line orientations later on
8837  const typename Triangulation<
8838  dim,
8839  spacedim>::raw_line_iterator lines[30] = {
8840  hex->face(0)
8841  ->isotropic_child(
8843  0, f_or[0], f_fl[0], f_ro[0]))
8844  ->line(
8846  1, f_or[0], f_fl[0], f_ro[0])), // 0
8847  hex->face(0)
8848  ->isotropic_child(
8850  3, f_or[0], f_fl[0], f_ro[0]))
8851  ->line(
8853  0, f_or[0], f_fl[0], f_ro[0])), // 1
8854  hex->face(0)
8855  ->isotropic_child(
8857  0, f_or[0], f_fl[0], f_ro[0]))
8858  ->line(
8860  3, f_or[0], f_fl[0], f_ro[0])), // 2
8861  hex->face(0)
8862  ->isotropic_child(
8864  3, f_or[0], f_fl[0], f_ro[0]))
8865  ->line(
8867  2, f_or[0], f_fl[0], f_ro[0])), // 3
8868 
8869  hex->face(1)
8870  ->isotropic_child(
8872  0, f_or[1], f_fl[1], f_ro[1]))
8873  ->line(
8875  1, f_or[1], f_fl[1], f_ro[1])), // 4
8876  hex->face(1)
8877  ->isotropic_child(
8879  3, f_or[1], f_fl[1], f_ro[1]))
8880  ->line(
8882  0, f_or[1], f_fl[1], f_ro[1])), // 5
8883  hex->face(1)
8884  ->isotropic_child(
8886  0, f_or[1], f_fl[1], f_ro[1]))
8887  ->line(
8889  3, f_or[1], f_fl[1], f_ro[1])), // 6
8890  hex->face(1)
8891  ->isotropic_child(
8893  3, f_or[1], f_fl[1], f_ro[1]))
8894  ->line(
8896  2, f_or[1], f_fl[1], f_ro[1])), // 7
8897 
8898  hex->face(2)
8899  ->isotropic_child(
8901  0, f_or[2], f_fl[2], f_ro[2]))
8902  ->line(
8904  1, f_or[2], f_fl[2], f_ro[2])), // 8
8905  hex->face(2)
8906  ->isotropic_child(
8908  3, f_or[2], f_fl[2], f_ro[2]))
8909  ->line(
8911  0, f_or[2], f_fl[2], f_ro[2])), // 9
8912  hex->face(2)
8913  ->isotropic_child(
8915  0, f_or[2], f_fl[2], f_ro[2]))
8916  ->line(
8918  3, f_or[2], f_fl[2], f_ro[2])), // 10
8919  hex->face(2)
8920  ->isotropic_child(
8922  3, f_or[2], f_fl[2], f_ro[2]))
8923  ->line(
8925  2, f_or[2], f_fl[2], f_ro[2])), // 11
8926 
8927  hex->face(3)
8928  ->isotropic_child(
8930  0, f_or[3], f_fl[3], f_ro[3]))
8931  ->line(
8933  1, f_or[3], f_fl[3], f_ro[3])), // 12
8934  hex->face(3)
8935  ->isotropic_child(
8937  3, f_or[3], f_fl[3], f_ro[3]))
8938  ->line(
8940  0, f_or[3], f_fl[3], f_ro[3])), // 13
8941  hex->face(3)
8942  ->isotropic_child(
8944  0, f_or[3], f_fl[3], f_ro[3]))
8945  ->line(
8947  3, f_or[3], f_fl[3], f_ro[3])), // 14
8948  hex->face(3)
8949  ->isotropic_child(
8951  3, f_or[3], f_fl[3], f_ro[3]))
8952  ->line(
8954  2, f_or[3], f_fl[3], f_ro[3])), // 15
8955 
8956  hex->face(4)
8957  ->isotropic_child(
8959  0, f_or[4], f_fl[4], f_ro[4]))
8960  ->line(
8962  1, f_or[4], f_fl[4], f_ro[4])), // 16
8963  hex->face(4)
8964  ->isotropic_child(
8966  3, f_or[4], f_fl[4], f_ro[4]))
8967  ->line(
8969  0, f_or[4], f_fl[4], f_ro[4])), // 17
8970  hex->face(4)
8971  ->isotropic_child(
8973  0, f_or[4], f_fl[4], f_ro[4]))
8974  ->line(
8976  3, f_or[4], f_fl[4], f_ro[4])), // 18
8977  hex->face(4)
8978  ->isotropic_child(
8980  3, f_or[4], f_fl[4], f_ro[4]))
8981  ->line(
8983  2, f_or[4], f_fl[4], f_ro[4])), // 19
8984 
8985  hex->face(5)
8986  ->isotropic_child(
8988  0, f_or[5], f_fl[5], f_ro[5]))
8989  ->line(
8991  1, f_or[5], f_fl[5], f_ro[5])), // 20
8992  hex->face(5)
8993  ->isotropic_child(
8995  3, f_or[5], f_fl[5], f_ro[5]))
8996  ->line(
8998  0, f_or[5], f_fl[5], f_ro[5])), // 21
8999  hex->face(5)
9000  ->isotropic_child(
9002  0, f_or[5], f_fl[5], f_ro[5]))
9003  ->line(
9005  3, f_or[5], f_fl[5], f_ro[5])), // 22
9006  hex->face(5)
9007  ->isotropic_child(
9009  3, f_or[5], f_fl[5], f_ro[5]))
9010  ->line(
9012  2, f_or[5], f_fl[5], f_ro[5])), // 23
9013 
9014  new_lines[0], // 24
9015  new_lines[1], // 25
9016  new_lines[2], // 26
9017  new_lines[3], // 27
9018  new_lines[4], // 28
9019  new_lines[5] // 29
9020  };
9021 
9022  unsigned int line_indices[30];
9023  for (unsigned int i = 0; i < 30; ++i)
9024  line_indices[i] = lines[i]->index();
9025 
9026  // the orientation of lines for the inner quads
9027  // is quite tricky. as these lines are newly
9028  // created ones and thus have no parents, they
9029  // cannot inherit this property. set up an array
9030  // and fill it with the respective values
9031  bool line_orientation[30];
9032 
9033  // note: for the first 24 lines (inner lines of
9034  // the outer quads) the following holds: the
9035  // second vertex of the even lines in standard
9036  // orientation is the vertex in the middle of
9037  // the quad, whereas for odd lines the first
9038  // vertex is the same middle vertex.
9039  for (unsigned int i = 0; i < 24; ++i)
9040  if (lines[i]->vertex_index((i + 1) % 2) ==
9041  vertex_indices[i / 4])
9042  line_orientation[i] = true;
9043  else
9044  {
9045  // it must be the other way
9046  // round then
9047  Assert(lines[i]->vertex_index(i % 2) ==
9048  vertex_indices[i / 4],
9049  ExcInternalError());
9050  line_orientation[i] = false;
9051  }
9052  // for the last 6 lines the line orientation is
9053  // always true, since they were just constructed
9054  // that way
9055  for (unsigned int i = 24; i < 30; ++i)
9056  line_orientation[i] = true;
9057 
9058  // set up the 12 quads, numbered as follows
9059  // (left quad numbering, right line numbering
9060  // extracted from above)
9061  //
9062  // * *
9063  // /| 21|
9064  // * | * 15
9065  // y/|3* 20| *
9066  // * |/| * |/|
9067  // |2* |x 11 * 14
9068  // |/|1* |/| *
9069  // * |/ * |17
9070  // |0* 10 *
9071  // |/ |16
9072  // * *
9073  //
9074  // x
9075  // *---*---* *22-*-23*
9076  // | 5 | 7 | 1 29 5
9077  // *---*---* *26-*-27*
9078  // | 4 | 6 | 0 28 4
9079  // *---*---*y *18-*-19*
9080  //
9081  // y
9082  // *----*----* *-12-*-13-*
9083  // / 10 / 11 / 3 25 7
9084  // *----*----* *-26-*-27-*
9085  // / 8 / 9 / 2 24 6
9086  // *----*----*x *--8-*--9-*
9087 
9088  new_quads[0]->set_bounding_object_indices(
9089  {line_indices[10],
9090  line_indices[28],
9091  line_indices[16],
9092  line_indices[24]});
9093  new_quads[1]->set_bounding_object_indices(
9094  {line_indices[28],
9095  line_indices[14],
9096  line_indices[17],
9097  line_indices[25]});
9098  new_quads[2]->set_bounding_object_indices(
9099  {line_indices[11],
9100  line_indices[29],
9101  line_indices[24],
9102  line_indices[20]});
9103  new_quads[3]->set_bounding_object_indices(
9104  {line_indices[29],
9105  line_indices[15],
9106  line_indices[25],
9107  line_indices[21]});
9108  new_quads[4]->set_bounding_object_indices(
9109  {line_indices[18],
9110  line_indices[26],
9111  line_indices[0],
9112  line_indices[28]});
9113  new_quads[5]->set_bounding_object_indices(
9114  {line_indices[26],
9115  line_indices[22],
9116  line_indices[1],
9117  line_indices[29]});
9118  new_quads[6]->set_bounding_object_indices(
9119  {line_indices[19],
9120  line_indices[27],
9121  line_indices[28],
9122  line_indices[4]});
9123  new_quads[7]->set_bounding_object_indices(
9124  {line_indices[27],
9125  line_indices[23],
9126  line_indices[29],
9127  line_indices[5]});
9128  new_quads[8]->set_bounding_object_indices(
9129  {line_indices[2],
9130  line_indices[24],
9131  line_indices[8],
9132  line_indices[26]});
9133  new_quads[9]->set_bounding_object_indices(
9134  {line_indices[24],
9135  line_indices[6],
9136  line_indices[9],
9137  line_indices[27]});
9138  new_quads[10]->set_bounding_object_indices(
9139  {line_indices[3],
9140  line_indices[25],
9141  line_indices[26],
9142  line_indices[12]});
9143  new_quads[11]->set_bounding_object_indices(
9144  {line_indices[25],
9145  line_indices[7],
9146  line_indices[27],
9147  line_indices[13]});
9148 
9149  // now reset the line_orientation flags of outer
9150  // lines as they cannot be set in a loop (at
9151  // least not easily)
9152  new_quads[0]->set_line_orientation(
9153  0, line_orientation[10]);
9154  new_quads[0]->set_line_orientation(
9155  2, line_orientation[16]);
9156 
9157  new_quads[1]->set_line_orientation(
9158  1, line_orientation[14]);
9159  new_quads[1]->set_line_orientation(
9160  2, line_orientation[17]);
9161 
9162  new_quads[2]->set_line_orientation(
9163  0, line_orientation[11]);
9164  new_quads[2]->set_line_orientation(
9165  3, line_orientation[20]);
9166 
9167  new_quads[3]->set_line_orientation(
9168  1, line_orientation[15]);
9169  new_quads[3]->set_line_orientation(
9170  3, line_orientation[21]);
9171 
9172  new_quads[4]->set_line_orientation(
9173  0, line_orientation[18]);
9174  new_quads[4]->set_line_orientation(
9175  2, line_orientation[0]);
9176 
9177  new_quads[5]->set_line_orientation(
9178  1, line_orientation[22]);
9179  new_quads[5]->set_line_orientation(
9180  2, line_orientation[1]);
9181 
9182  new_quads[6]->set_line_orientation(
9183  0, line_orientation[19]);
9184  new_quads[6]->set_line_orientation(
9185  3, line_orientation[4]);
9186 
9187  new_quads[7]->set_line_orientation(
9188  1, line_orientation[23]);
9189  new_quads[7]->set_line_orientation(
9190  3, line_orientation[5]);
9191 
9192  new_quads[8]->set_line_orientation(
9193  0, line_orientation[2]);
9194  new_quads[8]->set_line_orientation(
9195  2, line_orientation[8]);
9196 
9197  new_quads[9]->set_line_orientation(
9198  1, line_orientation[6]);
9199  new_quads[9]->set_line_orientation(
9200  2, line_orientation[9]);
9201 
9202  new_quads[10]->set_line_orientation(
9203  0, line_orientation[3]);
9204  new_quads[10]->set_line_orientation(
9205  3, line_orientation[12]);
9206 
9207  new_quads[11]->set_line_orientation(
9208  1, line_orientation[7]);
9209  new_quads[11]->set_line_orientation(
9210  3, line_orientation[13]);
9211 
9213  // create the eight new hexes
9214  //
9215  // again first collect some data. here, we need
9216  // the indices of a whole lotta quads.
9217 
9218  // the quads are numbered as follows:
9219  //
9220  // planes in the interior of the old hex:
9221  //
9222  // *
9223  // /|
9224  // * |
9225  // /|3* *---*---* *----*----*
9226  // * |/| | 5 | 7 | / 10 / 11 /
9227  // |2* | *---*---* *----*----*
9228  // |/|1* | 4 | 6 | / 8 / 9 /
9229  // * |/ *---*---*y *----*----*x
9230  // |0*
9231  // |/
9232  // *
9233  //
9234  // children of the faces
9235  // of the old hex
9236  // *-------* *-------*
9237  // /|25 27| /34 35/|
9238  // 15| | / /19
9239  // / | | /32 33/ |
9240  // * |24 26| *-------*18 |
9241  // 1413*-------* |21 23| 17*
9242  // | /30 31/ | | /
9243  // 12/ / | |16
9244  // |/28 29/ |20 22|/
9245  // *-------* *-------*
9246  //
9247  // note that we have to
9248  // take care of the
9249  // orientation of
9250  // faces.
9251  const int quad_indices[36] = {
9252  new_quads[0]->index(), // 0
9253  new_quads[1]->index(),
9254  new_quads[2]->index(),
9255  new_quads[3]->index(),
9256  new_quads[4]->index(),
9257  new_quads[5]->index(),
9258  new_quads[6]->index(),
9259  new_quads[7]->index(),
9260  new_quads[8]->index(),
9261  new_quads[9]->index(),
9262  new_quads[10]->index(),
9263  new_quads[11]->index(), // 11
9264 
9265  hex->face(0)->isotropic_child_index(
9267  0, f_or[0], f_fl[0], f_ro[0])), // 12
9268  hex->face(0)->isotropic_child_index(
9270  1, f_or[0], f_fl[0], f_ro[0])),
9271  hex->face(0)->isotropic_child_index(
9273  2, f_or[0], f_fl[0], f_ro[0])),
9274  hex->face(0)->isotropic_child_index(
9276  3, f_or[0], f_fl[0], f_ro[0])),
9277 
9278  hex->face(1)->isotropic_child_index(
9280  0, f_or[1], f_fl[1], f_ro[1])), // 16
9281  hex->face(1)->isotropic_child_index(
9283  1, f_or[1], f_fl[1], f_ro[1])),
9284  hex->face(1)->isotropic_child_index(
9286  2, f_or[1], f_fl[1], f_ro[1])),
9287  hex->face(1)->isotropic_child_index(
9289  3, f_or[1], f_fl[1], f_ro[1])),
9290 
9291  hex->face(2)->isotropic_child_index(
9293  0, f_or[2], f_fl[2], f_ro[2])), // 20
9294  hex->face(2)->isotropic_child_index(
9296  1, f_or[2], f_fl[2], f_ro[2])),
9297  hex->face(2)->isotropic_child_index(
9299  2, f_or[2], f_fl[2], f_ro[2])),
9300  hex->face(2)->isotropic_child_index(
9302  3, f_or[2], f_fl[2], f_ro[2])),
9303 
9304  hex->face(3)->isotropic_child_index(
9306  0, f_or[3], f_fl[3], f_ro[3])), // 24
9307  hex->face(3)->isotropic_child_index(
9309  1, f_or[3], f_fl[3], f_ro[3])),
9310  hex->face(3)->isotropic_child_index(
9312  2, f_or[3], f_fl[3], f_ro[3])),
9313  hex->face(3)->isotropic_child_index(
9315  3, f_or[3], f_fl[3], f_ro[3])),
9316 
9317  hex->face(4)->isotropic_child_index(
9319  0, f_or[4], f_fl[4], f_ro[4])), // 28
9320  hex->face(4)->isotropic_child_index(
9322  1, f_or[4], f_fl[4], f_ro[4])),
9323  hex->face(4)->isotropic_child_index(
9325  2, f_or[4], f_fl[4], f_ro[4])),
9326  hex->face(4)->isotropic_child_index(
9328  3, f_or[4], f_fl[4], f_ro[4])),
9329 
9330  hex->face(5)->isotropic_child_index(
9332  0, f_or[5], f_fl[5], f_ro[5])), // 32
9333  hex->face(5)->isotropic_child_index(
9335  1, f_or[5], f_fl[5], f_ro[5])),
9336  hex->face(5)->isotropic_child_index(
9338  2, f_or[5], f_fl[5], f_ro[5])),
9339  hex->face(5)->isotropic_child_index(
9341  3, f_or[5], f_fl[5], f_ro[5]))};
9342 
9343  // bottom children
9344  new_hexes[0]->set_bounding_object_indices(
9345  {quad_indices[12],
9346  quad_indices[0],
9347  quad_indices[20],
9348  quad_indices[4],
9349  quad_indices[28],
9350  quad_indices[8]});
9351  new_hexes[1]->set_bounding_object_indices(
9352  {quad_indices[0],
9353  quad_indices[16],
9354  quad_indices[22],
9355  quad_indices[6],
9356  quad_indices[29],
9357  quad_indices[9]});
9358  new_hexes[2]->set_bounding_object_indices(
9359  {quad_indices[13],
9360  quad_indices[1],
9361  quad_indices[4],
9362  quad_indices[24],
9363  quad_indices[30],
9364  quad_indices[10]});
9365  new_hexes[3]->set_bounding_object_indices(
9366  {quad_indices[1],
9367  quad_indices[17],
9368  quad_indices[6],
9369  quad_indices[26],
9370  quad_indices[31],
9371  quad_indices[11]});
9372 
9373  // top children
9374  new_hexes[4]->set_bounding_object_indices(
9375  {quad_indices[14],
9376  quad_indices[2],
9377  quad_indices[21],
9378  quad_indices[5],
9379  quad_indices[8],
9380  quad_indices[32]});
9381  new_hexes[5]->set_bounding_object_indices(
9382  {quad_indices[2],
9383  quad_indices[18],
9384  quad_indices[23],
9385  quad_indices[7],
9386  quad_indices[9],
9387  quad_indices[33]});
9388  new_hexes[6]->set_bounding_object_indices(
9389  {quad_indices[15],
9390  quad_indices[3],
9391  quad_indices[5],
9392  quad_indices[25],
9393  quad_indices[10],
9394  quad_indices[34]});
9395  new_hexes[7]->set_bounding_object_indices(
9396  {quad_indices[3],
9397  quad_indices[19],
9398  quad_indices[7],
9399  quad_indices[27],
9400  quad_indices[11],
9401  quad_indices[35]});
9402  break;
9403  }
9404  default:
9405  // all refinement cases have been treated, there
9406  // only remains
9407  // RefinementCase<dim>::no_refinement as
9408  // untreated enumeration value. However, in that
9409  // case we should have aborted much
9410  // earlier. thus we should never get here
9411  Assert(false, ExcInternalError());
9412  break;
9413  } // switch (ref_case)
9414 
9415  // and set face orientation flags. note that new
9416  // faces in the interior of the mother cell always
9417  // have a correctly oriented face, but the ones on
9418  // the outer faces will inherit this flag
9419  //
9420  // the flag have been set to true for all faces
9421  // initially, now go the other way round and reset
9422  // faces that are at the boundary of the mother cube
9423  //
9424  // the same is true for the face_flip and
9425  // face_rotation flags. however, the latter two are
9426  // set to false by default as this is the standard
9427  // value
9428 
9429  // loop over all faces and all (relevant) subfaces
9430  // of that in order to set the correct values for
9431  // face_orientation, face_flip and face_rotation,
9432  // which are inherited from the corresponding face
9433  // of the mother cube
9434  for (const unsigned int f : GeometryInfo<dim>::face_indices())
9435  for (unsigned int s = 0;
9438  ref_case, f)),
9439  1U);
9440  ++s)
9441  {
9442  const unsigned int current_child =
9444  ref_case,
9445  f,
9446  s,
9447  f_or[f],
9448  f_fl[f],
9449  f_ro[f],
9451  ref_case, f, f_or[f], f_fl[f], f_ro[f]));
9452  new_hexes[current_child]->set_face_orientation(f,
9453  f_or[f]);
9454  new_hexes[current_child]->set_face_flip(f, f_fl[f]);
9455  new_hexes[current_child]->set_face_rotation(f, f_ro[f]);
9456  }
9457 
9458  // now see if we have created cells that are
9459  // distorted and if so add them to our list
9460  if (check_for_distorted_cells &&
9461  has_distorted_children<dim, spacedim>(hex))
9462  cells_with_distorted_children.distorted_cells.push_back(
9463  hex);
9464 
9465  // note that the refinement flag was already cleared
9466  // at the beginning of this loop
9467 
9468  // inform all listeners that cell refinement is done
9469  triangulation.signals.post_refinement_on_cell(hex);
9470  }
9471  }
9472 
9473  // clear user data on quads. we used some of this data to
9474  // indicate anisotropic refinemnt cases on faces. all data
9475  // should be cleared by now, but the information whether we
9476  // used indices or pointers is still present. reset it now to
9477  // enable the user to use whichever they like later on.
9478  triangulation.faces->quads.clear_user_data();
9479 
9480  // return the list with distorted children
9481  return cells_with_distorted_children;
9482  }
9483 
9484 
9497  template <int spacedim>
9499  {}
9500 
9501 
9502 
9503  template <int dim, int spacedim>
9504  static void
9507  {
9508  // If the codimension is one, we cannot perform this check
9509  // yet.
9510  if (spacedim > dim)
9511  return;
9512 
9513  for (const auto &cell : triangulation.cell_iterators())
9514  if (cell->at_boundary() && cell->refine_flag_set() &&
9515  cell->refine_flag_set() !=
9517  {
9518  // The cell is at the boundary and it is flagged for
9519  // anisotropic refinement. Therefore, we have a closer
9520  // look
9521  const RefinementCase<dim> ref_case = cell->refine_flag_set();
9522  for (const unsigned int face_no :
9524  if (cell->face(face_no)->at_boundary())
9525  {
9526  // this is the critical face at the boundary.
9528  face_no) !=
9530  {
9531  // up to now, we do not want to refine this
9532  // cell along the face under consideration
9533  // here.
9534  const typename Triangulation<dim,
9535  spacedim>::face_iterator
9536  face = cell->face(face_no);
9537  // the new point on the boundary would be this
9538  // one.
9539  const Point<spacedim> new_bound = face->center(true);
9540  // to check it, transform to the unit cell
9541  // with a linear mapping
9542  const Point<dim> new_unit =
9543  cell->reference_cell()
9544  .template get_default_linear_mapping<dim,
9545  spacedim>()
9546  .transform_real_to_unit_cell(cell, new_bound);
9547 
9548  // Now, we have to calculate the distance from
9549  // the face in the unit cell.
9550 
9551  // take the correct coordinate direction (0
9552  // for faces 0 and 1, 1 for faces 2 and 3, 2
9553  // for faces 4 and 5) and subtract the correct
9554  // boundary value of the face (0 for faces 0,
9555  // 2, and 4; 1 for faces 1, 3 and 5)
9556  const double dist =
9557  std::fabs(new_unit[face_no / 2] - face_no % 2);
9558 
9559  // compare this with the empirical value
9560  // allowed. if it is too big, flag the face
9561  // for isotropic refinement
9562  const double allowed = 0.25;
9563 
9564  if (dist > allowed)
9565  cell->flag_for_face_refinement(face_no);
9566  } // if flagged for anistropic refinement
9567  } // if (cell->face(face)->at_boundary())
9568  } // for all cells
9569  }
9570 
9571 
9584  template <int dim, int spacedim>
9585  static void
9587  {
9588  Assert(dim < 3,
9589  ExcMessage("Wrong function called -- there should "
9590  "be a specialization."));
9591  }
9592 
9593 
9594  template <int spacedim>
9597  {
9598  const unsigned int dim = 3;
9599 
9600  // first clear flags on lines, since we need them to determine
9601  // which lines will be refined
9602  triangulation.clear_user_flags_line();
9603 
9604  // also clear flags on hexes, since we need them to mark those
9605  // cells which are to be coarsened
9606  triangulation.clear_user_flags_hex();
9607 
9608  // variable to store whether the mesh was changed in the
9609  // present loop and in the whole process
9610  bool mesh_changed = false;
9611 
9612  do
9613  {
9614  mesh_changed = false;
9615 
9616  // for this following, we need to know which cells are
9617  // going to be coarsened, if we had to make a
9618  // decision. the following function sets these flags:
9619  triangulation.fix_coarsen_flags();
9620 
9621 
9622  // flag those lines that are refined and will not be
9623  // coarsened and those that will be refined
9624  for (const auto &cell : triangulation.cell_iterators())
9625  if (cell->refine_flag_set())
9626  {
9627  for (unsigned int line = 0; line < cell->n_lines(); ++line)
9629  cell->refine_flag_set(), line) ==
9631  // flag a line, that will be
9632  // refined
9633  cell->line(line)->set_user_flag();
9634  }
9635  else if (cell->has_children() &&
9636  !cell->child(0)->coarsen_flag_set())
9637  {
9638  for (unsigned int line = 0;
9639  line < GeometryInfo<dim>::lines_per_cell;
9640  ++line)
9642  cell->refinement_case(), line) ==
9644  // flag a line, that is refined
9645  // and will stay so
9646  cell->line(line)->set_user_flag();
9647  }
9648  else if (cell->has_children() &&
9649  cell->child(0)->coarsen_flag_set())
9650  cell->set_user_flag();
9651 
9652 
9653  // now check whether there are cells with lines that are
9654  // more than once refined or that will be more than once
9655  // refined. The first thing should never be the case, in
9656  // the second case we flag the cell for refinement
9658  cell = triangulation.last_active();
9659  cell != triangulation.end();
9660  --cell)
9661  for (unsigned int line = 0; line < cell->n_lines(); ++line)
9662  {
9663  if (cell->line(line)->has_children())
9664  {
9665  // if this line is refined, its children should
9666  // not have further children
9667  //
9668  // however, if any of the children is flagged
9669  // for further refinement, we need to refine
9670  // this cell also (at least, if the cell is not
9671  // already flagged)
9672  bool offending_line_found = false;
9673 
9674  for (unsigned int c = 0; c < 2; ++c)
9675  {
9676  Assert(cell->line(line)->child(c)->has_children() ==
9677  false,
9678  ExcInternalError());
9679 
9680  if (cell->line(line)->child(c)->user_flag_set() &&
9682  cell->refine_flag_set(), line) ==
9684  {
9685  // tag this cell for refinement
9686  cell->clear_coarsen_flag();
9687  // if anisotropic coarsening is allowed:
9688  // extend the refine_flag in the needed
9689  // direction, else set refine_flag
9690  // (isotropic)
9691  if (triangulation.smooth_grid &
9693  allow_anisotropic_smoothing)
9694  cell->flag_for_line_refinement(line);
9695  else
9696  cell->set_refine_flag();
9697 
9698  for (unsigned int l = 0;
9699  l < GeometryInfo<dim>::lines_per_cell;
9700  ++l)
9702  cell->refine_flag_set(), line) ==
9704  // flag a line, that will be refined
9705  cell->line(l)->set_user_flag();
9706 
9707  // note that we have changed the grid
9708  offending_line_found = true;
9709 
9710  // it may save us several loop
9711  // iterations if we flag all lines of
9712  // this cell now (and not at the outset
9713  // of the next iteration) for refinement
9714  for (unsigned int l = 0;
9715  l < GeometryInfo<dim>::lines_per_cell;
9716  ++l)
9717  if (!cell->line(l)->has_children() &&
9719  cell->refine_flag_set(), l) !=
9721  cell->line(l)->set_user_flag();
9722 
9723  break;
9724  }
9725  }
9726 
9727  if (offending_line_found)
9728  {
9729  mesh_changed = true;
9730  break;
9731  }
9732  }
9733  }
9734 
9735 
9736  // there is another thing here: if any of the lines will
9737  // be refined, then we may not coarsen the present cell
9738  // similarly, if any of the lines *is* already refined, we
9739  // may not coarsen the current cell. however, there's a
9740  // catch: if the line is refined, but the cell behind it
9741  // is going to be coarsened, then the situation
9742  // changes. if we forget this second condition, the
9743  // refine_and_coarsen_3d test will start to fail. note
9744  // that to know which cells are going to be coarsened, the
9745  // call for fix_coarsen_flags above is necessary
9746  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
9747  triangulation.last();
9748  cell != triangulation.end();
9749  --cell)
9750  {
9751  if (cell->user_flag_set())
9752  for (unsigned int line = 0;
9753  line < GeometryInfo<dim>::lines_per_cell;
9754  ++line)
9755  if (cell->line(line)->has_children() &&
9756  (cell->line(line)->child(0)->user_flag_set() ||
9757  cell->line(line)->child(1)->user_flag_set()))
9758  {
9759  for (unsigned int c = 0; c < cell->n_children(); ++c)
9760  cell->child(c)->clear_coarsen_flag();
9761  cell->clear_user_flag();
9762  for (unsigned int l = 0;
9763  l < GeometryInfo<dim>::lines_per_cell;
9764  ++l)
9766  cell->refinement_case(), l) ==
9768  // flag a line, that is refined
9769  // and will stay so
9770  cell->line(l)->set_user_flag();
9771  mesh_changed = true;
9772  break;
9773  }
9774  }
9775  }
9776  while (mesh_changed == true);
9777  }
9778 
9779 
9780 
9787  template <int dim, int spacedim>
9788  static bool
9790  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
9791  {
9792  // in 1d, coarsening is always allowed since we don't enforce
9793  // the 2:1 constraint there
9794  if (dim == 1)
9795  return true;
9796 
9797  const RefinementCase<dim> ref_case = cell->refinement_case();
9798  for (unsigned int n : GeometryInfo<dim>::face_indices())
9799  {
9800  // if the cell is not refined along that face, coarsening
9801  // will not change anything, so do nothing. the same
9802  // applies, if the face is at the boandary
9803  const RefinementCase<dim - 1> face_ref_case =
9804  GeometryInfo<dim>::face_refinement_case(cell->refinement_case(),
9805  n);
9806 
9807  const unsigned int n_subfaces =
9808  GeometryInfo<dim - 1>::n_children(face_ref_case);
9809 
9810  if (n_subfaces == 0 || cell->at_boundary(n))
9811  continue;
9812  for (unsigned int c = 0; c < n_subfaces; ++c)
9813  {
9815  child = cell->child(
9816  GeometryInfo<dim>::child_cell_on_face(ref_case, n, c));
9817 
9819  child_neighbor = child->neighbor(n);
9820  if (!child->neighbor_is_coarser(n))
9821  // in 2d, if the child's neighbor is coarser, then
9822  // it has no children. however, in 3d it might be
9823  // otherwise. consider for example, that our face
9824  // might be refined with cut_x, but the neighbor is
9825  // refined with cut_xy at that face. then the
9826  // neighbor pointers of the children of our cell
9827  // will point to the common neighbor cell, not to
9828  // its children. what we really want to know in the
9829  // following is, whether the neighbor cell is
9830  // refined twice with reference to our cell. that
9831  // only has to be asked, if the child's neighbor is
9832  // not a coarser one.
9833  if ((child_neighbor->has_children() &&
9834  !child_neighbor->user_flag_set()) ||
9835  // neighbor has children, which are further
9836  // refined along the face, otherwise something
9837  // went wrong in the construction of neighbor
9838  // pointers. then only allow coarsening if this
9839  // neighbor will be coarsened as well
9840  // (user_pointer is set). the same applies, if
9841  // the neighbors children are not refined but
9842  // will be after refinement
9843  child_neighbor->refine_flag_set())
9844  return false;
9845  }
9846  }
9847  return true;
9848  }
9849  };
9850 
9851 
9856  {
9857  template <int spacedim>
9859  {}
9860 
9861  template <int dim, int spacedim>
9863  {
9864  std::vector<std::pair<unsigned int, unsigned int>> adjacent_cells(
9865  2 * triangulation.n_raw_faces(),
9866  {numbers::invalid_unsigned_int, numbers::invalid_unsigned_int});
9867 
9868  const auto set_entry = [&](const auto &face_index, const auto &cell) {
9869  const std::pair<unsigned int, unsigned int> cell_pair = {
9870  cell->level(), cell->index()};
9871  unsigned int index;
9872 
9873  if (adjacent_cells[2 * face_index].first ==
9875  adjacent_cells[2 * face_index].second ==
9877  {
9878  index = 2 * face_index + 0;
9879  }
9880  else
9881  {
9882  Assert(((adjacent_cells[2 * face_index + 1].first ==
9884  (adjacent_cells[2 * face_index + 1].second ==
9886  ExcNotImplemented());
9887  index = 2 * face_index + 1;
9888  }
9889 
9890  adjacent_cells[index] = cell_pair;
9891  };
9892 
9893  const auto get_entry =
9894  [&](const auto &face_index,
9895  const auto &cell) -> TriaIterator<CellAccessor<dim, spacedim>> {
9896  auto test = adjacent_cells[2 * face_index];
9897 
9898  if (test == std::pair<unsigned int, unsigned int>(cell->level(),
9899  cell->index()))
9900  test = adjacent_cells[2 * face_index + 1];
9901 
9902  if ((test.first != numbers::invalid_unsigned_int) &&
9903  (test.second != numbers::invalid_unsigned_int))
9905  test.first,
9906  test.second);
9907  else
9909  };
9910 
9911  for (const auto &cell : triangulation.cell_iterators())
9912  for (const auto &face : cell->face_iterators())
9913  {
9914  set_entry(face->index(), cell);
9915 
9916  if (cell->is_active() && face->has_children())
9917  for (unsigned int c = 0; c < face->n_children(); ++c)
9918  set_entry(face->child(c)->index(), cell);
9919  }
9920 
9921  for (const auto &cell : triangulation.cell_iterators())
9922  for (auto f : cell->face_indices())
9923  cell->set_neighbor(f, get_entry(cell->face(f)->index(), cell));
9924  }
9925 
9926  template <int dim, int spacedim>
9927  static void
9931  std::vector<unsigned int> & line_cell_count,
9932  std::vector<unsigned int> & quad_cell_count)
9933  {
9934  AssertThrow(false, ExcNotImplemented());
9935  (void)triangulation;
9936  (void)cell;
9937  (void)line_cell_count;
9938  (void)quad_cell_count;
9939  }
9940 
9941  template <int dim, int spacedim>
9944  const bool check_for_distorted_cells)
9945  {
9947  triangulation, check_for_distorted_cells);
9948  }
9949 
9950  template <int dim, int spacedim>
9951  static void
9954  {
9955  // nothing to do since anisotropy is not supported
9956  (void)triangulation;
9957  }
9958 
9959  template <int dim, int spacedim>
9960  static void
9963  {
9965  }
9966 
9967  template <int dim, int spacedim>
9968  static bool
9970  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
9971  {
9972  AssertThrow(false, ExcNotImplemented());
9973  (void)cell;
9974 
9975  return false;
9976  }
9977  };
9978 
9979 
9980  template <int dim, int spacedim>
9981  const Manifold<dim, spacedim> &
9983  {
9984  static const FlatManifold<dim, spacedim> flat_manifold;
9985  return flat_manifold;
9986  }
9987  } // namespace TriangulationImplementation
9988 } // namespace internal
9989 
9990 
9991 
9992 template <int dim, int spacedim>
9993 const unsigned int Triangulation<dim, spacedim>::dimension;
9994 
9995 
9996 
9997 template <int dim, int spacedim>
9999  const MeshSmoothing smooth_grid,
10000  const bool check_for_distorted_cells)
10001  : smooth_grid(smooth_grid)
10002  , anisotropic_refinement(false)
10003  , check_for_distorted_cells(check_for_distorted_cells)
10004 {
10005  if (dim == 1)
10006  {
10007  vertex_to_boundary_id_map_1d =
10008  std::make_unique<std::map<unsigned int, types::boundary_id>>();
10009  vertex_to_manifold_id_map_1d =
10010  std::make_unique<std::map<unsigned int, types::manifold_id>>();
10011  }
10012 
10013  // connect the any_change signal to the other top level signals
10014  signals.create.connect(signals.any_change);
10015  signals.post_refinement.connect(signals.any_change);
10016  signals.clear.connect(signals.any_change);
10017  signals.mesh_movement.connect(signals.any_change);
10018 }
10019 
10020 
10021 
10022 template <int dim, int spacedim>
10024  Triangulation<dim, spacedim> &&tria) noexcept
10025  : Subscriptor(std::move(tria))
10026  , smooth_grid(tria.smooth_grid)
10027  , reference_cells(std::move(tria.reference_cells))
10028  , periodic_face_pairs_level_0(std::move(tria.periodic_face_pairs_level_0))
10029  , periodic_face_map(std::move(tria.periodic_face_map))
10030  , levels(std::move(tria.levels))
10031  , faces(std::move(tria.faces))
10032  , vertices(std::move(tria.vertices))
10033  , vertices_used(std::move(tria.vertices_used))
10034  , manifold(std::move(tria.manifold))
10035  , anisotropic_refinement(tria.anisotropic_refinement)
10036  , check_for_distorted_cells(tria.check_for_distorted_cells)
10037  , number_cache(std::move(tria.number_cache))
10038  , vertex_to_boundary_id_map_1d(std::move(tria.vertex_to_boundary_id_map_1d))
10039  , vertex_to_manifold_id_map_1d(std::move(tria.vertex_to_manifold_id_map_1d))
10040 {
10042 
10043  if (tria.policy)
10044  this->policy = tria.policy->clone();
10045 }
10046 
10047 
10048 template <int dim, int spacedim>
10051 operator=(Triangulation<dim, spacedim> &&tria) noexcept
10052 {
10053  Subscriptor::operator=(std::move(tria));
10054 
10055  smooth_grid = tria.smooth_grid;
10056  reference_cells = std::move(tria.reference_cells);
10057  periodic_face_pairs_level_0 = std::move(tria.periodic_face_pairs_level_0);
10058  periodic_face_map = std::move(tria.periodic_face_map);
10059  levels = std::move(tria.levels);
10060  faces = std::move(tria.faces);
10061  vertices = std::move(tria.vertices);
10062  vertices_used = std::move(tria.vertices_used);
10063  manifold = std::move(tria.manifold);
10064  anisotropic_refinement = tria.anisotropic_refinement;
10065  number_cache = tria.number_cache;
10066  vertex_to_boundary_id_map_1d = std::move(tria.vertex_to_boundary_id_map_1d);
10067  vertex_to_manifold_id_map_1d = std::move(tria.vertex_to_manifold_id_map_1d);
10068 
10070 
10071  if (tria.policy)
10072  this->policy = tria.policy->clone();
10073 
10074  return *this;
10075 }
10076 
10077 
10078 
10079 template <int dim, int spacedim>
10081 {
10082  // notify listeners that the triangulation is going down...
10083  try
10084  {
10085  signals.clear();
10086  }
10087  catch (...)
10088  {}
10089 
10090  levels.clear();
10091 
10092  // the vertex_to_boundary_id_map_1d field should be unused except in
10093  // 1d. double check this here, as destruction is a good place to
10094  // ensure that what we've done over the course of the lifetime of
10095  // this object makes sense
10096  AssertNothrow((dim == 1) || (vertex_to_boundary_id_map_1d == nullptr),
10097  ExcInternalError());
10098 
10099  // the vertex_to_manifold_id_map_1d field should be also unused
10100  // except in 1d. check this as well
10101  AssertNothrow((dim == 1) || (vertex_to_manifold_id_map_1d == nullptr),
10102  ExcInternalError());
10103 }
10104 
10105 
10106 
10107 template <int dim, int spacedim>
10108 void
10110 {
10111  // notify listeners that the triangulation is going down...
10112  signals.clear();
10113 
10114  // ...and then actually clear all content of it
10115  clear_despite_subscriptions();
10116  periodic_face_pairs_level_0.clear();
10117  periodic_face_map.clear();
10118  reference_cells.clear();
10119 }
10120 
10121 
10122 template <int dim, int spacedim>
10123 MPI_Comm
10125 {
10126  return MPI_COMM_SELF;
10127 }
10128 
10129 
10130 
10131 template <int dim, int spacedim>
10132 void
10134  const MeshSmoothing mesh_smoothing)
10135 {
10136  Assert(n_levels() == 0,
10137  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
10138  smooth_grid = mesh_smoothing;
10139 }
10140 
10141 
10142 
10143 template <int dim, int spacedim>
10146 {
10147  return smooth_grid;
10148 }
10149 
10150 
10151 
10152 template <int dim, int spacedim>
10153 void
10155  const types::manifold_id m_number,
10156  const Manifold<dim, spacedim> &manifold_object)
10157 {
10159 
10160  manifold[m_number] = manifold_object.clone();
10161 }
10162 
10163 
10164 
10165 template <int dim, int spacedim>
10166 void
10168 {
10170 
10171  // delete the entry located at number.
10172  manifold.erase(m_number);
10173 }
10174 
10175 
10176 template <int dim, int spacedim>
10177 void
10179 {
10180  manifold.clear();
10181 }
10182 
10183 
10184 template <int dim, int spacedim>
10185 void
10187  const types::manifold_id m_number)
10188 {
10189  Assert(
10190  n_cells() > 0,
10191  ExcMessage(
10192  "Error: set_all_manifold_ids() can not be called on an empty Triangulation."));
10193 
10194  for (const auto &cell : this->active_cell_iterators())
10195  cell->set_all_manifold_ids(m_number);
10196 }
10197 
10198 
10199 template <int dim, int spacedim>
10200 void
10202  const types::manifold_id m_number)
10203 {
10204  Assert(
10205  n_cells() > 0,
10206  ExcMessage(
10207  "Error: set_all_manifold_ids_on_boundary() can not be called on an empty Triangulation."));
10208 
10209  for (const auto &cell : this->active_cell_iterators())
10210  for (auto f : GeometryInfo<dim>::face_indices())
10211  if (cell->face(f)->at_boundary())
10212  cell->face(f)->set_all_manifold_ids(m_number);
10213 }
10214 
10215 
10216 template <int dim, int spacedim>
10217 void
10219  const types::boundary_id b_id,
10220  const types::manifold_id m_number)
10221 {
10222  Assert(
10223  n_cells() > 0,
10224  ExcMessage(
10225  "Error: set_all_manifold_ids_on_boundary() can not be called on an empty Triangulation."));
10226 
10227  bool boundary_found = false;
10228 
10229  for (const auto &cell : this->active_cell_iterators())
10230  {
10231  // loop on faces
10232  for (auto f : GeometryInfo<dim>::face_indices())
10233  if (cell->face(f)->at_boundary() &&
10234  cell->face(f)->boundary_id() == b_id)
10235  {
10236  boundary_found = true;
10237  cell->face(f)->set_manifold_id(m_number);
10238  }
10239 
10240  // loop on edges if dim >= 3
10241  if (dim >= 3)
10242  for (unsigned int e = 0; e < GeometryInfo<dim>::lines_per_cell; ++e)
10243  if (cell->line(e)->at_boundary() &&
10244  cell->line(e)->boundary_id() == b_id)
10245  {
10246  boundary_found = true;
10247  cell->line(e)->set_manifold_id(m_number);
10248  }
10249  }
10250 
10251  (void)boundary_found;
10252  Assert(boundary_found, ExcBoundaryIdNotFound(b_id));
10253 }
10254 
10255 
10256 
10257 template <int dim, int spacedim>
10260  const types::manifold_id m_number) const
10261 {
10262  // look, if there is a manifold stored at
10263  // manifold_id number.
10264  const auto it = manifold.find(m_number);
10265 
10266  if (it != manifold.end())
10267  {
10268  // if we have found an entry, return it
10269  return *(it->second);
10270  }
10271 
10272  // if we have not found an entry connected with number, we return
10273  // the default (flat) manifold
10274  return internal::TriangulationImplementation::
10275  get_default_flat_manifold<dim, spacedim>();
10276 }
10277 
10278 
10279 
10280 template <int dim, int spacedim>
10281 std::vector<types::boundary_id>
10283 {
10284  // in 1d, we store a map of all used boundary indicators. use it for
10285  // our purposes
10286  if (dim == 1)
10287  {
10288  std::vector<types::boundary_id> boundary_ids;
10289  for (std::map<unsigned int, types::boundary_id>::const_iterator p =
10290  vertex_to_boundary_id_map_1d->begin();
10291  p != vertex_to_boundary_id_map_1d->end();
10292  ++p)
10293  boundary_ids.push_back(p->second);
10294 
10295  return boundary_ids;
10296  }
10297  else
10298  {
10299  std::set<types::boundary_id> b_ids;
10300  for (auto cell : active_cell_iterators())
10301  if (cell->is_locally_owned())
10302  for (const unsigned int face : cell->face_indices())
10303  if (cell->at_boundary(face))
10304  b_ids.insert(cell->face(face)->boundary_id());
10305  std::vector<types::boundary_id> boundary_ids(b_ids.begin(), b_ids.end());
10306  return boundary_ids;
10307  }
10308 }
10309 
10310 
10311 
10312 template <int dim, int spacedim>
10313 std::vector<types::manifold_id>
10315 {
10316  std::set<types::manifold_id> m_ids;
10317  for (auto cell : active_cell_iterators())
10318  if (cell->is_locally_owned())
10319  {
10320  m_ids.insert(cell->manifold_id());
10321  for (const auto &face : cell->face_iterators())
10322  m_ids.insert(face->manifold_id());
10323  if (dim == 3)
10324  for (const unsigned int l : cell->line_indices())
10325  m_ids.insert(cell->line(l)->manifold_id());
10326  }
10327  return {m_ids.begin(), m_ids.end()};
10328 }
10329 
10330 /*-----------------------------------------------------------------*/
10331 
10332 
10333 template <int dim, int spacedim>
10334 void
10336  const Triangulation<dim, spacedim> &other_tria)
10337 {
10338  Assert((vertices.size() == 0) && (levels.size() == 0) && (faces == nullptr),
10339  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
10340  Assert((other_tria.levels.size() != 0) && (other_tria.vertices.size() != 0) &&
10341  (dim == 1 || other_tria.faces != nullptr),
10342  ExcMessage(
10343  "When calling Triangulation::copy_triangulation(), "
10344  "the target triangulation must be empty but the source "
10345  "triangulation (the argument to this function) must contain "
10346  "something. Here, it seems like the source does not "
10347  "contain anything at all."));
10348 
10349 
10350  // copy normal elements
10351  vertices = other_tria.vertices;
10352  vertices_used = other_tria.vertices_used;
10353  anisotropic_refinement = other_tria.anisotropic_refinement;
10354  smooth_grid = other_tria.smooth_grid;
10355  reference_cells = other_tria.reference_cells;
10356 
10357  if (dim > 1)
10358  faces = std::make_unique<internal::TriangulationImplementation::TriaFaces>(
10359  *other_tria.faces);
10360 
10361  for (const auto &p : other_tria.manifold)
10362  set_manifold(p.first, *p.second);
10363 
10364 
10365  levels.reserve(other_tria.levels.size());
10366  for (unsigned int level = 0; level < other_tria.levels.size(); ++level)
10367  levels.push_back(
10368  std::make_unique<internal::TriangulationImplementation::TriaLevel>(
10369  *other_tria.levels[level]));
10370 
10371  number_cache = other_tria.number_cache;
10372 
10373  if (dim == 1)
10374  {
10375  vertex_to_boundary_id_map_1d =
10376  std::make_unique<std::map<unsigned int, types::boundary_id>>(
10377  *other_tria.vertex_to_boundary_id_map_1d);
10378 
10379  vertex_to_manifold_id_map_1d =
10380  std::make_unique<std::map<unsigned int, types::manifold_id>>(
10381  *other_tria.vertex_to_manifold_id_map_1d);
10382  }
10383 
10384  if (other_tria.policy)
10385  this->policy = other_tria.policy->clone();
10386 
10387  // inform those who are listening on other_tria of the copy operation
10388  other_tria.signals.copy(*this);
10389  // also inform all listeners of the current triangulation that the
10390  // triangulation has been created
10391  signals.create();
10392 
10393  // note that we need not copy the
10394  // subscriptor!
10395 }
10396 
10397 
10398 
10399 template <int dim, int spacedim>
10400 void
10402  const std::vector<Point<spacedim>> &v,
10403  const std::vector<CellData<dim>> & cells,
10404  const SubCellData & subcelldata)
10405 {
10406  std::vector<CellData<dim>> reordered_cells(cells); // NOLINT
10407  SubCellData reordered_subcelldata(subcelldata); // NOLINT
10408 
10409  // in-place reordering of data
10410  reorder_compatibility(reordered_cells, reordered_subcelldata);
10411 
10412  // now create triangulation from
10413  // reordered data
10414  create_triangulation(v, reordered_cells, reordered_subcelldata);
10415 }
10416 
10417 
10418 template <int dim, int spacedim>
10419 void
10421 {
10422  this->update_reference_cells();
10423 
10424  if (this->all_reference_cells_are_hyper_cube())
10425  {
10426  this->policy =
10428  dim,
10429  spacedim,
10431  }
10432  else
10433  {
10434  this->policy =
10436  dim,
10437  spacedim,
10439  }
10440 }
10441 
10442 
10443 
10444 template <int dim, int spacedim>
10445 void
10447  const std::vector<Point<spacedim>> &v,
10448  const std::vector<CellData<dim>> & cells,
10449  const SubCellData & subcelldata)
10450 {
10451  Assert((vertices.size() == 0) && (levels.size() == 0) && (faces == nullptr),
10452  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
10453  // check that no forbidden arrays
10454  // are used
10455  Assert(subcelldata.check_consistency(dim), ExcInternalError());
10456 
10457  // try to create a triangulation; if this fails, we still want to
10458  // throw an exception but if we just do so we'll get into trouble
10459  // because sometimes other objects are already attached to it:
10460  try
10461  {
10463  create_triangulation(v, cells, subcelldata, *this);
10464  }
10465  catch (...)
10466  {
10467  clear_despite_subscriptions();
10468  throw;
10469  }
10470 
10471  reset_policy();
10472 
10473  // update our counts of the various elements of a triangulation, and set
10474  // active_cell_indices of all cells
10475  reset_cell_vertex_indices_cache();
10477  *this, levels.size(), number_cache);
10478  reset_active_cell_indices();
10479  reset_global_cell_indices();
10480 
10481  // now verify that there are indeed no distorted cells. as per the
10482  // documentation of this class, we first collect all distorted cells
10483  // and then throw an exception if there are any
10484  if (check_for_distorted_cells)
10485  {
10486  DistortedCellList distorted_cells = collect_distorted_coarse_cells(*this);
10487  // throw the array (and fill the various location fields) if
10488  // there are distorted cells. otherwise, just fall off the end
10489  // of the function
10490  AssertThrow(distorted_cells.distorted_cells.size() == 0, distorted_cells);
10491  }
10492 
10493 
10494  /*
10495  When the triangulation is a manifold (dim < spacedim), the normal field
10496  provided from the map class depends on the order of the vertices.
10497  It may happen that this normal field is discontinuous.
10498  The following code takes care that this is not the case by setting the
10499  cell direction flag on those cell that produce the wrong orientation.
10500 
10501  To determine if 2 neighbours have the same or opposite orientation
10502  we use a table of truth.
10503  Its entries are indexes by the local indices of the common face.
10504  For example if two elements share a face, and this face is
10505  face 0 for element 0 and face 1 for element 1, then
10506  table(0,1) will tell whether the orientation are the same (true) or
10507  opposite (false).
10508 
10509  Even though there may be a combinatorial/graph theory argument to get
10510  this table in any dimension, I tested by hand all the different possible
10511  cases in 1D and 2D to generate the table.
10512 
10513  Assuming that a surface respects the standard orientation for 2d meshes,
10514  the tables of truth are symmetric and their true values are the following
10515  1D curves: (0,1)
10516  2D surface: (0,1),(0,2),(1,3),(2,3)
10517 
10518  We store this data using an n_faces x n_faces full matrix, which is
10519  actually much bigger than the minimal data required, but it makes the code
10520  more readable.
10521 
10522  */
10523  if (dim < spacedim)
10524  {
10527  switch (dim)
10528  {
10529  case 1:
10530  {
10531  bool values[][2] = {{false, true}, {true, false}};
10532  for (const unsigned int i : GeometryInfo<dim>::face_indices())
10533  for (const unsigned int j : GeometryInfo<dim>::face_indices())
10534  correct(i, j) = (values[i][j]);
10535  break;
10536  }
10537  case 2:
10538  {
10539  bool values[][4] = {{false, true, true, false},
10540  {true, false, false, true},
10541  {true, false, false, true},
10542  {false, true, true, false}};
10543  for (const unsigned int i : GeometryInfo<dim>::face_indices())
10544  for (const unsigned int j : GeometryInfo<dim>::face_indices())
10545  correct(i, j) = (values[i][j]);
10546  break;
10547  }
10548  default:
10549  Assert(false, ExcNotImplemented());
10550  }
10551 
10552 
10553  std::list<active_cell_iterator> this_round, next_round;
10554  active_cell_iterator neighbor;
10555 
10556  this_round.push_back(begin_active());
10557  begin_active()->set_direction_flag(true);
10558  begin_active()->set_user_flag();
10559 
10560  while (this_round.size() > 0)
10561  {
10562  for (typename std::list<active_cell_iterator>::iterator cell =
10563  this_round.begin();
10564  cell != this_round.end();
10565  ++cell)
10566  {
10567  for (const unsigned int i : (*cell)->face_indices())
10568  {
10569  if (!((*cell)->face(i)->at_boundary()))
10570  {
10571  neighbor = (*cell)->neighbor(i);
10572 
10573  unsigned int cf = (*cell)->face_index(i);
10574  unsigned int j = 0;
10575  while (neighbor->face_index(j) != cf)
10576  {
10577  ++j;
10578  }
10579 
10580 
10581  // If we already saw this guy, check that everything is
10582  // fine
10583  if (neighbor->user_flag_set())
10584  {
10585  // If we have visited this guy, then the ordering and
10586  // the orientation should agree
10587  Assert(!(correct(i, j) ^
10588  (neighbor->direction_flag() ==
10589  (*cell)->direction_flag())),
10590  ExcNonOrientableTriangulation());
10591  }
10592  else
10593  {
10594  next_round.push_back(neighbor);
10595  neighbor->set_user_flag();
10596  if ((correct(i, j) ^ (neighbor->direction_flag() ==
10597  (*cell)->direction_flag())))
10598  neighbor->set_direction_flag(
10599  !neighbor->direction_flag());
10600  }
10601  }
10602  }
10603  }
10604 
10605  // Before we quit let's check
10606  // that if the triangulation
10607  // is disconnected that we
10608  // still get all cells
10609  if (next_round.size() == 0)
10610  for (const auto &cell : this->active_cell_iterators())
10611  if (cell->user_flag_set() == false)
10612  {
10613  next_round.push_back(cell);
10614  cell->set_direction_flag(true);
10615  cell->set_user_flag();
10616  break;
10617  }
10618 
10619  this_round = next_round;
10620  next_round.clear();
10621  }
10622  }
10623 
10624  // inform all listeners that the triangulation has been created
10625  signals.create();
10626 }
10627 
10628 
10629 
10630 template <int dim, int spacedim>
10631 void
10634 {
10635  // 1) create coarse grid
10636  create_triangulation(construction_data.coarse_cell_vertices,
10637  construction_data.coarse_cells,
10638  SubCellData());
10639 
10640  // create a copy of cell_infos such that we can sort them
10641  auto cell_infos = construction_data.cell_infos;
10642 
10643  // sort cell_infos on each level separately
10644  for (auto &cell_info : cell_infos)
10645  std::sort(
10646  cell_info.begin(),
10647  cell_info.end(),
10650  const CellId a_id(a.id);
10651  const CellId b_id(b.id);
10652 
10653  const auto a_coarse_cell_index =
10654  this->coarse_cell_id_to_coarse_cell_index(a_id.get_coarse_cell_id());
10655  const auto b_coarse_cell_index =
10656  this->coarse_cell_id_to_coarse_cell_index(b_id.get_coarse_cell_id());
10657 
10658  // according to their coarse-cell index and if that is
10659  // same according to their cell id (the result is that
10660  // cells on each level are sorted according to their
10661  // index on that level - what we need in the following
10662  // operations)
10663  if (a_coarse_cell_index != b_coarse_cell_index)
10664  return a_coarse_cell_index < b_coarse_cell_index;
10665  else
10666  return a_id < b_id;
10667  });
10668 
10669  // 2) create all levels via a sequence of refinements. note that
10670  // we must make sure that we actually have cells on this level,
10671  // which is not clear in a parallel context for some processes
10672  for (unsigned int level = 0;
10673  level < cell_infos.size() && !cell_infos[level].empty();
10674  ++level)
10675  {
10676  // a) set manifold ids here (because new vertices have to be
10677  // positioned correctly during each refinement step)
10678  {
10679  auto cell = this->begin(level);
10680  auto cell_info = cell_infos[level].begin();
10681  for (; cell_info != cell_infos[level].end(); ++cell_info)
10682  {
10683  while (cell_info->id != cell->id().template to_binary<dim>())
10684  ++cell;
10685  if (dim == 3)
10686  for (const auto quad : cell->face_indices())
10687  cell->quad(quad)->set_manifold_id(
10688  cell_info->manifold_quad_ids[quad]);
10689 
10690  if (dim >= 2)
10691  for (const auto line : cell->line_indices())
10692  cell->line(line)->set_manifold_id(
10693  cell_info->manifold_line_ids[line]);
10694 
10695  cell->set_manifold_id(cell_info->manifold_id);
10696  }
10697  }
10698 
10699  // b) perform refinement on all levels but on the finest
10700  if (level + 1 != cell_infos.size())
10701  {
10702  // find cells that should have children and mark them for
10703  // refinement
10704  auto coarse_cell = this->begin(level);
10705  auto fine_cell_info = cell_infos[level + 1].begin();
10706 
10707  // loop over all cells on the next level
10708  for (; fine_cell_info != cell_infos[level + 1].end();
10709  ++fine_cell_info)
10710  {
10711  // find the parent of that cell
10712  while (
10713  !coarse_cell->id().is_parent_of(CellId(fine_cell_info->id)))
10714  ++coarse_cell;
10715 
10716  // set parent for refinement
10717  coarse_cell->set_refine_flag();
10718  }
10719 
10720  // execute refinement
10721  ::Triangulation<dim,
10722  spacedim>::execute_coarsening_and_refinement();
10723  }
10724  }
10725 
10726  // 3) set boundary ids
10727  for (unsigned int level = 0;
10728  level < cell_infos.size() && !cell_infos[level].empty();
10729  ++level)
10730  {
10731  auto cell = this->begin(level);
10732  auto cell_info = cell_infos[level].begin();
10733  for (; cell_info != cell_infos[level].end(); ++cell_info)
10734  {
10735  // find cell that has the correct cell
10736  while (cell_info->id != cell->id().template to_binary<dim>())
10737  ++cell;
10738 
10739  // boundary ids
10740  for (auto pair : cell_info->boundary_ids)
10741  {
10742  Assert(cell->at_boundary(pair.first),
10743  ExcMessage("Cell face is not on the boundary!"));
10744  cell->face(pair.first)->set_boundary_id(pair.second);
10745  }
10746  }
10747  }
10748 }
10749 
10750 
10751 template <int dim, int spacedim>
10752 void
10754 {
10755  AssertThrow(dim + 1 == spacedim,
10756  ExcMessage("Only works for dim == spacedim-1"));
10757  for (const auto &cell : this->active_cell_iterators())
10758  cell->set_direction_flag(!cell->direction_flag());
10759 }
10760 
10761 
10762 
10763 template <int dim, int spacedim>
10764 void
10766 {
10767  Assert(n_cells() > 0,
10768  ExcMessage("Error: An empty Triangulation can not be refined."));
10769 
10770  for (const auto &cell : this->active_cell_iterators())
10771  {
10772  cell->clear_coarsen_flag();
10773  cell->set_refine_flag();
10774  }
10775 }
10776 
10777 
10778 
10779 template <int dim, int spacedim>
10780 void
10781 Triangulation<dim, spacedim>::refine_global(const unsigned int times)
10782 {
10783  for (unsigned int i = 0; i < times; ++i)
10784  {
10785  set_all_refine_flags();
10786  execute_coarsening_and_refinement();
10787  }
10788 }
10789 
10790 
10791 
10792 template <int dim, int spacedim>
10793 void
10794 Triangulation<dim, spacedim>::coarsen_global(const unsigned int times)
10795 {
10796  for (unsigned int i = 0; i < times; ++i)
10797  {
10798  for (const auto &cell : this->active_cell_iterators())
10799  {
10800  cell->clear_refine_flag();
10801  cell->set_coarsen_flag();
10802  }
10803  execute_coarsening_and_refinement();
10804  }
10805 }
10806 
10807 
10808 /*-------------------- refine/coarsen flags -------------------------*/
10809 
10810 
10811 
10812 template <int dim, int spacedim>
10813 void
10814 Triangulation<dim, spacedim>::save_refine_flags(std::vector<bool> &v) const
10815 {
10816  v.resize(dim * n_active_cells(), false);
10817  std::vector<bool>::iterator i = v.begin();
10818 
10819  for (const auto &cell : this->active_cell_iterators())
10820  for (unsigned int j = 0; j < dim; ++j, ++i)
10821  if (cell->refine_flag_set() & (1 << j))
10822  *i = true;
10823 
10824  Assert(i == v.end(), ExcInternalError());
10825 }
10826 
10827 
10828 
10829 template <int dim, int spacedim>
10830 void
10831 Triangulation<dim, spacedim>::save_refine_flags(std::ostream &out) const
10832 {
10833  std::vector<bool> v;
10834  save_refine_flags(v);
10835  write_bool_vector(mn_tria_refine_flags_begin,
10836  v,
10838  out);
10839 }
10840 
10841 
10842 
10843 template <int dim, int spacedim>
10844 void
10846 {
10847  std::vector<bool> v;
10848  read_bool_vector(mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end, in);
10849  load_refine_flags(v);
10850 }
10851 
10852 
10853 
10854 template <int dim, int spacedim>
10855 void
10856 Triangulation<dim, spacedim>::load_refine_flags(const std::vector<bool> &v)
10857 {
10858  AssertThrow(v.size() == dim * n_active_cells(), ExcGridReadError());
10859 
10860  std::vector<bool>::const_iterator i = v.begin();
10861  for (const auto &cell : this->active_cell_iterators())
10862  {
10863  unsigned int ref_case = 0;
10864 
10865  for (unsigned int j = 0; j < dim; ++j, ++i)
10866  if (*i == true)
10867  ref_case += 1 << j;
10869  ExcGridReadError());
10870  if (ref_case > 0)
10871  cell->set_refine_flag(RefinementCase<dim>(ref_case));
10872  else
10873  cell->clear_refine_flag();
10874  }
10875 
10876  Assert(i == v.end(), ExcInternalError());
10877 }
10878 
10879 
10880 
10881 template <int dim, int spacedim>
10882 void
10883 Triangulation<dim, spacedim>::save_coarsen_flags(std::vector<bool> &v) const
10884 {
10885  v.resize(n_active_cells(), false);
10886  std::vector<bool>::iterator i = v.begin();
10887  for (const auto &cell : this->active_cell_iterators())
10888  {
10889  *i = cell->coarsen_flag_set();
10890  ++i;
10891  }
10892 
10893  Assert(i == v.end(), ExcInternalError());
10894 }
10895 
10896 
10897 
10898 template <int dim, int spacedim>
10899 void
10900 Triangulation<dim, spacedim>::save_coarsen_flags(std::ostream &out) const
10901 {
10902  std::vector<bool> v;
10903  save_coarsen_flags(v);
10904  write_bool_vector(mn_tria_coarsen_flags_begin,
10905  v,
10907  out);
10908 }
10909 
10910 
10911 
10912 template <int dim, int spacedim>
10913 void
10915 {
10916  std::vector<bool> v;
10917  read_bool_vector(mn_tria_coarsen_flags_begin,
10918  v,
10920  in);
10921  load_coarsen_flags(v);
10922 }
10923 
10924 
10925 
10926 template <int dim, int spacedim>
10927 void
10928 Triangulation<dim, spacedim>::load_coarsen_flags(const std::vector<bool> &v)
10929 {
10930  Assert(v.size() == n_active_cells(), ExcGridReadError());
10931 
10932  std::vector<bool>::const_iterator i = v.begin();
10933  for (const auto &cell : this->active_cell_iterators())
10934  {
10935  if (*i == true)
10936  cell->set_coarsen_flag();
10937  else
10938  cell->clear_coarsen_flag();
10939  ++i;
10940  }
10941 
10942  Assert(i == v.end(), ExcInternalError());
10943 }
10944 
10945 
10946 template <int dim, int spacedim>
10947 bool
10949 {
10950  return anisotropic_refinement;
10951 }
10952 
10953 
10954 
10955 /*-------------------- user data/flags -------------------------*/
10956 
10957 
10958 namespace
10959 {
10960  // clear user data of cells
10961  void
10962  clear_user_data(std::vector<std::unique_ptr<
10964  {
10965  for (auto &level : levels)
10966  level->cells.clear_user_data();
10967  }
10968 
10969 
10970  // clear user data of faces
10971  void
10972  clear_user_data(internal::TriangulationImplementation::TriaFaces *faces)
10973  {
10974  if (faces->dim == 2)
10975  {
10976  faces->lines.clear_user_data();
10977  }
10978 
10979 
10980  if (faces->dim == 3)
10981  {
10982  faces->lines.clear_user_data();
10983  faces->quads.clear_user_data();
10984  }
10985  }
10986 } // namespace
10987 
10988 
10989 template <int dim, int spacedim>
10990 void
10992 {
10993  // let functions in anonymous namespace do their work
10994  ::clear_user_data(levels);
10995  ::clear_user_data(faces.get());
10996 }
10997 
10998 
10999 
11000 namespace
11001 {
11002  void
11003  clear_user_flags_line(
11004  unsigned int dim,
11005  std::vector<
11006  std::unique_ptr<internal::TriangulationImplementation::TriaLevel>>
11007  & levels,
11009  {
11010  if (dim == 1)
11011  {
11012  for (const auto &level : levels)
11013  level->cells.clear_user_flags();
11014  }
11015  else if (dim == 2 || dim == 3)
11016  {
11017  faces->lines.clear_user_flags();
11018  }
11019  else
11020  {
11021  Assert(false, ExcNotImplemented())
11022  }
11023  }
11024 } // namespace
11025 
11026 
11027 template <int dim, int spacedim>
11028 void
11030 {
11031  ::clear_user_flags_line(dim, levels, faces.get());
11032 }
11033 
11034 
11035 
11036 namespace
11037 {
11038  void
11039  clear_user_flags_quad(
11040  unsigned int dim,
11041  std::vector<
11042  std::unique_ptr<internal::TriangulationImplementation::TriaLevel>>
11043  & levels,
11045  {
11046  if (dim == 1)
11047  {
11048  // nothing to do in 1d
11049  }
11050  else if (dim == 2)
11051  {
11052  for (const auto &level : levels)
11053  level->cells.clear_user_flags();
11054  }
11055  else if (dim == 3)
11056  {
11057  faces->quads.clear_user_flags();
11058  }
11059  else
11060  {
11061  Assert(false, ExcNotImplemented())
11062  }
11063  }
11064 } // namespace
11065 
11066 
11067 template <int dim, int spacedim>
11068 void
11070 {
11071  ::clear_user_flags_quad(dim, levels, faces.get());
11072 }
11073 
11074 
11075 
11076 namespace
11077 {
11078  void
11079  clear_user_flags_hex(
11080  unsigned int dim,
11081  std::vector<
11082  std::unique_ptr<internal::TriangulationImplementation::TriaLevel>>
11083  &levels,
11085  {
11086  if (dim == 1)
11087  {
11088  // nothing to do in 1d
11089  }
11090  else if (dim == 2)
11091  {
11092  // nothing to do in 2d
11093  }
11094  else if (dim == 3)
11095  {
11096  for (const auto &level : levels)
11097  level->cells.clear_user_flags();
11098  }
11099  else
11100  {
11101  Assert(false, ExcNotImplemented())
11102  }
11103  }
11104 } // namespace
11105 
11106 
11107 template <int dim, int spacedim>
11108 void
11110 {
11111  ::clear_user_flags_hex(dim, levels, faces.get());
11112 }
11113 
11114 
11115 
11116 template <int dim, int spacedim>
11117 void
11119 {
11120  clear_user_flags_line();
11121  clear_user_flags_quad();
11122  clear_user_flags_hex();
11123 }
11124 
11125 
11126 
11127 template <int dim, int spacedim>
11128 void
11129 Triangulation<dim, spacedim>::save_user_flags(std::ostream &out) const
11130 {
11131  save_user_flags_line(out);
11132 
11133  if (dim >= 2)
11134  save_user_flags_quad(out);
11135 
11136  if (dim >= 3)
11137  save_user_flags_hex(out);
11138 
11139  if (dim >= 4)
11140  Assert(false, ExcNotImplemented());
11141 }
11142 
11143 
11144 
11145 template <int dim, int spacedim>
11146 void
11147 Triangulation<dim, spacedim>::save_user_flags(std::vector<bool> &v) const
11148 {
11149  // clear vector and append
11150  // all the stuff later on
11151  v.clear();
11152 
11153  std::vector<bool> tmp;
11154 
11155  save_user_flags_line(tmp);
11156  v.insert(v.end(), tmp.begin(), tmp.end());
11157 
11158  if (dim >= 2)
11159  {
11160  save_user_flags_quad(tmp);
11161  v.insert(v.end(), tmp.begin(), tmp.end());
11162  }
11163 
11164  if (dim >= 3)
11165  {
11166  save_user_flags_hex(tmp);
11167  v.insert(v.end(), tmp.begin(), tmp.end());
11168  }
11169 
11170  if (dim >= 4)
11171  Assert(false, ExcNotImplemented());
11172 }
11173 
11174 
11175 
11176 template <int dim, int spacedim>
11177 void
11179 {
11180  load_user_flags_line(in);
11181 
11182  if (dim >= 2)
11183  load_user_flags_quad(in);
11184 
11185  if (dim >= 3)
11186  load_user_flags_hex(in);
11187 
11188  if (dim >= 4)
11189  Assert(false, ExcNotImplemented());
11190 }
11191 
11192 
11193 
11194 template <int dim, int spacedim>
11195 void
11196 Triangulation<dim, spacedim>::load_user_flags(const std::vector<bool> &v)
11197 {
11198  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
11199  std::vector<bool> tmp;
11200 
11201  // first extract the flags
11202  // belonging to lines
11203  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
11204  // and set the lines
11205  load_user_flags_line(tmp);
11206 
11207  if (dim >= 2)
11208  {
11209  tmp.clear();
11210  tmp.insert(tmp.end(),
11211  v.begin() + n_lines(),
11212  v.begin() + n_lines() + n_quads());
11213  load_user_flags_quad(tmp);
11214  }
11215 
11216  if (dim >= 3)
11217  {
11218  tmp.clear();
11219  tmp.insert(tmp.end(),
11220  v.begin() + n_lines() + n_quads(),
11221  v.begin() + n_lines() + n_quads() + n_hexs());
11222  load_user_flags_hex(tmp);
11223  }
11224 
11225  if (dim >= 4)
11226  Assert(false, ExcNotImplemented());
11227 }
11228 
11229 
11230 
11231 template <int dim, int spacedim>
11232 void
11233 Triangulation<dim, spacedim>::save_user_flags_line(std::vector<bool> &v) const
11234 {
11235  v.resize(n_lines(), false);
11236  std::vector<bool>::iterator i = v.begin();
11237  line_iterator line = begin_line(), endl = end_line();
11238  for (; line != endl; ++line, ++i)
11239  *i = line->user_flag_set();
11240 
11241  Assert(i == v.end(), ExcInternalError());
11242 }
11243 
11244 
11245 
11246 template <int dim, int spacedim>
11247 void
11249 {
11250  std::vector<bool> v;
11251  save_user_flags_line(v);
11252  write_bool_vector(mn_tria_line_user_flags_begin,
11253  v,
11255  out);
11256 }
11257 
11258 
11259 
11260 template <int dim, int spacedim>
11261 void
11263 {
11264  std::vector<bool> v;
11265  read_bool_vector(mn_tria_line_user_flags_begin,
11266  v,
11268  in);
11269  load_user_flags_line(v);
11270 }
11271 
11272 
11273 
11274 template <int dim, int spacedim>
11275 void
11276 Triangulation<dim, spacedim>::load_user_flags_line(const std::vector<bool> &v)
11277 {
11278  Assert(v.size() == n_lines(), ExcGridReadError());
11279 
11280  line_iterator line = begin_line(), endl = end_line();
11281  std::vector<bool>::const_iterator i = v.begin();
11282  for (; line != endl; ++line, ++i)
11283  if (*i == true)
11284  line->set_user_flag();
11285  else
11286  line->clear_user_flag();
11287 
11288  Assert(i == v.end(), ExcInternalError());
11289 }
11290 
11291 
11292 namespace
11293 {
11294  template <typename Iterator>
11295  bool
11296  get_user_flag(const Iterator &i)
11297  {
11298  return i->user_flag_set();
11299  }
11300 
11301 
11302 
11303  template <int structdim, int dim, int spacedim>
11304  bool
11306  {
11307  Assert(false, ExcInternalError());
11308  return false;
11309  }
11310 
11311 
11312 
11313  template <typename Iterator>
11314  void
11315  set_user_flag(const Iterator &i)
11316  {
11317  i->set_user_flag();
11318  }
11319 
11320 
11321 
11322  template <int structdim, int dim, int spacedim>
11323  void
11325  {
11326  Assert(false, ExcInternalError());
11327  }
11328 
11329 
11330 
11331  template <typename Iterator>
11332  void
11333  clear_user_flag(const Iterator &i)
11334  {
11335  i->clear_user_flag();
11336  }
11337 
11338 
11339 
11340  template <int structdim, int dim, int spacedim>
11341  void
11342  clear_user_flag(
11344  {
11345  Assert(false, ExcInternalError());
11346  }
11347 } // namespace
11348 
11349 
11350 template <int dim, int spacedim>
11351 void
11352 Triangulation<dim, spacedim>::save_user_flags_quad(std::vector<bool> &v) const
11353 {
11354  v.resize(n_quads(), false);
11355 
11356  if (dim >= 2)
11357  {
11358  std::vector<bool>::iterator i = v.begin();
11359  quad_iterator quad = begin_quad(), endq = end_quad();
11360  for (; quad != endq; ++quad, ++i)
11361  *i = get_user_flag(quad);
11362 
11363  Assert(i == v.end(), ExcInternalError());
11364  }
11365 }
11366 
11367 
11368 
11369 template <int dim, int spacedim>
11370 void
11372 {
11373  std::vector<bool> v;
11374  save_user_flags_quad(v);
11375  write_bool_vector(mn_tria_quad_user_flags_begin,
11376  v,
11378  out);
11379 }
11380 
11381 
11382 
11383 template <int dim, int spacedim>
11384 void
11386 {
11387  std::vector<bool> v;
11388  read_bool_vector(mn_tria_quad_user_flags_begin,
11389  v,
11391  in);
11392  load_user_flags_quad(v);
11393 }
11394 
11395 
11396 
11397 template <int dim, int spacedim>
11398 void
11399 Triangulation<dim, spacedim>::load_user_flags_quad(const std::vector<bool> &v)
11400 {
11401  Assert(v.size() == n_quads(), ExcGridReadError());
11402 
11403  if (dim >= 2)
11404  {
11405  quad_iterator quad = begin_quad(), endq = end_quad();
11406  std::vector<bool>::const_iterator i = v.begin();
11407  for (; quad != endq; ++quad, ++i)
11408  if (*i == true)
11409  set_user_flag(quad);
11410  else
11411  clear_user_flag(quad);
11412 
11413  Assert(i == v.end(), ExcInternalError());
11414  }
11415 }
11416 
11417 
11418 
11419 template <int dim, int spacedim>
11420 void
11421 Triangulation<dim, spacedim>::save_user_flags_hex(std::vector<bool> &v) const
11422 {
11423  v.resize(n_hexs(), false);
11424 
11425  if (dim >= 3)
11426  {
11427  std::vector<bool>::iterator i = v.begin();
11428  hex_iterator hex = begin_hex(), endh = end_hex();
11429  for (; hex != endh; ++hex, ++i)
11430  *i = get_user_flag(hex);
11431 
11432  Assert(i == v.end(), ExcInternalError());
11433  }
11434 }
11435 
11436 
11437 
11438 template <int dim, int spacedim>
11439 void
11441 {
11442  std::vector<bool> v;
11443  save_user_flags_hex(v);
11444  write_bool_vector(mn_tria_hex_user_flags_begin,
11445  v,
11447  out);
11448 }
11449 
11450 
11451 
11452 template <int dim, int spacedim>
11453 void
11455 {
11456  std::vector<bool> v;
11457  read_bool_vector(mn_tria_hex_user_flags_begin,
11458  v,
11460  in);
11461  load_user_flags_hex(v);
11462 }
11463 
11464 
11465 
11466 template <int dim, int spacedim>
11467 void
11468 Triangulation<dim, spacedim>::load_user_flags_hex(const std::vector<bool> &v)
11469 {
11470  Assert(v.size() == n_hexs(), ExcGridReadError());
11471 
11472  if (dim >= 3)
11473  {
11474  hex_iterator hex = begin_hex(), endh = end_hex();
11475  std::vector<bool>::const_iterator i = v.begin();
11476  for (; hex != endh; ++hex, ++i)
11477  if (*i == true)
11478  set_user_flag(hex);
11479  else
11480  clear_user_flag(hex);
11481 
11482  Assert(i == v.end(), ExcInternalError());
11483  }
11484 }
11485 
11486 
11487 
11488 template <int dim, int spacedim>
11489 void
11491  std::vector<unsigned int> &v) const
11492 {
11493  // clear vector and append all the
11494  // stuff later on
11495  v.clear();
11496 
11497  std::vector<unsigned int> tmp;
11498 
11499  save_user_indices_line(tmp);
11500  v.insert(v.end(), tmp.begin(), tmp.end());
11501 
11502  if (dim >= 2)
11503  {
11504  save_user_indices_quad(tmp);
11505  v.insert(v.end(), tmp.begin(), tmp.end());
11506  }
11507 
11508  if (dim >= 3)
11509  {
11510  save_user_indices_hex(tmp);
11511  v.insert(v.end(), tmp.begin(), tmp.end());
11512  }
11513 
11514  if (dim >= 4)
11515  Assert(false, ExcNotImplemented());
11516 }
11517 
11518 
11519 
11520 template <int dim, int spacedim>
11521 void
11523  const std::vector<unsigned int> &v)
11524 {
11525  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
11526  std::vector<unsigned int> tmp;
11527 
11528  // first extract the indices
11529  // belonging to lines
11530  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
11531  // and set the lines
11532  load_user_indices_line(tmp);
11533 
11534  if (dim >= 2)
11535  {
11536  tmp.clear();
11537  tmp.insert(tmp.end(),
11538  v.begin() + n_lines(),
11539  v.begin() + n_lines() + n_quads());
11540  load_user_indices_quad(tmp);
11541  }
11542 
11543  if (dim >= 3)
11544  {
11545  tmp.clear();
11546  tmp.insert(tmp.end(),
11547  v.begin() + n_lines() + n_quads(),
11548  v.begin() + n_lines() + n_quads() + n_hexs());
11549  load_user_indices_hex(tmp);
11550  }
11551 
11552  if (dim >= 4)
11553  Assert(false, ExcNotImplemented());
11554 }
11555 
11556 
11557 
11558 namespace
11559 {
11560  template <typename Iterator>
11561  unsigned int
11562  get_user_index(const Iterator &i)
11563  {
11564  return i->user_index();
11565  }
11566 
11567 
11568 
11569  template <int structdim, int dim, int spacedim>
11570  unsigned int
11571  get_user_index(
11573  {
11574  Assert(false, ExcInternalError());
11576  }
11577 
11578 
11579 
11580  template <typename Iterator>
11581  void
11582  set_user_index(const Iterator &i, const unsigned int x)
11583  {
11584  i->set_user_index(x);
11585  }
11586 
11587 
11588 
11589  template <int structdim, int dim, int spacedim>
11590  void
11591  set_user_index(
11593  const unsigned int)
11594  {
11595  Assert(false, ExcInternalError());
11596  }
11597 } // namespace
11598 
11599 
11600 template <int dim, int spacedim>
11601 void
11603  std::vector<unsigned int> &v) const
11604 {
11605  v.resize(n_lines(), 0);
11606  std::vector<unsigned int>::iterator i = v.begin();
11607  line_iterator line = begin_line(), endl = end_line();
11608  for (; line != endl; ++line, ++i)
11609  *i = line->user_index();
11610 }
11611 
11612 
11613 
11614 template <int dim, int spacedim>
11615 void
11617  const std::vector<unsigned int> &v)
11618 {
11619  Assert(v.size() == n_lines(), ExcGridReadError());
11620 
11621  line_iterator line = begin_line(), endl = end_line();
11622  std::vector<unsigned int>::const_iterator i = v.begin();
11623  for (; line != endl; ++line, ++i)
11624  line->set_user_index(*i);
11625 }
11626 
11627 
11628 template <int dim, int spacedim>
11629 void
11631  std::vector<unsigned int> &v) const
11632 {
11633  v.resize(n_quads(), 0);
11634 
11635  if (dim >= 2)
11636  {
11637  std::vector<unsigned int>::iterator i = v.begin();
11638  quad_iterator quad = begin_quad(), endq = end_quad();
11639  for (; quad != endq; ++quad, ++i)
11640  *i = get_user_index(quad);
11641  }
11642 }
11643 
11644 
11645 
11646 template <int dim, int spacedim>
11647 void
11649  const std::vector<unsigned int> &v)
11650 {
11651  Assert(v.size() == n_quads(), ExcGridReadError());
11652 
11653  if (dim >= 2)
11654  {
11655  quad_iterator quad = begin_quad(), endq = end_quad();
11656  std::vector<unsigned int>::const_iterator i = v.begin();
11657  for (; quad != endq; ++quad, ++i)
11658  set_user_index(quad, *i);
11659  }
11660 }
11661 
11662 
11663 template <int dim, int spacedim>
11664 void
11666  std::vector<unsigned int> &v) const
11667 {
11668  v.resize(n_hexs(), 0);
11669 
11670  if (dim >= 3)
11671  {
11672  std::vector<unsigned int>::iterator i = v.begin();
11673  hex_iterator hex = begin_hex(), endh = end_hex();
11674  for (; hex != endh; ++hex, ++i)
11675  *i = get_user_index(hex);
11676  }
11677 }
11678 
11679 
11680 
11681 template <int dim, int spacedim>
11682 void
11684  const std::vector<unsigned int> &v)
11685 {
11686  Assert(v.size() == n_hexs(), ExcGridReadError());
11687 
11688  if (dim >= 3)
11689  {
11690  hex_iterator hex = begin_hex(), endh = end_hex();
11691  std::vector<unsigned int>::const_iterator i = v.begin();
11692  for (; hex != endh; ++hex, ++i)
11693  set_user_index(hex, *i);
11694  }
11695 }
11696 
11697 
11698 
11699 //---------------- user pointers ----------------------------------------//
11700 
11701 
11702 namespace
11703 {
11704  template <typename Iterator>
11705  void *
11706  get_user_pointer(const Iterator &i)
11707  {
11708  return i->user_pointer();
11709  }
11710 
11711 
11712 
11713  template <int structdim, int dim, int spacedim>
11714  void *
11715  get_user_pointer(
11717  {
11718  Assert(false, ExcInternalError());
11719  return nullptr;
11720  }
11721 
11722 
11723 
11724  template <typename Iterator>
11725  void
11726  set_user_pointer(const Iterator &i, void *x)
11727  {
11728  i->set_user_pointer(x);
11729  }
11730 
11731 
11732 
11733  template <int structdim, int dim, int spacedim>
11734  void
11735  set_user_pointer(
11737  void *)
11738  {
11739  Assert(false, ExcInternalError());
11740  }
11741 } // namespace
11742 
11743 
11744 template <int dim, int spacedim>
11745 void
11746 Triangulation<dim, spacedim>::save_user_pointers(std::vector<void *> &v) const
11747 {
11748  // clear vector and append all the
11749  // stuff later on
11750  v.clear();
11751 
11752  std::vector<void *> tmp;
11753 
11754  save_user_pointers_line(tmp);
11755  v.insert(v.end(), tmp.begin(), tmp.end());
11756 
11757  if (dim >= 2)
11758  {
11759  save_user_pointers_quad(tmp);
11760  v.insert(v.end(), tmp.begin(), tmp.end());
11761  }
11762 
11763  if (dim >= 3)
11764  {
11765  save_user_pointers_hex(tmp);
11766  v.insert(v.end(), tmp.begin(), tmp.end());
11767  }
11768 
11769  if (dim >= 4)
11770  Assert(false, ExcNotImplemented());
11771 }
11772 
11773 
11774 
11775 template <int dim, int spacedim>
11776 void
11777 Triangulation<dim, spacedim>::load_user_pointers(const std::vector<void *> &v)
11778 {
11779  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
11780  std::vector<void *> tmp;
11781 
11782  // first extract the pointers
11783  // belonging to lines
11784  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
11785  // and set the lines
11786  load_user_pointers_line(tmp);
11787 
11788  if (dim >= 2)
11789  {
11790  tmp.clear();
11791  tmp.insert(tmp.end(),
11792  v.begin() + n_lines(),
11793  v.begin() + n_lines() + n_quads());
11794  load_user_pointers_quad(tmp);
11795  }
11796 
11797  if (dim >= 3)
11798  {
11799  tmp.clear();
11800  tmp.insert(tmp.end(),
11801  v.begin() + n_lines() + n_quads(),
11802  v.begin() + n_lines() + n_quads() + n_hexs());
11803  load_user_pointers_hex(tmp);
11804  }
11805 
11806  if (dim >= 4)
11807  Assert(false, ExcNotImplemented());
11808 }
11809 
11810 
11811 
11812 template <int dim, int spacedim>
11813 void
11815  std::vector<void *> &v) const
11816 {
11817  v.resize(n_lines(), nullptr);
11818  std::vector<void *>::iterator i = v.begin();
11819  line_iterator line = begin_line(), endl = end_line();
11820  for (; line != endl; ++line, ++i)
11821  *i = line->user_pointer();
11822 }
11823 
11824 
11825 
11826 template <int dim, int spacedim>
11827 void
11829  const std::vector<void *> &v)
11830 {
11831  Assert(v.size() == n_lines(), ExcGridReadError());
11832 
11833  line_iterator line = begin_line(), endl = end_line();
11834  std::vector<void *>::const_iterator i = v.begin();
11835  for (; line != endl; ++line, ++i)
11836  line->set_user_pointer(*i);
11837 }
11838 
11839 
11840 
11841 template <int dim, int spacedim>
11842 void
11844  std::vector<void *> &v) const
11845 {
11846  v.resize(n_quads(), nullptr);
11847 
11848  if (dim >= 2)
11849  {
11850  std::vector<void *>::iterator i = v.begin();
11851  quad_iterator quad = begin_quad(), endq = end_quad();
11852  for (; quad != endq; ++quad, ++i)
11853  *i = get_user_pointer(quad);
11854  }
11855 }
11856 
11857 
11858 
11859 template <int dim, int spacedim>
11860 void
11862  const std::vector<void *> &v)
11863 {
11864  Assert(v.size() == n_quads(), ExcGridReadError());
11865 
11866  if (dim >= 2)
11867  {
11868  quad_iterator quad = begin_quad(), endq = end_quad();
11869  std::vector<void *>::const_iterator i = v.begin();
11870  for (; quad != endq; ++quad, ++i)
11871  set_user_pointer(quad, *i);
11872  }
11873 }
11874 
11875 
11876 template <int dim, int spacedim>
11877 void
11879  std::vector<void *> &v) const
11880 {
11881  v.resize(n_hexs(), nullptr);
11882 
11883  if (dim >= 3)
11884  {
11885  std::vector<void *>::iterator i = v.begin();
11886  hex_iterator hex = begin_hex(), endh = end_hex();
11887  for (; hex != endh; ++hex, ++i)
11888  *i = get_user_pointer(hex);
11889  }
11890 }
11891 
11892 
11893 
11894 template <int dim, int spacedim>
11895 void
11897  const std::vector<void *> &v)
11898 {
11899  Assert(v.size() == n_hexs(), ExcGridReadError());
11900 
11901  if (dim >= 3)
11902  {
11903  hex_iterator hex = begin_hex(), endh = end_hex();
11904  std::vector<void *>::const_iterator i = v.begin();
11905  for (; hex != endh; ++hex, ++i)
11906  set_user_pointer(hex, *i);
11907  }
11908 }
11909 
11910 
11911 
11912 /*------------------------ Cell iterator functions ------------------------*/
11913 
11914 
11915 template <int dim, int spacedim>
11917 Triangulation<dim, spacedim>::begin_raw(const unsigned int level) const
11918 {
11919  switch (dim)
11920  {
11921  case 1:
11922  return begin_raw_line(level);
11923  case 2:
11924  return begin_raw_quad(level);
11925  case 3:
11926  return begin_raw_hex(level);
11927  default:
11928  Assert(false, ExcNotImplemented());
11929  return raw_cell_iterator();
11930  }
11931 }
11932 
11933 
11934 
11935 template <int dim, int spacedim>
11937 Triangulation<dim, spacedim>::begin(const unsigned int level) const
11938 {
11939  switch (dim)
11940  {
11941  case 1:
11942  return begin_line(level);
11943  case 2:
11944  return begin_quad(level);
11945  case 3:
11946  return begin_hex(level);
11947  default:
11948  Assert(false, ExcImpossibleInDim(dim));
11949  return cell_iterator();
11950  }
11951 }
11952 
11953 
11954 
11955 template <int dim, int spacedim>
11957 Triangulation<dim, spacedim>::begin_active(const unsigned int level) const
11958 {
11959  switch (dim)
11960  {
11961  case 1:
11962  return begin_active_line(level);
11963  case 2:
11964  return begin_active_quad(level);
11965  case 3:
11966  return begin_active_hex(level);
11967  default:
11968  Assert(false, ExcNotImplemented());
11969  return active_cell_iterator();
11970  }
11971 }
11972 
11973 
11974 
11975 template <int dim, int spacedim>
11978 {
11979  const unsigned int level = levels.size() - 1;
11980  if (levels[level]->cells.n_objects() == 0)
11981  return end(level);
11982 
11983  // find the last raw iterator on
11984  // this level
11985  raw_cell_iterator ri(const_cast<Triangulation<dim, spacedim> *>(this),
11986  level,
11987  levels[level]->cells.n_objects() - 1);
11988 
11989  // then move to the last used one
11990  if (ri->used() == true)
11991  return ri;
11992  while ((--ri).state() == IteratorState::valid)
11993  if (ri->used() == true)
11994  return ri;
11995  return ri;
11996 }
11997 
11998 
11999 
12000 template <int dim, int spacedim>
12003 {
12004  // get the last used cell
12005  cell_iterator cell = last();
12006 
12007  if (cell != end())
12008  {
12009  // then move to the last active one
12010  if (cell->is_active() == true)
12011  return cell;
12012  while ((--cell).state() == IteratorState::valid)
12013  if (cell->is_active() == true)
12014  return cell;
12015  }
12016  return cell;
12017 }
12018 
12019 
12020 
12021 template <int dim, int spacedim>
12024 {
12025  cell_iterator cell(
12026  this, 0, coarse_cell_id_to_coarse_cell_index(cell_id.get_coarse_cell_id()));
12027 
12028  for (const auto &child_index : cell_id.get_child_indices())
12029  {
12030  Assert(
12031  cell->has_children(),
12032  ExcMessage(
12033  "CellId is invalid for this triangulation.\n"
12034  "Either the provided CellId does not correspond to a cell in this "
12035  "triangulation object, or, in case you are using a parallel "
12036  "triangulation, may correspond to an artificial cell that is less "
12037  "refined on this processor."));
12038  cell = cell->child(static_cast<unsigned int>(child_index));
12039  }
12040 
12041  return cell;
12042 }
12043 
12044 
12045 
12046 template <int dim, int spacedim>
12049 {
12050  return cell_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12051  -1,
12052  -1);
12053 }
12054 
12055 
12056 
12057 template <int dim, int spacedim>
12059 Triangulation<dim, spacedim>::end_raw(const unsigned int level) const
12060 {
12061  // This function may be called on parallel triangulations on levels
12062  // that exist globally, but not on the local portion of the
12063  // triangulation. In that case, just return the end iterator.
12064  //
12065  // We need to use levels.size() instead of n_levels() because the
12066  // latter function uses the cache, but we need to be able to call
12067  // this function at a time when the cache is not currently up to
12068  // date.
12069  if (level >= levels.size())
12070  {
12071  Assert(level < n_global_levels(),
12072  ExcInvalidLevel(level, n_global_levels()));
12073  return end();
12074  }
12075 
12076  // Query whether the given level is valid for the local portion of the
12077  // triangulation.
12078  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12079  if (level < levels.size() - 1)
12080  return begin_raw(level + 1);
12081  else
12082  return end();
12083 }
12084 
12085 
12086 template <int dim, int spacedim>
12088 Triangulation<dim, spacedim>::end(const unsigned int level) const
12089 {
12090  // This function may be called on parallel triangulations on levels
12091  // that exist globally, but not on the local portion of the
12092  // triangulation. In that case, just retrn the end iterator.
12093  //
12094  // We need to use levels.size() instead of n_levels() because the
12095  // latter function uses the cache, but we need to be able to call
12096  // this function at a time when the cache is not currently up to
12097  // date.
12098  if (level >= levels.size())
12099  {
12100  Assert(level < n_global_levels(),
12101  ExcInvalidLevel(level, n_global_levels()));
12102  return end();
12103  }
12104 
12105  // Query whether the given level is valid for the local portion of the
12106  // triangulation.
12107  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12108  if (level < levels.size() - 1)
12109  return begin(level + 1);
12110  else
12111  return end();
12112 }
12113 
12114 
12115 template <int dim, int spacedim>
12117 Triangulation<dim, spacedim>::end_active(const unsigned int level) const
12118 {
12119  // This function may be called on parallel triangulations on levels
12120  // that exist globally, but not on the local portion of the
12121  // triangulation. In that case, just return the end iterator.
12122  //
12123  // We need to use levels.size() instead of n_levels() because the
12124  // latter function uses the cache, but we need to be able to call
12125  // this function at a time when the cache is not currently up to
12126  // date.
12127  if (level >= levels.size())
12128  {
12129  Assert(level < n_global_levels(),
12130  ExcInvalidLevel(level, n_global_levels()));
12131  return end();
12132  }
12133 
12134  // Query whether the given level is valid for the local portion of the
12135  // triangulation.
12136  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12137  return (level >= levels.size() - 1 ? active_cell_iterator(end()) :
12138  begin_active(level + 1));
12139 }
12140 
12141 
12142 
12143 template <int dim, int spacedim>
12146 {
12148  begin(), end());
12149 }
12150 
12151 
12152 template <int dim, int spacedim>
12155 {
12156  return IteratorRange<
12157  typename Triangulation<dim, spacedim>::active_cell_iterator>(begin_active(),
12158  end());
12159 }
12160 
12161 
12162 
12163 template <int dim, int spacedim>
12166  const unsigned int level) const
12167 {
12169  begin(level), end(level));
12170 }
12171 
12172 
12173 
12174 template <int dim, int spacedim>
12177  const unsigned int level) const
12178 {
12179  return IteratorRange<
12181  begin_active(level), end_active(level));
12182 }
12183 
12184 
12185 /*------------------------ Face iterator functions ------------------------*/
12186 
12187 
12188 template <int dim, int spacedim>
12191 {
12192  switch (dim)
12193  {
12194  case 1:
12195  Assert(false, ExcImpossibleInDim(1));
12196  return raw_face_iterator();
12197  case 2:
12198  return begin_line();
12199  case 3:
12200  return begin_quad();
12201  default:
12202  Assert(false, ExcNotImplemented());
12203  return face_iterator();
12204  }
12205 }
12206 
12207 
12208 
12209 template <int dim, int spacedim>
12212 {
12213  switch (dim)
12214  {
12215  case 1:
12216  Assert(false, ExcImpossibleInDim(1));
12217  return raw_face_iterator();
12218  case 2:
12219  return begin_active_line();
12220  case 3:
12221  return begin_active_quad();
12222  default:
12223  Assert(false, ExcNotImplemented());
12224  return active_face_iterator();
12225  }
12226 }
12227 
12228 
12229 
12230 template <int dim, int spacedim>
12233 {
12234  switch (dim)
12235  {
12236  case 1:
12237  Assert(false, ExcImpossibleInDim(1));
12238  return raw_face_iterator();
12239  case 2:
12240  return end_line();
12241  case 3:
12242  return end_quad();
12243  default:
12244  Assert(false, ExcNotImplemented());
12245  return raw_face_iterator();
12246  }
12247 }
12248 
12249 
12250 
12251 template <int dim, int spacedim>
12254 {
12255  return IteratorRange<
12257  begin_active_face(), end_face());
12258 }
12259 
12260 /*------------------------ Vertex iterator functions ------------------------*/
12261 
12262 
12263 template <int dim, int spacedim>
12266 {
12267  vertex_iterator i =
12268  raw_vertex_iterator(const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
12269  if (i.state() != IteratorState::valid)
12270  return i;
12271  // This loop will end because every triangulation has used vertices.
12272  while (i->used() == false)
12273  if ((++i).state() != IteratorState::valid)
12274  return i;
12275  return i;
12276 }
12277 
12278 
12279 
12280 template <int dim, int spacedim>
12283 {
12284  // every vertex is active
12285  return begin_vertex();
12286 }
12287 
12288 
12289 
12290 template <int dim, int spacedim>
12293 {
12294  return raw_vertex_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12295  -1,
12297 }
12298 
12299 
12300 
12301 /*------------------------ Line iterator functions ------------------------*/
12302 
12303 
12304 
12305 template <int dim, int spacedim>
12307 Triangulation<dim, spacedim>::begin_raw_line(const unsigned int level) const
12308 {
12309  // This function may be called on parallel triangulations on levels
12310  // that exist globally, but not on the local portion of the
12311  // triangulation. In that case, just return the end iterator.
12312  //
12313  // We need to use levels.size() instead of n_levels() because the
12314  // latter function uses the cache, but we need to be able to call
12315  // this function at a time when the cache is not currently up to
12316  // date.
12317  if (level >= levels.size())
12318  {
12319  Assert(level < n_global_levels(),
12320  ExcInvalidLevel(level, n_global_levels()));
12321  return end_line();
12322  }
12323 
12324  switch (dim)
12325  {
12326  case 1:
12327  // Query whether the given level is valid for the local portion of the
12328  // triangulation.
12329  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12330 
12331  if (level >= levels.size() || levels[level]->cells.n_objects() == 0)
12332  return end_line();
12333 
12334  return raw_line_iterator(
12335  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
12336 
12337  default:
12338  Assert(level == 0, ExcFacesHaveNoLevel());
12339  return raw_line_iterator(
12340  const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
12341  }
12342 }
12343 
12344 
12345 template <int dim, int spacedim>
12347 Triangulation<dim, spacedim>::begin_line(const unsigned int level) const
12348 {
12349  // level is checked in begin_raw
12350  raw_line_iterator ri = begin_raw_line(level);
12351  if (ri.state() != IteratorState::valid)
12352  return ri;
12353  while (ri->used() == false)
12354  if ((++ri).state() != IteratorState::valid)
12355  return ri;
12356  return ri;
12357 }
12358 
12359 
12360 
12361 template <int dim, int spacedim>
12364 {
12365  // level is checked in begin_raw
12366  line_iterator i = begin_line(level);
12367  if (i.state() != IteratorState::valid)
12368  return i;
12369  while (i->has_children())
12370  if ((++i).state() != IteratorState::valid)
12371  return i;
12372  return i;
12373 }
12374 
12375 
12376 
12377 template <int dim, int spacedim>
12380 {
12381  return raw_line_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12382  -1,
12383  -1);
12384 }
12385 
12386 
12387 
12388 /*------------------------ Quad iterator functions ------------------------*/
12389 
12390 
12391 template <int dim, int spacedim>
12393 Triangulation<dim, spacedim>::begin_raw_quad(const unsigned int level) const
12394 {
12395  // This function may be called on parallel triangulations on levels
12396  // that exist globally, but not on the local portion of the
12397  // triangulation. In that case, just return the end iterator.
12398  //
12399  // We need to use levels.size() instead of n_levels() because the
12400  // latter function uses the cache, but we need to be able to call
12401  // this function at a time when the cache is not currently up to
12402  // date.
12403  if (level >= levels.size())
12404  {
12405  Assert(level < n_global_levels(),
12406  ExcInvalidLevel(level, n_global_levels()));
12407  return end_quad();
12408  }
12409 
12410  switch (dim)
12411  {
12412  case 1:
12413  Assert(false, ExcImpossibleInDim(1));
12414  return raw_hex_iterator();
12415  case 2:
12416  {
12417  // Query whether the given level is valid for the local portion of the
12418  // triangulation.
12419  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12420 
12421  if (level >= levels.size() || levels[level]->cells.n_objects() == 0)
12422  return end_quad();
12423 
12424  return raw_quad_iterator(
12425  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
12426  }
12427 
12428  case 3:
12429  {
12430  Assert(level == 0, ExcFacesHaveNoLevel());
12431 
12432  return raw_quad_iterator(
12433  const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
12434  }
12435 
12436 
12437  default:
12438  Assert(false, ExcNotImplemented());
12439  return raw_hex_iterator();
12440  }
12441 }
12442 
12443 
12444 
12445 template <int dim, int spacedim>
12447 Triangulation<dim, spacedim>::begin_quad(const unsigned int level) const
12448 {
12449  // level is checked in begin_raw
12450  raw_quad_iterator ri = begin_raw_quad(level);
12451  if (ri.state() != IteratorState::valid)
12452  return ri;
12453  while (ri->used() == false)
12454  if ((++ri).state() != IteratorState::valid)
12455  return ri;
12456  return ri;
12457 }
12458 
12459 
12460 
12461 template <int dim, int spacedim>
12464 {
12465  // level is checked in begin_raw
12466  quad_iterator i = begin_quad(level);
12467  if (i.state() != IteratorState::valid)
12468  return i;
12469  while (i->has_children())
12470  if ((++i).state() != IteratorState::valid)
12471  return i;
12472  return i;
12473 }
12474 
12475 
12476 
12477 template <int dim, int spacedim>
12480 {
12481  return raw_quad_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12482  -1,
12483  -1);
12484 }
12485 
12486 
12487 /*------------------------ Hex iterator functions ------------------------*/
12488 
12489 
12490 template <int dim, int spacedim>
12492 Triangulation<dim, spacedim>::begin_raw_hex(const unsigned int level) const
12493 {
12494  // This function may be called on parallel triangulations on levels
12495  // that exist globally, but not on the local portion of the
12496  // triangulation. In that case, just return the end iterator.
12497  //
12498  // We need to use levels.size() instead of n_levels() because the
12499  // latter function uses the cache, but we need to be able to call
12500  // this function at a time when the cache is not currently up to
12501  // date.
12502  if (level >= levels.size())
12503  {
12504  Assert(level < n_global_levels(),
12505  ExcInvalidLevel(level, n_global_levels()));
12506  return end_hex();
12507  }
12508 
12509  switch (dim)
12510  {
12511  case 1:
12512  case 2:
12513  Assert(false, ExcImpossibleInDim(1));
12514  return raw_hex_iterator();
12515  case 3:
12516  {
12517  // Query whether the given level is valid for the local portion of the
12518  // triangulation.
12519  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12520 
12521  if (level >= levels.size() || levels[level]->cells.n_objects() == 0)
12522  return end_hex();
12523 
12524  return raw_hex_iterator(
12525  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
12526  }
12527 
12528  default:
12529  Assert(false, ExcNotImplemented());
12530  return raw_hex_iterator();
12531  }
12532 }
12533 
12534 
12535 
12536 template <int dim, int spacedim>
12538 Triangulation<dim, spacedim>::begin_hex(const unsigned int level) const
12539 {
12540  // level is checked in begin_raw
12541  raw_hex_iterator ri = begin_raw_hex(level);
12542  if (ri.state() != IteratorState::valid)
12543  return ri;
12544  while (ri->used() == false)
12545  if ((++ri).state() != IteratorState::valid)
12546  return ri;
12547  return ri;
12548 }
12549 
12550 
12551 
12552 template <int dim, int spacedim>
12554 Triangulation<dim, spacedim>::begin_active_hex(const unsigned int level) const
12555 {
12556  // level is checked in begin_raw
12557  hex_iterator i = begin_hex(level);
12558  if (i.state() != IteratorState::valid)
12559  return i;
12560  while (i->has_children())
12561  if ((++i).state() != IteratorState::valid)
12562  return i;
12563  return i;
12564 }
12565 
12566 
12567 
12568 template <int dim, int spacedim>
12571 {
12572  return raw_hex_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12573  -1,
12574  -1);
12575 }
12576 
12577 
12578 
12579 // -------------------------------- number of cells etc ---------------
12580 
12581 
12582 namespace internal
12583 {
12584  namespace TriangulationImplementation
12585  {
12586  inline unsigned int
12588  {
12589  return c.n_lines;
12590  }
12591 
12592 
12593  inline unsigned int
12596  {
12597  return c.n_active_lines;
12598  }
12599 
12600 
12601  inline unsigned int
12603  {
12604  return c.n_quads;
12605  }
12606 
12607 
12608  inline unsigned int
12611  {
12612  return c.n_active_quads;
12613  }
12614 
12615 
12616  inline unsigned int
12618  {
12619  return c.n_hexes;
12620  }
12621 
12622 
12623  inline unsigned int
12626  {
12627  return c.n_active_hexes;
12628  }
12629  } // namespace TriangulationImplementation
12630 } // namespace internal
12631 
12632 
12633 
12634 template <int dim, int spacedim>
12635 unsigned int
12637 {
12639 }
12640 
12641 
12642 template <int dim, int spacedim>
12643 unsigned int
12645 {
12647 }
12648 
12649 template <int dim, int spacedim>
12652 {
12653  return n_active_cells();
12654 }
12655 
12656 
12657 
12658 template <int dim, int spacedim>
12659 unsigned int
12661 {
12662  switch (dim)
12663  {
12664  case 1:
12665  return n_used_vertices();
12666  case 2:
12667  return n_lines();
12668  case 3:
12669  return n_quads();
12670  default:
12671  Assert(false, ExcNotImplemented());
12672  }
12673  return 0;
12674 }
12675 
12676 
12677 template <int dim, int spacedim>
12678 unsigned int
12680 {
12681  switch (dim)
12682  {
12683  case 1:
12684  return n_vertices();
12685  case 2:
12686  return n_raw_lines();
12687  case 3:
12688  return n_raw_quads();
12689  default:
12690  Assert(false, ExcNotImplemented());
12691  }
12692  return 0;
12693 }
12694 
12695 
12696 template <int dim, int spacedim>
12697 unsigned int
12699 {
12700  switch (dim)
12701  {
12702  case 1:
12703  return n_used_vertices();
12704  case 2:
12705  return n_active_lines();
12706  case 3:
12707  return n_active_quads();
12708  default:
12709  Assert(false, ExcNotImplemented());
12710  }
12711  return 0;
12712 }
12713 
12714 
12715 template <int dim, int spacedim>
12716 unsigned int
12717 Triangulation<dim, spacedim>::n_raw_cells(const unsigned int level) const
12718 {
12719  switch (dim)
12720  {
12721  case 1:
12722  return n_raw_lines(level);
12723  case 2:
12724  return n_raw_quads(level);
12725  case 3:
12726  return n_raw_hexs(level);
12727  default:
12728  Assert(false, ExcNotImplemented());
12729  }
12730  return 0;
12731 }
12732 
12733 
12734 
12735 template <int dim, int spacedim>
12736 unsigned int
12737 Triangulation<dim, spacedim>::n_cells(const unsigned int level) const
12738 {
12739  switch (dim)
12740  {
12741  case 1:
12742  return n_lines(level);
12743  case 2:
12744  return n_quads(level);
12745  case 3:
12746  return n_hexs(level);
12747  default:
12748  Assert(false, ExcNotImplemented());
12749  }
12750  return 0;
12751 }
12752 
12753 
12754 
12755 template <int dim, int spacedim>
12756 unsigned int
12757 Triangulation<dim, spacedim>::n_active_cells(const unsigned int level) const
12758 {
12759  switch (dim)
12760  {
12761  case 1:
12762  return n_active_lines(level);
12763  case 2:
12764  return n_active_quads(level);
12765  case 3:
12766  return n_active_hexs(level);
12767  default:
12768  Assert(false, ExcNotImplemented());
12769  }
12770  return 0;
12771 }
12772 
12773 
12774 template <int dim, int spacedim>
12775 bool
12777 {
12778  for (unsigned int lvl = 0; lvl < n_global_levels() - 1; lvl++)
12779  if (n_active_cells(lvl) != 0)
12780  return true;
12781 
12782  return false;
12783 }
12784 
12785 
12786 template <int dim, int spacedim>
12787 unsigned int
12789 {
12790  return number_cache.n_lines;
12791 }
12792 
12793 
12794 
12795 template <int dim, int spacedim>
12796 unsigned int
12797 Triangulation<dim, spacedim>::n_raw_lines(const unsigned int level) const
12798 {
12799  if (dim == 1)
12800  {
12801  AssertIndexRange(level, n_levels());
12802  return levels[level]->cells.n_objects();
12803  }
12804 
12805  Assert(false, ExcFacesHaveNoLevel());
12806  return 0;
12807 }
12808 
12809 
12810 template <int dim, int spacedim>
12811 unsigned int
12813 {
12814  if (dim == 1)
12815  {
12816  Assert(false, ExcNotImplemented());
12817  return 0;
12818  }
12819 
12820  return faces->lines.n_objects();
12821 }
12822 
12823 
12824 template <int dim, int spacedim>
12825 unsigned int
12826 Triangulation<dim, spacedim>::n_lines(const unsigned int level) const
12827 {
12828  AssertIndexRange(level, number_cache.n_lines_level.size());
12829  Assert(dim == 1, ExcFacesHaveNoLevel());
12830  return number_cache.n_lines_level[level];
12831 }
12832 
12833 
12834 template <int dim, int spacedim>
12835 unsigned int
12837 {
12838  return number_cache.n_active_lines;
12839 }
12840 
12841 
12842 template <int dim, int spacedim>
12843 unsigned int
12844 Triangulation<dim, spacedim>::n_active_lines(const unsigned int level) const
12845 {
12846  AssertIndexRange(level, number_cache.n_lines_level.size());
12847  Assert(dim == 1, ExcFacesHaveNoLevel());
12848 
12849  return number_cache.n_active_lines_level[level];
12850 }
12851 
12852 
12853 template <>
12854 unsigned int
12856 {
12857  return 0;
12858 }
12859 
12860 
12861 template <>
12862 unsigned int
12863 Triangulation<1, 1>::n_quads(const unsigned int) const
12864 {
12865  return 0;
12866 }
12867 
12868 
12869 template <>
12870 unsigned int
12871 Triangulation<1, 1>::n_raw_quads(const unsigned int) const
12872 {
12873  return 0;
12874 }
12875 
12876 
12877 template <>
12878 unsigned int
12879 Triangulation<1, 1>::n_raw_hexs(const unsigned int) const
12880 {
12881  return 0;
12882 }
12883 
12884 
12885 template <>
12886 unsigned int
12887 Triangulation<1, 1>::n_active_quads(const unsigned int) const
12888 {
12889  return 0;
12890 }
12891 
12892 
12893 template <>
12894 unsigned int
12896 {
12897  return 0;
12898 }
12899 
12900 
12901 
12902 template <>
12903 unsigned int
12905 {
12906  return 0;
12907 }
12908 
12909 
12910 template <>
12911 unsigned int
12912 Triangulation<1, 2>::n_quads(const unsigned int) const
12913 {
12914  return 0;
12915 }
12916 
12917 
12918 template <>
12919 unsigned int
12920 Triangulation<1, 2>::n_raw_quads(const unsigned int) const
12921 {
12922  return 0;
12923 }
12924 
12925 
12926 template <>
12927 unsigned int
12928 Triangulation<1, 2>::n_raw_hexs(const unsigned int) const
12929 {
12930  return 0;
12931 }
12932 
12933 
12934 template <>
12935 unsigned int
12936 Triangulation<1, 2>::n_active_quads(const unsigned int) const
12937 {
12938  return 0;
12939 }
12940 
12941 
12942 template <>
12943 unsigned int
12945 {
12946  return 0;
12947 }
12948 
12949 
12950 template <>
12951 unsigned int
12953 {
12954  return 0;
12955 }
12956 
12957 
12958 template <>
12959 unsigned int
12960 Triangulation<1, 3>::n_quads(const unsigned int) const
12961 {
12962  return 0;
12963 }
12964 
12965 
12966 template <>
12967 unsigned int
12968 Triangulation<1, 3>::n_raw_quads(const unsigned int) const
12969 {
12970  return 0;
12971 }
12972 
12973 
12974 template <>
12975 unsigned int
12976 Triangulation<1, 3>::n_raw_hexs(const unsigned int) const
12977 {
12978  return 0;
12979 }
12980 
12981 
12982 template <>
12983 unsigned int
12984 Triangulation<1, 3>::n_active_quads(const unsigned int) const
12985 {
12986  return 0;
12987 }
12988 
12989 
12990 template <>
12991 unsigned int
12993 {
12994  return 0;
12995 }
12996 
12997 
12998 
12999 template <int dim, int spacedim>
13000 unsigned int
13002 {
13003  return number_cache.n_quads;
13004 }
13005 
13006 
13007 template <int dim, int spacedim>
13008 unsigned int
13009 Triangulation<dim, spacedim>::n_quads(const unsigned int level) const
13010 {
13011  Assert(dim == 2, ExcFacesHaveNoLevel());
13012  AssertIndexRange(level, number_cache.n_quads_level.size());
13013  return number_cache.n_quads_level[level];
13014 }
13015 
13016 
13017 
13018 template <>
13019 unsigned int
13020 Triangulation<2, 2>::n_raw_quads(const unsigned int level) const
13021 {
13022  AssertIndexRange(level, n_levels());
13023  return levels[level]->cells.n_objects();
13024 }
13025 
13026 
13027 
13028 template <>
13029 unsigned int
13030 Triangulation<2, 3>::n_raw_quads(const unsigned int level) const
13031 {
13032  AssertIndexRange(level, n_levels());
13033  return levels[level]->cells.n_objects();
13034 }
13035 
13036 
13037 template <>
13038 unsigned int
13039 Triangulation<3, 3>::n_raw_quads(const unsigned int) const
13040 {
13041  Assert(false, ExcFacesHaveNoLevel());
13042  return 0;
13043 }
13044 
13045 
13046 
13047 template <int dim, int spacedim>
13048 unsigned int
13050 {
13051  Assert(false, ExcNotImplemented());
13052  return 0;
13053 }
13054 
13055 
13056 
13057 template <>
13058 unsigned int
13060 {
13061  return faces->quads.n_objects();
13062 }
13063 
13064 
13065 
13066 template <int dim, int spacedim>
13067 unsigned int
13069 {
13070  return number_cache.n_active_quads;
13071 }
13072 
13073 
13074 template <int dim, int spacedim>
13075 unsigned int
13076 Triangulation<dim, spacedim>::n_active_quads(const unsigned int level) const
13077 {
13078  AssertIndexRange(level, number_cache.n_quads_level.size());
13079  Assert(dim == 2, ExcFacesHaveNoLevel());
13080 
13081  return number_cache.n_active_quads_level[level];
13082 }
13083 
13084 
13085 template <int dim, int spacedim>
13086 unsigned int
13088 {
13089  return 0;
13090 }
13091 
13092 
13093 
13094 template <int dim, int spacedim>
13095 unsigned int
13096 Triangulation<dim, spacedim>::n_hexs(const unsigned int) const
13097 {
13098  return 0;
13099 }
13100 
13101 
13102 
13103 template <int dim, int spacedim>
13104 unsigned int
13105 Triangulation<dim, spacedim>::n_raw_hexs(const unsigned int) const
13106 {
13107  return 0;
13108 }
13109 
13110 
13111 template <int dim, int spacedim>
13112 unsigned int
13114 {
13115  return 0;
13116 }
13117 
13118 
13119 
13120 template <int dim, int spacedim>
13121 unsigned int
13122 Triangulation<dim, spacedim>::n_active_hexs(const unsigned int) const
13123 {
13124  return 0;
13125 }
13126 
13127 
13128 template <>
13129 unsigned int
13131 {
13132  return number_cache.n_hexes;
13133 }
13134 
13135 
13136 
13137 template <>
13138 unsigned int
13139 Triangulation<3, 3>::n_hexs(const unsigned int level) const
13140 {
13141  AssertIndexRange(level, number_cache.n_hexes_level.size());
13142 
13143  return number_cache.n_hexes_level[level];
13144 }
13145 
13146 
13147 
13148 template <>
13149 unsigned int
13150 Triangulation<3, 3>::n_raw_hexs(const unsigned int level) const
13151 {
13152  AssertIndexRange(level, n_levels());
13153  return levels[level]->cells.n_objects();
13154 }
13155 
13156 
13157 template <>
13158 unsigned int
13160 {
13161  return number_cache.n_active_hexes;
13162 }
13163 
13164 
13165 
13166 template <>
13167 unsigned int
13169 {
13170  AssertIndexRange(level, number_cache.n_hexes_level.size());
13171 
13172  return number_cache.n_active_hexes_level[level];
13173 }
13174 
13175 
13176 
13177 template <int dim, int spacedim>
13178 unsigned int
13180 {
13181  return std::count(vertices_used.begin(), vertices_used.end(), true);
13182 }
13183 
13184 
13185 
13186 template <int dim, int spacedim>
13187 const std::vector<bool> &
13189 {
13190  return vertices_used;
13191 }
13192 
13193 
13194 
13195 template <>
13196 unsigned int
13198 {
13199  return 2;
13200 }
13201 
13202 
13203 
13204 template <>
13205 unsigned int
13207 {
13208  return 2;
13209 }
13210 
13211 
13212 template <>
13213 unsigned int
13215 {
13216  return 2;
13217 }
13218 
13219 
13220 template <int dim, int spacedim>
13221 unsigned int
13223 {
13224  cell_iterator cell = begin(0),
13225  endc = (n_levels() > 1 ? begin(1) : cell_iterator(end()));
13226  // store the largest index of the
13227  // vertices used on level 0
13228  unsigned int max_vertex_index = 0;
13229  for (; cell != endc; ++cell)
13230  for (const unsigned int vertex : GeometryInfo<dim>::vertex_indices())
13231  if (cell->vertex_index(vertex) > max_vertex_index)
13232  max_vertex_index = cell->vertex_index(vertex);
13233 
13234  // store the number of times a cell
13235  // touches a vertex. An unsigned
13236  // int should suffice, even for
13237  // larger dimensions
13238  std::vector<unsigned short int> usage_count(max_vertex_index + 1, 0);
13239  // touch a vertex's usage count
13240  // every time we find an adjacent
13241  // element
13242  for (cell = begin(); cell != endc; ++cell)
13243  for (const unsigned int vertex : GeometryInfo<dim>::vertex_indices())
13244  ++usage_count[cell->vertex_index(vertex)];
13245 
13247  static_cast<unsigned int>(
13248  *std::max_element(usage_count.begin(), usage_count.end())));
13249 }
13250 
13251 
13252 
13253 template <int dim, int spacedim>
13256 {
13258 }
13259 
13260 
13261 
13262 template <int dim, int spacedim>
13265 {
13266  return *this;
13267 }
13268 
13269 
13270 
13271 template <int dim, int spacedim>
13274 {
13275  return *this;
13276 }
13277 
13278 
13279 
13280 template <int dim, int spacedim>
13281 void
13284  &periodicity_vector)
13285 {
13286  periodic_face_pairs_level_0.insert(periodic_face_pairs_level_0.end(),
13287  periodicity_vector.begin(),
13288  periodicity_vector.end());
13289 
13290  // Now initialize periodic_face_map
13291  update_periodic_face_map();
13292 }
13293 
13294 
13295 
13296 template <int dim, int spacedim>
13297 const typename std::map<
13298  std::pair<typename Triangulation<dim, spacedim>::cell_iterator, unsigned int>,
13299  std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
13300  unsigned int>,
13301  std::bitset<3>>> &
13303 {
13304  return periodic_face_map;
13305 }
13306 
13307 
13308 
13309 template <int dim, int spacedim>
13310 void
13312 {
13313  // Call our version of prepare_coarsening_and_refinement() even if a derived
13314  // class like parallel::distributed::Triangulation overrides it. Their
13315  // function will be called in their execute_coarsening_and_refinement()
13316  // function. Even in a distributed computation our job here is to reconstruct
13317  // the local part of the mesh and as such checking our flags is enough.
13319 
13320  // verify a case with which we have had
13321  // some difficulty in the past (see the
13322  // deal.II/coarsening_* tests)
13323  if (smooth_grid & limit_level_difference_at_vertices)
13324  Assert(satisfies_level1_at_vertex_rule(*this) == true, ExcInternalError());
13325 
13326  // Inform all listeners about beginning of refinement.
13327  signals.pre_refinement();
13328 
13329  execute_coarsening();
13330 
13331  const DistortedCellList cells_with_distorted_children = execute_refinement();
13332 
13333  reset_cell_vertex_indices_cache();
13334 
13335  // verify a case with which we have had
13336  // some difficulty in the past (see the
13337  // deal.II/coarsening_* tests)
13338  if (smooth_grid & limit_level_difference_at_vertices)
13339  Assert(satisfies_level1_at_vertex_rule(*this) == true, ExcInternalError());
13340 
13341  // finally build up neighbor connectivity information, and set
13342  // active cell indices
13343  this->policy->update_neighbors(*this);
13344  reset_active_cell_indices();
13345 
13346  reset_global_cell_indices(); // TODO: better place?
13347 
13348  // Inform all listeners about end of refinement.
13349  signals.post_refinement();
13350 
13351  AssertThrow(cells_with_distorted_children.distorted_cells.size() == 0,
13352  cells_with_distorted_children);
13353 
13354  update_periodic_face_map();
13355 }
13356 
13357 
13358 
13359 template <int dim, int spacedim>
13360 void
13362 {
13363  unsigned int active_cell_index = 0;
13364  for (raw_cell_iterator cell = begin_raw(); cell != end(); ++cell)
13365  if ((cell->used() == false) || cell->has_children())
13366  cell->set_active_cell_index(numbers::invalid_unsigned_int);
13367  else
13368  {
13369  cell->set_active_cell_index(active_cell_index);
13370  ++active_cell_index;
13371  }
13372 
13373  Assert(active_cell_index == n_active_cells(), ExcInternalError());
13374 }
13375 
13376 
13377 
13378 template <int dim, int spacedim>
13379 void
13381 {
13382  {
13384  for (const auto &cell : active_cell_iterators())
13385  cell->set_global_active_cell_index(cell_index++);
13386  }
13387 
13388  for (unsigned int l = 0; l < levels.size(); ++l)
13389  {
13391  for (const auto &cell : cell_iterators_on_level(l))
13392  cell->set_global_level_cell_index(cell_index++);
13393  }
13394 }
13395 
13396 
13397 
13398 template <int dim, int spacedim>
13399 void
13401 {
13402  for (unsigned int l = 0; l < levels.size(); ++l)
13403  {
13404  constexpr unsigned int max_vertices_per_cell = 1 << dim;
13405  std::vector<unsigned int> &cache = levels[l]->cell_vertex_indices_cache;
13406  cache.clear();
13407  cache.resize(levels[l]->refine_flags.size() * max_vertices_per_cell,
13409  for (const auto &cell : cell_iterators_on_level(l))
13410  {
13411  const unsigned int my_index = cell->index() * max_vertices_per_cell;
13412  for (const unsigned int i : cell->vertex_indices())
13413  cache[my_index + i] = internal::TriaAccessorImplementation::
13414  Implementation::vertex_index(*cell, i);
13415  }
13416  }
13417 }
13418 
13419 
13420 
13421 template <int dim, int spacedim>
13422 void
13424 {
13425  // first empty the currently stored objects
13426  periodic_face_map.clear();
13427 
13428  typename std::vector<
13429  GridTools::PeriodicFacePair<cell_iterator>>::const_iterator it;
13430  for (it = periodic_face_pairs_level_0.begin();
13431  it != periodic_face_pairs_level_0.end();
13432  ++it)
13433  {
13434  update_periodic_face_map_recursively<dim, spacedim>(it->cell[0],
13435  it->cell[1],
13436  it->face_idx[0],
13437  it->face_idx[1],
13438  it->orientation,
13439  periodic_face_map);
13440 
13441  // for the other way, we need to invert the orientation
13442  std::bitset<3> inverted_orientation;
13443  {
13444  bool orientation, flip, rotation;
13445  orientation = it->orientation[0];
13446  rotation = it->orientation[2];
13447  flip = orientation ? rotation ^ it->orientation[1] : it->orientation[1];
13448  inverted_orientation[0] = orientation;
13449  inverted_orientation[1] = flip;
13450  inverted_orientation[2] = rotation;
13451  }
13452  update_periodic_face_map_recursively<dim, spacedim>(it->cell[1],
13453  it->cell[0],
13454  it->face_idx[1],
13455  it->face_idx[0],
13456  inverted_orientation,
13457  periodic_face_map);
13458  }
13459 
13460  // check consistency
13461  typename std::map<std::pair<cell_iterator, unsigned int>,
13462  std::pair<std::pair<cell_iterator, unsigned int>,
13463  std::bitset<3>>>::const_iterator it_test;
13464  for (it_test = periodic_face_map.begin(); it_test != periodic_face_map.end();
13465  ++it_test)
13466  {
13468  it_test->first.first;
13470  it_test->second.first.first;
13471  if (cell_1->level() == cell_2->level())
13472  {
13473  // if both cells have the same neighbor, then the same pair
13474  // order swapped has to be in the map
13475  Assert(periodic_face_map[it_test->second.first].first ==
13476  it_test->first,
13477  ExcInternalError());
13478  }
13479  }
13480 }
13481 
13482 
13483 
13484 template <int dim, int spacedim>
13485 void
13487 {
13488  std::set<ReferenceCell> reference_cells_set;
13489  for (auto cell : active_cell_iterators())
13490  if (cell->is_locally_owned())
13491  reference_cells_set.insert(cell->reference_cell());
13492 
13493  std::vector<ReferenceCell> reference_cells(reference_cells_set.begin(),
13494  reference_cells_set.end());
13495 
13496  this->reference_cells = reference_cells;
13497 }
13498 
13499 
13500 
13501 template <int dim, int spacedim>
13502 const std::vector<ReferenceCell> &
13504 {
13505  return this->reference_cells;
13506 }
13507 
13508 
13509 
13510 template <int dim, int spacedim>
13511 bool
13513 {
13514  Assert(this->reference_cells.size() > 0,
13515  ExcMessage("You can't ask about the kinds of reference "
13516  "cells used by this triangulation if the "
13517  "triangulation doesn't yet have any cells in it."));
13518  return (this->reference_cells.size() == 1 &&
13519  this->reference_cells[0] == ReferenceCells::get_hypercube<dim>());
13520 }
13521 
13522 
13523 
13524 template <int dim, int spacedim>
13525 void
13527 {
13528  levels.clear();
13529  faces.reset();
13530 
13531  vertices.clear();
13532  vertices_used.clear();
13533 
13534  manifold.clear();
13535 
13537 }
13538 
13539 
13540 
13541 template <int dim, int spacedim>
13544 {
13545  const DistortedCellList cells_with_distorted_children =
13546  this->policy->execute_refinement(*this, check_for_distorted_cells);
13547 
13548 
13549 
13550  // re-compute number of lines
13552  *this, levels.size(), number_cache);
13553 
13554 #ifdef DEBUG
13555  for (const auto &level : levels)
13556  monitor_memory(level->cells, dim);
13557 
13558  // check whether really all refinement flags are reset (also of
13559  // previously non-active cells which we may not have touched. If the
13560  // refinement flag of a non-active cell is set, something went wrong
13561  // since the cell-accessors should have caught this)
13562  for (const auto &cell : this->cell_iterators())
13563  Assert(!cell->refine_flag_set(), ExcInternalError());
13564 #endif
13565 
13566  return cells_with_distorted_children;
13567 }
13568 
13569 
13570 
13571 template <int dim, int spacedim>
13572 void
13574 {
13575  // create a vector counting for each line how many cells contain
13576  // this line. in 3D, this is used later on to decide which lines can
13577  // be deleted after coarsening a cell. in other dimensions it will
13578  // be ignored
13579  std::vector<unsigned int> line_cell_count =
13580  count_cells_bounded_by_line(*this);
13581  std::vector<unsigned int> quad_cell_count =
13582  count_cells_bounded_by_quad(*this);
13583 
13584  // loop over all cells. Flag all cells of which all children are
13585  // flagged for coarsening and delete the childrens' flags. In
13586  // effect, only those cells are flagged of which originally all
13587  // children were flagged and for which all children are on the same
13588  // refinement level. For flagging, the user flags are used, to avoid
13589  // confusion and because non-active cells can't be flagged for
13590  // coarsening. Note that because of the effects of
13591  // @p{fix_coarsen_flags}, of a cell either all or no children must
13592  // be flagged for coarsening, so it is ok to only check the first
13593  // child
13594  clear_user_flags();
13595 
13596  for (const auto &cell : this->cell_iterators())
13597  if (!cell->is_active())
13598  if (cell->child(0)->coarsen_flag_set())
13599  {
13600  cell->set_user_flag();
13601  for (unsigned int child = 0; child < cell->n_children(); ++child)
13602  {
13603  Assert(cell->child(child)->coarsen_flag_set(),
13604  ExcInternalError());
13605  cell->child(child)->clear_coarsen_flag();
13606  }
13607  }
13608 
13609 
13610  // now do the actual coarsening step. Since the loop goes over used
13611  // cells we only need not worry about deleting some cells since the
13612  // ++operator will then just hop over them if we should hit one. Do
13613  // the loop in the reverse way since we may only delete some cells
13614  // if their neighbors have already been deleted (if the latter are
13615  // on a higher level for example)
13616  //
13617  // since we delete the *children* of cells, we can ignore cells
13618  // on the highest level, i.e., level must be less than or equal
13619  // to n_levels()-2.
13620  cell_iterator cell = begin(), endc = end();
13621  if (levels.size() >= 2)
13622  for (cell = last(); cell != endc; --cell)
13623  if (cell->level() <= static_cast<int>(levels.size() - 2) &&
13624  cell->user_flag_set())
13625  {
13626  // inform all listeners that cell coarsening is going to happen
13627  signals.pre_coarsening_on_cell(cell);
13628  // use a separate function, since this is dimension specific
13629  this->policy->delete_children(*this,
13630  cell,
13631  line_cell_count,
13632  quad_cell_count);
13633  }
13634 
13635  // re-compute number of lines and quads
13637  *this, levels.size(), number_cache);
13638 
13639  // in principle no user flags should be set any more at this point
13640 #if DEBUG
13641  for (cell = begin(); cell != endc; ++cell)
13642  Assert(cell->user_flag_set() == false, ExcInternalError());
13643 #endif
13644 }
13645 
13646 
13647 
13648 template <int dim, int spacedim>
13649 void
13651 {
13652  // copy a piece of code from prepare_coarsening_and_refinement that
13653  // ensures that the level difference at vertices is limited if so
13654  // desired. we need this code here since at least in 1d we don't
13655  // call the dimension-independent version of
13656  // prepare_coarsening_and_refinement function. in 2d and 3d, having
13657  // this hunk here makes our lives a bit easier as well as it takes
13658  // care of these cases earlier than it would otherwise happen.
13659  //
13660  // the main difference to the code in p_c_and_r is that here we
13661  // absolutely have to make sure that we get things right, i.e. that
13662  // in particular we set flags right if
13663  // limit_level_difference_at_vertices is set. to do so we iterate
13664  // until the flags don't change any more
13665  std::vector<bool> previous_coarsen_flags(n_active_cells());
13666  save_coarsen_flags(previous_coarsen_flags);
13667 
13668  std::vector<int> vertex_level(vertices.size(), 0);
13669 
13670  bool continue_iterating = true;
13671 
13672  do
13673  {
13674  if (smooth_grid & limit_level_difference_at_vertices)
13675  {
13676  Assert(!anisotropic_refinement,
13677  ExcMessage("In case of anisotropic refinement the "
13678  "limit_level_difference_at_vertices flag for "
13679  "mesh smoothing must not be set!"));
13680 
13681  // store highest level one of the cells adjacent to a vertex
13682  // belongs to
13683  std::fill(vertex_level.begin(), vertex_level.end(), 0);
13684  for (const auto &cell : this->active_cell_iterators())
13685  {
13686  if (cell->refine_flag_set())
13687  for (const unsigned int vertex :
13689  vertex_level[cell->vertex_index(vertex)] =
13690  std::max(vertex_level[cell->vertex_index(vertex)],
13691  cell->level() + 1);
13692  else if (!cell->coarsen_flag_set())
13693  for (const unsigned int vertex :
13695  vertex_level[cell->vertex_index(vertex)] =
13696  std::max(vertex_level[cell->vertex_index(vertex)],
13697  cell->level());
13698  else
13699  {
13700  // if coarsen flag is set then tentatively assume
13701  // that the cell will be coarsened. this isn't
13702  // always true (the coarsen flag could be removed
13703  // again) and so we may make an error here. we try
13704  // to correct this by iterating over the entire
13705  // process until we are converged
13706  Assert(cell->coarsen_flag_set(), ExcInternalError());
13707  for (const unsigned int vertex :
13709  vertex_level[cell->vertex_index(vertex)] =
13710  std::max(vertex_level[cell->vertex_index(vertex)],
13711  cell->level() - 1);
13712  }
13713  }
13714 
13715 
13716  // loop over all cells in reverse order. do so because we
13717  // can then update the vertex levels on the adjacent
13718  // vertices and maybe already flag additional cells in this
13719  // loop
13720  //
13721  // note that not only may we have to add additional
13722  // refinement flags, but we will also have to remove
13723  // coarsening flags on cells adjacent to vertices that will
13724  // see refinement
13725  active_cell_iterator cell = begin_active(), endc = end();
13726  for (cell = last_active(); cell != endc; --cell)
13727  if (cell->refine_flag_set() == false)
13728  {
13729  for (const unsigned int vertex :
13731  if (vertex_level[cell->vertex_index(vertex)] >=
13732  cell->level() + 1)
13733  {
13734  // remove coarsen flag...
13735  cell->clear_coarsen_flag();
13736 
13737  // ...and if necessary also refine the current
13738  // cell, at the same time updating the level
13739  // information about vertices
13740  if (vertex_level[cell->vertex_index(vertex)] >
13741  cell->level() + 1)
13742  {
13743  cell->set_refine_flag();
13744 
13745  for (const unsigned int v :
13747  vertex_level[cell->vertex_index(v)] =
13748  std::max(vertex_level[cell->vertex_index(v)],
13749  cell->level() + 1);
13750  }
13751 
13752  // continue and see whether we may, for example,
13753  // go into the inner 'if' above based on a
13754  // different vertex
13755  }
13756  }
13757  }
13758 
13759  // loop over all cells. Flag all cells of which all children are
13760  // flagged for coarsening and delete the childrens' flags. Also
13761  // delete all flags of cells for which not all children of a
13762  // cell are flagged. In effect, only those cells are flagged of
13763  // which originally all children were flagged and for which all
13764  // children are on the same refinement level. For flagging, the
13765  // user flags are used, to avoid confusion and because
13766  // non-active cells can't be flagged for coarsening
13767  //
13768  // In effect, all coarsen flags are turned into user flags of
13769  // the mother cell if coarsening is possible or deleted
13770  // otherwise.
13771  clear_user_flags();
13772  // Coarsen flags of cells with no mother cell, i.e. on the
13773  // coarsest level are deleted explicitly.
13774  for (const auto &acell : this->active_cell_iterators_on_level(0))
13775  acell->clear_coarsen_flag();
13776 
13777  for (const auto &cell : this->cell_iterators())
13778  {
13779  // nothing to do if we are already on the finest level
13780  if (cell->is_active())
13781  continue;
13782 
13783  const unsigned int n_children = cell->n_children();
13784  unsigned int flagged_children = 0;
13785  for (unsigned int child = 0; child < n_children; ++child)
13786  if (cell->child(child)->is_active() &&
13787  cell->child(child)->coarsen_flag_set())
13788  {
13789  ++flagged_children;
13790  // clear flag since we don't need it anymore
13791  cell->child(child)->clear_coarsen_flag();
13792  }
13793 
13794  // flag this cell for coarsening if all children were
13795  // flagged
13796  if (flagged_children == n_children)
13797  cell->set_user_flag();
13798  }
13799 
13800  // in principle no coarsen flags should be set any more at this
13801  // point
13802 #if DEBUG
13803  for (auto &cell : this->cell_iterators())
13804  Assert(cell->coarsen_flag_set() == false, ExcInternalError());
13805 #endif
13806 
13807  // now loop over all cells which have the user flag set. their
13808  // children were flagged for coarsening. set the coarsen flag
13809  // again if we are sure that none of the neighbors of these
13810  // children are refined, or will be refined, since then we would
13811  // get a two-level jump in refinement. on the other hand, if one
13812  // of the children's neighbors has their user flag set, then we
13813  // know that its children will go away by coarsening, and we
13814  // will be ok.
13815  //
13816  // note on the other hand that we do allow level-2 jumps in
13817  // refinement between neighbors in 1d, so this whole procedure
13818  // is only necessary if we are not in 1d
13819  //
13820  // since we remove some coarsening/user flags in the process, we
13821  // have to work from the finest level to the coarsest one, since
13822  // we occasionally inspect user flags of cells on finer levels
13823  // and need to be sure that these flags are final
13824  cell_iterator cell = begin(), endc = end();
13825  for (cell = last(); cell != endc; --cell)
13826  if (cell->user_flag_set())
13827  // if allowed: flag the
13828  // children for coarsening
13829  if (this->policy->coarsening_allowed(cell))
13830  for (unsigned int c = 0; c < cell->n_children(); ++c)
13831  {
13832  Assert(cell->child(c)->refine_flag_set() == false,
13833  ExcInternalError());
13834 
13835  cell->child(c)->set_coarsen_flag();
13836  }
13837 
13838  // clear all user flags again, now that we don't need them any
13839  // more
13840  clear_user_flags();
13841 
13842 
13843  // now see if anything has changed in the last iteration of this
13844  // function
13845  std::vector<bool> current_coarsen_flags(n_active_cells());
13846  save_coarsen_flags(current_coarsen_flags);
13847 
13848  continue_iterating = (current_coarsen_flags != previous_coarsen_flags);
13849  previous_coarsen_flags = current_coarsen_flags;
13850  }
13851  while (continue_iterating == true);
13852 }
13853 
13854 
13855 // TODO: merge the following 3 functions since they are the same
13856 template <>
13857 bool
13859 {
13860  // save the flags to determine whether something was changed in the
13861  // course of this function
13862  std::vector<bool> flags_before;
13863  save_coarsen_flags(flags_before);
13864 
13865  // do nothing in 1d, except setting the coarsening flags correctly
13866  fix_coarsen_flags();
13867 
13868  std::vector<bool> flags_after;
13869  save_coarsen_flags(flags_after);
13870 
13871  return (flags_before != flags_after);
13872 }
13873 
13874 
13875 template <>
13876 bool
13878 {
13879  // save the flags to determine whether something was changed in the
13880  // course of this function
13881  std::vector<bool> flags_before;
13882  save_coarsen_flags(flags_before);
13883 
13884  // do nothing in 1d, except setting the coarsening flags correctly
13885  fix_coarsen_flags();
13886 
13887  std::vector<bool> flags_after;
13888  save_coarsen_flags(flags_after);
13889 
13890  return (flags_before != flags_after);
13891 }
13892 
13893 
13894 template <>
13895 bool
13897 {
13898  // save the flags to determine whether something was changed in the
13899  // course of this function
13900  std::vector<bool> flags_before;
13901  save_coarsen_flags(flags_before);
13902 
13903  // do nothing in 1d, except setting the coarsening flags correctly
13904  fix_coarsen_flags();
13905 
13906  std::vector<bool> flags_after;
13907  save_coarsen_flags(flags_after);
13908 
13909  return (flags_before != flags_after);
13910 }
13911 
13912 
13913 
13914 namespace
13915 {
13916  // check if the given @param cell marked for coarsening would
13917  // produce an unrefined island. To break up long chains of these
13918  // cells we recursively check our neighbors in case we change this
13919  // cell. This reduces the number of outer iterations dramatically.
13920  template <int dim, int spacedim>
13921  void
13922  possibly_do_not_produce_unrefined_islands(
13923  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
13924  {
13925  Assert(cell->has_children(), ExcInternalError());
13926 
13927  unsigned int n_neighbors = 0;
13928  // count all neighbors that will be refined along the face of our
13929  // cell after the next step
13930  unsigned int count = 0;
13931  for (unsigned int n : GeometryInfo<dim>::face_indices())
13932  {
13933  const typename Triangulation<dim, spacedim>::cell_iterator neighbor =
13934  cell->neighbor(n);
13935  if (neighbor.state() == IteratorState::valid)
13936  {
13937  ++n_neighbors;
13938  if (face_will_be_refined_by_neighbor(cell, n))
13939  ++count;
13940  }
13941  }
13942  // clear coarsen flags if either all existing neighbors will be
13943  // refined or all but one will be and the cell is in the interior
13944  // of the domain
13945  if (count == n_neighbors ||
13946  (count >= n_neighbors - 1 &&
13947  n_neighbors == GeometryInfo<dim>::faces_per_cell))
13948  {
13949  for (unsigned int c = 0; c < cell->n_children(); ++c)
13950  cell->child(c)->clear_coarsen_flag();
13951 
13952  for (const unsigned int face : GeometryInfo<dim>::face_indices())
13953  if (!cell->at_boundary(face) &&
13954  (!cell->neighbor(face)->is_active()) &&
13955  (cell_will_be_coarsened(cell->neighbor(face))))
13956  possibly_do_not_produce_unrefined_islands<dim, spacedim>(
13957  cell->neighbor(face));
13958  }
13959  }
13960 
13961 
13962  // see if the current cell needs to be refined to avoid unrefined
13963  // islands.
13964  //
13965  // there are sometimes chains of cells that induce refinement of
13966  // each other. to avoid running the loop in
13967  // prepare_coarsening_and_refinement over and over again for each
13968  // one of them, at least for the isotropic refinement case we seek
13969  // to flag neighboring elements as well as necessary. this takes
13970  // care of (slightly pathological) cases like
13971  // deal.II/mesh_smoothing_03
13972  template <int dim, int spacedim>
13973  void
13974  possibly_refine_unrefined_island(
13975  const typename Triangulation<dim, spacedim>::cell_iterator &cell,
13976  const bool allow_anisotropic_smoothing)
13977  {
13978  Assert(cell->is_active(), ExcInternalError());
13979  Assert(cell->refine_flag_set() == false, ExcInternalError());
13980 
13981 
13982  // now we provide two algorithms. the first one is the standard
13983  // one, coming from the time, where only isotropic refinement was
13984  // possible. it simply counts the neighbors that are or will be
13985  // refined and compares to the number of other ones. the second
13986  // one does this check independently for each direction: if all
13987  // neighbors in one direction (normally two, at the boundary only
13988  // one) are refined, the current cell is flagged to be refined in
13989  // an according direction.
13990 
13991  if (allow_anisotropic_smoothing == false)
13992  {
13993  // use first algorithm
13994  unsigned int refined_neighbors = 0, unrefined_neighbors = 0;
13995  for (const unsigned int face : GeometryInfo<dim>::face_indices())
13996  if (!cell->at_boundary(face))
13997  {
13998  if (face_will_be_refined_by_neighbor(cell, face))
13999  ++refined_neighbors;
14000  else
14001  ++unrefined_neighbors;
14002  }
14003 
14004  if (unrefined_neighbors < refined_neighbors)
14005  {
14006  cell->clear_coarsen_flag();
14007  cell->set_refine_flag();
14008 
14009  // ok, so now we have flagged this cell. if we know that
14010  // there were any unrefined neighbors at all, see if any
14011  // of those will have to be refined as well
14012  if (unrefined_neighbors > 0)
14013  for (const unsigned int face : GeometryInfo<dim>::face_indices())
14014  if (!cell->at_boundary(face) &&
14015  (face_will_be_refined_by_neighbor(cell, face) == false) &&
14016  (cell->neighbor(face)->has_children() == false) &&
14017  (cell->neighbor(face)->refine_flag_set() == false))
14018  possibly_refine_unrefined_island<dim, spacedim>(
14019  cell->neighbor(face), allow_anisotropic_smoothing);
14020  }
14021  }
14022  else
14023  {
14024  // variable to store the cell refine case needed to fulfill
14025  // all smoothing requirements
14026  RefinementCase<dim> smoothing_cell_refinement_case =
14028 
14029  // use second algorithm, do the check individually for each
14030  // direction
14031  for (unsigned int face_pair = 0;
14032  face_pair < GeometryInfo<dim>::faces_per_cell / 2;
14033  ++face_pair)
14034  {
14035  // variable to store the cell refine case needed to refine
14036  // at the current face pair in the same way as the
14037  // neighbors do...
14038  RefinementCase<dim> directional_cell_refinement_case =
14040 
14041  for (unsigned int face_index = 0; face_index < 2; ++face_index)
14042  {
14043  unsigned int face = 2 * face_pair + face_index;
14044  // variable to store the refine case (to come) of the
14045  // face under consideration
14046  RefinementCase<dim - 1> expected_face_ref_case =
14047  RefinementCase<dim - 1>::no_refinement;
14048 
14049  if (cell->neighbor(face).state() == IteratorState::valid)
14050  face_will_be_refined_by_neighbor<dim, spacedim>(
14051  cell, face, expected_face_ref_case);
14052  // now extract which refine case would be necessary to
14053  // achieve the same face refinement. set the
14054  // intersection with other requirements for the same
14055  // direction.
14056 
14057  // note: using the intersection is not an obvious
14058  // decision, we could also argue that it is more
14059  // natural to use the union. however, intersection is
14060  // the less aggressive tactic and favours a smaller
14061  // number of refined cells over an intensive
14062  // smoothing. this way we try not to lose too much of
14063  // the effort we put in anisotropic refinement
14064  // indicators due to overly aggressive smoothing...
14065  directional_cell_refinement_case =
14066  (directional_cell_refinement_case &
14069  expected_face_ref_case,
14070  face,
14071  cell->face_orientation(face),
14072  cell->face_flip(face),
14073  cell->face_rotation(face)));
14074  } // for both face indices
14075  // if both requirements sum up to something useful, add
14076  // this to the refine case for smoothing. note: if
14077  // directional_cell_refinement_case is isotropic still,
14078  // then something went wrong...
14079  Assert(directional_cell_refinement_case <
14081  ExcInternalError());
14082  smoothing_cell_refinement_case =
14083  smoothing_cell_refinement_case | directional_cell_refinement_case;
14084  } // for all face_pairs
14085  // no we collected contributions from all directions. combine
14086  // the new flags with the existing refine case, but only if
14087  // smoothing is required
14088  if (smoothing_cell_refinement_case)
14089  {
14090  cell->clear_coarsen_flag();
14091  cell->set_refine_flag(cell->refine_flag_set() |
14092  smoothing_cell_refinement_case);
14093  }
14094  }
14095  }
14096 } // namespace
14097 
14098 
14099 template <int dim, int spacedim>
14100 bool
14102 {
14103  // save the flags to determine whether something was changed in the
14104  // course of this function
14105  std::vector<bool> flags_before[2];
14106  save_coarsen_flags(flags_before[0]);
14107  save_refine_flags(flags_before[1]);
14108 
14109  // save the flags at the outset of each loop. we do so in order to
14110  // find out whether something was changed in the present loop, in
14111  // which case we would have to re-run the loop. the other
14112  // possibility to find this out would be to set a flag
14113  // @p{something_changed} to true each time we change something.
14114  // however, sometimes one change in one of the parts of the loop is
14115  // undone by another one, so we might end up in an endless loop. we
14116  // could be tempted to break this loop at an arbitrary number of
14117  // runs, but that would not be a clean solution, since we would
14118  // either have to 1/ break the loop too early, in which case the
14119  // promise that a second call to this function immediately after the
14120  // first one does not change anything, would be broken, or 2/ we do
14121  // as many loops as there are levels. we know that information is
14122  // transported over one level in each run of the loop, so this is
14123  // enough. Unfortunately, each loop is rather expensive, so we chose
14124  // the way presented here
14125  std::vector<bool> flags_before_loop[2] = {flags_before[0], flags_before[1]};
14126 
14127  // now for what is done in each loop: we have to fulfill several
14128  // tasks at the same time, namely several mesh smoothing algorithms
14129  // and mesh regularization, by which we mean that the next mesh
14130  // fulfills several requirements such as no double refinement at
14131  // each face or line, etc.
14132  //
14133  // since doing these things at once seems almost impossible (in the
14134  // first year of this library, they were done in two functions, one
14135  // for refinement and one for coarsening, and most things within
14136  // these were done at once, so the code was rather impossible to
14137  // join into this, only, function), we do them one after each
14138  // other. the order in which we do them is such that the important
14139  // tasks, namely regularization, are done last and the least
14140  // important things are done the first. the following order is
14141  // chosen:
14142  //
14143  // 0/ Only if coarsest_level_1 or patch_level_1 is set: clear all
14144  // coarsen flags on level 1 to avoid level 0 cells being created
14145  // by coarsening. As coarsen flags will never be added, this can
14146  // be done once and for all before the actual loop starts.
14147  //
14148  // 1/ do not coarsen a cell if 'most of the neighbors' will be
14149  // refined after the step. This is to prevent occurrence of
14150  // unrefined islands.
14151  //
14152  // 2/ eliminate refined islands in the interior and at the
14153  // boundary. since they don't do much harm besides increasing the
14154  // number of degrees of freedom, doing this has a rather low
14155  // priority.
14156  //
14157  // 3/ limit the level difference of neighboring cells at each
14158  // vertex.
14159  //
14160  // 4/ eliminate unrefined islands. this has higher priority since
14161  // this diminishes the approximation properties not only of the
14162  // unrefined island, but also of the surrounding patch.
14163  //
14164  // 5/ ensure patch level 1. Then the triangulation consists of
14165  // patches, i.e. of cells that are refined once. It follows that
14166  // if at least one of the children of a cell is or will be
14167  // refined than all children need to be refined. This step only
14168  // sets refinement flags and does not set coarsening flags. If
14169  // the patch_level_1 flag is set, then
14170  // eliminate_unrefined_islands, eliminate_refined_inner_islands
14171  // and eliminate_refined_boundary_islands will be fulfilled
14172  // automatically and do not need to be enforced separately.
14173  //
14174  // 6/ take care of the requirement that no double refinement is done
14175  // at each face
14176  //
14177  // 7/ take care that no double refinement is done at each line in 3d
14178  // or higher dimensions.
14179  //
14180  // 8/ make sure that all children of each cell are either flagged
14181  // for coarsening or none of the children is
14182  //
14183  // For some of these steps, it is known that they interact. Namely,
14184  // it is not possible to guarantee that after step 6 another step 5
14185  // would have no effect; the same holds for the opposite order and
14186  // also when taking into account step 7. however, it is important to
14187  // guarantee that step five or six do not undo something that step 5
14188  // did, and step 7 not something of step 6, otherwise the
14189  // requirements will not be satisfied even if the loop
14190  // terminates. this is accomplished by the fact that steps 5 and 6
14191  // only *add* refinement flags and delete coarsening flags
14192  // (therefore, step 6 can't undo something that step 4 already did),
14193  // and step 7 only deletes coarsening flags, never adds some. step 7
14194  // needs also take care that it won't tag cells for refinement for
14195  // which some neighbors are more refined or will be refined.
14196 
14198  // STEP 0:
14199  // Only if coarsest_level_1 or patch_level_1 is set: clear all
14200  // coarsen flags on level 1 to avoid level 0 cells being created
14201  // by coarsening.
14202  if (((smooth_grid & coarsest_level_1) || (smooth_grid & patch_level_1)) &&
14203  n_levels() >= 2)
14204  {
14205  for (const auto &cell : active_cell_iterators_on_level(1))
14206  cell->clear_coarsen_flag();
14207  }
14208 
14209  bool mesh_changed_in_this_loop = false;
14210  do
14211  {
14213  // STEP 1:
14214  // do not coarsen a cell if 'most of the neighbors' will be
14215  // refined after the step. This is to prevent the occurrence
14216  // of unrefined islands. If patch_level_1 is set, this will
14217  // be automatically fulfilled.
14218  if (smooth_grid & do_not_produce_unrefined_islands &&
14219  !(smooth_grid & patch_level_1))
14220  {
14221  for (const auto &cell : cell_iterators())
14222  {
14223  // only do something if this
14224  // cell will be coarsened
14225  if (!cell->is_active() && cell_will_be_coarsened(cell))
14226  possibly_do_not_produce_unrefined_islands<dim, spacedim>(cell);
14227  }
14228  }
14229 
14230 
14232  // STEP 2:
14233  // eliminate refined islands in the interior and at the
14234  // boundary. since they don't do much harm besides increasing
14235  // the number of degrees of freedom, doing this has a rather
14236  // low priority. If patch_level_1 is set, this will be
14237  // automatically fulfilled.
14238  //
14239  // there is one corner case to consider: if this is a
14240  // distributed triangulation, there may be refined islands on
14241  // the boundary of which we own only part (e.g. a single cell
14242  // in the corner of a domain). the rest of the island is
14243  // ghost cells and it *looks* like the area around it
14244  // (artificial cells) are coarser but this is only because
14245  // they may actually be equally fine on other
14246  // processors. it's hard to detect this case but we can do
14247  // the following: only set coarsen flags to remove this
14248  // refined island if all cells we want to set flags on are
14249  // locally owned
14250  if (smooth_grid & (eliminate_refined_inner_islands |
14251  eliminate_refined_boundary_islands) &&
14252  !(smooth_grid & patch_level_1))
14253  {
14254  for (const auto &cell : cell_iterators())
14255  if (!cell->is_active() ||
14256  (cell->is_active() && cell->refine_flag_set() &&
14257  cell->is_locally_owned()))
14258  {
14259  // check whether all children are active, i.e. not
14260  // refined themselves. This is a precondition that the
14261  // children may be coarsened away. If the cell is only
14262  // flagged for refinement, then all future children
14263  // will be active
14264  bool all_children_active = true;
14265  if (!cell->is_active())
14266  for (unsigned int c = 0; c < cell->n_children(); ++c)
14267  if (!cell->child(c)->is_active() ||
14268  cell->child(c)->is_ghost() ||
14269  cell->child(c)->is_artificial())
14270  {
14271  all_children_active = false;
14272  break;
14273  }
14274 
14275  if (all_children_active)
14276  {
14277  // count number of refined and unrefined neighbors
14278  // of cell. neighbors on lower levels are counted
14279  // as unrefined since they can only get to the
14280  // same level as this cell by the next refinement
14281  // cycle
14282  unsigned int unrefined_neighbors = 0, total_neighbors = 0;
14283 
14284  // Keep track if this cell is at a periodic
14285  // boundary or not. TODO: We do not currently run
14286  // the algorithm for inner islands at a periodic
14287  // boundary (remains to be implemented), but we
14288  // also don't want to consider them
14289  // boundary_island cells as this can interfere
14290  // with 2:1 refinement across periodic faces.
14291  // Instead: just ignore those cells for this
14292  // smoothing operation below.
14293  bool at_periodic_boundary = false;
14294 
14295  for (const unsigned int n :
14297  {
14298  const cell_iterator neighbor = cell->neighbor(n);
14299  if (neighbor.state() == IteratorState::valid)
14300  {
14301  ++total_neighbors;
14302 
14303  if (!face_will_be_refined_by_neighbor(cell, n))
14304  ++unrefined_neighbors;
14305  }
14306  else if (cell->has_periodic_neighbor(n))
14307  {
14308  ++total_neighbors;
14309  at_periodic_boundary = true;
14310  }
14311  }
14312 
14313  // if all neighbors unrefined: mark this cell for
14314  // coarsening or don't refine if marked for that
14315  //
14316  // also do the distinction between the two
14317  // versions of the eliminate_refined_*_islands
14318  // flag
14319  //
14320  // the last check is whether there are any
14321  // neighbors at all. if not so, then we are (e.g.)
14322  // on the coarsest grid with one cell, for which,
14323  // of course, we do not remove the refine flag.
14324  if ((unrefined_neighbors == total_neighbors) &&
14325  ((!cell->at_boundary() &&
14326  (smooth_grid & eliminate_refined_inner_islands)) ||
14327  (cell->at_boundary() && !at_periodic_boundary &&
14328  (smooth_grid &
14329  eliminate_refined_boundary_islands))) &&
14330  (total_neighbors != 0))
14331  {
14332  if (!cell->is_active())
14333  for (unsigned int c = 0; c < cell->n_children(); ++c)
14334  {
14335  cell->child(c)->clear_refine_flag();
14336  cell->child(c)->set_coarsen_flag();
14337  }
14338  else
14339  cell->clear_refine_flag();
14340  }
14341  }
14342  }
14343  }
14344 
14346  // STEP 3:
14347  // limit the level difference of neighboring cells at each
14348  // vertex.
14349  //
14350  // in case of anisotropic refinement this does not make
14351  // sense. as soon as one cell is anisotropically refined, an
14352  // Assertion is thrown. therefore we can ignore this problem
14353  // later on
14354  if (smooth_grid & limit_level_difference_at_vertices)
14355  {
14356  Assert(!anisotropic_refinement,
14357  ExcMessage("In case of anisotropic refinement the "
14358  "limit_level_difference_at_vertices flag for "
14359  "mesh smoothing must not be set!"));
14360 
14361  // store highest level one of the cells adjacent to a vertex
14362  // belongs to
14363  std::vector<int> vertex_level(vertices.size(), 0);
14364  for (const auto &cell : active_cell_iterators())
14365  {
14366  if (cell->refine_flag_set())
14367  for (const unsigned int vertex :
14369  vertex_level[cell->vertex_index(vertex)] =
14370  std::max(vertex_level[cell->vertex_index(vertex)],
14371  cell->level() + 1);
14372  else if (!cell->coarsen_flag_set())
14373  for (const unsigned int vertex :
14375  vertex_level[cell->vertex_index(vertex)] =
14376  std::max(vertex_level[cell->vertex_index(vertex)],
14377  cell->level());
14378  else
14379  {
14380  // if coarsen flag is set then tentatively assume
14381  // that the cell will be coarsened. this isn't
14382  // always true (the coarsen flag could be removed
14383  // again) and so we may make an error here
14384  Assert(cell->coarsen_flag_set(), ExcInternalError());
14385  for (const unsigned int vertex :
14387  vertex_level[cell->vertex_index(vertex)] =
14388  std::max(vertex_level[cell->vertex_index(vertex)],
14389  cell->level() - 1);
14390  }
14391  }
14392 
14393 
14394  // loop over all cells in reverse order. do so because we
14395  // can then update the vertex levels on the adjacent
14396  // vertices and maybe already flag additional cells in this
14397  // loop
14398  //
14399  // note that not only may we have to add additional
14400  // refinement flags, but we will also have to remove
14401  // coarsening flags on cells adjacent to vertices that will
14402  // see refinement
14403  for (active_cell_iterator cell = last_active(); cell != end(); --cell)
14404  if (cell->refine_flag_set() == false)
14405  {
14406  for (const unsigned int vertex :
14408  if (vertex_level[cell->vertex_index(vertex)] >=
14409  cell->level() + 1)
14410  {
14411  // remove coarsen flag...
14412  cell->clear_coarsen_flag();
14413 
14414  // ...and if necessary also refine the current
14415  // cell, at the same time updating the level
14416  // information about vertices
14417  if (vertex_level[cell->vertex_index(vertex)] >
14418  cell->level() + 1)
14419  {
14420  cell->set_refine_flag();
14421 
14422  for (const unsigned int v :
14424  vertex_level[cell->vertex_index(v)] =
14425  std::max(vertex_level[cell->vertex_index(v)],
14426  cell->level() + 1);
14427  }
14428 
14429  // continue and see whether we may, for example,
14430  // go into the inner'if'
14431  // above based on a
14432  // different vertex
14433  }
14434  }
14435  }
14436 
14438  // STEP 4:
14439  // eliminate unrefined islands. this has higher priority
14440  // since this diminishes the approximation properties not
14441  // only of the unrefined island, but also of the surrounding
14442  // patch.
14443  //
14444  // do the loop from finest to coarsest cells since we may
14445  // trigger a cascade by marking cells for refinement which
14446  // may trigger more cells further down below
14447  if (smooth_grid & eliminate_unrefined_islands)
14448  {
14449  for (active_cell_iterator cell = last_active(); cell != end(); --cell)
14450  // only do something if cell is not already flagged for
14451  // (isotropic) refinement
14452  if (cell->refine_flag_set() !=
14454  possibly_refine_unrefined_island<dim, spacedim>(
14455  cell, (smooth_grid & allow_anisotropic_smoothing) != 0);
14456  }
14457 
14459  // STEP 5:
14460  // ensure patch level 1.
14461  //
14462  // Introduce some terminology:
14463  // - a cell that is refined
14464  // once is a patch of
14465  // level 1 simply called patch.
14466  // - a cell that is globally
14467  // refined twice is called
14468  // a patch of level 2.
14469  // - patch level n says that
14470  // the triangulation consists
14471  // of patches of level n.
14472  // This makes sense only
14473  // if the grid is already at
14474  // least n times globally
14475  // refined.
14476  //
14477  // E.g. from patch level 1 follows: if at least one of the
14478  // children of a cell is or will be refined than enforce all
14479  // children to be refined.
14480 
14481  // This step 4 only sets refinement flags and does not set
14482  // coarsening flags.
14483  if (smooth_grid & patch_level_1)
14484  {
14485  // An important assumption (A) is that before calling this
14486  // function the grid was already of patch level 1.
14487 
14488  // loop over all cells whose children are all active. (By
14489  // assumption (A) either all or none of the children are
14490  // active). If the refine flag of at least one of the
14491  // children is set then set_refine_flag and
14492  // clear_coarsen_flag of all children.
14493  for (const auto &cell : cell_iterators())
14494  if (!cell->is_active())
14495  {
14496  // ensure the invariant. we can then check whether all
14497  // of its children are further refined or not by
14498  // simply looking at the first child
14499  Assert(cell_is_patch_level_1(cell), ExcInternalError());
14500  if (cell->child(0)->has_children() == true)
14501  continue;
14502 
14503  // cell is found to be a patch. combine the refine
14504  // cases of all children
14505  RefinementCase<dim> combined_ref_case =
14507  for (unsigned int i = 0; i < cell->n_children(); ++i)
14508  combined_ref_case =
14509  combined_ref_case | cell->child(i)->refine_flag_set();
14510  if (combined_ref_case != RefinementCase<dim>::no_refinement)
14511  for (unsigned int i = 0; i < cell->n_children(); ++i)
14512  {
14513  cell_iterator child = cell->child(i);
14514 
14515  child->clear_coarsen_flag();
14516  child->set_refine_flag(combined_ref_case);
14517  }
14518  }
14519 
14520  // The code above dealt with the case where we may get a
14521  // non-patch_level_1 mesh from refinement. Now also deal
14522  // with the case where we could get such a mesh by
14523  // coarsening. Coarsen the children (and remove the
14524  // grandchildren) only if all cell->grandchild(i)
14525  // ->coarsen_flag_set() are set.
14526  //
14527  // for a case where this is a bit tricky, take a look at the
14528  // mesh_smoothing_0[12] testcases
14529  for (const auto &cell : cell_iterators())
14530  {
14531  // check if this cell has active grandchildren. note
14532  // that we know that it is patch_level_1, i.e. if one of
14533  // its children is active then so are all, and it isn't
14534  // going to have any grandchildren at all:
14535  if (cell->is_active() || cell->child(0)->is_active())
14536  continue;
14537 
14538  // cell is not active, and so are none of its
14539  // children. check the grandchildren. note that the
14540  // children are also patch_level_1, and so we only ever
14541  // need to check their first child
14542  const unsigned int n_children = cell->n_children();
14543  bool has_active_grandchildren = false;
14544 
14545  for (unsigned int i = 0; i < n_children; ++i)
14546  if (cell->child(i)->child(0)->is_active())
14547  {
14548  has_active_grandchildren = true;
14549  break;
14550  }
14551 
14552  if (has_active_grandchildren == false)
14553  continue;
14554 
14555 
14556  // ok, there are active grandchildren. see if either all
14557  // or none of them are flagged for coarsening
14558  unsigned int n_grandchildren = 0;
14559 
14560  // count all coarsen flags of the grandchildren.
14561  unsigned int n_coarsen_flags = 0;
14562 
14563  // cell is not a patch (of level 1) as it has a
14564  // grandchild. Is cell a patch of level 2?? Therefore:
14565  // find out whether all cell->child(i) are patches
14566  for (unsigned int c = 0; c < n_children; ++c)
14567  {
14568  // get at the child. by assumption (A), and the
14569  // check by which we got here, the child is not
14570  // active
14571  cell_iterator child = cell->child(c);
14572 
14573  const unsigned int nn_children = child->n_children();
14574  n_grandchildren += nn_children;
14575 
14576  // if child is found to be a patch of active cells
14577  // itself, then add up how many of its children are
14578  // supposed to be coarsened
14579  if (child->child(0)->is_active())
14580  for (unsigned int cc = 0; cc < nn_children; ++cc)
14581  if (child->child(cc)->coarsen_flag_set())
14582  ++n_coarsen_flags;
14583  }
14584 
14585  // if not all grandchildren are supposed to be coarsened
14586  // (e.g. because some simply don't have the flag set, or
14587  // because they are not active and therefore cannot
14588  // carry the flag), then remove the coarsen flag from
14589  // all of the active grandchildren. note that there may
14590  // be coarsen flags on the grandgrandchildren -- we
14591  // don't clear them here, but we'll get to them in later
14592  // iterations if necessary
14593  //
14594  // there is nothing we have to do if no coarsen flags
14595  // have been set at all
14596  if ((n_coarsen_flags != n_grandchildren) && (n_coarsen_flags > 0))
14597  for (unsigned int c = 0; c < n_children; ++c)
14598  {
14599  const cell_iterator child = cell->child(c);
14600  if (child->child(0)->is_active())
14601  for (unsigned int cc = 0; cc < child->n_children(); ++cc)
14602  child->child(cc)->clear_coarsen_flag();
14603  }
14604  }
14605  }
14606 
14608  //
14609  // at the boundary we could end up with cells with negative
14610  // volume or at least with a part, that is negative, if the
14611  // cell is refined anisotropically. we have to check, whether
14612  // that can happen
14613  this->policy->prevent_distorted_boundary_cells(*this);
14614 
14616  // STEP 6:
14617  // take care of the requirement that no
14618  // double refinement is done at each face
14619  //
14620  // in case of anisotropic refinement it is only likely, but
14621  // not sure, that the cells, which are more refined along a
14622  // certain face common to two cells are on a higher
14623  // level. therefore we cannot be sure, that the requirement
14624  // of no double refinement is fulfilled after a single pass
14625  // of the following actions. We could just wait for the next
14626  // global loop. when this function terminates, the
14627  // requirement will be fulfilled. However, it might be faster
14628  // to insert an inner loop here.
14629  bool changed = true;
14630  while (changed)
14631  {
14632  changed = false;
14633  active_cell_iterator cell = last_active(), endc = end();
14634 
14635  for (; cell != endc; --cell)
14636  if (cell->refine_flag_set())
14637  {
14638  // loop over neighbors of cell
14639  for (const auto i : cell->face_indices())
14640  {
14641  // only do something if the face is not at the
14642  // boundary and if the face will be refined with
14643  // the RefineCase currently flagged for
14644  const bool has_periodic_neighbor =
14645  cell->has_periodic_neighbor(i);
14646  const bool has_neighbor_or_periodic_neighbor =
14647  !cell->at_boundary(i) || has_periodic_neighbor;
14648  if (has_neighbor_or_periodic_neighbor &&
14650  cell->refine_flag_set(), i) !=
14652  {
14653  // 1) if the neighbor has children: nothing to
14654  // worry about. 2) if the neighbor is active
14655  // and a coarser one, ensure, that its
14656  // refine_flag is set 3) if the neighbor is
14657  // active and as refined along the face as our
14658  // current cell, make sure, that no
14659  // coarsen_flag is set. if we remove the
14660  // coarsen flag of our neighbor,
14661  // fix_coarsen_flags() makes sure, that the
14662  // mother cell will not be coarsened
14663  if (cell->neighbor_or_periodic_neighbor(i)->is_active())
14664  {
14665  if ((!has_periodic_neighbor &&
14666  cell->neighbor_is_coarser(i)) ||
14667  (has_periodic_neighbor &&
14668  cell->periodic_neighbor_is_coarser(i)))
14669  {
14670  if (cell->neighbor_or_periodic_neighbor(i)
14671  ->coarsen_flag_set())
14672  cell->neighbor_or_periodic_neighbor(i)
14673  ->clear_coarsen_flag();
14674  // we'll set the refine flag for this
14675  // neighbor below. we note, that we
14676  // have changed something by setting
14677  // the changed flag to true. We do not
14678  // need to do so, if we just removed
14679  // the coarsen flag, as the changed
14680  // flag only indicates the need to
14681  // re-run the inner loop. however, we
14682  // only loop over cells flagged for
14683  // refinement here, so nothing to
14684  // worry about if we remove coarsen
14685  // flags
14686 
14687  if (dim == 2)
14688  {
14689  if (smooth_grid &
14690  allow_anisotropic_smoothing)
14691  changed =
14692  has_periodic_neighbor ?
14693  cell->periodic_neighbor(i)
14694  ->flag_for_face_refinement(
14695  cell
14696  ->periodic_neighbor_of_coarser_periodic_neighbor(
14697  i)
14698  .first,
14700  cell->neighbor(i)
14701  ->flag_for_face_refinement(
14702  cell
14703  ->neighbor_of_coarser_neighbor(
14704  i)
14705  .first,
14707  else
14708  {
14709  if (!cell
14710  ->neighbor_or_periodic_neighbor(
14711  i)
14712  ->refine_flag_set())
14713  changed = true;
14714  cell->neighbor_or_periodic_neighbor(i)
14715  ->set_refine_flag();
14716  }
14717  }
14718  else // i.e. if (dim==3)
14719  {
14720  // ugly situations might arise here,
14721  // consider the following situation, which
14722  // shows neighboring cells at the common
14723  // face, where the upper right element is
14724  // coarser at the given face. Now the upper
14725  // child element of the lower left wants to
14726  // refine according to cut_z, such that
14727  // there is a 'horizontal' refinement of the
14728  // face marked with #####
14729  //
14730  // / /
14731  // / /
14732  // *---------------*
14733  // | |
14734  // | |
14735  // | |
14736  // | |
14737  // | |
14738  // | | /
14739  // | |/
14740  // *---------------*
14741  //
14742  //
14743  // *---------------*
14744  // /| /|
14745  // / | ##### / |
14746  // | |
14747  // *---------------*
14748  // /| /|
14749  // / | / |
14750  // | |
14751  // *---------------*
14752  // / /
14753  // / /
14754  //
14755  // this introduces too many hanging nodes
14756  // and the neighboring (coarser) cell (upper
14757  // right) has to be refined. If it is only
14758  // refined according to cut_z, then
14759  // everything is ok:
14760  //
14761  // / /
14762  // / /
14763  // *---------------*
14764  // | |
14765  // | | /
14766  // | |/
14767  // *---------------*
14768  // | |
14769  // | | /
14770  // | |/
14771  // *---------------*
14772  //
14773  //
14774  // *---------------*
14775  // /| /|
14776  // / *---------------*
14777  // /| /|
14778  // *---------------*
14779  // /| /|
14780  // / | / |
14781  // | |
14782  // *---------------*
14783  // / /
14784  // / /
14785  //
14786  // if however the cell wants to refine
14787  // itself in an other way, or if we disallow
14788  // anisotropic smoothing, then simply
14789  // refining the neighbor isotropically is
14790  // not going to work, since this introduces
14791  // a refinement of face ##### with both
14792  // cut_x and cut_y, which is not possible:
14793  //
14794  // / / /
14795  // / / /
14796  // *-------*-------*
14797  // | | |
14798  // | | | /
14799  // | | |/
14800  // *-------*-------*
14801  // | | |
14802  // | | | /
14803  // | | |/
14804  // *-------*-------*
14805  //
14806  //
14807  // *---------------*
14808  // /| /|
14809  // / *---------------*
14810  // /| /|
14811  // *---------------*
14812  // /| /|
14813  // / | / |
14814  // | |
14815  // *---------------*
14816  // / /
14817  // / /
14818  //
14819  // thus, in this case we also need to refine
14820  // our current cell in the new direction:
14821  //
14822  // / / /
14823  // / / /
14824  // *-------*-------*
14825  // | | |
14826  // | | | /
14827  // | | |/
14828  // *-------*-------*
14829  // | | |
14830  // | | | /
14831  // | | |/
14832  // *-------*-------*
14833  //
14834  //
14835  // *-------*-------*
14836  // /| /| /|
14837  // / *-------*-------*
14838  // /| /| /|
14839  // *-------*-------*
14840  // /| / /|
14841  // / | / |
14842  // | |
14843  // *---------------*
14844  // / /
14845  // / /
14846 
14847  std::pair<unsigned int, unsigned int>
14848  nb_indices =
14849  has_periodic_neighbor ?
14850  cell
14851  ->periodic_neighbor_of_coarser_periodic_neighbor(
14852  i) :
14853  cell->neighbor_of_coarser_neighbor(i);
14854  unsigned int refined_along_x = 0,
14855  refined_along_y = 0,
14856  to_be_refined_along_x = 0,
14857  to_be_refined_along_y = 0;
14858 
14859  const int this_face_index =
14860  cell->face_index(i);
14861 
14862  // step 1: detect, along which axis the face
14863  // is currently refined
14864 
14865  // first, we need an iterator pointing to
14866  // the parent face. This requires a slight
14867  // detour in case the neighbor is behind a
14868  // periodic face.
14869  const auto parent_face = [&]() {
14870  if (has_periodic_neighbor)
14871  {
14872  const auto neighbor =
14873  cell->periodic_neighbor(i);
14874  const auto parent_face_no =
14875  neighbor
14876  ->periodic_neighbor_of_periodic_neighbor(
14877  nb_indices.first);
14878  auto parent =
14879  neighbor->periodic_neighbor(
14880  nb_indices.first);
14881  return parent->face(parent_face_no);
14882  }
14883  else
14884  return cell->neighbor(i)->face(
14885  nb_indices.first);
14886  }();
14887 
14888  if ((this_face_index ==
14889  parent_face->child_index(0)) ||
14890  (this_face_index ==
14891  parent_face->child_index(1)))
14892  {
14893  // this might be an
14894  // anisotropic child. get the
14895  // face refine case of the
14896  // neighbors face and count
14897  // refinements in x and y
14898  // direction.
14899  RefinementCase<dim - 1> frc =
14900  parent_face->refinement_case();
14901  if (frc & RefinementCase<dim>::cut_x)
14902  ++refined_along_x;
14903  if (frc & RefinementCase<dim>::cut_y)
14904  ++refined_along_y;
14905  }
14906  else
14907  // this has to be an isotropic
14908  // child
14909  {
14910  ++refined_along_x;
14911  ++refined_along_y;
14912  }
14913  // step 2: detect, along which axis the face
14914  // has to be refined given the current
14915  // refine flag
14916  RefinementCase<dim - 1> flagged_frc =
14918  cell->refine_flag_set(),
14919  i,
14920  cell->face_orientation(i),
14921  cell->face_flip(i),
14922  cell->face_rotation(i));
14923  if (flagged_frc &
14925  ++to_be_refined_along_x;
14926  if (flagged_frc &
14928  ++to_be_refined_along_y;
14929 
14930  // step 3: set the refine flag of the
14931  // (coarser and active) neighbor.
14932  if ((smooth_grid &
14933  allow_anisotropic_smoothing) ||
14934  cell->neighbor_or_periodic_neighbor(i)
14935  ->refine_flag_set())
14936  {
14937  if (refined_along_x +
14938  to_be_refined_along_x >
14939  1)
14940  changed |=
14941  cell
14942  ->neighbor_or_periodic_neighbor(i)
14943  ->flag_for_face_refinement(
14944  nb_indices.first,
14945  RefinementCase<dim -
14946  1>::cut_axis(0));
14947  if (refined_along_y +
14948  to_be_refined_along_y >
14949  1)
14950  changed |=
14951  cell
14952  ->neighbor_or_periodic_neighbor(i)
14953  ->flag_for_face_refinement(
14954  nb_indices.first,
14955  RefinementCase<dim -
14956  1>::cut_axis(1));
14957  }
14958  else
14959  {
14960  if (cell
14961  ->neighbor_or_periodic_neighbor(i)
14962  ->refine_flag_set() !=
14964  dim>::isotropic_refinement)
14965  changed = true;
14966  cell->neighbor_or_periodic_neighbor(i)
14967  ->set_refine_flag();
14968  }
14969 
14970  // step 4: if necessary (see above) add to
14971  // the refine flag of the current cell
14972  cell_iterator nb =
14973  cell->neighbor_or_periodic_neighbor(i);
14974  RefinementCase<dim - 1> nb_frc =
14976  nb->refine_flag_set(),
14977  nb_indices.first,
14978  nb->face_orientation(nb_indices.first),
14979  nb->face_flip(nb_indices.first),
14980  nb->face_rotation(nb_indices.first));
14981  if ((nb_frc & RefinementCase<dim>::cut_x) &&
14982  !(refined_along_x ||
14983  to_be_refined_along_x))
14984  changed |= cell->flag_for_face_refinement(
14985  i,
14987  if ((nb_frc & RefinementCase<dim>::cut_y) &&
14988  !(refined_along_y ||
14989  to_be_refined_along_y))
14990  changed |= cell->flag_for_face_refinement(
14991  i,
14993  }
14994  } // if neighbor is coarser
14995  else // -> now the neighbor is not coarser
14996  {
14997  cell->neighbor_or_periodic_neighbor(i)
14998  ->clear_coarsen_flag();
14999  const unsigned int nb_nb =
15000  has_periodic_neighbor ?
15001  cell
15002  ->periodic_neighbor_of_periodic_neighbor(
15003  i) :
15004  cell->neighbor_of_neighbor(i);
15005  const cell_iterator neighbor =
15006  cell->neighbor_or_periodic_neighbor(i);
15007  RefinementCase<dim - 1> face_ref_case =
15009  neighbor->refine_flag_set(),
15010  nb_nb,
15011  neighbor->face_orientation(nb_nb),
15012  neighbor->face_flip(nb_nb),
15013  neighbor->face_rotation(nb_nb));
15014  RefinementCase<dim - 1> needed_face_ref_case =
15016  cell->refine_flag_set(),
15017  i,
15018  cell->face_orientation(i),
15019  cell->face_flip(i),
15020  cell->face_rotation(i));
15021  // if the neighbor wants to refine the
15022  // face with cut_x and we want cut_y
15023  // or vice versa, we have to refine
15024  // isotropically at the given face
15025  if ((face_ref_case ==
15027  needed_face_ref_case ==
15029  (face_ref_case ==
15031  needed_face_ref_case ==
15033  {
15034  changed = cell->flag_for_face_refinement(
15035  i, face_ref_case);
15036  neighbor->flag_for_face_refinement(
15037  nb_nb, needed_face_ref_case);
15038  }
15039  }
15040  }
15041  else //-> the neighbor is not active
15042  {
15043  RefinementCase<dim - 1>
15044  face_ref_case = cell->face(i)->refinement_case(),
15045  needed_face_ref_case =
15047  cell->refine_flag_set(),
15048  i,
15049  cell->face_orientation(i),
15050  cell->face_flip(i),
15051  cell->face_rotation(i));
15052  // if the face is refined with cut_x and
15053  // we want cut_y or vice versa, we have to
15054  // refine isotropically at the given face
15055  if ((face_ref_case == RefinementCase<dim>::cut_x &&
15056  needed_face_ref_case ==
15058  (face_ref_case == RefinementCase<dim>::cut_y &&
15059  needed_face_ref_case ==
15061  changed =
15062  cell->flag_for_face_refinement(i,
15063  face_ref_case);
15064  }
15065  }
15066  }
15067  }
15068  }
15069 
15071  // STEP 7:
15072  // take care that no double refinement
15073  // is done at each line in 3d or higher
15074  // dimensions.
15075  this->policy->prepare_refinement_dim_dependent(*this);
15076 
15078  // STEP 8:
15079  // make sure that all children of each
15080  // cell are either flagged for coarsening
15081  // or none of the children is
15082  fix_coarsen_flags();
15083  // get the refinement and coarsening
15084  // flags
15085  std::vector<bool> flags_after_loop[2];
15086  save_coarsen_flags(flags_after_loop[0]);
15087  save_refine_flags(flags_after_loop[1]);
15088 
15089  // find out whether something was
15090  // changed in this loop
15091  mesh_changed_in_this_loop =
15092  ((flags_before_loop[0] != flags_after_loop[0]) ||
15093  (flags_before_loop[1] != flags_after_loop[1]));
15094 
15095  // set the flags for the next loop
15096  // already
15097  flags_before_loop[0].swap(flags_after_loop[0]);
15098  flags_before_loop[1].swap(flags_after_loop[1]);
15099  }
15100  while (mesh_changed_in_this_loop);
15101 
15102 
15103  // find out whether something was really changed in this
15104  // function. Note that @p{flags_before_loop} represents the state
15105  // after the last loop, i.e. the present state
15106  return ((flags_before[0] != flags_before_loop[0]) ||
15107  (flags_before[1] != flags_before_loop[1]));
15108 }
15109 
15110 
15111 
15112 template <int dim, int spacedim>
15113 void
15115  const unsigned int magic_number1,
15116  const std::vector<bool> &v,
15117  const unsigned int magic_number2,
15118  std::ostream & out)
15119 {
15120  const unsigned int N = v.size();
15121  unsigned char * flags = new unsigned char[N / 8 + 1];
15122  for (unsigned int i = 0; i < N / 8 + 1; ++i)
15123  flags[i] = 0;
15124 
15125  for (unsigned int position = 0; position < N; ++position)
15126  flags[position / 8] |= (v[position] ? (1 << (position % 8)) : 0);
15127 
15128  AssertThrow(out, ExcIO());
15129 
15130  // format:
15131  // 0. magic number
15132  // 1. number of flags
15133  // 2. the flags
15134  // 3. magic number
15135  out << magic_number1 << ' ' << N << std::endl;
15136  for (unsigned int i = 0; i < N / 8 + 1; ++i)
15137  out << static_cast<unsigned int>(flags[i]) << ' ';
15138 
15139  out << std::endl << magic_number2 << std::endl;
15140 
15141  delete[] flags;
15142 
15143  AssertThrow(out, ExcIO());
15144 }
15145 
15146 
15147 template <int dim, int spacedim>
15148 void
15149 Triangulation<dim, spacedim>::read_bool_vector(const unsigned int magic_number1,
15150  std::vector<bool> &v,
15151  const unsigned int magic_number2,
15152  std::istream & in)
15153 {
15154  AssertThrow(in, ExcIO());
15155 
15156  unsigned int magic_number;
15157  in >> magic_number;
15158  AssertThrow(magic_number == magic_number1, ExcGridReadError());
15159 
15160  unsigned int N;
15161  in >> N;
15162  v.resize(N);
15163 
15164  unsigned char * flags = new unsigned char[N / 8 + 1];
15165  unsigned short int tmp;
15166  for (unsigned int i = 0; i < N / 8 + 1; ++i)
15167  {
15168  in >> tmp;
15169  flags[i] = tmp;
15170  }
15171 
15172  for (unsigned int position = 0; position != N; ++position)
15173  v[position] = (flags[position / 8] & (1 << (position % 8)));
15174 
15175  in >> magic_number;
15176  AssertThrow(magic_number == magic_number2, ExcGridReadError());
15177 
15178  delete[] flags;
15179 
15180  AssertThrow(in, ExcIO());
15181 }
15182 
15183 
15184 
15185 template <int dim, int spacedim>
15186 std::size_t
15188 {
15189  std::size_t mem = 0;
15191  for (const auto &level : levels)
15194  mem += MemoryConsumption::memory_consumption(vertices_used);
15195  mem += sizeof(manifold);
15196  mem += sizeof(smooth_grid);
15197  mem += MemoryConsumption::memory_consumption(number_cache);
15198  mem += sizeof(faces);
15199  if (faces)
15201 
15202  return mem;
15203 }
15204 
15205 
15206 
15207 template <int dim, int spacedim>
15209  default;
15210 
15211 
15212 // explicit instantiations
15213 #include "tria.inst"
15214 
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
Subscriptor & operator=(const Subscriptor &)
Definition: subscriptor.h:292
Definition: tensor.h:472
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:3620
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:3997
virtual void clear()
bool anisotropic_refinement
Definition: tria.h:4009
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)
std::unique_ptr< std::map< unsigned int, types::manifold_id > > vertex_to_manifold_id_map_1d
Definition: tria.h:4067
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
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:3992
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:4016
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:4044
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:3531
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:3986
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:4027
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
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
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
std::map< types::manifold_id, std::unique_ptr< const Manifold< dim, spacedim > > > manifold
Definition: tria.h:4004
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
MeshSmoothing smooth_grid
Definition: tria.h:3525
void save_refine_flags(std::ostream &out) const
std::unique_ptr< ::internal::TriangulationImplementation::Policy< dim, spacedim > > policy
Definition: tria.h:3583
Triangulation< dim, spacedim > & get_triangulation()
void save_user_flags_quad(std::ostream &out) const
Signals signals
Definition: tria.h:2295
virtual ~Triangulation() override
unsigned int n_vertices() const
void save_user_indices(std::vector< unsigned int > &v) const
std::vector< std::unique_ptr<::internal::TriangulationImplementation::TriaLevel > > levels
Definition: tria.h:3978
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:1682
void prepare_refinement_dim_dependent(Triangulation< dim, spacedim > &triangulation) override
Definition: tria.cc:1689
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:1665
void update_neighbors(Triangulation< dim, spacedim > &tria) override
Definition: tria.cc:1659
Triangulation< dim, spacedim >::DistortedCellList execute_refinement(Triangulation< dim, spacedim > &triangulation, const bool check_for_distorted_cells) override
Definition: tria.cc:1675
bool coarsening_allowed(const typename Triangulation< dim, spacedim >::cell_iterator &cell) override
Definition: tria.cc:1696
std::unique_ptr< Policy< dim, spacedim > > clone() override
Definition: tria.cc:1704
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:396
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:397
Point< 3 > vertices[4]
Point< 2 > second
Definition: grid_out.cc:4588
Point< 2 > first
Definition: grid_out.cc:4587
unsigned int level
Definition: grid_out.cc:4590
AdjacentCell adjacent_cells[2]
Definition: grid_tools.cc:1176
unsigned int vertex_indices[2]
Definition: grid_tools.cc:1256
unsigned int cell_index
Definition: grid_tools.cc:1092
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:584
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:1465
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:538
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1622
static ::ExceptionBase & ExcInternalErrorOnCell(int arg1)
static ::ExceptionBase & ExcQuadInexistant(int arg1, int arg2, int arg3, int arg4)
#define AssertNothrow(cond, exc)
Definition: exceptions.h:1528
#define AssertIndexRange(index, range)
Definition: exceptions.h:1690
static ::ExceptionBase & ExcInvalidVertexIndex(int arg1, int arg2, int arg3)
static ::ExceptionBase & ExcIO()
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:561
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:515
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:610
#define AssertThrow(cond, exc)
Definition: exceptions.h:1575
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
Definition: tria.h:1361
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)
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:240
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 Quadrilateral
constexpr const ReferenceCell Invalid
constexpr const ReferenceCell Triangle
constexpr const ReferenceCell Hexahedron
VectorType::value_type * begin(VectorType &V)
VectorType::value_type * end(VectorType &V)
Iterator lower_bound(Iterator first, Iterator last, const T &val)
Definition: utilities.h:1111
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:12617
unsigned int n_active_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
Definition: tria.cc:12594
const Manifold< dim, spacedim > & get_default_flat_manifold()
Definition: tria.cc:9982
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
Definition: tria.cc:12587
void reserve_space(TriaFaces &tria_faces, const unsigned int new_quads_in_pairs, const unsigned int new_quads_single)
Definition: tria.cc:1118
void monitor_memory(const TriaObjects &tria_object, const unsigned int)
Definition: tria.cc:1539
unsigned int n_active_cells(const internal::TriangulationImplementation::NumberCache< 3 > &c)
Definition: tria.cc:12624
void monitor_memory(const TriaLevel &tria_level, const unsigned int true_dimension)
Definition: tria.cc:1321
const types::boundary_id internal_face_boundary_id
Definition: types.h:255
const types::subdomain_id invalid_subdomain_id
Definition: types.h:276
static const unsigned int invalid_unsigned_int
Definition: types.h:196
const types::manifold_id flat_manifold_id
Definition: types.h:264
const types::global_dof_index invalid_dof_index
Definition: types.h:211
TriangulationBase< dim, spacedim > Triangulation
Definition: tria_base.h:396
unsigned int manifold_id
Definition: types.h:141
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:1542
static Triangulation< dim, spacedim >::DistortedCellList execute_refinement(Triangulation< dim, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:9943
static void update_neighbors(Triangulation< 1, spacedim > &)
Definition: tria.cc:9858
static bool coarsening_allowed(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
Definition: tria.cc:9969
static void update_neighbors(Triangulation< dim, spacedim > &triangulation)
Definition: tria.cc:9862
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:9928
static void prepare_refinement_dim_dependent(Triangulation< dim, spacedim > &triangulation)
Definition: tria.cc:9961
static void prevent_distorted_boundary_cells(Triangulation< dim, spacedim > &triangulation)
Definition: tria.cc:9952
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 3 > &number_cache)
Definition: tria.cc:2017
static void reserve_space_(TriaObjects &obj, const unsigned int size)
Definition: tria.cc:2677
static Triangulation< 1, spacedim >::DistortedCellList execute_refinement(Triangulation< 1, spacedim > &triangulation, const bool)
Definition: tria.cc:4559
static void reserve_space_(TriaFaces &faces, const unsigned structdim, const unsigned int size)
Definition: tria.cc:2618
static void prevent_distorted_boundary_cells(Triangulation< 1, spacedim > &)
Definition: tria.cc:9498
static void update_neighbors(Triangulation< dim, spacedim > &triangulation)
Definition: tria.cc:2116
static void prepare_refinement_dim_dependent(const Triangulation< dim, spacedim > &)
Definition: tria.cc:9586
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:2971
static void reserve_space_(TriaLevel &level, const unsigned int spacedim, const unsigned int size, const bool orientation_needed)
Definition: tria.cc:2640
static void update_neighbors(Triangulation< 1, spacedim > &)
Definition: tria.cc:2110
static Triangulation< dim, spacedim >::DistortedCellList execute_refinement_isotropic(Triangulation< dim, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:4018
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:2295
static void process_subcelldata(const CRS< T > &crs, TriaObjects &obj, const std::vector< CellData< structdim >> &boundary_objects_in)
Definition: tria.cc:2533
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:3601
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 2 > &number_cache)
Definition: tria.cc:1910
static void prevent_distorted_boundary_cells(Triangulation< dim, spacedim > &triangulation)
Definition: tria.cc:9505
static Triangulation< 2, spacedim >::DistortedCellList execute_refinement(Triangulation< 2, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:4793
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 1 > &number_cache)
Definition: tria.cc:1822
static bool coarsening_allowed(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
Definition: tria.cc:9789
static Triangulation< 3, spacedim >::DistortedCellList execute_refinement(Triangulation< 3, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:5121
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:2729
static void prepare_refinement_dim_dependent(Triangulation< 3, spacedim > &triangulation)
Definition: tria.cc:9595
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:2833
std::vector< unsigned int > n_active_lines_level
Definition: tria.h:183
std::vector< unsigned int > n_active_quads_level
Definition: tria.h:241
std::vector< unsigned int > n_active_hexes_level
Definition: tria.h:300