Reference documentation for deal.II version 9.2.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
tria.cc
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2020 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 
20 
21 #include <deal.II/fe/mapping_q1.h>
22 
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 <numeric>
42 
43 
45 
46 
47 template <int structdim>
49  : material_id(0)
51 {
52  std::fill(std::begin(vertices),
55 }
56 
57 
58 
59 template <int structdim>
60 bool
62 {
63  for (const unsigned int i : GeometryInfo<structdim>::vertex_indices())
64  if (vertices[i] != other.vertices[i])
65  return false;
66 
67  if (material_id != other.material_id)
68  return false;
69 
70  if (boundary_id != other.boundary_id)
71  return false;
72 
73  if (manifold_id != other.manifold_id)
74  return false;
75 
76  return true;
77 }
78 
79 
80 
81 bool
82 SubCellData::check_consistency(const unsigned int dim) const
83 {
84  switch (dim)
85  {
86  case 1:
87  return ((boundary_lines.size() == 0) && (boundary_quads.size() == 0));
88  case 2:
89  return (boundary_quads.size() == 0);
90  }
91  return true;
92 }
93 
94 
95 namespace internal
96 {
97  namespace TriangulationImplementation
98  {
100  : n_levels(0)
101  , n_lines(0)
102  , n_active_lines(0)
103  // all other fields are
104  // default constructed
105  {}
106 
107 
108 
109  std::size_t
111  {
112  return (MemoryConsumption::memory_consumption(n_levels) +
115  MemoryConsumption::memory_consumption(n_active_lines) +
116  MemoryConsumption::memory_consumption(n_active_lines_level));
117  }
118 
119 
121  : n_quads(0)
122  , n_active_quads(0)
123  // all other fields are
124  // default constructed
125  {}
126 
127 
128 
129  std::size_t
131  {
135  MemoryConsumption::memory_consumption(n_active_quads) +
136  MemoryConsumption::memory_consumption(n_active_quads_level));
137  }
138 
139 
140 
142  : n_hexes(0)
143  , n_active_hexes(0)
144  // all other fields are
145  // default constructed
146  {}
147 
148 
149 
150  std::size_t
152  {
156  MemoryConsumption::memory_consumption(n_active_hexes) +
157  MemoryConsumption::memory_consumption(n_active_hexes_level));
158  }
159  } // namespace TriangulationImplementation
160 } // namespace internal
161 
162 // anonymous namespace for internal helper functions
163 namespace
164 {
165  // return whether the given cell is
166  // patch_level_1, i.e. determine
167  // whether either all or none of
168  // its children are further
169  // refined. this function can only
170  // be called for non-active cells.
171  template <int dim, int spacedim>
172  bool
173  cell_is_patch_level_1(
175  {
176  Assert(cell->is_active() == false, ExcInternalError());
177 
178  unsigned int n_active_children = 0;
179  for (unsigned int i = 0; i < cell->n_children(); ++i)
180  if (cell->child(i)->is_active())
181  ++n_active_children;
182 
183  return (n_active_children == 0) ||
184  (n_active_children == cell->n_children());
185  }
186 
187 
188 
189  // return, whether a given @p cell will be
190  // coarsened, which is the case if all
191  // children are active and have their coarsen
192  // flag set. In case only part of the coarsen
193  // flags are set, remove them.
194  template <int dim, int spacedim>
195  bool
196  cell_will_be_coarsened(
198  {
199  // only cells with children should be
200  // considered for coarsening
201 
202  if (cell->has_children())
203  {
204  unsigned int children_to_coarsen = 0;
205  const unsigned int n_children = cell->n_children();
206 
207  for (unsigned int c = 0; c < n_children; ++c)
208  if (cell->child(c)->is_active() && cell->child(c)->coarsen_flag_set())
209  ++children_to_coarsen;
210  if (children_to_coarsen == n_children)
211  return true;
212  else
213  for (unsigned int c = 0; c < n_children; ++c)
214  if (cell->child(c)->is_active())
215  cell->child(c)->clear_coarsen_flag();
216  }
217  // no children, so no coarsening
218  // possible. however, no children also
219  // means that this cell will be in the same
220  // state as if it had children and was
221  // coarsened. So, what should we return -
222  // false or true?
223  // make sure we do not have to do this at
224  // all...
225  Assert(cell->has_children(), ExcInternalError());
226  // ... and then simply return false
227  return false;
228  }
229 
230 
231  // return, whether the face @p face_no of the
232  // given @p cell will be refined after the
233  // current refinement step, considering
234  // refine and coarsen flags and considering
235  // only those refinemnts that will be caused
236  // by the neighboring cell.
237 
238  // this function is used on both active cells
239  // and cells with children. on cells with
240  // children it also of interest to know 'how'
241  // the face will be refined. thus there is an
242  // additional third argument @p
243  // expected_face_ref_case returning just
244  // that. be aware, that this vriable will
245  // only contain useful information if this
246  // function is called for an active cell.
247  //
248  // thus, this is an internal function, users
249  // should call one of the two alternatives
250  // following below.
251  template <int dim, int spacedim>
252  bool
253  face_will_be_refined_by_neighbor_internal(
255  const unsigned int face_no,
256  RefinementCase<dim - 1> &expected_face_ref_case)
257  {
258  // first of all: set the default value for
259  // expected_face_ref_case, which is no
260  // refinement at all
261  expected_face_ref_case = RefinementCase<dim - 1>::no_refinement;
262 
263  const typename Triangulation<dim, spacedim>::cell_iterator neighbor =
264  cell->neighbor(face_no);
265 
266  // If we are at the boundary, there is no
267  // neighbor which could refine the face
268  if (neighbor.state() != IteratorState::valid)
269  return false;
270 
271  if (neighbor->has_children())
272  {
273  // if the neighbor is refined, it may be
274  // coarsened. if so, then it won't refine
275  // the face, no matter what else happens
276  if (cell_will_be_coarsened(neighbor))
277  return false;
278  else
279  // if the neighbor is refined, then it
280  // is also refined at our current
281  // face. He will stay so without
282  // coarsening, so return true in that
283  // case.
284  {
285  expected_face_ref_case = cell->face(face_no)->refinement_case();
286  return true;
287  }
288  }
289 
290  // now, the neighbor is not refined, but
291  // perhaps it will be
292  const RefinementCase<dim> nb_ref_flag = neighbor->refine_flag_set();
293  if (nb_ref_flag != RefinementCase<dim>::no_refinement)
294  {
295  // now we need to know, which of the
296  // neighbors faces points towards us
297  const unsigned int neighbor_neighbor = cell->neighbor_face_no(face_no);
298  // check, whether the cell will be
299  // refined in a way that refines our
300  // face
301  const RefinementCase<dim - 1> face_ref_case =
303  nb_ref_flag,
304  neighbor_neighbor,
305  neighbor->face_orientation(neighbor_neighbor),
306  neighbor->face_flip(neighbor_neighbor),
307  neighbor->face_rotation(neighbor_neighbor));
308  if (face_ref_case != RefinementCase<dim - 1>::no_refinement)
309  {
311  neighbor_face = neighbor->face(neighbor_neighbor);
312  const int this_face_index = cell->face_index(face_no);
313 
314  // there are still two basic
315  // possibilities here: the neighbor
316  // might be coarser or as coarse
317  // as we are
318  if (neighbor_face->index() == this_face_index)
319  // the neighbor is as coarse as
320  // we are and will be refined at
321  // the face of consideration, so
322  // return true
323  {
324  expected_face_ref_case = face_ref_case;
325  return true;
326  }
327  else
328  {
329  // the neighbor is coarser.
330  // this is the most complicated
331  // case. It might be, that the
332  // neighbor's face will be
333  // refined, but that we will
334  // not see this, as we are
335  // refined in a similar way.
336 
337  // so, the neighbor's face must
338  // have children. check, if our
339  // cell's face is one of these
340  // (it could also be a
341  // grand_child)
342  for (unsigned int c = 0; c < neighbor_face->n_children(); ++c)
343  if (neighbor_face->child_index(c) == this_face_index)
344  {
345  // if the flagged refine
346  // case of the face is a
347  // subset or the same as
348  // the current refine case,
349  // then the face, as seen
350  // from our cell, won't be
351  // refined by the neighbor
352  if ((neighbor_face->refinement_case() | face_ref_case) ==
353  neighbor_face->refinement_case())
354  return false;
355  else
356  {
357  // if we are active, we
358  // must be an
359  // anisotropic child
360  // and the coming
361  // face_ref_case is
362  // isotropic. Thus,
363  // from our cell we
364  // will see exactly the
365  // opposite refine case
366  // that the face has
367  // now...
368  Assert(
369  face_ref_case ==
371  ExcInternalError());
372  expected_face_ref_case =
373  ~neighbor_face->refinement_case();
374  return true;
375  }
376  }
377 
378  // so, obviously we were not
379  // one of the children, but a
380  // grandchild. This is only
381  // possible in 3d.
382  Assert(dim == 3, ExcInternalError());
383  // In that case, however, no
384  // matter what the neighbor
385  // does, it won't be finer
386  // after the next refinement
387  // step.
388  return false;
389  }
390  } // if face will be refined
391  } // if neighbor is flagged for refinement
392 
393  // no cases left, so the neighbor will not
394  // refine the face
395  return false;
396  }
397 
398  // version of above function for both active
399  // and non-active cells
400  template <int dim, int spacedim>
401  bool
402  face_will_be_refined_by_neighbor(
404  const unsigned int face_no)
405  {
406  RefinementCase<dim - 1> dummy = RefinementCase<dim - 1>::no_refinement;
407  return face_will_be_refined_by_neighbor_internal(cell, face_no, dummy);
408  }
409 
410  // version of above function for active cells
411  // only. Additionally returning the refine
412  // case (to come) of the face under
413  // consideration
414  template <int dim, int spacedim>
415  bool
416  face_will_be_refined_by_neighbor(
418  const unsigned int face_no,
419  RefinementCase<dim - 1> &expected_face_ref_case)
420  {
421  return face_will_be_refined_by_neighbor_internal(cell,
422  face_no,
423  expected_face_ref_case);
424  }
425 
426 
427 
428  template <int dim, int spacedim>
429  bool
430  satisfies_level1_at_vertex_rule(
432  {
433  std::vector<unsigned int> min_adjacent_cell_level(
434  triangulation.n_vertices(), triangulation.n_levels());
435  std::vector<unsigned int> max_adjacent_cell_level(
436  triangulation.n_vertices(), 0);
437 
438  for (const auto &cell : triangulation.active_cell_iterators())
439  for (const unsigned int v : GeometryInfo<dim>::vertex_indices())
440  {
441  min_adjacent_cell_level[cell->vertex_index(v)] =
442  std::min<unsigned int>(
443  min_adjacent_cell_level[cell->vertex_index(v)], cell->level());
444  max_adjacent_cell_level[cell->vertex_index(v)] =
445  std::max<unsigned int>(
446  min_adjacent_cell_level[cell->vertex_index(v)], cell->level());
447  }
448 
449  for (unsigned int k = 0; k < triangulation.n_vertices(); ++k)
450  if (triangulation.vertex_used(k))
451  if (max_adjacent_cell_level[k] - min_adjacent_cell_level[k] > 1)
452  return false;
453  return true;
454  }
455 
456 
457 
464  template <int dim, int spacedim>
465  std::vector<unsigned int>
466  count_cells_bounded_by_line(const Triangulation<dim, spacedim> &triangulation)
467  {
468  if (dim >= 2)
469  {
470  std::vector<unsigned int> line_cell_count(triangulation.n_raw_lines(),
471  0);
473  cell = triangulation.begin(),
474  endc = triangulation.end();
475  for (; cell != endc; ++cell)
476  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
477  ++line_cell_count[cell->line_index(l)];
478  return line_cell_count;
479  }
480  else
481  return std::vector<unsigned int>();
482  }
483 
484 
485 
492  template <int dim, int spacedim>
493  std::vector<unsigned int>
494  count_cells_bounded_by_quad(const Triangulation<dim, spacedim> &triangulation)
495  {
496  if (dim >= 3)
497  {
498  std::vector<unsigned int> quad_cell_count(triangulation.n_raw_quads(),
499  0);
501  cell = triangulation.begin(),
502  endc = triangulation.end();
503  for (; cell != endc; ++cell)
504  for (unsigned int q : GeometryInfo<dim>::face_indices())
505  ++quad_cell_count[cell->quad_index(q)];
506  return quad_cell_count;
507  }
508  else
509  return std::vector<unsigned int>();
510  }
511 
512 
513 
525  void
526  reorder_compatibility(const std::vector<CellData<1>> &, const SubCellData &)
527  {
528  // nothing to do here: the format
529  // hasn't changed for 1d
530  }
531 
532 
533  void reorder_compatibility(std::vector<CellData<2>> &cells,
534  const SubCellData &)
535  {
536  for (auto &cell : cells)
537  std::swap(cell.vertices[2], cell.vertices[3]);
538  }
539 
540 
541  void reorder_compatibility(std::vector<CellData<3>> &cells,
542  SubCellData & subcelldata)
543  {
544  unsigned int tmp[GeometryInfo<3>::vertices_per_cell];
545  for (auto &cell : cells)
546  {
547  for (const unsigned int i : GeometryInfo<3>::vertex_indices())
548  tmp[i] = cell.vertices[i];
549  for (const unsigned int i : GeometryInfo<3>::vertex_indices())
550  cell.vertices[GeometryInfo<3>::ucd_to_deal[i]] = tmp[i];
551  }
552 
553  // now points in boundary quads
554  std::vector<CellData<2>>::iterator boundary_quad =
555  subcelldata.boundary_quads.begin();
556  std::vector<CellData<2>>::iterator end_quad =
557  subcelldata.boundary_quads.end();
558  for (unsigned int quad_no = 0; boundary_quad != end_quad;
559  ++boundary_quad, ++quad_no)
560  std::swap(boundary_quad->vertices[2], boundary_quad->vertices[3]);
561  }
562 
563 
564 
582  template <int dim, int spacedim>
583  unsigned int
584  middle_vertex_index(
585  const typename Triangulation<dim, spacedim>::line_iterator &line)
586  {
587  if (line->has_children())
588  return line->child(0)->vertex_index(1);
590  }
591 
592 
593  template <int dim, int spacedim>
594  unsigned int
595  middle_vertex_index(
596  const typename Triangulation<dim, spacedim>::quad_iterator &quad)
597  {
598  switch (static_cast<unsigned char>(quad->refinement_case()))
599  {
601  return middle_vertex_index<dim, spacedim>(quad->child(0)->line(1));
602  break;
604  return middle_vertex_index<dim, spacedim>(quad->child(0)->line(3));
605  break;
607  return quad->child(0)->vertex_index(3);
608  break;
609  default:
610  break;
611  }
613  }
614 
615 
616  template <int dim, int spacedim>
617  unsigned int
618  middle_vertex_index(
619  const typename Triangulation<dim, spacedim>::hex_iterator &hex)
620  {
621  switch (static_cast<unsigned char>(hex->refinement_case()))
622  {
624  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(1));
625  break;
627  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(3));
628  break;
630  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(5));
631  break;
633  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(11));
634  break;
636  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(5));
637  break;
639  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(7));
640  break;
642  return hex->child(0)->vertex_index(7);
643  break;
644  default:
645  break;
646  }
648  }
649 
650 
663  template <class TRIANGULATION>
664  inline typename TRIANGULATION::DistortedCellList
665  collect_distorted_coarse_cells(const TRIANGULATION &)
666  {
667  return typename TRIANGULATION::DistortedCellList();
668  }
669 
670 
671 
680  template <int dim>
682  collect_distorted_coarse_cells(const Triangulation<dim, dim> &triangulation)
683  {
684  typename Triangulation<dim, dim>::DistortedCellList distorted_cells;
685  for (typename Triangulation<dim, dim>::cell_iterator cell =
686  triangulation.begin(0);
687  cell != triangulation.end(0);
688  ++cell)
689  {
691  for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
692  vertices[i] = cell->vertex(i);
693 
696 
697  for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
698  if (determinants[i] <= 1e-9 * std::pow(cell->diameter(), 1. * dim))
699  {
700  distorted_cells.distorted_cells.push_back(cell);
701  break;
702  }
703  }
704 
705  return distorted_cells;
706  }
707 
708 
715  template <int dim>
716  bool
717  has_distorted_children(
718  const typename Triangulation<dim, dim>::cell_iterator &cell,
719  std::integral_constant<int, dim>,
720  std::integral_constant<int, dim>)
721  {
722  Assert(cell->has_children(), ExcInternalError());
723 
724  for (unsigned int c = 0; c < cell->n_children(); ++c)
725  {
727  for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
728  vertices[i] = cell->child(c)->vertex(i);
729 
732 
733  for (const unsigned int i : GeometryInfo<dim>::vertex_indices())
734  if (determinants[i] <=
735  1e-9 * std::pow(cell->child(c)->diameter(), 1. * dim))
736  return true;
737  }
738 
739  return false;
740  }
741 
742 
750  template <int dim, int spacedim>
751  bool
752  has_distorted_children(
754  std::integral_constant<int, dim>,
755  std::integral_constant<int, spacedim>)
756  {
757  return false;
758  }
759 
760 
761 
766  template <int spacedim>
767  void update_neighbors(Triangulation<1, spacedim> &)
768  {}
769 
770 
771  template <int dim, int spacedim>
772  void
774  {
775  // each face can be neighbored on two sides
776  // by cells. according to the face's
777  // intrinsic normal we define the left
778  // neighbor as the one for which the face
779  // normal points outward, and store that
780  // one first; the second one is then
781  // the right neighbor for which the
782  // face normal points inward. This
783  // information depends on the type of cell
784  // and local number of face for the
785  // 'standard ordering and orientation' of
786  // faces and then on the face_orientation
787  // information for the real mesh. Set up a
788  // table to have fast access to those
789  // offsets (0 for left and 1 for
790  // right). Some of the values are invalid
791  // as they reference too large face
792  // numbers, but we just leave them at a
793  // zero value.
794  //
795  // Note, that in 2d for lines as faces the
796  // normal direction given in the
797  // GeometryInfo class is not consistent. We
798  // thus define here that the normal for a
799  // line points to the right if the line
800  // points upwards.
801  //
802  // There is one more point to
803  // consider, however: if we have
804  // dim<spacedim, then we may have
805  // cases where cells are
806  // inverted. In effect, both
807  // cells think they are the left
808  // neighbor of an edge, for
809  // example, which leads us to
810  // forget neighborship
811  // information (a case that shows
812  // this is
813  // codim_one/hanging_nodes_02). We
814  // store whether a cell is
815  // inverted using the
816  // direction_flag, so if a cell
817  // has a false direction_flag,
818  // then we need to invert our
819  // selection whether we are a
820  // left or right neighbor in all
821  // following computations.
822  //
823  // first index: dimension (minus 2)
824  // second index: local face index
825  // third index: face_orientation (false and true)
826  static const unsigned int left_right_offset[2][6][2] = {
827  // quadrilateral
828  {{0, 1}, // face 0, face_orientation = false and true
829  {1, 0}, // face 1, face_orientation = false and true
830  {1, 0}, // face 2, face_orientation = false and true
831  {0, 1}, // face 3, face_orientation = false and true
832  {0, 0}, // face 4, invalid face
833  {0, 0}}, // face 5, invalid face
834  // hexahedron
835  {{0, 1}, {1, 0}, {0, 1}, {1, 0}, {0, 1}, {1, 0}}};
836 
837  // now create a vector of the two active
838  // neighbors (left and right) for each face
839  // and fill it by looping over all cells. For
840  // cases with anisotropic refinement and more
841  // then one cell neighboring at a given side
842  // of the face we will automatically get the
843  // active one on the highest level as we loop
844  // over cells from lower levels first.
846  std::vector<typename Triangulation<dim, spacedim>::cell_iterator>
847  adjacent_cells(2 * triangulation.n_raw_faces(), dummy);
848 
850  .begin(),
851  endc =
852  triangulation.end();
853  for (; cell != endc; ++cell)
854  for (auto f : GeometryInfo<dim>::face_indices())
855  {
856  const typename Triangulation<dim, spacedim>::face_iterator face =
857  cell->face(f);
858 
859  const unsigned int offset =
860  (cell->direction_flag() ?
861  left_right_offset[dim - 2][f][cell->face_orientation(f)] :
862  1 - left_right_offset[dim - 2][f][cell->face_orientation(f)]);
863 
864  adjacent_cells[2 * face->index() + offset] = cell;
865 
866  // if this cell is not refined, but the
867  // face is, then we'll have to set our
868  // cell as neighbor for the child faces
869  // as well. Fortunately the normal
870  // orientation of children will be just
871  // the same.
872  if (dim == 2)
873  {
874  if (cell->is_active() && face->has_children())
875  {
876  adjacent_cells[2 * face->child(0)->index() + offset] = cell;
877  adjacent_cells[2 * face->child(1)->index() + offset] = cell;
878  }
879  }
880  else // -> dim == 3
881  {
882  // We need the same as in 2d
883  // here. Furthermore, if the face is
884  // refined with cut_x or cut_y then
885  // those children again in the other
886  // direction, and if this cell is
887  // refined isotropically (along the
888  // face) then the neighbor will
889  // (probably) be refined as cut_x or
890  // cut_y along the face. For those
891  // neighboring children cells, their
892  // neighbor will be the current,
893  // inactive cell, as our children are
894  // too fine to be neighbors. Catch that
895  // case by also acting on inactive
896  // cells with isotropic refinement
897  // along the face. If the situation
898  // described is not present, the data
899  // will be overwritten later on when we
900  // visit cells on finer levels, so no
901  // harm will be done.
902  if (face->has_children() &&
903  (cell->is_active() ||
905  cell->refinement_case(), f) ==
906  RefinementCase<dim - 1>::isotropic_refinement))
907  {
908  for (unsigned int c = 0; c < face->n_children(); ++c)
909  adjacent_cells[2 * face->child(c)->index() + offset] = cell;
910  if (face->child(0)->has_children())
911  {
912  adjacent_cells[2 * face->child(0)->child(0)->index() +
913  offset] = cell;
914  adjacent_cells[2 * face->child(0)->child(1)->index() +
915  offset] = cell;
916  }
917  if (face->child(1)->has_children())
918  {
919  adjacent_cells[2 * face->child(1)->child(0)->index() +
920  offset] = cell;
921  adjacent_cells[2 * face->child(1)->child(1)->index() +
922  offset] = cell;
923  }
924  } // if cell active and face refined
925  } // else -> dim==3
926  } // for all faces of all cells
927 
928  // now loop again over all cells and set the
929  // corresponding neighbor cell. Note, that we
930  // have to use the opposite of the
931  // left_right_offset in this case as we want
932  // the offset of the neighbor, not our own.
933  for (cell = triangulation.begin(); cell != endc; ++cell)
934  for (auto f : GeometryInfo<dim>::face_indices())
935  {
936  const unsigned int offset =
937  (cell->direction_flag() ?
938  left_right_offset[dim - 2][f][cell->face_orientation(f)] :
939  1 - left_right_offset[dim - 2][f][cell->face_orientation(f)]);
940  cell->set_neighbor(
941  f, adjacent_cells[2 * cell->face(f)->index() + 1 - offset]);
942  }
943  }
944 
945 
946  template <int dim, int spacedim>
947  void
948  update_periodic_face_map_recursively(
949  const typename Triangulation<dim, spacedim>::cell_iterator &cell_1,
950  const typename Triangulation<dim, spacedim>::cell_iterator &cell_2,
951  unsigned int n_face_1,
952  unsigned int n_face_2,
953  const std::bitset<3> & orientation,
954  typename std::map<
956  unsigned int>,
957  std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
958  unsigned int>,
959  std::bitset<3>>> &periodic_face_map)
960  {
961  using FaceIterator = typename Triangulation<dim, spacedim>::face_iterator;
962  const FaceIterator face_1 = cell_1->face(n_face_1);
963  const FaceIterator face_2 = cell_2->face(n_face_2);
964 
965  const bool face_orientation = orientation[0];
966  const bool face_flip = orientation[1];
967  const bool face_rotation = orientation[2];
968 
969  Assert((dim != 1) || (face_orientation == true && face_flip == false &&
970  face_rotation == false),
971  ExcMessage("The supplied orientation "
972  "(face_orientation, face_flip, face_rotation) "
973  "is invalid for 1D"));
974 
975  Assert((dim != 2) || (face_orientation == true && face_rotation == false),
976  ExcMessage("The supplied orientation "
977  "(face_orientation, face_flip, face_rotation) "
978  "is invalid for 2D"));
979 
980  Assert(face_1 != face_2, ExcMessage("face_1 and face_2 are equal!"));
981 
982  Assert(face_1->at_boundary() && face_2->at_boundary(),
983  ExcMessage("Periodic faces must be on the boundary"));
984 
985  // Check if the requirement that each edge can only have at most one hanging
986  // node, and as a consequence neighboring cells can differ by at most
987  // one refinement level is enforced. In 1d, there are no hanging nodes and
988  // so neighboring cells can differ by more than one refinement level.
989  Assert(dim == 1 || std::abs(cell_1->level() - cell_2->level()) < 2,
990  ExcInternalError());
991 
992  // insert periodic face pair for both cells
993  using CellFace =
994  std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
995  unsigned int>;
996  const CellFace cell_face_1(cell_1, n_face_1);
997  const CellFace cell_face_2(cell_2, n_face_2);
998  const std::pair<CellFace, std::bitset<3>> cell_face_orientation_2(
999  cell_face_2, orientation);
1000 
1001  const std::pair<CellFace, std::pair<CellFace, std::bitset<3>>>
1002  periodic_faces(cell_face_1, cell_face_orientation_2);
1003 
1004  // Only one periodic neighbor is allowed
1005  Assert(periodic_face_map.count(cell_face_1) == 0, ExcInternalError());
1006  periodic_face_map.insert(periodic_faces);
1007 
1008  if (dim == 1)
1009  {
1010  if (cell_1->has_children())
1011  {
1012  if (cell_2->has_children())
1013  {
1014  update_periodic_face_map_recursively<dim, spacedim>(
1015  cell_1->child(n_face_1),
1016  cell_2->child(n_face_2),
1017  n_face_1,
1018  n_face_2,
1019  orientation,
1020  periodic_face_map);
1021  }
1022  else // only face_1 has children
1023  {
1024  update_periodic_face_map_recursively<dim, spacedim>(
1025  cell_1->child(n_face_1),
1026  cell_2,
1027  n_face_1,
1028  n_face_2,
1029  orientation,
1030  periodic_face_map);
1031  }
1032  }
1033  }
1034  else // dim == 2 || dim == 3
1035  {
1036  // A lookup table on how to go through the child cells depending on the
1037  // orientation:
1038  // see Documentation of GeometryInfo for details
1039 
1040  static const int lookup_table_2d[2][2] =
1041  // flip:
1042  {
1043  {0, 1}, // false
1044  {1, 0} // true
1045  };
1046 
1047  static const int lookup_table_3d[2][2][2][4] =
1048  // orientation flip rotation
1049  {{{
1050  {0, 2, 1, 3}, // false false false
1051  {2, 3, 0, 1} // false false true
1052  },
1053  {
1054  {3, 1, 2, 0}, // false true false
1055  {1, 0, 3, 2} // false true true
1056  }},
1057  {{
1058  {0, 1, 2, 3}, // true false false
1059  {1, 3, 0, 2} // true false true
1060  },
1061  {
1062  {3, 2, 1, 0}, // true true false
1063  {2, 0, 3, 1} // true true true
1064  }}};
1065 
1066  if (cell_1->has_children())
1067  {
1068  if (cell_2->has_children())
1069  {
1070  // In the case that both faces have children, we loop over all
1071  // children and apply update_periodic_face_map_recursively
1072  // recursively:
1073 
1074  Assert(face_1->n_children() ==
1076  face_2->n_children() ==
1078  ExcNotImplemented());
1079 
1080  for (unsigned int i = 0;
1081  i < GeometryInfo<dim>::max_children_per_face;
1082  ++i)
1083  {
1084  // Lookup the index for the second face
1085  unsigned int j = 0;
1086  switch (dim)
1087  {
1088  case 2:
1089  j = lookup_table_2d[face_flip][i];
1090  break;
1091  case 3:
1092  j = lookup_table_3d[face_orientation][face_flip]
1093  [face_rotation][i];
1094  break;
1095  default:
1096  AssertThrow(false, ExcNotImplemented());
1097  }
1098 
1099  // find subcell ids that belong to the subface indices
1100  unsigned int child_cell_1 =
1102  cell_1->refinement_case(),
1103  n_face_1,
1104  i,
1105  cell_1->face_orientation(n_face_1),
1106  cell_1->face_flip(n_face_1),
1107  cell_1->face_rotation(n_face_1),
1108  face_1->refinement_case());
1109  unsigned int child_cell_2 =
1111  cell_2->refinement_case(),
1112  n_face_2,
1113  j,
1114  cell_2->face_orientation(n_face_2),
1115  cell_2->face_flip(n_face_2),
1116  cell_2->face_rotation(n_face_2),
1117  face_2->refinement_case());
1118 
1119  Assert(cell_1->child(child_cell_1)->face(n_face_1) ==
1120  face_1->child(i),
1121  ExcInternalError());
1122  Assert(cell_2->child(child_cell_2)->face(n_face_2) ==
1123  face_2->child(j),
1124  ExcInternalError());
1125 
1126  // precondition: subcell has the same orientation as cell
1127  // (so that the face numbers coincide) recursive call
1128  update_periodic_face_map_recursively<dim, spacedim>(
1129  cell_1->child(child_cell_1),
1130  cell_2->child(child_cell_2),
1131  n_face_1,
1132  n_face_2,
1133  orientation,
1134  periodic_face_map);
1135  }
1136  }
1137  else // only face_1 has children
1138  {
1139  for (unsigned int i = 0;
1140  i < GeometryInfo<dim>::max_children_per_face;
1141  ++i)
1142  {
1143  // find subcell ids that belong to the subface indices
1144  unsigned int child_cell_1 =
1146  cell_1->refinement_case(),
1147  n_face_1,
1148  i,
1149  cell_1->face_orientation(n_face_1),
1150  cell_1->face_flip(n_face_1),
1151  cell_1->face_rotation(n_face_1),
1152  face_1->refinement_case());
1153 
1154  // recursive call
1155  update_periodic_face_map_recursively<dim, spacedim>(
1156  cell_1->child(child_cell_1),
1157  cell_2,
1158  n_face_1,
1159  n_face_2,
1160  orientation,
1161  periodic_face_map);
1162  }
1163  }
1164  }
1165  }
1166  }
1167 
1168 
1169 } // end of anonymous namespace
1170 
1171 
1172 namespace internal
1173 {
1174  namespace TriangulationImplementation
1175  {
1176  // make sure that if in the following we
1177  // write Triangulation<dim,spacedim>
1178  // we mean the *class*
1179  // ::Triangulation, not the
1180  // enclosing namespace
1181  // internal::TriangulationImplementation
1183 
1189  int,
1190  << "Something went wrong when making cell " << arg1
1191  << ". Read the docs and the source code "
1192  << "for more information.");
1198  int,
1199  << "Something went wrong upon construction of cell "
1200  << arg1);
1211  int,
1212  << "Cell " << arg1
1213  << " has negative measure. This typically "
1214  << "indicates some distortion in the cell, or a mistakenly "
1215  << "swapped pair of vertices in the input to "
1216  << "Triangulation::create_triangulation().");
1225  int,
1226  int,
1227  int,
1228  << "Error while creating cell " << arg1
1229  << ": the vertex index " << arg2 << " must be between 0 and "
1230  << arg3 << ".");
1236  int,
1237  int,
1238  << "While trying to assign a boundary indicator to a line: "
1239  << "the line with end vertices " << arg1 << " and " << arg2
1240  << " does not exist.");
1246  int,
1247  int,
1248  int,
1249  int,
1250  << "While trying to assign a boundary indicator to a quad: "
1251  << "the quad with bounding lines " << arg1 << ", " << arg2
1252  << ", " << arg3 << ", " << arg4 << " does not exist.");
1259  int,
1260  int,
1262  << "The input data for creating a triangulation contained "
1263  << "information about a line with indices " << arg1 << " and " << arg2
1264  << " that is described to have boundary indicator "
1265  << static_cast<int>(arg3)
1266  << ". However, this is an internal line not located on the "
1267  << "boundary. You cannot assign a boundary indicator to it." << std::endl
1268  << std::endl
1269  << "If this happened at a place where you call "
1270  << "Triangulation::create_triangulation() yourself, you need "
1271  << "to check the SubCellData object you pass to this function."
1272  << std::endl
1273  << std::endl
1274  << "If this happened in a place where you are reading a mesh "
1275  << "from a file, then you need to investigate why such a line "
1276  << "ended up in the input file. A typical case is a geometry "
1277  << "that consisted of multiple parts and for which the mesh "
1278  << "generator program assumes that the interface between "
1279  << "two parts is a boundary when that isn't supposed to be "
1280  << "the case, or where the mesh generator simply assigns "
1281  << "'geometry indicators' to lines at the perimeter of "
1282  << "a part that are not supposed to be interpreted as "
1283  << "'boundary indicators'.");
1290  int,
1291  int,
1292  int,
1293  int,
1295  << "The input data for creating a triangulation contained "
1296  << "information about a quad with indices " << arg1 << ", " << arg2
1297  << ", " << arg3 << ", and " << arg4
1298  << " that is described to have boundary indicator "
1299  << static_cast<int>(arg5)
1300  << ". However, this is an internal quad not located on the "
1301  << "boundary. You cannot assign a boundary indicator to it." << std::endl
1302  << std::endl
1303  << "If this happened at a place where you call "
1304  << "Triangulation::create_triangulation() yourself, you need "
1305  << "to check the SubCellData object you pass to this function."
1306  << std::endl
1307  << std::endl
1308  << "If this happened in a place where you are reading a mesh "
1309  << "from a file, then you need to investigate why such a quad "
1310  << "ended up in the input file. A typical case is a geometry "
1311  << "that consisted of multiple parts and for which the mesh "
1312  << "generator program assumes that the interface between "
1313  << "two parts is a boundary when that isn't supposed to be "
1314  << "the case, or where the mesh generator simply assigns "
1315  << "'geometry indicators' to quads at the surface of "
1316  << "a part that are not supposed to be interpreted as "
1317  << "'boundary indicators'.");
1324  int,
1325  int,
1326  << "In SubCellData the line info of the line with vertex indices " << arg1
1327  << " and " << arg2 << " appears more than once. "
1328  << "This is not allowed.");
1335  int,
1336  int,
1337  std::string,
1338  << "In SubCellData the line info of the line with vertex indices " << arg1
1339  << " and " << arg2 << " appears multiple times with different (valid) "
1340  << arg3 << ". This is not allowed.");
1347  int,
1348  int,
1349  int,
1350  int,
1351  std::string,
1352  << "In SubCellData the quad info of the quad with line indices " << arg1
1353  << ", " << arg2 << ", " << arg3 << " and " << arg4
1354  << " appears multiple times with different (valid) " << arg5
1355  << ". This is not allowed.");
1356 
1453  {
1465  template <int dim, int spacedim>
1466  static void
1469  const unsigned int level_objects,
1471  {
1472  using line_iterator =
1474 
1475  number_cache.n_levels = 0;
1476  if (level_objects > 0)
1477  // find the last level on which there are used cells
1478  for (unsigned int level = 0; level < level_objects; ++level)
1479  if (triangulation.begin(level) != triangulation.end(level))
1480  number_cache.n_levels = level + 1;
1481 
1482  // no cells at all?
1483  Assert(number_cache.n_levels > 0, ExcInternalError());
1484 
1486  // update the number of lines on the different levels in the
1487  // cache
1488  number_cache.n_lines = 0;
1489  number_cache.n_active_lines = 0;
1490 
1491  // for 1d, lines have levels so take count the objects per
1492  // level and globally
1493  if (dim == 1)
1494  {
1495  number_cache.n_lines_level.resize(number_cache.n_levels);
1496  number_cache.n_active_lines_level.resize(number_cache.n_levels);
1497 
1498  for (unsigned int level = 0; level < number_cache.n_levels; ++level)
1499  {
1500  // count lines on this level
1501  number_cache.n_lines_level[level] = 0;
1502  number_cache.n_active_lines_level[level] = 0;
1503 
1504  line_iterator line = triangulation.begin_line(level),
1505  endc =
1506  (level == number_cache.n_levels - 1 ?
1507  line_iterator(triangulation.end_line()) :
1508  triangulation.begin_line(level + 1));
1509  for (; line != endc; ++line)
1510  {
1511  ++number_cache.n_lines_level[level];
1512  if (line->has_children() == false)
1513  ++number_cache.n_active_lines_level[level];
1514  }
1515 
1516  // update total number of lines
1517  number_cache.n_lines += number_cache.n_lines_level[level];
1518  number_cache.n_active_lines +=
1519  number_cache.n_active_lines_level[level];
1520  }
1521  }
1522  else
1523  {
1524  // for dim>1, there are no levels for lines
1525  number_cache.n_lines_level.clear();
1526  number_cache.n_active_lines_level.clear();
1527 
1528  line_iterator line = triangulation.begin_line(),
1529  endc = triangulation.end_line();
1530  for (; line != endc; ++line)
1531  {
1532  ++number_cache.n_lines;
1533  if (line->has_children() == false)
1534  ++number_cache.n_active_lines;
1535  }
1536  }
1537  }
1538 
1553  template <int dim, int spacedim>
1554  static void
1557  const unsigned int level_objects,
1559  {
1560  // update lines and n_levels in number_cache. since we don't
1561  // access any of these numbers, we can do this in the
1562  // background
1563  Threads::Task<void> update_lines = Threads::new_task(
1564  static_cast<
1565  void (*)(const Triangulation<dim, spacedim> &,
1566  const unsigned int,
1568  &compute_number_cache<dim, spacedim>),
1569  triangulation,
1570  level_objects,
1572  number_cache));
1573 
1574  using quad_iterator =
1576 
1578  // update the number of quads on the different levels in the
1579  // cache
1580  number_cache.n_quads = 0;
1581  number_cache.n_active_quads = 0;
1582 
1583  // for 2d, quads have levels so take count the objects per
1584  // level and globally
1585  if (dim == 2)
1586  {
1587  // count the number of levels; the function we called above
1588  // on a separate Task for lines also does this and puts it into
1589  // number_cache.n_levels, but this datum may not yet be
1590  // available as we call the function on a separate task
1591  unsigned int n_levels = 0;
1592  if (level_objects > 0)
1593  // find the last level on which there are used cells
1594  for (unsigned int level = 0; level < level_objects; ++level)
1595  if (triangulation.begin(level) != triangulation.end(level))
1596  n_levels = level + 1;
1597 
1598  number_cache.n_quads_level.resize(n_levels);
1599  number_cache.n_active_quads_level.resize(n_levels);
1600 
1601  for (unsigned int level = 0; level < n_levels; ++level)
1602  {
1603  // count quads on this level
1604  number_cache.n_quads_level[level] = 0;
1605  number_cache.n_active_quads_level[level] = 0;
1606 
1607  quad_iterator quad = triangulation.begin_quad(level),
1608  endc =
1609  (level == n_levels - 1 ?
1610  quad_iterator(triangulation.end_quad()) :
1611  triangulation.begin_quad(level + 1));
1612  for (; quad != endc; ++quad)
1613  {
1614  ++number_cache.n_quads_level[level];
1615  if (quad->has_children() == false)
1616  ++number_cache.n_active_quads_level[level];
1617  }
1618 
1619  // update total number of quads
1620  number_cache.n_quads += number_cache.n_quads_level[level];
1621  number_cache.n_active_quads +=
1622  number_cache.n_active_quads_level[level];
1623  }
1624  }
1625  else
1626  {
1627  // for dim>2, there are no levels for quads
1628  number_cache.n_quads_level.clear();
1629  number_cache.n_active_quads_level.clear();
1630 
1631  quad_iterator quad = triangulation.begin_quad(),
1632  endc = triangulation.end_quad();
1633  for (; quad != endc; ++quad)
1634  {
1635  ++number_cache.n_quads;
1636  if (quad->has_children() == false)
1637  ++number_cache.n_active_quads;
1638  }
1639  }
1640 
1641  // wait for the background computation for lines
1642  update_lines.join();
1643  }
1644 
1660  template <int dim, int spacedim>
1661  static void
1664  const unsigned int level_objects,
1666  {
1667  // update quads, lines and n_levels in number_cache. since we
1668  // don't access any of these numbers, we can do this in the
1669  // background
1670  Threads::Task<void> update_quads_and_lines = Threads::new_task(
1671  static_cast<
1672  void (*)(const Triangulation<dim, spacedim> &,
1673  const unsigned int,
1675  &compute_number_cache<dim, spacedim>),
1676  triangulation,
1677  level_objects,
1679  number_cache));
1680 
1681  using hex_iterator =
1683 
1685  // update the number of hexes on the different levels in the
1686  // cache
1687  number_cache.n_hexes = 0;
1688  number_cache.n_active_hexes = 0;
1689 
1690  // for 3d, hexes have levels so take count the objects per
1691  // level and globally
1692  if (dim == 3)
1693  {
1694  // count the number of levels; the function we called
1695  // above on a separate Task for quads (recursively, via
1696  // the lines function) also does this and puts it into
1697  // number_cache.n_levels, but this datum may not yet be
1698  // available as we call the function on a separate task
1699  unsigned int n_levels = 0;
1700  if (level_objects > 0)
1701  // find the last level on which there are used cells
1702  for (unsigned int level = 0; level < level_objects; ++level)
1703  if (triangulation.begin(level) != triangulation.end(level))
1704  n_levels = level + 1;
1705 
1706  number_cache.n_hexes_level.resize(n_levels);
1707  number_cache.n_active_hexes_level.resize(n_levels);
1708 
1709  for (unsigned int level = 0; level < n_levels; ++level)
1710  {
1711  // count hexes on this level
1712  number_cache.n_hexes_level[level] = 0;
1713  number_cache.n_active_hexes_level[level] = 0;
1714 
1715  hex_iterator hex = triangulation.begin_hex(level),
1716  endc = (level == n_levels - 1 ?
1717  hex_iterator(triangulation.end_hex()) :
1718  triangulation.begin_hex(level + 1));
1719  for (; hex != endc; ++hex)
1720  {
1721  ++number_cache.n_hexes_level[level];
1722  if (hex->has_children() == false)
1723  ++number_cache.n_active_hexes_level[level];
1724  }
1725 
1726  // update total number of hexes
1727  number_cache.n_hexes += number_cache.n_hexes_level[level];
1728  number_cache.n_active_hexes +=
1729  number_cache.n_active_hexes_level[level];
1730  }
1731  }
1732  else
1733  {
1734  // for dim>3, there are no levels for hexes
1735  number_cache.n_hexes_level.clear();
1736  number_cache.n_active_hexes_level.clear();
1737 
1738  hex_iterator hex = triangulation.begin_hex(),
1739  endc = triangulation.end_hex();
1740  for (; hex != endc; ++hex)
1741  {
1742  ++number_cache.n_hexes;
1743  if (hex->has_children() == false)
1744  ++number_cache.n_active_hexes;
1745  }
1746  }
1747 
1748  // wait for the background computation for quads
1749  update_quads_and_lines.join();
1750  }
1751 
1752 
1760  template <int spacedim>
1761  static void
1762  create_triangulation(const std::vector<Point<spacedim>> &v,
1763  const std::vector<CellData<1>> & cells,
1764  const SubCellData & /*subcelldata*/,
1766  {
1767  AssertThrow(v.size() > 0, ExcMessage("No vertices given"));
1768  AssertThrow(cells.size() > 0, ExcMessage("No cells given"));
1769 
1770  // note: since no boundary
1771  // information can be given in one
1772  // dimension, the @p{subcelldata}
1773  // field is ignored. (only used for
1774  // error checking, which is a good
1775  // idea in any case)
1776  const unsigned int dim = 1;
1777 
1778  // copy vertices
1779  triangulation.vertices = v;
1780  triangulation.vertices_used = std::vector<bool>(v.size(), true);
1781 
1782  // Check that all cells have positive volume. This check is not run in
1783  // the codimension one or two cases since cell_measure is not
1784  // implemented for those.
1785 #ifndef _MSC_VER
1786  // TODO: The following code does not compile with MSVC. Find a way
1787  // around it
1788  if (dim == spacedim)
1789  {
1790  for (unsigned int cell_no = 0; cell_no < cells.size(); ++cell_no)
1791  {
1792  // If we should check for distorted cells, then we permit them
1793  // to exist. If a cell has negative measure, then it must be
1794  // distorted (the converse is not necessarily true); hence
1795  // throw an exception if no such cells should exist.
1796  if (!triangulation.check_for_distorted_cells)
1797  {
1798  const double cell_measure =
1800  cells[cell_no].vertices);
1802  ExcGridHasInvalidCell(cell_no));
1803  }
1804  }
1805  }
1806 #endif
1807 
1808 
1809  // store the indices of the lines
1810  // which are adjacent to a given
1811  // vertex
1812  std::vector<std::vector<int>> lines_at_vertex(v.size());
1813 
1814  // reserve enough space
1815  triangulation.levels.push_back(
1816  std_cxx14::make_unique<
1818  triangulation.levels[0]->reserve_space(cells.size(), dim, spacedim);
1819  triangulation.levels[0]->cells.reserve_space(0, cells.size());
1820 
1821  // make up cells
1823  next_free_line = triangulation.begin_raw_line();
1824  for (unsigned int cell = 0; cell < cells.size(); ++cell)
1825  {
1826  while (next_free_line->used())
1827  ++next_free_line;
1828 
1829  next_free_line->set(
1831  cells[cell].vertices[0], cells[cell].vertices[1]));
1832  next_free_line->set_used_flag();
1833  next_free_line->set_material_id(cells[cell].material_id);
1834  next_free_line->set_manifold_id(cells[cell].manifold_id);
1835  next_free_line->clear_user_data();
1836  next_free_line->set_subdomain_id(0);
1837 
1838  // note that this cell is
1839  // adjacent to these vertices
1840  lines_at_vertex[cells[cell].vertices[0]].push_back(cell);
1841  lines_at_vertex[cells[cell].vertices[1]].push_back(cell);
1842  }
1843 
1844 
1845  // some security tests
1846  {
1847  unsigned int boundary_nodes = 0;
1848  for (const auto &line : lines_at_vertex)
1849  switch (line.size())
1850  {
1851  case 1:
1852  // this vertex has only
1853  // one adjacent line
1854  ++boundary_nodes;
1855  break;
1856  case 2:
1857  break;
1858  default:
1859  AssertThrow(
1860  false,
1861  ExcMessage(
1862  "You have a vertex in your triangulation "
1863  "at which more than two cells come together. "
1864  "(For one dimensional triangulation, cells are "
1865  "line segments.)"
1866  "\n\n"
1867  "This is not currently supported because the "
1868  "Triangulation class makes the assumption that "
1869  "every cell has zero or one neighbors behind "
1870  "each face (here, behind each vertex), but in your "
1871  "situation there would be more than one."
1872  "\n\n"
1873  "Support for this is not currently implemented. "
1874  "If you need to work with triangulations where "
1875  "more than two cells come together at a vertex, "
1876  "duplicate the vertices once per cell (i.e., put "
1877  "multiple vertices at the same physical location, "
1878  "but using different vertex indices for each) "
1879  "and then ensure continuity of the solution by "
1880  "explicitly creating constraints that the degrees "
1881  "of freedom at these vertices have the same "
1882  "value, using the AffineConstraints class."));
1883  }
1884  }
1885 
1886 
1887 
1888  // update neighborship info
1890  triangulation.begin_active_line();
1891  // for all lines
1892  for (; line != triangulation.end(); ++line)
1893  // for each of the two vertices
1894  for (const unsigned int vertex : GeometryInfo<dim>::vertex_indices())
1895  // if first cell adjacent to
1896  // this vertex is the present
1897  // one, then the neighbor is
1898  // the second adjacent cell and
1899  // vice versa
1900  if (lines_at_vertex[line->vertex_index(vertex)][0] == line->index())
1901  if (lines_at_vertex[line->vertex_index(vertex)].size() == 2)
1902  {
1904  neighbor(&triangulation,
1905  0, // level
1906  lines_at_vertex[line->vertex_index(vertex)][1]);
1907  line->set_neighbor(vertex, neighbor);
1908  }
1909  else
1910  // no second adjacent cell
1911  // entered -> cell at
1912  // boundary
1913  line->set_neighbor(vertex, triangulation.end());
1914  else
1915  // present line is not first
1916  // adjacent one -> first
1917  // adjacent one is neighbor
1918  {
1920  neighbor(&triangulation,
1921  0, // level
1922  lines_at_vertex[line->vertex_index(vertex)][0]);
1923  line->set_neighbor(vertex, neighbor);
1924  }
1925 
1926  // finally set the
1927  // vertex_to_boundary_id_map_1d
1928  // and vertex_to_manifold_id_map_1d
1929  // maps
1930  triangulation.vertex_to_boundary_id_map_1d->clear();
1931  triangulation.vertex_to_manifold_id_map_1d->clear();
1932  for (const auto &cell : triangulation.active_cell_iterators())
1933  for (auto f : GeometryInfo<dim>::face_indices())
1934  {
1935  (*triangulation.vertex_to_manifold_id_map_1d)
1936  [cell->face(f)->vertex_index()] = numbers::flat_manifold_id;
1937 
1938  if (cell->at_boundary(f))
1939  (*triangulation.vertex_to_boundary_id_map_1d)
1940  [cell->face(f)->vertex_index()] = f;
1941  }
1942  }
1943 
1944 
1952  template <int spacedim>
1953  static void
1954  create_triangulation(const std::vector<Point<spacedim>> &v,
1955  const std::vector<CellData<2>> & cells,
1956  const SubCellData & subcelldata,
1958  {
1959  AssertThrow(v.size() > 0, ExcMessage("No vertices given"));
1960  AssertThrow(cells.size() > 0, ExcMessage("No cells given"));
1961 
1962  const unsigned int dim = 2;
1963 
1964  // copy vertices
1965  triangulation.vertices = v;
1966  triangulation.vertices_used = std::vector<bool>(v.size(), true);
1967 
1968  // Check that all cells have positive volume. This check is not run in
1969  // the codimension one or two cases since cell_measure is not
1970  // implemented for those.
1971 #ifndef _MSC_VER
1972  // TODO: The following code does not compile with MSVC. Find a way
1973  // around it
1974  if (dim == spacedim)
1975  {
1976  for (unsigned int cell_no = 0; cell_no < cells.size(); ++cell_no)
1977  {
1978  // See the note in the 1D function on this if statement.
1979  if (!triangulation.check_for_distorted_cells)
1980  {
1981  const double cell_measure =
1983  cells[cell_no].vertices);
1985  ExcGridHasInvalidCell(cell_no));
1986  }
1987  }
1988  }
1989 #endif
1990 
1991  // make up a list of the needed
1992  // lines each line is a pair of
1993  // vertices. The list is kept
1994  // sorted and it is guaranteed that
1995  // each line is inserted only once.
1996  // While the key of such an entry
1997  // is the pair of vertices, the
1998  // thing it points to is an
1999  // iterator pointing to the line
2000  // object itself. In the first run,
2001  // these iterators are all invalid
2002  // ones, but they are filled
2003  // afterwards
2004  std::map<std::pair<int, int>,
2006  needed_lines;
2007  for (unsigned int cell = 0; cell < cells.size(); ++cell)
2008  {
2009  for (const auto vertex : cells[cell].vertices)
2010  AssertThrow(vertex < triangulation.vertices.size(),
2011  ExcInvalidVertexIndex(cell,
2012  vertex,
2013  triangulation.vertices.size()));
2014 
2015  for (const unsigned int line : GeometryInfo<dim>::face_indices())
2016  {
2017  // given a line vertex number (0,1) on a specific line
2018  // we get the cell vertex number (0-4) through the
2019  // line_to_cell_vertices function
2020  std::pair<int, int> line_vertices(
2022  line, 0)],
2024  line, 1)]);
2025 
2026  // assert that the line was not already inserted in
2027  // reverse order. This happens in spite of the vertex
2028  // rotation above, if the sense of the cell was
2029  // incorrect.
2030  //
2031  // Here is what usually happened when this exception
2032  // is thrown: consider these two cells and the
2033  // vertices
2034  // 3---4---5
2035  // | | |
2036  // 0---1---2
2037  // If in the input vector the two cells are given with
2038  // vertices <0 1 3 4> and <4 1 5 2>, in the first cell
2039  // the middle line would have direction 1->4, while in
2040  // the second it would be 4->1. This will cause the
2041  // exception.
2042  AssertThrow(needed_lines.find(std::make_pair(
2043  line_vertices.second, line_vertices.first)) ==
2044  needed_lines.end(),
2045  ExcGridHasInvalidCell(cell));
2046 
2047  // insert line, with
2048  // invalid iterator if line
2049  // already exists, then
2050  // nothing bad happens here
2051  needed_lines[line_vertices] = triangulation.end_line();
2052  }
2053  }
2054 
2055 
2056  // check that every vertex has at
2057  // least two adjacent lines
2058  {
2059  std::vector<unsigned short int> vertex_touch_count(v.size(), 0);
2060  typename std::map<
2061  std::pair<int, int>,
2062  typename Triangulation<dim, spacedim>::line_iterator>::iterator i;
2063  for (i = needed_lines.begin(); i != needed_lines.end(); ++i)
2064  {
2065  // touch the vertices of
2066  // this line
2067  ++vertex_touch_count[i->first.first];
2068  ++vertex_touch_count[i->first.second];
2069  }
2070 
2071  // assert minimum touch count
2072  // is at least two. if not so,
2073  // then clean triangulation and
2074  // exit with an exception
2075  AssertThrow(*(std::min_element(vertex_touch_count.begin(),
2076  vertex_touch_count.end())) >= 2,
2077  ExcMessage(
2078  "During creation of a triangulation, a part of the "
2079  "algorithm encountered a vertex that is part of only "
2080  "a single adjacent line. However, in 2d, every vertex "
2081  "needs to be at least part of two lines."));
2082  }
2083 
2084  // reserve enough space
2085  triangulation.levels.push_back(
2086  std_cxx14::make_unique<
2088  triangulation.faces = std_cxx14::make_unique<
2090  triangulation.levels[0]->reserve_space(cells.size(), dim, spacedim);
2091  triangulation.faces->lines.reserve_space(0, needed_lines.size());
2092  triangulation.levels[0]->cells.reserve_space(0, cells.size());
2093 
2094  // make up lines
2095  {
2097  triangulation.begin_raw_line();
2098  typename std::map<
2099  std::pair<int, int>,
2100  typename Triangulation<dim, spacedim>::line_iterator>::iterator i;
2101  for (i = needed_lines.begin(); line != triangulation.end_line();
2102  ++line, ++i)
2103  {
2105  i->first.first, i->first.second));
2106  line->set_used_flag();
2107  line->clear_user_flag();
2108  line->clear_user_data();
2109  i->second = line;
2110  }
2111  }
2112 
2113 
2114  // store for each line index
2115  // the adjacent cells
2116  std::map<
2117  int,
2118  std::vector<typename Triangulation<dim, spacedim>::cell_iterator>>
2119  adjacent_cells;
2120 
2121  // finally make up cells
2122  {
2124  triangulation.begin_raw_quad();
2125  for (unsigned int c = 0; c < cells.size(); ++c, ++cell)
2126  {
2129  for (unsigned int line = 0;
2130  line < GeometryInfo<dim>::lines_per_cell;
2131  ++line)
2132  lines[line] = needed_lines[std::make_pair(
2134  line, 0)],
2135  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2136  line, 1)])];
2137 
2139  lines[0]->index(),
2140  lines[1]->index(),
2141  lines[2]->index(),
2142  lines[3]->index()));
2143 
2144  cell->set_used_flag();
2145  cell->set_material_id(cells[c].material_id);
2146  cell->set_manifold_id(cells[c].manifold_id);
2147  cell->clear_user_data();
2148  cell->set_subdomain_id(0);
2149 
2150  // note that this cell is
2151  // adjacent to the four
2152  // lines
2153  for (const auto &line : lines)
2154  adjacent_cells[line->index()].push_back(cell);
2155  }
2156  }
2157 
2158 
2159  for (typename Triangulation<dim, spacedim>::line_iterator line =
2160  triangulation.begin_line();
2161  line != triangulation.end_line();
2162  ++line)
2163  {
2164  const unsigned int n_adj_cells =
2165  adjacent_cells[line->index()].size();
2166 
2167  // assert that every line has one or two adjacent cells.
2168  // this has to be the case for 2d triangulations in 2d.
2169  // in higher dimensions, this may happen but is not
2170  // implemented
2171  if (spacedim == 2)
2172  {
2173  AssertThrow((n_adj_cells >= 1) && (n_adj_cells <= 2),
2174  ExcInternalError());
2175  }
2176  else
2177  {
2178  AssertThrow(
2179  (n_adj_cells >= 1) && (n_adj_cells <= 2),
2180  ExcMessage("You have a line in your triangulation at which "
2181  "more than two cells come together."
2182  "\n\n"
2183  "This is not currently supported because the "
2184  "Triangulation class makes the assumption that "
2185  "every cell has zero or one neighbors behind each "
2186  "face (here, behind each line), but in your "
2187  "situation there would be more than one."
2188  "\n\n"
2189  "Support for this is not currently implemented. "
2190  "If you need to work with triangulations where "
2191  "more than two cells come together at a line, "
2192  "duplicate the vertices once per cell (i.e., put "
2193  "multiple vertices at the same physical location, "
2194  "but using different vertex indices for each) "
2195  "and then ensure continuity of the solution by "
2196  "explicitly creating constraints that the degrees "
2197  "of freedom at these lines have the same "
2198  "value, using the AffineConstraints class."));
2199  }
2200 
2201  // if only one cell: line is at boundary -> give it the boundary
2202  // indicator zero by default
2203  line->set_boundary_id_internal(
2204  (n_adj_cells == 1) ? 0 : numbers::internal_face_boundary_id);
2205  line->set_manifold_id(numbers::flat_manifold_id);
2206  }
2207 
2208  // set boundary indicators where given
2209  for (const auto &subcell_line : subcelldata.boundary_lines)
2210  {
2212  std::pair<int, int> line_vertices(
2213  std::make_pair(subcell_line.vertices[0],
2214  subcell_line.vertices[1]));
2215  if (needed_lines.find(line_vertices) != needed_lines.end())
2216  // line found in this direction
2217  line = needed_lines[line_vertices];
2218  else
2219  {
2220  // look whether it exists in reverse direction
2221  std::swap(line_vertices.first, line_vertices.second);
2222  if (needed_lines.find(line_vertices) != needed_lines.end())
2223  line = needed_lines[line_vertices];
2224  else
2225  // line does not exist
2226  AssertThrow(false,
2227  ExcLineInexistant(line_vertices.first,
2228  line_vertices.second));
2229  }
2230 
2231  // assert that we only set boundary info once
2232  AssertThrow(!(line->boundary_id() != 0 &&
2233  line->boundary_id() !=
2235  ExcMultiplySetLineInfoOfLine(line_vertices.first,
2236  line_vertices.second));
2237 
2238  // assert that the manifold id is not yet set or consistent
2239  // with the previous id
2240  AssertThrow(line->manifold_id() == numbers::flat_manifold_id ||
2241  line->manifold_id() == subcell_line.manifold_id,
2242  ExcInconsistentLineInfoOfLine(line_vertices.first,
2243  line_vertices.second,
2244  "manifold ids"));
2245  line->set_manifold_id(subcell_line.manifold_id);
2246 
2247  // assert that only exterior lines are given a boundary
2248  // indicator
2249  if (subcell_line.boundary_id != numbers::internal_face_boundary_id)
2250  {
2251  AssertThrow(
2252  line->boundary_id() != numbers::internal_face_boundary_id,
2253  ExcInteriorLineCantBeBoundary(line->vertex_index(0),
2254  line->vertex_index(1),
2255  subcell_line.boundary_id));
2256  line->set_boundary_id_internal(subcell_line.boundary_id);
2257  }
2258  }
2259 
2260 
2261  // finally update neighborship info
2262  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
2263  triangulation.begin();
2264  cell != triangulation.end();
2265  ++cell)
2266  for (unsigned int side = 0; side < 4; ++side)
2267  if (adjacent_cells[cell->line(side)->index()][0] == cell)
2268  // first adjacent cell is
2269  // this one
2270  {
2271  if (adjacent_cells[cell->line(side)->index()].size() == 2)
2272  // there is another
2273  // adjacent cell
2274  cell->set_neighbor(
2275  side, adjacent_cells[cell->line(side)->index()][1]);
2276  }
2277  // first adjacent cell is not this
2278  // one, -> it must be the neighbor
2279  // we are looking for
2280  else
2281  cell->set_neighbor(side,
2282  adjacent_cells[cell->line(side)->index()][0]);
2283  }
2284 
2285 
2297  {
2298  inline bool
2302  {
2303  // here is room to
2304  // optimize the repeated
2305  // equality test of the
2306  // previous lines; the
2307  // compiler will probably
2308  // take care of most of
2309  // it anyway
2310  if ((q1.face(0) < q2.face(0)) ||
2311  ((q1.face(0) == q2.face(0)) && (q1.face(1) < q2.face(1))) ||
2312  ((q1.face(0) == q2.face(0)) && (q1.face(1) == q2.face(1)) &&
2313  (q1.face(2) < q2.face(2))) ||
2314  ((q1.face(0) == q2.face(0)) && (q1.face(1) == q2.face(1)) &&
2315  (q1.face(2) == q2.face(2)) && (q1.face(3) < q2.face(3))))
2316  return true;
2317  else
2318  return false;
2319  }
2320  };
2321 
2322 
2330  template <int spacedim>
2331  static void
2332  create_triangulation(const std::vector<Point<spacedim>> &v,
2333  const std::vector<CellData<3>> & cells,
2334  const SubCellData & subcelldata,
2336  {
2337  AssertThrow(v.size() > 0, ExcMessage("No vertices given"));
2338  AssertThrow(cells.size() > 0, ExcMessage("No cells given"));
2339 
2340  const unsigned int dim = 3;
2341 
2342  // copy vertices
2343  triangulation.vertices = v;
2344  triangulation.vertices_used = std::vector<bool>(v.size(), true);
2345 
2346  // Check that all cells have positive volume.
2347 #ifndef _MSC_VER
2348  // TODO: The following code does not compile with MSVC. Find a way
2349  // around it
2350  for (unsigned int cell_no = 0; cell_no < cells.size(); ++cell_no)
2351  {
2352  // See the note in the 1D function on this if statement.
2353  if (!triangulation.check_for_distorted_cells)
2354  {
2355  const double cell_measure =
2357  cells[cell_no].vertices);
2359  }
2360  }
2361 #endif
2362 
2364  // first set up some collections of data
2365  //
2366  // make up a list of the needed
2367  // lines
2368  //
2369  // each line is a pair of
2370  // vertices. The list is kept
2371  // sorted and it is guaranteed that
2372  // each line is inserted only once.
2373  // While the key of such an entry
2374  // is the pair of vertices, the
2375  // thing it points to is an
2376  // iterator pointing to the line
2377  // object itself. In the first run,
2378  // these iterators are all invalid
2379  // ones, but they are filled
2380  // afterwards same applies for the
2381  // quads
2382  typename std::map<std::pair<int, int>,
2384  needed_lines;
2385  for (unsigned int cell = 0; cell < cells.size(); ++cell)
2386  {
2387  // check whether vertex indices
2388  // are valid ones
2389  for (const auto vertex : cells[cell].vertices)
2390  AssertThrow(vertex < triangulation.vertices.size(),
2391  ExcInvalidVertexIndex(cell,
2392  vertex,
2393  triangulation.vertices.size()));
2394 
2395  for (unsigned int line = 0;
2396  line < GeometryInfo<dim>::lines_per_cell;
2397  ++line)
2398  {
2399  // given a line vertex number
2400  // (0,1) on a specific line we
2401  // get the cell vertex number
2402  // (0-7) through the
2403  // line_to_cell_vertices
2404  // function
2405  std::pair<int, int> line_vertices(
2407  line, 0)],
2409  line, 1)]);
2410 
2411  // if that line was already inserted
2412  // in reverse order do nothing, else
2413  // insert the line
2414  if ((needed_lines.find(std::make_pair(line_vertices.second,
2415  line_vertices.first)) ==
2416  needed_lines.end()))
2417  {
2418  // insert line, with
2419  // invalid iterator. if line
2420  // already exists, then
2421  // nothing bad happens here
2422  needed_lines[line_vertices] = triangulation.end_line();
2423  }
2424  }
2425  }
2426 
2427 
2429  // now for some sanity-checks:
2430  //
2431  // check that every vertex has at
2432  // least tree adjacent lines
2433  {
2434  std::vector<unsigned short int> vertex_touch_count(v.size(), 0);
2435  typename std::map<
2436  std::pair<int, int>,
2437  typename Triangulation<dim, spacedim>::line_iterator>::iterator i;
2438  for (i = needed_lines.begin(); i != needed_lines.end(); ++i)
2439  {
2440  // touch the vertices of
2441  // this line
2442  ++vertex_touch_count[i->first.first];
2443  ++vertex_touch_count[i->first.second];
2444  }
2445 
2446  // assert minimum touch count
2447  // is at least three. if not so,
2448  // then clean triangulation and
2449  // exit with an exception
2450  AssertThrow(
2451  *(std::min_element(vertex_touch_count.begin(),
2452  vertex_touch_count.end())) >= 3,
2453  ExcMessage(
2454  "During creation of a triangulation, a part of the "
2455  "algorithm encountered a vertex that is part of only "
2456  "one or two adjacent lines. However, in 3d, every vertex "
2457  "needs to be at least part of three lines."));
2458  }
2459 
2460 
2462  // actually set up data structures
2463  // for the lines
2464  // reserve enough space
2465  triangulation.levels.push_back(
2466  std_cxx14::make_unique<
2468  triangulation.faces = std_cxx14::make_unique<
2470  triangulation.levels[0]->reserve_space(cells.size(), dim, spacedim);
2471  triangulation.faces->lines.reserve_space(0, needed_lines.size());
2472 
2473  // make up lines
2474  {
2476  triangulation.begin_raw_line();
2477  typename std::map<
2478  std::pair<int, int>,
2479  typename Triangulation<dim, spacedim>::line_iterator>::iterator i;
2480  for (i = needed_lines.begin(); line != triangulation.end_line();
2481  ++line, ++i)
2482  {
2484  i->first.first, i->first.second));
2485  line->set_used_flag();
2486  line->clear_user_flag();
2487  line->clear_user_data();
2488 
2489  // now set the iterator for
2490  // this line
2491  i->second = line;
2492  }
2493  }
2494 
2495 
2497  // make up the quads of this triangulation
2498  //
2499  // same thing: the iterators are
2500  // set to the invalid value at
2501  // first, we only collect the data
2502  // now
2503 
2504  // the bool array stores, whether the lines
2505  // are in the standard orientation or not
2506 
2507  // note that QuadComparator is a
2508  // class declared and defined in
2509  // this file
2510  std::map<internal::TriangulationImplementation::TriaObject<2>,
2511  std::pair<typename Triangulation<dim, spacedim>::quad_iterator,
2512  std::array<bool, GeometryInfo<dim>::lines_per_face>>,
2514  needed_quads;
2515  for (const auto &cell : cells)
2516  {
2517  // the faces are quads which
2518  // consist of four numbers
2519  // denoting the index of the
2520  // four lines bounding the
2521  // quad. we can get this index
2522  // by asking @p{needed_lines}
2523  // for an iterator to this
2524  // line, dereferencing it and
2525  // thus return an iterator into
2526  // the @p{lines} array of the
2527  // triangulation, which is
2528  // already set up. we can then
2529  // ask this iterator for its
2530  // index within the present
2531  // level (the level is zero, of
2532  // course)
2533  //
2534  // to make things easier, we
2535  // don't create the lines
2536  // (pairs of their vertex
2537  // indices) in place, but
2538  // before they are really
2539  // needed.
2540  std::pair<int, int> line_list[GeometryInfo<dim>::lines_per_cell],
2541  inverse_line_list[GeometryInfo<dim>::lines_per_cell];
2542  unsigned int face_line_list[GeometryInfo<dim>::lines_per_face];
2543  std::array<bool, GeometryInfo<dim>::lines_per_face> orientation;
2544 
2545  for (unsigned int line = 0;
2546  line < GeometryInfo<dim>::lines_per_cell;
2547  ++line)
2548  {
2549  line_list[line] = std::pair<int, int>(
2550  cell.vertices[GeometryInfo<dim>::line_to_cell_vertices(line,
2551  0)],
2552  cell.vertices[GeometryInfo<dim>::line_to_cell_vertices(line,
2553  1)]);
2554  inverse_line_list[line] = std::pair<int, int>(
2555  cell.vertices[GeometryInfo<dim>::line_to_cell_vertices(line,
2556  1)],
2557  cell.vertices[GeometryInfo<dim>::line_to_cell_vertices(line,
2558  0)]);
2559  }
2560 
2561  for (const unsigned int face : GeometryInfo<dim>::face_indices())
2562  {
2563  // set up a list of the lines to be
2564  // used for this face. check the
2565  // direction for each line
2566  //
2567  // given a face line number (0-3) on
2568  // a specific face we get the cell
2569  // line number (0-11) through the
2570  // face_to_cell_lines function
2571  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_face;
2572  ++l)
2573  if (needed_lines.find(
2574  inverse_line_list[GeometryInfo<dim>::face_to_cell_lines(
2575  face, l)]) == needed_lines.end())
2576  {
2577  face_line_list[l] =
2578  needed_lines[line_list[GeometryInfo<
2579  dim>::face_to_cell_lines(face, l)]]
2580  ->index();
2581  orientation[l] = true;
2582  }
2583  else
2584  {
2585  face_line_list[l] =
2586  needed_lines[inverse_line_list[GeometryInfo<
2587  dim>::face_to_cell_lines(face, l)]]
2588  ->index();
2589  orientation[l] = false;
2590  }
2591 
2592 
2594  face_line_list[0],
2595  face_line_list[1],
2596  face_line_list[2],
2597  face_line_list[3]);
2598 
2599  // insert quad, with
2600  // invalid iterator
2601  //
2602  // if quad already exists,
2603  // then nothing bad happens
2604  // here, as this will then
2605  // simply become an
2606  // interior face of the
2607  // triangulation. however,
2608  // we will run into major
2609  // trouble if the face was
2610  // already inserted in the
2611  // opposite
2612  // direction. there are
2613  // really only two
2614  // orientations for a face
2615  // to be in, since the edge
2616  // directions are already
2617  // set. thus, vertex 0 is
2618  // the one from which two
2619  // edges originate, and
2620  // vertex 3 is the one to
2621  // which they converge. we
2622  // are then left with
2623  // orientations 0-1-2-3 and
2624  // 2-3-0-1 for the order of
2625  // lines. the
2626  // corresponding quad can
2627  // be easily constructed by
2628  // exchanging lines. we do
2629  // so here, just to check
2630  // that that flipped quad
2631  // isn't already in the
2632  // triangulation. if it is,
2633  // then don't insert the
2634  // new one and instead
2635  // later set the
2636  // face_orientation flag
2638  test_quad_1(quad.face(2),
2639  quad.face(3),
2640  quad.face(0),
2641  quad.face(
2642  1)), // face_orientation=false, face_flip=false,
2643  // face_rotation=false
2644  test_quad_2(quad.face(0),
2645  quad.face(1),
2646  quad.face(3),
2647  quad.face(
2648  2)), // face_orientation=false, face_flip=false,
2649  // face_rotation=true
2650  test_quad_3(quad.face(3),
2651  quad.face(2),
2652  quad.face(1),
2653  quad.face(
2654  0)), // face_orientation=false, face_flip=true,
2655  // face_rotation=false
2656  test_quad_4(quad.face(1),
2657  quad.face(0),
2658  quad.face(2),
2659  quad.face(
2660  3)), // face_orientation=false, face_flip=true,
2661  // face_rotation=true
2662  test_quad_5(quad.face(2),
2663  quad.face(3),
2664  quad.face(1),
2665  quad.face(
2666  0)), // face_orientation=true, face_flip=false,
2667  // face_rotation=true
2668  test_quad_6(quad.face(1),
2669  quad.face(0),
2670  quad.face(3),
2671  quad.face(
2672  2)), // face_orientation=true, face_flip=true,
2673  // face_rotation=false
2674  test_quad_7(quad.face(3),
2675  quad.face(2),
2676  quad.face(0),
2677  quad.face(
2678  1)); // face_orientation=true, face_flip=true,
2679  // face_rotation=true
2680  if (needed_quads.find(test_quad_1) == needed_quads.end() &&
2681  needed_quads.find(test_quad_2) == needed_quads.end() &&
2682  needed_quads.find(test_quad_3) == needed_quads.end() &&
2683  needed_quads.find(test_quad_4) == needed_quads.end() &&
2684  needed_quads.find(test_quad_5) == needed_quads.end() &&
2685  needed_quads.find(test_quad_6) == needed_quads.end() &&
2686  needed_quads.find(test_quad_7) == needed_quads.end())
2687  needed_quads[quad] =
2688  std::make_pair(triangulation.end_quad(), orientation);
2689  }
2690  }
2691 
2692 
2694  // enter the resulting quads into
2695  // the arrays of the Triangulation
2696  //
2697  // first reserve enough space
2698  triangulation.faces->quads.reserve_space(0, needed_quads.size());
2699 
2700  {
2702  triangulation.begin_raw_quad();
2703  typename std::map<
2705  std::pair<typename Triangulation<dim, spacedim>::quad_iterator,
2706  std::array<bool, GeometryInfo<dim>::lines_per_face>>,
2707  QuadComparator>::iterator q;
2708  for (q = needed_quads.begin(); quad != triangulation.end_quad();
2709  ++quad, ++q)
2710  {
2711  quad->set(q->first);
2712  quad->set_used_flag();
2713  quad->clear_user_flag();
2714  quad->clear_user_data();
2715  // set the line orientation
2716  quad->set_line_orientation(0, q->second.second[0]);
2717  quad->set_line_orientation(1, q->second.second[1]);
2718  quad->set_line_orientation(2, q->second.second[2]);
2719  quad->set_line_orientation(3, q->second.second[3]);
2720 
2721 
2722  // now set the iterator for
2723  // this quad
2724  q->second.first = quad;
2725  }
2726  }
2727 
2729  // finally create the cells
2730  triangulation.levels[0]->cells.reserve_space(cells.size());
2731 
2732  // store for each quad index the
2733  // adjacent cells
2734  std::map<
2735  int,
2736  std::vector<typename Triangulation<dim, spacedim>::cell_iterator>>
2737  adjacent_cells;
2738 
2739  // finally make up cells
2740  {
2742  triangulation.begin_raw_hex();
2743  for (unsigned int c = 0; c < cells.size(); ++c, ++cell)
2744  {
2745  // first find for each of
2746  // the cells the quad
2747  // iterator of the
2748  // respective faces.
2749  //
2750  // to this end, set up the
2751  // lines of this cell and
2752  // find the quads that are
2753  // bounded by these lines;
2754  // these are then the faces
2755  // of the present cell
2756  std::pair<int, int> line_list[GeometryInfo<dim>::lines_per_cell],
2757  inverse_line_list[GeometryInfo<dim>::lines_per_cell];
2758  unsigned int face_line_list[4];
2759  for (unsigned int line = 0;
2760  line < GeometryInfo<dim>::lines_per_cell;
2761  ++line)
2762  {
2763  line_list[line] = std::make_pair(
2765  line, 0)],
2767  line, 1)]);
2768  inverse_line_list[line] = std::pair<int, int>(
2770  line, 1)],
2772  line, 0)]);
2773  }
2774 
2775  // get the iterators
2776  // corresponding to the
2777  // faces. also store
2778  // whether they are
2779  // reversed or not
2781  face_iterator[GeometryInfo<dim>::faces_per_cell];
2782  bool face_orientation[GeometryInfo<dim>::faces_per_cell];
2783  bool face_flip[GeometryInfo<dim>::faces_per_cell];
2784  bool face_rotation[GeometryInfo<dim>::faces_per_cell];
2785  for (const unsigned int face : GeometryInfo<dim>::face_indices())
2786  {
2787  for (unsigned int l = 0;
2788  l < GeometryInfo<dim>::lines_per_face;
2789  ++l)
2790  if (needed_lines.find(inverse_line_list[GeometryInfo<
2791  dim>::face_to_cell_lines(face, l)]) ==
2792  needed_lines.end())
2793  face_line_list[l] =
2794  needed_lines[line_list[GeometryInfo<
2795  dim>::face_to_cell_lines(face, l)]]
2796  ->index();
2797  else
2798  face_line_list[l] =
2799  needed_lines[inverse_line_list[GeometryInfo<
2800  dim>::face_to_cell_lines(face, l)]]
2801  ->index();
2802 
2804  face_line_list[0],
2805  face_line_list[1],
2806  face_line_list[2],
2807  face_line_list[3]);
2808 
2809  if (needed_quads.find(quad) != needed_quads.end())
2810  {
2811  // face is in standard
2812  // orientation (and not
2813  // flipped or rotated). this
2814  // must be true for at least
2815  // one of the two cells
2816  // containing this face
2817  // (i.e. for the cell which
2818  // originally inserted the
2819  // face)
2820  face_iterator[face] = needed_quads[quad].first;
2821  face_orientation[face] = true;
2822  face_flip[face] = false;
2823  face_rotation[face] = false;
2824  }
2825  else
2826  {
2827  // face must be available in
2828  // reverse order
2829  // then. construct all
2830  // possibilities and check
2831  // them one after the other
2833  test_quad_1(
2834  quad.face(2),
2835  quad.face(3),
2836  quad.face(0),
2837  quad.face(1)), // face_orientation=false,
2838  // face_flip=false, face_rotation=false
2839  test_quad_2(
2840  quad.face(0),
2841  quad.face(1),
2842  quad.face(3),
2843  quad.face(2)), // face_orientation=false,
2844  // face_flip=false, face_rotation=true
2845  test_quad_3(
2846  quad.face(3),
2847  quad.face(2),
2848  quad.face(1),
2849  quad.face(0)), // face_orientation=false,
2850  // face_flip=true, face_rotation=false
2851  test_quad_4(quad.face(1),
2852  quad.face(0),
2853  quad.face(2),
2854  quad.face(
2855  3)), // face_orientation=false,
2856  // face_flip=true, face_rotation=true
2857  test_quad_5(
2858  quad.face(2),
2859  quad.face(3),
2860  quad.face(1),
2861  quad.face(0)), // face_orientation=true,
2862  // face_flip=false, face_rotation=true
2863  test_quad_6(
2864  quad.face(1),
2865  quad.face(0),
2866  quad.face(3),
2867  quad.face(2)), // face_orientation=true,
2868  // face_flip=true, face_rotation=false
2869  test_quad_7(quad.face(3),
2870  quad.face(2),
2871  quad.face(0),
2872  quad.face(
2873  1)); // face_orientation=true,
2874  // face_flip=true, face_rotation=true
2875  if (needed_quads.find(test_quad_1) != needed_quads.end())
2876  {
2877  face_iterator[face] = needed_quads[test_quad_1].first;
2878  face_orientation[face] = false;
2879  face_flip[face] = false;
2880  face_rotation[face] = false;
2881  }
2882  else if (needed_quads.find(test_quad_2) !=
2883  needed_quads.end())
2884  {
2885  face_iterator[face] = needed_quads[test_quad_2].first;
2886  face_orientation[face] = false;
2887  face_flip[face] = false;
2888  face_rotation[face] = true;
2889  }
2890  else if (needed_quads.find(test_quad_3) !=
2891  needed_quads.end())
2892  {
2893  face_iterator[face] = needed_quads[test_quad_3].first;
2894  face_orientation[face] = false;
2895  face_flip[face] = true;
2896  face_rotation[face] = false;
2897  }
2898  else if (needed_quads.find(test_quad_4) !=
2899  needed_quads.end())
2900  {
2901  face_iterator[face] = needed_quads[test_quad_4].first;
2902  face_orientation[face] = false;
2903  face_flip[face] = true;
2904  face_rotation[face] = true;
2905  }
2906  else if (needed_quads.find(test_quad_5) !=
2907  needed_quads.end())
2908  {
2909  face_iterator[face] = needed_quads[test_quad_5].first;
2910  face_orientation[face] = true;
2911  face_flip[face] = false;
2912  face_rotation[face] = true;
2913  }
2914  else if (needed_quads.find(test_quad_6) !=
2915  needed_quads.end())
2916  {
2917  face_iterator[face] = needed_quads[test_quad_6].first;
2918  face_orientation[face] = true;
2919  face_flip[face] = true;
2920  face_rotation[face] = false;
2921  }
2922  else if (needed_quads.find(test_quad_7) !=
2923  needed_quads.end())
2924  {
2925  face_iterator[face] = needed_quads[test_quad_7].first;
2926  face_orientation[face] = true;
2927  face_flip[face] = true;
2928  face_rotation[face] = true;
2929  }
2930 
2931  else
2932  // we didn't find the
2933  // face in any direction,
2934  // so something went
2935  // wrong above
2936  Assert(false, ExcInternalError());
2937  }
2938  } // for all faces
2939 
2940  // make the cell out of
2941  // these iterators
2943  face_iterator[0]->index(),
2944  face_iterator[1]->index(),
2945  face_iterator[2]->index(),
2946  face_iterator[3]->index(),
2947  face_iterator[4]->index(),
2948  face_iterator[5]->index()));
2949 
2950  cell->set_used_flag();
2951  cell->set_material_id(cells[c].material_id);
2952  cell->set_manifold_id(cells[c].manifold_id);
2953  cell->clear_user_flag();
2954  cell->clear_user_data();
2955  cell->set_subdomain_id(0);
2956 
2957  // set orientation flag for
2958  // each of the faces
2959  for (const unsigned int quad : GeometryInfo<dim>::face_indices())
2960  {
2961  cell->set_face_orientation(quad, face_orientation[quad]);
2962  cell->set_face_flip(quad, face_flip[quad]);
2963  cell->set_face_rotation(quad, face_rotation[quad]);
2964  }
2965 
2966 
2967  // note that this cell is
2968  // adjacent to the six
2969  // quads
2970  for (const auto &quad : face_iterator)
2971  adjacent_cells[quad->index()].push_back(cell);
2972 
2973 #ifdef DEBUG
2974  // make some checks on the
2975  // lines and their
2976  // ordering
2977 
2978  // first map all cell lines
2979  // to the two face lines
2980  // which should
2981  // coincide. all face lines
2982  // are included with a cell
2983  // line number (0-11)
2984  // key. At the end all keys
2985  // will be included twice
2986  // (for each of the two
2987  // coinciding lines once)
2988  std::multimap<unsigned int, std::pair<unsigned int, unsigned int>>
2989  cell_to_face_lines;
2990  for (const unsigned int face : GeometryInfo<dim>::face_indices())
2991  for (unsigned int line = 0;
2992  line < GeometryInfo<dim>::lines_per_face;
2993  ++line)
2994  cell_to_face_lines.insert(
2995  std::pair<unsigned int,
2996  std::pair<unsigned int, unsigned int>>(
2998  std::pair<unsigned int, unsigned int>(face, line)));
2999  std::multimap<unsigned int,
3000  std::pair<unsigned int, unsigned int>>::
3001  const_iterator map_iter = cell_to_face_lines.begin();
3002 
3003  for (; map_iter != cell_to_face_lines.end(); ++map_iter)
3004  {
3005  const unsigned int cell_line = map_iter->first;
3006  const unsigned int face1 = map_iter->second.first;
3007  const unsigned int line1 = map_iter->second.second;
3008  ++map_iter;
3009  Assert(map_iter != cell_to_face_lines.end(),
3011  Assert(map_iter->first == cell_line,
3013  const unsigned int face2 = map_iter->second.first;
3014  const unsigned int line2 = map_iter->second.second;
3015 
3016  // check that the pair
3017  // of lines really
3018  // coincide. Take care
3019  // about the face
3020  // orientation;
3021  Assert(face_iterator[face1]->line(
3023  line1,
3024  face_orientation[face1],
3025  face_flip[face1],
3026  face_rotation[face1])) ==
3027  face_iterator[face2]->line(
3029  line2,
3030  face_orientation[face2],
3031  face_flip[face2],
3032  face_rotation[face2])),
3034  }
3035 #endif
3036  }
3037  }
3038 
3039 
3041  // find those quads which are at the
3042  // boundary and mark them appropriately
3043  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
3044  triangulation.begin_quad();
3045  quad != triangulation.end_quad();
3046  ++quad)
3047  {
3048  const unsigned int n_adj_cells =
3049  adjacent_cells[quad->index()].size();
3050  // assert that every quad has
3051  // one or two adjacent cells
3052  AssertThrow((n_adj_cells >= 1) && (n_adj_cells <= 2),
3053  ExcInternalError());
3054 
3055  // if only one cell: quad is at boundary -> give it the boundary
3056  // indicator zero by default
3057  quad->set_boundary_id_internal(
3058  (n_adj_cells == 1) ? 0 : numbers::internal_face_boundary_id);
3059 
3060  // Manifold ids are set independently of where they are
3061  quad->set_manifold_id(numbers::flat_manifold_id);
3062  }
3063 
3065  // next find those lines which are at
3066  // the boundary and mark all others as
3067  // interior ones
3068  //
3069  // for this: first mark all lines as interior. use this loop
3070  // to also set all manifold ids of all lines
3071  for (typename Triangulation<dim, spacedim>::line_iterator line =
3072  triangulation.begin_line();
3073  line != triangulation.end_line();
3074  ++line)
3075  {
3076  line->set_boundary_id_internal(numbers::internal_face_boundary_id);
3077  line->set_manifold_id(numbers::flat_manifold_id);
3078  }
3079 
3080  // next reset all lines bounding
3081  // boundary quads as on the
3082  // boundary also. note that since
3083  // we are in 3d, there are cases
3084  // where one or more lines of a
3085  // quad that is not on the
3086  // boundary, are actually boundary
3087  // lines. they will not be marked
3088  // when visiting this
3089  // face. however, since we do not
3090  // support dim-2 dimensional
3091  // boundaries (i.e. internal lines
3092  // constituting boundaries), every
3093  // such line is also part of a face
3094  // that is actually on the
3095  // boundary, so sooner or later we
3096  // get to mark that line for being
3097  // on the boundary
3098  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
3099  triangulation.begin_quad();
3100  quad != triangulation.end_quad();
3101  ++quad)
3102  if (quad->at_boundary())
3103  {
3104  for (unsigned int l = 0; l < 4; ++l)
3105  {
3107  quad->line(l);
3108  line->set_boundary_id_internal(0);
3109  }
3110  }
3111 
3113  // now set boundary indicators
3114  // where given
3115  //
3116  // first do so for lines
3117  for (const auto &subcell_line : subcelldata.boundary_lines)
3118  {
3120  std::pair<int, int> line_vertices(
3121  std::make_pair(subcell_line.vertices[0],
3122  subcell_line.vertices[1]));
3123  if (needed_lines.find(line_vertices) != needed_lines.end())
3124  // line found in this
3125  // direction
3126  line = needed_lines[line_vertices];
3127 
3128  else
3129  {
3130  // look whether it exists in
3131  // reverse direction
3132  std::swap(line_vertices.first, line_vertices.second);
3133  if (needed_lines.find(line_vertices) != needed_lines.end())
3134  line = needed_lines[line_vertices];
3135  else
3136  // line does not exist
3137  AssertThrow(false,
3138  ExcLineInexistant(line_vertices.first,
3139  line_vertices.second));
3140  }
3141  // Only exterior lines can be given a boundary indicator
3142  if (line->at_boundary())
3143  {
3144  // make sure that we don't attempt to reset the boundary
3145  // indicator to a different than the previously set value
3146  AssertThrow(line->boundary_id() == 0 ||
3147  line->boundary_id() == subcell_line.boundary_id,
3148  ExcInconsistentLineInfoOfLine(line_vertices.first,
3149  line_vertices.second,
3150  "boundary ids"));
3151  // If the boundary id provided in subcell_line
3152  // is anything other than the default
3153  // (internal_face_boundary_id), then set it in the new
3154  // triangulation.
3155  if (subcell_line.boundary_id !=
3157  line->set_boundary_id(subcell_line.boundary_id);
3158  }
3159  // Set manifold id if given
3160  AssertThrow(line->manifold_id() == numbers::flat_manifold_id ||
3161  line->manifold_id() == subcell_line.manifold_id,
3162  ExcInconsistentLineInfoOfLine(line_vertices.first,
3163  line_vertices.second,
3164  "manifold ids"));
3165  line->set_manifold_id(subcell_line.manifold_id);
3166  }
3167 
3168 
3169  // now go on with the faces
3170  for (const auto &subcell_quad : subcelldata.boundary_quads)
3171  {
3174 
3175  // first find the lines that
3176  // are made up of the given
3177  // vertices, then build up a
3178  // quad from these lines
3179  // finally use the find
3180  // function of the map template
3181  // to find the quad
3182  for (unsigned int i = 0; i < 4; ++i)
3183  {
3184  std::pair<int, int> line_vertices(
3185  subcell_quad
3187  0)],
3188  subcell_quad
3190  1)]);
3191 
3192  // check whether line
3193  // already exists
3194  if (needed_lines.find(line_vertices) != needed_lines.end())
3195  line[i] = needed_lines[line_vertices];
3196  else
3197  // look whether it exists
3198  // in reverse direction
3199  {
3200  std::swap(line_vertices.first, line_vertices.second);
3201  if (needed_lines.find(line_vertices) != needed_lines.end())
3202  line[i] = needed_lines[line_vertices];
3203  else
3204  // line does
3205  // not exist
3206  AssertThrow(false,
3207  ExcLineInexistant(line_vertices.first,
3208  line_vertices.second));
3209  }
3210  }
3211 
3212 
3213  // Set up 2 quads that are
3214  // built up from the lines for
3215  // reasons of comparison to
3216  // needed_quads. The second
3217  // quad is the reversed version
3218  // of the first quad in order
3219  // find the quad regardless of
3220  // its orientation. This is
3221  // introduced for convenience
3222  // and because boundary quad
3223  // orientation does not carry
3224  // any information.
3226  line[0]->index(),
3227  line[1]->index(),
3228  line[2]->index(),
3229  line[3]->index());
3231  line[2]->index(),
3232  line[3]->index(),
3233  line[0]->index(),
3234  line[1]->index());
3235 
3236  // try to find the quad with
3237  // lines situated as
3238  // constructed above. if it
3239  // could not be found, rotate
3240  // the boundary lines 3 times
3241  // until it is found or it does
3242  // not exist.
3243 
3244  // mapping from counterclock to
3245  // lexicographic ordering of
3246  // quad lines
3247  static const unsigned int lex2cclock[4] = {3, 1, 0, 2};
3248  // copy lines from
3249  // lexicographic to
3250  // counterclock ordering, as
3251  // rotation is much simpler in
3252  // counterclock ordering
3254  line_counterclock[4];
3255  for (unsigned int i = 0; i < 4; ++i)
3256  line_counterclock[lex2cclock[i]] = line[i];
3257  unsigned int n_rotations = 0;
3258  bool not_found_quad_1;
3259  while ((not_found_quad_1 = (needed_quads.find(quad_compare_1) ==
3260  needed_quads.end())) &&
3261  (needed_quads.find(quad_compare_2) == needed_quads.end()) &&
3262  (n_rotations < 4))
3263  {
3264  // use the rotate defined
3265  // in <algorithms>
3266  std::rotate(line_counterclock,
3267  line_counterclock + 1,
3268  line_counterclock + 4);
3269  // update the quads with
3270  // rotated lines (i runs in
3271  // lexicographic ordering)
3272  for (unsigned int i = 0; i < 4; ++i)
3273  {
3274  quad_compare_1.set_face(
3275  i, line_counterclock[lex2cclock[i]]->index());
3276  quad_compare_2.set_face(
3277  (i + 2) % 4, line_counterclock[lex2cclock[i]]->index());
3278  }
3279 
3280  ++n_rotations;
3281  }
3282 
3283  AssertThrow(n_rotations != 4,
3284  ExcQuadInexistant(line[0]->index(),
3285  line[1]->index(),
3286  line[2]->index(),
3287  line[3]->index()));
3288 
3289  if (not_found_quad_1)
3290  quad = needed_quads[quad_compare_2].first;
3291  else
3292  quad = needed_quads[quad_compare_1].first;
3293 
3294  // check whether this face is
3295  // really an exterior one
3296  if (quad->at_boundary())
3297  {
3298  // and make sure that we don't attempt to reset the boundary
3299  // indicator to a different than the previously set value
3300  AssertThrow(quad->boundary_id() == 0 ||
3301  quad->boundary_id() == subcell_quad.boundary_id,
3302  ExcInconsistentQuadInfoOfQuad(line[0]->index(),
3303  line[1]->index(),
3304  line[2]->index(),
3305  line[3]->index(),
3306  "boundary ids"));
3307  // If the boundary id provided in subcell_line
3308  // is anything other than the default
3309  // (internal_face_boundary_id), then set it in the new
3310  // triangulation.
3311  if (subcell_quad.boundary_id !=
3313  quad->set_boundary_id(subcell_quad.boundary_id);
3314  }
3315  // Set manifold id if given
3316  if (quad->manifold_id() != numbers::flat_manifold_id)
3317  AssertThrow(quad->manifold_id() == subcell_quad.manifold_id,
3318  ExcInconsistentQuadInfoOfQuad(line[0]->index(),
3319  line[1]->index(),
3320  line[2]->index(),
3321  line[3]->index(),
3322  "manifold ids"));
3323 
3324  quad->set_manifold_id(subcell_quad.manifold_id);
3325  }
3326 
3327 
3329  // finally update neighborship info
3330  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
3331  triangulation.begin();
3332  cell != triangulation.end();
3333  ++cell)
3334  for (unsigned int face = 0; face < 6; ++face)
3335  if (adjacent_cells[cell->quad(face)->index()][0] == cell)
3336  // first adjacent cell is
3337  // this one
3338  {
3339  if (adjacent_cells[cell->quad(face)->index()].size() == 2)
3340  // there is another
3341  // adjacent cell
3342  cell->set_neighbor(
3343  face, adjacent_cells[cell->quad(face)->index()][1]);
3344  }
3345  // first adjacent cell is not this
3346  // one, -> it must be the neighbor
3347  // we are looking for
3348  else
3349  cell->set_neighbor(face,
3350  adjacent_cells[cell->quad(face)->index()][0]);
3351  }
3352 
3353 
3369  template <int spacedim>
3370  static void delete_children(
3373  std::vector<unsigned int> &,
3374  std::vector<unsigned int> &)
3375  {
3376  const unsigned int dim = 1;
3377 
3378  // first we need to reset the
3379  // neighbor pointers of the
3380  // neighbors of this cell's
3381  // children to this cell. This is
3382  // different for one dimension,
3383  // since there neighbors can have a
3384  // refinement level differing from
3385  // that of this cell's children by
3386  // more than one level.
3387 
3388  Assert(!cell->child(0)->has_children() &&
3389  !cell->child(1)->has_children(),
3390  ExcInternalError());
3391 
3392  // first do it for the cells to the
3393  // left
3394  if (cell->neighbor(0).state() == IteratorState::valid)
3395  if (cell->neighbor(0)->has_children())
3396  {
3398  cell->neighbor(0);
3399  Assert(neighbor->level() == cell->level(), ExcInternalError());
3400 
3401  // right child
3402  neighbor = neighbor->child(1);
3403  while (true)
3404  {
3405  Assert(neighbor->neighbor(1) == cell->child(0),
3406  ExcInternalError());
3407  neighbor->set_neighbor(1, cell);
3408 
3409  // move on to further
3410  // children on the
3411  // boundary between this
3412  // cell and its neighbor
3413  if (neighbor->has_children())
3414  neighbor = neighbor->child(1);
3415  else
3416  break;
3417  }
3418  }
3419 
3420  // now do it for the cells to the
3421  // left
3422  if (cell->neighbor(1).state() == IteratorState::valid)
3423  if (cell->neighbor(1)->has_children())
3424  {
3426  cell->neighbor(1);
3427  Assert(neighbor->level() == cell->level(), ExcInternalError());
3428 
3429  // left child
3430  neighbor = neighbor->child(0);
3431  while (true)
3432  {
3433  Assert(neighbor->neighbor(0) == cell->child(1),
3434  ExcInternalError());
3435  neighbor->set_neighbor(0, cell);
3436 
3437  // move on to further
3438  // children on the
3439  // boundary between this
3440  // cell and its neighbor
3441  if (neighbor->has_children())
3442  neighbor = neighbor->child(0);
3443  else
3444  break;
3445  }
3446  }
3447 
3448 
3449  // delete the vertex which will not
3450  // be needed anymore. This vertex
3451  // is the second of the first child
3452  triangulation.vertices_used[cell->child(0)->vertex_index(1)] = false;
3453 
3454  // invalidate children. clear user
3455  // pointers, to avoid that they may
3456  // appear at unwanted places later
3457  // on...
3458  for (unsigned int child = 0; child < cell->n_children(); ++child)
3459  {
3460  cell->child(child)->clear_user_data();
3461  cell->child(child)->clear_user_flag();
3462  cell->child(child)->clear_used_flag();
3463  }
3464 
3465 
3466  // delete pointer to children
3467  cell->clear_children();
3468  cell->clear_user_flag();
3469  }
3470 
3471 
3472 
3473  template <int spacedim>
3474  static void delete_children(
3477  std::vector<unsigned int> & line_cell_count,
3478  std::vector<unsigned int> &)
3479  {
3480  const unsigned int dim = 2;
3481  const RefinementCase<dim> ref_case = cell->refinement_case();
3482 
3483  Assert(line_cell_count.size() == triangulation.n_raw_lines(),
3484  ExcInternalError());
3485 
3486  // vectors to hold all lines which
3487  // may be deleted
3488  std::vector<typename Triangulation<dim, spacedim>::line_iterator>
3489  lines_to_delete(0);
3490 
3491  lines_to_delete.reserve(4 * 2 + 4);
3492 
3493  // now we decrease the counters for
3494  // lines contained in the child
3495  // cells
3496  for (unsigned int c = 0; c < cell->n_children(); ++c)
3497  {
3499  cell->child(c);
3500  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
3501  --line_cell_count[child->line_index(l)];
3502  }
3503 
3504 
3505  // delete the vertex which will not
3506  // be needed anymore. This vertex
3507  // is the second of the second line
3508  // of the first child, if the cell
3509  // is refined with cut_xy, else there
3510  // is no inner vertex.
3511  // additionally delete unneeded inner
3512  // lines
3513  if (ref_case == RefinementCase<dim>::cut_xy)
3514  {
3516  .vertices_used[cell->child(0)->line(1)->vertex_index(1)] = false;
3517 
3518  lines_to_delete.push_back(cell->child(0)->line(1));
3519  lines_to_delete.push_back(cell->child(0)->line(3));
3520  lines_to_delete.push_back(cell->child(3)->line(0));
3521  lines_to_delete.push_back(cell->child(3)->line(2));
3522  }
3523  else
3524  {
3525  unsigned int inner_face_no =
3526  ref_case == RefinementCase<dim>::cut_x ? 1 : 3;
3527 
3528  // the inner line will not be
3529  // used any more
3530  lines_to_delete.push_back(cell->child(0)->line(inner_face_no));
3531  }
3532 
3533  // invalidate children
3534  for (unsigned int child = 0; child < cell->n_children(); ++child)
3535  {
3536  cell->child(child)->clear_user_data();
3537  cell->child(child)->clear_user_flag();
3538  cell->child(child)->clear_used_flag();
3539  }
3540 
3541 
3542  // delete pointer to children
3543  cell->clear_children();
3544  cell->clear_refinement_case();
3545  cell->clear_user_flag();
3546 
3547  // look at the refinement of outer
3548  // lines. if nobody needs those
3549  // anymore we can add them to the
3550  // list of lines to be deleted.
3551  for (unsigned int line_no = 0;
3552  line_no < GeometryInfo<dim>::lines_per_cell;
3553  ++line_no)
3554  {
3556  cell->line(line_no);
3557 
3558  if (line->has_children())
3559  {
3560  // if one of the cell counters is
3561  // zero, the other has to be as well
3562 
3563  Assert((line_cell_count[line->child_index(0)] == 0 &&
3564  line_cell_count[line->child_index(1)] == 0) ||
3565  (line_cell_count[line->child_index(0)] > 0 &&
3566  line_cell_count[line->child_index(1)] > 0),
3567  ExcInternalError());
3568 
3569  if (line_cell_count[line->child_index(0)] == 0)
3570  {
3571  for (unsigned int c = 0; c < 2; ++c)
3572  Assert(!line->child(c)->has_children(),
3573  ExcInternalError());
3574 
3575  // we may delete the line's
3576  // children and the middle vertex
3577  // as no cell references them
3578  // anymore
3580  .vertices_used[line->child(0)->vertex_index(1)] = false;
3581 
3582  lines_to_delete.push_back(line->child(0));
3583  lines_to_delete.push_back(line->child(1));
3584 
3585  line->clear_children();
3586  }
3587  }
3588  }
3589 
3590  // finally, delete unneeded lines
3591 
3592  // clear user pointers, to avoid that
3593  // they may appear at unwanted places
3594  // later on...
3595  // same for user flags, then finally
3596  // delete the lines
3597  typename std::vector<
3599  line = lines_to_delete.begin(),
3600  endline = lines_to_delete.end();
3601  for (; line != endline; ++line)
3602  {
3603  (*line)->clear_user_data();
3604  (*line)->clear_user_flag();
3605  (*line)->clear_used_flag();
3606  }
3607  }
3608 
3609 
3610 
3611  template <int spacedim>
3612  static void delete_children(
3615  std::vector<unsigned int> & line_cell_count,
3616  std::vector<unsigned int> & quad_cell_count)
3617  {
3618  const unsigned int dim = 3;
3619 
3620  Assert(line_cell_count.size() == triangulation.n_raw_lines(),
3621  ExcInternalError());
3622  Assert(quad_cell_count.size() == triangulation.n_raw_quads(),
3623  ExcInternalError());
3624 
3625  // first of all, we store the RefineCase of
3626  // this cell
3627  const RefinementCase<dim> ref_case = cell->refinement_case();
3628  // vectors to hold all lines and quads which
3629  // may be deleted
3630  std::vector<typename Triangulation<dim, spacedim>::line_iterator>
3631  lines_to_delete(0);
3632  std::vector<typename Triangulation<dim, spacedim>::quad_iterator>
3633  quads_to_delete(0);
3634 
3635  lines_to_delete.reserve(12 * 2 + 6 * 4 + 6);
3636  quads_to_delete.reserve(6 * 4 + 12);
3637 
3638  // now we decrease the counters for lines and
3639  // quads contained in the child cells
3640  for (unsigned int c = 0; c < cell->n_children(); ++c)
3641  {
3643  cell->child(c);
3644  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
3645  --line_cell_count[child->line_index(l)];
3646  for (auto f : GeometryInfo<dim>::face_indices())
3647  --quad_cell_count[child->quad_index(f)];
3648  }
3649 
3651  // delete interior quads and lines and the
3652  // interior vertex, depending on the
3653  // refinement case of the cell
3654  //
3655  // for append quads and lines: only append
3656  // them to the list of objects to be deleted
3657 
3658  switch (ref_case)
3659  {
3661  quads_to_delete.push_back(cell->child(0)->face(1));
3662  break;
3664  quads_to_delete.push_back(cell->child(0)->face(3));
3665  break;
3667  quads_to_delete.push_back(cell->child(0)->face(5));
3668  break;
3670  quads_to_delete.push_back(cell->child(0)->face(1));
3671  quads_to_delete.push_back(cell->child(0)->face(3));
3672  quads_to_delete.push_back(cell->child(3)->face(0));
3673  quads_to_delete.push_back(cell->child(3)->face(2));
3674 
3675  lines_to_delete.push_back(cell->child(0)->line(11));
3676  break;
3678  quads_to_delete.push_back(cell->child(0)->face(1));
3679  quads_to_delete.push_back(cell->child(0)->face(5));
3680  quads_to_delete.push_back(cell->child(3)->face(0));
3681  quads_to_delete.push_back(cell->child(3)->face(4));
3682 
3683  lines_to_delete.push_back(cell->child(0)->line(5));
3684  break;
3686  quads_to_delete.push_back(cell->child(0)->face(3));
3687  quads_to_delete.push_back(cell->child(0)->face(5));
3688  quads_to_delete.push_back(cell->child(3)->face(2));
3689  quads_to_delete.push_back(cell->child(3)->face(4));
3690 
3691  lines_to_delete.push_back(cell->child(0)->line(7));
3692  break;
3694  quads_to_delete.push_back(cell->child(0)->face(1));
3695  quads_to_delete.push_back(cell->child(2)->face(1));
3696  quads_to_delete.push_back(cell->child(4)->face(1));
3697  quads_to_delete.push_back(cell->child(6)->face(1));
3698 
3699  quads_to_delete.push_back(cell->child(0)->face(3));
3700  quads_to_delete.push_back(cell->child(1)->face(3));
3701  quads_to_delete.push_back(cell->child(4)->face(3));
3702  quads_to_delete.push_back(cell->child(5)->face(3));
3703 
3704  quads_to_delete.push_back(cell->child(0)->face(5));
3705  quads_to_delete.push_back(cell->child(1)->face(5));
3706  quads_to_delete.push_back(cell->child(2)->face(5));
3707  quads_to_delete.push_back(cell->child(3)->face(5));
3708 
3709  lines_to_delete.push_back(cell->child(0)->line(5));
3710  lines_to_delete.push_back(cell->child(0)->line(7));
3711  lines_to_delete.push_back(cell->child(0)->line(11));
3712  lines_to_delete.push_back(cell->child(7)->line(0));
3713  lines_to_delete.push_back(cell->child(7)->line(2));
3714  lines_to_delete.push_back(cell->child(7)->line(8));
3715  // delete the vertex which will not
3716  // be needed anymore. This vertex
3717  // is the vertex at the heart of
3718  // this cell, which is the sixth of
3719  // the first child
3720  triangulation.vertices_used[cell->child(0)->vertex_index(7)] =
3721  false;
3722  break;
3723  default:
3724  // only remaining case is
3725  // no_refinement, thus an error
3726  Assert(false, ExcInternalError());
3727  break;
3728  }
3729 
3730 
3731  // invalidate children
3732  for (unsigned int child = 0; child < cell->n_children(); ++child)
3733  {
3734  cell->child(child)->clear_user_data();
3735  cell->child(child)->clear_user_flag();
3736 
3737  for (auto f : GeometryInfo<dim>::face_indices())
3738  {
3739  // set flags denoting deviations from
3740  // standard orientation of faces back
3741  // to initialization values
3742  cell->child(child)->set_face_orientation(f, true);
3743  cell->child(child)->set_face_flip(f, false);
3744  cell->child(child)->set_face_rotation(f, false);
3745  }
3746 
3747  cell->child(child)->clear_used_flag();
3748  }
3749 
3750 
3751  // delete pointer to children
3752  cell->clear_children();
3753  cell->clear_refinement_case();
3754  cell->clear_user_flag();
3755 
3756  // so far we only looked at inner quads,
3757  // lines and vertices. Now we have to
3758  // consider outer ones as well. here, we have
3759  // to check, whether there are other cells
3760  // still needing these objects. otherwise we
3761  // can delete them. first for quads (and
3762  // their inner lines).
3763 
3764  for (const unsigned int quad_no : GeometryInfo<dim>::face_indices())
3765  {
3767  cell->face(quad_no);
3768 
3769  Assert(
3770  (GeometryInfo<dim>::face_refinement_case(ref_case, quad_no) &&
3771  quad->has_children()) ||
3772  GeometryInfo<dim>::face_refinement_case(ref_case, quad_no) ==
3774  ExcInternalError());
3775 
3776  switch (quad->refinement_case())
3777  {
3778  case RefinementCase<dim - 1>::no_refinement:
3779  // nothing to do as the quad
3780  // is not refined
3781  break;
3782  case RefinementCase<dim - 1>::cut_x:
3783  case RefinementCase<dim - 1>::cut_y:
3784  {
3785  // if one of the cell counters is
3786  // zero, the other has to be as
3787  // well
3788  Assert((quad_cell_count[quad->child_index(0)] == 0 &&
3789  quad_cell_count[quad->child_index(1)] == 0) ||
3790  (quad_cell_count[quad->child_index(0)] > 0 &&
3791  quad_cell_count[quad->child_index(1)] > 0),
3792  ExcInternalError());
3793  // it might be, that the quad is
3794  // refined twice anisotropically,
3795  // first check, whether we may
3796  // delete possible grand_children
3797  unsigned int deleted_grandchildren = 0;
3798  unsigned int number_of_child_refinements = 0;
3799 
3800  for (unsigned int c = 0; c < 2; ++c)
3801  if (quad->child(c)->has_children())
3802  {
3803  ++number_of_child_refinements;
3804  // if one of the cell counters is
3805  // zero, the other has to be as
3806  // well
3807  Assert(
3808  (quad_cell_count[quad->child(c)->child_index(0)] ==
3809  0 &&
3810  quad_cell_count[quad->child(c)->child_index(1)] ==
3811  0) ||
3812  (quad_cell_count[quad->child(c)->child_index(0)] >
3813  0 &&
3814  quad_cell_count[quad->child(c)->child_index(1)] >
3815  0),
3816  ExcInternalError());
3817  if (quad_cell_count[quad->child(c)->child_index(0)] ==
3818  0)
3819  {
3820  // Assert, that the two
3821  // anisotropic
3822  // refinements add up to
3823  // isotropic refinement
3824  Assert(quad->refinement_case() +
3825  quad->child(c)->refinement_case() ==
3827  ExcInternalError());
3828  // we may delete the
3829  // quad's children and
3830  // the inner line as no
3831  // cell references them
3832  // anymore
3833  quads_to_delete.push_back(
3834  quad->child(c)->child(0));
3835  quads_to_delete.push_back(
3836  quad->child(c)->child(1));
3837  if (quad->child(c)->refinement_case() ==
3839  lines_to_delete.push_back(
3840  quad->child(c)->child(0)->line(1));
3841  else
3842  lines_to_delete.push_back(
3843  quad->child(c)->child(0)->line(3));
3844  quad->child(c)->clear_children();
3845  quad->child(c)->clear_refinement_case();
3846  ++deleted_grandchildren;
3847  }
3848  }
3849  // if no grandchildren are left, we
3850  // may as well delete the
3851  // refinement of the inner line
3852  // between our children and the
3853  // corresponding vertex
3854  if (number_of_child_refinements > 0 &&
3855  deleted_grandchildren == number_of_child_refinements)
3856  {
3858  middle_line;
3859  if (quad->refinement_case() == RefinementCase<2>::cut_x)
3860  middle_line = quad->child(0)->line(1);
3861  else
3862  middle_line = quad->child(0)->line(3);
3863 
3864  lines_to_delete.push_back(middle_line->child(0));
3865  lines_to_delete.push_back(middle_line->child(1));
3867  .vertices_used[middle_vertex_index<dim, spacedim>(
3868  middle_line)] = false;
3869  middle_line->clear_children();
3870  }
3871 
3872  // now consider the direct children
3873  // of the given quad
3874  if (quad_cell_count[quad->child_index(0)] == 0)
3875  {
3876  // we may delete the quad's
3877  // children and the inner line
3878  // as no cell references them
3879  // anymore
3880  quads_to_delete.push_back(quad->child(0));
3881  quads_to_delete.push_back(quad->child(1));
3882  if (quad->refinement_case() == RefinementCase<2>::cut_x)
3883  lines_to_delete.push_back(quad->child(0)->line(1));
3884  else
3885  lines_to_delete.push_back(quad->child(0)->line(3));
3886 
3887  // if the counters just dropped
3888  // to zero, otherwise the
3889  // children would have been
3890  // deleted earlier, then this
3891  // cell's children must have
3892  // contained the anisotropic
3893  // quad children. thus, if
3894  // those have again anisotropic
3895  // children, which are in
3896  // effect isotropic children of
3897  // the original quad, those are
3898  // still needed by a
3899  // neighboring cell and we
3900  // cannot delete them. instead,
3901  // we have to reset this quad's
3902  // refine case to isotropic and
3903  // set the children
3904  // accordingly.
3905  if (quad->child(0)->has_children())
3906  if (quad->refinement_case() ==
3908  {
3909  // now evereything is
3910  // quite complicated. we
3911  // have the children
3912  // numbered according to
3913  //
3914  // *---*---*
3915  // |n+1|m+1|
3916  // *---*---*
3917  // | n | m |
3918  // *---*---*
3919  //
3920  // from the original
3921  // anisotropic
3922  // refinement. we have to
3923  // reorder them as
3924  //
3925  // *---*---*
3926  // | m |m+1|
3927  // *---*---*
3928  // | n |n+1|
3929  // *---*---*
3930  //
3931  // for isotropic refinement.
3932  //
3933  // this is a bit ugly, of
3934  // course: loop over all
3935  // cells on all levels
3936  // and look for faces n+1
3937  // (switch_1) and m
3938  // (switch_2).
3939  const typename Triangulation<dim, spacedim>::
3940  quad_iterator switch_1 =
3941  quad->child(0)->child(1),
3942  switch_2 =
3943  quad->child(1)->child(0);
3944 
3945  Assert(!switch_1->has_children(),
3946  ExcInternalError());
3947  Assert(!switch_2->has_children(),
3948  ExcInternalError());
3949 
3950  const int switch_1_index = switch_1->index();
3951  const int switch_2_index = switch_2->index();
3952  for (unsigned int l = 0;
3953  l < triangulation.levels.size();
3954  ++l)
3955  for (unsigned int h = 0;
3956  h < triangulation.levels[l]
3957  ->cells.cells.size();
3958  ++h)
3959  for (const unsigned int q :
3961  {
3962  const int index = triangulation.levels[l]
3963  ->cells.cells[h]
3964  .face(q);
3965  if (index == switch_1_index)
3966  triangulation.levels[l]
3967  ->cells.cells[h]
3968  .set_face(q, switch_2_index);
3969  else if (index == switch_2_index)
3970  triangulation.levels[l]
3971  ->cells.cells[h]
3972  .set_face(q, switch_1_index);
3973  }
3974  // now we have to copy
3975  // all information of the
3976  // two quads
3977  const int switch_1_lines[4] = {
3978  static_cast<signed int>(
3979  switch_1->line_index(0)),
3980  static_cast<signed int>(
3981  switch_1->line_index(1)),
3982  static_cast<signed int>(
3983  switch_1->line_index(2)),
3984  static_cast<signed int>(
3985  switch_1->line_index(3))};
3986  const bool switch_1_line_orientations[4] = {
3987  switch_1->line_orientation(0),
3988  switch_1->line_orientation(1),
3989  switch_1->line_orientation(2),
3990  switch_1->line_orientation(3)};
3991  const types::boundary_id switch_1_boundary_id =
3992  switch_1->boundary_id();
3993  const unsigned int switch_1_user_index =
3994  switch_1->user_index();
3995  const bool switch_1_user_flag =
3996  switch_1->user_flag_set();
3997 
3998  switch_1->set(
4000  TriaObject<2>(switch_2->line_index(0),
4001  switch_2->line_index(1),
4002  switch_2->line_index(2),
4003  switch_2->line_index(3)));
4004  switch_1->set_line_orientation(
4005  0, switch_2->line_orientation(0));
4006  switch_1->set_line_orientation(
4007  1, switch_2->line_orientation(1));
4008  switch_1->set_line_orientation(
4009  2, switch_2->line_orientation(2));
4010  switch_1->set_line_orientation(
4011  3, switch_2->line_orientation(3));
4012  switch_1->set_boundary_id_internal(
4013  switch_2->boundary_id());
4014  switch_1->set_manifold_id(
4015  switch_2->manifold_id());
4016  switch_1->set_user_index(switch_2->user_index());
4017  if (switch_2->user_flag_set())
4018  switch_1->set_user_flag();
4019  else
4020  switch_1->clear_user_flag();
4021 
4022  switch_2->set(
4024  TriaObject<2>(switch_1_lines[0],
4025  switch_1_lines[1],
4026  switch_1_lines[2],
4027  switch_1_lines[3]));
4028  switch_2->set_line_orientation(
4029  0, switch_1_line_orientations[0]);
4030  switch_2->set_line_orientation(
4031  1, switch_1_line_orientations[1]);
4032  switch_2->set_line_orientation(
4033  2, switch_1_line_orientations[2]);
4034  switch_2->set_line_orientation(
4035  3, switch_1_line_orientations[3]);
4036  switch_2->set_boundary_id_internal(
4037  switch_1_boundary_id);
4038  switch_2->set_manifold_id(
4039  switch_1->manifold_id());
4040  switch_2->set_user_index(switch_1_user_index);
4041  if (switch_1_user_flag)
4042  switch_2->set_user_flag();
4043  else
4044  switch_2->clear_user_flag();
4045 
4046  const unsigned int child_0 =
4047  quad->child(0)->child_index(0);
4048  const unsigned int child_2 =
4049  quad->child(1)->child_index(0);
4050  quad->clear_children();
4051  quad->clear_refinement_case();
4052  quad->set_refinement_case(
4054  quad->set_children(0, child_0);
4055  quad->set_children(2, child_2);
4056  std::swap(quad_cell_count[child_0 + 1],
4057  quad_cell_count[child_2]);
4058  }
4059  else
4060  {
4061  // the face was refined
4062  // with cut_y, thus the
4063  // children are already
4064  // in correct order. we
4065  // only have to set them
4066  // correctly, deleting
4067  // the indirection of two
4068  // anisotropic refinement
4069  // and going directly
4070  // from the quad to
4071  // isotropic children
4072  const unsigned int child_0 =
4073  quad->child(0)->child_index(0);
4074  const unsigned int child_2 =
4075  quad->child(1)->child_index(0);
4076  quad->clear_children();
4077  quad->clear_refinement_case();
4078  quad->set_refinement_case(
4080  quad->set_children(0, child_0);
4081  quad->set_children(2, child_2);
4082  }
4083  else
4084  {
4085  quad->clear_children();
4086  quad->clear_refinement_case();
4087  }
4088  }
4089  break;
4090  }
4091  case RefinementCase<dim - 1>::cut_xy:
4092  {
4093  // if one of the cell counters is
4094  // zero, the others have to be as
4095  // well
4096 
4097  Assert((quad_cell_count[quad->child_index(0)] == 0 &&
4098  quad_cell_count[quad->child_index(1)] == 0 &&
4099  quad_cell_count[quad->child_index(2)] == 0 &&
4100  quad_cell_count[quad->child_index(3)] == 0) ||
4101  (quad_cell_count[quad->child_index(0)] > 0 &&
4102  quad_cell_count[quad->child_index(1)] > 0 &&
4103  quad_cell_count[quad->child_index(2)] > 0 &&
4104  quad_cell_count[quad->child_index(3)] > 0),
4105  ExcInternalError());
4106 
4107  if (quad_cell_count[quad->child_index(0)] == 0)
4108  {
4109  // we may delete the quad's
4110  // children, the inner lines
4111  // and the middle vertex as no
4112  // cell references them anymore
4113  lines_to_delete.push_back(quad->child(0)->line(1));
4114  lines_to_delete.push_back(quad->child(3)->line(0));
4115  lines_to_delete.push_back(quad->child(0)->line(3));
4116  lines_to_delete.push_back(quad->child(3)->line(2));
4117 
4118  for (unsigned int child = 0; child < quad->n_children();
4119  ++child)
4120  quads_to_delete.push_back(quad->child(child));
4121 
4123  .vertices_used[quad->child(0)->vertex_index(3)] =
4124  false;
4125 
4126  quad->clear_children();
4127  quad->clear_refinement_case();
4128  }
4129  }
4130  break;
4131 
4132  default:
4133  Assert(false, ExcInternalError());
4134  break;
4135  }
4136  }
4137 
4138  // now we repeat a similar procedure
4139  // for the outer lines of this cell.
4140 
4141  // if in debug mode: check that each
4142  // of the lines for which we consider
4143  // deleting the children in fact has
4144  // children (the bits/coarsening_3d
4145  // test tripped over this initially)
4146  for (unsigned int line_no = 0;
4147  line_no < GeometryInfo<dim>::lines_per_cell;
4148  ++line_no)
4149  {
4151  cell->line(line_no);
4152 
4153  Assert(
4154  (GeometryInfo<dim>::line_refinement_case(ref_case, line_no) &&
4155  line->has_children()) ||
4156  GeometryInfo<dim>::line_refinement_case(ref_case, line_no) ==
4158  ExcInternalError());
4159 
4160  if (line->has_children())
4161  {
4162  // if one of the cell counters is
4163  // zero, the other has to be as well
4164 
4165  Assert((line_cell_count[line->child_index(0)] == 0 &&
4166  line_cell_count[line->child_index(1)] == 0) ||
4167  (line_cell_count[line->child_index(0)] > 0 &&
4168  line_cell_count[line->child_index(1)] > 0),
4169  ExcInternalError());
4170 
4171  if (line_cell_count[line->child_index(0)] == 0)
4172  {
4173  for (unsigned int c = 0; c < 2; ++c)
4174  Assert(!line->child(c)->has_children(),
4175  ExcInternalError());
4176 
4177  // we may delete the line's
4178  // children and the middle vertex
4179  // as no cell references them
4180  // anymore
4182  .vertices_used[line->child(0)->vertex_index(1)] = false;
4183 
4184  lines_to_delete.push_back(line->child(0));
4185  lines_to_delete.push_back(line->child(1));
4186 
4187  line->clear_children();
4188  }
4189  }
4190  }
4191 
4192  // finally, delete unneeded quads and lines
4193 
4194  // clear user pointers, to avoid that
4195  // they may appear at unwanted places
4196  // later on...
4197  // same for user flags, then finally
4198  // delete the quads and lines
4199  typename std::vector<
4201  line = lines_to_delete.begin(),
4202  endline = lines_to_delete.end();
4203  for (; line != endline; ++line)
4204  {
4205  (*line)->clear_user_data();
4206  (*line)->clear_user_flag();
4207  (*line)->clear_used_flag();
4208  }
4209 
4210  typename std::vector<
4212  quad = quads_to_delete.begin(),
4213  endquad = quads_to_delete.end();
4214  for (; quad != endquad; ++quad)
4215  {
4216  (*quad)->clear_user_data();
4217  (*quad)->clear_children();
4218  (*quad)->clear_refinement_case();
4219  (*quad)->clear_user_flag();
4220  (*quad)->clear_used_flag();
4221  }
4222  }
4223 
4224 
4242  template <int spacedim>
4243  static void create_children(
4245  unsigned int & next_unused_vertex,
4247  &next_unused_line,
4249  & next_unused_cell,
4251  {
4252  const unsigned int dim = 2;
4253  // clear refinement flag
4254  const RefinementCase<dim> ref_case = cell->refine_flag_set();
4255  cell->clear_refine_flag();
4256 
4257  /* For the refinement process: since we go the levels up from the
4258  lowest, there are (unlike above) only two possibilities: a neighbor
4259  cell is on the same level or one level up (in both cases, it may or
4260  may not be refined later on, but we don't care here).
4261 
4262  First:
4263  Set up an array of the 3x3 vertices, which are distributed on the
4264  cell (the array consists of indices into the @p{vertices} std::vector
4265 
4266  2--7--3
4267  | | |
4268  4--8--5
4269  | | |
4270  0--6--1
4271 
4272  note: in case of cut_x or cut_y not all these vertices are needed for
4273  the new cells
4274 
4275  Second:
4276  Set up an array of the new lines (the array consists of iterator
4277  pointers into the lines arrays)
4278 
4279  .-6-.-7-. The directions are: .->-.->-.
4280  1 9 3 ^ ^ ^
4281  .-10.11-. .->-.->-.
4282  0 8 2 ^ ^ ^
4283  .-4-.-5-. .->-.->-.
4284 
4285  cut_x:
4286  .-4-.-5-.
4287  | | |
4288  0 6 1
4289  | | |
4290  .-2-.-3-.
4291 
4292  cut_y:
4293  .---5---.
4294  1 3
4295  .---6---.
4296  0 2
4297  .---4---.
4298 
4299 
4300  Third:
4301  Set up an array of neighbors:
4302 
4303  6 7
4304  .--.--.
4305  1| | |3
4306  .--.--.
4307  0| | |2
4308  .--.--.
4309  4 5
4310 
4311  We need this array for two reasons: first to get the lines which will
4312  bound the four subcells (if the neighboring cell is refined, these
4313  lines already exist), and second to update neighborship information.
4314  Since if a neighbor is not refined, its neighborship record only
4315  points to the present, unrefined, cell rather than the children we
4316  are presently creating, we only need the neighborship information
4317  if the neighbor cells are refined. In all other cases, we store
4318  the unrefined neighbor address
4319 
4320  We also need for every neighbor (if refined) which number among its
4321  neighbors the present (unrefined) cell has, since that number is to
4322  be replaced and because that also is the number of the subline which
4323  will be the interface between that neighbor and the to be created
4324  cell. We will store this number (between 0 and 3) in the field
4325  @p{neighbors_neighbor}.
4326 
4327  It would be sufficient to use the children of the common line to the
4328  neighbor, if we only wanted to get the new sublines and the new
4329  vertex, but because we need to update the neighborship information of
4330  the two refined subcells of the neighbor, we need to search these
4331  anyway.
4332 
4333  Convention:
4334  The created children are numbered like this:
4335 
4336  .--.--.
4337  |2 . 3|
4338  .--.--.
4339  |0 | 1|
4340  .--.--.
4341  */
4342  // collect the
4343  // indices of the
4344  // eight
4345  // surrounding
4346  // vertices
4347  // 2--7--3
4348  // | | |
4349  // 4--9--5
4350  // | | |
4351  // 0--6--1
4352  int new_vertices[9];
4353  for (unsigned int vertex_no = 0; vertex_no < 4; ++vertex_no)
4354  new_vertices[vertex_no] = cell->vertex_index(vertex_no);
4355  for (unsigned int line_no = 0; line_no < 4; ++line_no)
4356  if (cell->line(line_no)->has_children())
4357  new_vertices[4 + line_no] =
4358  cell->line(line_no)->child(0)->vertex_index(1);
4359 
4360  if (ref_case == RefinementCase<dim>::cut_xy)
4361  {
4362  // find the next
4363  // unused vertex and
4364  // allocate it for
4365  // the new vertex we
4366  // need here
4367  while (triangulation.vertices_used[next_unused_vertex] == true)
4368  ++next_unused_vertex;
4369  Assert(
4370  next_unused_vertex < triangulation.vertices.size(),
4371  ExcMessage(
4372  "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."));
4373  triangulation.vertices_used[next_unused_vertex] = true;
4374 
4375  new_vertices[8] = next_unused_vertex;
4376 
4377  // if this quad lives
4378  // in 2d, then we can
4379  // compute the new
4380  // central vertex
4381  // location just from
4382  // the surrounding
4383  // ones. If this is
4384  // not the case, then
4385  // we need to ask a
4386  // boundary object
4387  if (dim == spacedim)
4388  {
4389  // triangulation.vertices[next_unused_vertex] = new_point;
4390  triangulation.vertices[next_unused_vertex] = cell->center(true);
4391 
4392  // if the user_flag is set, i.e. if the cell is at the
4393  // boundary, use a different calculation of the middle vertex
4394  // here. this is of advantage if the boundary is strongly
4395  // curved (whereas the cell is not) and the cell has a high
4396  // aspect ratio.
4397  if (cell->user_flag_set())
4398  {
4399  // first reset the user_flag and then refine
4400  cell->clear_user_flag();
4401  triangulation.vertices[next_unused_vertex] =
4402  cell->center(true, true);
4403  }
4404  }
4405  else
4406  {
4407  // if this quad lives in a higher dimensional space
4408  // then we don't need to worry if it is at the
4409  // boundary of the manifold -- we always have to use
4410  // the boundary object anyway; so ignore whether the
4411  // user flag is set or not
4412  cell->clear_user_flag();
4413 
4414  // determine middle vertex by transfinite interpolation to be
4415  // consistent with what happens to quads in a Triangulation<3,
4416  // 3> when they are refined
4417  triangulation.vertices[next_unused_vertex] =
4418  cell->center(true, true);
4419  }
4420  }
4421 
4422 
4423  // Now the lines:
4424  typename Triangulation<dim, spacedim>::raw_line_iterator new_lines[12];
4425  unsigned int lmin = 8;
4426  unsigned int lmax = 12;
4427  if (ref_case != RefinementCase<dim>::cut_xy)
4428  {
4429  lmin = 6;
4430  lmax = 7;
4431  }
4432 
4433  for (unsigned int l = lmin; l < lmax; ++l)
4434  {
4435  while (next_unused_line->used() == true)
4436  ++next_unused_line;
4437  new_lines[l] = next_unused_line;
4438  ++next_unused_line;
4439 
4440  Assert(
4441  new_lines[l]->used() == false,
4442  ExcMessage(
4443  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4444  }
4445 
4446  if (ref_case == RefinementCase<dim>::cut_xy)
4447  {
4448  // .-6-.-7-.
4449  // 1 9 3
4450  // .-10.11-.
4451  // 0 8 2
4452  // .-4-.-5-.
4453 
4454  // lines 0-7 already exist, create only the four interior
4455  // lines 8-11
4456  unsigned int l = 0;
4457  for (const unsigned int face_no : GeometryInfo<dim>::face_indices())
4458  for (unsigned int c = 0; c < 2; ++c, ++l)
4459  new_lines[l] = cell->line(face_no)->child(c);
4460  Assert(l == 8, ExcInternalError());
4461 
4462  new_lines[8]->set(
4464  new_vertices[6], new_vertices[8]));
4465  new_lines[9]->set(
4467  new_vertices[8], new_vertices[7]));
4468  new_lines[10]->set(
4470  new_vertices[4], new_vertices[8]));
4471  new_lines[11]->set(
4473  new_vertices[8], new_vertices[5]));
4474  }
4475  else if (ref_case == RefinementCase<dim>::cut_x)
4476  {
4477  // .-4-.-5-.
4478  // | | |
4479  // 0 6 1
4480  // | | |
4481  // .-2-.-3-.
4482  new_lines[0] = cell->line(0);
4483  new_lines[1] = cell->line(1);
4484  new_lines[2] = cell->line(2)->child(0);
4485  new_lines[3] = cell->line(2)->child(1);
4486  new_lines[4] = cell->line(3)->child(0);
4487  new_lines[5] = cell->line(3)->child(1);
4488  new_lines[6]->set(
4490  new_vertices[6], new_vertices[7]));
4491  }
4492  else
4493  {
4495  // .---5---.
4496  // 1 3
4497  // .---6---.
4498  // 0 2
4499  // .---4---.
4500  new_lines[0] = cell->line(0)->child(0);
4501  new_lines[1] = cell->line(0)->child(1);
4502  new_lines[2] = cell->line(1)->child(0);
4503  new_lines[3] = cell->line(1)->child(1);
4504  new_lines[4] = cell->line(2);
4505  new_lines[5] = cell->line(3);
4506  new_lines[6]->set(
4508  new_vertices[4], new_vertices[5]));
4509  }
4510 
4511  for (unsigned int l = lmin; l < lmax; ++l)
4512  {
4513  new_lines[l]->set_used_flag();
4514  new_lines[l]->clear_user_flag();
4515  new_lines[l]->clear_user_data();
4516  new_lines[l]->clear_children();
4517  // interior line
4518  new_lines[l]->set_boundary_id_internal(
4520  new_lines[l]->set_manifold_id(cell->manifold_id());
4521  }
4522 
4523  // Now add the four (two)
4524  // new cells!
4527  while (next_unused_cell->used() == true)
4528  ++next_unused_cell;
4529 
4530  const unsigned int n_children = GeometryInfo<dim>::n_children(ref_case);
4531  for (unsigned int i = 0; i < n_children; ++i)
4532  {
4533  Assert(
4534  next_unused_cell->used() == false,
4535  ExcMessage(
4536  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4537  subcells[i] = next_unused_cell;
4538  ++next_unused_cell;
4539  if (i % 2 == 1 && i < n_children - 1)
4540  while (next_unused_cell->used() == true)
4541  ++next_unused_cell;
4542  }
4543 
4544  if (ref_case == RefinementCase<dim>::cut_xy)
4545  {
4546  // children:
4547  // .--.--.
4548  // |2 . 3|
4549  // .--.--.
4550  // |0 | 1|
4551  // .--.--.
4552  // lines:
4553  // .-6-.-7-.
4554  // 1 9 3
4555  // .-10.11-.
4556  // 0 8 2
4557  // .-4-.-5-.
4558  subcells[0]->set(
4560  new_lines[0]->index(),
4561  new_lines[8]->index(),
4562  new_lines[4]->index(),
4563  new_lines[10]->index()));
4564  subcells[1]->set(
4566  new_lines[8]->index(),
4567  new_lines[2]->index(),
4568  new_lines[5]->index(),
4569  new_lines[11]->index()));
4570  subcells[2]->set(
4572  new_lines[1]->index(),
4573  new_lines[9]->index(),
4574  new_lines[10]->index(),
4575  new_lines[6]->index()));
4576  subcells[3]->set(
4578  new_lines[9]->index(),
4579  new_lines[3]->index(),
4580  new_lines[11]->index(),
4581  new_lines[7]->index()));
4582  }
4583  else if (ref_case == RefinementCase<dim>::cut_x)
4584  {
4585  // children:
4586  // .--.--.
4587  // | . |
4588  // .0 . 1.
4589  // | | |
4590  // .--.--.
4591  // lines:
4592  // .-4-.-5-.
4593  // | | |
4594  // 0 6 1
4595  // | | |
4596  // .-2-.-3-.
4597  subcells[0]->set(
4599  new_lines[0]->index(),
4600  new_lines[6]->index(),
4601  new_lines[2]->index(),
4602  new_lines[4]->index()));
4603  subcells[1]->set(
4605  new_lines[6]->index(),
4606  new_lines[1]->index(),
4607  new_lines[3]->index(),
4608  new_lines[5]->index()));
4609  }
4610  else
4611  {
4613  // children:
4614  // .-----.
4615  // | 1 |
4616  // .-----.
4617  // | 0 |
4618  // .-----.
4619  // lines:
4620  // .---5---.
4621  // 1 3
4622  // .---6---.
4623  // 0 2
4624  // .---4---.
4625  subcells[0]->set(
4627  new_lines[0]->index(),
4628  new_lines[2]->index(),
4629  new_lines[4]->index(),
4630  new_lines[6]->index()));
4631  subcells[1]->set(
4633  new_lines[1]->index(),
4634  new_lines[3]->index(),
4635  new_lines[6]->index(),
4636  new_lines[5]->index()));
4637  }
4638 
4639  types::subdomain_id subdomainid = cell->subdomain_id();
4640 
4641  for (unsigned int i = 0; i < n_children; ++i)
4642  {
4643  subcells[i]->set_used_flag();
4644  subcells[i]->clear_refine_flag();
4645  subcells[i]->clear_user_flag();
4646  subcells[i]->clear_user_data();
4647  subcells[i]->clear_children();
4648  // inherit material
4649  // properties
4650  subcells[i]->set_material_id(cell->material_id());
4651  subcells[i]->set_manifold_id(cell->manifold_id());
4652  subcells[i]->set_subdomain_id(subdomainid);
4653 
4654  if (i % 2 == 0)
4655  subcells[i]->set_parent(cell->index());
4656  }
4657 
4658 
4659 
4660  // set child index for
4661  // even children children
4662  // i=0,2 (0)
4663  for (unsigned int i = 0; i < n_children / 2; ++i)
4664  cell->set_children(2 * i, subcells[2 * i]->index());
4665  // set the refine case
4666  cell->set_refinement_case(ref_case);
4667 
4668  // note that the
4669  // refinement flag was
4670  // already cleared at the
4671  // beginning of this function
4672 
4673  if (dim < spacedim)
4674  for (unsigned int c = 0; c < n_children; ++c)
4675  cell->child(c)->set_direction_flag(cell->direction_flag());
4676  }
4677 
4678 
4679 
4684  template <int spacedim>
4687  const bool /*check_for_distorted_cells*/)
4688  {
4689  const unsigned int dim = 1;
4690 
4691  // check whether a new level is needed we have to check for
4692  // this on the highest level only (on this, all used cells are
4693  // also active, so we only have to check for this)
4694  {
4696  cell = triangulation.begin_active(triangulation.levels.size() - 1),
4697  endc = triangulation.end();
4698  for (; cell != endc; ++cell)
4699  if (cell->used())
4700  if (cell->refine_flag_set())
4701  {
4702  triangulation.levels.push_back(
4703  std_cxx14::make_unique<
4705  break;
4706  }
4707  }
4708 
4709 
4710  // check how much space is needed on every level we need not
4711  // check the highest level since either - on the highest level
4712  // no cells are flagged for refinement - there are, but
4713  // prepare_refinement added another empty level
4714  unsigned int needed_vertices = 0;
4715  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4716  {
4717  // count number of flagged
4718  // cells on this level
4719  unsigned int flagged_cells = 0;
4721  acell = triangulation.begin_active(level),
4722  aendc = triangulation.begin_active(level + 1);
4723  for (; acell != aendc; ++acell)
4724  if (acell->refine_flag_set())
4725  ++flagged_cells;
4726 
4727  // count number of used cells
4728  // on the next higher level
4729  const unsigned int used_cells =
4730  std::count(triangulation.levels[level + 1]->cells.used.begin(),
4731  triangulation.levels[level + 1]->cells.used.end(),
4732  true);
4733 
4734  // reserve space for the used_cells cells already existing
4735  // on the next higher level as well as for the
4736  // 2*flagged_cells that will be created on that level
4737  triangulation.levels[level + 1]->reserve_space(
4738  used_cells +
4740  1,
4741  spacedim);
4742  // reserve space for 2*flagged_cells new lines on the next
4743  // higher level
4744  triangulation.levels[level + 1]->cells.reserve_space(
4745  GeometryInfo<1>::max_children_per_cell * flagged_cells, 0);
4746 
4747  needed_vertices += flagged_cells;
4748  }
4749 
4750  // add to needed vertices how many
4751  // vertices are already in use
4752  needed_vertices += std::count(triangulation.vertices_used.begin(),
4753  triangulation.vertices_used.end(),
4754  true);
4755  // if we need more vertices: create them, if not: leave the
4756  // array as is, since shrinking is not really possible because
4757  // some of the vertices at the end may be in use
4758  if (needed_vertices > triangulation.vertices.size())
4759  {
4760  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
4761  triangulation.vertices_used.resize(needed_vertices, false);
4762  }
4763 
4764 
4765  // Do REFINEMENT on every level; exclude highest level as
4766  // above
4767 
4768  // index of next unused vertex
4769  unsigned int next_unused_vertex = 0;
4770 
4771  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4772  {
4774  cell = triangulation.begin_active(level),
4775  endc = triangulation.begin_active(level + 1);
4776 
4778  next_unused_cell = triangulation.begin_raw(level + 1);
4779 
4780  for (; (cell != endc) && (cell->level() == level); ++cell)
4781  if (cell->refine_flag_set())
4782  {
4783  // clear refinement flag
4784  cell->clear_refine_flag();
4785 
4786  // search for next unused
4787  // vertex
4788  while (triangulation.vertices_used[next_unused_vertex] ==
4789  true)
4790  ++next_unused_vertex;
4791  Assert(
4792  next_unused_vertex < triangulation.vertices.size(),
4793  ExcMessage(
4794  "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."));
4795 
4796  // Now we always ask the cell itself where to put
4797  // the new point. The cell in turn will query the
4798  // manifold object internally.
4799  triangulation.vertices[next_unused_vertex] =
4800  cell->center(true);
4801 
4802  triangulation.vertices_used[next_unused_vertex] = true;
4803 
4804  // search for next two unused cell (++ takes care of
4805  // the end of the vector)
4807  first_child,
4808  second_child;
4809  while (next_unused_cell->used() == true)
4810  ++next_unused_cell;
4811  first_child = next_unused_cell;
4812  first_child->set_used_flag();
4813  first_child->clear_user_data();
4814  ++next_unused_cell;
4815  Assert(
4816  next_unused_cell->used() == false,
4817  ExcMessage(
4818  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4819  second_child = next_unused_cell;
4820  second_child->set_used_flag();
4821  second_child->clear_user_data();
4822 
4823  types::subdomain_id subdomainid = cell->subdomain_id();
4824 
4825  // insert first child
4826  cell->set_children(0, first_child->index());
4827  first_child->clear_children();
4828  first_child->set(
4830  cell->vertex_index(0), next_unused_vertex));
4831  first_child->set_material_id(cell->material_id());
4832  first_child->set_manifold_id(cell->manifold_id());
4833  first_child->set_subdomain_id(subdomainid);
4834  first_child->set_direction_flag(cell->direction_flag());
4835 
4836  first_child->set_parent(cell->index());
4837 
4838  // Set manifold id of the right face. Only do this
4839  // on the first child.
4840  first_child->face(1)->set_manifold_id(cell->manifold_id());
4841 
4842  // reset neighborship info (refer to
4843  // internal::TriangulationImplementation::TriaLevel<0> for
4844  // details)
4845  first_child->set_neighbor(1, second_child);
4846  if (cell->neighbor(0).state() != IteratorState::valid)
4847  first_child->set_neighbor(0, cell->neighbor(0));
4848  else if (cell->neighbor(0)->is_active())
4849  {
4850  // since the neighbors level is always <=level,
4851  // if the cell is active, then there are no
4852  // cells to the left which may want to know
4853  // about this new child cell.
4854  Assert(cell->neighbor(0)->level() <= cell->level(),
4855  ExcInternalError());
4856  first_child->set_neighbor(0, cell->neighbor(0));
4857  }
4858  else
4859  // left neighbor is refined
4860  {
4861  // set neighbor to cell on same level
4862  const unsigned int nbnb = cell->neighbor_of_neighbor(0);
4863  first_child->set_neighbor(0,
4864  cell->neighbor(0)->child(nbnb));
4865 
4866  // reset neighbor info of all right descendant
4867  // of the left neighbor of cell
4869  left_neighbor = cell->neighbor(0);
4870  while (left_neighbor->has_children())
4871  {
4872  left_neighbor = left_neighbor->child(nbnb);
4873  left_neighbor->set_neighbor(nbnb, first_child);
4874  }
4875  }
4876 
4877  // insert second child
4878  second_child->clear_children();
4879  second_child->set(
4881  next_unused_vertex, cell->vertex_index(1)));
4882  second_child->set_neighbor(0, first_child);
4883  second_child->set_material_id(cell->material_id());
4884  second_child->set_manifold_id(cell->manifold_id());
4885  second_child->set_subdomain_id(subdomainid);
4886  second_child->set_direction_flag(cell->direction_flag());
4887 
4888  if (cell->neighbor(1).state() != IteratorState::valid)
4889  second_child->set_neighbor(1, cell->neighbor(1));
4890  else if (cell->neighbor(1)->is_active())
4891  {
4892  Assert(cell->neighbor(1)->level() <= cell->level(),
4893  ExcInternalError());
4894  second_child->set_neighbor(1, cell->neighbor(1));
4895  }
4896  else
4897  // right neighbor is refined same as above
4898  {
4899  const unsigned int nbnb = cell->neighbor_of_neighbor(1);
4900  second_child->set_neighbor(
4901  1, cell->neighbor(1)->child(nbnb));
4902 
4904  right_neighbor = cell->neighbor(1);
4905  while (right_neighbor->has_children())
4906  {
4907  right_neighbor = right_neighbor->child(nbnb);
4908  right_neighbor->set_neighbor(nbnb, second_child);
4909  }
4910  }
4911  // inform all listeners that cell refinement is done
4912  triangulation.signals.post_refinement_on_cell(cell);
4913  }
4914  }
4915 
4916  // in 1d, we can not have distorted children unless the parent
4917  // was already distorted (that is because we don't use
4918  // boundary information for 1d triangulations). so return an
4919  // empty list
4921  }
4922 
4923 
4928  template <int spacedim>
4931  const bool check_for_distorted_cells)
4932  {
4933  const unsigned int dim = 2;
4934 
4935  // check whether a new level is needed we have to check for
4936  // this on the highest level only (on this, all used cells are
4937  // also active, so we only have to check for this)
4938  {
4940  cell = triangulation.begin_active(triangulation.levels.size() - 1),
4941  endc = triangulation.end();
4942  for (; cell != endc; ++cell)
4943  if (cell->used())
4944  if (cell->refine_flag_set())
4945  {
4946  triangulation.levels.push_back(
4947  std_cxx14::make_unique<
4949  break;
4950  }
4951  }
4952 
4953  // TODO[WB]: we clear user flags and pointers of lines; we're going
4954  // to use them to flag which lines need refinement
4955  for (typename Triangulation<dim, spacedim>::line_iterator line =
4956  triangulation.begin_line();
4957  line != triangulation.end_line();
4958  ++line)
4959  {
4960  line->clear_user_flag();
4961  line->clear_user_data();
4962  }
4963  // running over all cells and lines count the number
4964  // n_single_lines of lines which can be stored as single
4965  // lines, e.g. inner lines
4966  unsigned int n_single_lines = 0;
4967 
4968  // New lines to be created: number lines which are stored in
4969  // pairs (the children of lines must be stored in pairs)
4970  unsigned int n_lines_in_pairs = 0;
4971 
4972  // check how much space is needed on every level we need not
4973  // check the highest level since either - on the highest level
4974  // no cells are flagged for refinement - there are, but
4975  // prepare_refinement added another empty level
4976  unsigned int needed_vertices = 0;
4977  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4978  {
4979  // count number of flagged cells on this level and compute
4980  // how many new vertices and new lines will be needed
4981  unsigned int needed_cells = 0;
4982 
4984  cell = triangulation.begin_active(level),
4985  endc = triangulation.begin_active(level + 1);
4986  for (; cell != endc; ++cell)
4987  if (cell->refine_flag_set())
4988  {
4989  if (cell->refine_flag_set() == RefinementCase<dim>::cut_xy)
4990  {
4991  needed_cells += 4;
4992 
4993  // new vertex at center of cell is needed in any
4994  // case
4995  ++needed_vertices;
4996 
4997  // the four inner lines can be stored as singles
4998  n_single_lines += 4;
4999  }
5000  else // cut_x || cut_y
5001  {
5002  // set the flag showing that anisotropic
5003  // refinement is used for at least one cell
5004  triangulation.anisotropic_refinement = true;
5005 
5006  needed_cells += 2;
5007  // no vertex at center
5008 
5009  // the inner line can be stored as single
5010  n_single_lines += 1;
5011  }
5012 
5013  // mark all faces (lines) for refinement; checking
5014  // locally whether the neighbor would also like to
5015  // refine them is rather difficult for lines so we
5016  // only flag them and after visiting all cells, we
5017  // decide which lines need refinement;
5018  for (const unsigned int line_no :
5020  {
5022  cell->refine_flag_set(), line_no) ==
5024  {
5026  line = cell->line(line_no);
5027  if (line->has_children() == false)
5028  line->set_user_flag();
5029  }
5030  }
5031  }
5032 
5033 
5034  // count number of used cells on the next higher level
5035  const unsigned int used_cells =
5036  std::count(triangulation.levels[level + 1]->cells.used.begin(),
5037  triangulation.levels[level + 1]->cells.used.end(),
5038  true);
5039 
5040 
5041  // reserve space for the used_cells cells already existing
5042  // on the next higher level as well as for the
5043  // needed_cells that will be created on that level
5044  triangulation.levels[level + 1]->reserve_space(
5045  used_cells + needed_cells, 2, spacedim);
5046 
5047  // reserve space for needed_cells new quads on the next
5048  // higher level
5049  triangulation.levels[level + 1]->cells.reserve_space(needed_cells,
5050  0);
5051  }
5052 
5053  // now count the lines which were flagged for refinement
5054  for (typename Triangulation<dim, spacedim>::line_iterator line =
5055  triangulation.begin_line();
5056  line != triangulation.end_line();
5057  ++line)
5058  if (line->user_flag_set())
5059  {
5060  Assert(line->has_children() == false, ExcInternalError());
5061  n_lines_in_pairs += 2;
5062  needed_vertices += 1;
5063  }
5064  // reserve space for n_lines_in_pairs new lines. note, that
5065  // we can't reserve space for the single lines here as well,
5066  // as all the space reserved for lines in pairs would be
5067  // counted as unused and we would end up with too little space
5068  // to store all lines. memory reservation for n_single_lines
5069  // can only be done AFTER we refined the lines of the current
5070  // cells
5071  triangulation.faces->lines.reserve_space(n_lines_in_pairs, 0);
5072 
5073  // add to needed vertices how many vertices are already in use
5074  needed_vertices += std::count(triangulation.vertices_used.begin(),
5075  triangulation.vertices_used.end(),
5076  true);
5077  // if we need more vertices: create them, if not: leave the
5078  // array as is, since shrinking is not really possible because
5079  // some of the vertices at the end may be in use
5080  if (needed_vertices > triangulation.vertices.size())
5081  {
5082  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
5083  triangulation.vertices_used.resize(needed_vertices, false);
5084  }
5085 
5086 
5087  // Do REFINEMENT on every level; exclude highest level as
5088  // above
5089 
5090  // index of next unused vertex
5091  unsigned int next_unused_vertex = 0;
5092 
5093  // first the refinement of lines. children are stored
5094  // pairwise
5095  {
5096  // only active objects can be refined further
5098  line = triangulation.begin_active_line(),
5099  endl = triangulation.end_line();
5101  next_unused_line = triangulation.begin_raw_line();
5102 
5103  for (; line != endl; ++line)
5104  if (line->user_flag_set())
5105  {
5106  // this line needs to be refined
5107 
5108  // find the next unused vertex and set it
5109  // appropriately
5110  while (triangulation.vertices_used[next_unused_vertex] == true)
5111  ++next_unused_vertex;
5112  Assert(
5113  next_unused_vertex < triangulation.vertices.size(),
5114  ExcMessage(
5115  "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."));
5116  triangulation.vertices_used[next_unused_vertex] = true;
5117 
5118  triangulation.vertices[next_unused_vertex] = line->center(true);
5119 
5120  // now that we created the right point, make up the
5121  // two child lines. To this end, find a pair of
5122  // unused lines
5123  bool pair_found = false;
5124  (void)pair_found;
5125  for (; next_unused_line != endl; ++next_unused_line)
5126  if (!next_unused_line->used() &&
5127  !(++next_unused_line)->used())
5128  {
5129  // go back to the first of the two unused
5130  // lines
5131  --next_unused_line;
5132  pair_found = true;
5133  break;
5134  }
5135  Assert(pair_found, ExcInternalError());
5136 
5137  // there are now two consecutive unused lines, such
5138  // that the children of a line will be consecutive.
5139  // then set the child pointer of the present line
5140  line->set_children(0, next_unused_line->index());
5141 
5142  // set the two new lines
5144  children[2] = {next_unused_line, ++next_unused_line};
5145  // some tests; if any of the iterators should be
5146  // invalid, then already dereferencing will fail
5147  Assert(
5148  children[0]->used() == false,
5149  ExcMessage(
5150  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5151  Assert(
5152  children[1]->used() == false,
5153  ExcMessage(
5154  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5155 
5156  children[0]->set(
5158  line->vertex_index(0), next_unused_vertex));
5159  children[1]->set(
5161  next_unused_vertex, line->vertex_index(1)));
5162 
5163  children[0]->set_used_flag();
5164  children[1]->set_used_flag();
5165  children[0]->clear_children();
5166  children[1]->clear_children();
5167  children[0]->clear_user_data();
5168  children[1]->clear_user_data();
5169  children[0]->clear_user_flag();
5170  children[1]->clear_user_flag();
5171 
5172 
5173  children[0]->set_boundary_id_internal(line->boundary_id());
5174  children[1]->set_boundary_id_internal(line->boundary_id());
5175 
5176  children[0]->set_manifold_id(line->manifold_id());
5177  children[1]->set_manifold_id(line->manifold_id());
5178 
5179  // finally clear flag indicating the need for
5180  // refinement
5181  line->clear_user_flag();
5182  }
5183  }
5184 
5185 
5186  // Now set up the new cells
5187 
5188  // reserve space for inner lines (can be stored as single
5189  // lines)
5190  triangulation.faces->lines.reserve_space(0, n_single_lines);
5191 
5193  cells_with_distorted_children;
5194 
5195  // reset next_unused_line, as now also single empty places in
5196  // the vector can be used
5198  next_unused_line = triangulation.begin_raw_line();
5199 
5200  for (int level = 0;
5201  level < static_cast<int>(triangulation.levels.size()) - 1;
5202  ++level)
5203  {
5204  // Remember: as we don't operate on the finest level,
5205  // begin_*(level+1) is allowed
5207  cell = triangulation.begin_active(level),
5208  endc = triangulation.begin_active(level + 1);
5209 
5211  next_unused_cell = triangulation.begin_raw(level + 1);
5212 
5213  for (; cell != endc; ++cell)
5214  if (cell->refine_flag_set())
5215  {
5216  // set the user flag to indicate, that at least one
5217  // line is at the boundary
5218 
5219  // TODO[Tobias Leicht] find a better place to set
5220  // this flag, so that we do not need so much time to
5221  // check each cell here
5222  if (cell->at_boundary())
5223  cell->set_user_flag();
5224 
5225  // actually set up the children and update neighbor
5226  // information
5228  next_unused_vertex,
5229  next_unused_line,
5230  next_unused_cell,
5231  cell);
5232 
5233  if ((check_for_distorted_cells == true) &&
5234  has_distorted_children(
5235  cell,
5236  std::integral_constant<int, dim>(),
5237  std::integral_constant<int, spacedim>()))
5238  cells_with_distorted_children.distorted_cells.push_back(
5239  cell);
5240  // inform all listeners that cell refinement is done
5241  triangulation.signals.post_refinement_on_cell(cell);
5242  }
5243  }
5244 
5245  return cells_with_distorted_children;
5246  }
5247 
5248 
5253  template <int spacedim>
5256  const bool check_for_distorted_cells)
5257  {
5258  const unsigned int dim = 3;
5259 
5260  // this function probably also works for spacedim>3 but it
5261  // isn't tested. it will probably be necessary to pull new
5262  // vertices onto the manifold just as we do for the other
5263  // functions above.
5264  Assert(spacedim == 3, ExcNotImplemented());
5265 
5266  // check whether a new level is needed we have to check for
5267  // this on the highest level only (on this, all used cells are
5268  // also active, so we only have to check for this)
5269  {
5271  cell = triangulation.begin_active(triangulation.levels.size() - 1),
5272  endc = triangulation.end();
5273  for (; cell != endc; ++cell)
5274  if (cell->used())
5275  if (cell->refine_flag_set())
5276  {
5277  triangulation.levels.push_back(
5278  std_cxx14::make_unique<
5280  break;
5281  }
5282  }
5283 
5284 
5285  // first clear user flags for quads and lines; we're going to
5286  // use them to flag which lines and quads need refinement
5287  triangulation.faces->quads.clear_user_data();
5288 
5289  for (typename Triangulation<dim, spacedim>::line_iterator line =
5290  triangulation.begin_line();
5291  line != triangulation.end_line();
5292  ++line)
5293  line->clear_user_flag();
5294  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
5295  triangulation.begin_quad();
5296  quad != triangulation.end_quad();
5297  ++quad)
5298  quad->clear_user_flag();
5299 
5300  // create an array of face refine cases. User indices of faces
5301  // will be set to values corresponding with indices in this
5302  // array.
5303  const RefinementCase<dim - 1> face_refinement_cases[4] = {
5304  RefinementCase<dim - 1>::no_refinement,
5305  RefinementCase<dim - 1>::cut_x,
5306  RefinementCase<dim - 1>::cut_y,
5307  RefinementCase<dim - 1>::cut_xy};
5308 
5309  // check how much space is needed on every level we need not
5310  // check the highest level since either
5311  // - on the highest level no cells are flagged for refinement
5312  // - there are, but prepare_refinement added another empty
5313  // level which then is the highest level
5314 
5315  // variables to hold the number of newly to be created
5316  // vertices, lines and quads. as these are stored globally,
5317  // declare them outside the loop over al levels. we need lines
5318  // and quads in pairs for refinement of old ones and lines and
5319  // quads, that can be stored as single ones, as they are newly
5320  // created in the inside of an existing cell
5321  unsigned int needed_vertices = 0;
5322  unsigned int needed_lines_single = 0;
5323  unsigned int needed_quads_single = 0;
5324  unsigned int needed_lines_pair = 0;
5325  unsigned int needed_quads_pair = 0;
5326  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
5327  {
5328  // count number of flagged cells on this level and compute
5329  // how many new vertices and new lines will be needed
5330  unsigned int new_cells = 0;
5331 
5333  acell = triangulation.begin_active(level),
5334  aendc = triangulation.begin_active(level + 1);
5335  for (; acell != aendc; ++acell)
5336  if (acell->refine_flag_set())
5337  {
5338  RefinementCase<dim> ref_case = acell->refine_flag_set();
5339 
5340  // now for interior vertices, lines and quads, which
5341  // are needed in any case
5342  if (ref_case == RefinementCase<dim>::cut_x ||
5343  ref_case == RefinementCase<dim>::cut_y ||
5344  ref_case == RefinementCase<dim>::cut_z)
5345  {
5346  ++needed_quads_single;
5347  new_cells += 2;
5348  triangulation.anisotropic_refinement = true;
5349  }
5350  else if (ref_case == RefinementCase<dim>::cut_xy ||
5351  ref_case == RefinementCase<dim>::cut_xz ||
5352  ref_case == RefinementCase<dim>::cut_yz)
5353  {
5354  ++needed_lines_single;
5355  needed_quads_single += 4;
5356  new_cells += 4;
5357  triangulation.anisotropic_refinement = true;
5358  }
5359  else if (ref_case == RefinementCase<dim>::cut_xyz)
5360  {
5361  ++needed_vertices;
5362  needed_lines_single += 6;
5363  needed_quads_single += 12;
5364  new_cells += 8;
5365  }
5366  else
5367  {
5368  // we should never get here
5369  Assert(false, ExcInternalError());
5370  }
5371 
5372  // mark all faces for refinement; checking locally
5373  // if and how the neighbor would like to refine
5374  // these is difficult so we only flag them and after
5375  // visiting all cells, we decide which faces need
5376  // which refinement;
5377  for (const unsigned int face :
5379  {
5381  aface = acell->face(face);
5382  // get the RefineCase this faces has for the
5383  // given RefineCase of the cell
5384  RefinementCase<dim - 1> face_ref_case =
5386  ref_case,
5387  face,
5388  acell->face_orientation(face),
5389  acell->face_flip(face),
5390  acell->face_rotation(face));
5391  // only do something, if this face has to be
5392  // refined
5393  if (face_ref_case)
5394  {
5395  if (face_ref_case ==
5397  {
5398  if (aface->number_of_children() < 4)
5399  // we use user_flags to denote needed
5400  // isotropic refinement
5401  aface->set_user_flag();
5402  }
5403  else if (aface->refinement_case() != face_ref_case)
5404  // we use user_indices to denote needed
5405  // anisotropic refinement. note, that we
5406  // can have at most one anisotropic
5407  // refinement case for this face, as
5408  // otherwise prepare_refinement() would
5409  // have changed one of the cells to yield
5410  // isotropic refinement at this
5411  // face. therefore we set the user_index
5412  // uniquely
5413  {
5414  Assert(aface->refinement_case() ==
5416  dim - 1>::isotropic_refinement ||
5417  aface->refinement_case() ==
5419  ExcInternalError());
5420  aface->set_user_index(face_ref_case);
5421  }
5422  }
5423  } // for all faces
5424 
5425  // flag all lines, that have to be refined
5426  for (unsigned int line = 0;
5427  line < GeometryInfo<dim>::lines_per_cell;
5428  ++line)
5430  line) &&
5431  !acell->line(line)->has_children())
5432  acell->line(line)->set_user_flag();
5433 
5434  } // if refine_flag set and for all cells on this level
5435 
5436 
5437  // count number of used cells on the next higher level
5438  const unsigned int used_cells =
5439  std::count(triangulation.levels[level + 1]->cells.used.begin(),
5440  triangulation.levels[level + 1]->cells.used.end(),
5441  true);
5442 
5443 
5444  // reserve space for the used_cells cells already existing
5445  // on the next higher level as well as for the
5446  // 8*flagged_cells that will be created on that level
5447  triangulation.levels[level + 1]->reserve_space(
5448  used_cells + new_cells, 3, spacedim);
5449  // reserve space for 8*flagged_cells new hexes on the next
5450  // higher level
5451  triangulation.levels[level + 1]->cells.reserve_space(new_cells);
5452  } // for all levels
5453  // now count the quads and lines which were flagged for
5454  // refinement
5455  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
5456  triangulation.begin_quad();
5457  quad != triangulation.end_quad();
5458  ++quad)
5459  {
5460  if (quad->user_flag_set())
5461  {
5462  // isotropic refinement: 1 interior vertex, 4 quads
5463  // and 4 interior lines. we store the interior lines
5464  // in pairs in case the face is already or will be
5465  // refined anisotropically
5466  needed_quads_pair += 4;
5467  needed_lines_pair += 4;
5468  needed_vertices += 1;
5469  }
5470  if (quad->user_index())
5471  {
5472  // anisotropic refinement: 1 interior
5473  // line and two quads
5474  needed_quads_pair += 2;
5475  needed_lines_single += 1;
5476  // there is a kind of complicated situation here which
5477  // requires our attention. if the quad is refined
5478  // isotropcally, two of the interior lines will get a
5479  // new mother line - the interior line of our
5480  // anisotropically refined quad. if those two lines
5481  // are not consecutive, we cannot do so and have to
5482  // replace them by two lines that are consecutive. we
5483  // try to avoid that situation, but it may happen
5484  // nevertheless through repeated refinement and
5485  // coarsening. thus we have to check here, as we will
5486  // need some additional space to store those new lines
5487  // in case we need them...
5488  if (quad->has_children())
5489  {
5490  Assert(quad->refinement_case() ==
5492  ExcInternalError());
5493  if ((face_refinement_cases[quad->user_index()] ==
5495  (quad->child(0)->line_index(1) + 1 !=
5496  quad->child(2)->line_index(1))) ||
5497  (face_refinement_cases[quad->user_index()] ==
5499  (quad->child(0)->line_index(3) + 1 !=
5500  quad->child(1)->line_index(3))))
5501  needed_lines_pair += 2;
5502  }
5503  }
5504  }
5505 
5506  for (typename Triangulation<dim, spacedim>::line_iterator line =
5507  triangulation.begin_line();
5508  line != triangulation.end_line();
5509  ++line)
5510  if (line->user_flag_set())
5511  {
5512  needed_lines_pair += 2;
5513  needed_vertices += 1;
5514  }
5515 
5516  // reserve space for needed_lines new lines stored in pairs
5517  triangulation.faces->lines.reserve_space(needed_lines_pair,
5518  needed_lines_single);
5519  // reserve space for needed_quads new quads stored in pairs
5520  triangulation.faces->quads.reserve_space(needed_quads_pair,
5521  needed_quads_single);
5522 
5523 
5524  // add to needed vertices how many vertices are already in use
5525  needed_vertices += std::count(triangulation.vertices_used.begin(),
5526  triangulation.vertices_used.end(),
5527  true);
5528  // if we need more vertices: create them, if not: leave the
5529  // array as is, since shrinking is not really possible because
5530  // some of the vertices at the end may be in use
5531  if (needed_vertices > triangulation.vertices.size())
5532  {
5533  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
5534  triangulation.vertices_used.resize(needed_vertices, false);
5535  }
5536 
5537 
5539  // Before we start with the actual refinement, we do some
5540  // sanity checks if in debug mode. especially, we try to catch
5541  // the notorious problem with lines being twice refined,
5542  // i.e. there are cells adjacent at one line ("around the
5543  // edge", but not at a face), with two cells differing by more
5544  // than one refinement level
5545  //
5546  // this check is very simple to implement here, since we have
5547  // all lines flagged if they shall be refined
5548 #ifdef DEBUG
5549  for (const auto &cell : triangulation.active_cell_iterators())
5550  if (!cell->refine_flag_set())
5551  for (unsigned int line = 0;
5552  line < GeometryInfo<dim>::lines_per_cell;
5553  ++line)
5554  if (cell->line(line)->has_children())
5555  for (unsigned int c = 0; c < 2; ++c)
5556  Assert(cell->line(line)->child(c)->user_flag_set() == false,
5557  ExcInternalError());
5558 #endif
5559 
5561  // Do refinement on every level
5562  //
5563  // To make life a bit easier, we first refine those lines and
5564  // quads that were flagged for refinement and then compose the
5565  // newly to be created cells.
5566  //
5567  // index of next unused vertex
5568  unsigned int next_unused_vertex = 0;
5569 
5570  // first for lines
5571  {
5572  // only active objects can be refined further
5574  line = triangulation.begin_active_line(),
5575  endl = triangulation.end_line();
5577  next_unused_line = triangulation.begin_raw_line();
5578 
5579  for (; line != endl; ++line)
5580  if (line->user_flag_set())
5581  {
5582  // this line needs to be refined
5583 
5584  // find the next unused vertex and set it
5585  // appropriately
5586  while (triangulation.vertices_used[next_unused_vertex] == true)
5587  ++next_unused_vertex;
5588  Assert(
5589  next_unused_vertex < triangulation.vertices.size(),
5590  ExcMessage(
5591  "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."));
5592  triangulation.vertices_used[next_unused_vertex] = true;
5593 
5594  triangulation.vertices[next_unused_vertex] = line->center(true);
5595 
5596  // now that we created the right point, make up the
5597  // two child lines (++ takes care of the end of the
5598  // vector)
5599  next_unused_line =
5600  triangulation.faces->lines.next_free_pair_object(
5601  triangulation);
5602  Assert(next_unused_line.state() == IteratorState::valid,
5603  ExcInternalError());
5604 
5605  // now we found two consecutive unused lines, such
5606  // that the children of a line will be consecutive.
5607  // then set the child pointer of the present line
5608  line->set_children(0, next_unused_line->index());
5609 
5610  // set the two new lines
5612  children[2] = {next_unused_line, ++next_unused_line};
5613 
5614  // some tests; if any of the iterators should be
5615  // invalid, then already dereferencing will fail
5616  Assert(
5617  children[0]->used() == false,
5618  ExcMessage(
5619  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5620  Assert(
5621  children[1]->used() == false,
5622  ExcMessage(
5623  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5624 
5625  children[0]->set(
5627  line->vertex_index(0), next_unused_vertex));
5628  children[1]->set(
5630  next_unused_vertex, line->vertex_index(1)));
5631 
5632  children[0]->set_used_flag();
5633  children[1]->set_used_flag();
5634  children[0]->clear_children();
5635  children[1]->clear_children();
5636  children[0]->clear_user_data();
5637  children[1]->clear_user_data();
5638  children[0]->clear_user_flag();
5639  children[1]->clear_user_flag();
5640 
5641  children[0]->set_boundary_id_internal(line->boundary_id());
5642  children[1]->set_boundary_id_internal(line->boundary_id());
5643 
5644  children[0]->set_manifold_id(line->manifold_id());
5645  children[1]->set_manifold_id(line->manifold_id());
5646 
5647  // finally clear flag
5648  // indicating the need
5649  // for refinement
5650  line->clear_user_flag();
5651  }
5652  }
5653 
5654 
5656  // now refine marked quads
5658 
5659  // here we encounter several cases:
5660 
5661  // a) the quad is unrefined and shall be refined isotropically
5662 
5663  // b) the quad is unrefined and shall be refined
5664  // anisotropically
5665 
5666  // c) the quad is unrefined and shall be refined both
5667  // anisotropically and isotropically (this is reduced to case
5668  // b) and then case b) for the children again)
5669 
5670  // d) the quad is refined anisotropically and shall be refined
5671  // isotropically (this is reduced to case b) for the
5672  // anisotropic children)
5673 
5674  // e) the quad is refined isotropically and shall be refined
5675  // anisotropically (this is transformed to case c), however we
5676  // might have to renumber/rename children...)
5677 
5678  // we need a loop in cases c) and d), as the anisotropic
5679  // children migt have a lower index than the mother quad
5680  for (unsigned int loop = 0; loop < 2; ++loop)
5681  {
5682  // usually, only active objects can be refined
5683  // further. however, in cases d) and e) that is not true,
5684  // so we have to use 'normal' iterators here
5686  quad = triangulation.begin_quad(),
5687  endq = triangulation.end_quad();
5689  next_unused_line = triangulation.begin_raw_line();
5691  next_unused_quad = triangulation.begin_raw_quad();
5692 
5693  for (; quad != endq; ++quad)
5694  {
5695  if (quad->user_index())
5696  {
5697  RefinementCase<dim - 1> aniso_quad_ref_case =
5698  face_refinement_cases[quad->user_index()];
5699  // there is one unlikely event here, where we
5700  // already have refind the face: if the face was
5701  // refined anisotropically and we want to refine
5702  // it isotropically, both children are flagged for
5703  // anisotropic refinement. however, if those
5704  // children were already flagged for anisotropic
5705  // refinement, they might already be processed and
5706  // refined.
5707  if (aniso_quad_ref_case == quad->refinement_case())
5708  continue;
5709 
5710  Assert(quad->refinement_case() ==
5712  quad->refinement_case() ==
5714  ExcInternalError());
5715 
5716  // this quad needs to be refined anisotropically
5717  Assert(quad->user_index() ==
5719  quad->user_index() ==
5721  ExcInternalError());
5722 
5723  // make the new line interior to the quad
5725  new_line;
5726 
5727  new_line =
5728  triangulation.faces->lines.next_free_single_object(
5729  triangulation);
5730  Assert(
5731  new_line->used() == false,
5732  ExcMessage(
5733  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5734 
5735  // first collect the
5736  // indices of the vertices:
5737  // *--1--*
5738  // | | |
5739  // | | | cut_x
5740  // | | |
5741  // *--0--*
5742  //
5743  // *-----*
5744  // | |
5745  // 0-----1 cut_y
5746  // | |
5747  // *-----*
5748  unsigned int vertex_indices[2];
5749  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5750  {
5751  vertex_indices[0] =
5752  quad->line(2)->child(0)->vertex_index(1);
5753  vertex_indices[1] =
5754  quad->line(3)->child(0)->vertex_index(1);
5755  }
5756  else
5757  {
5758  vertex_indices[0] =
5759  quad->line(0)->child(0)->vertex_index(1);
5760  vertex_indices[1] =
5761  quad->line(1)->child(0)->vertex_index(1);
5762  }
5763 
5764  new_line->set(
5766  vertex_indices[0], vertex_indices[1]));
5767  new_line->set_used_flag();
5768  new_line->clear_user_flag();
5769  new_line->clear_user_data();
5770  new_line->clear_children();
5771  new_line->set_boundary_id_internal(quad->boundary_id());
5772  new_line->set_manifold_id(quad->manifold_id());
5773 
5774  // child 0 and 1 of a line are switched if the
5775  // line orientation is false. set up a miniature
5776  // table, indicating which child to take for line
5777  // orientations false and true. first index: child
5778  // index in standard orientation, second index:
5779  // line orientation
5780  const unsigned int index[2][2] = {
5781  {1, 0}, // child 0, line_orientation=false and true
5782  {0, 1}}; // child 1, line_orientation=false and true
5783 
5784  // find some space (consecutive) for the two newly
5785  // to be created quads.
5787  new_quads[2];
5788 
5789  next_unused_quad =
5790  triangulation.faces->quads.next_free_pair_object(
5791  triangulation);
5792  new_quads[0] = next_unused_quad;
5793  Assert(
5794  new_quads[0]->used() == false,
5795  ExcMessage(
5796  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5797 
5798  ++next_unused_quad;
5799  new_quads[1] = next_unused_quad;
5800  Assert(
5801  new_quads[1]->used() == false,
5802  ExcMessage(
5803  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5804 
5805 
5806  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5807  {
5808  new_quads[0]->set(
5810  quad->line_index(0),
5811  new_line->index(),
5812  quad->line(2)
5813  ->child(index[0][quad->line_orientation(2)])
5814  ->index(),
5815  quad->line(3)
5816  ->child(index[0][quad->line_orientation(3)])
5817  ->index()));
5818  new_quads[1]->set(
5820  new_line->index(),
5821  quad->line_index(1),
5822  quad->line(2)
5823  ->child(index[1][quad->line_orientation(2)])
5824  ->index(),
5825  quad->line(3)
5826  ->child(index[1][quad->line_orientation(3)])
5827  ->index()));
5828  }
5829  else
5830  {
5831  new_quads[0]->set(
5833  quad->line(0)
5834  ->child(index[0][quad->line_orientation(0)])
5835  ->index(),
5836  quad->line(1)
5837  ->child(index[0][quad->line_orientation(1)])
5838  ->index(),
5839  quad->line_index(2),
5840  new_line->index()));
5841  new_quads[1]->set(
5843  quad->line(0)
5844  ->child(index[1][quad->line_orientation(0)])
5845  ->index(),
5846  quad->line(1)
5847  ->child(index[1][quad->line_orientation(1)])
5848  ->index(),
5849  new_line->index(),
5850  quad->line_index(3)));
5851  }
5852 
5853  for (const auto &new_quad : new_quads)
5854  {
5855  new_quad->set_used_flag();
5856  new_quad->clear_user_flag();
5857  new_quad->clear_user_data();
5858  new_quad->clear_children();
5859  new_quad->set_boundary_id_internal(quad->boundary_id());
5860  new_quad->set_manifold_id(quad->manifold_id());
5861  // set all line orientations to true, change
5862  // this after the loop, as we have to consider
5863  // different lines for each child
5864  for (unsigned int j = 0;
5865  j < GeometryInfo<dim>::lines_per_face;
5866  ++j)
5867  new_quad->set_line_orientation(j, true);
5868  }
5869  // now set the line orientation of children of
5870  // outer lines correctly, the lines in the
5871  // interior of the refined quad are automatically
5872  // oriented conforming to the standard
5873  new_quads[0]->set_line_orientation(
5874  0, quad->line_orientation(0));
5875  new_quads[0]->set_line_orientation(
5876  2, quad->line_orientation(2));
5877  new_quads[1]->set_line_orientation(
5878  1, quad->line_orientation(1));
5879  new_quads[1]->set_line_orientation(
5880  3, quad->line_orientation(3));
5881  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5882  {
5883  new_quads[0]->set_line_orientation(
5884  3, quad->line_orientation(3));
5885  new_quads[1]->set_line_orientation(
5886  2, quad->line_orientation(2));
5887  }
5888  else
5889  {
5890  new_quads[0]->set_line_orientation(
5891  1, quad->line_orientation(1));
5892  new_quads[1]->set_line_orientation(
5893  0, quad->line_orientation(0));
5894  }
5895 
5896  // test, whether this face is refined
5897  // isotropically already. if so, set the correct
5898  // children pointers.
5899  if (quad->refinement_case() ==
5901  {
5902  // we will put a new refinemnt level of
5903  // anisotropic refinement between the
5904  // unrefined and isotropically refined quad
5905  // ending up with the same fine quads but
5906  // introducing anisotropically refined ones as
5907  // children of the unrefined quad and mother
5908  // cells of the original fine ones.
5909 
5910  // this process includes the creation of a new
5911  // middle line which we will assign as the
5912  // mother line of two of the existing inner
5913  // lines. If those inner lines are not
5914  // consecutive in memory, we won't find them
5915  // later on, so we have to create new ones
5916  // instead and replace all occurrences of the
5917  // old ones with those new ones. As this is
5918  // kind of ugly, we hope we don't have to do
5919  // it often...
5921  old_child[2];
5922  if (aniso_quad_ref_case ==
5924  {
5925  old_child[0] = quad->child(0)->line(1);
5926  old_child[1] = quad->child(2)->line(1);
5927  }
5928  else
5929  {
5930  Assert(aniso_quad_ref_case ==
5932  ExcInternalError());
5933 
5934  old_child[0] = quad->child(0)->line(3);
5935  old_child[1] = quad->child(1)->line(3);
5936  }
5937 
5938  if (old_child[0]->index() + 1 != old_child[1]->index())
5939  {
5940  // this is exactly the ugly case we taked
5941  // about. so, no coimplaining, lets get
5942  // two new lines and copy all info
5943  typename Triangulation<dim,
5944  spacedim>::raw_line_iterator
5945  new_child[2];
5946 
5947  new_child[0] = new_child[1] =
5948  triangulation.faces->lines.next_free_pair_object(
5949  triangulation);
5950  ++new_child[1];
5951 
5952  new_child[0]->set_used_flag();
5953  new_child[1]->set_used_flag();
5954 
5955  const int old_index_0 = old_child[0]->index(),
5956  old_index_1 = old_child[1]->index(),
5957  new_index_0 = new_child[0]->index(),
5958  new_index_1 = new_child[1]->index();
5959 
5960  // loop over all quads and replace the old
5961  // lines
5962  for (unsigned int q = 0;
5963  q < triangulation.faces->quads.cells.size();
5964  ++q)
5965  for (unsigned int l = 0;
5966  l < GeometryInfo<dim>::lines_per_face;
5967  ++l)
5968  {
5969  const int this_index =
5970  triangulation.faces->quads.cells[q].face(l);
5971  if (this_index == old_index_0)
5972  triangulation.faces->quads.cells[q]
5973  .set_face(l, new_index_0);
5974  else if (this_index == old_index_1)
5975  triangulation.faces->quads.cells[q]
5976  .set_face(l, new_index_1);
5977  }
5978  // now we have to copy all information of
5979  // the two lines
5980  for (unsigned int i = 0; i < 2; ++i)
5981  {
5982  Assert(!old_child[i]->has_children(),
5983  ExcInternalError());
5984 
5985  new_child[i]->set(
5987  TriaObject<1>(old_child[i]->vertex_index(0),
5988  old_child[i]->vertex_index(
5989  1)));
5990  new_child[i]->set_boundary_id_internal(
5991  old_child[i]->boundary_id());
5992  new_child[i]->set_manifold_id(
5993  old_child[i]->manifold_id());
5994  new_child[i]->set_user_index(
5995  old_child[i]->user_index());
5996  if (old_child[i]->user_flag_set())
5997  new_child[i]->set_user_flag();
5998  else
5999  new_child[i]->clear_user_flag();
6000 
6001  new_child[i]->clear_children();
6002 
6003  old_child[i]->clear_user_flag();
6004  old_child[i]->clear_user_index();
6005  old_child[i]->clear_used_flag();
6006  }
6007  }
6008  // now that we cared about the lines, go on
6009  // with the quads themselves, where we might
6010  // encounter similar situations...
6011  if (aniso_quad_ref_case ==
6013  {
6014  new_line->set_children(
6015  0, quad->child(0)->line_index(1));
6016  Assert(new_line->child(1) ==
6017  quad->child(2)->line(1),
6018  ExcInternalError());
6019  // now evereything is quite
6020  // complicated. we have the children
6021  // numbered according to
6022  //
6023  // *---*---*
6024  // |n+2|n+3|
6025  // *---*---*
6026  // | n |n+1|
6027  // *---*---*
6028  //
6029  // from the original isotropic
6030  // refinement. we have to reorder them as
6031  //
6032  // *---*---*
6033  // |n+1|n+3|
6034  // *---*---*
6035  // | n |n+2|
6036  // *---*---*
6037  //
6038  // such that n and n+1 are consecutive
6039  // children of m and n+2 and n+3 are
6040  // consecutive children of m+1, where m
6041  // and m+1 are given as in
6042  //
6043  // *---*---*
6044  // | | |
6045  // | m |m+1|
6046  // | | |
6047  // *---*---*
6048  //
6049  // this is a bit ugly, of course: loop
6050  // over all cells on all levels and look
6051  // for faces n+1 (switch_1) and n+2
6052  // (switch_2).
6053  const typename Triangulation<dim, spacedim>::
6054  quad_iterator switch_1 = quad->child(1),
6055  switch_2 = quad->child(2);
6056  const int switch_1_index = switch_1->index();
6057  const int switch_2_index = switch_2->index();
6058  for (unsigned int l = 0;
6059  l < triangulation.levels.size();
6060  ++l)
6061  for (unsigned int h = 0;
6062  h <
6063  triangulation.levels[l]->cells.cells.size();
6064  ++h)
6065  for (const unsigned int q :
6067  {
6068  const int face_index =
6069  triangulation.levels[l]
6070  ->cells.cells[h]
6071  .face(q);
6072  if (face_index == switch_1_index)
6073  triangulation.levels[l]
6074  ->cells.cells[h]
6075  .set_face(q, switch_2_index);
6076  else if (face_index == switch_2_index)
6077  triangulation.levels[l]
6078  ->cells.cells[h]
6079  .set_face(q, switch_1_index);
6080  }
6081  // now we have to copy all information of
6082  // the two quads
6083  const unsigned int switch_1_lines[4] = {
6084  switch_1->line_index(0),
6085  switch_1->line_index(1),
6086  switch_1->line_index(2),
6087  switch_1->line_index(3)};
6088  const bool switch_1_line_orientations[4] = {
6089  switch_1->line_orientation(0),
6090  switch_1->line_orientation(1),
6091  switch_1->line_orientation(2),
6092  switch_1->line_orientation(3)};
6093  const types::boundary_id switch_1_boundary_id =
6094  switch_1->boundary_id();
6095  const unsigned int switch_1_user_index =
6096  switch_1->user_index();
6097  const bool switch_1_user_flag =
6098  switch_1->user_flag_set();
6099  const RefinementCase<dim - 1>
6100  switch_1_refinement_case =
6101  switch_1->refinement_case();
6102  const int switch_1_first_child_pair =
6103  (switch_1_refinement_case ?
6104  switch_1->child_index(0) :
6105  -1);
6106  const int switch_1_second_child_pair =
6107  (switch_1_refinement_case ==
6108  RefinementCase<dim - 1>::cut_xy ?
6109  switch_1->child_index(2) :
6110  -1);
6111 
6112  switch_1->set(
6114  2>(switch_2->line_index(0),
6115  switch_2->line_index(1),
6116  switch_2->line_index(2),
6117  switch_2->line_index(3)));
6118  switch_1->set_line_orientation(
6119  0, switch_2->line_orientation(0));
6120  switch_1->set_line_orientation(
6121  1, switch_2->line_orientation(1));
6122  switch_1->set_line_orientation(
6123  2, switch_2->line_orientation(2));
6124  switch_1->set_line_orientation(
6125  3, switch_2->line_orientation(3));
6126  switch_1->set_boundary_id_internal(
6127  switch_2->boundary_id());
6128  switch_1->set_manifold_id(switch_2->manifold_id());
6129  switch_1->set_user_index(switch_2->user_index());
6130  if (switch_2->user_flag_set())
6131  switch_1->set_user_flag();
6132  else
6133  switch_1->clear_user_flag();
6134  switch_1->clear_refinement_case();
6135  switch_1->set_refinement_case(
6136  switch_2->refinement_case());
6137  switch_1->clear_children();
6138  if (switch_2->refinement_case())
6139  switch_1->set_children(0,
6140  switch_2->child_index(0));
6141  if (switch_2->refinement_case() ==
6142  RefinementCase<dim - 1>::cut_xy)
6143  switch_1->set_children(2,
6144  switch_2->child_index(2));
6145 
6146  switch_2->set(
6148  2>(switch_1_lines[0],
6149  switch_1_lines[1],
6150  switch_1_lines[2],
6151  switch_1_lines[3]));
6152  switch_2->set_line_orientation(
6153  0, switch_1_line_orientations[0]);
6154  switch_2->set_line_orientation(
6155  1, switch_1_line_orientations[1]);
6156  switch_2->set_line_orientation(
6157  2, switch_1_line_orientations[2]);
6158  switch_2->set_line_orientation(
6159  3, switch_1_line_orientations[3]);
6160  switch_2->set_boundary_id_internal(
6161  switch_1_boundary_id);
6162  switch_2->set_manifold_id(switch_1->manifold_id());
6163  switch_2->set_user_index(switch_1_user_index);
6164  if (switch_1_user_flag)
6165  switch_2->set_user_flag();
6166  else
6167  switch_2->clear_user_flag();
6168  switch_2->clear_refinement_case();
6169  switch_2->set_refinement_case(
6170  switch_1_refinement_case);
6171  switch_2->clear_children();
6172  switch_2->set_children(0,
6173  switch_1_first_child_pair);
6174  switch_2->set_children(2,
6175  switch_1_second_child_pair);
6176 
6177  new_quads[0]->set_refinement_case(
6179  new_quads[0]->set_children(0, quad->child_index(0));
6180  new_quads[1]->set_refinement_case(
6182  new_quads[1]->set_children(0, quad->child_index(2));
6183  }
6184  else
6185  {
6186  new_quads[0]->set_refinement_case(
6188  new_quads[0]->set_children(0, quad->child_index(0));
6189  new_quads[1]->set_refinement_case(
6191  new_quads[1]->set_children(0, quad->child_index(2));
6192  new_line->set_children(
6193  0, quad->child(0)->line_index(3));
6194  Assert(new_line->child(1) ==
6195  quad->child(1)->line(3),
6196  ExcInternalError());
6197  }
6198  quad->clear_children();
6199  }
6200 
6201  // note these quads as children to the present one
6202  quad->set_children(0, new_quads[0]->index());
6203 
6204  quad->set_refinement_case(aniso_quad_ref_case);
6205 
6206  // finally clear flag indicating the need for
6207  // refinement
6208  quad->clear_user_data();
6209  } // if (anisotropic refinement)
6210 
6211  if (quad->user_flag_set())
6212  {
6213  // this quad needs to be refined isotropically
6214 
6215  // first of all: we only get here in the first run
6216  // of the loop
6217  Assert(loop == 0, ExcInternalError());
6218 
6219  // find the next unused vertex. we'll need this in
6220  // any case
6221  while (triangulation.vertices_used[next_unused_vertex] ==
6222  true)
6223  ++next_unused_vertex;
6224  Assert(
6225  next_unused_vertex < triangulation.vertices.size(),
6226  ExcMessage(
6227  "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."));
6228 
6229  // now: if the quad is refined anisotropically
6230  // already, set the anisotropic refinement flag
6231  // for both children. Additionally, we have to
6232  // refine the inner line, as it is an outer line
6233  // of the two (anisotropic) children
6234  const RefinementCase<dim - 1> quad_ref_case =
6235  quad->refinement_case();
6236 
6237  if (quad_ref_case == RefinementCase<dim - 1>::cut_x ||
6238  quad_ref_case == RefinementCase<dim - 1>::cut_y)
6239  {
6240  // set the 'opposite' refine case for children
6241  quad->child(0)->set_user_index(
6242  RefinementCase<dim - 1>::cut_xy - quad_ref_case);
6243  quad->child(1)->set_user_index(
6244  RefinementCase<dim - 1>::cut_xy - quad_ref_case);
6245  // refine the inner line
6247  middle_line;
6248  if (quad_ref_case == RefinementCase<dim - 1>::cut_x)
6249  middle_line = quad->child(0)->line(1);
6250  else
6251  middle_line = quad->child(0)->line(3);
6252 
6253  // if the face has been refined
6254  // anisotropically in the last refinement step
6255  // it might be, that it is flagged already and
6256  // that the middle line is thus refined
6257  // already. if not create children.
6258  if (!middle_line->has_children())
6259  {
6260  // set the middle vertex
6261  // appropriately. double refinement of
6262  // quads can only happen in the interior
6263  // of the domain, so we need not care
6264  // about boundary quads here
6265  triangulation.vertices[next_unused_vertex] =
6266  middle_line->center(true);
6267  triangulation.vertices_used[next_unused_vertex] =
6268  true;
6269 
6270  // now search a slot for the two
6271  // child lines
6272  next_unused_line =
6273  triangulation.faces->lines.next_free_pair_object(
6274  triangulation);
6275 
6276  // set the child pointer of the present
6277  // line
6278  middle_line->set_children(
6279  0, next_unused_line->index());
6280 
6281  // set the two new lines
6282  const typename Triangulation<dim, spacedim>::
6283  raw_line_iterator children[2] = {
6284  next_unused_line, ++next_unused_line};
6285 
6286  // some tests; if any of the iterators
6287  // should be invalid, then already
6288  // dereferencing will fail
6289  Assert(
6290  children[0]->used() == false,
6291  ExcMessage(
6292  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6293  Assert(
6294  children[1]->used() == false,
6295  ExcMessage(
6296  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6297 
6298  children[0]->set(
6300  1>(middle_line->vertex_index(0),
6301  next_unused_vertex));
6302  children[1]->set(
6304  1>(next_unused_vertex,
6305  middle_line->vertex_index(1)));
6306 
6307  children[0]->set_used_flag();
6308  children[1]->set_used_flag();
6309  children[0]->clear_children();
6310  children[1]->clear_children();
6311  children[0]->clear_user_data();
6312  children[1]->clear_user_data();
6313  children[0]->clear_user_flag();
6314  children[1]->clear_user_flag();
6315 
6316  children[0]->set_boundary_id_internal(
6317  middle_line->boundary_id());
6318  children[1]->set_boundary_id_internal(
6319  middle_line->boundary_id());
6320 
6321  children[0]->set_manifold_id(
6322  middle_line->manifold_id());
6323  children[1]->set_manifold_id(
6324  middle_line->manifold_id());
6325  }
6326  // now remove the flag from the quad and go to
6327  // the next quad, the actual refinement of the
6328  // quad takes place later on in this pass of
6329  // the loop or in the next one
6330  quad->clear_user_flag();
6331  continue;
6332  } // if (several refinement cases)
6333 
6334  // if we got here, we have an unrefined quad and
6335  // have to do the usual work like in an purely
6336  // isotropic refinement
6337  Assert(quad_ref_case ==
6339  ExcInternalError());
6340 
6341  // set the middle vertex appropriately: it might be that
6342  // the quad itself is not at the boundary, but that one of
6343  // its lines actually is. in this case, the newly created
6344  // vertices at the centers of the lines are not
6345  // necessarily the mean values of the adjacent vertices,
6346  // so do not compute the new vertex as the mean value of
6347  // the 4 vertices of the face, but rather as a weighted
6348  // mean value of the 8 vertices which we already have (the
6349  // four old ones, and the four ones inserted as middle
6350  // points for the four lines). summing up some more points
6351  // is generally cheaper than first asking whether one of
6352  // the lines is at the boundary
6353  //
6354  // note that the exact weights are chosen such as to
6355  // minimize the distortion of the four new quads from the
6356  // optimal shape. their description uses the formulas
6357  // underlying the TransfiniteInterpolationManifold
6358  // implementation
6359  triangulation.vertices[next_unused_vertex] =
6360  quad->center(true, true);
6361  triangulation.vertices_used[next_unused_vertex] = true;
6362 
6363  // now that we created the right point, make up
6364  // the four lines interior to the quad (++ takes
6365  // care of the end of the vector)
6367  new_lines[4];
6368 
6369  for (unsigned int i = 0; i < 4; ++i)
6370  {
6371  if (i % 2 == 0)
6372  // search a free pair of lines for 0. and
6373  // 2. line, so that two of them end up
6374  // together, which is necessary if later on
6375  // we want to refine the quad
6376  // anisotropically and the two lines end up
6377  // as children of new line
6378  next_unused_line =
6379  triangulation.faces->lines.next_free_pair_object(
6380  triangulation);
6381 
6382  new_lines[i] = next_unused_line;
6383  ++next_unused_line;
6384 
6385  Assert(
6386  new_lines[i]->used() == false,
6387  ExcMessage(
6388  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6389  }
6390 
6391  // set the data of the four lines. first collect
6392  // the indices of the five vertices:
6393  //
6394  // *--3--*
6395  // | | |
6396  // 0--4--1
6397  // | | |
6398  // *--2--*
6399  //
6400  // the lines are numbered as follows:
6401  //
6402  // *--*--*
6403  // | 1 |
6404  // *2-*-3*
6405  // | 0 |
6406  // *--*--*
6407 
6408  const unsigned int vertex_indices[5] = {
6409  quad->line(0)->child(0)->vertex_index(1),
6410  quad->line(1)->child(0)->vertex_index(1),
6411  quad->line(2)->child(0)->vertex_index(1),
6412  quad->line(3)->child(0)->vertex_index(1),
6413  next_unused_vertex};
6414 
6415  new_lines[0]->set(
6417  vertex_indices[2], vertex_indices[4]));
6418  new_lines[1]->set(
6420  vertex_indices[4], vertex_indices[3]));
6421  new_lines[2]->set(
6423  vertex_indices[0], vertex_indices[4]));
6424  new_lines[3]->set(
6426  vertex_indices[4], vertex_indices[1]));
6427 
6428  for (const auto &new_line : new_lines)
6429  {
6430  new_line->set_used_flag();
6431  new_line->clear_user_flag();
6432  new_line->clear_user_data();
6433  new_line->clear_children();
6434  new_line->set_boundary_id_internal(quad->boundary_id());
6435  new_line->set_manifold_id(quad->manifold_id());
6436  }
6437 
6438  // now for the quads. again, first collect some
6439  // data about the indices of the lines, with the
6440  // following numbering:
6441  //
6442  // .-6-.-7-.
6443  // 1 9 3
6444  // .-10.11-.
6445  // 0 8 2
6446  // .-4-.-5-.
6447 
6448  // child 0 and 1 of a line are switched if the
6449  // line orientation is false. set up a miniature
6450  // table, indicating which child to take for line
6451  // orientations false and true. first index: child
6452  // index in standard orientation, second index:
6453  // line orientation
6454  const unsigned int index[2][2] = {
6455  {1, 0}, // child 0, line_orientation=false and true
6456  {0, 1}}; // child 1, line_orientation=false and true
6457 
6458  const int line_indices[12] = {
6459  quad->line(0)
6460  ->child(index[0][quad->line_orientation(0)])
6461  ->index(),
6462  quad->line(0)
6463  ->child(index[1][quad->line_orientation(0)])
6464  ->index(),
6465  quad->line(1)
6466  ->child(index[0][quad->line_orientation(1)])
6467  ->index(),
6468  quad->line(1)
6469  ->child(index[1][quad->line_orientation(1)])
6470  ->index(),
6471  quad->line(2)
6472  ->child(index[0][quad->line_orientation(2)])
6473  ->index(),
6474  quad->line(2)
6475  ->child(index[1][quad->line_orientation(2)])
6476  ->index(),
6477  quad->line(3)
6478  ->child(index[0][quad->line_orientation(3)])
6479  ->index(),
6480  quad->line(3)
6481  ->child(index[1][quad->line_orientation(3)])
6482  ->index(),
6483  new_lines[0]->index(),
6484  new_lines[1]->index(),
6485  new_lines[2]->index(),
6486  new_lines[3]->index()};
6487 
6488  // find some space (consecutive)
6489  // for the first two newly to be
6490  // created quads.
6492  new_quads[4];
6493 
6494  next_unused_quad =
6495  triangulation.faces->quads.next_free_pair_object(
6496  triangulation);
6497 
6498  new_quads[0] = next_unused_quad;
6499  Assert(
6500  new_quads[0]->used() == false,
6501  ExcMessage(
6502  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6503 
6504  ++next_unused_quad;
6505  new_quads[1] = next_unused_quad;
6506  Assert(
6507  new_quads[1]->used() == false,
6508  ExcMessage(
6509  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6510 
6511  next_unused_quad =
6512  triangulation.faces->quads.next_free_pair_object(
6513  triangulation);
6514  new_quads[2] = next_unused_quad;
6515  Assert(
6516  new_quads[2]->used() == false,
6517  ExcMessage(
6518  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6519 
6520  ++next_unused_quad;
6521  new_quads[3] = next_unused_quad;
6522  Assert(
6523  new_quads[3]->used() == false,
6524  ExcMessage(
6525  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6526 
6527  // note these quads as children to the present one
6528  quad->set_children(0, new_quads[0]->index());
6529  quad->set_children(2, new_quads[2]->index());
6530  new_quads[0]->set(
6532  line_indices[0],
6533  line_indices[8],
6534  line_indices[4],
6535  line_indices[10]));
6536 
6537  quad->set_refinement_case(RefinementCase<2>::cut_xy);
6538 
6539  new_quads[0]->set(
6541  line_indices[0],
6542  line_indices[8],
6543  line_indices[4],
6544  line_indices[10]));
6545  new_quads[1]->set(
6547  line_indices[8],
6548  line_indices[2],
6549  line_indices[5],
6550  line_indices[11]));
6551  new_quads[2]->set(
6553  line_indices[1],
6554  line_indices[9],
6555  line_indices[10],
6556  line_indices[6]));
6557  new_quads[3]->set(
6559  line_indices[9],
6560  line_indices[3],
6561  line_indices[11],
6562  line_indices[7]));
6563  for (const auto &new_quad : new_quads)
6564  {
6565  new_quad->set_used_flag();
6566  new_quad->clear_user_flag();
6567  new_quad->clear_user_data();
6568  new_quad->clear_children();
6569  new_quad->set_boundary_id_internal(quad->boundary_id());
6570  new_quad->set_manifold_id(quad->manifold_id());
6571  // set all line orientations to true, change
6572  // this after the loop, as we have to consider
6573  // different lines for each child
6574  for (unsigned int j = 0;
6575  j < GeometryInfo<dim>::lines_per_face;
6576  ++j)
6577  new_quad->set_line_orientation(j, true);
6578  }
6579  // now set the line orientation of children of
6580  // outer lines correctly, the lines in the
6581  // interior of the refined quad are automatically
6582  // oriented conforming to the standard
6583  new_quads[0]->set_line_orientation(
6584  0, quad->line_orientation(0));
6585  new_quads[0]->set_line_orientation(
6586  2, quad->line_orientation(2));
6587  new_quads[1]->set_line_orientation(
6588  1, quad->line_orientation(1));
6589  new_quads[1]->set_line_orientation(
6590  2, quad->line_orientation(2));
6591  new_quads[2]->set_line_orientation(
6592  0, quad->line_orientation(0));
6593  new_quads[2]->set_line_orientation(
6594  3, quad->line_orientation(3));
6595  new_quads[3]->set_line_orientation(
6596  1, quad->line_orientation(1));
6597  new_quads[3]->set_line_orientation(
6598  3, quad->line_orientation(3));
6599 
6600  // finally clear flag indicating the need for
6601  // refinement
6602  quad->clear_user_flag();
6603  } // if (isotropic refinement)
6604  } // for all quads
6605  } // looped two times over all quads, all quads refined now
6606 
6608  // Now, finally, set up the new
6609  // cells
6611 
6613  cells_with_distorted_children;
6614 
6615  for (unsigned int level = 0; level != triangulation.levels.size() - 1;
6616  ++level)
6617  {
6618  // only active objects can be refined further; remember
6619  // that we won't operate on the finest level, so
6620  // triangulation.begin_*(level+1) is allowed
6622  hex = triangulation.begin_active_hex(level),
6623  endh = triangulation.begin_active_hex(level + 1);
6625  next_unused_hex = triangulation.begin_raw_hex(level + 1);
6626 
6627  for (; hex != endh; ++hex)
6628  if (hex->refine_flag_set())
6629  {
6630  // this hex needs to be refined
6631 
6632  // clear flag indicating the need for refinement. do
6633  // it here already, since we can't do it anymore
6634  // once the cell has children
6635  const RefinementCase<dim> ref_case = hex->refine_flag_set();
6636  hex->clear_refine_flag();
6637  hex->set_refinement_case(ref_case);
6638 
6639  // depending on the refine case we might have to
6640  // create additional vertices, lines and quads
6641  // interior of the hex before the actual children
6642  // can be set up.
6643 
6644  // in a first step: reserve the needed space for
6645  // lines, quads and hexes and initialize them
6646  // correctly
6647 
6648  unsigned int n_new_lines = 0;
6649  unsigned int n_new_quads = 0;
6650  unsigned int n_new_hexes = 0;
6651  switch (ref_case)
6652  {
6656  n_new_lines = 0;
6657  n_new_quads = 1;
6658  n_new_hexes = 2;
6659  break;
6663  n_new_lines = 1;
6664  n_new_quads = 4;
6665  n_new_hexes = 4;
6666  break;
6668  n_new_lines = 6;
6669  n_new_quads = 12;
6670  n_new_hexes = 8;
6671  break;
6672  default:
6673  Assert(false, ExcInternalError());
6674  break;
6675  }
6676 
6677  // find some space for the newly to be created
6678  // interior lines and initialize them.
6679  std::vector<
6681  new_lines(n_new_lines);
6682  for (unsigned int i = 0; i < n_new_lines; ++i)
6683  {
6684  new_lines[i] =
6685  triangulation.faces->lines.next_free_single_object(
6686  triangulation);
6687 
6688  Assert(
6689  new_lines[i]->used() == false,
6690  ExcMessage(
6691  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6692  new_lines[i]->set_used_flag();
6693  new_lines[i]->clear_user_flag();
6694  new_lines[i]->clear_user_data();
6695  new_lines[i]->clear_children();
6696  // interior line
6697  new_lines[i]->set_boundary_id_internal(
6699  // they inherit geometry description of the hex they
6700  // belong to
6701  new_lines[i]->set_manifold_id(hex->manifold_id());
6702  }
6703 
6704  // find some space for the newly to be created
6705  // interior quads and initialize them.
6706  std::vector<
6708  new_quads(n_new_quads);
6709  for (unsigned int i = 0; i < n_new_quads; ++i)
6710  {
6711  new_quads[i] =
6712  triangulation.faces->quads.next_free_single_object(
6713  triangulation);
6714 
6715  Assert(
6716  new_quads[i]->used() == false,
6717  ExcMessage(
6718  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6719  new_quads[i]->set_used_flag();
6720  new_quads[i]->clear_user_flag();
6721  new_quads[i]->clear_user_data();
6722  new_quads[i]->clear_children();
6723  // interior quad
6724  new_quads[i]->set_boundary_id_internal(
6726  // they inherit geometry description of the hex they
6727  // belong to
6728  new_quads[i]->set_manifold_id(hex->manifold_id());
6729  // set all line orientation flags to true by
6730  // default, change this afterwards, if necessary
6731  for (unsigned int j = 0;
6732  j < GeometryInfo<dim>::lines_per_face;
6733  ++j)
6734  new_quads[i]->set_line_orientation(j, true);
6735  }
6736 
6737  types::subdomain_id subdomainid = hex->subdomain_id();
6738 
6739  // find some space for the newly to be created hexes
6740  // and initialize them.
6741  std::vector<
6743  new_hexes(n_new_hexes);
6744  for (unsigned int i = 0; i < n_new_hexes; ++i)
6745  {
6746  if (i % 2 == 0)
6747  next_unused_hex =
6748  triangulation.levels[level + 1]->cells.next_free_hex(
6749  triangulation, level + 1);
6750  else
6751  ++next_unused_hex;
6752 
6753  new_hexes[i] = next_unused_hex;
6754 
6755  Assert(
6756  new_hexes[i]->used() == false,
6757  ExcMessage(
6758  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6759  new_hexes[i]->set_used_flag();
6760  new_hexes[i]->clear_user_flag();
6761  new_hexes[i]->clear_user_data();
6762  new_hexes[i]->clear_children();
6763  // inherit material
6764  // properties
6765  new_hexes[i]->set_material_id(hex->material_id());
6766  new_hexes[i]->set_manifold_id(hex->manifold_id());
6767  new_hexes[i]->set_subdomain_id(subdomainid);
6768 
6769  if (i % 2)
6770  new_hexes[i]->set_parent(hex->index());
6771  // set the face_orientation flag to true for all
6772  // faces initially, as this is the default value
6773  // which is true for all faces interior to the
6774  // hex. later on go the other way round and
6775  // reset faces that are at the boundary of the
6776  // mother cube
6777  //
6778  // the same is true for the face_flip and
6779  // face_rotation flags. however, the latter two
6780  // are set to false by default as this is the
6781  // standard value
6782  for (const unsigned int f :
6784  {
6785  new_hexes[i]->set_face_orientation(f, true);
6786  new_hexes[i]->set_face_flip(f, false);
6787  new_hexes[i]->set_face_rotation(f, false);
6788  }
6789  }
6790  // note these hexes as children to the present cell
6791  for (unsigned int i = 0; i < n_new_hexes / 2; ++i)
6792  hex->set_children(2 * i, new_hexes[2 * i]->index());
6793 
6794  // we have to take into account whether the
6795  // different faces are oriented correctly or in the
6796  // opposite direction, so store that up front
6797 
6798  // face_orientation
6799  const bool f_or[6] = {hex->face_orientation(0),
6800  hex->face_orientation(1),
6801  hex->face_orientation(2),
6802  hex->face_orientation(3),
6803  hex->face_orientation(4),
6804  hex->face_orientation(5)};
6805 
6806  // face_flip
6807  const bool f_fl[6] = {hex->face_flip(0),
6808  hex->face_flip(1),
6809  hex->face_flip(2),
6810  hex->face_flip(3),
6811  hex->face_flip(4),
6812  hex->face_flip(5)};
6813 
6814  // face_rotation
6815  const bool f_ro[6] = {hex->face_rotation(0),
6816  hex->face_rotation(1),
6817  hex->face_rotation(2),
6818  hex->face_rotation(3),
6819  hex->face_rotation(4),
6820  hex->face_rotation(5)};
6821 
6822  // little helper table, indicating, whether the
6823  // child with index 0 or with index 1 can be found
6824  // at the standard origin of an anisotropically
6825  // refined quads in real orientation index 1:
6826  // (RefineCase - 1) index 2: face_flip
6827 
6828  // index 3: face rotation
6829  // note: face orientation has no influence
6830  const unsigned int child_at_origin[2][2][2] = {
6831  {{0, 0}, // RefinementCase<dim>::cut_x, face_flip=false,
6832  // face_rotation=false and true
6833  {1, 1}}, // RefinementCase<dim>::cut_x, face_flip=true,
6834  // face_rotation=false and true
6835  {{0, 1}, // RefinementCase<dim>::cut_y, face_flip=false,
6836  // face_rotation=false and true
6837  {1, 0}}}; // RefinementCase<dim>::cut_y, face_flip=true,
6838  // face_rotation=false and true
6839 
6841  //
6842  // in the following we will do the same thing for
6843  // each refinement case: create a new vertex (if
6844  // needed), create new interior lines (if needed),
6845  // create new interior quads and afterwards build
6846  // the children hexes out of these and the existing
6847  // subfaces of the outer quads (which have been
6848  // created above). However, even if the steps are
6849  // quite similar, the actual work strongly depends
6850  // on the actual refinement case. therefore, we use
6851  // separate blocks of code for each of these cases,
6852  // which hopefully increases the readability to some
6853  // extend.
6854 
6855  switch (ref_case)
6856  {
6858  {
6860  //
6861  // RefinementCase<dim>::cut_x
6862  //
6863  // the refined cube will look
6864  // like this:
6865  //
6866  // *----*----*
6867  // / / /|
6868  // / / / |
6869  // / / / |
6870  // *----*----* |
6871  // | | | |
6872  // | | | *
6873  // | | | /
6874  // | | | /
6875  // | | |/
6876  // *----*----*
6877  //
6878  // again, first collect some data about the
6879  // indices of the lines, with the following
6880  // numbering:
6881 
6882  // face 2: front plane
6883  // (note: x,y exchanged)
6884  // *---*---*
6885  // | | |
6886  // | 0 |
6887  // | | |
6888  // *---*---*
6889  // m0
6890  // face 3: back plane
6891  // (note: x,y exchanged)
6892  // m1
6893  // *---*---*
6894  // | | |
6895  // | 1 |
6896  // | | |
6897  // *---*---*
6898  // face 4: bottom plane
6899  // *---*---*
6900  // / / /
6901  // / 2 /
6902  // / / /
6903  // *---*---*
6904  // m0
6905  // face 5: top plane
6906  // m1
6907  // *---*---*
6908  // / / /
6909  // / 3 /
6910  // / / /
6911  // *---*---*
6912 
6913  // set up a list of line iterators first. from
6914  // this, construct lists of line_indices and
6915  // line orientations later on
6916  const typename Triangulation<dim, spacedim>::
6917  raw_line_iterator lines[4] = {
6918  hex->face(2)->child(0)->line(
6919  (hex->face(2)->refinement_case() ==
6921  1 :
6922  3), // 0
6923  hex->face(3)->child(0)->line(
6924  (hex->face(3)->refinement_case() ==
6926  1 :
6927  3), // 1
6928  hex->face(4)->child(0)->line(
6929  (hex->face(4)->refinement_case() ==
6931  1 :
6932  3), // 2
6933  hex->face(5)->child(0)->line(
6934  (hex->face(5)->refinement_case() ==
6936  1 :
6937  3) // 3
6938  };
6939 
6940  unsigned int line_indices[4];
6941  for (unsigned int i = 0; i < 4; ++i)
6942  line_indices[i] = lines[i]->index();
6943 
6944  // the orientation of lines for the inner quads
6945  // is quite tricky. as these lines are newly
6946  // created ones and thus have no parents, they
6947  // cannot inherit this property. set up an array
6948  // and fill it with the respective values
6949  bool line_orientation[4];
6950 
6951  // the middle vertex marked as m0 above is the
6952  // start vertex for lines 0 and 2 in standard
6953  // orientation, whereas m1 is the end vertex of
6954  // lines 1 and 3 in standard orientation
6955  const unsigned int middle_vertices[2] = {
6956  hex->line(2)->child(0)->vertex_index(1),
6957  hex->line(7)->child(0)->vertex_index(1)};
6958 
6959  for (unsigned int i = 0; i < 4; ++i)
6960  if (lines[i]->vertex_index(i % 2) ==
6961  middle_vertices[i % 2])
6962  line_orientation[i] = true;
6963  else
6964  {
6965  // it must be the other
6966  // way round then
6967  Assert(lines[i]->vertex_index((i + 1) % 2) ==
6968  middle_vertices[i % 2],
6969  ExcInternalError());
6970  line_orientation[i] = false;
6971  }
6972 
6973  // set up the new quad, line numbering is as
6974  // indicated above
6975  new_quads[0]->set(
6977  2>(line_indices[0],
6978  line_indices[1],
6979  line_indices[2],
6980  line_indices[3]));
6981 
6982  new_quads[0]->set_line_orientation(
6983  0, line_orientation[0]);
6984  new_quads[0]->set_line_orientation(
6985  1, line_orientation[1]);
6986  new_quads[0]->set_line_orientation(
6987  2, line_orientation[2]);
6988  new_quads[0]->set_line_orientation(
6989  3, line_orientation[3]);
6990 
6991  // the quads are numbered as follows:
6992  //
6993  // planes in the interior of the old hex:
6994  //
6995  // *
6996  // /|
6997  // / | x
6998  // / | *-------* *---------*
6999  // * | | | / /
7000  // | 0 | | | / /
7001  // | * | | / /
7002  // | / *-------*y *---------*x
7003  // | /
7004  // |/
7005  // *
7006  //
7007  // children of the faces of the old hex
7008  //
7009  // *---*---* *---*---*
7010  // /| | | / / /|
7011  // / | | | / 9 / 10/ |
7012  // / | 5 | 6 | / / / |
7013  // * | | | *---*---* |
7014  // | 1 *---*---* | | | 2 *
7015  // | / / / | | | /
7016  // | / 7 / 8 / | 3 | 4 | /
7017  // |/ / / | | |/
7018  // *---*---* *---*---*
7019  //
7020  // note that we have to take care of the
7021  // orientation of faces.
7022  const int quad_indices[11] = {
7023  new_quads[0]->index(), // 0
7024 
7025  hex->face(0)->index(), // 1
7026 
7027  hex->face(1)->index(), // 2
7028 
7029  hex->face(2)->child_index(
7030  child_at_origin[hex->face(2)->refinement_case() -
7031  1][f_fl[2]][f_ro[2]]), // 3
7032  hex->face(2)->child_index(
7033  1 -
7034  child_at_origin[hex->face(2)->refinement_case() -
7035  1][f_fl[2]][f_ro[2]]),
7036 
7037  hex->face(3)->child_index(
7038  child_at_origin[hex->face(3)->refinement_case() -
7039  1][f_fl[3]][f_ro[3]]), // 5
7040  hex->face(3)->child_index(
7041  1 -
7042  child_at_origin[hex->face(3)->refinement_case() -
7043  1][f_fl[3]][f_ro[3]]),
7044 
7045  hex->face(4)->child_index(
7046  child_at_origin[hex->face(4)->refinement_case() -
7047  1][f_fl[4]][f_ro[4]]), // 7
7048  hex->face(4)->child_index(
7049  1 -
7050  child_at_origin[hex->face(4)->refinement_case() -
7051  1][f_fl[4]][f_ro[4]]),
7052 
7053  hex->face(5)->child_index(
7054  child_at_origin[hex->face(5)->refinement_case() -
7055  1][f_fl[5]][f_ro[5]]), // 9
7056  hex->face(5)->child_index(
7057  1 -
7058  child_at_origin[hex->face(5)->refinement_case() -
7059  1][f_fl[5]][f_ro[5]])
7060 
7061  };
7062 
7063  new_hexes[0]->set(
7065  3>(quad_indices[1],
7066  quad_indices[0],
7067  quad_indices[3],
7068  quad_indices[5],
7069  quad_indices[7],
7070  quad_indices[9]));
7071  new_hexes[1]->set(
7073  3>(quad_indices[0],
7074  quad_indices[2],
7075  quad_indices[4],
7076  quad_indices[6],
7077  quad_indices[8],
7078  quad_indices[10]));
7079  break;
7080  }
7081 
7083  {
7085  //
7086  // RefinementCase<dim>::cut_y
7087  //
7088  // the refined cube will look like this:
7089  //
7090  // *---------*
7091  // / /|
7092  // *---------* |
7093  // / /| |
7094  // *---------* | |
7095  // | | | |
7096  // | | | *
7097  // | | |/
7098  // | | *
7099  // | |/
7100  // *---------*
7101  //
7102  // again, first collect some data about the
7103  // indices of the lines, with the following
7104  // numbering:
7105 
7106  // face 0: left plane
7107  // *
7108  // /|
7109  // * |
7110  // /| |
7111  // * | |
7112  // | 0 |
7113  // | | *
7114  // | |/
7115  // | *m0
7116  // |/
7117  // *
7118  // face 1: right plane
7119  // *
7120  // /|
7121  // m1* |
7122  // /| |
7123  // * | |
7124  // | 1 |
7125  // | | *
7126  // | |/
7127  // | *
7128  // |/
7129  // *
7130  // face 4: bottom plane
7131  // *-------*
7132  // / /
7133  // m0*---2---*
7134  // / /
7135  // *-------*
7136  // face 5: top plane
7137  // *-------*
7138  // / /
7139  // *---3---*m1
7140  // / /
7141  // *-------*
7142 
7143  // set up a list of line iterators first. from
7144  // this, construct lists of line_indices and
7145  // line orientations later on
7146  const typename Triangulation<dim, spacedim>::
7147  raw_line_iterator lines[4] = {
7148  hex->face(0)->child(0)->line(
7149  (hex->face(0)->refinement_case() ==
7151  1 :
7152  3), // 0
7153  hex->face(1)->child(0)->line(
7154  (hex->face(1)->refinement_case() ==
7156  1 :
7157  3), // 1
7158  hex->face(4)->child(0)->line(
7159  (hex->face(4)->refinement_case() ==
7161  1 :
7162  3), // 2
7163  hex->face(5)->child(0)->line(
7164  (hex->face(5)->refinement_case() ==
7166  1 :
7167  3) // 3
7168  };
7169 
7170  unsigned int line_indices[4];
7171  for (unsigned int i = 0; i < 4; ++i)
7172  line_indices[i] = lines[i]->index();
7173 
7174  // the orientation of lines for the inner quads
7175  // is quite tricky. as these lines are newly
7176  // created ones and thus have no parents, they
7177  // cannot inherit this property. set up an array
7178  // and fill it with the respective values
7179  bool line_orientation[4];
7180 
7181  // the middle vertex marked as m0 above is the
7182  // start vertex for lines 0 and 2 in standard
7183  // orientation, whereas m1 is the end vertex of
7184  // lines 1 and 3 in standard orientation
7185  const unsigned int middle_vertices[2] = {
7186  hex->line(0)->child(0)->vertex_index(1),
7187  hex->line(5)->child(0)->vertex_index(1)};
7188 
7189  for (unsigned int i = 0; i < 4; ++i)
7190  if (lines[i]->vertex_index(i % 2) ==
7191  middle_vertices[i % 2])
7192  line_orientation[i] = true;
7193  else
7194  {
7195  // it must be the other way round then
7196  Assert(lines[i]->vertex_index((i + 1) % 2) ==
7197  middle_vertices[i % 2],
7198  ExcInternalError());
7199  line_orientation[i] = false;
7200  }
7201 
7202  // set up the new quad, line numbering is as
7203  // indicated above
7204  new_quads[0]->set(
7206  2>(line_indices[2],
7207  line_indices[3],
7208  line_indices[0],
7209  line_indices[1]));
7210 
7211  new_quads[0]->set_line_orientation(
7212  0, line_orientation[2]);
7213  new_quads[0]->set_line_orientation(
7214  1, line_orientation[3]);
7215  new_quads[0]->set_line_orientation(
7216  2, line_orientation[0]);
7217  new_quads[0]->set_line_orientation(
7218  3, line_orientation[1]);
7219 
7220  // the quads are numbered as follows:
7221  //
7222  // planes in the interior of the old hex:
7223  //
7224  // *
7225  // /|
7226  // / | x
7227  // / | *-------* *---------*
7228  // * | | | / /
7229  // | | | 0 | / /
7230  // | * | | / /
7231  // | / *-------*y *---------*x
7232  // | /
7233  // |/
7234  // *
7235  //
7236  // children of the faces of the old hex
7237  //
7238  // *-------* *-------*
7239  // /| | / 10 /|
7240  // * | | *-------* |
7241  // /| | 6 | / 9 /| |
7242  // * |2| | *-------* |4|
7243  // | | *-------* | | | *
7244  // |1|/ 8 / | |3|/
7245  // | *-------* | 5 | *
7246  // |/ 7 / | |/
7247  // *-------* *-------*
7248  //
7249  // note that we have to take care of the
7250  // orientation of faces.
7251  const int quad_indices[11] = {
7252  new_quads[0]->index(), // 0
7253 
7254  hex->face(0)->child_index(
7255  child_at_origin[hex->face(0)->refinement_case() -
7256  1][f_fl[0]][f_ro[0]]), // 1
7257  hex->face(0)->child_index(
7258  1 -
7259  child_at_origin[hex->face(0)->refinement_case() -
7260  1][f_fl[0]][f_ro[0]]),
7261 
7262  hex->face(1)->child_index(
7263  child_at_origin[hex->face(1)->refinement_case() -
7264  1][f_fl[1]][f_ro[1]]), // 3
7265  hex->face(1)->child_index(
7266  1 -
7267  child_at_origin[hex->face(1)->refinement_case() -
7268  1][f_fl[1]][f_ro[1]]),
7269 
7270  hex->face(2)->index(), // 5
7271 
7272  hex->face(3)->index(), // 6
7273 
7274  hex->face(4)->child_index(
7275  child_at_origin[hex->face(4)->refinement_case() -
7276  1][f_fl[4]][f_ro[4]]), // 7
7277  hex->face(4)->child_index(
7278  1 -
7279  child_at_origin[hex->face(4)->refinement_case() -
7280  1][f_fl[4]][f_ro[4]]),
7281 
7282  hex->face(5)->child_index(
7283  child_at_origin[hex->face(5)->refinement_case() -
7284  1][f_fl[5]][f_ro[5]]), // 9
7285  hex->face(5)->child_index(
7286  1 -
7287  child_at_origin[hex->face(5)->refinement_case() -
7288  1][f_fl[5]][f_ro[5]])
7289 
7290  };
7291 
7292  new_hexes[0]->set(
7294  3>(quad_indices[1],
7295  quad_indices[3],
7296  quad_indices[5],
7297  quad_indices[0],
7298  quad_indices[7],
7299  quad_indices[9]));
7300  new_hexes[1]->set(
7302  3>(quad_indices[2],
7303  quad_indices[4],
7304  quad_indices[0],
7305  quad_indices[6],
7306  quad_indices[8],
7307  quad_indices[10]));
7308  break;
7309  }
7310 
7312  {
7314  //
7315  // RefinementCase<dim>::cut_z
7316  //
7317  // the refined cube will look like this:
7318  //
7319  // *---------*
7320  // / /|
7321  // / / |
7322  // / / *
7323  // *---------* /|
7324  // | | / |
7325  // | |/ *
7326  // *---------* /
7327  // | | /
7328  // | |/
7329  // *---------*
7330  //
7331  // again, first collect some data about the
7332  // indices of the lines, with the following
7333  // numbering:
7334 
7335  // face 0: left plane
7336  // *
7337  // /|
7338  // / |
7339  // / *
7340  // * /|
7341  // | 0 |
7342  // |/ *
7343  // m0* /
7344  // | /
7345  // |/
7346  // *
7347  // face 1: right plane
7348  // *
7349  // /|
7350  // / |
7351  // / *m1
7352  // * /|
7353  // | 1 |
7354  // |/ *
7355  // * /
7356  // | /
7357  // |/
7358  // *
7359  // face 2: front plane
7360  // (note: x,y exchanged)
7361  // *-------*
7362  // | |
7363  // m0*---2---*
7364  // | |
7365  // *-------*
7366  // face 3: back plane
7367  // (note: x,y exchanged)
7368  // *-------*
7369  // | |
7370  // *---3---*m1
7371  // | |
7372  // *-------*
7373 
7374  // set up a list of line iterators first. from
7375  // this, construct lists of line_indices and
7376  // line orientations later on
7377  const typename Triangulation<dim, spacedim>::
7378  raw_line_iterator lines[4] = {
7379  hex->face(0)->child(0)->line(
7380  (hex->face(0)->refinement_case() ==
7382  1 :
7383  3), // 0
7384  hex->face(1)->child(0)->line(
7385  (hex->face(1)->refinement_case() ==
7387  1 :
7388  3), // 1
7389  hex->face(2)->child(0)->line(
7390  (hex->face(2)->refinement_case() ==
7392  1 :
7393  3), // 2
7394  hex->face(3)->child(0)->line(
7395  (hex->face(3)->refinement_case() ==
7397  1 :
7398  3) // 3
7399  };
7400 
7401  unsigned int line_indices[4];
7402  for (unsigned int i = 0; i < 4; ++i)
7403  line_indices[i] = lines[i]->index();
7404 
7405  // the orientation of lines for the inner quads
7406  // is quite tricky. as these lines are newly
7407  // created ones and thus have no parents, they
7408  // cannot inherit this property. set up an array
7409  // and fill it with the respective values
7410  bool line_orientation[4];
7411 
7412  // the middle vertex marked as m0 above is the
7413  // start vertex for lines 0 and 2 in standard
7414  // orientation, whereas m1 is the end vertex of
7415  // lines 1 and 3 in standard orientation
7416  const unsigned int middle_vertices[2] = {
7417  middle_vertex_index<dim, spacedim>(hex->line(8)),
7418  middle_vertex_index<dim, spacedim>(hex->line(11))};
7419 
7420  for (unsigned int i = 0; i < 4; ++i)
7421  if (lines[i]->vertex_index(i % 2) ==
7422  middle_vertices[i % 2])
7423  line_orientation[i] = true;
7424  else
7425  {
7426  // it must be the other way round then
7427  Assert(lines[i]->vertex_index((i + 1) % 2) ==
7428  middle_vertices[i % 2],
7429  ExcInternalError());
7430  line_orientation[i] = false;
7431  }
7432 
7433  // set up the new quad, line numbering is as
7434  // indicated above
7435  new_quads[0]->set(
7437  2>(line_indices[0],
7438  line_indices[1],
7439  line_indices[2],
7440  line_indices[3]));
7441 
7442  new_quads[0]->set_line_orientation(
7443  0, line_orientation[0]);
7444  new_quads[0]->set_line_orientation(
7445  1, line_orientation[1]);
7446  new_quads[0]->set_line_orientation(
7447  2, line_orientation[2]);
7448  new_quads[0]->set_line_orientation(
7449  3, line_orientation[3]);
7450 
7451  // the quads are numbered as follows:
7452  //
7453  // planes in the interior of the old hex:
7454  //
7455  // *
7456  // /|
7457  // / | x
7458  // / | *-------* *---------*
7459  // * | | | / /
7460  // | | | | / 0 /
7461  // | * | | / /
7462  // | / *-------*y *---------*x
7463  // | /
7464  // |/
7465  // *
7466  //
7467  // children of the faces of the old hex
7468  //
7469  // *---*---* *-------*
7470  // /| 8 | / /|
7471  // / | | / 10 / |
7472  // / *-------* / / *
7473  // * 2/| | *-------* 4/|
7474  // | / | 7 | | 6 | / |
7475  // |/1 *-------* | |/3 *
7476  // * / / *-------* /
7477  // | / 9 / | | /
7478  // |/ / | 5 |/
7479  // *-------* *---*---*
7480  //
7481  // note that we have to take care of the
7482  // orientation of faces.
7483  const int quad_indices[11] = {
7484  new_quads[0]->index(), // 0
7485 
7486  hex->face(0)->child_index(
7487  child_at_origin[hex->face(0)->refinement_case() -
7488  1][f_fl[0]][f_ro[0]]), // 1
7489  hex->face(0)->child_index(
7490  1 -
7491  child_at_origin[hex->face(0)->refinement_case() -
7492  1][f_fl[0]][f_ro[0]]),
7493 
7494  hex->face(1)->child_index(
7495  child_at_origin[hex->face(1)->refinement_case() -
7496  1][f_fl[1]][f_ro[1]]), // 3
7497  hex->face(1)->child_index(
7498  1 -
7499  child_at_origin[hex->face(1)->refinement_case() -
7500  1][f_fl[1]][f_ro[1]]),
7501 
7502  hex->face(2)->child_index(
7503  child_at_origin[hex->face(2)->refinement_case() -
7504  1][f_fl[2]][f_ro[2]]), // 5
7505  hex->face(2)->child_index(
7506  1 -
7507  child_at_origin[hex->face(2)->refinement_case() -
7508  1][f_fl[2]][f_ro[2]]),
7509 
7510  hex->face(3)->child_index(
7511  child_at_origin[hex->face(3)->refinement_case() -
7512  1][f_fl[3]][f_ro[3]]), // 7
7513  hex->face(3)->child_index(
7514  1 -
7515  child_at_origin[hex->face(3)->refinement_case() -
7516  1][f_fl[3]][f_ro[3]]),
7517 
7518  hex->face(4)->index(), // 9
7519 
7520  hex->face(5)->index() // 10
7521  };
7522 
7523  new_hexes[0]->set(
7525  3>(quad_indices[1],
7526  quad_indices[3],
7527  quad_indices[5],
7528  quad_indices[7],
7529  quad_indices[9],
7530  quad_indices[0]));
7531  new_hexes[1]->set(
7533  3>(quad_indices[2],
7534  quad_indices[4],
7535  quad_indices[6],
7536  quad_indices[8],
7537  quad_indices[0],
7538  quad_indices[10]));
7539  break;
7540  }
7541 
7543  {
7545  //
7546  // RefinementCase<dim>::cut_xy
7547  //
7548  // the refined cube will look like this:
7549  //
7550  // *----*----*
7551  // / / /|
7552  // *----*----* |
7553  // / / /| |
7554  // *----*----* | |
7555  // | | | | |
7556  // | | | | *
7557  // | | | |/
7558  // | | | *
7559  // | | |/
7560  // *----*----*
7561  //
7562 
7563  // first, create the new internal line
7564  new_lines[0]->set(
7566  1>(middle_vertex_index<dim, spacedim>(
7567  hex->face(4)),
7568  middle_vertex_index<dim, spacedim>(
7569  hex->face(5))));
7570 
7571  // again, first collect some data about the
7572  // indices of the lines, with the following
7573  // numbering:
7574 
7575  // face 0: left plane
7576  // *
7577  // /|
7578  // * |
7579  // /| |
7580  // * | |
7581  // | 0 |
7582  // | | *
7583  // | |/
7584  // | *
7585  // |/
7586  // *
7587  // face 1: right plane
7588  // *
7589  // /|
7590  // * |
7591  // /| |
7592  // * | |
7593  // | 1 |
7594  // | | *
7595  // | |/
7596  // | *
7597  // |/
7598  // *
7599  // face 2: front plane
7600  // (note: x,y exchanged)
7601  // *---*---*
7602  // | | |
7603  // | 2 |
7604  // | | |
7605  // *-------*
7606  // face 3: back plane
7607  // (note: x,y exchanged)
7608  // *---*---*
7609  // | | |
7610  // | 3 |
7611  // | | |
7612  // *---*---*
7613  // face 4: bottom plane
7614  // *---*---*
7615  // / 5 /
7616  // *-6-*-7-*
7617  // / 4 /
7618  // *---*---*
7619  // face 5: top plane
7620  // *---*---*
7621  // / 9 /
7622  // *10-*-11*
7623  // / 8 /
7624  // *---*---*
7625  // middle planes
7626  // *-------* *---*---*
7627  // / / | | |
7628  // / / | 12 |
7629  // / / | | |
7630  // *-------* *---*---*
7631 
7632  // set up a list of line iterators first. from
7633  // this, construct lists of line_indices and
7634  // line orientations later on
7635  const typename Triangulation<
7636  dim,
7637  spacedim>::raw_line_iterator lines[13] = {
7638  hex->face(0)->child(0)->line(
7639  (hex->face(0)->refinement_case() ==
7641  1 :
7642  3), // 0
7643  hex->face(1)->child(0)->line(
7644  (hex->face(1)->refinement_case() ==
7646  1 :
7647  3), // 1
7648  hex->face(2)->child(0)->line(
7649  (hex->face(2)->refinement_case() ==
7651  1 :
7652  3), // 2
7653  hex->face(3)->child(0)->line(
7654  (hex->face(3)->refinement_case() ==
7656  1 :
7657  3), // 3
7658 
7659  hex->face(4)
7660  ->isotropic_child(
7662  0, f_or[4], f_fl[4], f_ro[4]))
7663  ->line(
7665  1, f_or[4], f_fl[4], f_ro[4])), // 4
7666  hex->face(4)
7667  ->isotropic_child(
7669  3, f_or[4], f_fl[4], f_ro[4]))
7670  ->line(
7672  0, f_or[4], f_fl[4], f_ro[4])), // 5
7673  hex->face(4)
7674  ->isotropic_child(
7676  0, f_or[4], f_fl[4], f_ro[4]))
7677  ->line(
7679  3, f_or[4], f_fl[4], f_ro[4])), // 6
7680  hex->face(4)
7681  ->isotropic_child(
7683  3, f_or[4], f_fl[4], f_ro[4]))
7684  ->line(
7686  2, f_or[4], f_fl[4], f_ro[4])), // 7
7687 
7688  hex->face(5)
7689  ->isotropic_child(
7691  0, f_or[5], f_fl[5], f_ro[5]))
7692  ->line(
7694  1, f_or[5], f_fl[5], f_ro[5])), // 8
7695  hex->face(5)
7696  ->isotropic_child(
7698  3, f_or[5], f_fl[5], f_ro[5]))
7699  ->line(
7701  0, f_or[5], f_fl[5], f_ro[5])), // 9
7702  hex->face(5)
7703  ->isotropic_child(
7705  0, f_or[5], f_fl[5], f_ro[5]))
7706  ->line(
7708  3, f_or[5], f_fl[5], f_ro[5])), // 10
7709  hex->face(5)
7710  ->isotropic_child(
7712  3, f_or[5], f_fl[5], f_ro[5]))
7713  ->line(
7715  2, f_or[5], f_fl[5], f_ro[5])), // 11
7716 
7717  new_lines[0] // 12
7718  };
7719 
7720  unsigned int line_indices[13];
7721  for (unsigned int i = 0; i < 13; ++i)
7722  line_indices[i] = lines[i]->index();
7723 
7724  // the orientation of lines for the inner quads
7725  // is quite tricky. as these lines are newly
7726  // created ones and thus have no parents, they
7727  // cannot inherit this property. set up an array
7728  // and fill it with the respective values
7729  bool line_orientation[13];
7730 
7731  // the middle vertices of the lines of our
7732  // bottom face
7733  const unsigned int middle_vertices[4] = {
7734  hex->line(0)->child(0)->vertex_index(1),
7735  hex->line(1)->child(0)->vertex_index(1),
7736  hex->line(2)->child(0)->vertex_index(1),
7737  hex->line(3)->child(0)->vertex_index(1),
7738  };
7739 
7740  // note: for lines 0 to 3 the orientation of the
7741  // line is 'true', if vertex 0 is on the bottom
7742  // face
7743  for (unsigned int i = 0; i < 4; ++i)
7744  if (lines[i]->vertex_index(0) == middle_vertices[i])
7745  line_orientation[i] = true;
7746  else
7747  {
7748  // it must be the other way round then
7749  Assert(lines[i]->vertex_index(1) ==
7750  middle_vertices[i],
7751  ExcInternalError());
7752  line_orientation[i] = false;
7753  }
7754 
7755  // note: for lines 4 to 11 (inner lines of the
7756  // outer quads) the following holds: the second
7757  // vertex of the even lines in standard
7758  // orientation is the vertex in the middle of
7759  // the quad, whereas for odd lines the first
7760  // vertex is the same middle vertex.
7761  for (unsigned int i = 4; i < 12; ++i)
7762  if (lines[i]->vertex_index((i + 1) % 2) ==
7763  middle_vertex_index<dim, spacedim>(
7764  hex->face(3 + i / 4)))
7765  line_orientation[i] = true;
7766  else
7767  {
7768  // it must be the other way
7769  // round then
7770  Assert(lines[i]->vertex_index(i % 2) ==
7771  (middle_vertex_index<dim, spacedim>(
7772  hex->face(3 + i / 4))),
7773  ExcInternalError());
7774  line_orientation[i] = false;
7775  }
7776  // for the last line the line orientation is
7777  // always true, since it was just constructed
7778  // that way
7779  line_orientation[12] = true;
7780 
7781  // set up the 4 quads, numbered as follows (left
7782  // quad numbering, right line numbering
7783  // extracted from above)
7784  //
7785  // * *
7786  // /| 9|
7787  // * | * |
7788  // y/| | 8| 3
7789  // * |1| * | |
7790  // | | |x | 12|
7791  // |0| * | | *
7792  // | |/ 2 |5
7793  // | * | *
7794  // |/ |4
7795  // * *
7796  //
7797  // x
7798  // *---*---* *10-*-11*
7799  // | | | | | |
7800  // | 2 | 3 | 0 12 1
7801  // | | | | | |
7802  // *---*---*y *-6-*-7-*
7803 
7804  new_quads[0]->set(
7806  2>(line_indices[2],
7807  line_indices[12],
7808  line_indices[4],
7809  line_indices[8]));
7810  new_quads[1]->set(
7812  2>(line_indices[12],
7813  line_indices[3],
7814  line_indices[5],
7815  line_indices[9]));
7816  new_quads[2]->set(
7818  2>(line_indices[6],
7819  line_indices[10],
7820  line_indices[0],
7821  line_indices[12]));
7822  new_quads[3]->set(
7824  2>(line_indices[7],
7825  line_indices[11],
7826  line_indices[12],
7827  line_indices[1]));
7828 
7829  new_quads[0]->set_line_orientation(
7830  0, line_orientation[2]);
7831  new_quads[0]->set_line_orientation(
7832  2, line_orientation[4]);
7833  new_quads[0]->set_line_orientation(
7834  3, line_orientation[8]);
7835 
7836  new_quads[1]->set_line_orientation(
7837  1, line_orientation[3]);
7838  new_quads[1]->set_line_orientation(
7839  2, line_orientation[5]);
7840  new_quads[1]->set_line_orientation(
7841  3, line_orientation[9]);
7842 
7843  new_quads[2]->set_line_orientation(
7844  0, line_orientation[6]);
7845  new_quads[2]->set_line_orientation(
7846  1, line_orientation[10]);
7847  new_quads[2]->set_line_orientation(
7848  2, line_orientation[0]);
7849 
7850  new_quads[3]->set_line_orientation(
7851  0, line_orientation[7]);
7852  new_quads[3]->set_line_orientation(
7853  1, line_orientation[11]);
7854  new_quads[3]->set_line_orientation(
7855  3, line_orientation[1]);
7856 
7857  // the quads are numbered as follows:
7858  //
7859  // planes in the interior of the old hex:
7860  //
7861  // *
7862  // /|
7863  // * | x
7864  // /| | *---*---* *---------*
7865  // * |1| | | | / /
7866  // | | | | 2 | 3 | / /
7867  // |0| * | | | / /
7868  // | |/ *---*---*y *---------*x
7869  // | *
7870  // |/
7871  // *
7872  //
7873  // children of the faces of the old hex
7874  //
7875  // *---*---* *---*---*
7876  // /| | | /18 / 19/|
7877  // * |10 | 11| /---/---* |
7878  // /| | | | /16 / 17/| |
7879  // * |5| | | *---*---* |7|
7880  // | | *---*---* | | | | *
7881  // |4|/14 / 15/ | | |6|/
7882  // | *---/---/ | 8 | 9 | *
7883  // |/12 / 13/ | | |/
7884  // *---*---* *---*---*
7885  //
7886  // note that we have to take care of the
7887  // orientation of faces.
7888  const int quad_indices[20] = {
7889  new_quads[0]->index(), // 0
7890  new_quads[1]->index(),
7891  new_quads[2]->index(),
7892  new_quads[3]->index(),
7893 
7894  hex->face(0)->child_index(
7895  child_at_origin[hex->face(0)->refinement_case() -
7896  1][f_fl[0]][f_ro[0]]), // 4
7897  hex->face(0)->child_index(
7898  1 -
7899  child_at_origin[hex->face(0)->refinement_case() -
7900  1][f_fl[0]][f_ro[0]]),
7901 
7902  hex->face(1)->child_index(
7903  child_at_origin[hex->face(1)->refinement_case() -
7904  1][f_fl[1]][f_ro[1]]), // 6
7905  hex->face(1)->child_index(
7906  1 -
7907  child_at_origin[hex->face(1)->refinement_case() -
7908  1][f_fl[1]][f_ro[1]]),
7909 
7910  hex->face(2)->child_index(
7911  child_at_origin[hex->face(2)->refinement_case() -
7912  1][f_fl[2]][f_ro[2]]), // 8
7913  hex->face(2)->child_index(
7914  1 -
7915  child_at_origin[hex->face(2)->refinement_case() -
7916  1][f_fl[2]][f_ro[2]]),
7917 
7918  hex->face(3)->child_index(
7919  child_at_origin[hex->face(3)->refinement_case() -
7920  1][f_fl[3]][f_ro[3]]), // 10
7921  hex->face(3)->child_index(
7922  1 -
7923  child_at_origin[hex->face(3)->refinement_case() -
7924  1][f_fl[3]][f_ro[3]]),
7925 
7926  hex->face(4)->isotropic_child_index(
7928  0, f_or[4], f_fl[4], f_ro[4])), // 12
7929  hex->face(4)->isotropic_child_index(
7931  1, f_or[4], f_fl[4], f_ro[4])),
7932  hex->face(4)->isotropic_child_index(
7934  2, f_or[4], f_fl[4], f_ro[4])),
7935  hex->face(4)->isotropic_child_index(
7937  3, f_or[4], f_fl[4], f_ro[4])),
7938 
7939  hex->face(5)->isotropic_child_index(
7941  0, f_or[5], f_fl[5], f_ro[5])), // 16
7942  hex->face(5)->isotropic_child_index(
7944  1, f_or[5], f_fl[5], f_ro[5])),
7945  hex->face(5)->isotropic_child_index(
7947  2, f_or[5], f_fl[5], f_ro[5])),
7948  hex->face(5)->isotropic_child_index(
7950  3, f_or[5], f_fl[5], f_ro[5]))};
7951 
7952  new_hexes[0]->set(
7954  3>(quad_indices[4],
7955  quad_indices[0],
7956  quad_indices[8],
7957  quad_indices[2],
7958  quad_indices[12],
7959  quad_indices[16]));
7960  new_hexes[1]->set(
7962  3>(quad_indices[0],
7963  quad_indices[6],
7964  quad_indices[9],
7965  quad_indices[3],
7966  quad_indices[13],
7967  quad_indices[17]));
7968  new_hexes[2]->set(
7970  3>(quad_indices[5],
7971  quad_indices[1],
7972  quad_indices[2],
7973  quad_indices[10],
7974  quad_indices[14],
7975  quad_indices[18]));
7976  new_hexes[3]->set(
7978  3>(quad_indices[1],
7979  quad_indices[7],
7980  quad_indices[3],
7981  quad_indices[11],
7982  quad_indices[15],
7983  quad_indices[19]));
7984  break;
7985  }
7986 
7988  {
7990  //
7991  // RefinementCase<dim>::cut_xz
7992  //
7993  // the refined cube will look like this:
7994  //
7995  // *----*----*
7996  // / / /|
7997  // / / / |
7998  // / / / *
7999  // *----*----* /|
8000  // | | | / |
8001  // | | |/ *
8002  // *----*----* /
8003  // | | | /
8004  // | | |/
8005  // *----*----*
8006  //
8007 
8008  // first, create the new internal line
8009  new_lines[0]->set(
8011  1>(middle_vertex_index<dim, spacedim>(
8012  hex->face(2)),
8013  middle_vertex_index<dim, spacedim>(
8014  hex->face(3))));
8015 
8016  // again, first collect some data about the
8017  // indices of the lines, with the following
8018  // numbering:
8019 
8020  // face 0: left plane
8021  // *
8022  // /|
8023  // / |
8024  // / *
8025  // * /|
8026  // | 0 |
8027  // |/ *
8028  // * /
8029  // | /
8030  // |/
8031  // *
8032  // face 1: right plane
8033  // *
8034  // /|
8035  // / |
8036  // / *
8037  // * /|
8038  // | 1 |
8039  // |/ *
8040  // * /
8041  // | /
8042  // |/
8043  // *
8044  // face 2: front plane
8045  // (note: x,y exchanged)
8046  // *---*---*
8047  // | 5 |
8048  // *-6-*-7-*
8049  // | 4 |
8050  // *---*---*
8051  // face 3: back plane
8052  // (note: x,y exchanged)
8053  // *---*---*
8054  // | 9 |
8055  // *10-*-11*
8056  // | 8 |
8057  // *---*---*
8058  // face 4: bottom plane
8059  // *---*---*
8060  // / / /
8061  // / 2 /
8062  // / / /
8063  // *---*---*
8064  // face 5: top plane
8065  // *---*---*
8066  // / / /
8067  // / 3 /
8068  // / / /
8069  // *---*---*
8070  // middle planes
8071  // *---*---* *-------*
8072  // / / / | |
8073  // / 12 / | |
8074  // / / / | |
8075  // *---*---* *-------*
8076 
8077  // set up a list of line iterators first. from
8078  // this, construct lists of line_indices and
8079  // line orientations later on
8080  const typename Triangulation<
8081  dim,
8082  spacedim>::raw_line_iterator lines[13] = {
8083  hex->face(0)->child(0)->line(
8084  (hex->face(0)->refinement_case() ==
8086  1 :
8087  3), // 0
8088  hex->face(1)->child(0)->line(
8089  (hex->face(1)->refinement_case() ==
8091  1 :
8092  3), // 1
8093  hex->face(4)->child(0)->line(
8094  (hex->face(4)->refinement_case() ==
8096  1 :
8097  3), // 2
8098  hex->face(5)->child(0)->line(
8099  (hex->face(5)->refinement_case() ==
8101  1 :
8102  3), // 3
8103 
8104  hex->face(2)
8105  ->isotropic_child(
8107  0, f_or[2], f_fl[2], f_ro[2]))
8108  ->line(
8110  3, f_or[2], f_fl[2], f_ro[2])), // 4
8111  hex->face(2)
8112  ->isotropic_child(
8114  3, f_or[2], f_fl[2], f_ro[2]))
8115  ->line(
8117  2, f_or[2], f_fl[2], f_ro[2])), // 5
8118  hex->face(2)
8119  ->isotropic_child(
8121  0, f_or[2], f_fl[2], f_ro[2]))
8122  ->line(
8124  1, f_or[2], f_fl[2], f_ro[2])), // 6
8125  hex->face(2)
8126  ->isotropic_child(
8128  3, f_or[2], f_fl[2], f_ro[2]))
8129  ->line(
8131  0, f_or[2], f_fl[2], f_ro[2])), // 7
8132 
8133  hex->face(3)
8134  ->isotropic_child(
8136  0, f_or[3], f_fl[3], f_ro[3]))
8137  ->line(
8139  3, f_or[3], f_fl[3], f_ro[3])), // 8
8140  hex->face(3)
8141  ->isotropic_child(
8143  3, f_or[3], f_fl[3], f_ro[3]))
8144  ->line(
8146  2, f_or[3], f_fl[3], f_ro[3])), // 9
8147  hex->face(3)
8148  ->isotropic_child(
8150  0, f_or[3], f_fl[3], f_ro[3]))
8151  ->line(
8153  1, f_or[3], f_fl[3], f_ro[3])), // 10
8154  hex->face(3)
8155  ->isotropic_child(
8157  3, f_or[3], f_fl[3], f_ro[3]))
8158  ->line(
8160  0, f_or[3], f_fl[3], f_ro[3])), // 11
8161 
8162  new_lines[0] // 12
8163  };
8164 
8165  unsigned int line_indices[13];
8166  for (unsigned int i = 0; i < 13; ++i)
8167  line_indices[i] = lines[i]->index();
8168 
8169  // the orientation of lines for the inner quads
8170  // is quite tricky. as these lines are newly
8171  // created ones and thus have no parents, they
8172  // cannot inherit this property. set up an array
8173  // and fill it with the respective values
8174  bool line_orientation[13];
8175 
8176  // the middle vertices of the
8177  // lines of our front face
8178  const unsigned int middle_vertices[4] = {
8179  hex->line(8)->child(0)->vertex_index(1),
8180  hex->line(9)->child(0)->vertex_index(1),
8181  hex->line(2)->child(0)->vertex_index(1),
8182  hex->line(6)->child(0)->vertex_index(1),
8183  };
8184 
8185  // note: for lines 0 to 3 the orientation of the
8186  // line is 'true', if vertex 0 is on the front
8187  for (unsigned int i = 0; i < 4; ++i)
8188  if (lines[i]->vertex_index(0) == middle_vertices[i])
8189  line_orientation[i] = true;
8190  else
8191  {
8192  // it must be the other way round then
8193  Assert(lines[i]->vertex_index(1) ==
8194  middle_vertices[i],
8195  ExcInternalError());
8196  line_orientation[i] = false;
8197  }
8198 
8199  // note: for lines 4 to 11 (inner lines of the
8200  // outer quads) the following holds: the second
8201  // vertex of the even lines in standard
8202  // orientation is the vertex in the middle of
8203  // the quad, whereas for odd lines the first
8204  // vertex is the same middle vertex.
8205  for (unsigned int i = 4; i < 12; ++i)
8206  if (lines[i]->vertex_index((i + 1) % 2) ==
8207  middle_vertex_index<dim, spacedim>(
8208  hex->face(1 + i / 4)))
8209  line_orientation[i] = true;
8210  else
8211  {
8212  // it must be the other way
8213  // round then
8214  Assert(lines[i]->vertex_index(i % 2) ==
8215  (middle_vertex_index<dim, spacedim>(
8216  hex->face(1 + i / 4))),
8217  ExcInternalError());
8218  line_orientation[i] = false;
8219  }
8220  // for the last line the line orientation is
8221  // always true, since it was just constructed
8222  // that way
8223  line_orientation[12] = true;
8224 
8225  // set up the 4 quads, numbered as follows (left
8226  // quad numbering, right line numbering
8227  // extracted from above), the drawings denote
8228  // middle planes
8229  //
8230  // * *
8231  // /| /|
8232  // / | 3 9
8233  // y/ * / *
8234  // * 3/| * /|
8235  // | / |x 5 12|8
8236  // |/ * |/ *
8237  // * 2/ * /
8238  // | / 4 2
8239  // |/ |/
8240  // * *
8241  //
8242  // y
8243  // *----*----* *-10-*-11-*
8244  // / / / / / /
8245  // / 0 / 1 / 0 12 1
8246  // / / / / / /
8247  // *----*----*x *--6-*--7-*
8248 
8249  new_quads[0]->set(
8251  2>(line_indices[0],
8252  line_indices[12],
8253  line_indices[6],
8254  line_indices[10]));
8255  new_quads[1]->set(
8257  2>(line_indices[12],
8258  line_indices[1],
8259  line_indices[7],
8260  line_indices[11]));
8261  new_quads[2]->set(
8263  2>(line_indices[4],
8264  line_indices[8],
8265  line_indices[2],
8266  line_indices[12]));
8267  new_quads[3]->set(
8269  2>(line_indices[5],
8270  line_indices[9],
8271  line_indices[12],
8272  line_indices[3]));
8273 
8274  new_quads[0]->set_line_orientation(
8275  0, line_orientation[0]);
8276  new_quads[0]->set_line_orientation(
8277  2, line_orientation[6]);
8278  new_quads[0]->set_line_orientation(
8279  3, line_orientation[10]);
8280 
8281  new_quads[1]->set_line_orientation(
8282  1, line_orientation[1]);
8283  new_quads[1]->set_line_orientation(
8284  2, line_orientation[7]);
8285  new_quads[1]->set_line_orientation(
8286  3, line_orientation[11]);
8287 
8288  new_quads[2]->set_line_orientation(
8289  0, line_orientation[4]);
8290  new_quads[2]->set_line_orientation(
8291  1, line_orientation[8]);
8292  new_quads[2]->set_line_orientation(
8293  2, line_orientation[2]);
8294 
8295  new_quads[3]->set_line_orientation(
8296  0, line_orientation[5]);
8297  new_quads[3]->set_line_orientation(
8298  1, line_orientation[9]);
8299  new_quads[3]->set_line_orientation(
8300  3, line_orientation[3]);
8301 
8302  // the quads are numbered as follows:
8303  //
8304  // planes in the interior of the old hex:
8305  //
8306  // *
8307  // /|
8308  // / | x
8309  // /3 * *-------* *----*----*
8310  // * /| | | / / /
8311  // | / | | | / 0 / 1 /
8312  // |/ * | | / / /
8313  // * 2/ *-------*y *----*----*x
8314  // | /
8315  // |/
8316  // *
8317  //
8318  // children of the faces
8319  // of the old hex
8320  // *---*---* *---*---*
8321  // /|13 | 15| / / /|
8322  // / | | | /18 / 19/ |
8323  // / *---*---* / / / *
8324  // * 5/| | | *---*---* 7/|
8325  // | / |12 | 14| | 9 | 11| / |
8326  // |/4 *---*---* | | |/6 *
8327  // * / / / *---*---* /
8328  // | /16 / 17/ | | | /
8329  // |/ / / | 8 | 10|/
8330  // *---*---* *---*---*
8331  //
8332  // note that we have to take care of the
8333  // orientation of faces.
8334  const int quad_indices[20] = {
8335  new_quads[0]->index(), // 0
8336  new_quads[1]->index(),
8337  new_quads[2]->index(),
8338  new_quads[3]->index(),
8339 
8340  hex->face(0)->child_index(
8341  child_at_origin[hex->face(0)->refinement_case() -
8342  1][f_fl[0]][f_ro[0]]), // 4
8343  hex->face(0)->child_index(
8344  1 -
8345  child_at_origin[hex->face(0)->refinement_case() -
8346  1][f_fl[0]][f_ro[0]]),
8347 
8348  hex->face(1)->child_index(
8349  child_at_origin[hex->face(1)->refinement_case() -
8350  1][f_fl[1]][f_ro[1]]), // 6
8351  hex->face(1)->child_index(
8352  1 -
8353  child_at_origin[hex->face(1)->refinement_case() -
8354  1][f_fl[1]][f_ro[1]]),
8355 
8356  hex->face(2)->isotropic_child_index(
8358  0, f_or[2], f_fl[2], f_ro[2])), // 8
8359  hex->face(2)->isotropic_child_index(
8361  1, f_or[2], f_fl[2], f_ro[2])),
8362  hex->face(2)->isotropic_child_index(
8364  2, f_or[2], f_fl[2], f_ro[2])),
8365  hex->face(2)->isotropic_child_index(
8367  3, f_or[2], f_fl[2], f_ro[2])),
8368 
8369  hex->face(3)->isotropic_child_index(
8371  0, f_or[3], f_fl[3], f_ro[3])), // 12
8372  hex->face(3)->isotropic_child_index(
8374  1, f_or[3], f_fl[3], f_ro[3])),
8375  hex->face(3)->isotropic_child_index(
8377  2, f_or[3], f_fl[3], f_ro[3])),
8378  hex->face(3)->isotropic_child_index(
8380  3, f_or[3], f_fl[3], f_ro[3])),
8381 
8382  hex->face(4)->child_index(
8383  child_at_origin[hex->face(4)->refinement_case() -
8384  1][f_fl[4]][f_ro[4]]), // 16
8385  hex->face(4)->child_index(
8386  1 -
8387  child_at_origin[hex->face(4)->refinement_case() -
8388  1][f_fl[4]][f_ro[4]]),
8389 
8390  hex->face(5)->child_index(
8391  child_at_origin[hex->face(5)->refinement_case() -
8392  1][f_fl[5]][f_ro[5]]), // 18
8393  hex->face(5)->child_index(
8394  1 -
8395  child_at_origin[hex->face(5)->refinement_case() -
8396  1][f_fl[5]][f_ro[5]])};
8397 
8398  // due to the exchange of x and y for the front
8399  // and back face, we order the children
8400  // according to
8401  //
8402  // *---*---*
8403  // | 1 | 3 |
8404  // *---*---*
8405  // | 0 | 2 |
8406  // *---*---*
8407  new_hexes[0]->set(
8409  3>(quad_indices[4],
8410  quad_indices[2],
8411  quad_indices[8],
8412  quad_indices[12],
8413  quad_indices[16],
8414  quad_indices[0]));
8415  new_hexes[1]->set(
8417  3>(quad_indices[5],
8418  quad_indices[3],
8419  quad_indices[9],
8420  quad_indices[13],
8421  quad_indices[0],
8422  quad_indices[18]));
8423  new_hexes[2]->set(
8425  3>(quad_indices[2],
8426  quad_indices[6],
8427  quad_indices[10],
8428  quad_indices[14],
8429  quad_indices[17],
8430  quad_indices[1]));
8431  new_hexes[3]->set(
8433  3>(quad_indices[3],
8434  quad_indices[7],
8435  quad_indices[11],
8436  quad_indices[15],
8437  quad_indices[1],
8438  quad_indices[19]));
8439  break;
8440  }
8441 
8443  {
8445  //
8446  // RefinementCase<dim>::cut_yz
8447  //
8448  // the refined cube will look like this:
8449  //
8450  // *---------*
8451  // / /|
8452  // *---------* |
8453  // / /| |
8454  // *---------* |/|
8455  // | | * |
8456  // | |/| *
8457  // *---------* |/
8458  // | | *
8459  // | |/
8460  // *---------*
8461  //
8462 
8463  // first, create the new
8464  // internal line
8465  new_lines[0]->set(
8467  1>(middle_vertex_index<dim, spacedim>(
8468  hex->face(0)),
8469  middle_vertex_index<dim, spacedim>(
8470  hex->face(1))));
8471 
8472  // again, first collect some data about the
8473  // indices of the lines, with the following
8474  // numbering: (note that face 0 and 1 each are
8475  // shown twice for better readability)
8476 
8477  // face 0: left plane
8478  // * *
8479  // /| /|
8480  // * | * |
8481  // /| * /| *
8482  // * 5/| * |7|
8483  // | * | | * |
8484  // |/| * |6| *
8485  // * 4/ * |/
8486  // | * | *
8487  // |/ |/
8488  // * *
8489  // face 1: right plane
8490  // * *
8491  // /| /|
8492  // * | * |
8493  // /| * /| *
8494  // * 9/| * |11
8495  // | * | | * |
8496  // |/| * |10 *
8497  // * 8/ * |/
8498  // | * | *
8499  // |/ |/
8500  // * *
8501  // face 2: front plane
8502  // (note: x,y exchanged)
8503  // *-------*
8504  // | |
8505  // *---0---*
8506  // | |
8507  // *-------*
8508  // face 3: back plane
8509  // (note: x,y exchanged)
8510  // *-------*
8511  // | |
8512  // *---1---*
8513  // | |
8514  // *-------*
8515  // face 4: bottom plane
8516  // *-------*
8517  // / /
8518  // *---2---*
8519  // / /
8520  // *-------*
8521  // face 5: top plane
8522  // *-------*
8523  // / /
8524  // *---3---*
8525  // / /
8526  // *-------*
8527  // middle planes
8528  // *-------* *-------*
8529  // / / | |
8530  // *---12--* | |
8531  // / / | |
8532  // *-------* *-------*
8533 
8534  // set up a list of line iterators first. from
8535  // this, construct lists of line_indices and
8536  // line orientations later on
8537  const typename Triangulation<
8538  dim,
8539  spacedim>::raw_line_iterator lines[13] = {
8540  hex->face(2)->child(0)->line(
8541  (hex->face(2)->refinement_case() ==
8543  1 :
8544  3), // 0
8545  hex->face(3)->child(0)->line(
8546  (hex->face(3)->refinement_case() ==
8548  1 :
8549  3), // 1
8550  hex->face(4)->child(0)->line(
8551  (hex->face(4)->refinement_case() ==
8553  1 :
8554  3), // 2
8555  hex->face(5)->child(0)->line(
8556  (hex->face(5)->refinement_case() ==
8558  1 :
8559  3), // 3
8560 
8561  hex->face(0)
8562  ->isotropic_child(
8564  0, f_or[0], f_fl[0], f_ro[0]))
8565  ->line(
8567  1, f_or[0], f_fl[0], f_ro[0])), // 4
8568  hex->face(0)
8569  ->isotropic_child(
8571  3, f_or[0], f_fl[0], f_ro[0]))
8572  ->line(
8574  0, f_or[0], f_fl[0], f_ro[0])), // 5
8575  hex->face(0)
8576  ->isotropic_child(
8578  0, f_or[0], f_fl[0], f_ro[0]))
8579  ->line(
8581  3, f_or[0], f_fl[0], f_ro[0])), // 6
8582  hex->face(0)
8583  ->isotropic_child(
8585  3, f_or[0], f_fl[0], f_ro[0]))
8586  ->line(
8588  2, f_or[0], f_fl[0], f_ro[0])), // 7
8589 
8590  hex->face(1)
8591  ->isotropic_child(
8593  0, f_or[1], f_fl[1], f_ro[1]))
8594  ->line(
8596  1, f_or[1], f_fl[1], f_ro[1])), // 8
8597  hex->face(1)
8598  ->isotropic_child(
8600  3, f_or[1], f_fl[1], f_ro[1]))
8601  ->line(
8603  0, f_or[1], f_fl[1], f_ro[1])), // 9
8604  hex->face(1)
8605  ->isotropic_child(
8607  0, f_or[1], f_fl[1], f_ro[1]))
8608  ->line(
8610  3, f_or[1], f_fl[1], f_ro[1])), // 10
8611  hex->face(1)
8612  ->isotropic_child(
8614  3, f_or[1], f_fl[1], f_ro[1]))
8615  ->line(
8617  2, f_or[1], f_fl[1], f_ro[1])), // 11
8618 
8619  new_lines[0] // 12
8620  };
8621 
8622  unsigned int line_indices[13];
8623 
8624  for (unsigned int i = 0; i < 13; ++i)
8625  line_indices[i] = lines[i]->index();
8626 
8627  // the orientation of lines for the inner quads
8628  // is quite tricky. as these lines are newly
8629  // created ones and thus have no parents, they
8630  // cannot inherit this property. set up an array
8631  // and fill it with the respective values
8632  bool line_orientation[13];
8633 
8634  // the middle vertices of the lines of our front
8635  // face
8636  const unsigned int middle_vertices[4] = {
8637  hex->line(8)->child(0)->vertex_index(1),
8638  hex->line(10)->child(0)->vertex_index(1),
8639  hex->line(0)->child(0)->vertex_index(1),
8640  hex->line(4)->child(0)->vertex_index(1),
8641  };
8642 
8643  // note: for lines 0 to 3 the orientation of the
8644  // line is 'true', if vertex 0 is on the front
8645  for (unsigned int i = 0; i < 4; ++i)
8646  if (lines[i]->vertex_index(0) == middle_vertices[i])
8647  line_orientation[i] = true;
8648  else
8649  {
8650  // it must be the other way round then
8651  Assert(lines[i]->vertex_index(1) ==
8652  middle_vertices[i],
8653  ExcInternalError());
8654  line_orientation[i] = false;
8655  }
8656 
8657  // note: for lines 4 to 11 (inner lines of the
8658  // outer quads) the following holds: the second
8659  // vertex of the even lines in standard
8660  // orientation is the vertex in the middle of
8661  // the quad, whereas for odd lines the first
8662  // vertex is the same middle vertex.
8663  for (unsigned int i = 4; i < 12; ++i)
8664  if (lines[i]->vertex_index((i + 1) % 2) ==
8665  middle_vertex_index<dim, spacedim>(
8666  hex->face(i / 4 - 1)))
8667  line_orientation[i] = true;
8668  else
8669  {
8670  // it must be the other way
8671  // round then
8672  Assert(lines[i]->vertex_index(i % 2) ==
8673  (middle_vertex_index<dim, spacedim>(
8674  hex->face(i / 4 - 1))),
8675  ExcInternalError());
8676  line_orientation[i] = false;
8677  }
8678  // for the last line the line orientation is
8679  // always true, since it was just constructed
8680  // that way
8681  line_orientation[12] = true;
8682 
8683  // set up the 4 quads, numbered as follows (left
8684  // quad numbering, right line numbering
8685  // extracted from above)
8686  //
8687  // x
8688  // *-------* *---3---*
8689  // | 3 | 5 9
8690  // *-------* *---12--*
8691  // | 2 | 4 8
8692  // *-------*y *---2---*
8693  //
8694  // y
8695  // *---------* *----1----*
8696  // / 1 / 7 11
8697  // *---------* *----12---*
8698  // / 0 / 6 10
8699  // *---------*x *----0----*
8700 
8701  new_quads[0]->set(
8703  2>(line_indices[6],
8704  line_indices[10],
8705  line_indices[0],
8706  line_indices[12]));
8707  new_quads[1]->set(
8709  2>(line_indices[7],
8710  line_indices[11],
8711  line_indices[12],
8712  line_indices[1]));
8713  new_quads[2]->set(
8715  2>(line_indices[2],
8716  line_indices[12],
8717  line_indices[4],
8718  line_indices[8]));
8719  new_quads[3]->set(
8721  2>(line_indices[12],
8722  line_indices[3],
8723  line_indices[5],
8724  line_indices[9]));
8725 
8726  new_quads[0]->set_line_orientation(
8727  0, line_orientation[6]);
8728  new_quads[0]->set_line_orientation(
8729  1, line_orientation[10]);
8730  new_quads[0]->set_line_orientation(
8731  2, line_orientation[0]);
8732 
8733  new_quads[1]->set_line_orientation(
8734  0, line_orientation[7]);
8735  new_quads[1]->set_line_orientation(
8736  1, line_orientation[11]);
8737  new_quads[1]->set_line_orientation(
8738  3, line_orientation[1]);
8739 
8740  new_quads[2]->set_line_orientation(
8741  0, line_orientation[2]);
8742  new_quads[2]->set_line_orientation(
8743  2, line_orientation[4]);
8744  new_quads[2]->set_line_orientation(
8745  3, line_orientation[8]);
8746 
8747  new_quads[3]->set_line_orientation(
8748  1, line_orientation[3]);
8749  new_quads[3]->set_line_orientation(
8750  2, line_orientation[5]);
8751  new_quads[3]->set_line_orientation(
8752  3, line_orientation[9]);
8753 
8754  // the quads are numbered as follows:
8755  //
8756  // planes in the interior of the old hex:
8757  //
8758  // *
8759  // /|
8760  // / | x
8761  // / | *-------* *---------*
8762  // * | | 3 | / 1 /
8763  // | | *-------* *---------*
8764  // | * | 2 | / 0 /
8765  // | / *-------*y *---------*x
8766  // | /
8767  // |/
8768  // *
8769  //
8770  // children of the faces
8771  // of the old hex
8772  // *-------* *-------*
8773  // /| | / 19 /|
8774  // * | 15 | *-------* |
8775  // /|7*-------* / 18 /|11
8776  // * |/| | *-------* |/|
8777  // |6* | 14 | | 10* |
8778  // |/|5*-------* | 13 |/|9*
8779  // * |/ 17 / *-------* |/
8780  // |4*-------* | |8*
8781  // |/ 16 / | 12 |/
8782  // *-------* *-------*
8783  //
8784  // note that we have to take care of the
8785  // orientation of faces.
8786  const int quad_indices[20] = {
8787  new_quads[0]->index(), // 0
8788  new_quads[1]->index(),
8789  new_quads[2]->index(),
8790  new_quads[3]->index(),
8791 
8792  hex->face(0)->isotropic_child_index(
8794  0, f_or[0], f_fl[0], f_ro[0])), // 4
8795  hex->face(0)->isotropic_child_index(
8797  1, f_or[0], f_fl[0], f_ro[0])),
8798  hex->face(0)->isotropic_child_index(
8800  2, f_or[0], f_fl[0], f_ro[0])),
8801  hex->face(0)->isotropic_child_index(
8803  3, f_or[0], f_fl[0], f_ro[0])),
8804 
8805  hex->face(1)->isotropic_child_index(
8807  0, f_or[1], f_fl[1], f_ro[1])), // 8
8808  hex->face(1)->isotropic_child_index(
8810  1, f_or[1], f_fl[1], f_ro[1])),
8811  hex->face(1)->isotropic_child_index(
8813  2, f_or[1], f_fl[1], f_ro[1])),
8814  hex->face(1)->isotropic_child_index(
8816  3, f_or[1], f_fl[1], f_ro[1])),
8817 
8818  hex->face(2)->child_index(
8819  child_at_origin[hex->face(2)->refinement_case() -
8820  1][f_fl[2]][f_ro[2]]), // 12
8821  hex->face(2)->child_index(
8822  1 -
8823  child_at_origin[hex->face(2)->refinement_case() -
8824  1][f_fl[2]][f_ro[2]]),
8825 
8826  hex->face(3)->child_index(
8827  child_at_origin[hex->face(3)->refinement_case() -
8828  1][f_fl[3]][f_ro[3]]), // 14
8829  hex->face(3)->child_index(
8830  1 -
8831  child_at_origin[hex->face(3)->refinement_case() -
8832  1][f_fl[3]][f_ro[3]]),
8833 
8834  hex->face(4)->child_index(
8835  child_at_origin[hex->face(4)->refinement_case() -
8836  1][f_fl[4]][f_ro[4]]), // 16
8837  hex->face(4)->child_index(
8838  1 -
8839  child_at_origin[hex->face(4)->refinement_case() -
8840  1][f_fl[4]][f_ro[4]]),
8841 
8842  hex->face(5)->child_index(
8843  child_at_origin[hex->face(5)->refinement_case() -
8844  1][f_fl[5]][f_ro[5]]), // 18
8845  hex->face(5)->child_index(
8846  1 -
8847  child_at_origin[hex->face(5)->refinement_case() -
8848  1][f_fl[5]][f_ro[5]])};
8849 
8850  new_hexes[0]->set(
8852  3>(quad_indices[4],
8853  quad_indices[8],
8854  quad_indices[12],
8855  quad_indices[2],
8856  quad_indices[16],
8857  quad_indices[0]));
8858  new_hexes[1]->set(
8860  3>(quad_indices[5],
8861  quad_indices[9],
8862  quad_indices[2],
8863  quad_indices[14],
8864  quad_indices[17],
8865  quad_indices[1]));
8866  new_hexes[2]->set(
8868  3>(quad_indices[6],
8869  quad_indices[10],
8870  quad_indices[13],
8871  quad_indices[3],
8872  quad_indices[0],
8873  quad_indices[18]));
8874  new_hexes[3]->set(
8876  3>(quad_indices[7],
8877  quad_indices[11],
8878  quad_indices[3],
8879  quad_indices[15],
8880  quad_indices[1],
8881  quad_indices[19]));
8882  break;
8883  }
8884 
8886  {
8888  //
8889  // RefinementCase<dim>::cut_xyz
8890  // isotropic refinement
8891  //
8892  // the refined cube will look
8893  // like this:
8894  //
8895  // *----*----*
8896  // / / /|
8897  // *----*----* |
8898  // / / /| *
8899  // *----*----* |/|
8900  // | | | * |
8901  // | | |/| *
8902  // *----*----* |/
8903  // | | | *
8904  // | | |/
8905  // *----*----*
8906  //
8907 
8908  // find the next unused vertex and set it
8909  // appropriately
8910  while (
8911  triangulation.vertices_used[next_unused_vertex] ==
8912  true)
8913  ++next_unused_vertex;
8914  Assert(
8915  next_unused_vertex < triangulation.vertices.size(),
8916  ExcMessage(
8917  "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."));
8918  triangulation.vertices_used[next_unused_vertex] =
8919  true;
8920 
8921  // the new vertex is definitely in the interior,
8922  // so we need not worry about the
8923  // boundary. However we need to worry about
8924  // Manifolds. Let the cell compute its own
8925  // center, by querying the underlying manifold
8926  // object.
8927  triangulation.vertices[next_unused_vertex] =
8928  hex->center(true, true);
8929 
8930  // set the data of the six lines. first collect
8931  // the indices of the seven vertices (consider
8932  // the two planes to be crossed to form the
8933  // planes cutting the hex in two vertically and
8934  // horizontally)
8935  //
8936  // *--3--* *--5--*
8937  // / / / | | |
8938  // 0--6--1 0--6--1
8939  // / / / | | |
8940  // *--2--* *--4--*
8941  // the lines are numbered
8942  // as follows:
8943  // *--*--* *--*--*
8944  // / 1 / | 5 |
8945  // *2-*-3* *2-*-3*
8946  // / 0 / | 4 |
8947  // *--*--* *--*--*
8948  //
8949  const unsigned int vertex_indices[7] = {
8950  middle_vertex_index<dim, spacedim>(hex->face(0)),
8951  middle_vertex_index<dim, spacedim>(hex->face(1)),
8952  middle_vertex_index<dim, spacedim>(hex->face(2)),
8953  middle_vertex_index<dim, spacedim>(hex->face(3)),
8954  middle_vertex_index<dim, spacedim>(hex->face(4)),
8955  middle_vertex_index<dim, spacedim>(hex->face(5)),
8956  next_unused_vertex};
8957 
8958  new_lines[0]->set(
8960  1>(vertex_indices[2], vertex_indices[6]));
8961  new_lines[1]->set(
8963  1>(vertex_indices[6], vertex_indices[3]));
8964  new_lines[2]->set(
8966  1>(vertex_indices[0], vertex_indices[6]));
8967  new_lines[3]->set(
8969  1>(vertex_indices[6], vertex_indices[1]));
8970  new_lines[4]->set(
8972  1>(vertex_indices[4], vertex_indices[6]));
8973  new_lines[5]->set(
8975  1>(vertex_indices[6], vertex_indices[5]));
8976 
8977  // again, first collect some data about the
8978  // indices of the lines, with the following
8979  // numbering: (note that face 0 and 1 each are
8980  // shown twice for better readability)
8981 
8982  // face 0: left plane
8983  // * *
8984  // /| /|
8985  // * | * |
8986  // /| * /| *
8987  // * 1/| * |3|
8988  // | * | | * |
8989  // |/| * |2| *
8990  // * 0/ * |/
8991  // | * | *
8992  // |/ |/
8993  // * *
8994  // face 1: right plane
8995  // * *
8996  // /| /|
8997  // * | * |
8998  // /| * /| *
8999  // * 5/| * |7|
9000  // | * | | * |
9001  // |/| * |6| *
9002  // * 4/ * |/
9003  // | * | *
9004  // |/ |/
9005  // * *
9006  // face 2: front plane
9007  // (note: x,y exchanged)
9008  // *---*---*
9009  // | 11 |
9010  // *-8-*-9-*
9011  // | 10 |
9012  // *---*---*
9013  // face 3: back plane
9014  // (note: x,y exchanged)
9015  // *---*---*
9016  // | 15 |
9017  // *12-*-13*
9018  // | 14 |
9019  // *---*---*
9020  // face 4: bottom plane
9021  // *---*---*
9022  // / 17 /
9023  // *18-*-19*
9024  // / 16 /
9025  // *---*---*
9026  // face 5: top plane
9027  // *---*---*
9028  // / 21 /
9029  // *22-*-23*
9030  // / 20 /
9031  // *---*---*
9032  // middle planes
9033  // *---*---* *---*---*
9034  // / 25 / | 29 |
9035  // *26-*-27* *26-*-27*
9036  // / 24 / | 28 |
9037  // *---*---* *---*---*
9038 
9039  // set up a list of line iterators first. from
9040  // this, construct lists of line_indices and
9041  // line orientations later on
9042  const typename Triangulation<
9043  dim,
9044  spacedim>::raw_line_iterator lines[30] = {
9045  hex->face(0)
9046  ->isotropic_child(
9048  0, f_or[0], f_fl[0], f_ro[0]))
9049  ->line(
9051  1, f_or[0], f_fl[0], f_ro[0])), // 0
9052  hex->face(0)
9053  ->isotropic_child(
9055  3, f_or[0], f_fl[0], f_ro[0]))
9056  ->line(
9058  0, f_or[0], f_fl[0], f_ro[0])), // 1
9059  hex->face(0)
9060  ->isotropic_child(
9062  0, f_or[0], f_fl[0], f_ro[0]))
9063  ->line(
9065  3, f_or[0], f_fl[0], f_ro[0])), // 2
9066  hex->face(0)
9067  ->isotropic_child(
9069  3, f_or[0], f_fl[0], f_ro[0]))
9070  ->line(
9072  2, f_or[0], f_fl[0], f_ro[0])), // 3
9073 
9074  hex->face(1)
9075  ->isotropic_child(
9077  0, f_or[1], f_fl[1], f_ro[1]))
9078  ->line(
9080  1, f_or[1], f_fl[1], f_ro[1])), // 4
9081  hex->face(1)
9082  ->isotropic_child(
9084  3, f_or[1], f_fl[1], f_ro[1]))
9085  ->line(
9087  0, f_or[1], f_fl[1], f_ro[1])), // 5
9088  hex->face(1)
9089  ->isotropic_child(
9091  0, f_or[1], f_fl[1], f_ro[1]))
9092  ->line(
9094  3, f_or[1], f_fl[1], f_ro[1])), // 6
9095  hex->face(1)
9096  ->isotropic_child(
9098  3, f_or[1], f_fl[1], f_ro[1]))
9099  ->line(
9101  2, f_or[1], f_fl[1], f_ro[1])), // 7
9102 
9103  hex->face(2)
9104  ->isotropic_child(
9106  0, f_or[2], f_fl[2], f_ro[2]))
9107  ->line(
9109  1, f_or[2], f_fl[2], f_ro[2])), // 8
9110  hex->face(2)
9111  ->isotropic_child(
9113  3, f_or[2], f_fl[2], f_ro[2]))
9114  ->line(
9116  0, f_or[2], f_fl[2], f_ro[2])), // 9
9117  hex->face(2)
9118  ->isotropic_child(
9120  0, f_or[2], f_fl[2], f_ro[2]))
9121  ->line(
9123  3, f_or[2], f_fl[2], f_ro[2])), // 10
9124  hex->face(2)
9125  ->isotropic_child(
9127  3, f_or[2], f_fl[2], f_ro[2]))
9128  ->line(
9130  2, f_or[2], f_fl[2], f_ro[2])), // 11
9131 
9132  hex->face(3)
9133  ->isotropic_child(
9135  0, f_or[3], f_fl[3], f_ro[3]))
9136  ->line(
9138  1, f_or[3], f_fl[3], f_ro[3])), // 12
9139  hex->face(3)
9140  ->isotropic_child(
9142  3, f_or[3], f_fl[3], f_ro[3]))
9143  ->line(
9145  0, f_or[3], f_fl[3], f_ro[3])), // 13
9146  hex->face(3)
9147  ->isotropic_child(
9149  0, f_or[3], f_fl[3], f_ro[3]))
9150  ->line(
9152  3, f_or[3], f_fl[3], f_ro[3])), // 14
9153  hex->face(3)
9154  ->isotropic_child(
9156  3, f_or[3], f_fl[3], f_ro[3]))
9157  ->line(
9159  2, f_or[3], f_fl[3], f_ro[3])), // 15
9160 
9161  hex->face(4)
9162  ->isotropic_child(
9164  0, f_or[4], f_fl[4], f_ro[4]))
9165  ->line(
9167  1, f_or[4], f_fl[4], f_ro[4])), // 16
9168  hex->face(4)
9169  ->isotropic_child(
9171  3, f_or[4], f_fl[4], f_ro[4]))
9172  ->line(
9174  0, f_or[4], f_fl[4], f_ro[4])), // 17
9175  hex->face(4)
9176  ->isotropic_child(
9178  0, f_or[4], f_fl[4], f_ro[4]))
9179  ->line(
9181  3, f_or[4], f_fl[4], f_ro[4])), // 18
9182  hex->face(4)
9183  ->isotropic_child(
9185  3, f_or[4], f_fl[4], f_ro[4]))
9186  ->line(
9188  2, f_or[4], f_fl[4], f_ro[4])), // 19
9189 
9190  hex->face(5)
9191  ->isotropic_child(
9193  0, f_or[5], f_fl[5], f_ro[5]))
9194  ->line(
9196  1, f_or[5], f_fl[5], f_ro[5])), // 20
9197  hex->face(5)
9198  ->isotropic_child(
9200  3, f_or[5], f_fl[5], f_ro[5]))
9201  ->line(
9203  0, f_or[5], f_fl[5], f_ro[5])), // 21
9204  hex->face(5)
9205  ->isotropic_child(
9207  0, f_or[5], f_fl[5], f_ro[5]))
9208  ->line(
9210  3, f_or[5], f_fl[5], f_ro[5])), // 22
9211  hex->face(5)
9212  ->isotropic_child(
9214  3, f_or[5], f_fl[5], f_ro[5]))
9215  ->line(
9217  2, f_or[5], f_fl[5], f_ro[5])), // 23
9218 
9219  new_lines[0], // 24
9220  new_lines[1], // 25
9221  new_lines[2], // 26
9222  new_lines[3], // 27
9223  new_lines[4], // 28
9224  new_lines[5] // 29
9225  };
9226 
9227  unsigned int line_indices[30];
9228  for (unsigned int i = 0; i < 30; ++i)
9229  line_indices[i] = lines[i]->index();
9230 
9231  // the orientation of lines for the inner quads
9232  // is quite tricky. as these lines are newly
9233  // created ones and thus have no parents, they
9234  // cannot inherit this property. set up an array
9235  // and fill it with the respective values
9236  bool line_orientation[30];
9237 
9238  // note: for the first 24 lines (inner lines of
9239  // the outer quads) the following holds: the
9240  // second vertex of the even lines in standard
9241  // orientation is the vertex in the middle of
9242  // the quad, whereas for odd lines the first
9243  // vertex is the same middle vertex.
9244  for (unsigned int i = 0; i < 24; ++i)
9245  if (lines[i]->vertex_index((i + 1) % 2) ==
9246  vertex_indices[i / 4])
9247  line_orientation[i] = true;
9248  else
9249  {
9250  // it must be the other way
9251  // round then
9252  Assert(lines[i]->vertex_index(i % 2) ==
9253  vertex_indices[i / 4],
9254  ExcInternalError());
9255  line_orientation[i] = false;
9256  }
9257  // for the last 6 lines the line orientation is
9258  // always true, since they were just constructed
9259  // that way
9260  for (unsigned int i = 24; i < 30; ++i)
9261  line_orientation[i] = true;
9262 
9263  // set up the 12 quads, numbered as follows
9264  // (left quad numbering, right line numbering
9265  // extracted from above)
9266  //
9267  // * *
9268  // /| 21|
9269  // * | * 15
9270  // y/|3* 20| *
9271  // * |/| * |/|
9272  // |2* |x 11 * 14
9273  // |/|1* |/| *
9274  // * |/ * |17
9275  // |0* 10 *
9276  // |/ |16
9277  // * *
9278  //
9279  // x
9280  // *---*---* *22-*-23*
9281  // | 5 | 7 | 1 29 5
9282  // *---*---* *26-*-27*
9283  // | 4 | 6 | 0 28 4
9284  // *---*---*y *18-*-19*
9285  //
9286  // y
9287  // *----*----* *-12-*-13-*
9288  // / 10 / 11 / 3 25 7
9289  // *----*----* *-26-*-27-*
9290  // / 8 / 9 / 2 24 6
9291  // *----*----*x *--8-*--9-*
9292 
9293  new_quads[0]->set(
9295  2>(line_indices[10],
9296  line_indices[28],
9297  line_indices[16],
9298  line_indices[24]));
9299  new_quads[1]->set(
9301  2>(line_indices[28],
9302  line_indices[14],
9303  line_indices[17],
9304  line_indices[25]));
9305  new_quads[2]->set(
9307  2>(line_indices[11],
9308  line_indices[29],
9309  line_indices[24],
9310  line_indices[20]));
9311  new_quads[3]->set(
9313  2>(line_indices[29],
9314  line_indices[15],
9315  line_indices[25],
9316  line_indices[21]));
9317  new_quads[4]->set(
9319  2>(line_indices[18],
9320  line_indices[26],
9321  line_indices[0],
9322  line_indices[28]));
9323  new_quads[5]->set(
9325  2>(line_indices[26],
9326  line_indices[22],
9327  line_indices[1],
9328  line_indices[29]));
9329  new_quads[6]->set(
9331  2>(line_indices[19],
9332  line_indices[27],
9333  line_indices[28],
9334  line_indices[4]));
9335  new_quads[7]->set(
9337  2>(line_indices[27],
9338  line_indices[23],
9339  line_indices[29],
9340  line_indices[5]));
9341  new_quads[8]->set(
9343  2>(line_indices[2],
9344  line_indices[24],
9345  line_indices[8],
9346  line_indices[26]));
9347  new_quads[9]->set(
9349  2>(line_indices[24],
9350  line_indices[6],
9351  line_indices[9],
9352  line_indices[27]));
9353  new_quads[10]->set(
9355  2>(line_indices[3],
9356  line_indices[25],
9357  line_indices[26],
9358  line_indices[12]));
9359  new_quads[11]->set(
9361  2>(line_indices[25],
9362  line_indices[7],
9363  line_indices[27],
9364  line_indices[13]));
9365 
9366  // now reset the line_orientation flags of outer
9367  // lines as they cannot be set in a loop (at
9368  // least not easily)
9369  new_quads[0]->set_line_orientation(
9370  0, line_orientation[10]);
9371  new_quads[0]->set_line_orientation(
9372  2, line_orientation[16]);
9373 
9374  new_quads[1]->set_line_orientation(
9375  1, line_orientation[14]);
9376  new_quads[1]->set_line_orientation(
9377  2, line_orientation[17]);
9378 
9379  new_quads[2]->set_line_orientation(
9380  0, line_orientation[11]);
9381  new_quads[2]->set_line_orientation(
9382  3, line_orientation[20]);
9383 
9384  new_quads[3]->set_line_orientation(
9385  1, line_orientation[15]);
9386  new_quads[3]->set_line_orientation(
9387  3, line_orientation[21]);
9388 
9389  new_quads[4]->set_line_orientation(
9390  0, line_orientation[18]);
9391  new_quads[4]->set_line_orientation(
9392  2, line_orientation[0]);
9393 
9394  new_quads[5]->set_line_orientation(
9395  1, line_orientation[22]);
9396  new_quads[5]->set_line_orientation(
9397  2, line_orientation[1]);
9398 
9399  new_quads[6]->set_line_orientation(
9400  0, line_orientation[19]);
9401  new_quads[6]->set_line_orientation(
9402  3, line_orientation[4]);
9403 
9404  new_quads[7]->set_line_orientation(
9405  1, line_orientation[23]);
9406  new_quads[7]->set_line_orientation(
9407  3, line_orientation[5]);
9408 
9409  new_quads[8]->set_line_orientation(
9410  0, line_orientation[2]);
9411  new_quads[8]->set_line_orientation(
9412  2, line_orientation[8]);
9413 
9414  new_quads[9]->set_line_orientation(
9415  1, line_orientation[6]);
9416  new_quads[9]->set_line_orientation(
9417  2, line_orientation[9]);
9418 
9419  new_quads[10]->set_line_orientation(
9420  0, line_orientation[3]);
9421  new_quads[10]->set_line_orientation(
9422  3, line_orientation[12]);
9423 
9424  new_quads[11]->set_line_orientation(
9425  1, line_orientation[7]);
9426  new_quads[11]->set_line_orientation(
9427  3, line_orientation[13]);
9428 
9430  // create the eight new hexes
9431  //
9432  // again first collect some data. here, we need
9433  // the indices of a whole lotta quads.
9434 
9435  // the quads are numbered as follows:
9436  //
9437  // planes in the interior of the old hex:
9438  //
9439  // *
9440  // /|
9441  // * |
9442  // /|3* *---*---* *----*----*
9443  // * |/| | 5 | 7 | / 10 / 11 /
9444  // |2* | *---*---* *----*----*
9445  // |/|1* | 4 | 6 | / 8 / 9 /
9446  // * |/ *---*---*y *----*----*x
9447  // |0*
9448  // |/
9449  // *
9450  //
9451  // children of the faces
9452  // of the old hex
9453  // *-------* *-------*
9454  // /|25 27| /34 35/|
9455  // 15| | / /19
9456  // / | | /32 33/ |
9457  // * |24 26| *-------*18 |
9458  // 1413*-------* |21 23| 17*
9459  // | /30 31/ | | /
9460  // 12/ / | |16
9461  // |/28 29/ |20 22|/
9462  // *-------* *-------*
9463  //
9464  // note that we have to
9465  // take care of the
9466  // orientation of
9467  // faces.
9468  const int quad_indices[36] = {
9469  new_quads[0]->index(), // 0
9470  new_quads[1]->index(),
9471  new_quads[2]->index(),
9472  new_quads[3]->index(),
9473  new_quads[4]->index(),
9474  new_quads[5]->index(),
9475  new_quads[6]->index(),
9476  new_quads[7]->index(),
9477  new_quads[8]->index(),
9478  new_quads[9]->index(),
9479  new_quads[10]->index(),
9480  new_quads[11]->index(), // 11
9481 
9482  hex->face(0)->isotropic_child_index(
9484  0, f_or[0], f_fl[0], f_ro[0])), // 12
9485  hex->face(0)->isotropic_child_index(
9487  1, f_or[0], f_fl[0], f_ro[0])),
9488  hex->face(0)->isotropic_child_index(
9490  2, f_or[0], f_fl[0], f_ro[0])),
9491  hex->face(0)->isotropic_child_index(
9493  3, f_or[0], f_fl[0], f_ro[0])),
9494 
9495  hex->face(1)->isotropic_child_index(
9497  0, f_or[1], f_fl[1], f_ro[1])), // 16
9498  hex->face(1)->isotropic_child_index(
9500  1, f_or[1], f_fl[1], f_ro[1])),
9501  hex->face(1)->isotropic_child_index(
9503  2, f_or[1], f_fl[1], f_ro[1])),
9504  hex->face(1)->isotropic_child_index(
9506  3, f_or[1], f_fl[1], f_ro[1])),
9507 
9508  hex->face(2)->isotropic_child_index(
9510  0, f_or[2], f_fl[2], f_ro[2])), // 20
9511  hex->face(2)->isotropic_child_index(
9513  1, f_or[2], f_fl[2], f_ro[2])),
9514  hex->face(2)->isotropic_child_index(
9516  2, f_or[2], f_fl[2], f_ro[2])),
9517  hex->face(2)->isotropic_child_index(
9519  3, f_or[2], f_fl[2], f_ro[2])),
9520 
9521  hex->face(3)->isotropic_child_index(
9523  0, f_or[3], f_fl[3], f_ro[3])), // 24
9524  hex->face(3)->isotropic_child_index(
9526  1, f_or[3], f_fl[3], f_ro[3])),
9527  hex->face(3)->isotropic_child_index(
9529  2, f_or[3], f_fl[3], f_ro[3])),
9530  hex->face(3)->isotropic_child_index(
9532  3, f_or[3], f_fl[3], f_ro[3])),
9533 
9534  hex->face(4)->isotropic_child_index(
9536  0, f_or[4], f_fl[4], f_ro[4])), // 28
9537  hex->face(4)->isotropic_child_index(
9539  1, f_or[4], f_fl[4], f_ro[4])),
9540  hex->face(4)->isotropic_child_index(
9542  2, f_or[4], f_fl[4], f_ro[4])),
9543  hex->face(4)->isotropic_child_index(
9545  3, f_or[4], f_fl[4], f_ro[4])),
9546 
9547  hex->face(5)->isotropic_child_index(
9549  0, f_or[5], f_fl[5], f_ro[5])), // 32
9550  hex->face(5)->isotropic_child_index(
9552  1, f_or[5], f_fl[5], f_ro[5])),
9553  hex->face(5)->isotropic_child_index(
9555  2, f_or[5], f_fl[5], f_ro[5])),
9556  hex->face(5)->isotropic_child_index(
9558  3, f_or[5], f_fl[5], f_ro[5]))};
9559 
9560  // bottom children
9561  new_hexes[0]->set(
9563  3>(quad_indices[12],
9564  quad_indices[0],
9565  quad_indices[20],
9566  quad_indices[4],
9567  quad_indices[28],
9568  quad_indices[8]));
9569  new_hexes[1]->set(
9571  3>(quad_indices[0],
9572  quad_indices[16],
9573  quad_indices[22],
9574  quad_indices[6],
9575  quad_indices[29],
9576  quad_indices[9]));
9577  new_hexes[2]->set(
9579  3>(quad_indices[13],
9580  quad_indices[1],
9581  quad_indices[4],
9582  quad_indices[24],
9583  quad_indices[30],
9584  quad_indices[10]));
9585  new_hexes[3]->set(
9587  3>(quad_indices[1],
9588  quad_indices[17],
9589  quad_indices[6],
9590  quad_indices[26],
9591  quad_indices[31],
9592  quad_indices[11]));
9593 
9594  // top children
9595  new_hexes[4]->set(
9597  3>(quad_indices[14],
9598  quad_indices[2],
9599  quad_indices[21],
9600  quad_indices[5],
9601  quad_indices[8],
9602  quad_indices[32]));
9603  new_hexes[5]->set(
9605  3>(quad_indices[2],
9606  quad_indices[18],
9607  quad_indices[23],
9608  quad_indices[7],
9609  quad_indices[9],
9610  quad_indices[33]));
9611  new_hexes[6]->set(
9613  3>(quad_indices[15],
9614  quad_indices[3],
9615  quad_indices[5],
9616  quad_indices[25],
9617  quad_indices[10],
9618  quad_indices[34]));
9619  new_hexes[7]->set(
9621  3>(quad_indices[3],
9622  quad_indices[19],
9623  quad_indices[7],
9624  quad_indices[27],
9625  quad_indices[11],
9626  quad_indices[35]));
9627  break;
9628  }
9629  default:
9630  // all refinement cases have been treated, there
9631  // only remains
9632  // RefinementCase<dim>::no_refinement as
9633  // untreated enumeration value. However, in that
9634  // case we should have aborted much
9635  // earlier. thus we should never get here
9636  Assert(false, ExcInternalError());
9637  break;
9638  } // switch (ref_case)
9639 
9640  // and set face orientation flags. note that new
9641  // faces in the interior of the mother cell always
9642  // have a correctly oriented face, but the ones on
9643  // the outer faces will inherit this flag
9644  //
9645  // the flag have been set to true for all faces
9646  // initially, now go the other way round and reset
9647  // faces that are at the boundary of the mother cube
9648  //
9649  // the same is true for the face_flip and
9650  // face_rotation flags. however, the latter two are
9651  // set to false by default as this is the standard
9652  // value
9653 
9654  // loop over all faces and all (relevant) subfaces
9655  // of that in order to set the correct values for
9656  // face_orientation, face_flip and face_rotation,
9657  // which are inherited from the corresponding face
9658  // of the mother cube
9659  for (const unsigned int f : GeometryInfo<dim>::face_indices())
9660  for (unsigned int s = 0;
9663  ref_case, f)),
9664  1U);
9665  ++s)
9666  {
9667  const unsigned int current_child =
9669  ref_case,
9670  f,
9671  s,
9672  f_or[f],
9673  f_fl[f],
9674  f_ro[f],
9676  ref_case, f, f_or[f], f_fl[f], f_ro[f]));
9677  new_hexes[current_child]->set_face_orientation(f,
9678  f_or[f]);
9679  new_hexes[current_child]->set_face_flip(f, f_fl[f]);
9680  new_hexes[current_child]->set_face_rotation(f, f_ro[f]);
9681  }
9682 
9683  // now see if we have created cells that are
9684  // distorted and if so add them to our list
9685  if ((check_for_distorted_cells == true) &&
9686  has_distorted_children(
9687  hex,
9688  std::integral_constant<int, dim>(),
9689  std::integral_constant<int, spacedim>()))
9690  cells_with_distorted_children.distorted_cells.push_back(
9691  hex);
9692 
9693  // note that the refinement flag was already cleared
9694  // at the beginning of this loop
9695 
9696  // inform all listeners that cell refinement is done
9697  triangulation.signals.post_refinement_on_cell(hex);
9698  }
9699  }
9700 
9701  // clear user data on quads. we used some of this data to
9702  // indicate anisotropic refinemnt cases on faces. all data
9703  // should be cleared by now, but the information whether we
9704  // used indices or pointers is still present. reset it now to
9705  // enable the user to use whichever they like later on.
9706  triangulation.faces->quads.clear_user_data();
9707 
9708  // return the list with distorted children
9709  return cells_with_distorted_children;
9710  }
9711 
9712 
9725  template <int spacedim>
9726  static void
9728 
9729 
9730  template <int dim, int spacedim>
9731  static void
9734  {
9735  // If the codimension is one, we cannot perform this check
9736  // yet.
9737  if (spacedim > dim)
9738  return;
9739 
9740  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
9741  triangulation.begin();
9742  cell != triangulation.end();
9743  ++cell)
9744  if (cell->at_boundary() && cell->refine_flag_set() &&
9745  cell->refine_flag_set() !=
9747  {
9748  // The cell is at the boundary and it is flagged for
9749  // anisotropic refinement. Therefore, we have a closer
9750  // look
9751  const RefinementCase<dim> ref_case = cell->refine_flag_set();
9752  for (const unsigned int face_no :
9754  if (cell->face(face_no)->at_boundary())
9755  {
9756  // this is the critical face at the boundary.
9758  face_no) !=
9760  {
9761  // up to now, we do not want to refine this
9762  // cell along the face under consideration
9763  // here.
9764  const typename Triangulation<dim,
9765  spacedim>::face_iterator
9766  face = cell->face(face_no);
9767  // the new point on the boundary would be this
9768  // one.
9769  const Point<spacedim> new_bound = face->center(true);
9770  // to check it, transform to the unit cell
9771  // with Q1Mapping
9772  const Point<dim> new_unit =
9774  .transform_real_to_unit_cell(cell, new_bound);
9775 
9776  // Now, we have to calculate the distance from
9777  // the face in the unit cell.
9778 
9779  // take the correct coordinate direction (0
9780  // for faces 0 and 1, 1 for faces 2 and 3, 2
9781  // for faces 4 and 5) and subtract the correct
9782  // boundary value of the face (0 for faces 0,
9783  // 2, and 4; 1 for faces 1, 3 and 5)
9784  const double dist =
9785  std::fabs(new_unit[face_no / 2] - face_no % 2);
9786 
9787  // compare this with the empirical value
9788  // allowed. if it is too big, flag the face
9789  // for isotropic refinement
9790  const double allowed = 0.25;
9791 
9792  if (dist > allowed)
9793  cell->flag_for_face_refinement(face_no);
9794  } // if flagged for anistropic refinement
9795  } // if (cell->face(face)->at_boundary())
9796  } // for all cells
9797  }
9798 
9799 
9812  template <int dim, int spacedim>
9813  static void
9815  {
9816  Assert(dim < 3,
9817  ExcMessage("Wrong function called -- there should "
9818  "be a specialization."));
9819  }
9820 
9821 
9822  template <int spacedim>
9825  {
9826  const unsigned int dim = 3;
9827 
9828  // first clear flags on lines, since we need them to determine
9829  // which lines will be refined
9830  triangulation.clear_user_flags_line();
9831 
9832  // also clear flags on hexes, since we need them to mark those
9833  // cells which are to be coarsened
9834  triangulation.clear_user_flags_hex();
9835 
9836  // variable to store whether the mesh was changed in the
9837  // present loop and in the whole process
9838  bool mesh_changed = false;
9839 
9840  do
9841  {
9842  mesh_changed = false;
9843 
9844  // for this following, we need to know which cells are
9845  // going to be coarsened, if we had to make a
9846  // decision. the following function sets these flags:
9847  triangulation.fix_coarsen_flags();
9848 
9849 
9850  // flag those lines that are refined and will not be
9851  // coarsened and those that will be refined
9852  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
9853  triangulation.begin();
9854  cell != triangulation.end();
9855  ++cell)
9856  if (cell->refine_flag_set())
9857  {
9858  for (unsigned int line = 0;
9859  line < GeometryInfo<dim>::lines_per_cell;
9860  ++line)
9862  cell->refine_flag_set(), line) ==
9864  // flag a line, that will be
9865  // refined
9866  cell->line(line)->set_user_flag();
9867  }
9868  else if (cell->has_children() &&
9869  !cell->child(0)->coarsen_flag_set())
9870  {
9871  for (unsigned int line = 0;
9872  line < GeometryInfo<dim>::lines_per_cell;
9873  ++line)
9875  cell->refinement_case(), line) ==
9877  // flag a line, that is refined
9878  // and will stay so
9879  cell->line(line)->set_user_flag();
9880  }
9881  else if (cell->has_children() &&
9882  cell->child(0)->coarsen_flag_set())
9883  cell->set_user_flag();
9884 
9885 
9886  // now check whether there are cells with lines that are
9887  // more than once refined or that will be more than once
9888  // refined. The first thing should never be the case, in
9889  // the second case we flag the cell for refinement
9891  cell = triangulation.last_active();
9892  cell != triangulation.end();
9893  --cell)
9894  for (unsigned int line = 0;
9895  line < GeometryInfo<dim>::lines_per_cell;
9896  ++line)
9897  {
9898  if (cell->line(line)->has_children())
9899  {
9900  // if this line is refined, its children should
9901  // not have further children
9902  //
9903  // however, if any of the children is flagged
9904  // for further refinement, we need to refine
9905  // this cell also (at least, if the cell is not
9906  // already flagged)
9907  bool offending_line_found = false;
9908 
9909  for (unsigned int c = 0; c < 2; ++c)
9910  {
9911  Assert(cell->line(line)->child(c)->has_children() ==
9912  false,
9913  ExcInternalError());
9914 
9915  if (cell->line(line)->child(c)->user_flag_set() &&
9917  cell->refine_flag_set(), line) ==
9919  {
9920  // tag this cell for refinement
9921  cell->clear_coarsen_flag();
9922  // if anisotropic coarsening is allowed:
9923  // extend the refine_flag in the needed
9924  // direction, else set refine_flag
9925  // (isotropic)
9926  if (triangulation.smooth_grid &
9928  allow_anisotropic_smoothing)
9929  cell->flag_for_line_refinement(line);
9930  else
9931  cell->set_refine_flag();
9932 
9933  for (unsigned int l = 0;
9934  l < GeometryInfo<dim>::lines_per_cell;
9935  ++l)
9937  cell->refine_flag_set(), line) ==
9939  // flag a line, that will be refined
9940  cell->line(l)->set_user_flag();
9941 
9942  // note that we have changed the grid
9943  offending_line_found = true;
9944 
9945  // it may save us several loop
9946  // iterations if we flag all lines of
9947  // this cell now (and not at the outset
9948  // of the next iteration) for refinement
9949  for (unsigned int l = 0;
9950  l < GeometryInfo<dim>::lines_per_cell;
9951  ++l)
9952  if (!cell->line(l)->has_children() &&
9954  cell->refine_flag_set(), l) !=
9956  cell->line(l)->set_user_flag();
9957 
9958  break;
9959  }
9960  }
9961 
9962  if (offending_line_found)
9963  {
9964  mesh_changed = true;
9965  break;
9966  }
9967  }
9968  }
9969 
9970 
9971  // there is another thing here: if any of the lines will
9972  // be refined, then we may not coarsen the present cell
9973  // similarly, if any of the lines *is* already refined, we
9974  // may not coarsen the current cell. however, there's a
9975  // catch: if the line is refined, but the cell behind it
9976  // is going to be coarsened, then the situation
9977  // changes. if we forget this second condition, the
9978  // refine_and_coarsen_3d test will start to fail. note
9979  // that to know which cells are going to be coarsened, the
9980  // call for fix_coarsen_flags above is necessary
9981  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
9982  triangulation.last();
9983  cell != triangulation.end();
9984  --cell)
9985  {
9986  if (cell->user_flag_set())
9987  for (unsigned int line = 0;
9988  line < GeometryInfo<dim>::lines_per_cell;
9989  ++line)
9990  if (cell->line(line)->has_children() &&
9991  (cell->line(line)->child(0)->user_flag_set() ||
9992  cell->line(line)->child(1)->user_flag_set()))
9993  {
9994  for (unsigned int c = 0; c < cell->n_children(); ++c)
9995  cell->child(c)->clear_coarsen_flag();
9996  cell->clear_user_flag();
9997  for (unsigned int l = 0;
9998  l < GeometryInfo<dim>::lines_per_cell;
9999  ++l)
10001  cell->refinement_case(), l) ==
10003  // flag a line, that is refined
10004  // and will stay so
10005  cell->line(l)->set_user_flag();
10006  mesh_changed = true;
10007  break;
10008  }
10009  }
10010  }
10011  while (mesh_changed == true);
10012  }
10013 
10014 
10015 
10022  template <int dim, int spacedim>
10023  static bool
10025  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
10026  {
10027  // in 1d, coarsening is always allowed since we don't enforce
10028  // the 2:1 constraint there
10029  if (dim == 1)
10030  return true;
10031 
10032  const RefinementCase<dim> ref_case = cell->refinement_case();
10033  for (unsigned int n : GeometryInfo<dim>::face_indices())
10034  {
10035  // if the cell is not refined along that face, coarsening
10036  // will not change anything, so do nothing. the same
10037  // applies, if the face is at the boandary
10038  const RefinementCase<dim - 1> face_ref_case =
10039  GeometryInfo<dim>::face_refinement_case(cell->refinement_case(),
10040  n);
10041 
10042  const unsigned int n_subfaces =
10043  GeometryInfo<dim - 1>::n_children(face_ref_case);
10044 
10045  if (n_subfaces == 0 || cell->at_boundary(n))
10046  continue;
10047  for (unsigned int c = 0; c < n_subfaces; ++c)
10048  {
10050  child = cell->child(
10051  GeometryInfo<dim>::child_cell_on_face(ref_case, n, c));
10052 
10054  child_neighbor = child->neighbor(n);
10055  if (!child->neighbor_is_coarser(n))
10056  // in 2d, if the child's neighbor is coarser, then
10057  // it has no children. however, in 3d it might be
10058  // otherwise. consider for example, that our face
10059  // might be refined with cut_x, but the neighbor is
10060  // refined with cut_xy at that face. then the
10061  // neighbor pointers of the children of our cell
10062  // will point to the common neighbor cell, not to
10063  // its children. what we really want to know in the
10064  // following is, whether the neighbor cell is
10065  // refined twice with reference to our cell. that
10066  // only has to be asked, if the child's neighbor is
10067  // not a coarser one.
10068  if ((child_neighbor->has_children() &&
10069  !child_neighbor->user_flag_set()) ||
10070  // neighbor has children, which are further
10071  // refined along the face, otherwise something
10072  // went wrong in the construction of neighbor
10073  // pointers. then only allow coarsening if this
10074  // neighbor will be coarsened as well
10075  // (user_pointer is set). the same applies, if
10076  // the neighbors children are not refined but
10077  // will be after refinement
10078  child_neighbor->refine_flag_set())
10079  return false;
10080  }
10081  }
10082  return true;
10083  }
10084  };
10085 
10086 
10087 
10088  template <int dim, int spacedim>
10089  const Manifold<dim, spacedim> &
10091  {
10092  static const FlatManifold<dim, spacedim> flat_manifold;
10093  return flat_manifold;
10094  }
10095  } // namespace TriangulationImplementation
10096 } // namespace internal
10097 
10098 
10099 
10100 template <int dim, int spacedim>
10101 const unsigned int Triangulation<dim, spacedim>::dimension;
10102 
10103 
10104 
10105 template <int dim, int spacedim>
10107  const MeshSmoothing smooth_grid,
10108  const bool check_for_distorted_cells)
10109  : smooth_grid(smooth_grid)
10110  , anisotropic_refinement(false)
10111  , check_for_distorted_cells(check_for_distorted_cells)
10112 {
10113  if (dim == 1)
10114  {
10116  std_cxx14::make_unique<std::map<unsigned int, types::boundary_id>>();
10118  std_cxx14::make_unique<std::map<unsigned int, types::manifold_id>>();
10119  }
10120 
10121  // connect the any_change signal to the other top level signals
10122  signals.create.connect(signals.any_change);
10124  signals.clear.connect(signals.any_change);
10126 }
10127 
10128 
10129 
10130 template <int dim, int spacedim>
10132  Triangulation<dim, spacedim> &&tria) noexcept
10133  : Subscriptor(std::move(tria))
10134  , smooth_grid(tria.smooth_grid)
10135  , periodic_face_pairs_level_0(std::move(tria.periodic_face_pairs_level_0))
10136  , periodic_face_map(std::move(tria.periodic_face_map))
10137  , levels(std::move(tria.levels))
10138  , faces(std::move(tria.faces))
10139  , vertices(std::move(tria.vertices))
10140  , vertices_used(std::move(tria.vertices_used))
10141  , manifold(std::move(tria.manifold))
10142  , anisotropic_refinement(tria.anisotropic_refinement)
10143  , check_for_distorted_cells(tria.check_for_distorted_cells)
10144  , number_cache(std::move(tria.number_cache))
10145  , vertex_to_boundary_id_map_1d(std::move(tria.vertex_to_boundary_id_map_1d))
10146  , vertex_to_manifold_id_map_1d(std::move(tria.vertex_to_manifold_id_map_1d))
10147 {
10149 }
10150 
10151 
10152 template <int dim, int spacedim>
10156 {
10157  Subscriptor::operator=(std::move(tria));
10158 
10159  smooth_grid = tria.smooth_grid;
10160  periodic_face_pairs_level_0 = std::move(tria.periodic_face_pairs_level_0);
10161  periodic_face_map = std::move(tria.periodic_face_map);
10162  levels = std::move(tria.levels);
10163  faces = std::move(tria.faces);
10164  vertices = std::move(tria.vertices);
10165  vertices_used = std::move(tria.vertices_used);
10166  manifold = std::move(tria.manifold);
10167  anisotropic_refinement = tria.anisotropic_refinement;
10168  number_cache = tria.number_cache;
10169  vertex_to_boundary_id_map_1d = std::move(tria.vertex_to_boundary_id_map_1d);
10170  vertex_to_manifold_id_map_1d = std::move(tria.vertex_to_manifold_id_map_1d);
10171 
10173 
10174  return *this;
10175 }
10176 
10177 
10178 
10179 template <int dim, int spacedim>
10181 {
10182  // notify listeners that the triangulation is going down...
10183  try
10184  {
10185  signals.clear();
10186  }
10187  catch (...)
10188  {}
10189 
10190  levels.clear();
10191 
10192  // the vertex_to_boundary_id_map_1d field should be unused except in
10193  // 1d. double check this here, as destruction is a good place to
10194  // ensure that what we've done over the course of the lifetime of
10195  // this object makes sense
10196  AssertNothrow((dim == 1) || (vertex_to_boundary_id_map_1d == nullptr),
10197  ExcInternalError());
10198 
10199  // the vertex_to_manifold_id_map_1d field should be also unused
10200  // except in 1d. check this as well
10201  AssertNothrow((dim == 1) || (vertex_to_manifold_id_map_1d == nullptr),
10202  ExcInternalError());
10203 }
10204 
10205 
10206 
10207 template <int dim, int spacedim>
10208 void
10210 {
10211  // notify listeners that the triangulation is going down...
10212  signals.clear();
10213 
10214  // ...and then actually clear all content of it
10215  clear_despite_subscriptions();
10216  periodic_face_pairs_level_0.clear();
10217  periodic_face_map.clear();
10218 }
10219 
10220 
10221 
10222 template <int dim, int spacedim>
10223 void
10225  const MeshSmoothing mesh_smoothing)
10226 {
10227  Assert(n_levels() == 0,
10228  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
10229  smooth_grid = mesh_smoothing;
10230 }
10231 
10232 
10233 
10234 template <int dim, int spacedim>
10237 {
10238  return smooth_grid;
10239 }
10240 
10241 
10242 
10243 template <int dim, int spacedim>
10244 void
10246  const types::manifold_id m_number,
10247  const Manifold<dim, spacedim> &manifold_object)
10248 {
10250 
10251  manifold[m_number] = manifold_object.clone();
10252 }
10253 
10254 
10255 
10256 template <int dim, int spacedim>
10257 void
10259 {
10261 
10262  // delete the entry located at number.
10263  manifold.erase(m_number);
10264 }
10265 
10266 
10267 template <int dim, int spacedim>
10268 void
10270 {
10271  manifold.clear();
10272 }
10273 
10274 
10275 template <int dim, int spacedim>
10276 void
10278  const types::manifold_id m_number)
10279 {
10280  Assert(
10281  n_cells() > 0,
10282  ExcMessage(
10283  "Error: set_all_manifold_ids() can not be called on an empty Triangulation."));
10284 
10286  cell = this->begin_active(),
10287  endc = this->end();
10288 
10289  for (; cell != endc; ++cell)
10290  cell->set_all_manifold_ids(m_number);
10291 }
10292 
10293 
10294 template <int dim, int spacedim>
10295 void
10297  const types::manifold_id m_number)
10298 {
10299  Assert(
10300  n_cells() > 0,
10301  ExcMessage(
10302  "Error: set_all_manifold_ids_on_boundary() can not be called on an empty Triangulation."));
10303 
10305  cell = this->begin_active(),
10306  endc = this->end();
10307 
10308  for (; cell != endc; ++cell)
10309  for (auto f : GeometryInfo<dim>::face_indices())
10310  if (cell->face(f)->at_boundary())
10311  cell->face(f)->set_all_manifold_ids(m_number);
10312 }
10313 
10314 
10315 template <int dim, int spacedim>
10316 void
10318  const types::boundary_id b_id,
10319  const types::manifold_id m_number)
10320 {
10321  Assert(
10322  n_cells() > 0,
10323  ExcMessage(
10324  "Error: set_all_manifold_ids_on_boundary() can not be called on an empty Triangulation."));
10325 
10326  bool boundary_found = false;
10328  cell = this->begin_active(),
10329  endc = this->end();
10330 
10331  for (; cell != endc; ++cell)
10332  {
10333  // loop on faces
10334  for (auto f : GeometryInfo<dim>::face_indices())
10335  if (cell->face(f)->at_boundary() &&
10336  cell->face(f)->boundary_id() == b_id)
10337  {
10338  boundary_found = true;
10339  cell->face(f)->set_manifold_id(m_number);
10340  }
10341 
10342  // loop on edges if dim >= 3
10343  if (dim >= 3)
10344  for (unsigned int e = 0; e < GeometryInfo<dim>::lines_per_cell; ++e)
10345  if (cell->line(e)->at_boundary() &&
10346  cell->line(e)->boundary_id() == b_id)
10347  {
10348  boundary_found = true;
10349  cell->line(e)->set_manifold_id(m_number);
10350  }
10351  }
10352 
10353  (void)boundary_found;
10354  Assert(boundary_found, ExcBoundaryIdNotFound(b_id));
10355 }
10356 
10357 
10358 
10359 template <int dim, int spacedim>
10362  const types::manifold_id m_number) const
10363 {
10364  // look, if there is a manifold stored at
10365  // manifold_id number.
10366  const auto it = manifold.find(m_number);
10367 
10368  if (it != manifold.end())
10369  {
10370  // if we have found an entry, return it
10371  return *(it->second);
10372  }
10373 
10374  // if we have not found an entry connected with number, we return
10375  // the default (flat) manifold
10376  return internal::TriangulationImplementation::
10377  get_default_flat_manifold<dim, spacedim>();
10378 }
10379 
10380 
10381 
10382 template <int dim, int spacedim>
10383 std::vector<types::boundary_id>
10385 {
10386  // in 1d, we store a map of all used boundary indicators. use it for
10387  // our purposes
10388  if (dim == 1)
10389  {
10390  std::vector<types::boundary_id> boundary_ids;
10391  for (std::map<unsigned int, types::boundary_id>::const_iterator p =
10392  vertex_to_boundary_id_map_1d->begin();
10393  p != vertex_to_boundary_id_map_1d->end();
10394  ++p)
10395  boundary_ids.push_back(p->second);
10396 
10397  return boundary_ids;
10398  }
10399  else
10400  {
10401  std::set<types::boundary_id> b_ids;
10402  for (auto cell : active_cell_iterators())
10403  if (cell->is_locally_owned())
10404  for (const unsigned int face : GeometryInfo<dim>::face_indices())
10405  if (cell->at_boundary(face))
10406  b_ids.insert(cell->face(face)->boundary_id());
10407  std::vector<types::boundary_id> boundary_ids(b_ids.begin(), b_ids.end());
10408  return boundary_ids;
10409  }
10410 }
10411 
10412 
10413 
10414 template <int dim, int spacedim>
10415 std::vector<types::manifold_id>
10417 {
10418  std::set<types::manifold_id> m_ids;
10419  for (auto cell : active_cell_iterators())
10420  if (cell->is_locally_owned())
10421  {
10422  m_ids.insert(cell->manifold_id());
10423  if (dim > 1)
10424  for (const unsigned int face : GeometryInfo<dim>::face_indices())
10425  if (cell->at_boundary(face))
10426  m_ids.insert(cell->face(face)->manifold_id());
10427  }
10428  std::vector<types::manifold_id> manifold_indicators(m_ids.begin(),
10429  m_ids.end());
10430  return manifold_indicators;
10431 }
10432 
10433 /*-----------------------------------------------------------------*/
10434 
10435 
10436 template <int dim, int spacedim>
10437 void
10439  const Triangulation<dim, spacedim> &other_tria)
10440 {
10441  Assert((vertices.size() == 0) && (levels.size() == 0) && (faces == nullptr),
10442  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
10443  Assert((other_tria.levels.size() != 0) && (other_tria.vertices.size() != 0) &&
10444  (dim == 1 || other_tria.faces != nullptr),
10445  ExcMessage(
10446  "When calling Triangulation::copy_triangulation(), "
10447  "the target triangulation must be empty but the source "
10448  "triangulation (the argument to this function) must contain "
10449  "something. Here, it seems like the source does not "
10450  "contain anything at all."));
10451 
10452 
10453  // copy normal elements
10454  vertices = other_tria.vertices;
10455  vertices_used = other_tria.vertices_used;
10456  anisotropic_refinement = other_tria.anisotropic_refinement;
10457  smooth_grid = other_tria.smooth_grid;
10458 
10459  if (dim > 1)
10460  faces = std_cxx14::make_unique<
10462 
10463  auto bdry_iterator = other_tria.manifold.begin();
10464  for (; bdry_iterator != other_tria.manifold.end(); ++bdry_iterator)
10465  manifold[bdry_iterator->first] = bdry_iterator->second->clone();
10466 
10467 
10468  levels.reserve(other_tria.levels.size());
10469  for (unsigned int level = 0; level < other_tria.levels.size(); ++level)
10470  levels.push_back(std_cxx14::make_unique<
10472  *other_tria.levels[level]));
10473 
10474  number_cache = other_tria.number_cache;
10475 
10476  if (dim == 1)
10477  {
10478  vertex_to_boundary_id_map_1d =
10479  std_cxx14::make_unique<std::map<unsigned int, types::boundary_id>>(
10480  *other_tria.vertex_to_boundary_id_map_1d);
10481 
10482  vertex_to_manifold_id_map_1d =
10483  std_cxx14::make_unique<std::map<unsigned int, types::manifold_id>>(
10484  *other_tria.vertex_to_manifold_id_map_1d);
10485  }
10486 
10487  // inform those who are listening on other_tria of the copy operation
10488  other_tria.signals.copy(*this);
10489  // also inform all listeners of the current triangulation that the
10490  // triangulation has been created
10491  signals.create();
10492 
10493  // note that we need not copy the
10494  // subscriptor!
10495 }
10496 
10497 
10498 
10499 template <int dim, int spacedim>
10500 void
10502  const std::vector<Point<spacedim>> &v,
10503  const std::vector<CellData<dim>> & cells,
10504  const SubCellData & subcelldata)
10505 {
10506  std::vector<CellData<dim>> reordered_cells(cells); // NOLINT
10507  SubCellData reordered_subcelldata(subcelldata); // NOLINT
10508 
10509  // in-place reordering of data
10510  reorder_compatibility(reordered_cells, reordered_subcelldata);
10511 
10512  // now create triangulation from
10513  // reordered data
10514  create_triangulation(v, reordered_cells, reordered_subcelldata);
10515 }
10516 
10517 
10518 
10519 template <int dim, int spacedim>
10520 void
10522  const std::vector<Point<spacedim>> &v,
10523  const std::vector<CellData<dim>> & cells,
10524  const SubCellData & subcelldata)
10525 {
10526  Assert((vertices.size() == 0) && (levels.size() == 0) && (faces == nullptr),
10527  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
10528  // check that no forbidden arrays
10529  // are used
10530  Assert(subcelldata.check_consistency(dim), ExcInternalError());
10531 
10532  // try to create a triangulation; if this fails, we still want to
10533  // throw an exception but if we just do so we'll get into trouble
10534  // because sometimes other objects are already attached to it:
10535  try
10536  {
10538  create_triangulation(v, cells, subcelldata, *this);
10539  }
10540  catch (...)
10541  {
10542  clear_despite_subscriptions();
10543  throw;
10544  }
10545 
10546  // update our counts of the various elements of a triangulation, and set
10547  // active_cell_indices of all cells
10549  *this, levels.size(), number_cache);
10550  reset_active_cell_indices();
10551 
10552  // now verify that there are indeed no distorted cells. as per the
10553  // documentation of this class, we first collect all distorted cells
10554  // and then throw an exception if there are any
10555  if (check_for_distorted_cells == true)
10556  {
10557  DistortedCellList distorted_cells = collect_distorted_coarse_cells(*this);
10558  // throw the array (and fill the various location fields) if
10559  // there are distorted cells. otherwise, just fall off the end
10560  // of the function
10561  AssertThrow(distorted_cells.distorted_cells.size() == 0, distorted_cells);
10562  }
10563 
10564 
10565  /*
10566  When the triangulation is a manifold (dim < spacedim), the normal field
10567  provided from the map class depends on the order of the vertices.
10568  It may happen that this normal field is discontinuous.
10569  The following code takes care that this is not the case by setting the
10570  cell direction flag on those cell that produce the wrong orientation.
10571 
10572  To determine if 2 neighbours have the same or opposite orientation
10573  we use a table of truth.
10574  Its entries are indexes by the local indices of the common face.
10575  For example if two elements share a face, and this face is
10576  face 0 for element 0 and face 1 for element 1, then
10577  table(0,1) will tell whether the orientation are the same (true) or
10578  opposite (false).
10579 
10580  Even though there may be a combinatorial/graph theory argument to get
10581  this table in any dimension, I tested by hand all the different possible
10582  cases in 1D and 2D to generate the table.
10583 
10584  Assuming that a surface respects the standard orientation for 2d meshes,
10585  the tables of truth are symmetric and their true values are the following
10586  1D curves: (0,1)
10587  2D surface: (0,1),(0,2),(1,3),(2,3)
10588 
10589  We store this data using an n_faces x n_faces full matrix, which is
10590  actually much bigger than the minimal data required, but it makes the code
10591  more readable.
10592 
10593  */
10594  if (dim < spacedim)
10595  {
10598  switch (dim)
10599  {
10600  case 1:
10601  {
10602  bool values[][2] = {{false, true}, {true, false}};
10603  for (const unsigned int i : GeometryInfo<dim>::face_indices())
10604  for (const unsigned int j : GeometryInfo<dim>::face_indices())
10605  correct(i, j) = (values[i][j]);
10606  break;
10607  }
10608  case 2:
10609  {
10610  bool values[][4] = {{false, true, true, false},
10611  {true, false, false, true},
10612  {true, false, false, true},
10613  {false, true, true, false}};
10614  for (const unsigned int i : GeometryInfo<dim>::face_indices())
10615  for (const unsigned int j : GeometryInfo<dim>::face_indices())
10616  correct(i, j) = (values[i][j]);
10617  break;
10618  }
10619  default:
10620  Assert(false, ExcNotImplemented());
10621  }
10622 
10623 
10624  std::list<active_cell_iterator> this_round, next_round;
10625  active_cell_iterator neighbor;
10626 
10627  this_round.push_back(begin_active());
10628  begin_active()->set_direction_flag(true);
10629  begin_active()->set_user_flag();
10630 
10631  while (this_round.size() > 0)
10632  {
10633  for (typename std::list<active_cell_iterator>::iterator cell =
10634  this_round.begin();
10635  cell != this_round.end();
10636  ++cell)
10637  {
10638  for (const unsigned int i : GeometryInfo<dim>::face_indices())
10639  {
10640  if (!((*cell)->face(i)->at_boundary()))
10641  {
10642  neighbor = (*cell)->neighbor(i);
10643 
10644  unsigned int cf = (*cell)->face_index(i);
10645  unsigned int j = 0;
10646  while (neighbor->face_index(j) != cf)
10647  {
10648  ++j;
10649  }
10650 
10651 
10652  // If we already saw this guy, check that everything is
10653  // fine
10654  if (neighbor->user_flag_set())
10655  {
10656  // If we have visited this guy, then the ordering and
10657  // the orientation should agree
10658  Assert(!(correct(i, j) ^
10659  (neighbor->direction_flag() ==
10660  (*cell)->direction_flag())),
10661  ExcNonOrientableTriangulation());
10662  }
10663  else
10664  {
10665  next_round.push_back(neighbor);
10666  neighbor->set_user_flag();
10667  if ((correct(i, j) ^ (neighbor->direction_flag() ==
10668  (*cell)->direction_flag())))
10669  neighbor->set_direction_flag(
10670  !neighbor->direction_flag());
10671  }
10672  }
10673  }
10674  }
10675 
10676  // Before we quit let's check
10677  // that if the triangulation
10678  // is disconnected that we
10679  // still get all cells
10680  if (next_round.size() == 0)
10681  for (const auto &cell : this->active_cell_iterators())
10682  if (cell->user_flag_set() == false)
10683  {
10684  next_round.push_back(cell);
10685  cell->set_direction_flag(true);
10686  cell->set_user_flag();
10687  break;
10688  }
10689 
10690  this_round = next_round;
10691  next_round.clear();
10692  }
10693  }
10694 
10695  // inform all listeners that the triangulation has been created
10696  signals.create();
10697 }
10698 
10699 
10700 
10701 template <int dim, int spacedim>
10702 void
10705 {
10706  // 1) create coarse grid
10707  create_triangulation(construction_data.coarse_cell_vertices,
10708  construction_data.coarse_cells,
10709  SubCellData());
10710 
10711  // create a copy of cell_infos such that we can sort them
10712  auto cell_infos = construction_data.cell_infos;
10713 
10714  // sort cell_infos on each level separately
10715  for (auto &cell_info : cell_infos)
10716  std::sort(
10717  cell_info.begin(),
10718  cell_info.end(),
10721  const CellId a_id(a.id);
10722  const CellId b_id(b.id);
10723 
10724  const auto a_coarse_cell_index =
10725  this->coarse_cell_id_to_coarse_cell_index(a_id.get_coarse_cell_id());
10726  const auto b_coarse_cell_index =
10727  this->coarse_cell_id_to_coarse_cell_index(b_id.get_coarse_cell_id());
10728 
10729  // according to their coarse-cell index and if that is
10730  // same according to their cell id (the result is that
10731  // cells on each level are sorted according to their
10732  // index on that level - what we need in the following
10733  // operations)
10734  if (a_coarse_cell_index != b_coarse_cell_index)
10735  return a_coarse_cell_index < b_coarse_cell_index;
10736  else
10737  return a_id < b_id;
10738  });
10739 
10740  // 2) create all levels via a sequence of refinements
10741  for (unsigned int level = 0; level < cell_infos.size(); ++level)
10742  {
10743  // a) set manifold ids here (because new vertices have to be
10744  // positioned correctly during each refinement step)
10745  {
10746  auto cell = this->begin(level);
10747  auto cell_info = cell_infos[level].begin();
10748  for (; cell_info != cell_infos[level].end(); ++cell_info)
10749  {
10750  while (cell_info->id != cell->id().template to_binary<dim>())
10751  ++cell;
10752  if (dim == 3)
10753  for (unsigned int quad = 0;
10754  quad < GeometryInfo<dim>::quads_per_cell;
10755  ++quad)
10756  cell->quad(quad)->set_manifold_id(
10757  cell_info->manifold_quad_ids[quad]);
10758 
10759  if (dim >= 2)
10760  for (unsigned int line = 0;
10761  line < GeometryInfo<dim>::lines_per_cell;
10762  ++line)
10763  cell->line(line)->set_manifold_id(
10764  cell_info->manifold_line_ids[line]);
10765 
10766  cell->set_manifold_id(cell_info->manifold_id);
10767  }
10768  }
10769 
10770  // b) perform refinement on all levels but on the finest
10771  if (level + 1 != cell_infos.size())
10772  {
10773  // find cells that should have children and mark them for
10774  // refinement
10775  auto coarse_cell = this->begin(level);
10776  auto fine_cell_info = cell_infos[level + 1].begin();
10777 
10778  // loop over all cells on the next level
10779  for (; fine_cell_info != cell_infos[level + 1].end();
10780  ++fine_cell_info)
10781  {
10782  // find the parent of that cell
10783  while (
10784  !coarse_cell->id().is_parent_of(CellId(fine_cell_info->id)))
10785  ++coarse_cell;
10786 
10787  // set parent for refinement
10788  coarse_cell->set_refine_flag();
10789  }
10790 
10791  // execute refinement
10792  ::Triangulation<dim,
10793  spacedim>::execute_coarsening_and_refinement();
10794  }
10795  }
10796 
10797  // 3) set boundary ids
10798  for (unsigned int level = 0; level < cell_infos.size(); ++level)
10799  {
10800  auto cell = this->begin(level);
10801  auto cell_info = cell_infos[level].begin();
10802  for (; cell_info != cell_infos[level].end(); ++cell_info)
10803  {
10804  // find cell that has the correct cell
10805  while (cell_info->id != cell->id().template to_binary<dim>())
10806  ++cell;
10807 
10808  // boundary ids
10809  for (auto pair : cell_info->boundary_ids)
10810  {
10811  Assert(cell->at_boundary(pair.first),
10812  ExcMessage("Cell face is not on the boundary!"));
10813  cell->face(pair.first)->set_boundary_id(pair.second);
10814  }
10815  }
10816  }
10817 }
10818 
10819 
10820 template <int dim, int spacedim>
10821 void
10823 {
10824  AssertThrow(dim + 1 == spacedim,
10825  ExcMessage("Only works for dim == spacedim-1"));
10826  for (const auto &cell : this->active_cell_iterators())
10827  cell->set_direction_flag(!cell->direction_flag());
10828 }
10829 
10830 
10831 
10832 template <int dim, int spacedim>
10833 void
10835 {
10836  Assert(n_cells() > 0,
10837  ExcMessage("Error: An empty Triangulation can not be refined."));
10838  active_cell_iterator cell = begin_active(), endc = end();
10839 
10840  for (; cell != endc; ++cell)
10841  {
10842  cell->clear_coarsen_flag();
10843  cell->set_refine_flag();
10844  }
10845 }
10846 
10847 
10848 
10849 template <int dim, int spacedim>
10850 void
10852 {
10853  for (unsigned int i = 0; i < times; ++i)
10854  {
10855  set_all_refine_flags();
10856  execute_coarsening_and_refinement();
10857  }
10858 }
10859 
10860 
10861 
10862 /*-------------------- refine/coarsen flags -------------------------*/
10863 
10864 
10865 
10866 template <int dim, int spacedim>
10867 void
10869 {
10870  v.resize(dim * n_active_cells(), false);
10871  std::vector<bool>::iterator i = v.begin();
10872  active_cell_iterator cell = begin_active(), endc = end();
10873  for (; cell != endc; ++cell)
10874  for (unsigned int j = 0; j < dim; ++j, ++i)
10875  if (cell->refine_flag_set() & (1 << j))
10876  *i = true;
10877 
10878  Assert(i == v.end(), ExcInternalError());
10879 }
10880 
10881 
10882 
10883 template <int dim, int spacedim>
10884 void
10886 {
10887  std::vector<bool> v;
10888  save_refine_flags(v);
10889  write_bool_vector(mn_tria_refine_flags_begin,
10890  v,
10892  out);
10893 }
10894 
10895 
10896 
10897 template <int dim, int spacedim>
10898 void
10900 {
10901  std::vector<bool> v;
10902  read_bool_vector(mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end, in);
10903  load_refine_flags(v);
10904 }
10905 
10906 
10907 
10908 template <int dim, int spacedim>
10909 void
10911 {
10912  AssertThrow(v.size() == dim * n_active_cells(), ExcGridReadError());
10913 
10914  active_cell_iterator cell = begin_active(), endc = end();
10915  std::vector<bool>::const_iterator i = v.begin();
10916  for (; cell != endc; ++cell)
10917  {
10918  unsigned int ref_case = 0;
10919 
10920  for (unsigned int j = 0; j < dim; ++j, ++i)
10921  if (*i == true)
10922  ref_case += 1 << j;
10924  ExcGridReadError());
10925  if (ref_case > 0)
10926  cell->set_refine_flag(RefinementCase<dim>(ref_case));
10927  else
10928  cell->clear_refine_flag();
10929  }
10930 
10931  Assert(i == v.end(), ExcInternalError());
10932 }
10933 
10934 
10935 
10936 template <int dim, int spacedim>
10937 void
10939 {
10940  v.resize(n_active_cells(), false);
10941  std::vector<bool>::iterator i = v.begin();
10942  active_cell_iterator cell = begin_active(), endc = end();
10943  for (; cell != endc; ++cell, ++i)
10944  *i = cell->coarsen_flag_set();
10945 
10946  Assert(i == v.end(), ExcInternalError());
10947 }
10948 
10949 
10950 
10951 template <int dim, int spacedim>
10952 void
10954 {
10955  std::vector<bool> v;
10956  save_coarsen_flags(v);
10957  write_bool_vector(mn_tria_coarsen_flags_begin,
10958  v,
10960  out);
10961 }
10962 
10963 
10964 
10965 template <int dim, int spacedim>
10966 void
10968 {
10969  std::vector<bool> v;
10970  read_bool_vector(mn_tria_coarsen_flags_begin,
10971  v,
10973  in);
10974  load_coarsen_flags(v);
10975 }
10976 
10977 
10978 
10979 template <int dim, int spacedim>
10980 void
10982 {
10983  Assert(v.size() == n_active_cells(), ExcGridReadError());
10984 
10985  active_cell_iterator cell = begin_active(), endc = end();
10986  std::vector<bool>::const_iterator i = v.begin();
10987  for (; cell != endc; ++cell, ++i)
10988  if (*i == true)
10989  cell->set_coarsen_flag();
10990  else
10991  cell->clear_coarsen_flag();
10992 
10993  Assert(i == v.end(), ExcInternalError());
10994 }
10995 
10996 
10997 template <int dim, int spacedim>
10998 bool
11000 {
11001  return anisotropic_refinement;
11002 }
11003 
11004 
11005 
11006 /*-------------------- user data/flags -------------------------*/
11007 
11008 
11009 namespace
11010 {
11011  // clear user data of cells
11012  template <int dim>
11013  void
11014  clear_user_data(
11015  std::vector<
11017  &levels)
11018  {
11019  for (unsigned int level = 0; level < levels.size(); ++level)
11020  levels[level]->cells.clear_user_data();
11021  }
11022 
11023 
11024  // clear user data of faces
11026  {
11027  // nothing to do in 1d
11028  }
11029 
11030 
11031  void
11033  {
11034  faces->lines.clear_user_data();
11035  }
11036 
11037 
11038  void
11040  {
11041  faces->lines.clear_user_data();
11042  faces->quads.clear_user_data();
11043  }
11044 } // namespace
11045 
11046 
11047 template <int dim, int spacedim>
11048 void
11050 {
11051  // let functions in anonymous namespace do their work
11052  ::clear_user_data(levels);
11053  ::clear_user_data(faces.get());
11054 }
11055 
11056 
11057 
11058 namespace
11059 {
11060  void clear_user_flags_line(
11061  std::vector<
11063  &levels,
11065  {
11066  for (const auto &level : levels)
11067  level->cells.clear_user_flags();
11068  }
11069 
11070  template <int dim>
11071  void
11072  clear_user_flags_line(
11073  std::vector<
11076  {
11077  faces->lines.clear_user_flags();
11078  }
11079 } // namespace
11080 
11081 
11082 template <int dim, int spacedim>
11083 void
11085 {
11086  ::clear_user_flags_line(levels, faces.get());
11087 }
11088 
11089 
11090 
11091 namespace
11092 {
11093  void clear_user_flags_quad(
11094  std::vector<
11097  {
11098  // nothing to do in 1d
11099  }
11100 
11101  void clear_user_flags_quad(
11102  std::vector<
11104  &levels,
11106  {
11107  for (const auto &level : levels)
11108  level->cells.clear_user_flags();
11109  }
11110 
11111  template <int dim>
11112  void
11113  clear_user_flags_quad(
11114  std::vector<
11117  {
11118  faces->quads.clear_user_flags();
11119  }
11120 } // namespace
11121 
11122 
11123 template <int dim, int spacedim>
11124 void
11126 {
11127  ::clear_user_flags_quad(levels, faces.get());
11128 }
11129 
11130 
11131 
11132 namespace
11133 {
11134  void clear_user_flags_hex(
11135  std::vector<
11138  {
11139  // nothing to do in 1d
11140  }
11141 
11142 
11143  void clear_user_flags_hex(
11144  std::vector<
11147  {
11148  // nothing to do in 2d
11149  }
11150 
11151  void clear_user_flags_hex(
11152  std::vector<
11154  &levels,
11156  {
11157  for (const auto &level : levels)
11158  level->cells.clear_user_flags();
11159  }
11160 } // namespace
11161 
11162 
11163 template <int dim, int spacedim>
11164 void
11166 {
11167  ::clear_user_flags_hex(levels, faces.get());
11168 }
11169 
11170 
11171 
11172 template <int dim, int spacedim>
11173 void
11175 {
11176  clear_user_flags_line();
11177  clear_user_flags_quad();
11178  clear_user_flags_hex();
11179 }
11180 
11181 
11182 
11183 template <int dim, int spacedim>
11184 void
11186 {
11187  save_user_flags_line(out);
11188 
11189  if (dim >= 2)
11190  save_user_flags_quad(out);
11191 
11192  if (dim >= 3)
11193  save_user_flags_hex(out);
11194 
11195  if (dim >= 4)
11196  Assert(false, ExcNotImplemented());
11197 }
11198 
11199 
11200 
11201 template <int dim, int spacedim>
11202 void
11204 {
11205  // clear vector and append
11206  // all the stuff later on
11207  v.clear();
11208 
11209  std::vector<bool> tmp;
11210 
11211  save_user_flags_line(tmp);
11212  v.insert(v.end(), tmp.begin(), tmp.end());
11213 
11214  if (dim >= 2)
11215  {
11216  save_user_flags_quad(tmp);
11217  v.insert(v.end(), tmp.begin(), tmp.end());
11218  }
11219 
11220  if (dim >= 3)
11221  {
11222  save_user_flags_hex(tmp);
11223  v.insert(v.end(), tmp.begin(), tmp.end());
11224  }
11225 
11226  if (dim >= 4)
11227  Assert(false, ExcNotImplemented());
11228 }
11229 
11230 
11231 
11232 template <int dim, int spacedim>
11233 void
11235 {
11236  load_user_flags_line(in);
11237 
11238  if (dim >= 2)
11239  load_user_flags_quad(in);
11240 
11241  if (dim >= 3)
11242  load_user_flags_hex(in);
11243 
11244  if (dim >= 4)
11245  Assert(false, ExcNotImplemented());
11246 }
11247 
11248 
11249 
11250 template <int dim, int spacedim>
11251 void
11253 {
11254  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
11255  std::vector<bool> tmp;
11256 
11257  // first extract the flags
11258  // belonging to lines
11259  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
11260  // and set the lines
11261  load_user_flags_line(tmp);
11262 
11263  if (dim >= 2)
11264  {
11265  tmp.clear();
11266  tmp.insert(tmp.end(),
11267  v.begin() + n_lines(),
11268  v.begin() + n_lines() + n_quads());
11269  load_user_flags_quad(tmp);
11270  }
11271 
11272  if (dim >= 3)
11273  {
11274  tmp.clear();
11275  tmp.insert(tmp.end(),
11276  v.begin() + n_lines() + n_quads(),
11277  v.begin() + n_lines() + n_quads() + n_hexs());
11278  load_user_flags_hex(tmp);
11279  }
11280 
11281  if (dim >= 4)
11282  Assert(false, ExcNotImplemented());
11283 }
11284 
11285 
11286 
11287 template <int dim, int spacedim>
11288 void
11290 {
11291  v.resize(n_lines(), false);
11292  std::vector<bool>::iterator i = v.begin();
11293  line_iterator line = begin_line(), endl = end_line();
11294  for (; line != endl; ++line, ++i)
11295  *i = line->user_flag_set();
11296 
11297  Assert(i == v.end(), ExcInternalError());
11298 }
11299 
11300 
11301 
11302 template <int dim, int spacedim>
11303 void
11305 {
11306  std::vector<bool> v;
11307  save_user_flags_line(v);
11308  write_bool_vector(mn_tria_line_user_flags_begin,
11309  v,
11311  out);
11312 }
11313 
11314 
11315 
11316 template <int dim, int spacedim>
11317 void
11319 {
11320  std::vector<bool> v;
11321  read_bool_vector(mn_tria_line_user_flags_begin,
11322  v,
11324  in);
11325  load_user_flags_line(v);
11326 }
11327 
11328 
11329 
11330 template <int dim, int spacedim>
11331 void
11333 {
11334  Assert(v.size() == n_lines(), ExcGridReadError());
11335 
11336  line_iterator line = begin_line(), endl = end_line();
11337  std::vector<bool>::const_iterator i = v.begin();
11338  for (; line != endl; ++line, ++i)
11339  if (*i == true)
11340  line->set_user_flag();
11341  else
11342  line->clear_user_flag();
11343 
11344  Assert(i == v.end(), ExcInternalError());
11345 }
11346 
11347 
11348 namespace
11349 {
11350  template <typename Iterator>
11351  bool
11352  get_user_flag(const Iterator &i)
11353  {
11354  return i->user_flag_set();
11355  }
11356 
11357 
11358 
11359  template <int structdim, int dim, int spacedim>
11360  bool
11362  {
11363  Assert(false, ExcInternalError());
11364  return false;
11365  }
11366 
11367 
11368 
11369  template <typename Iterator>
11370  void
11371  set_user_flag(const Iterator &i)
11372  {
11373  i->set_user_flag();
11374  }
11375 
11376 
11377 
11378  template <int structdim, int dim, int spacedim>
11379  void
11381  {
11382  Assert(false, ExcInternalError());
11383  }
11384 
11385 
11386 
11387  template <typename Iterator>
11388  void
11389  clear_user_flag(const Iterator &i)
11390  {
11391  i->clear_user_flag();
11392  }
11393 
11394 
11395 
11396  template <int structdim, int dim, int spacedim>
11397  void
11398  clear_user_flag(
11400  {
11401  Assert(false, ExcInternalError());
11402  }
11403 } // namespace
11404 
11405 
11406 template <int dim, int spacedim>
11407 void
11409 {
11410  v.resize(n_quads(), false);
11411 
11412  if (dim >= 2)
11413  {
11414  std::vector<bool>::iterator i = v.begin();
11415  quad_iterator quad = begin_quad(), endq = end_quad();
11416  for (; quad != endq; ++quad, ++i)
11417  *i = get_user_flag(quad);
11418 
11419  Assert(i == v.end(), ExcInternalError());
11420  }
11421 }
11422 
11423 
11424 
11425 template <int dim, int spacedim>
11426 void
11428 {
11429  std::vector<bool> v;
11430  save_user_flags_quad(v);
11431  write_bool_vector(mn_tria_quad_user_flags_begin,
11432  v,
11434  out);
11435 }
11436 
11437 
11438 
11439 template <int dim, int spacedim>
11440 void
11442 {
11443  std::vector<bool> v;
11444  read_bool_vector(mn_tria_quad_user_flags_begin,
11445  v,
11447  in);
11448  load_user_flags_quad(v);
11449 }
11450 
11451 
11452 
11453 template <int dim, int spacedim>
11454 void
11456 {
11457  Assert(v.size() == n_quads(), ExcGridReadError());
11458 
11459  if (dim >= 2)
11460  {
11461  quad_iterator quad = begin_quad(), endq = end_quad();
11462  std::vector<bool>::const_iterator i = v.begin();
11463  for (; quad != endq; ++quad, ++i)
11464  if (*i == true)
11465  set_user_flag(quad);
11466  else
11467  clear_user_flag(quad);
11468 
11469  Assert(i == v.end(), ExcInternalError());
11470  }
11471 }
11472 
11473 
11474 
11475 template <int dim, int spacedim>
11476 void
11478 {
11479  v.resize(n_hexs(), false);
11480 
11481  if (dim >= 3)
11482  {
11483  std::vector<bool>::iterator i = v.begin();
11484  hex_iterator hex = begin_hex(), endh = end_hex();
11485  for (; hex != endh; ++hex, ++i)
11486  *i = get_user_flag(hex);
11487 
11488  Assert(i == v.end(), ExcInternalError());
11489  }
11490 }
11491 
11492 
11493 
11494 template <int dim, int spacedim>
11495 void
11497 {
11498  std::vector<bool> v;
11499  save_user_flags_hex(v);
11500  write_bool_vector(mn_tria_hex_user_flags_begin,
11501  v,
11503  out);
11504 }
11505 
11506 
11507 
11508 template <int dim, int spacedim>
11509 void
11511 {
11512  std::vector<bool> v;
11513  read_bool_vector(mn_tria_hex_user_flags_begin,
11514  v,
11516  in);
11517  load_user_flags_hex(v);
11518 }
11519 
11520 
11521 
11522 template <int dim, int spacedim>
11523 void
11525 {
11526  Assert(v.size() == n_hexs(), ExcGridReadError());
11527 
11528  if (dim >= 3)
11529  {
11530  hex_iterator hex = begin_hex(), endh = end_hex();
11531  std::vector<bool>::const_iterator i = v.begin();
11532  for (; hex != endh; ++hex, ++i)
11533  if (*i == true)
11534  set_user_flag(hex);
11535  else
11536  clear_user_flag(hex);
11537 
11538  Assert(i == v.end(), ExcInternalError());
11539  }
11540 }
11541 
11542 
11543 
11544 template <int dim, int spacedim>
11545 void
11547  std::vector<unsigned int> &v) const
11548 {
11549  // clear vector and append all the
11550  // stuff later on
11551  v.clear();
11552 
11553  std::vector<unsigned int> tmp;
11554 
11555  save_user_indices_line(tmp);
11556  v.insert(v.end(), tmp.begin(), tmp.end());
11557 
11558  if (dim >= 2)
11559  {
11560  save_user_indices_quad(tmp);
11561  v.insert(v.end(), tmp.begin(), tmp.end());
11562  }
11563 
11564  if (dim >= 3)
11565  {
11566  save_user_indices_hex(tmp);
11567  v.insert(v.end(), tmp.begin(), tmp.end());
11568  }
11569 
11570  if (dim >= 4)
11571  Assert(false, ExcNotImplemented());
11572 }
11573 
11574 
11575 
11576 template <int dim, int spacedim>
11577 void
11579  const std::vector<unsigned int> &v)
11580 {
11581  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
11582  std::vector<unsigned int> tmp;
11583 
11584  // first extract the indices
11585  // belonging to lines
11586  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
11587  // and set the lines
11588  load_user_indices_line(tmp);
11589 
11590  if (dim >= 2)
11591  {
11592  tmp.clear();
11593  tmp.insert(tmp.end(),
11594  v.begin() + n_lines(),
11595  v.begin() + n_lines() + n_quads());
11596  load_user_indices_quad(tmp);
11597  }
11598 
11599  if (dim >= 3)
11600  {
11601  tmp.clear();
11602  tmp.insert(tmp.end(),
11603  v.begin() + n_lines() + n_quads(),
11604  v.begin() + n_lines() + n_quads() + n_hexs());
11605  load_user_indices_hex(tmp);
11606  }
11607 
11608  if (dim >= 4)
11609  Assert(false, ExcNotImplemented());
11610 }
11611 
11612 
11613 
11614 namespace
11615 {
11616  template <typename Iterator>
11617  unsigned int
11618  get_user_index(const Iterator &i)
11619  {
11620  return i->user_index();
11621  }
11622 
11623 
11624 
11625  template <int structdim, int dim, int spacedim>
11626  unsigned int
11627  get_user_index(
11629  {
11630  Assert(false, ExcInternalError());
11632  }
11633 
11634 
11635 
11636  template <typename Iterator>
11637  void
11638  set_user_index(const Iterator &i, const unsigned int x)
11639  {
11640  i->set_user_index(x);
11641  }
11642 
11643 
11644 
11645  template <int structdim, int dim, int spacedim>
11646  void
11647  set_user_index(
11649  const unsigned int)
11650  {
11651  Assert(false, ExcInternalError());
11652  }
11653 } // namespace
11654 
11655 
11656 template <int dim, int spacedim>
11657 void
11659  std::vector<unsigned int> &v) const
11660 {
11661  v.resize(n_lines(), 0);
11662  std::vector<unsigned int>::iterator i = v.begin();
11663  line_iterator line = begin_line(), endl = end_line();
11664  for (; line != endl; ++line, ++i)
11665  *i = line->user_index();
11666 }
11667 
11668 
11669 
11670 template <int dim, int spacedim>
11671 void
11673  const std::vector<unsigned int> &v)
11674 {
11675  Assert(v.size() == n_lines(), ExcGridReadError());
11676 
11677  line_iterator line = begin_line(), endl = end_line();
11678  std::vector<unsigned int>::const_iterator i = v.begin();
11679  for (; line != endl; ++line, ++i)
11680  line->set_user_index(*i);
11681 }
11682 
11683 
11684 template <int dim, int spacedim>
11685 void
11687  std::vector<unsigned int> &v) const
11688 {
11689  v.resize(n_quads(), 0);
11690 
11691  if (dim >= 2)
11692  {
11693  std::vector<unsigned int>::iterator i = v.begin();
11694  quad_iterator quad = begin_quad(), endq = end_quad();
11695  for (; quad != endq; ++quad, ++i)
11696  *i = get_user_index(quad);
11697  }
11698 }
11699 
11700 
11701 
11702 template <int dim, int spacedim>
11703 void
11705  const std::vector<unsigned int> &v)
11706 {
11707  Assert(v.size() == n_quads(), ExcGridReadError());
11708 
11709  if (dim >= 2)
11710  {
11711  quad_iterator quad = begin_quad(), endq = end_quad();
11712  std::vector<unsigned int>::const_iterator i = v.begin();
11713  for (; quad != endq; ++quad, ++i)
11714  set_user_index(quad, *i);
11715  }
11716 }
11717 
11718 
11719 template <int dim, int spacedim>
11720 void
11722  std::vector<unsigned int> &v) const
11723 {
11724  v.resize(n_hexs(), 0);
11725 
11726  if (dim >= 3)
11727  {
11728  std::vector<unsigned int>::iterator i = v.begin();
11729  hex_iterator hex = begin_hex(), endh = end_hex();
11730  for (; hex != endh; ++hex, ++i)
11731  *i = get_user_index(hex);
11732  }
11733 }
11734 
11735 
11736 
11737 template <int dim, int spacedim>
11738 void
11740  const std::vector<unsigned int> &v)
11741 {
11742  Assert(v.size() == n_hexs(), ExcGridReadError());
11743 
11744  if (dim >= 3)
11745  {
11746  hex_iterator hex = begin_hex(), endh = end_hex();
11747  std::vector<unsigned int>::const_iterator i = v.begin();
11748  for (; hex != endh; ++hex, ++i)
11749  set_user_index(hex, *i);
11750  }
11751 }
11752 
11753 
11754 
11755 //---------------- user pointers ----------------------------------------//
11756 
11757 
11758 namespace
11759 {
11760  template <typename Iterator>
11761  void *
11762  get_user_pointer(const Iterator &i)
11763  {
11764  return i->user_pointer();
11765  }
11766 
11767 
11768 
11769  template <int structdim, int dim, int spacedim>
11770  void *
11771  get_user_pointer(
11773  {
11774  Assert(false, ExcInternalError());
11775  return nullptr;
11776  }
11777 
11778 
11779 
11780  template <typename Iterator>
11781  void
11782  set_user_pointer(const Iterator &i, void *x)
11783  {
11784  i->set_user_pointer(x);
11785  }
11786 
11787 
11788 
11789  template <int structdim, int dim, int spacedim>
11790  void
11791  set_user_pointer(
11793  void *)
11794  {
11795  Assert(false, ExcInternalError());
11796  }
11797 } // namespace
11798 
11799 
11800 template <int dim, int spacedim>
11801 void
11803 {
11804  // clear vector and append all the
11805  // stuff later on
11806  v.clear();
11807 
11808  std::vector<void *> tmp;
11809 
11810  save_user_pointers_line(tmp);
11811  v.insert(v.end(), tmp.begin(), tmp.end());
11812 
11813  if (dim >= 2)
11814  {
11815  save_user_pointers_quad(tmp);
11816  v.insert(v.end(), tmp.begin(), tmp.end());
11817  }
11818 
11819  if (dim >= 3)
11820  {
11821  save_user_pointers_hex(tmp);
11822  v.insert(v.end(), tmp.begin(), tmp.end());
11823  }
11824 
11825  if (dim >= 4)
11826  Assert(false, ExcNotImplemented());
11827 }
11828 
11829 
11830 
11831 template <int dim, int spacedim>
11832 void
11834 {
11835  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
11836  std::vector<void *> tmp;
11837 
11838  // first extract the pointers
11839  // belonging to lines
11840  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
11841  // and set the lines
11842  load_user_pointers_line(tmp);
11843 
11844  if (dim >= 2)
11845  {
11846  tmp.clear();
11847  tmp.insert(tmp.end(),
11848  v.begin() + n_lines(),
11849  v.begin() + n_lines() + n_quads());
11850  load_user_pointers_quad(tmp);
11851  }
11852 
11853  if (dim >= 3)
11854  {
11855  tmp.clear();
11856  tmp.insert(tmp.end(),
11857  v.begin() + n_lines() + n_quads(),
11858  v.begin() + n_lines() + n_quads() + n_hexs());
11859  load_user_pointers_hex(tmp);
11860  }
11861 
11862  if (dim >= 4)
11863  Assert(false, ExcNotImplemented());
11864 }
11865 
11866 
11867 
11868 template <int dim, int spacedim>
11869 void
11871  std::vector<void *> &v) const
11872 {
11873  v.resize(n_lines(), nullptr);
11874  std::vector<void *>::iterator i = v.begin();
11875  line_iterator line = begin_line(), endl = end_line();
11876  for (; line != endl; ++line, ++i)
11877  *i = line->user_pointer();
11878 }
11879 
11880 
11881 
11882 template <int dim, int spacedim>
11883 void
11885  const std::vector<void *> &v)
11886 {
11887  Assert(v.size() == n_lines(), ExcGridReadError());
11888 
11889  line_iterator line = begin_line(), endl = end_line();
11890  std::vector<void *>::const_iterator i = v.begin();
11891  for (; line != endl; ++line, ++i)
11892  line->set_user_pointer(*i);
11893 }
11894 
11895 
11896 
11897 template <int dim, int spacedim>
11898 void
11900  std::vector<void *> &v) const
11901 {
11902  v.resize(n_quads(), nullptr);
11903 
11904  if (dim >= 2)
11905  {
11906  std::vector<void *>::iterator i = v.begin();
11907  quad_iterator quad = begin_quad(), endq = end_quad();
11908  for (; quad != endq; ++quad, ++i)
11909  *i = get_user_pointer(quad);
11910  }
11911 }
11912 
11913 
11914 
11915 template <int dim, int spacedim>
11916 void
11918  const std::vector<void *> &v)
11919 {
11920  Assert(v.size() == n_quads(), ExcGridReadError());
11921 
11922  if (dim >= 2)
11923  {
11924  quad_iterator quad = begin_quad(), endq = end_quad();
11925  std::vector<void *>::const_iterator i = v.begin();
11926  for (; quad != endq; ++quad, ++i)
11927  set_user_pointer(quad, *i);
11928  }
11929 }
11930 
11931 
11932 template <int dim, int spacedim>
11933 void
11935  std::vector<void *> &v) const
11936 {
11937  v.resize(n_hexs(), nullptr);
11938 
11939  if (dim >= 3)
11940  {
11941  std::vector<void *>::iterator i = v.begin();
11942  hex_iterator hex = begin_hex(), endh = end_hex();
11943  for (; hex != endh; ++hex, ++i)
11944  *i = get_user_pointer(hex);
11945  }
11946 }
11947 
11948 
11949 
11950 template <int dim, int spacedim>
11951 void
11953  const std::vector<void *> &v)
11954 {
11955  Assert(v.size() == n_hexs(), ExcGridReadError());
11956 
11957  if (dim >= 3)
11958  {
11959  hex_iterator hex = begin_hex(), endh = end_hex();
11960  std::vector<void *>::const_iterator i = v.begin();
11961  for (; hex != endh; ++hex, ++i)
11962  set_user_pointer(hex, *i);
11963  }
11964 }
11965 
11966 
11967 
11968 /*------------------------ Cell iterator functions ------------------------*/
11969 
11970 
11971 template <int dim, int spacedim>
11974 {
11975  switch (dim)
11976  {
11977  case 1:
11978  return begin_raw_line(level);
11979  case 2:
11980  return begin_raw_quad(level);
11981  case 3:
11982  return begin_raw_hex(level);
11983  default:
11984  Assert(false, ExcNotImplemented());
11985  return raw_cell_iterator();
11986  }
11987 }
11988 
11989 
11990 
11991 template <int dim, int spacedim>
11994 {
11995  switch (dim)
11996  {
11997  case 1:
11998  return begin_line(level);
11999  case 2:
12000  return begin_quad(level);
12001  case 3:
12002  return begin_hex(level);
12003  default:
12004  Assert(false, ExcImpossibleInDim(dim));
12005  return cell_iterator();
12006  }
12007 }
12008 
12009 
12010 
12011 template <int dim, int spacedim>
12014 {
12015  switch (dim)
12016  {
12017  case 1:
12018  return begin_active_line(level);
12019  case 2:
12020  return begin_active_quad(level);
12021  case 3:
12022  return begin_active_hex(level);
12023  default:
12024  Assert(false, ExcNotImplemented());
12025  return active_cell_iterator();
12026  }
12027 }
12028 
12029 
12030 
12031 template <int dim, int spacedim>
12034 {
12035  const unsigned int level = levels.size() - 1;
12036  if (levels[level]->cells.cells.size() == 0)
12037  return end(level);
12038 
12039  // find the last raw iterator on
12040  // this level
12041  raw_cell_iterator ri(const_cast<Triangulation<dim, spacedim> *>(this),
12042  level,
12043  levels[level]->cells.cells.size() - 1);
12044 
12045  // then move to the last used one
12046  if (ri->used() == true)
12047  return ri;
12048  while ((--ri).state() == IteratorState::valid)
12049  if (ri->used() == true)
12050  return ri;
12051  return ri;
12052 }
12053 
12054 
12055 
12056 template <int dim, int spacedim>
12059 {
12060  // get the last used cell
12061  cell_iterator cell = last();
12062 
12063  if (cell != end())
12064  {
12065  // then move to the last active one
12066  if (cell->is_active() == true)
12067  return cell;
12068  while ((--cell).state() == IteratorState::valid)
12069  if (cell->is_active() == true)
12070  return cell;
12071  }
12072  return cell;
12073 }
12074 
12075 
12076 
12077 template <int dim, int spacedim>
12080 {
12081  return cell_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12082  -1,
12083  -1);
12084 }
12085 
12086 
12087 
12088 template <int dim, int spacedim>
12091 {
12092  // This function may be called on parallel triangulations on levels
12093  // that exist globally, but not on the local portion of the
12094  // triangulation. In that case, just return the end iterator.
12095  //
12096  // We need to use levels.size() instead of n_levels() because the
12097  // latter function uses the cache, but we need to be able to call
12098  // this function at a time when the cache is not currently up to
12099  // date.
12100  if (level >= levels.size())
12101  {
12102  Assert(level < n_global_levels(),
12103  ExcInvalidLevel(level, n_global_levels()));
12104  return end();
12105  }
12106 
12107  // Query whether the given level is valid for the local portion of the
12108  // triangulation.
12109  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12110  if (level < levels.size() - 1)
12111  return begin_raw(level + 1);
12112  else
12113  return end();
12114 }
12115 
12116 
12117 template <int dim, int spacedim>
12119 Triangulation<dim, spacedim>::end(const unsigned int level) const
12120 {
12121  // This function may be called on parallel triangulations on levels
12122  // that exist globally, but not on the local portion of the
12123  // triangulation. In that case, just retrn the end iterator.
12124  //
12125  // We need to use levels.size() instead of n_levels() because the
12126  // latter function uses the cache, but we need to be able to call
12127  // this function at a time when the cache is not currently up to
12128  // date.
12129  if (level >= levels.size())
12130  {
12131  Assert(level < n_global_levels(),
12132  ExcInvalidLevel(level, n_global_levels()));
12133  return end();
12134  }
12135 
12136  // Query whether the given level is valid for the local portion of the
12137  // triangulation.
12138  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12139  if (level < levels.size() - 1)
12140  return begin(level + 1);
12141  else
12142  return end();
12143 }
12144 
12145 
12146 template <int dim, int spacedim>
12149 {
12150  // This function may be called on parallel triangulations on levels
12151  // that exist globally, but not on the local portion of the
12152  // triangulation. In that case, just return the end iterator.
12153  //
12154  // We need to use levels.size() instead of n_levels() because the
12155  // latter function uses the cache, but we need to be able to call
12156  // this function at a time when the cache is not currently up to
12157  // date.
12158  if (level >= levels.size())
12159  {
12160  Assert(level < n_global_levels(),
12161  ExcInvalidLevel(level, n_global_levels()));
12162  return end();
12163  }
12164 
12165  // Query whether the given level is valid for the local portion of the
12166  // triangulation.
12167  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12168  return (level >= levels.size() - 1 ? active_cell_iterator(end()) :
12169  begin_active(level + 1));
12170 }
12171 
12172 
12173 
12174 template <int dim, int spacedim>
12177 {
12179  begin(), end());
12180 }
12181 
12182 
12183 template <int dim, int spacedim>
12186 {
12187  return IteratorRange<
12188  typename Triangulation<dim, spacedim>::active_cell_iterator>(begin_active(),
12189  end());
12190 }
12191 
12192 
12193 
12194 template <int dim, int spacedim>
12197  const unsigned int level) const
12198 {
12200  begin(level), end(level));
12201 }
12202 
12203 
12204 
12205 template <int dim, int spacedim>
12208  const unsigned int level) const
12209 {
12210  return IteratorRange<
12212  begin_active(level), end_active(level));
12213 }
12214 
12215 
12216 /*------------------------ Face iterator functions ------------------------*/
12217 
12218 
12219 template <int dim, int spacedim>
12222 {
12223  switch (dim)
12224  {
12225  case 1:
12226  Assert(false, ExcImpossibleInDim(1));
12227  return raw_face_iterator();
12228  case 2:
12229  return begin_line();
12230  case 3:
12231  return begin_quad();
12232  default:
12233  Assert(false, ExcNotImplemented());
12234  return face_iterator();
12235  }
12236 }
12237 
12238 
12239 
12240 template <int dim, int spacedim>
12243 {
12244  switch (dim)
12245  {
12246  case 1:
12247  Assert(false, ExcImpossibleInDim(1));
12248  return raw_face_iterator();
12249  case 2:
12250  return begin_active_line();
12251  case 3:
12252  return begin_active_quad();
12253  default:
12254  Assert(false, ExcNotImplemented());
12255  return active_face_iterator();
12256  }
12257 }
12258 
12259 
12260 
12261 template <int dim, int spacedim>
12264 {
12265  switch (dim)
12266  {
12267  case 1:
12268  Assert(false, ExcImpossibleInDim(1));
12269  return raw_face_iterator();
12270  case 2:
12271  return end_line();
12272  case 3:
12273  return end_quad();
12274  default:
12275  Assert(false, ExcNotImplemented());
12276  return raw_face_iterator();
12277  }
12278 }
12279 
12280 
12281 
12282 template <int dim, int spacedim>
12285 {
12286  return IteratorRange<
12288  begin_active_face(), end_face());
12289 }
12290 
12291 /*------------------------ Vertex iterator functions ------------------------*/
12292 
12293 
12294 template <int dim, int spacedim>
12297 {
12298  vertex_iterator i =
12299  raw_vertex_iterator(const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
12300  if (i.state() != IteratorState::valid)
12301  return i;
12302  // This loop will end because every triangulation has used vertices.
12303  while (i->used() == false)
12304  if ((++i).state() != IteratorState::valid)
12305  return i;
12306  return i;
12307 }
12308 
12309 
12310 
12311 template <int dim, int spacedim>
12314 {
12315  // every vertex is active
12316  return begin_vertex();
12317 }
12318 
12319 
12320 
12321 template <int dim, int spacedim>
12324 {
12325  return raw_vertex_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12326  -1,
12328 }
12329 
12330 
12331 
12332 /*------------------------ Line iterator functions ------------------------*/
12333 
12334 
12335 
12336 template <int dim, int spacedim>
12339 {
12340  // This function may be called on parallel triangulations on levels
12341  // that exist globally, but not on the local portion of the
12342  // triangulation. In that case, just return the end iterator.
12343  //
12344  // We need to use levels.size() instead of n_levels() because the
12345  // latter function uses the cache, but we need to be able to call
12346  // this function at a time when the cache is not currently up to
12347  // date.
12348  if (level >= levels.size())
12349  {
12350  Assert(level < n_global_levels(),
12351  ExcInvalidLevel(level, n_global_levels()));
12352  return end_line();
12353  }
12354 
12355  switch (dim)
12356  {
12357  case 1:
12358  // Query whether the given level is valid for the local portion of the
12359  // triangulation.
12360  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12361 
12362  if (level >= levels.size() || levels[level]->cells.cells.size() == 0)
12363  return end_line();
12364 
12365  return raw_line_iterator(
12366  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
12367 
12368  default:
12369  Assert(level == 0, ExcFacesHaveNoLevel());
12370  return raw_line_iterator(
12371  const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
12372  }
12373 }
12374 
12375 
12376 template <int dim, int spacedim>
12379 {
12380  // level is checked in begin_raw
12381  raw_line_iterator ri = begin_raw_line(level);
12382  if (ri.state() != IteratorState::valid)
12383  return ri;
12384  while (ri->used() == false)
12385  if ((++ri).state() != IteratorState::valid)
12386  return ri;
12387  return ri;
12388 }
12389 
12390 
12391 
12392 template <int dim, int spacedim>
12395 {
12396  // level is checked in begin_raw
12397  line_iterator i = begin_line(level);
12398  if (i.state() != IteratorState::valid)
12399  return i;
12400  while (i->has_children())
12401  if ((++i).state() != IteratorState::valid)
12402  return i;
12403  return i;
12404 }
12405 
12406 
12407 
12408 template <int dim, int spacedim>
12411 {
12412  return raw_line_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12413  -1,
12414  -1);
12415 }
12416 
12417 
12418 
12419 /*------------------------ Quad iterator functions ------------------------*/
12420 
12421 
12422 template <int dim, int spacedim>
12425 {
12426  // This function may be called on parallel triangulations on levels
12427  // that exist globally, but not on the local portion of the
12428  // triangulation. In that case, just return the end iterator.
12429  //
12430  // We need to use levels.size() instead of n_levels() because the
12431  // latter function uses the cache, but we need to be able to call
12432  // this function at a time when the cache is not currently up to
12433  // date.
12434  if (level >= levels.size())
12435  {
12436  Assert(level < n_global_levels(),
12437  ExcInvalidLevel(level, n_global_levels()));
12438  return end_quad();
12439  }
12440 
12441  switch (dim)
12442  {
12443  case 1:
12444  Assert(false, ExcImpossibleInDim(1));
12445  return raw_hex_iterator();
12446  case 2:
12447  {
12448  // Query whether the given level is valid for the local portion of the
12449  // triangulation.
12450  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12451 
12452  if (level >= levels.size() || levels[level]->cells.cells.size() == 0)
12453  return end_quad();
12454 
12455  return raw_quad_iterator(
12456  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
12457  }
12458 
12459  case 3:
12460  {
12461  Assert(level == 0, ExcFacesHaveNoLevel());
12462 
12463  return raw_quad_iterator(
12464  const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
12465  }
12466 
12467 
12468  default:
12469  Assert(false, ExcNotImplemented());
12470  return raw_hex_iterator();
12471  }
12472 }
12473 
12474 
12475 
12476 template <int dim, int spacedim>
12479 {
12480  // level is checked in begin_raw
12481  raw_quad_iterator ri = begin_raw_quad(level);
12482  if (ri.state() != IteratorState::valid)
12483  return ri;
12484  while (ri->used() == false)
12485  if ((++ri).state() != IteratorState::valid)
12486  return ri;
12487  return ri;
12488 }
12489 
12490 
12491 
12492 template <int dim, int spacedim>
12495 {
12496  // level is checked in begin_raw
12497  quad_iterator i = begin_quad(level);
12498  if (i.state() != IteratorState::valid)
12499  return i;
12500  while (i->has_children())
12501  if ((++i).state() != IteratorState::valid)
12502  return i;
12503  return i;
12504 }
12505 
12506 
12507 
12508 template <int dim, int spacedim>
12511 {
12512  return raw_quad_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12513  -1,
12514  -1);
12515 }
12516 
12517 
12518 /*------------------------ Hex iterator functions ------------------------*/
12519 
12520 
12521 template <int dim, int spacedim>
12524 {
12525  // This function may be called on parallel triangulations on levels
12526  // that exist globally, but not on the local portion of the
12527  // triangulation. In that case, just return the end iterator.
12528  //
12529  // We need to use levels.size() instead of n_levels() because the
12530  // latter function uses the cache, but we need to be able to call
12531  // this function at a time when the cache is not currently up to
12532  // date.
12533  if (level >= levels.size())
12534  {
12535  Assert(level < n_global_levels(),
12536  ExcInvalidLevel(level, n_global_levels()));
12537  return end_hex();
12538  }
12539 
12540  switch (dim)
12541  {
12542  case 1:
12543  case 2:
12544  Assert(false, ExcImpossibleInDim(1));
12545  return raw_hex_iterator();
12546  case 3:
12547  {
12548  // Query whether the given level is valid for the local portion of the
12549  // triangulation.
12550  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12551 
12552  if (level >= levels.size() || levels[level]->cells.cells.size() == 0)
12553  return end_hex();
12554 
12555  return raw_hex_iterator(
12556  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
12557  }
12558 
12559  default:
12560  Assert(false, ExcNotImplemented());
12561  return raw_hex_iterator();
12562  }
12563 }
12564 
12565 
12566 
12567 template <int dim, int spacedim>
12570 {
12571  // level is checked in begin_raw
12572  raw_hex_iterator ri = begin_raw_hex(level);
12573  if (ri.state() != IteratorState::valid)
12574  return ri;
12575  while (ri->used() == false)
12576  if ((++ri).state() != IteratorState::valid)
12577  return ri;
12578  return ri;
12579 }
12580 
12581 
12582 
12583 template <int dim, int spacedim>
12586 {
12587  // level is checked in begin_raw
12588  hex_iterator i = begin_hex(level);
12589  if (i.state() != IteratorState::valid)
12590  return i;
12591  while (i->has_children())
12592  if ((++i).state() != IteratorState::valid)
12593  return i;
12594  return i;
12595 }
12596 
12597 
12598 
12599 template <int dim, int spacedim>
12602 {
12603  return raw_hex_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12604  -1,
12605  -1);
12606 }
12607 
12608 
12609 
12610 // -------------------------------- number of cells etc ---------------
12611 
12612 
12613 namespace internal
12614 {
12615  namespace TriangulationImplementation
12616  {
12617  inline unsigned int
12619  {
12620  return c.n_lines;
12621  }
12622 
12623 
12624  inline unsigned int
12627  {
12628  return c.n_active_lines;
12629  }
12630 
12631 
12632  inline unsigned int
12634  {
12635  return c.n_quads;
12636  }
12637 
12638 
12639  inline unsigned int
12642  {
12643  return c.n_active_quads;
12644  }
12645 
12646 
12647  inline unsigned int
12649  {
12650  return c.n_hexes;
12651  }
12652 
12653 
12654  inline unsigned int
12657  {
12658  return c.n_active_hexes;
12659  }
12660  } // namespace TriangulationImplementation
12661 } // namespace internal
12662 
12663 
12664 
12665 template <int dim, int spacedim>
12666 unsigned int
12668 {
12670 }
12671 
12672 
12673 template <int dim, int spacedim>
12674 unsigned int
12676 {
12678 }
12679 
12680 template <int dim, int spacedim>
12683 {
12684  return n_active_cells();
12685 }
12686 
12687 
12688 
12689 template <int dim, int spacedim>
12690 unsigned int
12692 {
12693  switch (dim)
12694  {
12695  case 1:
12696  return n_used_vertices();
12697  case 2:
12698  return n_lines();
12699  case 3:
12700  return n_quads();
12701  default:
12702  Assert(false, ExcNotImplemented());
12703  }
12704  return 0;
12705 }
12706 
12707 
12708 template <int dim, int spacedim>
12709 unsigned int
12711 {
12712  switch (dim)
12713  {
12714  case 1:
12715  return n_vertices();
12716  case 2:
12717  return n_raw_lines();
12718  case 3:
12719  return n_raw_quads();
12720  default:
12721  Assert(false, ExcNotImplemented());
12722  }
12723  return 0;
12724 }
12725 
12726 
12727 template <int dim, int spacedim>
12728 unsigned int
12730 {
12731  switch (dim)
12732  {
12733  case 1:
12734  return n_used_vertices();
12735  case 2:
12736  return n_active_lines();
12737  case 3:
12738  return n_active_quads();
12739  default:
12740  Assert(false, ExcNotImplemented());
12741  }
12742  return 0;
12743 }
12744 
12745 
12746 template <int dim, int spacedim>
12747 unsigned int
12749 {
12750  switch (dim)
12751  {
12752  case 1:
12753  return n_raw_lines(level);
12754  case 2:
12755  return n_raw_quads(level);
12756  case 3:
12757  return n_raw_hexs(level);
12758  default:
12759  Assert(false, ExcNotImplemented());
12760  }
12761  return 0;
12762 }
12763 
12764 
12765 
12766 template <int dim, int spacedim>
12767 unsigned int
12769 {
12770  switch (dim)
12771  {
12772  case 1:
12773  return n_lines(level);
12774  case 2:
12775  return n_quads(level);
12776  case 3:
12777  return n_hexs(level);
12778  default:
12779  Assert(false, ExcNotImplemented());
12780  }
12781  return 0;
12782 }
12783 
12784 
12785 
12786 template <int dim, int spacedim>
12787 unsigned int
12789 {
12790  switch (dim)
12791  {
12792  case 1:
12793  return n_active_lines(level);
12794  case 2:
12795  return n_active_quads(level);
12796  case 3:
12797  return n_active_hexs(level);
12798  default:
12799  Assert(false, ExcNotImplemented());
12800  }
12801  return 0;
12802 }
12803 
12804 
12805 template <int dim, int spacedim>
12806 bool
12808 {
12809  for (unsigned int lvl = 0; lvl < n_global_levels() - 1; lvl++)
12810  if (n_active_cells(lvl) != 0)
12811  return true;
12812 
12813  return false;
12814 }
12815 
12816 
12817 template <int dim, int spacedim>
12818 unsigned int
12820 {
12821  return number_cache.n_lines;
12822 }
12823 
12824 
12825 // TODO: Merge the following 6 functions somehow
12826 template <>
12827 unsigned int
12828 Triangulation<1, 1>::n_raw_lines(const unsigned int level) const
12829 {
12830  AssertIndexRange(level, n_levels());
12831  return levels[level]->cells.cells.size();
12832 }
12833 
12834 
12835 template <>
12836 unsigned int
12838 {
12839  Assert(false, ExcNotImplemented());
12840  return 0;
12841 }
12842 
12843 
12844 
12845 template <>
12846 unsigned int
12847 Triangulation<1, 2>::n_raw_lines(const unsigned int level) const
12848 {
12849  AssertIndexRange(level, n_levels());
12850  return levels[level]->cells.cells.size();
12851 }
12852 
12853 
12854 template <>
12855 unsigned int
12857 {
12858  Assert(false, ExcNotImplemented());
12859  return 0;
12860 }
12861 
12862 
12863 template <>
12864 unsigned int
12865 Triangulation<1, 3>::n_raw_lines(const unsigned int level) const
12866 {
12867  AssertIndexRange(level, n_levels());
12868  return levels[level]->cells.cells.size();
12869 }
12870 
12871 template <>
12872 unsigned int
12874 {
12875  Assert(false, ExcNotImplemented());
12876  return 0;
12877 }
12878 
12879 
12880 
12881 template <int dim, int spacedim>
12882 unsigned int
12884 {
12885  Assert(false, ExcFacesHaveNoLevel());
12886  return 0;
12887 }
12888 
12889 
12890 template <int dim, int spacedim>
12891 unsigned int
12893 {
12894  return faces->lines.cells.size();
12895 }
12896 
12897 
12898 template <int dim, int spacedim>
12899 unsigned int
12901 {
12902  AssertIndexRange(level, number_cache.n_lines_level.size());
12903  Assert(dim == 1, ExcFacesHaveNoLevel());
12904  return number_cache.n_lines_level[level];
12905 }
12906 
12907 
12908 template <int dim, int spacedim>
12909 unsigned int
12911 {
12912  return number_cache.n_active_lines;
12913 }
12914 
12915 
12916 template <int dim, int spacedim>
12917 unsigned int
12919 {
12920  AssertIndexRange(level, number_cache.n_lines_level.size());
12921  Assert(dim == 1, ExcFacesHaveNoLevel());
12922 
12923  return number_cache.n_active_lines_level[level];
12924 }
12925 
12926 
12927 template <>
12928 unsigned int
12930 {
12931  return 0;
12932 }
12933 
12934 
12935 template <>
12936 unsigned int
12937 Triangulation<1, 1>::n_quads(const unsigned int) const
12938 {
12939  return 0;
12940 }
12941 
12942 
12943 template <>
12944 unsigned int
12945 Triangulation<1, 1>::n_raw_quads(const unsigned int) const
12946 {
12947  return 0;
12948 }
12949 
12950 
12951 template <>
12952 unsigned int
12953 Triangulation<1, 1>::n_raw_hexs(const unsigned int) const
12954 {
12955  return 0;
12956 }
12957 
12958 
12959 template <>
12960 unsigned int
12961 Triangulation<1, 1>::n_active_quads(const unsigned int) const
12962 {
12963  return 0;
12964 }
12965 
12966 
12967 template <>
12968 unsigned int
12970 {
12971  return 0;
12972 }
12973 
12974 
12975 
12976 template <>
12977 unsigned int
12979 {
12980  return 0;
12981 }
12982 
12983 
12984 template <>
12985 unsigned int
12986 Triangulation<1, 2>::n_quads(const unsigned int) const
12987 {
12988  return 0;
12989 }
12990 
12991 
12992 template <>
12993 unsigned int
12994 Triangulation<1, 2>::n_raw_quads(const unsigned int) const
12995 {
12996  return 0;
12997 }
12998 
12999 
13000 template <>
13001 unsigned int
13002 Triangulation<1, 2>::n_raw_hexs(const unsigned int) const
13003 {
13004  return 0;
13005 }
13006 
13007 
13008 template <>
13009 unsigned int
13010 Triangulation<1, 2>::n_active_quads(const unsigned int) const
13011 {
13012  return 0;
13013 }
13014 
13015 
13016 template <>
13017 unsigned int
13019 {
13020  return 0;
13021 }
13022 
13023 
13024 template <>
13025 unsigned int
13027 {
13028  return 0;
13029 }
13030 
13031 
13032 template <>
13033 unsigned int
13034 Triangulation<1, 3>::n_quads(const unsigned int) const
13035 {
13036  return 0;
13037 }
13038 
13039 
13040 template <>
13041 unsigned int
13042 Triangulation<1, 3>::n_raw_quads(const unsigned int) const
13043 {
13044  return 0;
13045 }
13046 
13047 
13048 template <>
13049 unsigned int
13050 Triangulation<1, 3>::n_raw_hexs(const unsigned int) const
13051 {
13052  return 0;
13053 }
13054 
13055 
13056 template <>
13057 unsigned int
13058 Triangulation<1, 3>::n_active_quads(const unsigned int) const
13059 {
13060  return 0;
13061 }
13062 
13063 
13064 template <>
13065 unsigned int
13067 {
13068  return 0;
13069 }
13070 
13071 
13072 
13073 template <int dim, int spacedim>
13074 unsigned int
13076 {
13077  return number_cache.n_quads;
13078 }
13079 
13080 
13081 template <int dim, int spacedim>
13082 unsigned int
13084 {
13085  Assert(dim == 2, ExcFacesHaveNoLevel());
13086  AssertIndexRange(level, number_cache.n_quads_level.size());
13087  return number_cache.n_quads_level[level];
13088 }
13089 
13090 
13091 
13092 template <>
13093 unsigned int
13094 Triangulation<2, 2>::n_raw_quads(const unsigned int level) const
13095 {
13096  AssertIndexRange(level, n_levels());
13097  return levels[level]->cells.cells.size();
13098 }
13099 
13100 
13101 
13102 template <>
13103 unsigned int
13104 Triangulation<2, 3>::n_raw_quads(const unsigned int level) const
13105 {
13106  AssertIndexRange(level, n_levels());
13107  return levels[level]->cells.cells.size();
13108 }
13109 
13110 
13111 template <>
13112 unsigned int
13113 Triangulation<3, 3>::n_raw_quads(const unsigned int) const
13114 {
13115  Assert(false, ExcFacesHaveNoLevel());
13116  return 0;
13117 }
13118 
13119 
13120 
13121 template <int dim, int spacedim>
13122 unsigned int
13124 {
13125  Assert(false, ExcNotImplemented());
13126  return 0;
13127 }
13128 
13129 
13130 
13131 template <>
13132 unsigned int
13134 {
13135  return faces->quads.cells.size();
13136 }
13137 
13138 
13139 
13140 template <int dim, int spacedim>
13141 unsigned int
13143 {
13144  return number_cache.n_active_quads;
13145 }
13146 
13147 
13148 template <int dim, int spacedim>
13149 unsigned int
13151 {
13152  AssertIndexRange(level, number_cache.n_quads_level.size());
13153  Assert(dim == 2, ExcFacesHaveNoLevel());
13154 
13155  return number_cache.n_active_quads_level[level];
13156 }
13157 
13158 
13159 template <int dim, int spacedim>
13160 unsigned int
13162 {
13163  return 0;
13164 }
13165 
13166 
13167 
13168 template <int dim, int spacedim>
13169 unsigned int
13170 Triangulation<dim, spacedim>::n_hexs(const unsigned int) const
13171 {
13172  return 0;
13173 }
13174 
13175 
13176 
13177 template <int dim, int spacedim>
13178 unsigned int
13180 {
13181  return 0;
13182 }
13183 
13184 
13185 template <int dim, int spacedim>
13186 unsigned int
13188 {
13189  return 0;
13190 }
13191 
13192 
13193 
13194 template <int dim, int spacedim>
13195 unsigned int
13197 {
13198  return 0;
13199 }
13200 
13201 
13202 template <>
13203 unsigned int
13205 {
13206  return number_cache.n_hexes;
13207 }
13208 
13209 
13210 
13211 template <>
13212 unsigned int
13213 Triangulation<3, 3>::n_hexs(const unsigned int level) const
13214 {
13215  AssertIndexRange(level, number_cache.n_hexes_level.size());
13216 
13217  return number_cache.n_hexes_level[level];
13218 }
13219 
13220 
13221 
13222 template <>
13223 unsigned int
13224 Triangulation<3, 3>::n_raw_hexs(const unsigned int level) const
13225 {
13226  AssertIndexRange(level, n_levels());
13227  return levels[level]->cells.cells.size();
13228 }
13229 
13230 
13231 template <>
13232 unsigned int
13234 {
13235  return number_cache.n_active_hexes;
13236 }
13237 
13238 
13239 
13240 template <>
13241 unsigned int
13243 {
13244  AssertIndexRange(level, number_cache.n_hexes_level.size());
13245 
13246  return number_cache.n_active_hexes_level[level];
13247 }
13248 
13249 
13250 
13251 template <int dim, int spacedim>
13252 unsigned int
13254 {
13255  return std::count(vertices_used.begin(), vertices_used.end(), true);
13256 }
13257 
13258 
13259 
13260 template <int dim, int spacedim>
13261 const std::vector<bool> &
13263 {
13264  return vertices_used;
13265 }
13266 
13267 
13268 
13269 template <>
13270 unsigned int
13272 {
13273  return 2;
13274 }
13275 
13276 
13277 
13278 template <>
13279 unsigned int
13281 {
13282  return 2;
13283 }
13284 
13285 
13286 template <>
13287 unsigned int
13289 {
13290  return 2;
13291 }
13292 
13293 
13294 template <int dim, int spacedim>
13295 unsigned int
13297 {
13298  cell_iterator cell = begin(0),
13299  endc = (n_levels() > 1 ? begin(1) : cell_iterator(end()));
13300  // store the largest index of the
13301  // vertices used on level 0
13302  unsigned int max_vertex_index = 0;
13303  for (; cell != endc; ++cell)
13304  for (const unsigned int vertex : GeometryInfo<dim>::vertex_indices())
13305  if (cell->vertex_index(vertex) > max_vertex_index)
13306  max_vertex_index = cell->vertex_index(vertex);
13307 
13308  // store the number of times a cell
13309  // touches a vertex. An unsigned
13310  // int should suffice, even for
13311  // larger dimensions
13312  std::vector<unsigned short int> usage_count(max_vertex_index + 1, 0);
13313  // touch a vertex's usage count
13314  // every time we find an adjacent
13315  // element
13316  for (cell = begin(); cell != endc; ++cell)
13317  for (const unsigned int vertex : GeometryInfo<dim>::vertex_indices())
13318  ++usage_count[cell->vertex_index(vertex)];
13319 
13321  static_cast<unsigned int>(
13322  *std::max_element(usage_count.begin(), usage_count.end())));
13323 }
13324 
13325 
13326 
13327 template <int dim, int spacedim>
13330 {
13332 }
13333 
13334 
13335 
13336 template <int dim, int spacedim>
13339 {
13340  return *this;
13341 }
13342 
13343 
13344 
13345 template <int dim, int spacedim>
13348 {
13349  return *this;
13350 }
13351 
13352 
13353 
13354 template <int dim, int spacedim>
13355 void
13358  &periodicity_vector)
13359 {
13360  periodic_face_pairs_level_0.insert(periodic_face_pairs_level_0.end(),
13361  periodicity_vector.begin(),
13362  periodicity_vector.end());
13363 
13364  // Now initialize periodic_face_map
13365  update_periodic_face_map();
13366 }
13367 
13368 
13369 
13370 template <int dim, int spacedim>
13371 const typename std::map<
13372  std::pair<typename Triangulation<dim, spacedim>::cell_iterator, unsigned int>,
13373  std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
13374  unsigned int>,
13375  std::bitset<3>>> &
13377 {
13378  return periodic_face_map;
13379 }
13380 
13381 
13382 
13383 template <int dim, int spacedim>
13384 void
13386 {
13387  prepare_coarsening_and_refinement();
13388 
13389  // verify a case with which we have had
13390  // some difficulty in the past (see the
13391  // deal.II/coarsening_* tests)
13392  if (smooth_grid & limit_level_difference_at_vertices)
13393  Assert(satisfies_level1_at_vertex_rule(*this) == true, ExcInternalError());
13394 
13395  // Inform all listeners about beginning of refinement.
13396  signals.pre_refinement();
13397 
13398  execute_coarsening();
13399 
13400  const DistortedCellList cells_with_distorted_children = execute_refinement();
13401 
13402  // verify a case with which we have had
13403  // some difficulty in the past (see the
13404  // deal.II/coarsening_* tests)
13405  if (smooth_grid & limit_level_difference_at_vertices)
13406  Assert(satisfies_level1_at_vertex_rule(*this) == true, ExcInternalError());
13407 
13408  // finally build up neighbor connectivity information, and set
13409  // active cell indices
13410  update_neighbors(*this);
13411  reset_active_cell_indices();
13412 
13413  // Inform all listeners about end of refinement.
13414  signals.post_refinement();
13415 
13416  AssertThrow(cells_with_distorted_children.distorted_cells.size() == 0,
13417  cells_with_distorted_children);
13418 
13419  update_periodic_face_map();
13420 }
13421 
13422 
13423 
13424 template <int dim, int spacedim>
13425 void
13427 {
13428  unsigned int active_cell_index = 0;
13429  for (raw_cell_iterator cell = begin_raw(); cell != end(); ++cell)
13430  if ((cell->used() == false) || cell->has_children())
13431  cell->set_active_cell_index(numbers::invalid_unsigned_int);
13432  else
13433  {
13434  cell->set_active_cell_index(active_cell_index);
13435  ++active_cell_index;
13436  }
13437 
13438  Assert(active_cell_index == n_active_cells(), ExcInternalError());
13439 }
13440 
13441 
13442 template <int dim, int spacedim>
13443 void
13445 {
13446  // first empty the currently stored objects
13447  periodic_face_map.clear();
13448 
13449  typename std::vector<
13450  GridTools::PeriodicFacePair<cell_iterator>>::const_iterator it;
13451  for (it = periodic_face_pairs_level_0.begin();
13452  it != periodic_face_pairs_level_0.end();
13453  ++it)
13454  {
13455  update_periodic_face_map_recursively<dim, spacedim>(it->cell[0],
13456  it->cell[1],
13457  it->face_idx[0],
13458  it->face_idx[1],
13459  it->orientation,
13460  periodic_face_map);
13461 
13462  // for the other way, we need to invert the orientation
13463  std::bitset<3> inverted_orientation;
13464  {
13465  bool orientation, flip, rotation;
13466  orientation = it->orientation[0];
13467  rotation = it->orientation[2];
13468  flip = orientation ? rotation ^ it->orientation[1] : it->orientation[1];
13469  inverted_orientation[0] = orientation;
13470  inverted_orientation[1] = flip;
13471  inverted_orientation[2] = rotation;
13472  }
13473  update_periodic_face_map_recursively<dim, spacedim>(it->cell[1],
13474  it->cell[0],
13475  it->face_idx[1],
13476  it->face_idx[0],
13477  inverted_orientation,
13478  periodic_face_map);
13479  }
13480 
13481  // check consistency
13482  typename std::map<std::pair<cell_iterator, unsigned int>,
13483  std::pair<std::pair<cell_iterator, unsigned int>,
13484  std::bitset<3>>>::const_iterator it_test;
13485  for (it_test = periodic_face_map.begin(); it_test != periodic_face_map.end();
13486  ++it_test)
13487  {
13489  it_test->first.first;
13491  it_test->second.first.first;
13492  if (cell_1->level() == cell_2->level())
13493  {
13494  // if both cells have the same neighbor, then the same pair
13495  // order swapped has to be in the map
13496  Assert(periodic_face_map[it_test->second.first].first ==
13497  it_test->first,
13498  ExcInternalError());
13499  }
13500  }
13501 }
13502 
13503 
13504 
13505 template <int dim, int spacedim>
13506 void
13508 {
13509  levels.clear();
13510  faces.reset();
13511 
13512  vertices.clear();
13513  vertices_used.clear();
13514 
13515  manifold.clear();
13516 
13518 }
13519 
13520 
13521 template <int dim, int spacedim>
13524 {
13525  const DistortedCellList cells_with_distorted_children =
13527  *this, check_for_distorted_cells);
13528 
13529 
13530 
13531  // re-compute number of lines
13533  *this, levels.size(), number_cache);
13534 
13535 #ifdef DEBUG
13536  for (unsigned int level = 0; level < levels.size(); ++level)
13537  levels[level]->cells.monitor_memory(dim);
13538 
13539  // check whether really all refinement flags are reset (also of
13540  // previously non-active cells which we may not have touched. If the
13541  // refinement flag of a non-active cell is set, something went wrong
13542  // since the cell-accessors should have caught this)
13543  cell_iterator cell = begin(), endc = end();
13544  while (cell != endc)
13545  Assert(!(cell++)->refine_flag_set(), ExcInternalError());
13546 #endif
13547 
13548  return cells_with_distorted_children;
13549 }
13550 
13551 
13552 
13553 template <int dim, int spacedim>
13554 void
13556 {
13557  // create a vector counting for each line how many cells contain
13558  // this line. in 3D, this is used later on to decide which lines can
13559  // be deleted after coarsening a cell. in other dimensions it will
13560  // be ignored
13561  std::vector<unsigned int> line_cell_count =
13562  count_cells_bounded_by_line(*this);
13563  std::vector<unsigned int> quad_cell_count =
13564  count_cells_bounded_by_quad(*this);
13565 
13566  // loop over all cells. Flag all cells of which all children are
13567  // flagged for coarsening and delete the childrens' flags. In
13568  // effect, only those cells are flagged of which originally all
13569  // children were flagged and for which all children are on the same
13570  // refinement level. For flagging, the user flags are used, to avoid
13571  // confusion and because non-active cells can't be flagged for
13572  // coarsening. Note that because of the effects of
13573  // @p{fix_coarsen_flags}, of a cell either all or no children must
13574  // be flagged for coarsening, so it is ok to only check the first
13575  // child
13576  clear_user_flags();
13577 
13578  cell_iterator cell = begin(), endc = end();
13579  for (; cell != endc; ++cell)
13580  if (!cell->is_active())
13581  if (cell->child(0)->coarsen_flag_set())
13582  {
13583  cell->set_user_flag();
13584  for (unsigned int child = 0; child < cell->n_children(); ++child)
13585  {
13586  Assert(cell->child(child)->coarsen_flag_set(),
13587  ExcInternalError());
13588  cell->child(child)->clear_coarsen_flag();
13589  }
13590  }
13591 
13592 
13593  // now do the actual coarsening step. Since the loop goes over used
13594  // cells we only need not worry about deleting some cells since the
13595  // ++operator will then just hop over them if we should hit one. Do
13596  // the loop in the reverse way since we may only delete some cells
13597  // if their neighbors have already been deleted (if the latter are
13598  // on a higher level for example)
13599  //
13600  // since we delete the *children* of cells, we can ignore cells
13601  // on the highest level, i.e., level must be less than or equal
13602  // to n_levels()-2.
13603  if (levels.size() >= 2)
13604  for (cell = last(); cell != endc; --cell)
13605  if (cell->level() <= static_cast<int>(levels.size() - 2) &&
13606  cell->user_flag_set())
13607  {
13608  // inform all listeners that cell coarsening is going to happen
13609  signals.pre_coarsening_on_cell(cell);
13610  // use a separate function, since this is dimension specific
13612  delete_children(*this, cell, line_cell_count, quad_cell_count);
13613  }
13614 
13615  // re-compute number of lines and quads
13617  *this, levels.size(), number_cache);
13618 
13619  // in principle no user flags should be set any more at this point
13620 #if DEBUG
13621  for (cell = begin(); cell != endc; ++cell)
13622  Assert(cell->user_flag_set() == false, ExcInternalError());
13623 #endif
13624 }
13625 
13626 
13627 
13628 template <int dim, int spacedim>
13629 void
13631 {
13632  // copy a piece of code from prepare_coarsening_and_refinement that
13633  // ensures that the level difference at vertices is limited if so
13634  // desired. we need this code here since at least in 1d we don't
13635  // call the dimension-independent version of
13636  // prepare_coarsening_and_refinement function. in 2d and 3d, having
13637  // this hunk here makes our lives a bit easier as well as it takes
13638  // care of these cases earlier than it would otherwise happen.
13639  //
13640  // the main difference to the code in p_c_and_r is that here we
13641  // absolutely have to make sure that we get things right, i.e. that
13642  // in particular we set flags right if
13643  // limit_level_difference_at_vertices is set. to do so we iterate
13644  // until the flags don't change any more
13645  std::vector<bool> previous_coarsen_flags(n_active_cells());
13646  save_coarsen_flags(previous_coarsen_flags);
13647 
13648  std::vector<int> vertex_level(vertices.size(), 0);
13649 
13650  bool continue_iterating = true;
13651 
13652  do
13653  {
13654  if (smooth_grid & limit_level_difference_at_vertices)
13655  {
13656  Assert(!anisotropic_refinement,
13657  ExcMessage("In case of anisotropic refinement the "
13658  "limit_level_difference_at_vertices flag for "
13659  "mesh smoothing must not be set!"));
13660 
13661  // store highest level one of the cells adjacent to a vertex
13662  // belongs to
13663  std::fill(vertex_level.begin(), vertex_level.end(), 0);
13664  active_cell_iterator cell = begin_active(), endc = end();
13665  for (; cell != endc; ++cell)
13666  {
13667  if (cell->refine_flag_set())
13668  for (const unsigned int vertex :
13670  vertex_level[cell->vertex_index(vertex)] =
13671  std::max(vertex_level[cell->vertex_index(vertex)],
13672  cell->level() + 1);
13673  else if (!cell->coarsen_flag_set())
13674  for (const unsigned int vertex :
13676  vertex_level[cell->vertex_index(vertex)] =
13677  std::max(vertex_level[cell->vertex_index(vertex)],
13678  cell->level());
13679  else
13680  {
13681  // if coarsen flag is set then tentatively assume
13682  // that the cell will be coarsened. this isn't
13683  // always true (the coarsen flag could be removed
13684  // again) and so we may make an error here. we try
13685  // to correct this by iterating over the entire
13686  // process until we are converged
13687  Assert(cell->coarsen_flag_set(), ExcInternalError());
13688  for (const unsigned int vertex :
13690  vertex_level[cell->vertex_index(vertex)] =
13691  std::max(vertex_level[cell->vertex_index(vertex)],
13692  cell->level() - 1);
13693  }
13694  }
13695 
13696 
13697  // loop over all cells in reverse order. do so because we
13698  // can then update the vertex levels on the adjacent
13699  // vertices and maybe already flag additional cells in this
13700  // loop
13701  //
13702  // note that not only may we have to add additional
13703  // refinement flags, but we will also have to remove
13704  // coarsening flags on cells adjacent to vertices that will
13705  // see refinement
13706  for (cell = last_active(); cell != endc; --cell)
13707  if (cell->refine_flag_set() == false)
13708  {
13709  for (const unsigned int vertex :
13711  if (vertex_level[cell->vertex_index(vertex)] >=
13712  cell->level() + 1)
13713  {
13714  // remove coarsen flag...
13715  cell->clear_coarsen_flag();
13716 
13717  // ...and if necessary also refine the current
13718  // cell, at the same time updating the level
13719  // information about vertices
13720  if (vertex_level[cell->vertex_index(vertex)] >
13721  cell->level() + 1)
13722  {
13723  cell->set_refine_flag();
13724 
13725  for (const unsigned int v :
13727  vertex_level[cell->vertex_index(v)] =
13728  std::max(vertex_level[cell->vertex_index(v)],
13729  cell->level() + 1);
13730  }
13731 
13732  // continue and see whether we may, for example,
13733  // go into the inner 'if' above based on a
13734  // different vertex
13735  }
13736  }
13737  }
13738 
13739  // loop over all cells. Flag all cells of which all children are
13740  // flagged for coarsening and delete the childrens' flags. Also
13741  // delete all flags of cells for which not all children of a
13742  // cell are flagged. In effect, only those cells are flagged of
13743  // which originally all children were flagged and for which all
13744  // children are on the same refinement level. For flagging, the
13745  // user flags are used, to avoid confusion and because
13746  // non-active cells can't be flagged for coarsening
13747  //
13748  // In effect, all coarsen flags are turned into user flags of
13749  // the mother cell if coarsening is possible or deleted
13750  // otherwise.
13751  clear_user_flags();
13752  // Coarsen flags of cells with no mother cell, i.e. on the
13753  // coarsest level are deleted explicitly.
13754  active_cell_iterator acell = begin_active(0), end_ac = end_active(0);
13755  for (; acell != end_ac; ++acell)
13756  acell->clear_coarsen_flag();
13757 
13758  cell_iterator cell = begin(), endc = end();
13759  for (; cell != endc; ++cell)
13760  {
13761  // nothing to do if we are already on the finest level
13762  if (cell->is_active())
13763  continue;
13764 
13765  const unsigned int n_children = cell->n_children();
13766  unsigned int flagged_children = 0;
13767  for (unsigned int child = 0; child < n_children; ++child)
13768  if (cell->child(child)->is_active() &&
13769  cell->child(child)->coarsen_flag_set())
13770  {
13771  ++flagged_children;
13772  // clear flag since we don't need it anymore
13773  cell->child(child)->clear_coarsen_flag();
13774  }
13775 
13776  // flag this cell for coarsening if all children were
13777  // flagged
13778  if (flagged_children == n_children)
13779  cell->set_user_flag();
13780  }
13781 
13782  // in principle no coarsen flags should be set any more at this
13783  // point
13784 #if DEBUG
13785  for (cell = begin(); cell != endc; ++cell)
13786  Assert(cell->coarsen_flag_set() == false, ExcInternalError());
13787 #endif
13788 
13789  // now loop over all cells which have the user flag set. their
13790  // children were flagged for coarsening. set the coarsen flag
13791  // again if we are sure that none of the neighbors of these
13792  // children are refined, or will be refined, since then we would
13793  // get a two-level jump in refinement. on the other hand, if one
13794  // of the children's neighbors has their user flag set, then we
13795  // know that its children will go away by coarsening, and we
13796  // will be ok.
13797  //
13798  // note on the other hand that we do allow level-2 jumps in
13799  // refinement between neighbors in 1d, so this whole procedure
13800  // is only necessary if we are not in 1d
13801  //
13802  // since we remove some coarsening/user flags in the process, we
13803  // have to work from the finest level to the coarsest one, since
13804  // we occasionally inspect user flags of cells on finer levels
13805  // and need to be sure that these flags are final
13806  for (cell = last(); cell != endc; --cell)
13807  if (cell->user_flag_set())
13808  // if allowed: flag the
13809  // children for coarsening
13811  template coarsening_allowed<dim, spacedim>(cell))
13812  for (unsigned int c = 0; c < cell->n_children(); ++c)
13813  {
13814  Assert(cell->child(c)->refine_flag_set() == false,
13815  ExcInternalError());
13816 
13817  cell->child(c)->set_coarsen_flag();
13818  }
13819 
13820  // clear all user flags again, now that we don't need them any
13821  // more
13822  clear_user_flags();
13823 
13824 
13825  // now see if anything has changed in the last iteration of this
13826  // function
13827  std::vector<bool> current_coarsen_flags(n_active_cells());
13828  save_coarsen_flags(current_coarsen_flags);
13829 
13830  continue_iterating = (current_coarsen_flags != previous_coarsen_flags);
13831  previous_coarsen_flags = current_coarsen_flags;
13832  }
13833  while (continue_iterating == true);
13834 }
13835 
13836 
13837 // TODO: merge the following 3 functions since they are the same
13838 template <>
13839 bool
13841 {
13842  // save the flags to determine whether something was changed in the
13843  // course of this function
13844  std::vector<bool> flags_before;
13845  save_coarsen_flags(flags_before);
13846 
13847  // do nothing in 1d, except setting the coarsening flags correctly
13848  fix_coarsen_flags();
13849 
13850  std::vector<bool> flags_after;
13851  save_coarsen_flags(flags_after);
13852 
13853  return (flags_before != flags_after);
13854 }
13855 
13856 
13857 template <>
13858 bool
13860 {
13861  // save the flags to determine whether something was changed in the
13862  // course of this function
13863  std::vector<bool> flags_before;
13864  save_coarsen_flags(flags_before);
13865 
13866  // do nothing in 1d, except setting the coarsening flags correctly
13867  fix_coarsen_flags();
13868 
13869  std::vector<bool> flags_after;
13870  save_coarsen_flags(flags_after);
13871 
13872  return (flags_before != flags_after);
13873 }
13874 
13875 
13876 template <>
13877 bool
13879 {
13880  // save the flags to determine whether something was changed in the
13881  // course of this function
13882  std::vector<bool> flags_before;
13883  save_coarsen_flags(flags_before);
13884 
13885  // do nothing in 1d, except setting the coarsening flags correctly
13886  fix_coarsen_flags();
13887 
13888  std::vector<bool> flags_after;
13889  save_coarsen_flags(flags_after);
13890 
13891  return (flags_before != flags_after);
13892 }
13893 
13894 
13895 
13896 namespace
13897 {
13898  // check if the given @param cell marked for coarsening would
13899  // produce an unrefined island. To break up long chains of these
13900  // cells we recursively check our neighbors in case we change this
13901  // cell. This reduces the number of outer iterations dramatically.
13902  template <int dim, int spacedim>
13903  void
13904  possibly_do_not_produce_unrefined_islands(
13905  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
13906  {
13907  Assert(cell->has_children(), ExcInternalError());
13908 
13909  unsigned int n_neighbors = 0;
13910  // count all neighbors that will be refined along the face of our
13911  // cell after the next step
13912  unsigned int count = 0;
13913  for (unsigned int n : GeometryInfo<dim>::face_indices())
13914  {
13915  const typename Triangulation<dim, spacedim>::cell_iterator neighbor =
13916  cell->neighbor(n);
13917  if (neighbor.state() == IteratorState::valid)
13918  {
13919  ++n_neighbors;
13920  if (face_will_be_refined_by_neighbor(cell, n))
13921  ++count;
13922  }
13923  }
13924  // clear coarsen flags if either all existing neighbors will be
13925  // refined or all but one will be and the cell is in the interior
13926  // of the domain
13927  if (count == n_neighbors ||
13928  (count >= n_neighbors - 1 &&
13929  n_neighbors == GeometryInfo<dim>::faces_per_cell))
13930  {
13931  for (unsigned int c = 0; c < cell->n_children(); ++c)
13932  cell->child(c)->clear_coarsen_flag();
13933 
13934  for (const unsigned int face : GeometryInfo<dim>::face_indices())
13935  if (!cell->at_boundary(face) &&
13936  (!cell->neighbor(face)->is_active()) &&
13937  (cell_will_be_coarsened(cell->neighbor(face))))
13938  possibly_do_not_produce_unrefined_islands<dim, spacedim>(
13939  cell->neighbor(face));
13940  }
13941  }
13942 
13943 
13944  // see if the current cell needs to be refined to avoid unrefined
13945  // islands.
13946  //
13947  // there are sometimes chains of cells that induce refinement of
13948  // each other. to avoid running the loop in
13949  // prepare_coarsening_and_refinement over and over again for each
13950  // one of them, at least for the isotropic refinement case we seek
13951  // to flag neighboring elements as well as necessary. this takes
13952  // care of (slightly pathological) cases like
13953  // deal.II/mesh_smoothing_03
13954  template <int dim, int spacedim>
13955  void
13956  possibly_refine_unrefined_island(
13957  const typename Triangulation<dim, spacedim>::cell_iterator &cell,
13958  const bool allow_anisotropic_smoothing)
13959  {
13960  Assert(cell->is_active(), ExcInternalError());
13961  Assert(cell->refine_flag_set() == false, ExcInternalError());
13962 
13963 
13964  // now we provide two algorithms. the first one is the standard
13965  // one, coming from the time, where only isotropic refinement was
13966  // possible. it simply counts the neighbors that are or will be
13967  // refined and compares to the number of other ones. the second
13968  // one does this check independently for each direction: if all
13969  // neighbors in one direction (normally two, at the boundary only
13970  // one) are refined, the current cell is flagged to be refined in
13971  // an according direction.
13972 
13973  if (allow_anisotropic_smoothing == false)
13974  {
13975  // use first algorithm
13976  unsigned int refined_neighbors = 0, unrefined_neighbors = 0;
13977  for (const unsigned int face : GeometryInfo<dim>::face_indices())
13978  if (!cell->at_boundary(face))
13979  {
13980  if (face_will_be_refined_by_neighbor(cell, face))
13981  ++refined_neighbors;
13982  else
13983  ++unrefined_neighbors;
13984  }
13985 
13986  if (unrefined_neighbors < refined_neighbors)
13987  {
13988  cell->clear_coarsen_flag();
13989  cell->set_refine_flag();
13990 
13991  // ok, so now we have flagged this cell. if we know that
13992  // there were any unrefined neighbors at all, see if any
13993  // of those will have to be refined as well
13994  if (unrefined_neighbors > 0)
13995  for (const unsigned int face : GeometryInfo<dim>::face_indices())
13996  if (!cell->at_boundary(face) &&
13997  (face_will_be_refined_by_neighbor(cell, face) == false) &&
13998  (cell->neighbor(face)->has_children() == false) &&
13999  (cell->neighbor(face)->refine_flag_set() == false))
14000  possibly_refine_unrefined_island<dim, spacedim>(
14001  cell->neighbor(face), allow_anisotropic_smoothing);
14002  }
14003  }
14004  else
14005  {
14006  // variable to store the cell refine case needed to fulfill
14007  // all smoothing requirements
14008  RefinementCase<dim> smoothing_cell_refinement_case =
14010 
14011  // use second algorithm, do the check individually for each
14012  // direction
14013  for (unsigned int face_pair = 0;
14014  face_pair < GeometryInfo<dim>::faces_per_cell / 2;
14015  ++face_pair)
14016  {
14017  // variable to store the cell refine case needed to refine
14018  // at the current face pair in the same way as the
14019  // neighbors do...
14020  RefinementCase<dim> directional_cell_refinement_case =
14022 
14023  for (unsigned int face_index = 0; face_index < 2; ++face_index)
14024  {
14025  unsigned int face = 2 * face_pair + face_index;
14026  // variable to store the refine case (to come) of the
14027  // face under consideration
14028  RefinementCase<dim - 1> expected_face_ref_case =
14029  RefinementCase<dim - 1>::no_refinement;
14030 
14031  if (cell->neighbor(face).state() == IteratorState::valid)
14032  face_will_be_refined_by_neighbor<dim, spacedim>(
14033  cell, face, expected_face_ref_case);
14034  // now extract which refine case would be necessary to
14035  // achieve the same face refinement. set the
14036  // intersection with other requirements for the same
14037  // direction.
14038 
14039  // note: using the intersection is not an obvious
14040  // decision, we could also argue that it is more
14041  // natural to use the union. however, intersection is
14042  // the less aggressive tactic and favours a smaller
14043  // number of refined cells over an intensive
14044  // smoothing. this way we try not to lose too much of
14045  // the effort we put in anisotropic refinement
14046  // indicators due to overly aggressive smoothing...
14047  directional_cell_refinement_case =
14048  (directional_cell_refinement_case &
14051  expected_face_ref_case,
14052  face,
14053  cell->face_orientation(face),
14054  cell->face_flip(face),
14055  cell->face_rotation(face)));
14056  } // for both face indices
14057  // if both requirements sum up to something useful, add
14058  // this to the refine case for smoothing. note: if
14059  // directional_cell_refinement_case is isotropic still,
14060  // then something went wrong...
14061  Assert(directional_cell_refinement_case <
14063  ExcInternalError());
14064  smoothing_cell_refinement_case =
14065  smoothing_cell_refinement_case | directional_cell_refinement_case;
14066  } // for all face_pairs
14067  // no we collected contributions from all directions. combine
14068  // the new flags with the existing refine case, but only if
14069  // smoothing is required
14070  if (smoothing_cell_refinement_case)
14071  {
14072  cell->clear_coarsen_flag();
14073  cell->set_refine_flag(cell->refine_flag_set() |
14074  smoothing_cell_refinement_case);
14075  }
14076  }
14077  }
14078 } // namespace
14079 
14080 
14081 template <int dim, int spacedim>
14082 bool
14084 {
14085  // save the flags to determine whether something was changed in the
14086  // course of this function
14087  std::vector<bool> flags_before[2];
14088  save_coarsen_flags(flags_before[0]);
14089  save_refine_flags(flags_before[1]);
14090 
14091  // save the flags at the outset of each loop. we do so in order to
14092  // find out whether something was changed in the present loop, in
14093  // which case we would have to re-run the loop. the other
14094  // possibility to find this out would be to set a flag
14095  // @p{something_changed} to true each time we change something.
14096  // however, sometimes one change in one of the parts of the loop is
14097  // undone by another one, so we might end up in an endless loop. we
14098  // could be tempted to break this loop at an arbitrary number of
14099  // runs, but that would not be a clean solution, since we would
14100  // either have to 1/ break the loop too early, in which case the
14101  // promise that a second call to this function immediately after the
14102  // first one does not change anything, would be broken, or 2/ we do
14103  // as many loops as there are levels. we know that information is
14104  // transported over one level in each run of the loop, so this is
14105  // enough. Unfortunately, each loop is rather expensive, so we chose
14106  // the way presented here
14107  std::vector<bool> flags_before_loop[2] = {flags_before[0], flags_before[1]};
14108 
14109  // now for what is done in each loop: we have to fulfill several
14110  // tasks at the same time, namely several mesh smoothing algorithms
14111  // and mesh regularization, by which we mean that the next mesh
14112  // fulfills several requirements such as no double refinement at
14113  // each face or line, etc.
14114  //
14115  // since doing these things at once seems almost impossible (in the
14116  // first year of this library, they were done in two functions, one
14117  // for refinement and one for coarsening, and most things within
14118  // these were done at once, so the code was rather impossible to
14119  // join into this, only, function), we do them one after each
14120  // other. the order in which we do them is such that the important
14121  // tasks, namely regularization, are done last and the least
14122  // important things are done the first. the following order is
14123  // chosen:
14124  //
14125  // 0/ Only if coarsest_level_1 or patch_level_1 is set: clear all
14126  // coarsen flags on level 1 to avoid level 0 cells being created
14127  // by coarsening. As coarsen flags will never be added, this can
14128  // be done once and for all before the actual loop starts.
14129  //
14130  // 1/ do not coarsen a cell if 'most of the neighbors' will be
14131  // refined after the step. This is to prevent occurrence of
14132  // unrefined islands.
14133  //
14134  // 2/ eliminate refined islands in the interior and at the
14135  // boundary. since they don't do much harm besides increasing the
14136  // number of degrees of freedom, doing this has a rather low
14137  // priority.
14138  //
14139  // 3/ limit the level difference of neighboring cells at each
14140  // vertex.
14141  //
14142  // 4/ eliminate unrefined islands. this has higher priority since
14143  // this diminishes the approximation properties not only of the
14144  // unrefined island, but also of the surrounding patch.
14145  //
14146  // 5/ ensure patch level 1. Then the triangulation consists of
14147  // patches, i.e. of cells that are refined once. It follows that
14148  // if at least one of the children of a cell is or will be
14149  // refined than all children need to be refined. This step only
14150  // sets refinement flags and does not set coarsening flags. If
14151  // the patch_level_1 flag is set, then
14152  // eliminate_unrefined_islands, eliminate_refined_inner_islands
14153  // and eliminate_refined_boundary_islands will be fulfilled
14154  // automatically and do not need to be enforced separately.
14155  //
14156  // 6/ take care of the requirement that no double refinement is done
14157  // at each face
14158  //
14159  // 7/ take care that no double refinement is done at each line in 3d
14160  // or higher dimensions.
14161  //
14162  // 8/ make sure that all children of each cell are either flagged
14163  // for coarsening or none of the children is
14164  //
14165  // For some of these steps, it is known that they interact. Namely,
14166  // it is not possible to guarantee that after step 6 another step 5
14167  // would have no effect; the same holds for the opposite order and
14168  // also when taking into account step 7. however, it is important to
14169  // guarantee that step five or six do not undo something that step 5
14170  // did, and step 7 not something of step 6, otherwise the
14171  // requirements will not be satisfied even if the loop
14172  // terminates. this is accomplished by the fact that steps 5 and 6
14173  // only *add* refinement flags and delete coarsening flags
14174  // (therefore, step 6 can't undo something that step 4 already did),
14175  // and step 7 only deletes coarsening flags, never adds some. step 7
14176  // needs also take care that it won't tag cells for refinement for
14177  // which some neighbors are more refined or will be refined.
14178 
14180  // STEP 0:
14181  // Only if coarsest_level_1 or patch_level_1 is set: clear all
14182  // coarsen flags on level 1 to avoid level 0 cells being created
14183  // by coarsening.
14184  if (((smooth_grid & coarsest_level_1) || (smooth_grid & patch_level_1)) &&
14185  n_levels() >= 2)
14186  {
14187  for (const auto &cell : active_cell_iterators_on_level(1))
14188  cell->clear_coarsen_flag();
14189  }
14190 
14191  bool mesh_changed_in_this_loop = false;
14192  do
14193  {
14195  // STEP 1:
14196  // do not coarsen a cell if 'most of the neighbors' will be
14197  // refined after the step. This is to prevent the occurrence
14198  // of unrefined islands. If patch_level_1 is set, this will
14199  // be automatically fulfilled.
14200  if (smooth_grid & do_not_produce_unrefined_islands &&
14201  !(smooth_grid & patch_level_1))
14202  {
14203  for (const auto &cell : cell_iterators())
14204  {
14205  // only do something if this
14206  // cell will be coarsened
14207  if (!cell->is_active() && cell_will_be_coarsened(cell))
14208  possibly_do_not_produce_unrefined_islands<dim, spacedim>(cell);
14209  }
14210  }
14211 
14212 
14214  // STEP 2:
14215  // eliminate refined islands in the interior and at the
14216  // boundary. since they don't do much harm besides increasing
14217  // the number of degrees of freedom, doing this has a rather
14218  // low priority. If patch_level_1 is set, this will be
14219  // automatically fulfilled.
14220  //
14221  // there is one corner case to consider: if this is a
14222  // distributed triangulation, there may be refined islands on
14223  // the boundary of which we own only part (e.g. a single cell
14224  // in the corner of a domain). the rest of the island is
14225  // ghost cells and it *looks* like the area around it
14226  // (artificial cells) are coarser but this is only because
14227  // they may actually be equally fine on other
14228  // processors. it's hard to detect this case but we can do
14229  // the following: only set coarsen flags to remove this
14230  // refined island if all cells we want to set flags on are
14231  // locally owned
14232  if (smooth_grid & (eliminate_refined_inner_islands |
14233  eliminate_refined_boundary_islands) &&
14234  !(smooth_grid & patch_level_1))
14235  {
14236  for (const auto &cell : cell_iterators())
14237  if (!cell->is_active() ||
14238  (cell->is_active() && cell->refine_flag_set() &&
14239  cell->is_locally_owned()))
14240  {
14241  // check whether all children are active, i.e. not
14242  // refined themselves. This is a precondition that the
14243  // children may be coarsened away. If the cell is only
14244  // flagged for refinement, then all future children
14245  // will be active
14246  bool all_children_active = true;
14247  if (!cell->is_active())
14248  for (unsigned int c = 0; c < cell->n_children(); ++c)
14249  if (!cell->child(c)->is_active() ||
14250  cell->child(c)->is_ghost() ||
14251  cell->child(c)->is_artificial())
14252  {
14253  all_children_active = false;
14254  break;
14255  }
14256 
14257  if (all_children_active)
14258  {
14259  // count number of refined and unrefined neighbors
14260  // of cell. neighbors on lower levels are counted
14261  // as unrefined since they can only get to the
14262  // same level as this cell by the next refinement
14263  // cycle
14264  unsigned int unrefined_neighbors = 0, total_neighbors = 0;
14265 
14266  for (const unsigned int n :
14268  {
14269  const cell_iterator neighbor = cell->neighbor(n);
14270  if (neighbor.state() == IteratorState::valid)
14271  {
14272  ++total_neighbors;
14273 
14274  if (!face_will_be_refined_by_neighbor(cell, n))
14275  ++unrefined_neighbors;
14276  }
14277  }
14278 
14279  // if all neighbors unrefined: mark this cell for
14280  // coarsening or don't refine if marked for that
14281  //
14282  // also do the distinction between the two
14283  // versions of the eliminate_refined_*_islands
14284  // flag
14285  //
14286  // the last check is whether there are any
14287  // neighbors at all. if not so, then we are (e.g.)
14288  // on the coarsest grid with one cell, for which,
14289  // of course, we do not remove the refine flag.
14290  if ((unrefined_neighbors == total_neighbors) &&
14291  (((unrefined_neighbors ==
14293  (smooth_grid & eliminate_refined_inner_islands)) ||
14294  ((unrefined_neighbors <
14296  (smooth_grid &
14297  eliminate_refined_boundary_islands))) &&
14298  (total_neighbors != 0))
14299  {
14300  if (!cell->is_active())
14301  for (unsigned int c = 0; c < cell->n_children(); ++c)
14302  {
14303  cell->child(c)->clear_refine_flag();
14304  cell->child(c)->set_coarsen_flag();
14305  }
14306  else
14307  cell->clear_refine_flag();
14308  }
14309  }
14310  }
14311  }
14312 
14314  // STEP 3:
14315  // limit the level difference of neighboring cells at each
14316  // vertex.
14317  //
14318  // in case of anisotropic refinement this does not make
14319  // sense. as soon as one cell is anisotropically refined, an
14320  // Assertion is thrown. therefore we can ignore this problem
14321  // later on
14322  if (smooth_grid & limit_level_difference_at_vertices)
14323  {
14324  Assert(!anisotropic_refinement,
14325  ExcMessage("In case of anisotropic refinement the "
14326  "limit_level_difference_at_vertices flag for "
14327  "mesh smoothing must not be set!"));
14328 
14329  // store highest level one of the cells adjacent to a vertex
14330  // belongs to
14331  std::vector<int> vertex_level(vertices.size(), 0);
14332  for (const auto &cell : active_cell_iterators())
14333  {
14334  if (cell->refine_flag_set())
14335  for (const unsigned int vertex :
14337  vertex_level[cell->vertex_index(vertex)] =
14338  std::max(vertex_level[cell->vertex_index(vertex)],
14339  cell->level() + 1);
14340  else if (!cell->coarsen_flag_set())
14341  for (const unsigned int vertex :
14343  vertex_level[cell->vertex_index(vertex)] =
14344  std::max(vertex_level[cell->vertex_index(vertex)],
14345  cell->level());
14346  else
14347  {
14348  // if coarsen flag is set then tentatively assume
14349  // that the cell will be coarsened. this isn't
14350  // always true (the coarsen flag could be removed
14351  // again) and so we may make an error here
14352  Assert(cell->coarsen_flag_set(), ExcInternalError());
14353  for (const unsigned int vertex :
14355  vertex_level[cell->vertex_index(vertex)] =
14356  std::max(vertex_level[cell->vertex_index(vertex)],
14357  cell->level() - 1);
14358  }
14359  }
14360 
14361 
14362  // loop over all cells in reverse order. do so because we
14363  // can then update the vertex levels on the adjacent
14364  // vertices and maybe already flag additional cells in this
14365  // loop
14366  //
14367  // note that not only may we have to add additional
14368  // refinement flags, but we will also have to remove
14369  // coarsening flags on cells adjacent to vertices that will
14370  // see refinement
14371  for (active_cell_iterator cell = last_active(); cell != end(); --cell)
14372  if (cell->refine_flag_set() == false)
14373  {
14374  for (const unsigned int vertex :
14376  if (vertex_level[cell->vertex_index(vertex)] >=
14377  cell->level() + 1)
14378  {
14379  // remove coarsen flag...
14380  cell->clear_coarsen_flag();
14381 
14382  // ...and if necessary also refine the current
14383  // cell, at the same time updating the level
14384  // information about vertices
14385  if (vertex_level[cell->vertex_index(vertex)] >
14386  cell->level() + 1)
14387  {
14388  cell->set_refine_flag();
14389 
14390  for (const unsigned int v :
14392  vertex_level[cell->vertex_index(v)] =
14393  std::max(vertex_level[cell->vertex_index(v)],
14394  cell->level() + 1);
14395  }
14396 
14397  // continue and see whether we may, for example,
14398  // go into the inner'if'
14399  // above based on a
14400  // different vertex
14401  }
14402  }
14403  }
14404 
14406  // STEP 4:
14407  // eliminate unrefined islands. this has higher priority
14408  // since this diminishes the approximation properties not
14409  // only of the unrefined island, but also of the surrounding
14410  // patch.
14411  //
14412  // do the loop from finest to coarsest cells since we may
14413  // trigger a cascade by marking cells for refinement which
14414  // may trigger more cells further down below
14415  if (smooth_grid & eliminate_unrefined_islands)
14416  {
14417  for (active_cell_iterator cell = last_active(); cell != end(); --cell)
14418  // only do something if cell is not already flagged for
14419  // (isotropic) refinement
14420  if (cell->refine_flag_set() !=
14422  possibly_refine_unrefined_island<dim, spacedim>(
14423  cell, (smooth_grid & allow_anisotropic_smoothing) != 0);
14424  }
14425 
14427  // STEP 5:
14428  // ensure patch level 1.
14429  //
14430  // Introduce some terminology:
14431  // - a cell that is refined
14432  // once is a patch of
14433  // level 1 simply called patch.
14434  // - a cell that is globally
14435  // refined twice is called
14436  // a patch of level 2.
14437  // - patch level n says that
14438  // the triangulation consists
14439  // of patches of level n.
14440  // This makes sense only
14441  // if the grid is already at
14442  // least n times globally
14443  // refined.
14444  //
14445  // E.g. from patch level 1 follows: if at least one of the
14446  // children of a cell is or will be refined than enforce all
14447  // children to be refined.
14448 
14449  // This step 4 only sets refinement flags and does not set
14450  // coarsening flags.
14451  if (smooth_grid & patch_level_1)
14452  {
14453  // An important assumption (A) is that before calling this
14454  // function the grid was already of patch level 1.
14455 
14456  // loop over all cells whose children are all active. (By
14457  // assumption (A) either all or none of the children are
14458  // active). If the refine flag of at least one of the
14459  // children is set then set_refine_flag and
14460  // clear_coarsen_flag of all children.
14461  for (const auto &cell : cell_iterators())
14462  if (!cell->is_active())
14463  {
14464  // ensure the invariant. we can then check whether all
14465  // of its children are further refined or not by
14466  // simply looking at the first child
14467  Assert(cell_is_patch_level_1(cell), ExcInternalError());
14468  if (cell->child(0)->has_children() == true)
14469  continue;
14470 
14471  // cell is found to be a patch. combine the refine
14472  // cases of all children
14473  RefinementCase<dim> combined_ref_case =
14475  for (unsigned int i = 0; i < cell->n_children(); ++i)
14476  combined_ref_case =
14477  combined_ref_case | cell->child(i)->refine_flag_set();
14478  if (combined_ref_case != RefinementCase<dim>::no_refinement)
14479  for (unsigned int i = 0; i < cell->n_children(); ++i)
14480  {
14481  cell_iterator child = cell->child(i);
14482 
14483  child->clear_coarsen_flag();
14484  child->set_refine_flag(combined_ref_case);
14485  }
14486  }
14487 
14488  // The code above dealt with the case where we may get a
14489  // non-patch_level_1 mesh from refinement. Now also deal
14490  // with the case where we could get such a mesh by
14491  // coarsening. Coarsen the children (and remove the
14492  // grandchildren) only if all cell->grandchild(i)
14493  // ->coarsen_flag_set() are set.
14494  //
14495  // for a case where this is a bit tricky, take a look at the
14496  // mesh_smoothing_0[12] testcases
14497  for (const auto &cell : cell_iterators())
14498  {
14499  // check if this cell has active grandchildren. note
14500  // that we know that it is patch_level_1, i.e. if one of
14501  // its children is active then so are all, and it isn't
14502  // going to have any grandchildren at all:
14503  if (cell->is_active() || cell->child(0)->is_active())
14504  continue;
14505 
14506  // cell is not active, and so are none of its
14507  // children. check the grandchildren. note that the
14508  // children are also patch_level_1, and so we only ever
14509  // need to check their first child
14510  const unsigned int n_children = cell->n_children();
14511  bool has_active_grandchildren = false;
14512 
14513  for (unsigned int i = 0; i < n_children; ++i)
14514  if (cell->child(i)->child(0)->is_active())
14515  {
14516  has_active_grandchildren = true;
14517  break;
14518  }
14519 
14520  if (has_active_grandchildren == false)
14521  continue;
14522 
14523 
14524  // ok, there are active grandchildren. see if either all
14525  // or none of them are flagged for coarsening
14526  unsigned int n_grandchildren = 0;
14527 
14528  // count all coarsen flags of the grandchildren.
14529  unsigned int n_coarsen_flags = 0;
14530 
14531  // cell is not a patch (of level 1) as it has a
14532  // grandchild. Is cell a patch of level 2?? Therefore:
14533  // find out whether all cell->child(i) are patches
14534  for (unsigned int c = 0; c < n_children; ++c)
14535  {
14536  // get at the child. by assumption (A), and the
14537  // check by which we got here, the child is not
14538  // active
14539  cell_iterator child = cell->child(c);
14540 
14541  const unsigned int nn_children = child->n_children();
14542  n_grandchildren += nn_children;
14543 
14544  // if child is found to be a patch of active cells
14545  // itself, then add up how many of its children are
14546  // supposed to be coarsened
14547  if (child->child(0)->is_active())
14548  for (unsigned int cc = 0; cc < nn_children; ++cc)
14549  if (child->child(cc)->coarsen_flag_set())
14550  ++n_coarsen_flags;
14551  }
14552 
14553  // if not all grandchildren are supposed to be coarsened
14554  // (e.g. because some simply don't have the flag set, or
14555  // because they are not active and therefore cannot
14556  // carry the flag), then remove the coarsen flag from
14557  // all of the active grandchildren. note that there may
14558  // be coarsen flags on the grandgrandchildren -- we
14559  // don't clear them here, but we'll get to them in later
14560  // iterations if necessary
14561  //
14562  // there is nothing we have to do if no coarsen flags
14563  // have been set at all
14564  if ((n_coarsen_flags != n_grandchildren) && (n_coarsen_flags > 0))
14565  for (unsigned int c = 0; c < n_children; ++c)
14566  {
14567  const cell_iterator child = cell->child(c);
14568  if (child->child(0)->is_active())
14569  for (unsigned int cc = 0; cc < child->n_children(); ++cc)
14570  child->child(cc)->clear_coarsen_flag();
14571  }
14572  }
14573  }
14574 
14576  //
14577  // at the boundary we could end up with cells with negative
14578  // volume or at least with a part, that is negative, if the
14579  // cell is refined anisotropically. we have to check, whether
14580  // that can happen
14583 
14585  // STEP 6:
14586  // take care of the requirement that no
14587  // double refinement is done at each face
14588  //
14589  // in case of anisotropic refinement it is only likely, but
14590  // not sure, that the cells, which are more refined along a
14591  // certain face common to two cells are on a higher
14592  // level. therefore we cannot be sure, that the requirement
14593  // of no double refinement is fulfilled after a single pass
14594  // of the following actions. We could just wait for the next
14595  // global loop. when this function terminates, the
14596  // requirement will be fulfilled. However, it might be faster
14597  // to insert an inner loop here.
14598  bool changed = true;
14599  while (changed)
14600  {
14601  changed = false;
14602  active_cell_iterator cell = last_active(), endc = end();
14603 
14604  for (; cell != endc; --cell)
14605  if (cell->refine_flag_set())
14606  {
14607  // loop over neighbors of cell
14608  for (const unsigned int i : GeometryInfo<dim>::face_indices())
14609  {
14610  // only do something if the face is not at the
14611  // boundary and if the face will be refined with
14612  // the RefineCase currently flagged for
14613  const bool has_periodic_neighbor =
14614  cell->has_periodic_neighbor(i);
14615  const bool has_neighbor_or_periodic_neighbor =
14616  !cell->at_boundary(i) || has_periodic_neighbor;
14617  if (has_neighbor_or_periodic_neighbor &&
14619  cell->refine_flag_set(), i) !=
14621  {
14622  // 1) if the neighbor has children: nothing to
14623  // worry about. 2) if the neighbor is active
14624  // and a coarser one, ensure, that its
14625  // refine_flag is set 3) if the neighbor is
14626  // active and as refined along the face as our
14627  // current cell, make sure, that no
14628  // coarsen_flag is set. if we remove the
14629  // coarsen flag of our neighbor,
14630  // fix_coarsen_flags() makes sure, that the
14631  // mother cell will not be coarsened
14632  if (cell->neighbor_or_periodic_neighbor(i)->is_active())
14633  {
14634  if ((!has_periodic_neighbor &&
14635  cell->neighbor_is_coarser(i)) ||
14636  (has_periodic_neighbor &&
14637  cell->periodic_neighbor_is_coarser(i)))
14638  {
14639  if (cell->neighbor_or_periodic_neighbor(i)
14640  ->coarsen_flag_set())
14641  cell->neighbor_or_periodic_neighbor(i)
14642  ->clear_coarsen_flag();
14643  // we'll set the refine flag for this
14644  // neighbor below. we note, that we
14645  // have changed something by setting
14646  // the changed flag to true. We do not
14647  // need to do so, if we just removed
14648  // the coarsen flag, as the changed
14649  // flag only indicates the need to
14650  // re-run the inner loop. however, we
14651  // only loop over cells flagged for
14652  // refinement here, so nothing to
14653  // worry about if we remove coarsen
14654  // flags
14655 
14656  if (dim == 2)
14657  {
14658  if (smooth_grid &
14659  allow_anisotropic_smoothing)
14660  changed =
14661  has_periodic_neighbor ?
14662  cell->periodic_neighbor(i)
14663  ->flag_for_face_refinement(
14664  cell
14665  ->periodic_neighbor_of_coarser_periodic_neighbor(
14666  i)
14667  .first,
14669  cell->neighbor(i)
14670  ->flag_for_face_refinement(
14671  cell
14672  ->neighbor_of_coarser_neighbor(
14673  i)
14674  .first,
14676  else
14677  {
14678  if (!cell
14679  ->neighbor_or_periodic_neighbor(
14680  i)
14681  ->refine_flag_set())
14682  changed = true;
14683  cell->neighbor_or_periodic_neighbor(i)
14684  ->set_refine_flag();
14685  }
14686  }
14687  else // i.e. if (dim==3)
14688  {
14689  // ugly situations might arise here,
14690  // consider the following situation, which
14691  // shows neighboring cells at the common
14692  // face, where the upper right element is
14693  // coarser at the given face. Now the upper
14694  // child element of the lower left wants to
14695  // refine according to cut_z, such that
14696  // there is a 'horizontal' refinement of the
14697  // face marked with #####
14698  //
14699  // / /
14700  // / /
14701  // *---------------*
14702  // | |
14703  // | |
14704  // | |
14705  // | |
14706  // | |
14707  // | | /
14708  // | |/
14709  // *---------------*
14710  //
14711  //
14712  // *---------------*
14713  // /| /|
14714  // / | ##### / |
14715  // | |
14716  // *---------------*
14717  // /| /|
14718  // / | / |
14719  // | |
14720  // *---------------*
14721  // / /
14722  // / /
14723  //
14724  // this introduces too many hanging nodes
14725  // and the neighboring (coarser) cell (upper
14726  // right) has to be refined. If it is only
14727  // refined according to cut_z, then
14728  // everything is ok:
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  // if however the cell wants to refine
14756  // itself in an other way, or if we disallow
14757  // anisotropic smoothing, then simply
14758  // refining the neighbor isotropically is
14759  // not going to work, since this introduces
14760  // a refinement of face ##### with both
14761  // cut_x and cut_y, which is not possible:
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  // / /
14787  //
14788  // thus, in this case we also need to refine
14789  // our current cell in the new direction:
14790  //
14791  // / / /
14792  // / / /
14793  // *-------*-------*
14794  // | | |
14795  // | | | /
14796  // | | |/
14797  // *-------*-------*
14798  // | | |
14799  // | | | /
14800  // | | |/
14801  // *-------*-------*
14802  //
14803  //
14804  // *-------*-------*
14805  // /| /| /|
14806  // / *-------*-------*
14807  // /| /| /|
14808  // *-------*-------*
14809  // /| / /|
14810  // / | / |
14811  // | |
14812  // *---------------*
14813  // / /
14814  // / /
14815 
14816  std::pair<unsigned int, unsigned int>
14817  nb_indices =
14818  has_periodic_neighbor ?
14819  cell
14820  ->periodic_neighbor_of_coarser_periodic_neighbor(
14821  i) :
14822  cell->neighbor_of_coarser_neighbor(i);
14823  unsigned int refined_along_x = 0,
14824  refined_along_y = 0,
14825  to_be_refined_along_x = 0,
14826  to_be_refined_along_y = 0;
14827 
14828  const int this_face_index =
14829  cell->face_index(i);
14830 
14831  // step 1: detect, along which axis the face
14832  // is currently refined
14833 
14834  // first, we need an iterator pointing to
14835  // the parent face. This requires a slight
14836  // detour in case the neighbor is behind a
14837  // periodic face.
14838  const auto parent_face = [&]() {
14839  if (has_periodic_neighbor)
14840  {
14841  const auto neighbor =
14842  cell->periodic_neighbor(i);
14843  const auto parent_face_no =
14844  neighbor
14845  ->periodic_neighbor_of_periodic_neighbor(
14846  nb_indices.first);
14847  auto parent =
14848  neighbor->periodic_neighbor(
14849  nb_indices.first);
14850  return parent->face(parent_face_no);
14851  }
14852  else
14853  return cell->neighbor(i)->face(
14854  nb_indices.first);
14855  }();
14856 
14857  if ((this_face_index ==
14858  parent_face->child_index(0)) ||
14859  (this_face_index ==
14860  parent_face->child_index(1)))
14861  {
14862  // this might be an
14863  // anisotropic child. get the
14864  // face refine case of the
14865  // neighbors face and count
14866  // refinements in x and y
14867  // direction.
14868  RefinementCase<dim - 1> frc =
14869  parent_face->refinement_case();
14870  if (frc & RefinementCase<dim>::cut_x)
14871  ++refined_along_x;
14872  if (frc & RefinementCase<dim>::cut_y)
14873  ++refined_along_y;
14874  }
14875  else
14876  // this has to be an isotropic
14877  // child
14878  {
14879  ++refined_along_x;
14880  ++refined_along_y;
14881  }
14882  // step 2: detect, along which axis the face
14883  // has to be refined given the current
14884  // refine flag
14885  RefinementCase<dim - 1> flagged_frc =
14887  cell->refine_flag_set(),
14888  i,
14889  cell->face_orientation(i),
14890  cell->face_flip(i),
14891  cell->face_rotation(i));
14892  if (flagged_frc &
14894  ++to_be_refined_along_x;
14895  if (flagged_frc &
14897  ++to_be_refined_along_y;
14898 
14899  // step 3: set the refine flag of the
14900  // (coarser and active) neighbor.
14901  if ((smooth_grid &
14902  allow_anisotropic_smoothing) ||
14903  cell->neighbor_or_periodic_neighbor(i)
14904  ->refine_flag_set())
14905  {
14906  if (refined_along_x +
14907  to_be_refined_along_x >
14908  1)
14909  changed |=
14910  cell
14911  ->neighbor_or_periodic_neighbor(i)
14912  ->flag_for_face_refinement(
14913  nb_indices.first,
14914  RefinementCase<dim -
14915  1>::cut_axis(0));
14916  if (refined_along_y +
14917  to_be_refined_along_y >
14918  1)
14919  changed |=
14920  cell
14921  ->neighbor_or_periodic_neighbor(i)
14922  ->flag_for_face_refinement(
14923  nb_indices.first,
14924  RefinementCase<dim -
14925  1>::cut_axis(1));
14926  }
14927  else
14928  {
14929  if (cell
14930  ->neighbor_or_periodic_neighbor(i)
14931  ->refine_flag_set() !=
14933  dim>::isotropic_refinement)
14934  changed = true;
14935  cell->neighbor_or_periodic_neighbor(i)
14936  ->set_refine_flag();
14937  }
14938 
14939  // step 4: if necessary (see above) add to
14940  // the refine flag of the current cell
14941  cell_iterator nb =
14942  cell->neighbor_or_periodic_neighbor(i);
14943  RefinementCase<dim - 1> nb_frc =
14945  nb->refine_flag_set(),
14946  nb_indices.first,
14947  nb->face_orientation(nb_indices.first),
14948  nb->face_flip(nb_indices.first),
14949  nb->face_rotation(nb_indices.first));
14950  if ((nb_frc & RefinementCase<dim>::cut_x) &&
14951  !(refined_along_x ||
14952  to_be_refined_along_x))
14953  changed |= cell->flag_for_face_refinement(
14954  i,
14956  if ((nb_frc & RefinementCase<dim>::cut_y) &&
14957  !(refined_along_y ||
14958  to_be_refined_along_y))
14959  changed |= cell->flag_for_face_refinement(
14960  i,
14962  }
14963  } // if neighbor is coarser
14964  else // -> now the neighbor is not coarser
14965  {
14966  cell->neighbor_or_periodic_neighbor(i)
14967  ->clear_coarsen_flag();
14968  const unsigned int nb_nb =
14969  has_periodic_neighbor ?
14970  cell
14971  ->periodic_neighbor_of_periodic_neighbor(
14972  i) :
14973  cell->neighbor_of_neighbor(i);
14974  const cell_iterator neighbor =
14975  cell->neighbor_or_periodic_neighbor(i);
14976  RefinementCase<dim - 1> face_ref_case =
14978  neighbor->refine_flag_set(),
14979  nb_nb,
14980  neighbor->face_orientation(nb_nb),
14981  neighbor->face_flip(nb_nb),
14982  neighbor->face_rotation(nb_nb));
14983  RefinementCase<dim - 1> needed_face_ref_case =
14985  cell->refine_flag_set(),
14986  i,
14987  cell->face_orientation(i),
14988  cell->face_flip(i),
14989  cell->face_rotation(i));
14990  // if the neighbor wants to refine the
14991  // face with cut_x and we want cut_y
14992  // or vice versa, we have to refine
14993  // isotropically at the given face
14994  if ((face_ref_case ==
14996  needed_face_ref_case ==
14998  (face_ref_case ==
15000  needed_face_ref_case ==
15002  {
15003  changed = cell->flag_for_face_refinement(
15004  i, face_ref_case);
15005  neighbor->flag_for_face_refinement(
15006  nb_nb, needed_face_ref_case);
15007  }
15008  }
15009  }
15010  else //-> the neighbor is not active
15011  {
15012  RefinementCase<dim - 1>
15013  face_ref_case = cell->face(i)->refinement_case(),
15014  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 face is refined with cut_x and
15022  // we want cut_y or vice versa, we have to
15023  // refine isotropically at the given face
15024  if ((face_ref_case == RefinementCase<dim>::cut_x &&
15025  needed_face_ref_case ==
15027  (face_ref_case == RefinementCase<dim>::cut_y &&
15028  needed_face_ref_case ==
15030  changed =
15031  cell->flag_for_face_refinement(i,
15032  face_ref_case);
15033  }
15034  }
15035  }
15036  }
15037  }
15038 
15040  // STEP 7:
15041  // take care that no double refinement
15042  // is done at each line in 3d or higher
15043  // dimensions.
15046 
15048  // STEP 8:
15049  // make sure that all children of each
15050  // cell are either flagged for coarsening
15051  // or none of the children is
15052  fix_coarsen_flags();
15053  // get the refinement and coarsening
15054  // flags
15055  std::vector<bool> flags_after_loop[2];
15056  save_coarsen_flags(flags_after_loop[0]);
15057  save_refine_flags(flags_after_loop[1]);
15058 
15059  // find out whether something was
15060  // changed in this loop
15061  mesh_changed_in_this_loop =
15062  ((flags_before_loop[0] != flags_after_loop[0]) ||
15063  (flags_before_loop[1] != flags_after_loop[1]));
15064 
15065  // set the flags for the next loop
15066  // already
15067  flags_before_loop[0].swap(flags_after_loop[0]);
15068  flags_before_loop[1].swap(flags_after_loop[1]);
15069  }
15070  while (mesh_changed_in_this_loop);
15071 
15072 
15073  // find out whether something was really changed in this
15074  // function. Note that @p{flags_before_loop} represents the state
15075  // after the last loop, i.e. the present state
15076  return ((flags_before[0] != flags_before_loop[0]) ||
15077  (flags_before[1] != flags_before_loop[1]));
15078 }
15079 
15080 
15081 
15082 template <int dim, int spacedim>
15083 void
15085  const unsigned int magic_number1,
15086  const std::vector<bool> &v,
15087  const unsigned int magic_number2,
15088  std::ostream & out)
15089 {
15090  const unsigned int N = v.size();
15091  unsigned char * flags = new unsigned char[N / 8 + 1];
15092  for (unsigned int i = 0; i < N / 8 + 1; ++i)
15093  flags[i] = 0;
15094 
15095  for (unsigned int position = 0; position < N; ++position)
15096  flags[position / 8] |= (v[position] ? (1 << (position % 8)) : 0);
15097 
15098  AssertThrow(out, ExcIO());
15099 
15100  // format:
15101  // 0. magic number
15102  // 1. number of flags
15103  // 2. the flags
15104  // 3. magic number
15105  out << magic_number1 << ' ' << N << std::endl;
15106  for (unsigned int i = 0; i < N / 8 + 1; ++i)
15107  out << static_cast<unsigned int>(flags[i]) << ' ';
15108 
15109  out << std::endl << magic_number2 << std::endl;
15110 
15111  delete[] flags;
15112 
15113  AssertThrow(out, ExcIO());
15114 }
15115 
15116 
15117 template <int dim, int spacedim>
15118 void
15119 Triangulation<dim, spacedim>::read_bool_vector(const unsigned int magic_number1,
15120  std::vector<bool> &v,
15121  const unsigned int magic_number2,
15122  std::istream & in)
15123 {
15124  AssertThrow(in, ExcIO());
15125 
15126  unsigned int magic_number;
15127  in >> magic_number;
15128  AssertThrow(magic_number == magic_number1, ExcGridReadError());
15129 
15130  unsigned int N;
15131  in >> N;
15132  v.resize(N);
15133 
15134  unsigned char * flags = new unsigned char[N / 8 + 1];
15135  unsigned short int tmp;
15136  for (unsigned int i = 0; i < N / 8 + 1; ++i)
15137  {
15138  in >> tmp;
15139  flags[i] = tmp;
15140  }
15141 
15142  for (unsigned int position = 0; position != N; ++position)
15143  v[position] = (flags[position / 8] & (1 << (position % 8)));
15144 
15145  in >> magic_number;
15146  AssertThrow(magic_number == magic_number2, ExcGridReadError());
15147 
15148  delete[] flags;
15149 
15150  AssertThrow(in, ExcIO());
15151 }
15152 
15153 
15154 
15155 template <int dim, int spacedim>
15156 std::size_t
15158 {
15159  std::size_t mem = 0;
15161  for (unsigned int i = 0; i < levels.size(); ++i)
15162  mem += MemoryConsumption::memory_consumption(*levels[i]);
15164  mem += MemoryConsumption::memory_consumption(vertices_used);
15165  mem += sizeof(manifold);
15166  mem += sizeof(smooth_grid);
15167  mem += MemoryConsumption::memory_consumption(number_cache);
15168  mem += sizeof(faces);
15169  if (faces)
15171 
15172  return mem;
15173 }
15174 
15175 
15176 // explicit instantiations
15177 #include "tria.inst"
15178 
Triangulation::n_raw_lines
unsigned int n_raw_lines() const
Definition: tria.cc:12892
internal::TriangulationImplementation::NumberCache< 3 >::n_active_hexes_level
std::vector< unsigned int > n_active_hexes_level
Definition: tria.h:297
TriangulationDescription::Description::cell_infos
std::vector< std::vector< CellData< dim > > > cell_infos
Definition: tria_description.h:384
Triangulation::clear_user_flags_quad
void clear_user_flags_quad()
Definition: tria.cc:11125
internal::TriangulationImplementation::Implementation::execute_refinement
static Triangulation< 3, spacedim >::DistortedCellList execute_refinement(Triangulation< 3, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:5255
internal::TriangulationImplementation::Implementation::prevent_distorted_boundary_cells
static void prevent_distorted_boundary_cells(const Triangulation< 1, spacedim > &)
Triangulation::save_user_flags
void save_user_flags(std::ostream &out) const
Definition: tria.cc:11185
Triangulation::Signals::any_change
boost::signals2::signal< void()> any_change
Definition: tria.h:2116
Triangulation::signals
Signals signals
Definition: tria.h:2222
Triangulation::n_faces
unsigned int n_faces() const
Definition: tria.cc:12691
internal::TriangulationImplementation::Implementation::create_triangulation
static void create_triangulation(const std::vector< Point< spacedim >> &v, const std::vector< CellData< 2 >> &cells, const SubCellData &subcelldata, Triangulation< 2, spacedim > &triangulation)
Definition: tria.cc:1954
Triangulation::write_bool_vector
static void write_bool_vector(const unsigned int magic_number1, const std::vector< bool > &v, const unsigned int magic_number2, std::ostream &out)
Definition: tria.cc:15084
internal::TriangulationImplementation::ExcGridHasInvalidCell
static ::ExceptionBase & ExcGridHasInvalidCell(int arg1)
internal::TriangulationImplementation::NumberCache< 2 >::n_active_quads_level
std::vector< unsigned int > n_active_quads_level
Definition: tria.h:237
Triangulation::n_active_quads
unsigned int n_active_quads() const
Definition: tria.cc:13142
Triangulation::save_coarsen_flags
void save_coarsen_flags(std::ostream &out) const
Definition: tria.cc:10953
Triangulation::fix_coarsen_flags
void fix_coarsen_flags()
Definition: tria.cc:13630
Triangulation::load_user_pointers_hex
void load_user_pointers_hex(const std::vector< void * > &v)
Definition: tria.cc:11952
tria_accessor.h
StandardExceptions::ExcIO
static ::ExceptionBase & ExcIO()
internal::TriangulationImplementation
Definition: tria.h:120
GeometryInfo::n_children
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
SubCellData::boundary_quads
std::vector< CellData< 2 > > boundary_quads
Definition: tria_description.h:215
StaticMappingQ1
Definition: mapping_q1.h:88
GridTools::cell_measure< 1 >
double cell_measure< 1 >(const std::vector< Point< 1 >> &all_vertices, const unsigned int(&vertex_indices)[GeometryInfo< 1 >::vertices_per_cell])
Definition: grid_tools_nontemplates.cc:32
CellData::CellData
CellData()
Definition: tria.cc:48
internal::TriangulationImplementation::NumberCache< 3 >::n_hexes
unsigned int n_hexes
Definition: tria.h:282
Triangulation::begin_raw_hex
raw_hex_iterator begin_raw_hex(const unsigned int level=0) const
Definition: tria.cc:12523
Triangulation::end_active
active_cell_iterator end_active(const unsigned int level) const
Definition: tria.cc:12148
mn_tria_refine_flags_end
const unsigned int mn_tria_refine_flags_end
Definition: magic_numbers.h:30
mn_tria_hex_user_flags_begin
const unsigned int mn_tria_hex_user_flags_begin
Definition: magic_numbers.h:37
Triangulation::clear_despite_subscriptions
void clear_despite_subscriptions()
Definition: tria.cc:13507
mn_tria_line_user_flags_end
const unsigned int mn_tria_line_user_flags_end
Definition: magic_numbers.h:34
Triangulation::n_lines
unsigned int n_lines() const
Definition: tria.cc:12819
internal::TriangulationImplementation::NumberCache< 1 >::n_lines
unsigned int n_lines
Definition: tria.h:163
CellData
Definition: tria_description.h:67
internal::TriangulationImplementation::ExcInteriorQuadCantBeBoundary
static ::ExceptionBase & ExcInteriorQuadCantBeBoundary(int arg1, int arg2, int arg3, int arg4, types::boundary_id arg5)
CellAccessor
Definition: tria_accessor.h:2667
Triangulation::load_user_indices_quad
void load_user_indices_quad(const std::vector< unsigned int > &v)
Definition: tria.cc:11704
Triangulation::set_all_refine_flags
void set_all_refine_flags()
Definition: tria.cc:10834
Triangulation::load_user_flags
void load_user_flags(std::istream &in)
Definition: tria.cc:11234
Triangulation::raw_hex_iterator
typename IteratorSelector::raw_hex_iterator raw_hex_iterator
Definition: tria.h:3496
tria_levels.h
StandardExceptions::ExcNotImplemented
static ::ExceptionBase & ExcNotImplemented()
GeometryInfo::alternating_form_at_vertices
static void alternating_form_at_vertices(const Point< spacedim >(&vertices)[vertices_per_cell], Tensor< spacedim - dim, spacedim >(&forms)[vertices_per_cell])
Triangulation::get_triangulation
Triangulation< dim, spacedim > & get_triangulation()
Definition: tria.cc:13338
Triangulation::save_user_flags_hex
void save_user_flags_hex(std::ostream &out) const
Definition: tria.cc:11496
Triangulation
Definition: tria.h:1109
tria.h
internal::TriangulationImplementation::TriaObject::face
int face(const unsigned int i) const
Definition: tria_object.h:168
internal::TriangulationImplementation::ExcLineInexistant
static ::ExceptionBase & ExcLineInexistant(int arg1, int arg2)
Triangulation::raw_quad_iterator
typename IteratorSelector::raw_quad_iterator raw_quad_iterator
Definition: tria.h:3495
Triangulation::n_global_active_cells
virtual types::global_cell_index n_global_active_cells() const
Definition: tria.cc:12682
memory_consumption.h
vertices
std::vector<::Point< spacedim > > vertices
Definition: tria.cc:2247
Triangulation::end_line
line_iterator end_line() const
Definition: tria.cc:12410
Subscriptor::operator=
Subscriptor & operator=(const Subscriptor &)
Definition: subscriptor.h:283
tria_iterator.h
Triangulation::refine_global
void refine_global(const unsigned int times=1)
Definition: tria.cc:10851
mapping_q1.h
Triangulation::save_user_indices_quad
void save_user_indices_quad(std::vector< unsigned int > &v) const
Definition: tria.cc:11686
internal::TriangulationImplementation::Implementation::compute_number_cache
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 3 > &number_cache)
Definition: tria.cc:1662
Threads::Task< void >
LAPACKSupport::U
static const char U
Definition: lapack_support.h:167
GeometryInfo
Definition: geometry_info.h:1224
Triangulation::Signals::clear
boost::signals2::signal< void()> clear
Definition: tria.h:2105
internal::TriangulationImplementation::Implementation::coarsening_allowed
static bool coarsening_allowed(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
Definition: tria.cc:10024
AssertIndexRange
#define AssertIndexRange(index, range)
Definition: exceptions.h:1649
internal::TriangulationImplementation::ExcMultiplySetLineInfoOfLine
static ::ExceptionBase & ExcMultiplySetLineInfoOfLine(int arg1, int arg2)
Triangulation::execute_refinement
DistortedCellList execute_refinement()
Definition: tria.cc:13523
internal::TriangulationImplementation::NumberCache< 1 >::n_lines_level
std::vector< unsigned int > n_lines_level
Definition: tria.h:168
Triangulation::DistortedCellList::distorted_cells
std::list< typename Triangulation< dim, spacedim >::cell_iterator > distorted_cells
Definition: tria.h:1518
Triangulation::active_cell_iterators_on_level
IteratorRange< active_cell_iterator > active_cell_iterators_on_level(const unsigned int level) const
Definition: tria.cc:12207
Triangulation::vertex_to_boundary_id_map_1d
std::unique_ptr< std::map< unsigned int, types::boundary_id > > vertex_to_boundary_id_map_1d
Definition: tria.h:3900
Triangulation::n_active_hexs
unsigned int n_active_hexs() const
Definition: tria.cc:13187
IteratorState::valid
@ valid
Iterator points to a valid object.
Definition: tria_iterator_base.h:38
Physics::Elasticity::Kinematics::e
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
internal::TriangulationImplementation::get_default_flat_manifold
const Manifold< dim, spacedim > & get_default_flat_manifold()
Definition: tria.cc:10090
internal::TriangulationImplementation::Implementation::create_triangulation
static void create_triangulation(const std::vector< Point< spacedim >> &v, const std::vector< CellData< 3 >> &cells, const SubCellData &subcelldata, Triangulation< 3, spacedim > &triangulation)
Definition: tria.cc:2332
Triangulation::get_anisotropic_refinement_flag
bool get_anisotropic_refinement_flag() const
Definition: tria.cc:10999
Triangulation::Signals::mesh_movement
boost::signals2::signal< void()> mesh_movement
Definition: tria.h:2059
numbers::flat_manifold_id
const types::manifold_id flat_manifold_id
Definition: types.h:273
types::boundary_id
unsigned int boundary_id
Definition: types.h:129
Triangulation::load_user_flags_line
void load_user_flags_line(std::istream &in)
Definition: tria.cc:11318
Triangulation::clear_user_data
void clear_user_data()
Definition: tria.cc:11049
GridTools::cell_measure< 2 >
double cell_measure< 2 >(const std::vector< Point< 2 >> &all_vertices, const unsigned int(&vertex_indices)[GeometryInfo< 2 >::vertices_per_cell])
Definition: grid_tools_nontemplates.cc:44
mn_tria_quad_user_flags_end
const unsigned int mn_tria_quad_user_flags_end
Definition: magic_numbers.h:36
internal::TriangulationImplementation::TriaFaces< 3 >
Definition: tria_faces.h:122
Triangulation::save_user_pointers_line
void save_user_pointers_line(std::vector< void * > &v) const
Definition: tria.cc:11870
Triangulation::load_user_flags_quad
void load_user_flags_quad(std::istream &in)
Definition: tria.cc:11441
Triangulation::n_raw_quads
unsigned int n_raw_quads() const
Definition: tria.cc:13123
Threads::new_task
Task< RT > new_task(const std::function< RT()> &function)
Definition: thread_management.h:1647
Triangulation::n_raw_faces
unsigned int n_raw_faces() const
Definition: tria.cc:12710
internal::TriangulationImplementation::ExcInvalidVertexIndex
static ::ExceptionBase & ExcInvalidVertexIndex(int arg1, int arg2, int arg3)
Triangulation::raw_line_iterator
typename IteratorSelector::raw_line_iterator raw_line_iterator
Definition: tria.h:3494
Triangulation::n_raw_hexs
unsigned int n_raw_hexs(const unsigned int level) const
Definition: tria.cc:13179
CellData::vertices
unsigned int vertices[GeometryInfo< structdim >::vertices_per_cell]
Definition: tria_description.h:74
Triangulation::save_user_indices
void save_user_indices(std::vector< unsigned int > &v) const
Definition: tria.cc:11546
Triangulation::active_line_iterator
typename IteratorSelector::active_line_iterator active_line_iterator
Definition: tria.h:1439
Triangulation::~Triangulation
virtual ~Triangulation() override
Definition: tria.cc:10180
Triangulation::get_boundary_ids
virtual std::vector< types::boundary_id > get_boundary_ids() const
Definition: tria.cc:10384
Table
Definition: table.h:699
Triangulation::update_periodic_face_map
void update_periodic_face_map()
Definition: tria.cc:13444
mn_tria_refine_flags_begin
const unsigned int mn_tria_refine_flags_begin
Definition: magic_numbers.h:29
Triangulation::get_mesh_smoothing
virtual const MeshSmoothing & get_mesh_smoothing() const
Definition: tria.cc:10236
Triangulation::end_hex
hex_iterator end_hex() const
Definition: tria.cc:12601
Triangulation::begin_quad
quad_iterator begin_quad(const unsigned int level=0) const
Definition: tria.cc:12478
Triangulation::memory_consumption
virtual std::size_t memory_consumption() const
Definition: tria.cc:15157
Differentiation::SD::fabs
Expression fabs(const Expression &x)
Definition: symengine_math.cc:273
Triangulation::load_user_pointers_line
void load_user_pointers_line(const std::vector< void * > &v)
Definition: tria.cc:11884
Triangulation::set_manifold
void set_manifold(const types::manifold_id number, const Manifold< dim, spacedim > &manifold_object)
Definition: tria.cc:10245
Subscriptor
Definition: subscriptor.h:62
internal::TriangulationImplementation::n_active_cells
unsigned int n_active_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
Definition: tria.cc:12625
GridGenerator::Airfoil::create_triangulation
void create_triangulation(Triangulation< dim, dim > &tria, const AdditionalData &additional_data=AdditionalData())
Triangulation::begin_face
face_iterator begin_face() const
Definition: tria.cc:12221
GridTools::cell_measure< 3 >
double cell_measure< 3 >(const std::vector< Point< 3 >> &all_vertices, const unsigned int(&vertex_indices)[GeometryInfo< 3 >::vertices_per_cell])
Definition: grid_tools_nontemplates.cc:103
level
unsigned int level
Definition: grid_out.cc:4355
Triangulation::hex_iterator
typename IteratorSelector::hex_iterator hex_iterator
Definition: tria.h:1472
Triangulation::manifold
std::map< types::manifold_id, std::unique_ptr< const Manifold< dim, spacedim > > > manifold
Definition: tria.h:3860
magic_numbers.h
mn_tria_coarsen_flags_begin
const unsigned int mn_tria_coarsen_flags_begin
Definition: magic_numbers.h:31
internal::TriangulationImplementation::Implementation::create_triangulation
static void create_triangulation(const std::vector< Point< spacedim >> &v, const std::vector< CellData< 1 >> &cells, const SubCellData &, Triangulation< 1, spacedim > &triangulation)
Definition: tria.cc:1762
Triangulation::save_user_pointers_hex
void save_user_pointers_hex(std::vector< void * > &v) const
Definition: tria.cc:11934
Triangulation::reset_active_cell_indices
void reset_active_cell_indices()
Definition: tria.cc:13426
Triangulation::cell_iterators
IteratorRange< cell_iterator > cell_iterators() const
Definition: tria.cc:12176
internal::TriangulationImplementation::Implementation::delete_children
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:3370
Triangulation::execute_coarsening_and_refinement
virtual void execute_coarsening_and_refinement()
Definition: tria.cc:13385
Triangulation::read_bool_vector
static void read_bool_vector(const unsigned int magic_number1, std::vector< bool > &v, const unsigned int magic_number2, std::istream &in)
Definition: tria.cc:15119
internal::TriangulationImplementation::n_cells
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 3 > &c)
Definition: tria.cc:12648
TransposeTableIterators::Iterator
MatrixTableIterators::Iterator< TransposeTable< T >, Constness, MatrixTableIterators::Storage::column_major > Iterator
Definition: table.h:1913
mn_tria_hex_user_flags_end
const unsigned int mn_tria_hex_user_flags_end
Definition: magic_numbers.h:38
internal::TriangulationImplementation::ExcInconsistentLineInfoOfLine
static ::ExceptionBase & ExcInconsistentLineInfoOfLine(int arg1, int arg2, std::string arg3)
types::material_id
unsigned int material_id
Definition: types.h:152
internal::TriangulationImplementation::TriaFaces< 3 >::lines
TriaObjects< TriaObject< 1 > > lines
Definition: tria_faces.h:134
Triangulation::save_user_indices_line
void save_user_indices_line(std::vector< unsigned int > &v) const
Definition: tria.cc:11658
Triangulation::create_triangulation
virtual void create_triangulation(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
Definition: tria.cc:10521
internal::TriangulationImplementation::Implementation::execute_refinement
static Triangulation< 1, spacedim >::DistortedCellList execute_refinement(Triangulation< 1, spacedim > &triangulation, const bool)
Definition: tria.cc:4686
Triangulation::quad_iterator
typename IteratorSelector::quad_iterator quad_iterator
Definition: tria.h:1448
Triangulation::flip_all_direction_flags
void flip_all_direction_flags()
Definition: tria.cc:10822
Triangulation::end_face
face_iterator end_face() const
Definition: tria.cc:12263
DeclException5
#define DeclException5( Exception5, type1, type2, type3, type4, type5, outsequence)
Definition: exceptions.h:613
Triangulation::n_raw_cells
unsigned int n_raw_cells(const unsigned int level) const
Definition: tria.cc:12748
Triangulation::save_user_flags_line
void save_user_flags_line(std::ostream &out) const
Definition: tria.cc:11304
Triangulation::Triangulation
Triangulation(const MeshSmoothing smooth_grid=none, const bool check_for_distorted_cells=false)
Definition: tria.cc:10106
StandardExceptions::ExcMessage
static ::ExceptionBase & ExcMessage(std::string arg1)
TrilinosWrappers::internal::begin
VectorType::value_type * begin(VectorType &V)
Definition: trilinos_sparse_matrix.cc:51
geometry_info.h
IteratorRange
Definition: iterator_range.h:129
internal::TriangulationImplementation::Implementation::QuadComparator
Definition: tria.cc:2296
Triangulation::begin_active
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: tria.cc:12013
Triangulation::load_user_pointers
void load_user_pointers(const std::vector< void * > &v)
Definition: tria.cc:11833
GridTools::cell_measure
double cell_measure(const std::vector< Point< dim >> &all_vertices, const unsigned int(&vertex_indices)[GeometryInfo< dim >::vertices_per_cell])
CellId
Definition: cell_id.h:69
TriangulationDescription::Description::coarse_cell_vertices
std::vector< Point< spacedim > > coarse_cell_vertices
Definition: tria_description.h:370
Triangulation::DistortedCellList
Definition: tria.h:1503
Triangulation::n_used_vertices
unsigned int n_used_vertices() const
Definition: tria.cc:13253
grid_tools.h
Triangulation::clear_user_flags
void clear_user_flags()
Definition: tria.cc:11174
Triangulation::execute_coarsening
void execute_coarsening()
Definition: tria.cc:13555
Tensor
Definition: tensor.h:450
internal::TriangulationImplementation::NumberCache
Definition: tria.h:136
DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:358
CellData::boundary_id
types::boundary_id boundary_id
Definition: tria_description.h:104
Triangulation::set_all_manifold_ids
void set_all_manifold_ids(const types::manifold_id number)
Definition: tria.cc:10277
Triangulation::reset_all_manifolds
void reset_all_manifolds()
Definition: tria.cc:10269
internal::TriangulationImplementation::Implementation::delete_children
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:3612
RefinementCase
Definition: geometry_info.h:795
Manifold::clone
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const =0
GeometryInfo::child_cell_on_face
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)
Triangulation::n_active_faces
unsigned int n_active_faces() const
Definition: tria.cc:12729
internal::TriangulationImplementation::NumberCache< 3 >::n_active_hexes
unsigned int n_active_hexes
Definition: tria.h:292
MemoryConsumption::memory_consumption
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
Definition: memory_consumption.h:268
Physics::Elasticity::Kinematics::b
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
Physics::Elasticity::Kinematics::l
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
Triangulation::n_quads
unsigned int n_quads() const
Definition: tria.cc:13075
Triangulation::load_user_indices
void load_user_indices(const std::vector< unsigned int > &v)
Definition: tria.cc:11578
Triangulation::begin_raw_quad
raw_quad_iterator begin_raw_quad(const unsigned int level=0) const
Definition: tria.cc:12424
internal::TriangulationImplementation::NumberCache< 1 >::n_levels
unsigned int n_levels
Definition: tria.h:158
Triangulation::save_user_indices_hex
void save_user_indices_hex(std::vector< unsigned int > &v) const
Definition: tria.cc:11721
DeclException3
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:564
internal::TriangulationImplementation::Implementation::compute_number_cache
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 2 > &number_cache)
Definition: tria.cc:1555
internal::TriangulationImplementation::ExcQuadInexistant
static ::ExceptionBase & ExcQuadInexistant(int arg1, int arg2, int arg3, int arg4)
TriangulationDescription::CellData
Definition: tria_description.h:282
Triangulation::begin_raw_line
raw_line_iterator begin_raw_line(const unsigned int level=0) const
Definition: tria.cc:12338
Triangulation::anisotropic_refinement
bool anisotropic_refinement
Definition: tria.h:3865
manifold.h
TrilinosWrappers::internal::end
VectorType::value_type * end(VectorType &V)
Definition: trilinos_sparse_matrix.cc:65
DeclException1
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:518
FlatManifold
Definition: manifold.h:682
internal::TriangulationImplementation::NumberCache< 1 >
Definition: tria.h:153
MemorySpace::swap
void swap(MemorySpaceData< Number, MemorySpace > &, MemorySpaceData< Number, MemorySpace > &)
Definition: memory_space.h:103
GeometryInfo::line_to_cell_vertices
static unsigned int line_to_cell_vertices(const unsigned int line, const unsigned int vertex)
numbers::internal_face_boundary_id
const types::boundary_id internal_face_boundary_id
Definition: types.h:250
Triangulation::add_periodicity
virtual void add_periodicity(const std::vector< GridTools::PeriodicFacePair< cell_iterator >> &)
Definition: tria.cc:13356
numbers
Definition: numbers.h:207
Triangulation::end_quad
quad_iterator end_quad() const
Definition: tria.cc:12510
internal::TriangulationImplementation::ExcInteriorLineCantBeBoundary
static ::ExceptionBase & ExcInteriorLineCantBeBoundary(int arg1, int arg2, types::boundary_id arg3)
Triangulation::active_face_iterators
IteratorRange< active_face_iterator > active_face_iterators() const
Definition: tria.cc:12284
TriaActiveIterator
Definition: tria_iterator.h:759
internal::TriangulationImplementation::NumberCache< 1 >::n_active_lines
unsigned int n_active_lines
Definition: tria.h:173
Triangulation::set_mesh_smoothing
virtual void set_mesh_smoothing(const MeshSmoothing mesh_smoothing)
Definition: tria.cc:10224
internal::TriangulationImplementation::Implementation::execute_refinement
static Triangulation< 2, spacedim >::DistortedCellList execute_refinement(Triangulation< 2, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:4930
internal::TriangulationImplementation::TriaFaces< 2 >
Definition: tria_faces.h:92
Triangulation::save_user_flags_quad
void save_user_flags_quad(std::ostream &out) const
Definition: tria.cc:11427
Triangulation::copy_triangulation
virtual void copy_triangulation(const Triangulation< dim, spacedim > &other_tria)
Definition: tria.cc:10438
DeclException4
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:587
internal::TriangulationImplementation::n_active_cells
unsigned int n_active_cells(const internal::TriangulationImplementation::NumberCache< 3 > &c)
Definition: tria.cc:12655
Triangulation::begin_active_face
active_face_iterator begin_active_face() const
Definition: tria.cc:12242
types::manifold_id
unsigned int manifold_id
Definition: types.h:141
parallel::Triangulation
TriangulationBase< dim, spacedim > Triangulation
Definition: tria_base.h:302
mn_tria_quad_user_flags_begin
const unsigned int mn_tria_quad_user_flags_begin
Definition: magic_numbers.h:35
Triangulation::end_raw
raw_cell_iterator end_raw(const unsigned int level) const
Definition: tria.cc:12090
Triangulation::number_cache
::internal::TriangulationImplementation::NumberCache< dim > number_cache
Definition: tria.h:3883
internal::TriangulationImplementation::TriaObjects::clear_user_data
void clear_user_data(const unsigned int i)
Definition: tria_objects.h:671
internal::dummy
const types::global_dof_index * dummy()
Definition: dof_handler.cc:59
TriaRawIterator::state
IteratorState::IteratorStates state() const
Definition: tria_iterator.h:1051
Triangulation::save_user_pointers
void save_user_pointers(std::vector< void * > &v) const
Definition: tria.cc:11802
Triangulation::load_user_indices_hex
void load_user_indices_hex(const std::vector< unsigned int > &v)
Definition: tria.cc:11739
unsigned int
Triangulation::begin_hex
hex_iterator begin_hex(const unsigned int level=0) const
Definition: tria.cc:12569
Triangulation::end_vertex
vertex_iterator end_vertex() const
Definition: tria.cc:12323
StandardExceptions::ExcInternalError
static ::ExceptionBase & ExcInternalError()
Triangulation::reset_manifold
void reset_manifold(const types::manifold_id manifold_number)
Definition: tria.cc:10258
vertex_indices
std::vector< unsigned int > vertex_indices
Definition: tria.cc:2244
internal::TriangulationImplementation::NumberCache< 3 >
Definition: tria.h:277
internal::TriangulationImplementation::NumberCache< 1 >::n_active_lines_level
std::vector< unsigned int > n_active_lines_level
Definition: tria.h:178
internal::TriangulationImplementation::NumberCache< 3 >::n_hexes_level
std::vector< unsigned int > n_hexes_level
Definition: tria.h:287
Assert
#define Assert(cond, exc)
Definition: exceptions.h:1419
internal::TriangulationImplementation::Implementation
Definition: tria.cc:1452
Triangulation::last_active
active_cell_iterator last_active() const
Definition: tria.cc:12058
internal::TriangulationImplementation::TriaObjects::cells
std::vector< G > cells
Definition: tria_objects.h:81
SubCellData::check_consistency
bool check_consistency(const unsigned int dim) const
Definition: tria.cc:82
Triangulation::last
cell_iterator last() const
Definition: tria.cc:12033
Triangulation::Signals::create
boost::signals2::signal< void()> create
Definition: tria.h:2026
internal::TriangulationImplementation::Implementation::prepare_refinement_dim_dependent
static void prepare_refinement_dim_dependent(Triangulation< 3, spacedim > &triangulation)
Definition: tria.cc:9823
internal::TriangulationImplementation::Implementation::prepare_refinement_dim_dependent
static void prepare_refinement_dim_dependent(const Triangulation< dim, spacedim > &)
Definition: tria.cc:9814
InvalidAccessor
Definition: tria_accessor.h:558
Triangulation::active_quad_iterator
typename IteratorSelector::active_quad_iterator active_quad_iterator
Definition: tria.h:1463
vector.h
internal::TriangulationImplementation::TriaObject< 1 >
Triangulation< dim >::MeshSmoothing
MeshSmoothing
Definition: tria.h:1124
Triangulation::vertices_used
std::vector< bool > vertices_used
Definition: tria.h:3853
internal::TriangulationImplementation::Implementation::QuadComparator::operator()
bool operator()(const internal::TriangulationImplementation::TriaObject< 2 > &q1, const internal::TriangulationImplementation::TriaObject< 2 > &q2) const
Definition: tria.cc:2299
mn_tria_coarsen_flags_end
const unsigned int mn_tria_coarsen_flags_end
Definition: magic_numbers.h:32
StandardExceptions::ExcImpossibleInDim
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
Triangulation::begin_vertex
vertex_iterator begin_vertex() const
Definition: tria.cc:12296
Triangulation::cell_iterators_on_level
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
Definition: tria.cc:12196
Triangulation::Signals::post_refinement
boost::signals2::signal< void()> post_refinement
Definition: tria.h:2042
GridTools::PeriodicFacePair
Definition: grid_tools.h:2463
tria_faces.h
numbers::invalid_unsigned_int
static const unsigned int invalid_unsigned_int
Definition: types.h:191
Triangulation::n_active_lines
unsigned int n_active_lines() const
Definition: tria.cc:12910
Triangulation::prepare_coarsening_and_refinement
virtual bool prepare_coarsening_and_refinement()
Definition: tria.cc:14083
Triangulation::locally_owned_subdomain
virtual types::subdomain_id locally_owned_subdomain() const
Definition: tria.cc:13329
Triangulation::vertices
std::vector< Point< spacedim > > vertices
Definition: tria.h:3848
internal::TriangulationImplementation::TriaFaces< 2 >::lines
TriaObjects< TriaObject< 1 > > lines
Definition: tria_faces.h:98
Point< dim >
Triangulation::n_active_cells
unsigned int n_active_cells() const
Definition: tria.cc:12675
Triangulation::begin_active_quad
active_quad_iterator begin_active_quad(const unsigned int level=0) const
Definition: tria.cc:12494
Triangulation::load_coarsen_flags
void load_coarsen_flags(std::istream &out)
Definition: tria.cc:10967
Triangulation::faces
std::unique_ptr<::internal::TriangulationImplementation::TriaFaces< dim > > faces
Definition: tria.h:3842
internal::TriangulationImplementation::Implementation::compute_number_cache
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 1 > &number_cache)
Definition: tria.cc:1467
internal::TriangulationImplementation::NumberCache< 2 >::n_quads
unsigned int n_quads
Definition: tria.h:222
Triangulation::load_user_indices_line
void load_user_indices_line(const std::vector< unsigned int > &v)
Definition: tria.cc:11672
AssertNothrow
#define AssertNothrow(cond, exc)
Definition: exceptions.h:1483
Triangulation::begin_line
line_iterator begin_line(const unsigned int level=0) const
Definition: tria.cc:12378
Triangulation::begin_active_line
active_line_iterator begin_active_line(const unsigned int level=0) const
Definition: tria.cc:12394
Triangulation::n_hexs
unsigned int n_hexs() const
Definition: tria.cc:13161
internal::TriangulationImplementation::TriaFaces
Definition: tria_faces.h:50
numbers::invalid_subdomain_id
const types::subdomain_id invalid_subdomain_id
Definition: types.h:285
internal::TriangulationImplementation::Implementation::create_children
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, typename Triangulation< 2, spacedim >::cell_iterator &cell)
Definition: tria.cc:4243
internal::TriangulationImplementation::TriaFaces< 3 >::quads
TriaObjectsQuad3D quads
Definition: tria_faces.h:129
triangulation
const typename ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
Definition: p4est_wrappers.cc:69
internal
Definition: aligned_vector.h:369
GeometryInfo::face_refinement_case
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)
Triangulation::begin
cell_iterator begin(const unsigned int level=0) const
Definition: tria.cc:11993
GridTools::rotate
void rotate(const double angle, Triangulation< dim > &triangulation)
LAPACKSupport::N
static const char N
Definition: lapack_support.h:159
Triangulation::load_user_pointers_quad
void load_user_pointers_quad(const std::vector< void * > &v)
Definition: tria.cc:11917
memory.h
Manifold
Definition: manifold.h:334
Triangulation::active_cell_iterators
IteratorRange< active_cell_iterator > active_cell_iterators() const
Definition: tria.cc:12185
Triangulation::save_user_pointers_quad
void save_user_pointers_quad(std::vector< void * > &v) const
Definition: tria.cc:11899
SubCellData::boundary_lines
std::vector< CellData< 1 > > boundary_lines
Definition: tria_description.h:207
TriangulationDescription::Description
Definition: tria_description.h:347
GeometryInfo::min_cell_refinement_case_for_face_refinement
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)
SubCellData
Definition: tria_description.h:199
Triangulation::vertex_to_manifold_id_map_1d
std::unique_ptr< std::map< unsigned int, types::manifold_id > > vertex_to_manifold_id_map_1d
Definition: tria.h:3923
Triangulation::create_triangulation_compatibility
virtual void create_triangulation_compatibility(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
Definition: tria.cc:10501
internal::TriangulationImplementation::n_cells
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
Definition: tria.cc:12618
CellData::material_id
types::material_id material_id
Definition: tria_description.h:93
internal::TriangulationImplementation::NumberCache< 2 >::n_active_quads
unsigned int n_active_quads
Definition: tria.h:232
DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:359
Triangulation::active_hex_iterator
typename IteratorSelector::active_hex_iterator active_hex_iterator
Definition: tria.h:1483
Triangulation::begin_active_hex
active_hex_iterator begin_active_hex(const unsigned int level=0) const
Definition: tria.cc:12585
Triangulation::set_all_manifold_ids_on_boundary
void set_all_manifold_ids_on_boundary(const types::manifold_id number)
Definition: tria.cc:10296
MeshWorker::loop
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:443
Triangulation::operator=
Triangulation & operator=(Triangulation< dim, spacedim > &&tria) noexcept
Definition: tria.cc:10155
internal::TriangulationImplementation::Implementation::delete_children
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:3474
Triangulation::n_cells
unsigned int n_cells() const
Definition: tria.cc:12667
Triangulation::begin_active_vertex
active_vertex_iterator begin_active_vertex() const
Definition: tria.cc:12313
Triangulation::clear_user_flags_hex
void clear_user_flags_hex()
Definition: tria.cc:11165
Threads::Task::join
void join() const
Definition: thread_management.h:1525
first
Point< 2 > first
Definition: grid_out.cc:4352
Triangulation::save_refine_flags
void save_refine_flags(std::ostream &out) const
Definition: tria.cc:10885
Triangulation::clear_user_flags_line
void clear_user_flags_line()
Definition: tria.cc:11084
Triangulation::get_used_vertices
const std::vector< bool > & get_used_vertices() const
Definition: tria.cc:13262
internal::TriangulationImplementation::ExcCellHasNegativeMeasure
static ::ExceptionBase & ExcCellHasNegativeMeasure(int arg1)
Triangulation::has_hanging_nodes
virtual bool has_hanging_nodes() const
Definition: tria.cc:12807
Triangulation::begin_raw
raw_cell_iterator begin_raw(const unsigned int level=0) const
Definition: tria.cc:11973
TriaIterator
Definition: tria_iterator.h:578
internal::TriangulationImplementation::TriaLevel< 3 >
Definition: tria_levels.h:222
internal::TriangulationImplementation::NumberCache< 2 >
Definition: tria.h:217
DeclException2
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:541
Triangulation::line_iterator
typename IteratorSelector::line_iterator line_iterator
Definition: tria.h:1424
internal::TriangulationImplementation::ExcInternalErrorOnCell
static ::ExceptionBase & ExcInternalErrorOnCell(int arg1)
internal::TriangulationImplementation::NumberCache< 2 >::n_quads_level
std::vector< unsigned int > n_quads_level
Definition: tria.h:227
AssertThrow
#define AssertThrow(cond, exc)
Definition: exceptions.h:1531
TriangulationDescription::Description::coarse_cells
std::vector<::CellData< dim > > coarse_cells
Definition: tria_description.h:365
Triangulation::max_adjacent_cells
unsigned int max_adjacent_cells() const
Definition: tria.cc:13296
mn_tria_line_user_flags_begin
const unsigned int mn_tria_line_user_flags_begin
Definition: magic_numbers.h:33
Triangulation::clear
virtual void clear()
Definition: tria.cc:10209
internal::TriangulationImplementation::Implementation::prevent_distorted_boundary_cells
static void prevent_distorted_boundary_cells(Triangulation< dim, spacedim > &triangulation)
Definition: tria.cc:9732
Triangulation::load_refine_flags
void load_refine_flags(std::istream &in)
Definition: tria.cc:10899
Triangulation::smooth_grid
MeshSmoothing smooth_grid
Definition: tria.h:3419
CellData::operator==
bool operator==(const CellData< structdim > &other) const
Definition: tria.cc:61
internal::TriangulationImplementation::TriaObject::set_face
void set_face(const unsigned int i, const int index)
Definition: tria_object.h:178
full_matrix.h
internal::TriangulationImplementation::ExcInconsistentQuadInfoOfQuad
static ::ExceptionBase & ExcInconsistentQuadInfoOfQuad(int arg1, int arg2, int arg3, int arg4, std::string arg5)
Triangulation::get_manifold
const Manifold< dim, spacedim > & get_manifold(const types::manifold_id number) const
Definition: tria.cc:10361
Utilities::MPI::max
T max(const T &t, const MPI_Comm &mpi_communicator)
Triangulation::get_manifold_ids
virtual std::vector< types::manifold_id > get_manifold_ids() const
Definition: tria.cc:10416
internal::TriangulationImplementation::TriaLevel
Definition: tria_levels.h:58
Triangulation::end
cell_iterator end() const
Definition: tria.cc:12079
TriaAccessorExceptions::ExcFacesHaveNoLevel
static ::ExceptionBase & ExcFacesHaveNoLevel()
Triangulation::get_periodic_face_map
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
Definition: tria.cc:13376
int
Triangulation::levels
std::vector< std::unique_ptr< ::internal::TriangulationImplementation::TriaLevel< dim > > > levels
Definition: tria.h:3834
internal::TriangulationImplementation::TriaFaces< 1 >
Definition: tria_faces.h:69
TriaRawIterator
Definition: tria_iterator.h:232
Triangulation::load_user_flags_hex
void load_user_flags_hex(std::istream &in)
Definition: tria.cc:11510
CellData::manifold_id
types::manifold_id manifold_id
Definition: tria_description.h:115