Reference documentation for deal.II version 9.1.1
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
tria.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2019 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #include <deal.II/base/geometry_info.h>
18 #include <deal.II/base/memory_consumption.h>
19 #include <deal.II/base/std_cxx14/memory.h>
20 
21 #include <deal.II/fe/mapping_q1.h>
22 
23 #include <deal.II/grid/grid_tools.h>
24 #include <deal.II/grid/magic_numbers.h>
25 #include <deal.II/grid/manifold.h>
26 #include <deal.II/grid/tria.h>
27 #include <deal.II/grid/tria_accessor.h>
28 #include <deal.II/grid/tria_faces.h>
29 #include <deal.II/grid/tria_iterator.h>
30 #include <deal.II/grid/tria_levels.h>
31 
32 #include <deal.II/lac/full_matrix.h>
33 #include <deal.II/lac/vector.h>
34 
35 #include <algorithm>
36 #include <array>
37 #include <cmath>
38 #include <functional>
39 #include <list>
40 #include <map>
41 #include <numeric>
42 
43 
44 DEAL_II_NAMESPACE_OPEN
45 
46 bool
47 SubCellData::check_consistency(const unsigned int dim) const
48 {
49  switch (dim)
50  {
51  case 1:
52  return ((boundary_lines.size() == 0) && (boundary_quads.size() == 0));
53  case 2:
54  return (boundary_quads.size() == 0);
55  }
56  return true;
57 }
58 
59 
60 namespace internal
61 {
62  namespace TriangulationImplementation
63  {
65  : n_levels(0)
66  , n_lines(0)
67  , n_active_lines(0)
68  // all other fields are
69  // default constructed
70  {}
71 
72 
73 
74  std::size_t
76  {
77  return (MemoryConsumption::memory_consumption(n_levels) +
81  MemoryConsumption::memory_consumption(n_active_lines_level));
82  }
83 
84 
86  : n_quads(0)
87  , n_active_quads(0)
88  // all other fields are
89  // default constructed
90  {}
91 
92 
93 
94  std::size_t
96  {
100  MemoryConsumption::memory_consumption(n_active_quads) +
101  MemoryConsumption::memory_consumption(n_active_quads_level));
102  }
103 
104 
105 
107  : n_hexes(0)
108  , n_active_hexes(0)
109  // all other fields are
110  // default constructed
111  {}
112 
113 
114 
115  std::size_t
117  {
121  MemoryConsumption::memory_consumption(n_active_hexes) +
122  MemoryConsumption::memory_consumption(n_active_hexes_level));
123  }
124  } // namespace TriangulationImplementation
125 } // namespace internal
126 
127 // anonymous namespace for internal helper functions
128 namespace
129 {
130  // return whether the given cell is
131  // patch_level_1, i.e. determine
132  // whether either all or none of
133  // its children are further
134  // refined. this function can only
135  // be called for non-active cells.
136  template <int dim, int spacedim>
137  bool
138  cell_is_patch_level_1(
140  {
141  Assert(cell->active() == false, ExcInternalError());
142 
143  unsigned int n_active_children = 0;
144  for (unsigned int i = 0; i < cell->n_children(); ++i)
145  if (cell->child(i)->active())
146  ++n_active_children;
147 
148  return (n_active_children == 0) ||
149  (n_active_children == cell->n_children());
150  }
151 
152 
153 
154  // return, whether a given @p cell will be
155  // coarsened, which is the case if all
156  // children are active and have their coarsen
157  // flag set. In case only part of the coarsen
158  // flags are set, remove them.
159  template <int dim, int spacedim>
160  bool
161  cell_will_be_coarsened(
163  {
164  // only cells with children should be
165  // considered for coarsening
166 
167  if (cell->has_children())
168  {
169  unsigned int children_to_coarsen = 0;
170  const unsigned int n_children = cell->n_children();
171 
172  for (unsigned int c = 0; c < n_children; ++c)
173  if (cell->child(c)->active() && cell->child(c)->coarsen_flag_set())
174  ++children_to_coarsen;
175  if (children_to_coarsen == n_children)
176  return true;
177  else
178  for (unsigned int c = 0; c < n_children; ++c)
179  if (cell->child(c)->active())
180  cell->child(c)->clear_coarsen_flag();
181  }
182  // no children, so no coarsening
183  // possible. however, no children also
184  // means that this cell will be in the same
185  // state as if it had children and was
186  // coarsened. So, what should we return -
187  // false or true?
188  // make sure we do not have to do this at
189  // all...
190  Assert(cell->has_children(), ExcInternalError());
191  // ... and then simply return false
192  return false;
193  }
194 
195 
196  // return, whether the face @p face_no of the
197  // given @p cell will be refined after the
198  // current refinement step, considering
199  // refine and coarsen flags and considering
200  // only those refinemnts that will be caused
201  // by the neighboring cell.
202 
203  // this function is used on both active cells
204  // and cells with children. on cells with
205  // children it also of interest to know 'how'
206  // the face will be refined. thus there is an
207  // additional third argument @p
208  // expected_face_ref_case returning just
209  // that. be aware, that this vriable will
210  // only contain useful information if this
211  // function is called for an active cell.
212  //
213  // thus, this is an internal function, users
214  // should call one of the two alternatives
215  // following below.
216  template <int dim, int spacedim>
217  bool
218  face_will_be_refined_by_neighbor_internal(
220  const unsigned int face_no,
221  RefinementCase<dim - 1> &expected_face_ref_case)
222  {
223  // first of all: set the default value for
224  // expected_face_ref_case, which is no
225  // refinement at all
226  expected_face_ref_case = RefinementCase<dim - 1>::no_refinement;
227 
228  const typename Triangulation<dim, spacedim>::cell_iterator neighbor =
229  cell->neighbor(face_no);
230 
231  // If we are at the boundary, there is no
232  // neighbor which could refine the face
233  if (neighbor.state() != IteratorState::valid)
234  return false;
235 
236  if (neighbor->has_children())
237  {
238  // if the neighbor is refined, it may be
239  // coarsened. if so, then it won't refine
240  // the face, no matter what else happens
241  if (cell_will_be_coarsened(neighbor))
242  return false;
243  else
244  // if the neighor is refined, then he
245  // is also refined at our current
246  // face. He will stay so without
247  // coarsening, so return true in that
248  // case.
249  {
250  expected_face_ref_case = cell->face(face_no)->refinement_case();
251  return true;
252  }
253  }
254 
255  // now, the neighbor is not refined, but
256  // perhaps he will be
257  const RefinementCase<dim> nb_ref_flag = neighbor->refine_flag_set();
258  if (nb_ref_flag != RefinementCase<dim>::no_refinement)
259  {
260  // now we need to know, which of the
261  // neighbors faces points towards us
262  const unsigned int neighbor_neighbor = cell->neighbor_face_no(face_no);
263  // check, whether the cell will be
264  // refined in a way that refines our
265  // face
266  const RefinementCase<dim - 1> face_ref_case =
268  nb_ref_flag,
269  neighbor_neighbor,
270  neighbor->face_orientation(neighbor_neighbor),
271  neighbor->face_flip(neighbor_neighbor),
272  neighbor->face_rotation(neighbor_neighbor));
273  if (face_ref_case != RefinementCase<dim - 1>::no_refinement)
274  {
276  neighbor_face = neighbor->face(neighbor_neighbor);
277  const int this_face_index = cell->face_index(face_no);
278 
279  // there are still two basic
280  // possibilities here: the neighbor
281  // might be coarser or as coarse
282  // as we are
283  if (neighbor_face->index() == this_face_index)
284  // the neighbor is as coarse as
285  // we are and will be refined at
286  // the face of consideration, so
287  // return true
288  {
289  expected_face_ref_case = face_ref_case;
290  return true;
291  }
292  else
293  {
294  // the neighbor is coarser.
295  // this is the most complicated
296  // case. It might be, that the
297  // neighbor's face will be
298  // refined, but that we will
299  // not see this, as we are
300  // refined in a similar way.
301 
302  // so, the neighbor's face must
303  // have children. check, if our
304  // cell's face is one of these
305  // (it could also be a
306  // grand_child)
307  for (unsigned int c = 0; c < neighbor_face->n_children(); ++c)
308  if (neighbor_face->child_index(c) == this_face_index)
309  {
310  // if the flagged refine
311  // case of the face is a
312  // subset or the same as
313  // the current refine case,
314  // then the face, as seen
315  // from our cell, won't be
316  // refined by the neighbor
317  if ((neighbor_face->refinement_case() | face_ref_case) ==
318  neighbor_face->refinement_case())
319  return false;
320  else
321  {
322  // if we are active, we
323  // must be an
324  // anisotropic child
325  // and the coming
326  // face_ref_case is
327  // isotropic. Thus,
328  // from our cell we
329  // will see exactly the
330  // opposite refine case
331  // that the face has
332  // now...
333  Assert(
334  face_ref_case ==
336  ExcInternalError());
337  expected_face_ref_case =
338  ~neighbor_face->refinement_case();
339  return true;
340  }
341  }
342 
343  // so, obviously we were not
344  // one of the children, but a
345  // grandchild. This is only
346  // possible in 3d.
347  Assert(dim == 3, ExcInternalError());
348  // In that case, however, no
349  // matter what the neighbor
350  // does, he won't be finer
351  // after the next refinement
352  // step.
353  return false;
354  }
355  } // if face will be refined
356  } // if neighbor is flagged for refinement
357 
358  // no cases left, so the neighbor will not
359  // refine the face
360  return false;
361  }
362 
363  // version of above function for both active
364  // and non-active cells
365  template <int dim, int spacedim>
366  bool
367  face_will_be_refined_by_neighbor(
369  const unsigned int face_no)
370  {
371  RefinementCase<dim - 1> dummy = RefinementCase<dim - 1>::no_refinement;
372  return face_will_be_refined_by_neighbor_internal(cell, face_no, dummy);
373  }
374 
375  // version of above function for active cells
376  // only. Additionally returning the refine
377  // case (to come) of the face under
378  // consideration
379  template <int dim, int spacedim>
380  bool
381  face_will_be_refined_by_neighbor(
383  const unsigned int face_no,
384  RefinementCase<dim - 1> &expected_face_ref_case)
385  {
386  return face_will_be_refined_by_neighbor_internal(cell,
387  face_no,
388  expected_face_ref_case);
389  }
390 
391 
392 
393  template <int dim, int spacedim>
394  bool
395  satisfies_level1_at_vertex_rule(
396  const Triangulation<dim, spacedim> &triangulation)
397  {
398  std::vector<unsigned int> min_adjacent_cell_level(
399  triangulation.n_vertices(), triangulation.n_levels());
400  std::vector<unsigned int> max_adjacent_cell_level(
401  triangulation.n_vertices(), 0);
402 
404  triangulation.begin_active();
405  cell != triangulation.end();
406  ++cell)
407  for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; ++v)
408  {
409  min_adjacent_cell_level[cell->vertex_index(v)] =
410  std::min<unsigned int>(
411  min_adjacent_cell_level[cell->vertex_index(v)], cell->level());
412  max_adjacent_cell_level[cell->vertex_index(v)] =
413  std::max<unsigned int>(
414  min_adjacent_cell_level[cell->vertex_index(v)], cell->level());
415  }
416 
417  for (unsigned int k = 0; k < triangulation.n_vertices(); ++k)
418  if (triangulation.vertex_used(k))
419  if (max_adjacent_cell_level[k] - min_adjacent_cell_level[k] > 1)
420  return false;
421  return true;
422  }
423 
424 
425 
432  template <int dim, int spacedim>
433  std::vector<unsigned int>
434  count_cells_bounded_by_line(const Triangulation<dim, spacedim> &triangulation)
435  {
436  if (dim >= 2)
437  {
438  std::vector<unsigned int> line_cell_count(triangulation.n_raw_lines(),
439  0);
441  cell = triangulation.begin(),
442  endc = triangulation.end();
443  for (; cell != endc; ++cell)
444  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
445  ++line_cell_count[cell->line_index(l)];
446  return line_cell_count;
447  }
448  else
449  return std::vector<unsigned int>();
450  }
451 
452 
453 
460  template <int dim, int spacedim>
461  std::vector<unsigned int>
462  count_cells_bounded_by_quad(const Triangulation<dim, spacedim> &triangulation)
463  {
464  if (dim >= 3)
465  {
466  std::vector<unsigned int> quad_cell_count(triangulation.n_raw_quads(),
467  0);
469  cell = triangulation.begin(),
470  endc = triangulation.end();
471  for (; cell != endc; ++cell)
472  for (unsigned int q = 0; q < GeometryInfo<dim>::faces_per_cell; ++q)
473  ++quad_cell_count[cell->quad_index(q)];
474  return quad_cell_count;
475  }
476  else
477  return std::vector<unsigned int>();
478  }
479 
480 
481 
493  void
494  reorder_compatibility(const std::vector<CellData<1>> &, const SubCellData &)
495  {
496  // nothing to do here: the format
497  // hasn't changed for 1d
498  }
499 
500 
501  void reorder_compatibility(std::vector<CellData<2>> &cells,
502  const SubCellData &)
503  {
504  for (auto &cell : cells)
505  std::swap(cell.vertices[2], cell.vertices[3]);
506  }
507 
508 
509  void reorder_compatibility(std::vector<CellData<3>> &cells,
510  SubCellData & subcelldata)
511  {
512  unsigned int tmp[GeometryInfo<3>::vertices_per_cell];
513  for (auto &cell : cells)
514  {
515  for (unsigned int i = 0; i < GeometryInfo<3>::vertices_per_cell; ++i)
516  tmp[i] = cell.vertices[i];
517  for (unsigned int i = 0; i < GeometryInfo<3>::vertices_per_cell; ++i)
518  cell.vertices[GeometryInfo<3>::ucd_to_deal[i]] = tmp[i];
519  }
520 
521  // now points in boundary quads
522  std::vector<CellData<2>>::iterator boundary_quad =
523  subcelldata.boundary_quads.begin();
524  std::vector<CellData<2>>::iterator end_quad =
525  subcelldata.boundary_quads.end();
526  for (unsigned int quad_no = 0; boundary_quad != end_quad;
527  ++boundary_quad, ++quad_no)
528  std::swap(boundary_quad->vertices[2], boundary_quad->vertices[3]);
529  }
530 
531 
532 
550  template <int dim, int spacedim>
551  unsigned int
552  middle_vertex_index(
553  const typename Triangulation<dim, spacedim>::line_iterator &line)
554  {
555  if (line->has_children())
556  return line->child(0)->vertex_index(1);
558  }
559 
560 
561  template <int dim, int spacedim>
562  unsigned int
563  middle_vertex_index(
564  const typename Triangulation<dim, spacedim>::quad_iterator &quad)
565  {
566  switch (static_cast<unsigned char>(quad->refinement_case()))
567  {
569  return middle_vertex_index<dim, spacedim>(quad->child(0)->line(1));
570  break;
572  return middle_vertex_index<dim, spacedim>(quad->child(0)->line(3));
573  break;
575  return quad->child(0)->vertex_index(3);
576  break;
577  default:
578  break;
579  }
581  }
582 
583 
584  template <int dim, int spacedim>
585  unsigned int
586  middle_vertex_index(
587  const typename Triangulation<dim, spacedim>::hex_iterator &hex)
588  {
589  switch (static_cast<unsigned char>(hex->refinement_case()))
590  {
592  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(1));
593  break;
595  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(3));
596  break;
598  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(5));
599  break;
601  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(11));
602  break;
604  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(5));
605  break;
607  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(7));
608  break;
610  return hex->child(0)->vertex_index(7);
611  break;
612  default:
613  break;
614  }
616  }
617 
618 
631  template <class TRIANGULATION>
632  inline typename TRIANGULATION::DistortedCellList
633  collect_distorted_coarse_cells(const TRIANGULATION &)
634  {
635  return typename TRIANGULATION::DistortedCellList();
636  }
637 
638 
639 
648  template <int dim>
650  collect_distorted_coarse_cells(const Triangulation<dim, dim> &triangulation)
651  {
652  typename Triangulation<dim, dim>::DistortedCellList distorted_cells;
653  for (typename Triangulation<dim, dim>::cell_iterator cell =
654  triangulation.begin(0);
655  cell != triangulation.end(0);
656  ++cell)
657  {
659  for (unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
660  vertices[i] = cell->vertex(i);
661 
663  GeometryInfo<dim>::alternating_form_at_vertices(vertices, determinants);
664 
665  for (unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
666  if (determinants[i] <= 1e-9 * std::pow(cell->diameter(), 1. * dim))
667  {
668  distorted_cells.distorted_cells.push_back(cell);
669  break;
670  }
671  }
672 
673  return distorted_cells;
674  }
675 
676 
683  template <int dim>
684  bool
685  has_distorted_children(
686  const typename Triangulation<dim, dim>::cell_iterator &cell,
687  std::integral_constant<int, dim>,
688  std::integral_constant<int, dim>)
689  {
690  Assert(cell->has_children(), ExcInternalError());
691 
692  for (unsigned int c = 0; c < cell->n_children(); ++c)
693  {
695  for (unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
696  vertices[i] = cell->child(c)->vertex(i);
697 
699  GeometryInfo<dim>::alternating_form_at_vertices(vertices, determinants);
700 
701  for (unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
702  if (determinants[i] <=
703  1e-9 * std::pow(cell->child(c)->diameter(), 1. * dim))
704  return true;
705  }
706 
707  return false;
708  }
709 
710 
718  template <int dim, int spacedim>
719  bool
720  has_distorted_children(
722  std::integral_constant<int, dim>,
723  std::integral_constant<int, spacedim>)
724  {
725  return false;
726  }
727 
728 
729 
734  template <int spacedim>
735  void update_neighbors(Triangulation<1, spacedim> &)
736  {}
737 
738 
739  template <int dim, int spacedim>
740  void
741  update_neighbors(Triangulation<dim, spacedim> &triangulation)
742  {
743  // each face can be neighbored on two sides
744  // by cells. according to the face's
745  // intrinsic normal we define the left
746  // neighbor as the one for which the face
747  // normal points outward, and store that
748  // one first; the second one is then
749  // the right neighbor for which the
750  // face normal points inward. This
751  // information depends on the type of cell
752  // and local number of face for the
753  // 'standard ordering and orientation' of
754  // faces and then on the face_orientation
755  // information for the real mesh. Set up a
756  // table to have fast access to those
757  // offsets (0 for left and 1 for
758  // right). Some of the values are invalid
759  // as they reference too large face
760  // numbers, but we just leave them at a
761  // zero value.
762  //
763  // Note, that in 2d for lines as faces the
764  // normal direction given in the
765  // GeometryInfo class is not consistent. We
766  // thus define here that the normal for a
767  // line points to the right if the line
768  // points upwards.
769  //
770  // There is one more point to
771  // consider, however: if we have
772  // dim<spacedim, then we may have
773  // cases where cells are
774  // inverted. In effect, both
775  // cells think they are the left
776  // neighbor of an edge, for
777  // example, which leads us to
778  // forget neighborship
779  // information (a case that shows
780  // this is
781  // codim_one/hanging_nodes_02). We
782  // store whether a cell is
783  // inverted using the
784  // direction_flag, so if a cell
785  // has a false direction_flag,
786  // then we need to invert our
787  // selection whether we are a
788  // left or right neighbor in all
789  // following computations.
790  //
791  // first index: dimension (minus 2)
792  // second index: local face index
793  // third index: face_orientation (false and true)
794  static const unsigned int left_right_offset[2][6][2] = {
795  // quadrilateral
796  {{0, 1}, // face 0, face_orientation = false and true
797  {1, 0}, // face 1, face_orientation = false and true
798  {1, 0}, // face 2, face_orientation = false and true
799  {0, 1}, // face 3, face_orientation = false and true
800  {0, 0}, // face 4, invalid face
801  {0, 0}}, // face 5, invalid face
802  // hexahedron
803  {{0, 1}, {1, 0}, {0, 1}, {1, 0}, {0, 1}, {1, 0}}};
804 
805  // now create a vector of the two active
806  // neighbors (left and right) for each face
807  // and fill it by looping over all cells. For
808  // cases with anisotropic refinement and more
809  // then one cell neighboring at a given side
810  // of the face we will automatically get the
811  // active one on the highest level as we loop
812  // over cells from lower levels first.
813  const typename Triangulation<dim, spacedim>::cell_iterator dummy;
814  std::vector<typename Triangulation<dim, spacedim>::cell_iterator>
815  adjacent_cells(2 * triangulation.n_raw_faces(), dummy);
816 
817  typename Triangulation<dim, spacedim>::cell_iterator cell = triangulation
818  .begin(),
819  endc =
820  triangulation.end();
821  for (; cell != endc; ++cell)
822  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
823  {
824  const typename Triangulation<dim, spacedim>::face_iterator face =
825  cell->face(f);
826 
827  const unsigned int offset =
828  (cell->direction_flag() ?
829  left_right_offset[dim - 2][f][cell->face_orientation(f)] :
830  1 - left_right_offset[dim - 2][f][cell->face_orientation(f)]);
831 
832  adjacent_cells[2 * face->index() + offset] = cell;
833 
834  // if this cell is not refined, but the
835  // face is, then we'll have to set our
836  // cell as neighbor for the child faces
837  // as well. Fortunately the normal
838  // orientation of children will be just
839  // the same.
840  if (dim == 2)
841  {
842  if (cell->active() && face->has_children())
843  {
844  adjacent_cells[2 * face->child(0)->index() + offset] = cell;
845  adjacent_cells[2 * face->child(1)->index() + offset] = cell;
846  }
847  }
848  else // -> dim == 3
849  {
850  // We need the same as in 2d
851  // here. Furthermore, if the face is
852  // refined with cut_x or cut_y then
853  // those children again in the other
854  // direction, and if this cell is
855  // refined isotropically (along the
856  // face) then the neighbor will
857  // (probably) be refined as cut_x or
858  // cut_y along the face. For those
859  // neighboring children cells, their
860  // neighbor will be the current,
861  // inactive cell, as our children are
862  // too fine to be neighbors. Catch that
863  // case by also acting on inactive
864  // cells with isotropic refinement
865  // along the face. If the situation
866  // described is not present, the data
867  // will be overwritten later on when we
868  // visit cells on finer levels, so no
869  // harm will be done.
870  if (face->has_children() &&
871  (cell->active() ||
873  cell->refinement_case(), f) ==
875  {
876  for (unsigned int c = 0; c < face->n_children(); ++c)
877  adjacent_cells[2 * face->child(c)->index() + offset] = cell;
878  if (face->child(0)->has_children())
879  {
880  adjacent_cells[2 * face->child(0)->child(0)->index() +
881  offset] = cell;
882  adjacent_cells[2 * face->child(0)->child(1)->index() +
883  offset] = cell;
884  }
885  if (face->child(1)->has_children())
886  {
887  adjacent_cells[2 * face->child(1)->child(0)->index() +
888  offset] = cell;
889  adjacent_cells[2 * face->child(1)->child(1)->index() +
890  offset] = cell;
891  }
892  } // if cell active and face refined
893  } // else -> dim==3
894  } // for all faces of all cells
895 
896  // now loop again over all cells and set the
897  // corresponding neighbor cell. Note, that we
898  // have to use the opposite of the
899  // left_right_offset in this case as we want
900  // the offset of the neighbor, not our own.
901  for (cell = triangulation.begin(); cell != endc; ++cell)
902  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
903  {
904  const unsigned int offset =
905  (cell->direction_flag() ?
906  left_right_offset[dim - 2][f][cell->face_orientation(f)] :
907  1 - left_right_offset[dim - 2][f][cell->face_orientation(f)]);
908  cell->set_neighbor(
909  f, adjacent_cells[2 * cell->face(f)->index() + 1 - offset]);
910  }
911  }
912 
913 
914  template <int dim, int spacedim>
915  void
916  update_periodic_face_map_recursively(
917  const typename Triangulation<dim, spacedim>::cell_iterator &cell_1,
918  const typename Triangulation<dim, spacedim>::cell_iterator &cell_2,
919  unsigned int n_face_1,
920  unsigned int n_face_2,
921  const std::bitset<3> & orientation,
922  typename std::map<
924  unsigned int>,
925  std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
926  unsigned int>,
927  std::bitset<3>>> &periodic_face_map)
928  {
929  using FaceIterator = typename Triangulation<dim, spacedim>::face_iterator;
930  const FaceIterator face_1 = cell_1->face(n_face_1);
931  const FaceIterator face_2 = cell_2->face(n_face_2);
932 
933  const bool face_orientation = orientation[0];
934  const bool face_flip = orientation[1];
935  const bool face_rotation = orientation[2];
936 
937  Assert((dim != 1) || (face_orientation == true && face_flip == false &&
938  face_rotation == false),
939  ExcMessage("The supplied orientation "
940  "(face_orientation, face_flip, face_rotation) "
941  "is invalid for 1D"));
942 
943  Assert((dim != 2) || (face_orientation == true && face_rotation == false),
944  ExcMessage("The supplied orientation "
945  "(face_orientation, face_flip, face_rotation) "
946  "is invalid for 2D"));
947 
948  Assert(face_1 != face_2, ExcMessage("face_1 and face_2 are equal!"));
949 
950  Assert(face_1->at_boundary() && face_2->at_boundary(),
951  ExcMessage("Periodic faces must be on the boundary"));
952 
953  Assert(std::abs(cell_1->level() - cell_2->level()) < 2, ExcInternalError());
954 
955  // insert periodic face pair for both cells
956  using CellFace =
957  std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
958  unsigned int>;
959  const CellFace cell_face_1(cell_1, n_face_1);
960  const CellFace cell_face_2(cell_2, n_face_2);
961  const std::pair<CellFace, std::bitset<3>> cell_face_orientation_2(
962  cell_face_2, orientation);
963 
964  const std::pair<CellFace, std::pair<CellFace, std::bitset<3>>>
965  periodic_faces(cell_face_1, cell_face_orientation_2);
966 
967  // Only one periodic neighbor is allowed
968  Assert(periodic_face_map.count(cell_face_1) == 0, ExcInternalError());
969  periodic_face_map.insert(periodic_faces);
970 
971  // A lookup table on how to go through the child cells depending on the
972  // orientation:
973  // see Documentation of GeometryInfo for details
974 
975  static const int lookup_table_2d[2][2] =
976  // flip:
977  {
978  {0, 1}, // false
979  {1, 0} // true
980  };
981 
982  static const int lookup_table_3d[2][2][2][4] =
983  // orientation flip rotation
984  {{{
985  {0, 2, 1, 3}, // false false false
986  {2, 3, 0, 1} // false false true
987  },
988  {
989  {3, 1, 2, 0}, // false true false
990  {1, 0, 3, 2} // false true true
991  }},
992  {{
993  {0, 1, 2, 3}, // true false false
994  {1, 3, 0, 2} // true false true
995  },
996  {
997  {3, 2, 1, 0}, // true true false
998  {2, 0, 3, 1} // true true true
999  }}};
1000 
1001  if (cell_1->has_children())
1002  {
1003  if (cell_2->has_children())
1004  {
1005  // In the case that both faces have children, we loop over all
1006  // children and apply update_periodic_face_map_recursively
1007  // recursively:
1008 
1009  Assert(face_1->n_children() ==
1011  face_2->n_children() ==
1013  ExcNotImplemented());
1014 
1015  for (unsigned int i = 0;
1016  i < GeometryInfo<dim>::max_children_per_face;
1017  ++i)
1018  {
1019  // Lookup the index for the second face
1020  unsigned int j = 0;
1021  switch (dim)
1022  {
1023  case 2:
1024  j = lookup_table_2d[face_flip][i];
1025  break;
1026  case 3:
1027  j = lookup_table_3d[face_orientation][face_flip]
1028  [face_rotation][i];
1029  break;
1030  default:
1031  AssertThrow(false, ExcNotImplemented());
1032  }
1033 
1034  // find subcell ids that belong to the subface indices
1035  unsigned int child_cell_1 =
1037  cell_1->refinement_case(),
1038  n_face_1,
1039  i,
1040  cell_1->face_orientation(n_face_1),
1041  cell_1->face_flip(n_face_1),
1042  cell_1->face_rotation(n_face_1),
1043  face_1->refinement_case());
1044  unsigned int child_cell_2 =
1046  cell_2->refinement_case(),
1047  n_face_2,
1048  j,
1049  cell_2->face_orientation(n_face_2),
1050  cell_2->face_flip(n_face_2),
1051  cell_2->face_rotation(n_face_2),
1052  face_2->refinement_case());
1053 
1054  Assert(cell_1->child(child_cell_1)->face(n_face_1) ==
1055  face_1->child(i),
1056  ExcInternalError());
1057  Assert(cell_2->child(child_cell_2)->face(n_face_2) ==
1058  face_2->child(j),
1059  ExcInternalError());
1060 
1061  // precondition: subcell has the same orientation as cell (so
1062  // that the face numbers coincide) recursive call
1063  update_periodic_face_map_recursively<dim, spacedim>(
1064  cell_1->child(child_cell_1),
1065  cell_2->child(child_cell_2),
1066  n_face_1,
1067  n_face_2,
1068  orientation,
1069  periodic_face_map);
1070  }
1071  }
1072  else // only face_1 has children
1073  {
1074  for (unsigned int i = 0;
1075  i < GeometryInfo<dim>::max_children_per_face;
1076  ++i)
1077  {
1078  // find subcell ids that belong to the subface indices
1079  unsigned int child_cell_1 =
1081  cell_1->refinement_case(),
1082  n_face_1,
1083  i,
1084  cell_1->face_orientation(n_face_1),
1085  cell_1->face_flip(n_face_1),
1086  cell_1->face_rotation(n_face_1),
1087  face_1->refinement_case());
1088 
1089  // recursive call
1090  update_periodic_face_map_recursively<dim, spacedim>(
1091  cell_1->child(child_cell_1),
1092  cell_2,
1093  n_face_1,
1094  n_face_2,
1095  orientation,
1096  periodic_face_map);
1097  }
1098  }
1099  }
1100  }
1101 
1102 
1103 } // end of anonymous namespace
1104 
1105 
1106 namespace internal
1107 {
1108  namespace TriangulationImplementation
1109  {
1110  // make sure that if in the following we
1111  // write Triangulation<dim,spacedim>
1112  // we mean the *class*
1113  // ::Triangulation, not the
1114  // enclosing namespace
1115  // internal::TriangulationImplementation
1116  using ::Triangulation;
1117 
1123  int,
1124  << "Something went wrong when making cell " << arg1
1125  << ". Read the docs and the source code "
1126  << "for more information.");
1132  int,
1133  << "Something went wrong upon construction of cell "
1134  << arg1);
1145  int,
1146  << "Cell " << arg1
1147  << " has negative measure. This typically "
1148  << "indicates some distortion in the cell, or a mistakenly "
1149  << "swapped pair of vertices in the input to "
1150  << "Triangulation::create_triangulation().");
1159  int,
1160  int,
1161  int,
1162  << "Error while creating cell " << arg1
1163  << ": the vertex index " << arg2 << " must be between 0 and "
1164  << arg3 << ".");
1170  int,
1171  int,
1172  << "While trying to assign a boundary indicator to a line: "
1173  << "the line with end vertices " << arg1 << " and " << arg2
1174  << " does not exist.");
1180  int,
1181  int,
1182  int,
1183  int,
1184  << "While trying to assign a boundary indicator to a quad: "
1185  << "the quad with bounding lines " << arg1 << ", " << arg2
1186  << ", " << arg3 << ", " << arg4 << " does not exist.");
1193  int,
1194  int,
1196  << "The input data for creating a triangulation contained "
1197  << "information about a line with indices " << arg1 << " and " << arg2
1198  << " that is described to have boundary indicator "
1199  << static_cast<int>(arg3)
1200  << ". However, this is an internal line not located on the "
1201  << "boundary. You cannot assign a boundary indicator to it." << std::endl
1202  << std::endl
1203  << "If this happened at a place where you call "
1204  << "Triangulation::create_triangulation() yourself, you need "
1205  << "to check the SubCellData object you pass to this function."
1206  << std::endl
1207  << std::endl
1208  << "If this happened in a place where you are reading a mesh "
1209  << "from a file, then you need to investigate why such a line "
1210  << "ended up in the input file. A typical case is a geometry "
1211  << "that consisted of multiple parts and for which the mesh "
1212  << "generator program assumes that the interface between "
1213  << "two parts is a boundary when that isn't supposed to be "
1214  << "the case, or where the mesh generator simply assigns "
1215  << "'geometry indicators' to lines at the perimeter of "
1216  << "a part that are not supposed to be interpreted as "
1217  << "'boundary indicators'.");
1224  int,
1225  int,
1226  int,
1227  int,
1229  << "The input data for creating a triangulation contained "
1230  << "information about a quad with indices " << arg1 << ", " << arg2
1231  << ", " << arg3 << ", and " << arg4
1232  << " that is described to have boundary indicator "
1233  << static_cast<int>(arg5)
1234  << ". However, this is an internal quad not located on the "
1235  << "boundary. You cannot assign a boundary indicator to it." << std::endl
1236  << std::endl
1237  << "If this happened at a place where you call "
1238  << "Triangulation::create_triangulation() yourself, you need "
1239  << "to check the SubCellData object you pass to this function."
1240  << std::endl
1241  << std::endl
1242  << "If this happened in a place where you are reading a mesh "
1243  << "from a file, then you need to investigate why such a quad "
1244  << "ended up in the input file. A typical case is a geometry "
1245  << "that consisted of multiple parts and for which the mesh "
1246  << "generator program assumes that the interface between "
1247  << "two parts is a boundary when that isn't supposed to be "
1248  << "the case, or where the mesh generator simply assigns "
1249  << "'geometry indicators' to quads at the surface of "
1250  << "a part that are not supposed to be interpreted as "
1251  << "'boundary indicators'.");
1258  int,
1259  int,
1260  << "In SubCellData the line info of the line with vertex indices " << arg1
1261  << " and " << arg2 << " appears more than once. "
1262  << "This is not allowed.");
1269  int,
1270  int,
1271  std::string,
1272  << "In SubCellData the line info of the line with vertex indices " << arg1
1273  << " and " << arg2 << " appears multiple times with different (valid) "
1274  << arg3 << ". This is not allowed.");
1281  int,
1282  int,
1283  int,
1284  int,
1285  std::string,
1286  << "In SubCellData the quad info of the quad with line indices " << arg1
1287  << ", " << arg2 << ", " << arg3 << " and " << arg4
1288  << " appears multiple times with different (valid) " << arg5
1289  << ". This is not allowed.");
1290 
1387  {
1399  template <int dim, int spacedim>
1400  static void
1402  const Triangulation<dim, spacedim> & triangulation,
1403  const unsigned int level_objects,
1405  {
1406  using line_iterator =
1408 
1409  number_cache.n_levels = 0;
1410  if (level_objects > 0)
1411  // find the last level on which there are used cells
1412  for (unsigned int level = 0; level < level_objects; ++level)
1413  if (triangulation.begin(level) != triangulation.end(level))
1414  number_cache.n_levels = level + 1;
1415 
1416  // no cells at all?
1417  Assert(number_cache.n_levels > 0, ExcInternalError());
1418 
1420  // update the number of lines on the different levels in the
1421  // cache
1422  number_cache.n_lines = 0;
1423  number_cache.n_active_lines = 0;
1424 
1425  // for 1d, lines have levels so take count the objects per
1426  // level and globally
1427  if (dim == 1)
1428  {
1429  number_cache.n_lines_level.resize(number_cache.n_levels);
1430  number_cache.n_active_lines_level.resize(number_cache.n_levels);
1431 
1432  for (unsigned int level = 0; level < number_cache.n_levels; ++level)
1433  {
1434  // count lines on this level
1435  number_cache.n_lines_level[level] = 0;
1436  number_cache.n_active_lines_level[level] = 0;
1437 
1438  line_iterator line = triangulation.begin_line(level),
1439  endc =
1440  (level == number_cache.n_levels - 1 ?
1441  line_iterator(triangulation.end_line()) :
1442  triangulation.begin_line(level + 1));
1443  for (; line != endc; ++line)
1444  {
1445  ++number_cache.n_lines_level[level];
1446  if (line->has_children() == false)
1447  ++number_cache.n_active_lines_level[level];
1448  }
1449 
1450  // update total number of lines
1451  number_cache.n_lines += number_cache.n_lines_level[level];
1452  number_cache.n_active_lines +=
1453  number_cache.n_active_lines_level[level];
1454  }
1455  }
1456  else
1457  {
1458  // for dim>1, there are no levels for lines
1459  number_cache.n_lines_level.clear();
1460  number_cache.n_active_lines_level.clear();
1461 
1462  line_iterator line = triangulation.begin_line(),
1463  endc = triangulation.end_line();
1464  for (; line != endc; ++line)
1465  {
1466  ++number_cache.n_lines;
1467  if (line->has_children() == false)
1468  ++number_cache.n_active_lines;
1469  }
1470  }
1471  }
1472 
1487  template <int dim, int spacedim>
1488  static void
1490  const Triangulation<dim, spacedim> & triangulation,
1491  const unsigned int level_objects,
1493  {
1494  // update lines and n_levels in number_cache. since we don't
1495  // access any of these numbers, we can do this in the
1496  // background
1497  Threads::Task<void> update_lines = Threads::new_task(
1498  static_cast<
1499  void (*)(const Triangulation<dim, spacedim> &,
1500  const unsigned int,
1502  &compute_number_cache<dim, spacedim>),
1503  triangulation,
1504  level_objects,
1506  number_cache));
1507 
1508  using quad_iterator =
1510 
1512  // update the number of quads on the different levels in the
1513  // cache
1514  number_cache.n_quads = 0;
1515  number_cache.n_active_quads = 0;
1516 
1517  // for 2d, quads have levels so take count the objects per
1518  // level and globally
1519  if (dim == 2)
1520  {
1521  // count the number of levels; the function we called above
1522  // on a separate Task for lines also does this and puts it into
1523  // number_cache.n_levels, but this datum may not yet be
1524  // available as we call the function on a separate task
1525  unsigned int n_levels = 0;
1526  if (level_objects > 0)
1527  // find the last level on which there are used cells
1528  for (unsigned int level = 0; level < level_objects; ++level)
1529  if (triangulation.begin(level) != triangulation.end(level))
1530  n_levels = level + 1;
1531 
1532  number_cache.n_quads_level.resize(n_levels);
1533  number_cache.n_active_quads_level.resize(n_levels);
1534 
1535  for (unsigned int level = 0; level < n_levels; ++level)
1536  {
1537  // count quads on this level
1538  number_cache.n_quads_level[level] = 0;
1539  number_cache.n_active_quads_level[level] = 0;
1540 
1541  quad_iterator quad = triangulation.begin_quad(level),
1542  endc =
1543  (level == n_levels - 1 ?
1544  quad_iterator(triangulation.end_quad()) :
1545  triangulation.begin_quad(level + 1));
1546  for (; quad != endc; ++quad)
1547  {
1548  ++number_cache.n_quads_level[level];
1549  if (quad->has_children() == false)
1550  ++number_cache.n_active_quads_level[level];
1551  }
1552 
1553  // update total number of quads
1554  number_cache.n_quads += number_cache.n_quads_level[level];
1555  number_cache.n_active_quads +=
1556  number_cache.n_active_quads_level[level];
1557  }
1558  }
1559  else
1560  {
1561  // for dim>2, there are no levels for quads
1562  number_cache.n_quads_level.clear();
1563  number_cache.n_active_quads_level.clear();
1564 
1565  quad_iterator quad = triangulation.begin_quad(),
1566  endc = triangulation.end_quad();
1567  for (; quad != endc; ++quad)
1568  {
1569  ++number_cache.n_quads;
1570  if (quad->has_children() == false)
1571  ++number_cache.n_active_quads;
1572  }
1573  }
1574 
1575  // wait for the background computation for lines
1576  update_lines.join();
1577  }
1578 
1594  template <int dim, int spacedim>
1595  static void
1597  const Triangulation<dim, spacedim> & triangulation,
1598  const unsigned int level_objects,
1600  {
1601  // update quads, lines and n_levels in number_cache. since we
1602  // don't access any of these numbers, we can do this in the
1603  // background
1604  Threads::Task<void> update_quads_and_lines = Threads::new_task(
1605  static_cast<
1606  void (*)(const Triangulation<dim, spacedim> &,
1607  const unsigned int,
1609  &compute_number_cache<dim, spacedim>),
1610  triangulation,
1611  level_objects,
1613  number_cache));
1614 
1615  using hex_iterator =
1617 
1619  // update the number of hexes on the different levels in the
1620  // cache
1621  number_cache.n_hexes = 0;
1622  number_cache.n_active_hexes = 0;
1623 
1624  // for 3d, hexes have levels so take count the objects per
1625  // level and globally
1626  if (dim == 3)
1627  {
1628  // count the number of levels; the function we called
1629  // above on a separate Task for quads (recursively, via
1630  // the lines function) also does this and puts it into
1631  // number_cache.n_levels, but this datum may not yet be
1632  // available as we call the function on a separate task
1633  unsigned int n_levels = 0;
1634  if (level_objects > 0)
1635  // find the last level on which there are used cells
1636  for (unsigned int level = 0; level < level_objects; ++level)
1637  if (triangulation.begin(level) != triangulation.end(level))
1638  n_levels = level + 1;
1639 
1640  number_cache.n_hexes_level.resize(n_levels);
1641  number_cache.n_active_hexes_level.resize(n_levels);
1642 
1643  for (unsigned int level = 0; level < n_levels; ++level)
1644  {
1645  // count hexes on this level
1646  number_cache.n_hexes_level[level] = 0;
1647  number_cache.n_active_hexes_level[level] = 0;
1648 
1649  hex_iterator hex = triangulation.begin_hex(level),
1650  endc = (level == n_levels - 1 ?
1651  hex_iterator(triangulation.end_hex()) :
1652  triangulation.begin_hex(level + 1));
1653  for (; hex != endc; ++hex)
1654  {
1655  ++number_cache.n_hexes_level[level];
1656  if (hex->has_children() == false)
1657  ++number_cache.n_active_hexes_level[level];
1658  }
1659 
1660  // update total number of hexes
1661  number_cache.n_hexes += number_cache.n_hexes_level[level];
1662  number_cache.n_active_hexes +=
1663  number_cache.n_active_hexes_level[level];
1664  }
1665  }
1666  else
1667  {
1668  // for dim>3, there are no levels for hexes
1669  number_cache.n_hexes_level.clear();
1670  number_cache.n_active_hexes_level.clear();
1671 
1672  hex_iterator hex = triangulation.begin_hex(),
1673  endc = triangulation.end_hex();
1674  for (; hex != endc; ++hex)
1675  {
1676  ++number_cache.n_hexes;
1677  if (hex->has_children() == false)
1678  ++number_cache.n_active_hexes;
1679  }
1680  }
1681 
1682  // wait for the background computation for quads
1683  update_quads_and_lines.join();
1684  }
1685 
1686 
1694  template <int spacedim>
1695  static void
1696  create_triangulation(const std::vector<Point<spacedim>> &v,
1697  const std::vector<CellData<1>> & cells,
1698  const SubCellData & /*subcelldata*/,
1699  Triangulation<1, spacedim> &triangulation)
1700  {
1701  AssertThrow(v.size() > 0, ExcMessage("No vertices given"));
1702  AssertThrow(cells.size() > 0, ExcMessage("No cells given"));
1703 
1704  // note: since no boundary
1705  // information can be given in one
1706  // dimension, the @p{subcelldata}
1707  // field is ignored. (only used for
1708  // error checking, which is a good
1709  // idea in any case)
1710  const unsigned int dim = 1;
1711 
1712  // copy vertices
1713  triangulation.vertices = v;
1714  triangulation.vertices_used = std::vector<bool>(v.size(), true);
1715 
1716  // Check that all cells have positive volume. This check is not run in
1717  // the codimension one or two cases since cell_measure is not
1718  // implemented for those.
1719 #ifndef _MSC_VER
1720  // TODO: The following code does not compile with MSVC. Find a way
1721  // around it
1722  if (dim == spacedim)
1723  {
1724  for (unsigned int cell_no = 0; cell_no < cells.size(); ++cell_no)
1725  {
1726  // If we should check for distorted cells, then we permit them
1727  // to exist. If a cell has negative measure, then it must be
1728  // distorted (the converse is not necessarily true); hence
1729  // throw an exception if no such cells should exist.
1730  if (!triangulation.check_for_distorted_cells)
1731  {
1732  const double cell_measure =
1733  GridTools::cell_measure<1>(triangulation.vertices,
1734  cells[cell_no].vertices);
1735  AssertThrow(cell_measure > 0,
1736  ExcGridHasInvalidCell(cell_no));
1737  }
1738  }
1739  }
1740 #endif
1741 
1742 
1743  // store the indices of the lines
1744  // which are adjacent to a given
1745  // vertex
1746  std::vector<std::vector<int>> lines_at_vertex(v.size());
1747 
1748  // reserve enough space
1749  triangulation.levels.push_back(
1750  std_cxx14::make_unique<
1752  triangulation.levels[0]->reserve_space(cells.size(), dim, spacedim);
1753  triangulation.levels[0]->cells.reserve_space(0, cells.size());
1754 
1755  // make up cells
1756  typename Triangulation<dim, spacedim>::raw_line_iterator
1757  next_free_line = triangulation.begin_raw_line();
1758  for (unsigned int cell = 0; cell < cells.size(); ++cell)
1759  {
1760  while (next_free_line->used())
1761  ++next_free_line;
1762 
1763  next_free_line->set(
1764  internal::TriangulationImplementation ::TriaObject<1>(
1765  cells[cell].vertices[0], cells[cell].vertices[1]));
1766  next_free_line->set_used_flag();
1767  next_free_line->set_material_id(cells[cell].material_id);
1768  next_free_line->set_manifold_id(cells[cell].manifold_id);
1769  next_free_line->clear_user_data();
1770  next_free_line->set_subdomain_id(0);
1771 
1772  // note that this cell is
1773  // adjacent to these vertices
1774  lines_at_vertex[cells[cell].vertices[0]].push_back(cell);
1775  lines_at_vertex[cells[cell].vertices[1]].push_back(cell);
1776  }
1777 
1778 
1779  // some security tests
1780  {
1781  unsigned int boundary_nodes = 0;
1782  for (const auto &line : lines_at_vertex)
1783  switch (line.size())
1784  {
1785  case 1:
1786  // this vertex has only
1787  // one adjacent line
1788  ++boundary_nodes;
1789  break;
1790  case 2:
1791  break;
1792  default:
1793  AssertThrow(
1794  false,
1795  ExcMessage(
1796  "You have a vertex in your triangulation "
1797  "at which more than two cells come together. "
1798  "(For one dimensional triangulation, cells are "
1799  "line segments.)"
1800  "\n\n"
1801  "This is not currently supported because the "
1802  "Triangulation class makes the assumption that "
1803  "every cell has zero or one neighbors behind "
1804  "each face (here, behind each vertex), but in your "
1805  "situation there would be more than one."
1806  "\n\n"
1807  "Support for this is not currently implemented. "
1808  "If you need to work with triangulations where "
1809  "more than two cells come together at a vertex, "
1810  "duplicate the vertices once per cell (i.e., put "
1811  "multiple vertices at the same physical location, "
1812  "but using different vertex indices for each) "
1813  "and then ensure continuity of the solution by "
1814  "explicitly creating constraints that the degrees "
1815  "of freedom at these vertices have the same "
1816  "value, using the AffineConstraints class."));
1817  }
1818 
1819  // assert there are no more
1820  // than two boundary
1821  // nodes. note that if the
1822  // space dimension is
1823  // bigger than 1, then we
1824  // can have fewer than 2
1825  // nodes (for example a
1826  // ring of cells -- no end
1827  // points at all)
1828  AssertThrow(((spacedim == 1) && (boundary_nodes == 2)) ||
1829  (spacedim > 1),
1830  ExcMessage("The Triangulation has too many end points"));
1831  }
1832 
1833 
1834 
1835  // update neighborship info
1837  triangulation.begin_active_line();
1838  // for all lines
1839  for (; line != triangulation.end(); ++line)
1840  // for each of the two vertices
1841  for (unsigned int vertex = 0;
1842  vertex < GeometryInfo<dim>::vertices_per_cell;
1843  ++vertex)
1844  // if first cell adjacent to
1845  // this vertex is the present
1846  // one, then the neighbor is
1847  // the second adjacent cell and
1848  // vice versa
1849  if (lines_at_vertex[line->vertex_index(vertex)][0] == line->index())
1850  if (lines_at_vertex[line->vertex_index(vertex)].size() == 2)
1851  {
1853  neighbor(&triangulation,
1854  0, // level
1855  lines_at_vertex[line->vertex_index(vertex)][1]);
1856  line->set_neighbor(vertex, neighbor);
1857  }
1858  else
1859  // no second adjacent cell
1860  // entered -> cell at
1861  // boundary
1862  line->set_neighbor(vertex, triangulation.end());
1863  else
1864  // present line is not first
1865  // adjacent one -> first
1866  // adjacent one is neighbor
1867  {
1869  neighbor(&triangulation,
1870  0, // level
1871  lines_at_vertex[line->vertex_index(vertex)][0]);
1872  line->set_neighbor(vertex, neighbor);
1873  }
1874 
1875  // finally set the
1876  // vertex_to_boundary_id_map_1d
1877  // and vertex_to_manifold_id_map_1d
1878  // maps
1879  triangulation.vertex_to_boundary_id_map_1d->clear();
1880  triangulation.vertex_to_manifold_id_map_1d->clear();
1882  triangulation.begin_active();
1883  cell != triangulation.end();
1884  ++cell)
1885  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
1886  {
1887  (*triangulation.vertex_to_manifold_id_map_1d)
1888  [cell->face(f)->vertex_index()] = numbers::flat_manifold_id;
1889 
1890  if (cell->at_boundary(f))
1891  (*triangulation.vertex_to_boundary_id_map_1d)
1892  [cell->face(f)->vertex_index()] = f;
1893  }
1894  }
1895 
1896 
1904  template <int spacedim>
1905  static void
1906  create_triangulation(const std::vector<Point<spacedim>> &v,
1907  const std::vector<CellData<2>> & cells,
1908  const SubCellData & subcelldata,
1909  Triangulation<2, spacedim> & triangulation)
1910  {
1911  AssertThrow(v.size() > 0, ExcMessage("No vertices given"));
1912  AssertThrow(cells.size() > 0, ExcMessage("No cells given"));
1913 
1914  const unsigned int dim = 2;
1915 
1916  // copy vertices
1917  triangulation.vertices = v;
1918  triangulation.vertices_used = std::vector<bool>(v.size(), true);
1919 
1920  // Check that all cells have positive volume. This check is not run in
1921  // the codimension one or two cases since cell_measure is not
1922  // implemented for those.
1923 #ifndef _MSC_VER
1924  // TODO: The following code does not compile with MSVC. Find a way
1925  // around it
1926  if (dim == spacedim)
1927  {
1928  for (unsigned int cell_no = 0; cell_no < cells.size(); ++cell_no)
1929  {
1930  // See the note in the 1D function on this if statement.
1931  if (!triangulation.check_for_distorted_cells)
1932  {
1933  const double cell_measure =
1934  GridTools::cell_measure<2>(triangulation.vertices,
1935  cells[cell_no].vertices);
1936  AssertThrow(cell_measure > 0,
1937  ExcGridHasInvalidCell(cell_no));
1938  }
1939  }
1940  }
1941 #endif
1942 
1943  // make up a list of the needed
1944  // lines each line is a pair of
1945  // vertices. The list is kept
1946  // sorted and it is guaranteed that
1947  // each line is inserted only once.
1948  // While the key of such an entry
1949  // is the pair of vertices, the
1950  // thing it points to is an
1951  // iterator pointing to the line
1952  // object itself. In the first run,
1953  // these iterators are all invalid
1954  // ones, but they are filled
1955  // afterwards
1956  std::map<std::pair<int, int>,
1958  needed_lines;
1959  for (unsigned int cell = 0; cell < cells.size(); ++cell)
1960  {
1961  for (const auto vertex : cells[cell].vertices)
1962  AssertThrow(vertex < triangulation.vertices.size(),
1963  ExcInvalidVertexIndex(cell,
1964  vertex,
1965  triangulation.vertices.size()));
1966 
1967  for (unsigned int line = 0;
1968  line < GeometryInfo<dim>::faces_per_cell;
1969  ++line)
1970  {
1971  // given a line vertex number (0,1) on a specific line
1972  // we get the cell vertex number (0-4) through the
1973  // line_to_cell_vertices function
1974  std::pair<int, int> line_vertices(
1975  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(
1976  line, 0)],
1977  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(
1978  line, 1)]);
1979 
1980  // assert that the line was not already inserted in
1981  // reverse order. This happens in spite of the vertex
1982  // rotation above, if the sense of the cell was
1983  // incorrect.
1984  //
1985  // Here is what usually happened when this exception
1986  // is thrown: consider these two cells and the
1987  // vertices
1988  // 3---4---5
1989  // | | |
1990  // 0---1---2
1991  // If in the input vector the two cells are given with
1992  // vertices <0 1 3 4> and <4 1 5 2>, in the first cell
1993  // the middle line would have direction 1->4, while in
1994  // the second it would be 4->1. This will cause the
1995  // exception.
1996  AssertThrow(needed_lines.find(std::make_pair(
1997  line_vertices.second, line_vertices.first)) ==
1998  needed_lines.end(),
1999  ExcGridHasInvalidCell(cell));
2000 
2001  // insert line, with
2002  // invalid iterator if line
2003  // already exists, then
2004  // nothing bad happens here
2005  needed_lines[line_vertices] = triangulation.end_line();
2006  }
2007  }
2008 
2009 
2010  // check that every vertex has at
2011  // least two adjacent lines
2012  {
2013  std::vector<unsigned short int> vertex_touch_count(v.size(), 0);
2014  typename std::map<
2015  std::pair<int, int>,
2016  typename Triangulation<dim, spacedim>::line_iterator>::iterator i;
2017  for (i = needed_lines.begin(); i != needed_lines.end(); ++i)
2018  {
2019  // touch the vertices of
2020  // this line
2021  ++vertex_touch_count[i->first.first];
2022  ++vertex_touch_count[i->first.second];
2023  }
2024 
2025  // assert minimum touch count
2026  // is at least two. if not so,
2027  // then clean triangulation and
2028  // exit with an exception
2029  AssertThrow(*(std::min_element(vertex_touch_count.begin(),
2030  vertex_touch_count.end())) >= 2,
2031  ExcMessage(
2032  "During creation of a triangulation, a part of the "
2033  "algorithm encountered a vertex that is part of only "
2034  "a single adjacent line. However, in 2d, every vertex "
2035  "needs to be at least part of two lines."));
2036  }
2037 
2038  // reserve enough space
2039  triangulation.levels.push_back(
2040  std_cxx14::make_unique<
2042  triangulation.faces = std_cxx14::make_unique<
2044  triangulation.levels[0]->reserve_space(cells.size(), dim, spacedim);
2045  triangulation.faces->lines.reserve_space(0, needed_lines.size());
2046  triangulation.levels[0]->cells.reserve_space(0, cells.size());
2047 
2048  // make up lines
2049  {
2050  typename Triangulation<dim, spacedim>::raw_line_iterator line =
2051  triangulation.begin_raw_line();
2052  typename std::map<
2053  std::pair<int, int>,
2054  typename Triangulation<dim, spacedim>::line_iterator>::iterator i;
2055  for (i = needed_lines.begin(); line != triangulation.end_line();
2056  ++line, ++i)
2057  {
2059  i->first.first, i->first.second));
2060  line->set_used_flag();
2061  line->clear_user_flag();
2062  line->clear_user_data();
2063  i->second = line;
2064  }
2065  }
2066 
2067 
2068  // store for each line index
2069  // the adjacent cells
2070  std::map<
2071  int,
2072  std::vector<typename Triangulation<dim, spacedim>::cell_iterator>>
2073  adjacent_cells;
2074 
2075  // finally make up cells
2076  {
2078  triangulation.begin_raw_quad();
2079  for (unsigned int c = 0; c < cells.size(); ++c, ++cell)
2080  {
2083  for (unsigned int line = 0;
2084  line < GeometryInfo<dim>::lines_per_cell;
2085  ++line)
2086  lines[line] = needed_lines[std::make_pair(
2087  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2088  line, 0)],
2089  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2090  line, 1)])];
2091 
2093  lines[0]->index(),
2094  lines[1]->index(),
2095  lines[2]->index(),
2096  lines[3]->index()));
2097 
2098  cell->set_used_flag();
2099  cell->set_material_id(cells[c].material_id);
2100  cell->set_manifold_id(cells[c].manifold_id);
2101  cell->clear_user_data();
2102  cell->set_subdomain_id(0);
2103 
2104  // note that this cell is
2105  // adjacent to the four
2106  // lines
2107  for (const auto &line : lines)
2108  adjacent_cells[line->index()].push_back(cell);
2109  }
2110  }
2111 
2112 
2113  for (typename Triangulation<dim, spacedim>::line_iterator line =
2114  triangulation.begin_line();
2115  line != triangulation.end_line();
2116  ++line)
2117  {
2118  const unsigned int n_adj_cells =
2119  adjacent_cells[line->index()].size();
2120 
2121  // assert that every line has one or two adjacent cells.
2122  // this has to be the case for 2d triangulations in 2d.
2123  // in higher dimensions, this may happen but is not
2124  // implemented
2125  if (spacedim == 2)
2126  {
2127  AssertThrow((n_adj_cells >= 1) && (n_adj_cells <= 2),
2128  ExcInternalError());
2129  }
2130  else
2131  {
2132  AssertThrow(
2133  (n_adj_cells >= 1) && (n_adj_cells <= 2),
2134  ExcMessage("You have a line in your triangulation at which "
2135  "more than two cells come together."
2136  "\n\n"
2137  "This is not currently supported because the "
2138  "Triangulation class makes the assumption that "
2139  "every cell has zero or one neighbors behind each "
2140  "face (here, behind each line), but in your "
2141  "situation there would be more than one."
2142  "\n\n"
2143  "Support for this is not currently implemented. "
2144  "If you need to work with triangulations where "
2145  "more than two cells come together at a line, "
2146  "duplicate the vertices once per cell (i.e., put "
2147  "multiple vertices at the same physical location, "
2148  "but using different vertex indices for each) "
2149  "and then ensure continuity of the solution by "
2150  "explicitly creating constraints that the degrees "
2151  "of freedom at these lines have the same "
2152  "value, using the AffineConstraints class."));
2153  }
2154 
2155  // if only one cell: line is at boundary -> give it the boundary
2156  // indicator zero by default
2157  line->set_boundary_id_internal(
2158  (n_adj_cells == 1) ? 0 : numbers::internal_face_boundary_id);
2159  line->set_manifold_id(numbers::flat_manifold_id);
2160  }
2161 
2162  // set boundary indicators where given
2163  for (const auto &subcell_line : subcelldata.boundary_lines)
2164  {
2166  std::pair<int, int> line_vertices(
2167  std::make_pair(subcell_line.vertices[0],
2168  subcell_line.vertices[1]));
2169  if (needed_lines.find(line_vertices) != needed_lines.end())
2170  // line found in this direction
2171  line = needed_lines[line_vertices];
2172  else
2173  {
2174  // look whether it exists in reverse direction
2175  std::swap(line_vertices.first, line_vertices.second);
2176  if (needed_lines.find(line_vertices) != needed_lines.end())
2177  line = needed_lines[line_vertices];
2178  else
2179  // line does not exist
2180  AssertThrow(false,
2181  ExcLineInexistant(line_vertices.first,
2182  line_vertices.second));
2183  }
2184 
2185  // assert that we only set boundary info once
2186  AssertThrow(!(line->boundary_id() != 0 &&
2187  line->boundary_id() !=
2189  ExcMultiplySetLineInfoOfLine(line_vertices.first,
2190  line_vertices.second));
2191 
2192  // assert that the manifold id is not yet set or consistent
2193  // with the previous id
2194  AssertThrow(line->manifold_id() == numbers::flat_manifold_id ||
2195  line->manifold_id() == subcell_line.manifold_id,
2196  ExcInconsistentLineInfoOfLine(line_vertices.first,
2197  line_vertices.second,
2198  "manifold ids"));
2199  line->set_manifold_id(subcell_line.manifold_id);
2200 
2201  // assert that only exterior lines are given a boundary
2202  // indicator
2203  if (subcell_line.boundary_id != numbers::internal_face_boundary_id)
2204  {
2205  AssertThrow(
2206  line->boundary_id() != numbers::internal_face_boundary_id,
2207  ExcInteriorLineCantBeBoundary(line->vertex_index(0),
2208  line->vertex_index(1),
2209  subcell_line.boundary_id));
2210  line->set_boundary_id_internal(subcell_line.boundary_id);
2211  }
2212  }
2213 
2214 
2215  // finally update neighborship info
2216  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
2217  triangulation.begin();
2218  cell != triangulation.end();
2219  ++cell)
2220  for (unsigned int side = 0; side < 4; ++side)
2221  if (adjacent_cells[cell->line(side)->index()][0] == cell)
2222  // first adjacent cell is
2223  // this one
2224  {
2225  if (adjacent_cells[cell->line(side)->index()].size() == 2)
2226  // there is another
2227  // adjacent cell
2228  cell->set_neighbor(
2229  side, adjacent_cells[cell->line(side)->index()][1]);
2230  }
2231  // first adjacent cell is not this
2232  // one, -> it must be the neighbor
2233  // we are looking for
2234  else
2235  cell->set_neighbor(side,
2236  adjacent_cells[cell->line(side)->index()][0]);
2237  }
2238 
2239 
2251  {
2252  inline bool
2253  operator()(
2256  {
2257  // here is room to
2258  // optimize the repeated
2259  // equality test of the
2260  // previous lines; the
2261  // compiler will probably
2262  // take care of most of
2263  // it anyway
2264  if ((q1.face(0) < q2.face(0)) ||
2265  ((q1.face(0) == q2.face(0)) && (q1.face(1) < q2.face(1))) ||
2266  ((q1.face(0) == q2.face(0)) && (q1.face(1) == q2.face(1)) &&
2267  (q1.face(2) < q2.face(2))) ||
2268  ((q1.face(0) == q2.face(0)) && (q1.face(1) == q2.face(1)) &&
2269  (q1.face(2) == q2.face(2)) && (q1.face(3) < q2.face(3))))
2270  return true;
2271  else
2272  return false;
2273  }
2274  };
2275 
2276 
2284  template <int spacedim>
2285  static void
2286  create_triangulation(const std::vector<Point<spacedim>> &v,
2287  const std::vector<CellData<3>> & cells,
2288  const SubCellData & subcelldata,
2289  Triangulation<3, spacedim> & triangulation)
2290  {
2291  AssertThrow(v.size() > 0, ExcMessage("No vertices given"));
2292  AssertThrow(cells.size() > 0, ExcMessage("No cells given"));
2293 
2294  const unsigned int dim = 3;
2295 
2296  // copy vertices
2297  triangulation.vertices = v;
2298  triangulation.vertices_used = std::vector<bool>(v.size(), true);
2299 
2300  // Check that all cells have positive volume.
2301 #ifndef _MSC_VER
2302  // TODO: The following code does not compile with MSVC. Find a way
2303  // around it
2304  for (unsigned int cell_no = 0; cell_no < cells.size(); ++cell_no)
2305  {
2306  // See the note in the 1D function on this if statement.
2307  if (!triangulation.check_for_distorted_cells)
2308  {
2309  const double cell_measure =
2310  GridTools::cell_measure<3>(triangulation.vertices,
2311  cells[cell_no].vertices);
2312  AssertThrow(cell_measure > 0, ExcGridHasInvalidCell(cell_no));
2313  }
2314  }
2315 #endif
2316 
2318  // first set up some collections of data
2319  //
2320  // make up a list of the needed
2321  // lines
2322  //
2323  // each line is a pair of
2324  // vertices. The list is kept
2325  // sorted and it is guaranteed that
2326  // each line is inserted only once.
2327  // While the key of such an entry
2328  // is the pair of vertices, the
2329  // thing it points to is an
2330  // iterator pointing to the line
2331  // object itself. In the first run,
2332  // these iterators are all invalid
2333  // ones, but they are filled
2334  // afterwards same applies for the
2335  // quads
2336  typename std::map<std::pair<int, int>,
2338  needed_lines;
2339  for (unsigned int cell = 0; cell < cells.size(); ++cell)
2340  {
2341  // check whether vertex indices
2342  // are valid ones
2343  for (const auto vertex : cells[cell].vertices)
2344  AssertThrow(vertex < triangulation.vertices.size(),
2345  ExcInvalidVertexIndex(cell,
2346  vertex,
2347  triangulation.vertices.size()));
2348 
2349  for (unsigned int line = 0;
2350  line < GeometryInfo<dim>::lines_per_cell;
2351  ++line)
2352  {
2353  // given a line vertex number
2354  // (0,1) on a specific line we
2355  // get the cell vertex number
2356  // (0-7) through the
2357  // line_to_cell_vertices
2358  // function
2359  std::pair<int, int> line_vertices(
2360  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2361  line, 0)],
2362  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2363  line, 1)]);
2364 
2365  // if that line was already inserted
2366  // in reverse order do nothing, else
2367  // insert the line
2368  if ((needed_lines.find(std::make_pair(line_vertices.second,
2369  line_vertices.first)) ==
2370  needed_lines.end()))
2371  {
2372  // insert line, with
2373  // invalid iterator. if line
2374  // already exists, then
2375  // nothing bad happens here
2376  needed_lines[line_vertices] = triangulation.end_line();
2377  }
2378  }
2379  }
2380 
2381 
2383  // now for some sanity-checks:
2384  //
2385  // check that every vertex has at
2386  // least tree adjacent lines
2387  {
2388  std::vector<unsigned short int> vertex_touch_count(v.size(), 0);
2389  typename std::map<
2390  std::pair<int, int>,
2391  typename Triangulation<dim, spacedim>::line_iterator>::iterator i;
2392  for (i = needed_lines.begin(); i != needed_lines.end(); ++i)
2393  {
2394  // touch the vertices of
2395  // this line
2396  ++vertex_touch_count[i->first.first];
2397  ++vertex_touch_count[i->first.second];
2398  }
2399 
2400  // assert minimum touch count
2401  // is at least three. if not so,
2402  // then clean triangulation and
2403  // exit with an exception
2404  AssertThrow(
2405  *(std::min_element(vertex_touch_count.begin(),
2406  vertex_touch_count.end())) >= 3,
2407  ExcMessage(
2408  "During creation of a triangulation, a part of the "
2409  "algorithm encountered a vertex that is part of only "
2410  "one or two adjacent lines. However, in 3d, every vertex "
2411  "needs to be at least part of three lines."));
2412  }
2413 
2414 
2416  // actually set up data structures
2417  // for the lines
2418  // reserve enough space
2419  triangulation.levels.push_back(
2420  std_cxx14::make_unique<
2422  triangulation.faces = std_cxx14::make_unique<
2424  triangulation.levels[0]->reserve_space(cells.size(), dim, spacedim);
2425  triangulation.faces->lines.reserve_space(0, needed_lines.size());
2426 
2427  // make up lines
2428  {
2429  typename Triangulation<dim, spacedim>::raw_line_iterator line =
2430  triangulation.begin_raw_line();
2431  typename std::map<
2432  std::pair<int, int>,
2433  typename Triangulation<dim, spacedim>::line_iterator>::iterator i;
2434  for (i = needed_lines.begin(); line != triangulation.end_line();
2435  ++line, ++i)
2436  {
2438  i->first.first, i->first.second));
2439  line->set_used_flag();
2440  line->clear_user_flag();
2441  line->clear_user_data();
2442 
2443  // now set the iterator for
2444  // this line
2445  i->second = line;
2446  }
2447  }
2448 
2449 
2451  // make up the quads of this triangulation
2452  //
2453  // same thing: the iterators are
2454  // set to the invalid value at
2455  // first, we only collect the data
2456  // now
2457 
2458  // the bool array stores, whether the lines
2459  // are in the standard orientation or not
2460 
2461  // note that QuadComparator is a
2462  // class declared and defined in
2463  // this file
2464  std::map<internal::TriangulationImplementation::TriaObject<2>,
2465  std::pair<typename Triangulation<dim, spacedim>::quad_iterator,
2466  std::array<bool, GeometryInfo<dim>::lines_per_face>>,
2468  needed_quads;
2469  for (const auto &cell : cells)
2470  {
2471  // the faces are quads which
2472  // consist of four numbers
2473  // denoting the index of the
2474  // four lines bounding the
2475  // quad. we can get this index
2476  // by asking @p{needed_lines}
2477  // for an iterator to this
2478  // line, dereferencing it and
2479  // thus return an iterator into
2480  // the @p{lines} array of the
2481  // triangulation, which is
2482  // already set up. we can then
2483  // ask this iterator for its
2484  // index within the present
2485  // level (the level is zero, of
2486  // course)
2487  //
2488  // to make things easier, we
2489  // don't create the lines
2490  // (pairs of their vertex
2491  // indices) in place, but
2492  // before they are really
2493  // needed.
2494  std::pair<int, int> line_list[GeometryInfo<dim>::lines_per_cell],
2495  inverse_line_list[GeometryInfo<dim>::lines_per_cell];
2496  unsigned int face_line_list[GeometryInfo<dim>::lines_per_face];
2497  std::array<bool, GeometryInfo<dim>::lines_per_face> orientation;
2498 
2499  for (unsigned int line = 0;
2500  line < GeometryInfo<dim>::lines_per_cell;
2501  ++line)
2502  {
2503  line_list[line] = std::pair<int, int>(
2504  cell.vertices[GeometryInfo<dim>::line_to_cell_vertices(line,
2505  0)],
2506  cell.vertices[GeometryInfo<dim>::line_to_cell_vertices(line,
2507  1)]);
2508  inverse_line_list[line] = std::pair<int, int>(
2509  cell.vertices[GeometryInfo<dim>::line_to_cell_vertices(line,
2510  1)],
2511  cell.vertices[GeometryInfo<dim>::line_to_cell_vertices(line,
2512  0)]);
2513  }
2514 
2515  for (unsigned int face = 0;
2516  face < GeometryInfo<dim>::faces_per_cell;
2517  ++face)
2518  {
2519  // set up a list of the lines to be
2520  // used for this face. check the
2521  // direction for each line
2522  //
2523  // given a face line number (0-3) on
2524  // a specific face we get the cell
2525  // line number (0-11) through the
2526  // face_to_cell_lines function
2527  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_face;
2528  ++l)
2529  if (needed_lines.find(
2530  inverse_line_list[GeometryInfo<dim>::face_to_cell_lines(
2531  face, l)]) == needed_lines.end())
2532  {
2533  face_line_list[l] =
2534  needed_lines[line_list[GeometryInfo<
2535  dim>::face_to_cell_lines(face, l)]]
2536  ->index();
2537  orientation[l] = true;
2538  }
2539  else
2540  {
2541  face_line_list[l] =
2542  needed_lines[inverse_line_list[GeometryInfo<
2543  dim>::face_to_cell_lines(face, l)]]
2544  ->index();
2545  orientation[l] = false;
2546  }
2547 
2548 
2550  face_line_list[0],
2551  face_line_list[1],
2552  face_line_list[2],
2553  face_line_list[3]);
2554 
2555  // insert quad, with
2556  // invalid iterator
2557  //
2558  // if quad already exists,
2559  // then nothing bad happens
2560  // here, as this will then
2561  // simply become an
2562  // interior face of the
2563  // triangulation. however,
2564  // we will run into major
2565  // trouble if the face was
2566  // already inserted in the
2567  // opposite
2568  // direction. there are
2569  // really only two
2570  // orientations for a face
2571  // to be in, since the edge
2572  // directions are already
2573  // set. thus, vertex 0 is
2574  // the one from which two
2575  // edges originate, and
2576  // vertex 3 is the one to
2577  // which they converge. we
2578  // are then left with
2579  // orientations 0-1-2-3 and
2580  // 2-3-0-1 for the order of
2581  // lines. the
2582  // corresponding quad can
2583  // be easily constructed by
2584  // exchanging lines. we do
2585  // so here, just to check
2586  // that that flipped quad
2587  // isn't already in the
2588  // triangulation. if it is,
2589  // then don't insert the
2590  // new one and instead
2591  // later set the
2592  // face_orientation flag
2594  test_quad_1(quad.face(2),
2595  quad.face(3),
2596  quad.face(0),
2597  quad.face(
2598  1)), // face_orientation=false, face_flip=false,
2599  // face_rotation=false
2600  test_quad_2(quad.face(0),
2601  quad.face(1),
2602  quad.face(3),
2603  quad.face(
2604  2)), // face_orientation=false, face_flip=false,
2605  // face_rotation=true
2606  test_quad_3(quad.face(3),
2607  quad.face(2),
2608  quad.face(1),
2609  quad.face(
2610  0)), // face_orientation=false, face_flip=true,
2611  // face_rotation=false
2612  test_quad_4(quad.face(1),
2613  quad.face(0),
2614  quad.face(2),
2615  quad.face(
2616  3)), // face_orientation=false, face_flip=true,
2617  // face_rotation=true
2618  test_quad_5(quad.face(2),
2619  quad.face(3),
2620  quad.face(1),
2621  quad.face(
2622  0)), // face_orientation=true, face_flip=false,
2623  // face_rotation=true
2624  test_quad_6(quad.face(1),
2625  quad.face(0),
2626  quad.face(3),
2627  quad.face(
2628  2)), // face_orientation=true, face_flip=true,
2629  // face_rotation=false
2630  test_quad_7(quad.face(3),
2631  quad.face(2),
2632  quad.face(0),
2633  quad.face(
2634  1)); // face_orientation=true, face_flip=true,
2635  // face_rotation=true
2636  if (needed_quads.find(test_quad_1) == needed_quads.end() &&
2637  needed_quads.find(test_quad_2) == needed_quads.end() &&
2638  needed_quads.find(test_quad_3) == needed_quads.end() &&
2639  needed_quads.find(test_quad_4) == needed_quads.end() &&
2640  needed_quads.find(test_quad_5) == needed_quads.end() &&
2641  needed_quads.find(test_quad_6) == needed_quads.end() &&
2642  needed_quads.find(test_quad_7) == needed_quads.end())
2643  needed_quads[quad] =
2644  std::make_pair(triangulation.end_quad(), orientation);
2645  }
2646  }
2647 
2648 
2650  // enter the resulting quads into
2651  // the arrays of the Triangulation
2652  //
2653  // first reserve enough space
2654  triangulation.faces->quads.reserve_space(0, needed_quads.size());
2655 
2656  {
2657  typename Triangulation<dim, spacedim>::raw_quad_iterator quad =
2658  triangulation.begin_raw_quad();
2659  typename std::map<
2661  std::pair<typename Triangulation<dim, spacedim>::quad_iterator,
2662  std::array<bool, GeometryInfo<dim>::lines_per_face>>,
2663  QuadComparator>::iterator q;
2664  for (q = needed_quads.begin(); quad != triangulation.end_quad();
2665  ++quad, ++q)
2666  {
2667  quad->set(q->first);
2668  quad->set_used_flag();
2669  quad->clear_user_flag();
2670  quad->clear_user_data();
2671  // set the line orientation
2672  quad->set_line_orientation(0, q->second.second[0]);
2673  quad->set_line_orientation(1, q->second.second[1]);
2674  quad->set_line_orientation(2, q->second.second[2]);
2675  quad->set_line_orientation(3, q->second.second[3]);
2676 
2677 
2678  // now set the iterator for
2679  // this quad
2680  q->second.first = quad;
2681  }
2682  }
2683 
2685  // finally create the cells
2686  triangulation.levels[0]->cells.reserve_space(cells.size());
2687 
2688  // store for each quad index the
2689  // adjacent cells
2690  std::map<
2691  int,
2692  std::vector<typename Triangulation<dim, spacedim>::cell_iterator>>
2693  adjacent_cells;
2694 
2695  // finally make up cells
2696  {
2698  triangulation.begin_raw_hex();
2699  for (unsigned int c = 0; c < cells.size(); ++c, ++cell)
2700  {
2701  // first find for each of
2702  // the cells the quad
2703  // iterator of the
2704  // respective faces.
2705  //
2706  // to this end, set up the
2707  // lines of this cell and
2708  // find the quads that are
2709  // bounded by these lines;
2710  // these are then the faces
2711  // of the present cell
2712  std::pair<int, int> line_list[GeometryInfo<dim>::lines_per_cell],
2713  inverse_line_list[GeometryInfo<dim>::lines_per_cell];
2714  unsigned int face_line_list[4];
2715  for (unsigned int line = 0;
2716  line < GeometryInfo<dim>::lines_per_cell;
2717  ++line)
2718  {
2719  line_list[line] = std::make_pair(
2720  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2721  line, 0)],
2722  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2723  line, 1)]);
2724  inverse_line_list[line] = std::pair<int, int>(
2725  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2726  line, 1)],
2727  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2728  line, 0)]);
2729  }
2730 
2731  // get the iterators
2732  // corresponding to the
2733  // faces. also store
2734  // whether they are
2735  // reversed or not
2737  face_iterator[GeometryInfo<dim>::faces_per_cell];
2738  bool face_orientation[GeometryInfo<dim>::faces_per_cell];
2739  bool face_flip[GeometryInfo<dim>::faces_per_cell];
2740  bool face_rotation[GeometryInfo<dim>::faces_per_cell];
2741  for (unsigned int face = 0;
2742  face < GeometryInfo<dim>::faces_per_cell;
2743  ++face)
2744  {
2745  for (unsigned int l = 0;
2746  l < GeometryInfo<dim>::lines_per_face;
2747  ++l)
2748  if (needed_lines.find(inverse_line_list[GeometryInfo<
2749  dim>::face_to_cell_lines(face, l)]) ==
2750  needed_lines.end())
2751  face_line_list[l] =
2752  needed_lines[line_list[GeometryInfo<
2753  dim>::face_to_cell_lines(face, l)]]
2754  ->index();
2755  else
2756  face_line_list[l] =
2757  needed_lines[inverse_line_list[GeometryInfo<
2758  dim>::face_to_cell_lines(face, l)]]
2759  ->index();
2760 
2762  face_line_list[0],
2763  face_line_list[1],
2764  face_line_list[2],
2765  face_line_list[3]);
2766 
2767  if (needed_quads.find(quad) != needed_quads.end())
2768  {
2769  // face is in standard
2770  // orientation (and not
2771  // flipped or rotated). this
2772  // must be true for at least
2773  // one of the two cells
2774  // containing this face
2775  // (i.e. for the cell which
2776  // originally inserted the
2777  // face)
2778  face_iterator[face] = needed_quads[quad].first;
2779  face_orientation[face] = true;
2780  face_flip[face] = false;
2781  face_rotation[face] = false;
2782  }
2783  else
2784  {
2785  // face must be available in
2786  // reverse order
2787  // then. construct all
2788  // possibilities and check
2789  // them one after the other
2791  test_quad_1(
2792  quad.face(2),
2793  quad.face(3),
2794  quad.face(0),
2795  quad.face(1)), // face_orientation=false,
2796  // face_flip=false, face_rotation=false
2797  test_quad_2(
2798  quad.face(0),
2799  quad.face(1),
2800  quad.face(3),
2801  quad.face(2)), // face_orientation=false,
2802  // face_flip=false, face_rotation=true
2803  test_quad_3(
2804  quad.face(3),
2805  quad.face(2),
2806  quad.face(1),
2807  quad.face(0)), // face_orientation=false,
2808  // face_flip=true, face_rotation=false
2809  test_quad_4(quad.face(1),
2810  quad.face(0),
2811  quad.face(2),
2812  quad.face(
2813  3)), // face_orientation=false,
2814  // face_flip=true, face_rotation=true
2815  test_quad_5(
2816  quad.face(2),
2817  quad.face(3),
2818  quad.face(1),
2819  quad.face(0)), // face_orientation=true,
2820  // face_flip=false, face_rotation=true
2821  test_quad_6(
2822  quad.face(1),
2823  quad.face(0),
2824  quad.face(3),
2825  quad.face(2)), // face_orientation=true,
2826  // face_flip=true, face_rotation=false
2827  test_quad_7(quad.face(3),
2828  quad.face(2),
2829  quad.face(0),
2830  quad.face(
2831  1)); // face_orientation=true,
2832  // face_flip=true, face_rotation=true
2833  if (needed_quads.find(test_quad_1) != needed_quads.end())
2834  {
2835  face_iterator[face] = needed_quads[test_quad_1].first;
2836  face_orientation[face] = false;
2837  face_flip[face] = false;
2838  face_rotation[face] = false;
2839  }
2840  else if (needed_quads.find(test_quad_2) !=
2841  needed_quads.end())
2842  {
2843  face_iterator[face] = needed_quads[test_quad_2].first;
2844  face_orientation[face] = false;
2845  face_flip[face] = false;
2846  face_rotation[face] = true;
2847  }
2848  else if (needed_quads.find(test_quad_3) !=
2849  needed_quads.end())
2850  {
2851  face_iterator[face] = needed_quads[test_quad_3].first;
2852  face_orientation[face] = false;
2853  face_flip[face] = true;
2854  face_rotation[face] = false;
2855  }
2856  else if (needed_quads.find(test_quad_4) !=
2857  needed_quads.end())
2858  {
2859  face_iterator[face] = needed_quads[test_quad_4].first;
2860  face_orientation[face] = false;
2861  face_flip[face] = true;
2862  face_rotation[face] = true;
2863  }
2864  else if (needed_quads.find(test_quad_5) !=
2865  needed_quads.end())
2866  {
2867  face_iterator[face] = needed_quads[test_quad_5].first;
2868  face_orientation[face] = true;
2869  face_flip[face] = false;
2870  face_rotation[face] = true;
2871  }
2872  else if (needed_quads.find(test_quad_6) !=
2873  needed_quads.end())
2874  {
2875  face_iterator[face] = needed_quads[test_quad_6].first;
2876  face_orientation[face] = true;
2877  face_flip[face] = true;
2878  face_rotation[face] = false;
2879  }
2880  else if (needed_quads.find(test_quad_7) !=
2881  needed_quads.end())
2882  {
2883  face_iterator[face] = needed_quads[test_quad_7].first;
2884  face_orientation[face] = true;
2885  face_flip[face] = true;
2886  face_rotation[face] = true;
2887  }
2888 
2889  else
2890  // we didn't find the
2891  // face in any direction,
2892  // so something went
2893  // wrong above
2894  Assert(false, ExcInternalError());
2895  }
2896  } // for all faces
2897 
2898  // make the cell out of
2899  // these iterators
2900  cell->set(internal::TriangulationImplementation ::TriaObject<3>(
2901  face_iterator[0]->index(),
2902  face_iterator[1]->index(),
2903  face_iterator[2]->index(),
2904  face_iterator[3]->index(),
2905  face_iterator[4]->index(),
2906  face_iterator[5]->index()));
2907 
2908  cell->set_used_flag();
2909  cell->set_material_id(cells[c].material_id);
2910  cell->set_manifold_id(cells[c].manifold_id);
2911  cell->clear_user_flag();
2912  cell->clear_user_data();
2913  cell->set_subdomain_id(0);
2914 
2915  // set orientation flag for
2916  // each of the faces
2917  for (unsigned int quad = 0;
2918  quad < GeometryInfo<dim>::faces_per_cell;
2919  ++quad)
2920  {
2921  cell->set_face_orientation(quad, face_orientation[quad]);
2922  cell->set_face_flip(quad, face_flip[quad]);
2923  cell->set_face_rotation(quad, face_rotation[quad]);
2924  }
2925 
2926 
2927  // note that this cell is
2928  // adjacent to the six
2929  // quads
2930  for (const auto &quad : face_iterator)
2931  adjacent_cells[quad->index()].push_back(cell);
2932 
2933 #ifdef DEBUG
2934  // make some checks on the
2935  // lines and their
2936  // ordering
2937 
2938  // first map all cell lines
2939  // to the two face lines
2940  // which should
2941  // coincide. all face lines
2942  // are included with a cell
2943  // line number (0-11)
2944  // key. At the end all keys
2945  // will be included twice
2946  // (for each of the two
2947  // coinciding lines once)
2948  std::multimap<unsigned int, std::pair<unsigned int, unsigned int>>
2949  cell_to_face_lines;
2950  for (unsigned int face = 0;
2951  face < GeometryInfo<dim>::faces_per_cell;
2952  ++face)
2953  for (unsigned int line = 0;
2954  line < GeometryInfo<dim>::lines_per_face;
2955  ++line)
2956  cell_to_face_lines.insert(
2957  std::pair<unsigned int,
2958  std::pair<unsigned int, unsigned int>>(
2960  std::pair<unsigned int, unsigned int>(face, line)));
2961  std::multimap<unsigned int,
2962  std::pair<unsigned int, unsigned int>>::
2963  const_iterator map_iter = cell_to_face_lines.begin();
2964 
2965  for (; map_iter != cell_to_face_lines.end(); ++map_iter)
2966  {
2967  const unsigned int cell_line = map_iter->first;
2968  const unsigned int face1 = map_iter->second.first;
2969  const unsigned int line1 = map_iter->second.second;
2970  ++map_iter;
2971  Assert(map_iter != cell_to_face_lines.end(),
2973  Assert(map_iter->first == cell_line,
2975  const unsigned int face2 = map_iter->second.first;
2976  const unsigned int line2 = map_iter->second.second;
2977 
2978  // check that the pair
2979  // of lines really
2980  // coincide. Take care
2981  // about the face
2982  // orientation;
2983  Assert(face_iterator[face1]->line(
2985  line1,
2986  face_orientation[face1],
2987  face_flip[face1],
2988  face_rotation[face1])) ==
2989  face_iterator[face2]->line(
2991  line2,
2992  face_orientation[face2],
2993  face_flip[face2],
2994  face_rotation[face2])),
2996  }
2997 #endif
2998  }
2999  }
3000 
3001 
3003  // find those quads which are at the
3004  // boundary and mark them appropriately
3005  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
3006  triangulation.begin_quad();
3007  quad != triangulation.end_quad();
3008  ++quad)
3009  {
3010  const unsigned int n_adj_cells =
3011  adjacent_cells[quad->index()].size();
3012  // assert that every quad has
3013  // one or two adjacent cells
3014  AssertThrow((n_adj_cells >= 1) && (n_adj_cells <= 2),
3015  ExcInternalError());
3016 
3017  // if only one cell: quad is at boundary -> give it the boundary
3018  // indicator zero by default
3019  quad->set_boundary_id_internal(
3020  (n_adj_cells == 1) ? 0 : numbers::internal_face_boundary_id);
3021 
3022  // Manifold ids are set independently of where they are
3023  quad->set_manifold_id(numbers::flat_manifold_id);
3024  }
3025 
3027  // next find those lines which are at
3028  // the boundary and mark all others as
3029  // interior ones
3030  //
3031  // for this: first mark all lines as interior. use this loop
3032  // to also set all manifold ids of all lines
3033  for (typename Triangulation<dim, spacedim>::line_iterator line =
3034  triangulation.begin_line();
3035  line != triangulation.end_line();
3036  ++line)
3037  {
3038  line->set_boundary_id_internal(numbers::internal_face_boundary_id);
3039  line->set_manifold_id(numbers::flat_manifold_id);
3040  }
3041 
3042  // next reset all lines bounding
3043  // boundary quads as on the
3044  // boundary also. note that since
3045  // we are in 3d, there are cases
3046  // where one or more lines of a
3047  // quad that is not on the
3048  // boundary, are actually boundary
3049  // lines. they will not be marked
3050  // when visiting this
3051  // face. however, since we do not
3052  // support dim-2 dimensional
3053  // boundaries (i.e. internal lines
3054  // constituting boundaries), every
3055  // such line is also part of a face
3056  // that is actually on the
3057  // boundary, so sooner or later we
3058  // get to mark that line for being
3059  // on the boundary
3060  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
3061  triangulation.begin_quad();
3062  quad != triangulation.end_quad();
3063  ++quad)
3064  if (quad->at_boundary())
3065  {
3066  for (unsigned int l = 0; l < 4; ++l)
3067  {
3069  quad->line(l);
3070  line->set_boundary_id_internal(0);
3071  }
3072  }
3073 
3075  // now set boundary indicators
3076  // where given
3077  //
3078  // first do so for lines
3079  for (const auto &subcell_line : subcelldata.boundary_lines)
3080  {
3082  std::pair<int, int> line_vertices(
3083  std::make_pair(subcell_line.vertices[0],
3084  subcell_line.vertices[1]));
3085  if (needed_lines.find(line_vertices) != needed_lines.end())
3086  // line found in this
3087  // direction
3088  line = needed_lines[line_vertices];
3089 
3090  else
3091  {
3092  // look whether it exists in
3093  // reverse direction
3094  std::swap(line_vertices.first, line_vertices.second);
3095  if (needed_lines.find(line_vertices) != needed_lines.end())
3096  line = needed_lines[line_vertices];
3097  else
3098  // line does not exist
3099  AssertThrow(false,
3100  ExcLineInexistant(line_vertices.first,
3101  line_vertices.second));
3102  }
3103  // Only exterior lines can be given a boundary indicator
3104  if (line->at_boundary())
3105  {
3106  // make sure that we don't attempt to reset the boundary
3107  // indicator to a different than the previously set value
3108  AssertThrow(line->boundary_id() == 0 ||
3109  line->boundary_id() == subcell_line.boundary_id,
3110  ExcInconsistentLineInfoOfLine(line_vertices.first,
3111  line_vertices.second,
3112  "boundary ids"));
3113 
3114  line->set_boundary_id_internal(subcell_line.boundary_id);
3115  }
3116  // Set manifold id if given
3117  AssertThrow(line->manifold_id() == numbers::flat_manifold_id ||
3118  line->manifold_id() == subcell_line.manifold_id,
3119  ExcInconsistentLineInfoOfLine(line_vertices.first,
3120  line_vertices.second,
3121  "manifold ids"));
3122  line->set_manifold_id(subcell_line.manifold_id);
3123  }
3124 
3125 
3126  // now go on with the faces
3127  for (const auto &subcell_quad : subcelldata.boundary_quads)
3128  {
3131 
3132  // first find the lines that
3133  // are made up of the given
3134  // vertices, then build up a
3135  // quad from these lines
3136  // finally use the find
3137  // function of the map template
3138  // to find the quad
3139  for (unsigned int i = 0; i < 4; ++i)
3140  {
3141  std::pair<int, int> line_vertices(
3142  subcell_quad
3144  0)],
3145  subcell_quad
3147  1)]);
3148 
3149  // check whether line
3150  // already exists
3151  if (needed_lines.find(line_vertices) != needed_lines.end())
3152  line[i] = needed_lines[line_vertices];
3153  else
3154  // look whether it exists
3155  // in reverse direction
3156  {
3157  std::swap(line_vertices.first, line_vertices.second);
3158  if (needed_lines.find(line_vertices) != needed_lines.end())
3159  line[i] = needed_lines[line_vertices];
3160  else
3161  // line does
3162  // not exist
3163  AssertThrow(false,
3164  ExcLineInexistant(line_vertices.first,
3165  line_vertices.second));
3166  }
3167  }
3168 
3169 
3170  // Set up 2 quads that are
3171  // built up from the lines for
3172  // reasons of comparison to
3173  // needed_quads. The second
3174  // quad is the reversed version
3175  // of the first quad in order
3176  // find the quad regardless of
3177  // its orientation. This is
3178  // introduced for convenience
3179  // and because boundary quad
3180  // orientation does not carry
3181  // any information.
3183  line[0]->index(),
3184  line[1]->index(),
3185  line[2]->index(),
3186  line[3]->index());
3188  line[2]->index(),
3189  line[3]->index(),
3190  line[0]->index(),
3191  line[1]->index());
3192 
3193  // try to find the quad with
3194  // lines situated as
3195  // constructed above. if it
3196  // could not be found, rotate
3197  // the boundary lines 3 times
3198  // until it is found or it does
3199  // not exist.
3200 
3201  // mapping from counterclock to
3202  // lexicographic ordering of
3203  // quad lines
3204  static const unsigned int lex2cclock[4] = {3, 1, 0, 2};
3205  // copy lines from
3206  // lexicographic to
3207  // counterclock ordering, as
3208  // rotation is much simpler in
3209  // counterclock ordering
3211  line_counterclock[4];
3212  for (unsigned int i = 0; i < 4; ++i)
3213  line_counterclock[lex2cclock[i]] = line[i];
3214  unsigned int n_rotations = 0;
3215  bool not_found_quad_1;
3216  while ((not_found_quad_1 = (needed_quads.find(quad_compare_1) ==
3217  needed_quads.end())) &&
3218  (needed_quads.find(quad_compare_2) == needed_quads.end()) &&
3219  (n_rotations < 4))
3220  {
3221  // use the rotate defined
3222  // in <algorithms>
3223  std::rotate(line_counterclock,
3224  line_counterclock + 1,
3225  line_counterclock + 4);
3226  // update the quads with
3227  // rotated lines (i runs in
3228  // lexicographic ordering)
3229  for (unsigned int i = 0; i < 4; ++i)
3230  {
3231  quad_compare_1.set_face(
3232  i, line_counterclock[lex2cclock[i]]->index());
3233  quad_compare_2.set_face(
3234  (i + 2) % 4, line_counterclock[lex2cclock[i]]->index());
3235  }
3236 
3237  ++n_rotations;
3238  }
3239 
3240  AssertThrow(n_rotations != 4,
3241  ExcQuadInexistant(line[0]->index(),
3242  line[1]->index(),
3243  line[2]->index(),
3244  line[3]->index()));
3245 
3246  if (not_found_quad_1)
3247  quad = needed_quads[quad_compare_2].first;
3248  else
3249  quad = needed_quads[quad_compare_1].first;
3250 
3251  // check whether this face is
3252  // really an exterior one
3253  if (quad->at_boundary())
3254  {
3255  // and make sure that we don't attempt to reset the boundary
3256  // indicator to a different than the previously set value
3257  AssertThrow(quad->boundary_id() == 0 ||
3258  quad->boundary_id() == subcell_quad.boundary_id,
3259  ExcInconsistentQuadInfoOfQuad(line[0]->index(),
3260  line[1]->index(),
3261  line[2]->index(),
3262  line[3]->index(),
3263  "boundary ids"));
3264 
3265  quad->set_boundary_id_internal(subcell_quad.boundary_id);
3266  }
3267  // Set manifold id if given
3268  if (quad->manifold_id() != numbers::flat_manifold_id)
3269  AssertThrow(quad->manifold_id() == subcell_quad.manifold_id,
3270  ExcInconsistentQuadInfoOfQuad(line[0]->index(),
3271  line[1]->index(),
3272  line[2]->index(),
3273  line[3]->index(),
3274  "manifold ids"));
3275 
3276  quad->set_manifold_id(subcell_quad.manifold_id);
3277  }
3278 
3279 
3281  // finally update neighborship info
3282  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
3283  triangulation.begin();
3284  cell != triangulation.end();
3285  ++cell)
3286  for (unsigned int face = 0; face < 6; ++face)
3287  if (adjacent_cells[cell->quad(face)->index()][0] == cell)
3288  // first adjacent cell is
3289  // this one
3290  {
3291  if (adjacent_cells[cell->quad(face)->index()].size() == 2)
3292  // there is another
3293  // adjacent cell
3294  cell->set_neighbor(
3295  face, adjacent_cells[cell->quad(face)->index()][1]);
3296  }
3297  // first adjacent cell is not this
3298  // one, -> it must be the neighbor
3299  // we are looking for
3300  else
3301  cell->set_neighbor(face,
3302  adjacent_cells[cell->quad(face)->index()][0]);
3303  }
3304 
3305 
3321  template <int spacedim>
3322  static void delete_children(
3323  Triangulation<1, spacedim> & triangulation,
3325  std::vector<unsigned int> &,
3326  std::vector<unsigned int> &)
3327  {
3328  const unsigned int dim = 1;
3329 
3330  // first we need to reset the
3331  // neighbor pointers of the
3332  // neighbors of this cell's
3333  // children to this cell. This is
3334  // different for one dimension,
3335  // since there neighbors can have a
3336  // refinement level differing from
3337  // that of this cell's children by
3338  // more than one level.
3339 
3340  Assert(!cell->child(0)->has_children() &&
3341  !cell->child(1)->has_children(),
3342  ExcInternalError());
3343 
3344  // first do it for the cells to the
3345  // left
3346  if (cell->neighbor(0).state() == IteratorState::valid)
3347  if (cell->neighbor(0)->has_children())
3348  {
3350  cell->neighbor(0);
3351  Assert(neighbor->level() == cell->level(), ExcInternalError());
3352 
3353  // right child
3354  neighbor = neighbor->child(1);
3355  while (true)
3356  {
3357  Assert(neighbor->neighbor(1) == cell->child(0),
3358  ExcInternalError());
3359  neighbor->set_neighbor(1, cell);
3360 
3361  // move on to further
3362  // children on the
3363  // boundary between this
3364  // cell and its neighbor
3365  if (neighbor->has_children())
3366  neighbor = neighbor->child(1);
3367  else
3368  break;
3369  }
3370  }
3371 
3372  // now do it for the cells to the
3373  // left
3374  if (cell->neighbor(1).state() == IteratorState::valid)
3375  if (cell->neighbor(1)->has_children())
3376  {
3378  cell->neighbor(1);
3379  Assert(neighbor->level() == cell->level(), ExcInternalError());
3380 
3381  // left child
3382  neighbor = neighbor->child(0);
3383  while (true)
3384  {
3385  Assert(neighbor->neighbor(0) == cell->child(1),
3386  ExcInternalError());
3387  neighbor->set_neighbor(0, cell);
3388 
3389  // move on to further
3390  // children on the
3391  // boundary between this
3392  // cell and its neighbor
3393  if (neighbor->has_children())
3394  neighbor = neighbor->child(0);
3395  else
3396  break;
3397  }
3398  }
3399 
3400 
3401  // delete the vertex which will not
3402  // be needed anymore. This vertex
3403  // is the second of the first child
3404  triangulation.vertices_used[cell->child(0)->vertex_index(1)] = false;
3405 
3406  // invalidate children. clear user
3407  // pointers, to avoid that they may
3408  // appear at unwanted places later
3409  // on...
3410  for (unsigned int child = 0; child < cell->n_children(); ++child)
3411  {
3412  cell->child(child)->clear_user_data();
3413  cell->child(child)->clear_user_flag();
3414  cell->child(child)->clear_used_flag();
3415  }
3416 
3417 
3418  // delete pointer to children
3419  cell->clear_children();
3420  cell->clear_user_flag();
3421  }
3422 
3423 
3424 
3425  template <int spacedim>
3426  static void delete_children(
3427  Triangulation<2, spacedim> & triangulation,
3429  std::vector<unsigned int> & line_cell_count,
3430  std::vector<unsigned int> &)
3431  {
3432  const unsigned int dim = 2;
3433  const RefinementCase<dim> ref_case = cell->refinement_case();
3434 
3435  Assert(line_cell_count.size() == triangulation.n_raw_lines(),
3436  ExcInternalError());
3437 
3438  // vectors to hold all lines which
3439  // may be deleted
3440  std::vector<typename Triangulation<dim, spacedim>::line_iterator>
3441  lines_to_delete(0);
3442 
3443  lines_to_delete.reserve(4 * 2 + 4);
3444 
3445  // now we decrease the counters for
3446  // lines contained in the child
3447  // cells
3448  for (unsigned int c = 0; c < cell->n_children(); ++c)
3449  {
3451  cell->child(c);
3452  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
3453  --line_cell_count[child->line_index(l)];
3454  }
3455 
3456 
3457  // delete the vertex which will not
3458  // be needed anymore. This vertex
3459  // is the second of the second line
3460  // of the first child, if the cell
3461  // is refined with cut_xy, else there
3462  // is no inner vertex.
3463  // additionally delete unneeded inner
3464  // lines
3465  if (ref_case == RefinementCase<dim>::cut_xy)
3466  {
3467  triangulation
3468  .vertices_used[cell->child(0)->line(1)->vertex_index(1)] = false;
3469 
3470  lines_to_delete.push_back(cell->child(0)->line(1));
3471  lines_to_delete.push_back(cell->child(0)->line(3));
3472  lines_to_delete.push_back(cell->child(3)->line(0));
3473  lines_to_delete.push_back(cell->child(3)->line(2));
3474  }
3475  else
3476  {
3477  unsigned int inner_face_no =
3478  ref_case == RefinementCase<dim>::cut_x ? 1 : 3;
3479 
3480  // the inner line will not be
3481  // used any more
3482  lines_to_delete.push_back(cell->child(0)->line(inner_face_no));
3483  }
3484 
3485  // invalidate children
3486  for (unsigned int child = 0; child < cell->n_children(); ++child)
3487  {
3488  cell->child(child)->clear_user_data();
3489  cell->child(child)->clear_user_flag();
3490  cell->child(child)->clear_used_flag();
3491  }
3492 
3493 
3494  // delete pointer to children
3495  cell->clear_children();
3496  cell->clear_refinement_case();
3497  cell->clear_user_flag();
3498 
3499  // look at the refinement of outer
3500  // lines. if nobody needs those
3501  // anymore we can add them to the
3502  // list of lines to be deleted.
3503  for (unsigned int line_no = 0;
3504  line_no < GeometryInfo<dim>::lines_per_cell;
3505  ++line_no)
3506  {
3508  cell->line(line_no);
3509 
3510  if (line->has_children())
3511  {
3512  // if one of the cell counters is
3513  // zero, the other has to be as well
3514 
3515  Assert((line_cell_count[line->child_index(0)] == 0 &&
3516  line_cell_count[line->child_index(1)] == 0) ||
3517  (line_cell_count[line->child_index(0)] > 0 &&
3518  line_cell_count[line->child_index(1)] > 0),
3519  ExcInternalError());
3520 
3521  if (line_cell_count[line->child_index(0)] == 0)
3522  {
3523  for (unsigned int c = 0; c < 2; ++c)
3524  Assert(!line->child(c)->has_children(),
3525  ExcInternalError());
3526 
3527  // we may delete the line's
3528  // children and the middle vertex
3529  // as no cell references them
3530  // anymore
3531  triangulation
3532  .vertices_used[line->child(0)->vertex_index(1)] = false;
3533 
3534  lines_to_delete.push_back(line->child(0));
3535  lines_to_delete.push_back(line->child(1));
3536 
3537  line->clear_children();
3538  }
3539  }
3540  }
3541 
3542  // finally, delete unneeded lines
3543 
3544  // clear user pointers, to avoid that
3545  // they may appear at unwanted places
3546  // later on...
3547  // same for user flags, then finally
3548  // delete the lines
3549  typename std::vector<
3551  line = lines_to_delete.begin(),
3552  endline = lines_to_delete.end();
3553  for (; line != endline; ++line)
3554  {
3555  (*line)->clear_user_data();
3556  (*line)->clear_user_flag();
3557  (*line)->clear_used_flag();
3558  }
3559  }
3560 
3561 
3562 
3563  template <int spacedim>
3564  static void delete_children(
3565  Triangulation<3, spacedim> & triangulation,
3567  std::vector<unsigned int> & line_cell_count,
3568  std::vector<unsigned int> & quad_cell_count)
3569  {
3570  const unsigned int dim = 3;
3571 
3572  Assert(line_cell_count.size() == triangulation.n_raw_lines(),
3573  ExcInternalError());
3574  Assert(quad_cell_count.size() == triangulation.n_raw_quads(),
3575  ExcInternalError());
3576 
3577  // first of all, we store the RefineCase of
3578  // this cell
3579  const RefinementCase<dim> ref_case = cell->refinement_case();
3580  // vectors to hold all lines and quads which
3581  // may be deleted
3582  std::vector<typename Triangulation<dim, spacedim>::line_iterator>
3583  lines_to_delete(0);
3584  std::vector<typename Triangulation<dim, spacedim>::quad_iterator>
3585  quads_to_delete(0);
3586 
3587  lines_to_delete.reserve(12 * 2 + 6 * 4 + 6);
3588  quads_to_delete.reserve(6 * 4 + 12);
3589 
3590  // now we decrease the counters for lines and
3591  // quads contained in the child cells
3592  for (unsigned int c = 0; c < cell->n_children(); ++c)
3593  {
3595  cell->child(c);
3596  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
3597  --line_cell_count[child->line_index(l)];
3598  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
3599  --quad_cell_count[child->quad_index(f)];
3600  }
3601 
3603  // delete interior quads and lines and the
3604  // interior vertex, depending on the
3605  // refinement case of the cell
3606  //
3607  // for append quads and lines: only append
3608  // them to the list of objects to be deleted
3609 
3610  switch (ref_case)
3611  {
3613  quads_to_delete.push_back(cell->child(0)->face(1));
3614  break;
3616  quads_to_delete.push_back(cell->child(0)->face(3));
3617  break;
3619  quads_to_delete.push_back(cell->child(0)->face(5));
3620  break;
3622  quads_to_delete.push_back(cell->child(0)->face(1));
3623  quads_to_delete.push_back(cell->child(0)->face(3));
3624  quads_to_delete.push_back(cell->child(3)->face(0));
3625  quads_to_delete.push_back(cell->child(3)->face(2));
3626 
3627  lines_to_delete.push_back(cell->child(0)->line(11));
3628  break;
3630  quads_to_delete.push_back(cell->child(0)->face(1));
3631  quads_to_delete.push_back(cell->child(0)->face(5));
3632  quads_to_delete.push_back(cell->child(3)->face(0));
3633  quads_to_delete.push_back(cell->child(3)->face(4));
3634 
3635  lines_to_delete.push_back(cell->child(0)->line(5));
3636  break;
3638  quads_to_delete.push_back(cell->child(0)->face(3));
3639  quads_to_delete.push_back(cell->child(0)->face(5));
3640  quads_to_delete.push_back(cell->child(3)->face(2));
3641  quads_to_delete.push_back(cell->child(3)->face(4));
3642 
3643  lines_to_delete.push_back(cell->child(0)->line(7));
3644  break;
3646  quads_to_delete.push_back(cell->child(0)->face(1));
3647  quads_to_delete.push_back(cell->child(2)->face(1));
3648  quads_to_delete.push_back(cell->child(4)->face(1));
3649  quads_to_delete.push_back(cell->child(6)->face(1));
3650 
3651  quads_to_delete.push_back(cell->child(0)->face(3));
3652  quads_to_delete.push_back(cell->child(1)->face(3));
3653  quads_to_delete.push_back(cell->child(4)->face(3));
3654  quads_to_delete.push_back(cell->child(5)->face(3));
3655 
3656  quads_to_delete.push_back(cell->child(0)->face(5));
3657  quads_to_delete.push_back(cell->child(1)->face(5));
3658  quads_to_delete.push_back(cell->child(2)->face(5));
3659  quads_to_delete.push_back(cell->child(3)->face(5));
3660 
3661  lines_to_delete.push_back(cell->child(0)->line(5));
3662  lines_to_delete.push_back(cell->child(0)->line(7));
3663  lines_to_delete.push_back(cell->child(0)->line(11));
3664  lines_to_delete.push_back(cell->child(7)->line(0));
3665  lines_to_delete.push_back(cell->child(7)->line(2));
3666  lines_to_delete.push_back(cell->child(7)->line(8));
3667  // delete the vertex which will not
3668  // be needed anymore. This vertex
3669  // is the vertex at the heart of
3670  // this cell, which is the sixth of
3671  // the first child
3672  triangulation.vertices_used[cell->child(0)->vertex_index(7)] =
3673  false;
3674  break;
3675  default:
3676  // only remaining case is
3677  // no_refinement, thus an error
3678  Assert(false, ExcInternalError());
3679  break;
3680  }
3681 
3682 
3683  // invalidate children
3684  for (unsigned int child = 0; child < cell->n_children(); ++child)
3685  {
3686  cell->child(child)->clear_user_data();
3687  cell->child(child)->clear_user_flag();
3688 
3689  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
3690  {
3691  // set flags denoting deviations from
3692  // standard orientation of faces back
3693  // to initialization values
3694  cell->child(child)->set_face_orientation(f, true);
3695  cell->child(child)->set_face_flip(f, false);
3696  cell->child(child)->set_face_rotation(f, false);
3697  }
3698 
3699  cell->child(child)->clear_used_flag();
3700  }
3701 
3702 
3703  // delete pointer to children
3704  cell->clear_children();
3705  cell->clear_refinement_case();
3706  cell->clear_user_flag();
3707 
3708  // so far we only looked at inner quads,
3709  // lines and vertices. Now we have to
3710  // consider outer ones as well. here, we have
3711  // to check, whether there are other cells
3712  // still needing these objects. otherwise we
3713  // can delete them. first for quads (and
3714  // their inner lines).
3715 
3716  for (unsigned int quad_no = 0;
3717  quad_no < GeometryInfo<dim>::faces_per_cell;
3718  ++quad_no)
3719  {
3721  cell->face(quad_no);
3722 
3723  Assert(
3724  (GeometryInfo<dim>::face_refinement_case(ref_case, quad_no) &&
3725  quad->has_children()) ||
3726  GeometryInfo<dim>::face_refinement_case(ref_case, quad_no) ==
3727  RefinementCase<dim - 1>::no_refinement,
3728  ExcInternalError());
3729 
3730  switch (quad->refinement_case())
3731  {
3732  case RefinementCase<dim - 1>::no_refinement:
3733  // nothing to do as the quad
3734  // is not refined
3735  break;
3736  case RefinementCase<dim - 1>::cut_x:
3737  case RefinementCase<dim - 1>::cut_y:
3738  {
3739  // if one of the cell counters is
3740  // zero, the other has to be as
3741  // well
3742  Assert((quad_cell_count[quad->child_index(0)] == 0 &&
3743  quad_cell_count[quad->child_index(1)] == 0) ||
3744  (quad_cell_count[quad->child_index(0)] > 0 &&
3745  quad_cell_count[quad->child_index(1)] > 0),
3746  ExcInternalError());
3747  // it might be, that the quad is
3748  // refined twice anisotropically,
3749  // first check, whether we may
3750  // delete possible grand_children
3751  unsigned int deleted_grandchildren = 0;
3752  unsigned int number_of_child_refinements = 0;
3753 
3754  for (unsigned int c = 0; c < 2; ++c)
3755  if (quad->child(c)->has_children())
3756  {
3757  ++number_of_child_refinements;
3758  // if one of the cell counters is
3759  // zero, the other has to be as
3760  // well
3761  Assert(
3762  (quad_cell_count[quad->child(c)->child_index(0)] ==
3763  0 &&
3764  quad_cell_count[quad->child(c)->child_index(1)] ==
3765  0) ||
3766  (quad_cell_count[quad->child(c)->child_index(0)] >
3767  0 &&
3768  quad_cell_count[quad->child(c)->child_index(1)] >
3769  0),
3770  ExcInternalError());
3771  if (quad_cell_count[quad->child(c)->child_index(0)] ==
3772  0)
3773  {
3774  // Assert, that the two
3775  // anisotropic
3776  // refinements add up to
3777  // isotropic refinement
3778  Assert(quad->refinement_case() +
3779  quad->child(c)->refinement_case() ==
3781  ExcInternalError());
3782  // we may delete the
3783  // quad's children and
3784  // the inner line as no
3785  // cell references them
3786  // anymore
3787  quads_to_delete.push_back(
3788  quad->child(c)->child(0));
3789  quads_to_delete.push_back(
3790  quad->child(c)->child(1));
3791  if (quad->child(c)->refinement_case() ==
3793  lines_to_delete.push_back(
3794  quad->child(c)->child(0)->line(1));
3795  else
3796  lines_to_delete.push_back(
3797  quad->child(c)->child(0)->line(3));
3798  quad->child(c)->clear_children();
3799  quad->child(c)->clear_refinement_case();
3800  ++deleted_grandchildren;
3801  }
3802  }
3803  // if no grandchildren are left, we
3804  // may as well delete the
3805  // refinement of the inner line
3806  // between our children and the
3807  // corresponding vertex
3808  if (number_of_child_refinements > 0 &&
3809  deleted_grandchildren == number_of_child_refinements)
3810  {
3812  middle_line;
3813  if (quad->refinement_case() == RefinementCase<2>::cut_x)
3814  middle_line = quad->child(0)->line(1);
3815  else
3816  middle_line = quad->child(0)->line(3);
3817 
3818  lines_to_delete.push_back(middle_line->child(0));
3819  lines_to_delete.push_back(middle_line->child(1));
3820  triangulation
3821  .vertices_used[middle_vertex_index<dim, spacedim>(
3822  middle_line)] = false;
3823  middle_line->clear_children();
3824  }
3825 
3826  // now consider the direct children
3827  // of the given quad
3828  if (quad_cell_count[quad->child_index(0)] == 0)
3829  {
3830  // we may delete the quad's
3831  // children and the inner line
3832  // as no cell references them
3833  // anymore
3834  quads_to_delete.push_back(quad->child(0));
3835  quads_to_delete.push_back(quad->child(1));
3836  if (quad->refinement_case() == RefinementCase<2>::cut_x)
3837  lines_to_delete.push_back(quad->child(0)->line(1));
3838  else
3839  lines_to_delete.push_back(quad->child(0)->line(3));
3840 
3841  // if the counters just dropped
3842  // to zero, otherwise the
3843  // children would have been
3844  // deleted earlier, then this
3845  // cell's children must have
3846  // contained the anisotropic
3847  // quad children. thus, if
3848  // those have again anisotropic
3849  // children, which are in
3850  // effect isotropic children of
3851  // the original quad, those are
3852  // still needed by a
3853  // neighboring cell and we
3854  // cannot delete them. instead,
3855  // we have to reset this quad's
3856  // refine case to isotropic and
3857  // set the children
3858  // accordingly.
3859  if (quad->child(0)->has_children())
3860  if (quad->refinement_case() ==
3862  {
3863  // now evereything is
3864  // quite complicated. we
3865  // have the children
3866  // numbered according to
3867  //
3868  // *---*---*
3869  // |n+1|m+1|
3870  // *---*---*
3871  // | n | m |
3872  // *---*---*
3873  //
3874  // from the original
3875  // anisotropic
3876  // refinement. we have to
3877  // reorder them as
3878  //
3879  // *---*---*
3880  // | m |m+1|
3881  // *---*---*
3882  // | n |n+1|
3883  // *---*---*
3884  //
3885  // for isotropic refinement.
3886  //
3887  // this is a bit ugly, of
3888  // course: loop over all
3889  // cells on all levels
3890  // and look for faces n+1
3891  // (switch_1) and m
3892  // (switch_2).
3893  const typename Triangulation<dim, spacedim>::
3894  quad_iterator switch_1 =
3895  quad->child(0)->child(1),
3896  switch_2 =
3897  quad->child(1)->child(0);
3898 
3899  Assert(!switch_1->has_children(),
3900  ExcInternalError());
3901  Assert(!switch_2->has_children(),
3902  ExcInternalError());
3903 
3904  const int switch_1_index = switch_1->index();
3905  const int switch_2_index = switch_2->index();
3906  for (unsigned int l = 0;
3907  l < triangulation.levels.size();
3908  ++l)
3909  for (unsigned int h = 0;
3910  h < triangulation.levels[l]
3911  ->cells.cells.size();
3912  ++h)
3913  for (unsigned int q = 0;
3914  q < GeometryInfo<dim>::faces_per_cell;
3915  ++q)
3916  {
3917  const int index = triangulation.levels[l]
3918  ->cells.cells[h]
3919  .face(q);
3920  if (index == switch_1_index)
3921  triangulation.levels[l]
3922  ->cells.cells[h]
3923  .set_face(q, switch_2_index);
3924  else if (index == switch_2_index)
3925  triangulation.levels[l]
3926  ->cells.cells[h]
3927  .set_face(q, switch_1_index);
3928  }
3929  // now we have to copy
3930  // all information of the
3931  // two quads
3932  const int switch_1_lines[4] = {
3933  static_cast<signed int>(
3934  switch_1->line_index(0)),
3935  static_cast<signed int>(
3936  switch_1->line_index(1)),
3937  static_cast<signed int>(
3938  switch_1->line_index(2)),
3939  static_cast<signed int>(
3940  switch_1->line_index(3))};
3941  const bool switch_1_line_orientations[4] = {
3942  switch_1->line_orientation(0),
3943  switch_1->line_orientation(1),
3944  switch_1->line_orientation(2),
3945  switch_1->line_orientation(3)};
3946  const types::boundary_id switch_1_boundary_id =
3947  switch_1->boundary_id();
3948  const unsigned int switch_1_user_index =
3949  switch_1->user_index();
3950  const bool switch_1_user_flag =
3951  switch_1->user_flag_set();
3952 
3953  switch_1->set(
3955  TriaObject<2>(switch_2->line_index(0),
3956  switch_2->line_index(1),
3957  switch_2->line_index(2),
3958  switch_2->line_index(3)));
3959  switch_1->set_line_orientation(
3960  0, switch_2->line_orientation(0));
3961  switch_1->set_line_orientation(
3962  1, switch_2->line_orientation(1));
3963  switch_1->set_line_orientation(
3964  2, switch_2->line_orientation(2));
3965  switch_1->set_line_orientation(
3966  3, switch_2->line_orientation(3));
3967  switch_1->set_boundary_id_internal(
3968  switch_2->boundary_id());
3969  switch_1->set_manifold_id(
3970  switch_2->manifold_id());
3971  switch_1->set_user_index(switch_2->user_index());
3972  if (switch_2->user_flag_set())
3973  switch_1->set_user_flag();
3974  else
3975  switch_1->clear_user_flag();
3976 
3977  switch_2->set(
3979  TriaObject<2>(switch_1_lines[0],
3980  switch_1_lines[1],
3981  switch_1_lines[2],
3982  switch_1_lines[3]));
3983  switch_2->set_line_orientation(
3984  0, switch_1_line_orientations[0]);
3985  switch_2->set_line_orientation(
3986  1, switch_1_line_orientations[1]);
3987  switch_2->set_line_orientation(
3988  2, switch_1_line_orientations[2]);
3989  switch_2->set_line_orientation(
3990  3, switch_1_line_orientations[3]);
3991  switch_2->set_boundary_id_internal(
3992  switch_1_boundary_id);
3993  switch_2->set_manifold_id(
3994  switch_1->manifold_id());
3995  switch_2->set_user_index(switch_1_user_index);
3996  if (switch_1_user_flag)
3997  switch_2->set_user_flag();
3998  else
3999  switch_2->clear_user_flag();
4000 
4001  const unsigned int child_0 =
4002  quad->child(0)->child_index(0);
4003  const unsigned int child_2 =
4004  quad->child(1)->child_index(0);
4005  quad->clear_children();
4006  quad->clear_refinement_case();
4007  quad->set_refinement_case(
4009  quad->set_children(0, child_0);
4010  quad->set_children(2, child_2);
4011  std::swap(quad_cell_count[child_0 + 1],
4012  quad_cell_count[child_2]);
4013  }
4014  else
4015  {
4016  // the face was refined
4017  // with cut_y, thus the
4018  // children are already
4019  // in correct order. we
4020  // only have to set them
4021  // correctly, deleting
4022  // the indirection of two
4023  // anisotropic refinement
4024  // and going directly
4025  // from the quad to
4026  // isotropic children
4027  const unsigned int child_0 =
4028  quad->child(0)->child_index(0);
4029  const unsigned int child_2 =
4030  quad->child(1)->child_index(0);
4031  quad->clear_children();
4032  quad->clear_refinement_case();
4033  quad->set_refinement_case(
4035  quad->set_children(0, child_0);
4036  quad->set_children(2, child_2);
4037  }
4038  else
4039  {
4040  quad->clear_children();
4041  quad->clear_refinement_case();
4042  }
4043  }
4044  break;
4045  }
4046  case RefinementCase<dim - 1>::cut_xy:
4047  {
4048  // if one of the cell counters is
4049  // zero, the others have to be as
4050  // well
4051 
4052  Assert((quad_cell_count[quad->child_index(0)] == 0 &&
4053  quad_cell_count[quad->child_index(1)] == 0 &&
4054  quad_cell_count[quad->child_index(2)] == 0 &&
4055  quad_cell_count[quad->child_index(3)] == 0) ||
4056  (quad_cell_count[quad->child_index(0)] > 0 &&
4057  quad_cell_count[quad->child_index(1)] > 0 &&
4058  quad_cell_count[quad->child_index(2)] > 0 &&
4059  quad_cell_count[quad->child_index(3)] > 0),
4060  ExcInternalError());
4061 
4062  if (quad_cell_count[quad->child_index(0)] == 0)
4063  {
4064  // we may delete the quad's
4065  // children, the inner lines
4066  // and the middle vertex as no
4067  // cell references them anymore
4068  lines_to_delete.push_back(quad->child(0)->line(1));
4069  lines_to_delete.push_back(quad->child(3)->line(0));
4070  lines_to_delete.push_back(quad->child(0)->line(3));
4071  lines_to_delete.push_back(quad->child(3)->line(2));
4072 
4073  for (unsigned int child = 0; child < quad->n_children();
4074  ++child)
4075  quads_to_delete.push_back(quad->child(child));
4076 
4077  triangulation
4078  .vertices_used[quad->child(0)->vertex_index(3)] =
4079  false;
4080 
4081  quad->clear_children();
4082  quad->clear_refinement_case();
4083  }
4084  }
4085  break;
4086 
4087  default:
4088  Assert(false, ExcInternalError());
4089  break;
4090  }
4091  }
4092 
4093  // now we repeat a similar procedure
4094  // for the outer lines of this cell.
4095 
4096  // if in debug mode: check that each
4097  // of the lines for which we consider
4098  // deleting the children in fact has
4099  // children (the bits/coarsening_3d
4100  // test tripped over this initially)
4101  for (unsigned int line_no = 0;
4102  line_no < GeometryInfo<dim>::lines_per_cell;
4103  ++line_no)
4104  {
4106  cell->line(line_no);
4107 
4108  Assert(
4109  (GeometryInfo<dim>::line_refinement_case(ref_case, line_no) &&
4110  line->has_children()) ||
4111  GeometryInfo<dim>::line_refinement_case(ref_case, line_no) ==
4113  ExcInternalError());
4114 
4115  if (line->has_children())
4116  {
4117  // if one of the cell counters is
4118  // zero, the other has to be as well
4119 
4120  Assert((line_cell_count[line->child_index(0)] == 0 &&
4121  line_cell_count[line->child_index(1)] == 0) ||
4122  (line_cell_count[line->child_index(0)] > 0 &&
4123  line_cell_count[line->child_index(1)] > 0),
4124  ExcInternalError());
4125 
4126  if (line_cell_count[line->child_index(0)] == 0)
4127  {
4128  for (unsigned int c = 0; c < 2; ++c)
4129  Assert(!line->child(c)->has_children(),
4130  ExcInternalError());
4131 
4132  // we may delete the line's
4133  // children and the middle vertex
4134  // as no cell references them
4135  // anymore
4136  triangulation
4137  .vertices_used[line->child(0)->vertex_index(1)] = false;
4138 
4139  lines_to_delete.push_back(line->child(0));
4140  lines_to_delete.push_back(line->child(1));
4141 
4142  line->clear_children();
4143  }
4144  }
4145  }
4146 
4147  // finally, delete unneeded quads and lines
4148 
4149  // clear user pointers, to avoid that
4150  // they may appear at unwanted places
4151  // later on...
4152  // same for user flags, then finally
4153  // delete the quads and lines
4154  typename std::vector<
4156  line = lines_to_delete.begin(),
4157  endline = lines_to_delete.end();
4158  for (; line != endline; ++line)
4159  {
4160  (*line)->clear_user_data();
4161  (*line)->clear_user_flag();
4162  (*line)->clear_used_flag();
4163  }
4164 
4165  typename std::vector<
4167  quad = quads_to_delete.begin(),
4168  endquad = quads_to_delete.end();
4169  for (; quad != endquad; ++quad)
4170  {
4171  (*quad)->clear_user_data();
4172  (*quad)->clear_children();
4173  (*quad)->clear_refinement_case();
4174  (*quad)->clear_user_flag();
4175  (*quad)->clear_used_flag();
4176  }
4177  }
4178 
4179 
4197  template <int spacedim>
4198  static void create_children(
4199  Triangulation<2, spacedim> &triangulation,
4200  unsigned int & next_unused_vertex,
4201  typename Triangulation<2, spacedim>::raw_line_iterator
4202  &next_unused_line,
4204  & next_unused_cell,
4206  {
4207  const unsigned int dim = 2;
4208  // clear refinement flag
4209  const RefinementCase<dim> ref_case = cell->refine_flag_set();
4210  cell->clear_refine_flag();
4211 
4212  /* For the refinement process: since we go the levels up from the
4213  lowest, there are (unlike above) only two possibilities: a neighbor
4214  cell is on the same level or one level up (in both cases, it may or
4215  may not be refined later on, but we don't care here).
4216 
4217  First:
4218  Set up an array of the 3x3 vertices, which are distributed on the
4219  cell (the array consists of indices into the @p{vertices} std::vector
4220 
4221  2--7--3
4222  | | |
4223  4--8--5
4224  | | |
4225  0--6--1
4226 
4227  note: in case of cut_x or cut_y not all these vertices are needed for
4228  the new cells
4229 
4230  Second:
4231  Set up an array of the new lines (the array consists of iterator
4232  pointers into the lines arrays)
4233 
4234  .-6-.-7-. The directions are: .->-.->-.
4235  1 9 3 ^ ^ ^
4236  .-10.11-. .->-.->-.
4237  0 8 2 ^ ^ ^
4238  .-4-.-5-. .->-.->-.
4239 
4240  cut_x:
4241  .-4-.-5-.
4242  | | |
4243  0 6 1
4244  | | |
4245  .-2-.-3-.
4246 
4247  cut_y:
4248  .---5---.
4249  1 3
4250  .---6---.
4251  0 2
4252  .---4---.
4253 
4254 
4255  Third:
4256  Set up an array of neighbors:
4257 
4258  6 7
4259  .--.--.
4260  1| | |3
4261  .--.--.
4262  0| | |2
4263  .--.--.
4264  4 5
4265 
4266  We need this array for two reasons: first to get the lines which will
4267  bound the four subcells (if the neighboring cell is refined, these
4268  lines already exist), and second to update neighborship information.
4269  Since if a neighbor is not refined, its neighborship record only
4270  points to the present, unrefined, cell rather than the children we
4271  are presently creating, we only need the neighborship information
4272  if the neighbor cells are refined. In all other cases, we store
4273  the unrefined neighbor address
4274 
4275  We also need for every neighbor (if refined) which number among its
4276  neighbors the present (unrefined) cell has, since that number is to
4277  be replaced and because that also is the number of the subline which
4278  will be the interface between that neighbor and the to be created
4279  cell. We will store this number (between 0 and 3) in the field
4280  @p{neighbors_neighbor}.
4281 
4282  It would be sufficient to use the children of the common line to the
4283  neighbor, if we only wanted to get the new sublines and the new
4284  vertex, but because we need to update the neighborship information of
4285  the two refined subcells of the neighbor, we need to search these
4286  anyway.
4287 
4288  Convention:
4289  The created children are numbered like this:
4290 
4291  .--.--.
4292  |2 . 3|
4293  .--.--.
4294  |0 | 1|
4295  .--.--.
4296  */
4297  // collect the
4298  // indices of the
4299  // eight
4300  // surrounding
4301  // vertices
4302  // 2--7--3
4303  // | | |
4304  // 4--9--5
4305  // | | |
4306  // 0--6--1
4307  int new_vertices[9];
4308  for (unsigned int vertex_no = 0; vertex_no < 4; ++vertex_no)
4309  new_vertices[vertex_no] = cell->vertex_index(vertex_no);
4310  for (unsigned int line_no = 0; line_no < 4; ++line_no)
4311  if (cell->line(line_no)->has_children())
4312  new_vertices[4 + line_no] =
4313  cell->line(line_no)->child(0)->vertex_index(1);
4314 
4315  if (ref_case == RefinementCase<dim>::cut_xy)
4316  {
4317  // find the next
4318  // unused vertex and
4319  // allocate it for
4320  // the new vertex we
4321  // need here
4322  while (triangulation.vertices_used[next_unused_vertex] == true)
4323  ++next_unused_vertex;
4324  Assert(
4325  next_unused_vertex < triangulation.vertices.size(),
4326  ExcMessage(
4327  "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."));
4328  triangulation.vertices_used[next_unused_vertex] = true;
4329 
4330  new_vertices[8] = next_unused_vertex;
4331 
4332  // if this quad lives
4333  // in 2d, then we can
4334  // compute the new
4335  // central vertex
4336  // location just from
4337  // the surrounding
4338  // ones. If this is
4339  // not the case, then
4340  // we need to ask a
4341  // boundary object
4342  if (dim == spacedim)
4343  {
4344  // triangulation.vertices[next_unused_vertex] = new_point;
4345  triangulation.vertices[next_unused_vertex] = cell->center(true);
4346 
4347  // if the user_flag is set, i.e. if the cell is at the
4348  // boundary, use a different calculation of the middle vertex
4349  // here. this is of advantage if the boundary is strongly
4350  // curved (whereas the cell is not) and the cell has a high
4351  // aspect ratio.
4352  if (cell->user_flag_set())
4353  {
4354  // first reset the user_flag and then refine
4355  cell->clear_user_flag();
4356  triangulation.vertices[next_unused_vertex] =
4357  cell->center(true, true);
4358  }
4359  }
4360  else
4361  {
4362  // if this quad lives in a higher dimensional space
4363  // then we don't need to worry if it is at the
4364  // boundary of the manifold -- we always have to use
4365  // the boundary object anyway; so ignore whether the
4366  // user flag is set or not
4367  cell->clear_user_flag();
4368 
4369  // new vertex is placed on the surface according to
4370  // the information stored in the boundary class
4371  triangulation.vertices[next_unused_vertex] = cell->center(true);
4372  }
4373  }
4374 
4375 
4376  // Now the lines:
4377  typename Triangulation<dim, spacedim>::raw_line_iterator new_lines[12];
4378  unsigned int lmin = 8;
4379  unsigned int lmax = 12;
4380  if (ref_case != RefinementCase<dim>::cut_xy)
4381  {
4382  lmin = 6;
4383  lmax = 7;
4384  }
4385 
4386  for (unsigned int l = lmin; l < lmax; ++l)
4387  {
4388  while (next_unused_line->used() == true)
4389  ++next_unused_line;
4390  new_lines[l] = next_unused_line;
4391  ++next_unused_line;
4392 
4393  Assert(
4394  new_lines[l]->used() == false,
4395  ExcMessage(
4396  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4397  }
4398 
4399  if (ref_case == RefinementCase<dim>::cut_xy)
4400  {
4401  // .-6-.-7-.
4402  // 1 9 3
4403  // .-10.11-.
4404  // 0 8 2
4405  // .-4-.-5-.
4406 
4407  // lines 0-7 already exist, create only the four interior
4408  // lines 8-11
4409  unsigned int l = 0;
4410  for (unsigned int face_no = 0;
4411  face_no < GeometryInfo<dim>::faces_per_cell;
4412  ++face_no)
4413  for (unsigned int c = 0; c < 2; ++c, ++l)
4414  new_lines[l] = cell->line(face_no)->child(c);
4415  Assert(l == 8, ExcInternalError());
4416 
4417  new_lines[8]->set(
4419  new_vertices[6], new_vertices[8]));
4420  new_lines[9]->set(
4422  new_vertices[8], new_vertices[7]));
4423  new_lines[10]->set(
4425  new_vertices[4], new_vertices[8]));
4426  new_lines[11]->set(
4428  new_vertices[8], new_vertices[5]));
4429  }
4430  else if (ref_case == RefinementCase<dim>::cut_x)
4431  {
4432  // .-4-.-5-.
4433  // | | |
4434  // 0 6 1
4435  // | | |
4436  // .-2-.-3-.
4437  new_lines[0] = cell->line(0);
4438  new_lines[1] = cell->line(1);
4439  new_lines[2] = cell->line(2)->child(0);
4440  new_lines[3] = cell->line(2)->child(1);
4441  new_lines[4] = cell->line(3)->child(0);
4442  new_lines[5] = cell->line(3)->child(1);
4443  new_lines[6]->set(
4445  new_vertices[6], new_vertices[7]));
4446  }
4447  else
4448  {
4450  // .---5---.
4451  // 1 3
4452  // .---6---.
4453  // 0 2
4454  // .---4---.
4455  new_lines[0] = cell->line(0)->child(0);
4456  new_lines[1] = cell->line(0)->child(1);
4457  new_lines[2] = cell->line(1)->child(0);
4458  new_lines[3] = cell->line(1)->child(1);
4459  new_lines[4] = cell->line(2);
4460  new_lines[5] = cell->line(3);
4461  new_lines[6]->set(
4463  new_vertices[4], new_vertices[5]));
4464  }
4465 
4466  for (unsigned int l = lmin; l < lmax; ++l)
4467  {
4468  new_lines[l]->set_used_flag();
4469  new_lines[l]->clear_user_flag();
4470  new_lines[l]->clear_user_data();
4471  new_lines[l]->clear_children();
4472  // interior line
4473  new_lines[l]->set_boundary_id_internal(
4475  new_lines[l]->set_manifold_id(cell->manifold_id());
4476  }
4477 
4478  // Now add the four (two)
4479  // new cells!
4482  while (next_unused_cell->used() == true)
4483  ++next_unused_cell;
4484 
4485  const unsigned int n_children = GeometryInfo<dim>::n_children(ref_case);
4486  for (unsigned int i = 0; i < n_children; ++i)
4487  {
4488  Assert(
4489  next_unused_cell->used() == false,
4490  ExcMessage(
4491  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4492  subcells[i] = next_unused_cell;
4493  ++next_unused_cell;
4494  if (i % 2 == 1 && i < n_children - 1)
4495  while (next_unused_cell->used() == true)
4496  ++next_unused_cell;
4497  }
4498 
4499  if (ref_case == RefinementCase<dim>::cut_xy)
4500  {
4501  // children:
4502  // .--.--.
4503  // |2 . 3|
4504  // .--.--.
4505  // |0 | 1|
4506  // .--.--.
4507  // lines:
4508  // .-6-.-7-.
4509  // 1 9 3
4510  // .-10.11-.
4511  // 0 8 2
4512  // .-4-.-5-.
4513  subcells[0]->set(
4515  new_lines[0]->index(),
4516  new_lines[8]->index(),
4517  new_lines[4]->index(),
4518  new_lines[10]->index()));
4519  subcells[1]->set(
4521  new_lines[8]->index(),
4522  new_lines[2]->index(),
4523  new_lines[5]->index(),
4524  new_lines[11]->index()));
4525  subcells[2]->set(
4527  new_lines[1]->index(),
4528  new_lines[9]->index(),
4529  new_lines[10]->index(),
4530  new_lines[6]->index()));
4531  subcells[3]->set(
4533  new_lines[9]->index(),
4534  new_lines[3]->index(),
4535  new_lines[11]->index(),
4536  new_lines[7]->index()));
4537  }
4538  else if (ref_case == RefinementCase<dim>::cut_x)
4539  {
4540  // children:
4541  // .--.--.
4542  // | . |
4543  // .0 . 1.
4544  // | | |
4545  // .--.--.
4546  // lines:
4547  // .-4-.-5-.
4548  // | | |
4549  // 0 6 1
4550  // | | |
4551  // .-2-.-3-.
4552  subcells[0]->set(
4554  new_lines[0]->index(),
4555  new_lines[6]->index(),
4556  new_lines[2]->index(),
4557  new_lines[4]->index()));
4558  subcells[1]->set(
4560  new_lines[6]->index(),
4561  new_lines[1]->index(),
4562  new_lines[3]->index(),
4563  new_lines[5]->index()));
4564  }
4565  else
4566  {
4568  // children:
4569  // .-----.
4570  // | 1 |
4571  // .-----.
4572  // | 0 |
4573  // .-----.
4574  // lines:
4575  // .---5---.
4576  // 1 3
4577  // .---6---.
4578  // 0 2
4579  // .---4---.
4580  subcells[0]->set(
4582  new_lines[0]->index(),
4583  new_lines[2]->index(),
4584  new_lines[4]->index(),
4585  new_lines[6]->index()));
4586  subcells[1]->set(
4588  new_lines[1]->index(),
4589  new_lines[3]->index(),
4590  new_lines[6]->index(),
4591  new_lines[5]->index()));
4592  }
4593 
4594  types::subdomain_id subdomainid = cell->subdomain_id();
4595 
4596  for (unsigned int i = 0; i < n_children; ++i)
4597  {
4598  subcells[i]->set_used_flag();
4599  subcells[i]->clear_refine_flag();
4600  subcells[i]->clear_user_flag();
4601  subcells[i]->clear_user_data();
4602  subcells[i]->clear_children();
4603  // inherit material
4604  // properties
4605  subcells[i]->set_material_id(cell->material_id());
4606  subcells[i]->set_manifold_id(cell->manifold_id());
4607  subcells[i]->set_subdomain_id(subdomainid);
4608 
4609  if (i % 2 == 0)
4610  subcells[i]->set_parent(cell->index());
4611  }
4612 
4613 
4614 
4615  // set child index for
4616  // even children children
4617  // i=0,2 (0)
4618  for (unsigned int i = 0; i < n_children / 2; ++i)
4619  cell->set_children(2 * i, subcells[2 * i]->index());
4620  // set the refine case
4621  cell->set_refinement_case(ref_case);
4622 
4623  // note that the
4624  // refinement flag was
4625  // already cleared at the
4626  // beginning of this function
4627 
4628  if (dim < spacedim)
4629  for (unsigned int c = 0; c < n_children; ++c)
4630  cell->child(c)->set_direction_flag(cell->direction_flag());
4631  }
4632 
4633 
4634 
4639  template <int spacedim>
4642  const bool /*check_for_distorted_cells*/)
4643  {
4644  const unsigned int dim = 1;
4645 
4646  // check whether a new level is needed we have to check for
4647  // this on the highest level only (on this, all used cells are
4648  // also active, so we only have to check for this)
4649  {
4651  cell = triangulation.begin_active(triangulation.levels.size() - 1),
4652  endc = triangulation.end();
4653  for (; cell != endc; ++cell)
4654  if (cell->used())
4655  if (cell->refine_flag_set())
4656  {
4657  triangulation.levels.push_back(
4658  std_cxx14::make_unique<
4660  break;
4661  }
4662  }
4663 
4664 
4665  // check how much space is needed on every level we need not
4666  // check the highest level since either - on the highest level
4667  // no cells are flagged for refinement - there are, but
4668  // prepare_refinement added another empty level
4669  unsigned int needed_vertices = 0;
4670  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4671  {
4672  // count number of flagged
4673  // cells on this level
4674  unsigned int flagged_cells = 0;
4676  acell = triangulation.begin_active(level),
4677  aendc = triangulation.begin_active(level + 1);
4678  for (; acell != aendc; ++acell)
4679  if (acell->refine_flag_set())
4680  ++flagged_cells;
4681 
4682  // count number of used cells
4683  // on the next higher level
4684  const unsigned int used_cells = std::count_if(
4685  triangulation.levels[level + 1]->cells.used.begin(),
4686  triangulation.levels[level + 1]->cells.used.end(),
4687  std::bind(std::equal_to<bool>(), std::placeholders::_1, true));
4688 
4689  // reserve space for the used_cells cells already existing
4690  // on the next higher level as well as for the
4691  // 2*flagged_cells that will be created on that level
4692  triangulation.levels[level + 1]->reserve_space(
4693  used_cells +
4695  1,
4696  spacedim);
4697  // reserve space for 2*flagged_cells new lines on the next
4698  // higher level
4699  triangulation.levels[level + 1]->cells.reserve_space(
4700  GeometryInfo<1>::max_children_per_cell * flagged_cells, 0);
4701 
4702  needed_vertices += flagged_cells;
4703  }
4704 
4705  // add to needed vertices how many
4706  // vertices are already in use
4707  needed_vertices += std::count_if(triangulation.vertices_used.begin(),
4708  triangulation.vertices_used.end(),
4709  std::bind(std::equal_to<bool>(),
4710  std::placeholders::_1,
4711  true));
4712  // if we need more vertices: create them, if not: leave the
4713  // array as is, since shrinking is not really possible because
4714  // some of the vertices at the end may be in use
4715  if (needed_vertices > triangulation.vertices.size())
4716  {
4717  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
4718  triangulation.vertices_used.resize(needed_vertices, false);
4719  }
4720 
4721 
4722  // Do REFINEMENT on every level; exclude highest level as
4723  // above
4724 
4725  // index of next unused vertex
4726  unsigned int next_unused_vertex = 0;
4727 
4728  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4729  {
4731  cell = triangulation.begin_active(level),
4732  endc = triangulation.begin_active(level + 1);
4733 
4735  next_unused_cell = triangulation.begin_raw(level + 1);
4736 
4737  for (; (cell != endc) && (cell->level() == level); ++cell)
4738  if (cell->refine_flag_set())
4739  {
4740  // clear refinement flag
4741  cell->clear_refine_flag();
4742 
4743  // search for next unused
4744  // vertex
4745  while (triangulation.vertices_used[next_unused_vertex] ==
4746  true)
4747  ++next_unused_vertex;
4748  Assert(
4749  next_unused_vertex < triangulation.vertices.size(),
4750  ExcMessage(
4751  "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."));
4752 
4753  // Now we always ask the cell itself where to put
4754  // the new point. The cell in turn will query the
4755  // manifold object internally.
4756  triangulation.vertices[next_unused_vertex] =
4757  cell->center(true);
4758 
4759  triangulation.vertices_used[next_unused_vertex] = true;
4760 
4761  // search for next two unused cell (++ takes care of
4762  // the end of the vector)
4764  first_child,
4765  second_child;
4766  while (next_unused_cell->used() == true)
4767  ++next_unused_cell;
4768  first_child = next_unused_cell;
4769  first_child->set_used_flag();
4770  first_child->clear_user_data();
4771  ++next_unused_cell;
4772  Assert(
4773  next_unused_cell->used() == false,
4774  ExcMessage(
4775  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4776  second_child = next_unused_cell;
4777  second_child->set_used_flag();
4778  second_child->clear_user_data();
4779 
4780  types::subdomain_id subdomainid = cell->subdomain_id();
4781 
4782  // insert first child
4783  cell->set_children(0, first_child->index());
4784  first_child->clear_children();
4785  first_child->set(
4786  internal::TriangulationImplementation ::TriaObject<1>(
4787  cell->vertex_index(0), next_unused_vertex));
4788  first_child->set_material_id(cell->material_id());
4789  first_child->set_manifold_id(cell->manifold_id());
4790  first_child->set_subdomain_id(subdomainid);
4791  first_child->set_direction_flag(cell->direction_flag());
4792 
4793  first_child->set_parent(cell->index());
4794 
4795  // Set manifold id of the right face. Only do this
4796  // on the first child.
4797  first_child->face(1)->set_manifold_id(cell->manifold_id());
4798 
4799  // reset neighborship info (refer to
4800  // internal::TriangulationImplementation::TriaLevel<0> for
4801  // details)
4802  first_child->set_neighbor(1, second_child);
4803  if (cell->neighbor(0).state() != IteratorState::valid)
4804  first_child->set_neighbor(0, cell->neighbor(0));
4805  else if (cell->neighbor(0)->active())
4806  {
4807  // since the neighbors level is always <=level,
4808  // if the cell is active, then there are no
4809  // cells to the left which may want to know
4810  // about this new child cell.
4811  Assert(cell->neighbor(0)->level() <= cell->level(),
4812  ExcInternalError());
4813  first_child->set_neighbor(0, cell->neighbor(0));
4814  }
4815  else
4816  // left neighbor is refined
4817  {
4818  // set neighbor to cell on same level
4819  const unsigned int nbnb = cell->neighbor_of_neighbor(0);
4820  first_child->set_neighbor(0,
4821  cell->neighbor(0)->child(nbnb));
4822 
4823  // reset neighbor info of all right descendant
4824  // of the left neighbor of cell
4826  left_neighbor = cell->neighbor(0);
4827  while (left_neighbor->has_children())
4828  {
4829  left_neighbor = left_neighbor->child(nbnb);
4830  left_neighbor->set_neighbor(nbnb, first_child);
4831  }
4832  }
4833 
4834  // insert second child
4835  second_child->clear_children();
4836  second_child->set(
4837  internal::TriangulationImplementation ::TriaObject<1>(
4838  next_unused_vertex, cell->vertex_index(1)));
4839  second_child->set_neighbor(0, first_child);
4840  second_child->set_material_id(cell->material_id());
4841  second_child->set_manifold_id(cell->manifold_id());
4842  second_child->set_subdomain_id(subdomainid);
4843  second_child->set_direction_flag(cell->direction_flag());
4844 
4845  if (cell->neighbor(1).state() != IteratorState::valid)
4846  second_child->set_neighbor(1, cell->neighbor(1));
4847  else if (cell->neighbor(1)->active())
4848  {
4849  Assert(cell->neighbor(1)->level() <= cell->level(),
4850  ExcInternalError());
4851  second_child->set_neighbor(1, cell->neighbor(1));
4852  }
4853  else
4854  // right neighbor is refined same as above
4855  {
4856  const unsigned int nbnb = cell->neighbor_of_neighbor(1);
4857  second_child->set_neighbor(
4858  1, cell->neighbor(1)->child(nbnb));
4859 
4861  right_neighbor = cell->neighbor(1);
4862  while (right_neighbor->has_children())
4863  {
4864  right_neighbor = right_neighbor->child(nbnb);
4865  right_neighbor->set_neighbor(nbnb, second_child);
4866  }
4867  }
4868  // inform all listeners that cell refinement is done
4869  triangulation.signals.post_refinement_on_cell(cell);
4870  }
4871  }
4872 
4873  // in 1d, we can not have distorted children unless the parent
4874  // was already distorted (that is because we don't use
4875  // boundary information for 1d triangulations). so return an
4876  // empty list
4878  }
4879 
4880 
4885  template <int spacedim>
4888  const bool check_for_distorted_cells)
4889  {
4890  const unsigned int dim = 2;
4891 
4892  // check whether a new level is needed we have to check for
4893  // this on the highest level only (on this, all used cells are
4894  // also active, so we only have to check for this)
4895  {
4897  cell = triangulation.begin_active(triangulation.levels.size() - 1),
4898  endc = triangulation.end();
4899  for (; cell != endc; ++cell)
4900  if (cell->used())
4901  if (cell->refine_flag_set())
4902  {
4903  triangulation.levels.push_back(
4904  std_cxx14::make_unique<
4906  break;
4907  }
4908  }
4909 
4910  // TODO[WB]: we clear user flags and pointers of lines; we're going
4911  // to use them to flag which lines need refinement
4912  for (typename Triangulation<dim, spacedim>::line_iterator line =
4913  triangulation.begin_line();
4914  line != triangulation.end_line();
4915  ++line)
4916  {
4917  line->clear_user_flag();
4918  line->clear_user_data();
4919  }
4920  // running over all cells and lines count the number
4921  // n_single_lines of lines which can be stored as single
4922  // lines, e.g. inner lines
4923  unsigned int n_single_lines = 0;
4924 
4925  // New lines to be created: number lines which are stored in
4926  // pairs (the children of lines must be stored in pairs)
4927  unsigned int n_lines_in_pairs = 0;
4928 
4929  // check how much space is needed on every level we need not
4930  // check the highest level since either - on the highest level
4931  // no cells are flagged for refinement - there are, but
4932  // prepare_refinement added another empty level
4933  unsigned int needed_vertices = 0;
4934  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4935  {
4936  // count number of flagged cells on this level and compute
4937  // how many new vertices and new lines will be needed
4938  unsigned int needed_cells = 0;
4939 
4941  cell = triangulation.begin_active(level),
4942  endc = triangulation.begin_active(level + 1);
4943  for (; cell != endc; ++cell)
4944  if (cell->refine_flag_set())
4945  {
4946  if (cell->refine_flag_set() == RefinementCase<dim>::cut_xy)
4947  {
4948  needed_cells += 4;
4949 
4950  // new vertex at center of cell is needed in any
4951  // case
4952  ++needed_vertices;
4953 
4954  // the four inner lines can be stored as singles
4955  n_single_lines += 4;
4956  }
4957  else // cut_x || cut_y
4958  {
4959  // set the flag showing that anisotropic
4960  // refinement is used for at least one cell
4961  triangulation.anisotropic_refinement = true;
4962 
4963  needed_cells += 2;
4964  // no vertex at center
4965 
4966  // the inner line can be stored as single
4967  n_single_lines += 1;
4968  }
4969 
4970  // mark all faces (lines) for refinement; checking
4971  // locally whether the neighbor would also like to
4972  // refine them is rather difficult for lines so we
4973  // only flag them and after visiting all cells, we
4974  // decide which lines need refinement;
4975  for (unsigned int line_no = 0;
4976  line_no < GeometryInfo<dim>::faces_per_cell;
4977  ++line_no)
4978  {
4980  cell->refine_flag_set(), line_no) ==
4982  {
4984  line = cell->line(line_no);
4985  if (line->has_children() == false)
4986  line->set_user_flag();
4987  }
4988  }
4989  }
4990 
4991 
4992  // count number of used cells on the next higher level
4993  const unsigned int used_cells = std::count_if(
4994  triangulation.levels[level + 1]->cells.used.begin(),
4995  triangulation.levels[level + 1]->cells.used.end(),
4996  std::bind(std::equal_to<bool>(), std::placeholders::_1, true));
4997 
4998 
4999  // reserve space for the used_cells cells already existing
5000  // on the next higher level as well as for the
5001  // needed_cells that will be created on that level
5002  triangulation.levels[level + 1]->reserve_space(
5003  used_cells + needed_cells, 2, spacedim);
5004 
5005  // reserve space for needed_cells new quads on the next
5006  // higher level
5007  triangulation.levels[level + 1]->cells.reserve_space(needed_cells,
5008  0);
5009  }
5010 
5011  // now count the lines which were flagged for refinement
5012  for (typename Triangulation<dim, spacedim>::line_iterator line =
5013  triangulation.begin_line();
5014  line != triangulation.end_line();
5015  ++line)
5016  if (line->user_flag_set())
5017  {
5018  Assert(line->has_children() == false, ExcInternalError());
5019  n_lines_in_pairs += 2;
5020  needed_vertices += 1;
5021  }
5022  // reserve space for n_lines_in_pairs new lines. note, that
5023  // we can't reserve space for the single lines here as well,
5024  // as all the space reserved for lines in pairs would be
5025  // counted as unused and we would end up with too little space
5026  // to store all lines. memory reservation for n_single_lines
5027  // can only be done AFTER we refined the lines of the current
5028  // cells
5029  triangulation.faces->lines.reserve_space(n_lines_in_pairs, 0);
5030 
5031  // add to needed vertices how many vertices are already in use
5032  needed_vertices += std::count_if(triangulation.vertices_used.begin(),
5033  triangulation.vertices_used.end(),
5034  std::bind(std::equal_to<bool>(),
5035  std::placeholders::_1,
5036  true));
5037  // if we need more vertices: create them, if not: leave the
5038  // array as is, since shrinking is not really possible because
5039  // some of the vertices at the end may be in use
5040  if (needed_vertices > triangulation.vertices.size())
5041  {
5042  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
5043  triangulation.vertices_used.resize(needed_vertices, false);
5044  }
5045 
5046 
5047  // Do REFINEMENT on every level; exclude highest level as
5048  // above
5049 
5050  // index of next unused vertex
5051  unsigned int next_unused_vertex = 0;
5052 
5053  // first the refinement of lines. children are stored
5054  // pairwise
5055  {
5056  // only active objects can be refined further
5058  line = triangulation.begin_active_line(),
5059  endl = triangulation.end_line();
5060  typename Triangulation<dim, spacedim>::raw_line_iterator
5061  next_unused_line = triangulation.begin_raw_line();
5062 
5063  for (; line != endl; ++line)
5064  if (line->user_flag_set())
5065  {
5066  // this line needs to be refined
5067 
5068  // find the next unused vertex and set it
5069  // appropriately
5070  while (triangulation.vertices_used[next_unused_vertex] == true)
5071  ++next_unused_vertex;
5072  Assert(
5073  next_unused_vertex < triangulation.vertices.size(),
5074  ExcMessage(
5075  "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."));
5076  triangulation.vertices_used[next_unused_vertex] = true;
5077 
5078  triangulation.vertices[next_unused_vertex] = line->center(true);
5079 
5080  // now that we created the right point, make up the
5081  // two child lines. To this end, find a pair of
5082  // unused lines
5083  bool pair_found = false;
5084  (void)pair_found;
5085  for (; next_unused_line != endl; ++next_unused_line)
5086  if (!next_unused_line->used() &&
5087  !(++next_unused_line)->used())
5088  {
5089  // go back to the first of the two unused
5090  // lines
5091  --next_unused_line;
5092  pair_found = true;
5093  break;
5094  }
5095  Assert(pair_found, ExcInternalError());
5096 
5097  // there are now two consecutive unused lines, such
5098  // that the children of a line will be consecutive.
5099  // then set the child pointer of the present line
5100  line->set_children(0, next_unused_line->index());
5101 
5102  // set the two new lines
5103  const typename Triangulation<dim, spacedim>::raw_line_iterator
5104  children[2] = {next_unused_line, ++next_unused_line};
5105  // some tests; if any of the iterators should be
5106  // invalid, then already dereferencing will fail
5107  Assert(
5108  children[0]->used() == false,
5109  ExcMessage(
5110  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5111  Assert(
5112  children[1]->used() == false,
5113  ExcMessage(
5114  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5115 
5116  children[0]->set(
5117  internal::TriangulationImplementation ::TriaObject<1>(
5118  line->vertex_index(0), next_unused_vertex));
5119  children[1]->set(
5120  internal::TriangulationImplementation ::TriaObject<1>(
5121  next_unused_vertex, line->vertex_index(1)));
5122 
5123  children[0]->set_used_flag();
5124  children[1]->set_used_flag();
5125  children[0]->clear_children();
5126  children[1]->clear_children();
5127  children[0]->clear_user_data();
5128  children[1]->clear_user_data();
5129  children[0]->clear_user_flag();
5130  children[1]->clear_user_flag();
5131 
5132 
5133  children[0]->set_boundary_id_internal(line->boundary_id());
5134  children[1]->set_boundary_id_internal(line->boundary_id());
5135 
5136  children[0]->set_manifold_id(line->manifold_id());
5137  children[1]->set_manifold_id(line->manifold_id());
5138 
5139  // finally clear flag indicating the need for
5140  // refinement
5141  line->clear_user_flag();
5142  }
5143  }
5144 
5145 
5146  // Now set up the new cells
5147 
5148  // reserve space for inner lines (can be stored as single
5149  // lines)
5150  triangulation.faces->lines.reserve_space(0, n_single_lines);
5151 
5153  cells_with_distorted_children;
5154 
5155  // reset next_unused_line, as now also single empty places in
5156  // the vector can be used
5157  typename Triangulation<dim, spacedim>::raw_line_iterator
5158  next_unused_line = triangulation.begin_raw_line();
5159 
5160  for (int level = 0;
5161  level < static_cast<int>(triangulation.levels.size()) - 1;
5162  ++level)
5163  {
5164  // Remember: as we don't operate on the finest level,
5165  // begin_*(level+1) is allowed
5167  cell = triangulation.begin_active(level),
5168  endc = triangulation.begin_active(level + 1);
5169 
5171  next_unused_cell = triangulation.begin_raw(level + 1);
5172 
5173  for (; cell != endc; ++cell)
5174  if (cell->refine_flag_set())
5175  {
5176  // set the user flag to indicate, that at least one
5177  // line is at the boundary
5178 
5179  // TODO[Tobias Leicht] find a better place to set
5180  // this flag, so that we do not need so much time to
5181  // check each cell here
5182  if (cell->at_boundary())
5183  cell->set_user_flag();
5184 
5185  // actually set up the children and update neighbor
5186  // information
5187  create_children(triangulation,
5188  next_unused_vertex,
5189  next_unused_line,
5190  next_unused_cell,
5191  cell);
5192 
5193  if ((check_for_distorted_cells == true) &&
5194  has_distorted_children(
5195  cell,
5196  std::integral_constant<int, dim>(),
5197  std::integral_constant<int, spacedim>()))
5198  cells_with_distorted_children.distorted_cells.push_back(
5199  cell);
5200  // inform all listeners that cell refinement is done
5201  triangulation.signals.post_refinement_on_cell(cell);
5202  }
5203  }
5204 
5205  return cells_with_distorted_children;
5206  }
5207 
5208 
5213  template <int spacedim>
5216  const bool check_for_distorted_cells)
5217  {
5218  const unsigned int dim = 3;
5219 
5220  // this function probably also works for spacedim>3 but it
5221  // isn't tested. it will probably be necessary to pull new
5222  // vertices onto the manifold just as we do for the other
5223  // functions above.
5224  Assert(spacedim == 3, ExcNotImplemented());
5225 
5226  // check whether a new level is needed we have to check for
5227  // this on the highest level only (on this, all used cells are
5228  // also active, so we only have to check for this)
5229  {
5231  cell = triangulation.begin_active(triangulation.levels.size() - 1),
5232  endc = triangulation.end();
5233  for (; cell != endc; ++cell)
5234  if (cell->used())
5235  if (cell->refine_flag_set())
5236  {
5237  triangulation.levels.push_back(
5238  std_cxx14::make_unique<
5240  break;
5241  }
5242  }
5243 
5244 
5245  // first clear user flags for quads and lines; we're going to
5246  // use them to flag which lines and quads need refinement
5247  triangulation.faces->quads.clear_user_data();
5248 
5249  for (typename Triangulation<dim, spacedim>::line_iterator line =
5250  triangulation.begin_line();
5251  line != triangulation.end_line();
5252  ++line)
5253  line->clear_user_flag();
5254  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
5255  triangulation.begin_quad();
5256  quad != triangulation.end_quad();
5257  ++quad)
5258  quad->clear_user_flag();
5259 
5260  // create an array of face refine cases. User indices of faces
5261  // will be set to values corresponding with indices in this
5262  // array.
5263  const RefinementCase<dim - 1> face_refinement_cases[4] = {
5264  RefinementCase<dim - 1>::no_refinement,
5265  RefinementCase<dim - 1>::cut_x,
5266  RefinementCase<dim - 1>::cut_y,
5267  RefinementCase<dim - 1>::cut_xy};
5268 
5269  // check how much space is needed on every level we need not
5270  // check the highest level since either
5271  // - on the highest level no cells are flagged for refinement
5272  // - there are, but prepare_refinement added another empty
5273  // level which then is the highest level
5274 
5275  // variables to hold the number of newly to be created
5276  // vertices, lines and quads. as these are stored globally,
5277  // declare them outside the loop over al levels. we need lines
5278  // and quads in pairs for refinement of old ones and lines and
5279  // quads, that can be stored as single ones, as they are newly
5280  // created in the inside of an existing cell
5281  unsigned int needed_vertices = 0;
5282  unsigned int needed_lines_single = 0;
5283  unsigned int needed_quads_single = 0;
5284  unsigned int needed_lines_pair = 0;
5285  unsigned int needed_quads_pair = 0;
5286  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
5287  {
5288  // count number of flagged cells on this level and compute
5289  // how many new vertices and new lines will be needed
5290  unsigned int new_cells = 0;
5291 
5293  acell = triangulation.begin_active(level),
5294  aendc = triangulation.begin_active(level + 1);
5295  for (; acell != aendc; ++acell)
5296  if (acell->refine_flag_set())
5297  {
5298  RefinementCase<dim> ref_case = acell->refine_flag_set();
5299 
5300  // now for interior vertices, lines and quads, which
5301  // are needed in any case
5302  if (ref_case == RefinementCase<dim>::cut_x ||
5303  ref_case == RefinementCase<dim>::cut_y ||
5304  ref_case == RefinementCase<dim>::cut_z)
5305  {
5306  ++needed_quads_single;
5307  new_cells += 2;
5308  triangulation.anisotropic_refinement = true;
5309  }
5310  else if (ref_case == RefinementCase<dim>::cut_xy ||
5311  ref_case == RefinementCase<dim>::cut_xz ||
5312  ref_case == RefinementCase<dim>::cut_yz)
5313  {
5314  ++needed_lines_single;
5315  needed_quads_single += 4;
5316  new_cells += 4;
5317  triangulation.anisotropic_refinement = true;
5318  }
5319  else if (ref_case == RefinementCase<dim>::cut_xyz)
5320  {
5321  ++needed_vertices;
5322  needed_lines_single += 6;
5323  needed_quads_single += 12;
5324  new_cells += 8;
5325  }
5326  else
5327  {
5328  // we should never get here
5329  Assert(false, ExcInternalError());
5330  }
5331 
5332  // mark all faces for refinement; checking locally
5333  // if and how the neighbor would like to refine
5334  // these is difficult so we only flag them and after
5335  // visiting all cells, we decide which faces need
5336  // which refinement;
5337  for (unsigned int face = 0;
5338  face < GeometryInfo<dim>::faces_per_cell;
5339  ++face)
5340  {
5342  aface = acell->face(face);
5343  // get the RefineCase this faces has for the
5344  // given RefineCase of the cell
5345  RefinementCase<dim - 1> face_ref_case =
5347  ref_case,
5348  face,
5349  acell->face_orientation(face),
5350  acell->face_flip(face),
5351  acell->face_rotation(face));
5352  // only do something, if this face has to be
5353  // refined
5354  if (face_ref_case)
5355  {
5356  if (face_ref_case ==
5358  {
5359  if (aface->number_of_children() < 4)
5360  // we use user_flags to denote needed
5361  // isotropic refinement
5362  aface->set_user_flag();
5363  }
5364  else if (aface->refinement_case() != face_ref_case)
5365  // we use user_indices to denote needed
5366  // anisotropic refinement. note, that we
5367  // can have at most one anisotropic
5368  // refinement case for this face, as
5369  // otherwise prepare_refinement() would
5370  // have changed one of the cells to yield
5371  // isotropic refinement at this
5372  // face. therefore we set the user_index
5373  // uniquely
5374  {
5375  Assert(aface->refinement_case() ==
5377  dim - 1>::isotropic_refinement ||
5378  aface->refinement_case() ==
5379  RefinementCase<dim - 1>::no_refinement,
5380  ExcInternalError());
5381  aface->set_user_index(face_ref_case);
5382  }
5383  }
5384  } // for all faces
5385 
5386  // flag all lines, that have to be refined
5387  for (unsigned int line = 0;
5388  line < GeometryInfo<dim>::lines_per_cell;
5389  ++line)
5391  line) &&
5392  !acell->line(line)->has_children())
5393  acell->line(line)->set_user_flag();
5394 
5395  } // if refine_flag set and for all cells on this level
5396 
5397 
5398  // count number of used cells on the next higher level
5399  const unsigned int used_cells = std::count_if(
5400  triangulation.levels[level + 1]->cells.used.begin(),
5401  triangulation.levels[level + 1]->cells.used.end(),
5402  std::bind(std::equal_to<bool>(), std::placeholders::_1, true));
5403 
5404 
5405  // reserve space for the used_cells cells already existing
5406  // on the next higher level as well as for the
5407  // 8*flagged_cells that will be created on that level
5408  triangulation.levels[level + 1]->reserve_space(
5409  used_cells + new_cells, 3, spacedim);
5410  // reserve space for 8*flagged_cells new hexes on the next
5411  // higher level
5412  triangulation.levels[level + 1]->cells.reserve_space(new_cells);
5413  } // for all levels
5414  // now count the quads and lines which were flagged for
5415  // refinement
5416  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
5417  triangulation.begin_quad();
5418  quad != triangulation.end_quad();
5419  ++quad)
5420  {
5421  if (quad->user_flag_set())
5422  {
5423  // isotropic refinement: 1 interior vertex, 4 quads
5424  // and 4 interior lines. we store the interior lines
5425  // in pairs in case the face is already or will be
5426  // refined anisotropically
5427  needed_quads_pair += 4;
5428  needed_lines_pair += 4;
5429  needed_vertices += 1;
5430  }
5431  if (quad->user_index())
5432  {
5433  // anisotropic refinement: 1 interior
5434  // line and two quads
5435  needed_quads_pair += 2;
5436  needed_lines_single += 1;
5437  // there is a kind of complicated situation here which
5438  // requires our attention. if the quad is refined
5439  // isotropcally, two of the interior lines will get a
5440  // new mother line - the interior line of our
5441  // anisotropically refined quad. if those two lines
5442  // are not consecutive, we cannot do so and have to
5443  // replace them by two lines that are consecutive. we
5444  // try to avoid that situation, but it may happen
5445  // nevertheless through repeated refinement and
5446  // coarsening. thus we have to check here, as we will
5447  // need some additional space to store those new lines
5448  // in case we need them...
5449  if (quad->has_children())
5450  {
5451  Assert(quad->refinement_case() ==
5452  RefinementCase<dim - 1>::isotropic_refinement,
5453  ExcInternalError());
5454  if ((face_refinement_cases[quad->user_index()] ==
5455  RefinementCase<dim - 1>::cut_x &&
5456  (quad->child(0)->line_index(1) + 1 !=
5457  quad->child(2)->line_index(1))) ||
5458  (face_refinement_cases[quad->user_index()] ==
5459  RefinementCase<dim - 1>::cut_y &&
5460  (quad->child(0)->line_index(3) + 1 !=
5461  quad->child(1)->line_index(3))))
5462  needed_lines_pair += 2;
5463  }
5464  }
5465  }
5466 
5467  for (typename Triangulation<dim, spacedim>::line_iterator line =
5468  triangulation.begin_line();
5469  line != triangulation.end_line();
5470  ++line)
5471  if (line->user_flag_set())
5472  {
5473  needed_lines_pair += 2;
5474  needed_vertices += 1;
5475  }
5476 
5477  // reserve space for needed_lines new lines stored in pairs
5478  triangulation.faces->lines.reserve_space(needed_lines_pair,
5479  needed_lines_single);
5480  // reserve space for needed_quads new quads stored in pairs
5481  triangulation.faces->quads.reserve_space(needed_quads_pair,
5482  needed_quads_single);
5483 
5484 
5485  // add to needed vertices how many vertices are already in use
5486  needed_vertices += std::count_if(triangulation.vertices_used.begin(),
5487  triangulation.vertices_used.end(),
5488  std::bind(std::equal_to<bool>(),
5489  std::placeholders::_1,
5490  true));
5491  // if we need more vertices: create them, if not: leave the
5492  // array as is, since shrinking is not really possible because
5493  // some of the vertices at the end may be in use
5494  if (needed_vertices > triangulation.vertices.size())
5495  {
5496  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
5497  triangulation.vertices_used.resize(needed_vertices, false);
5498  }
5499 
5500 
5502  // Before we start with the actual refinement, we do some
5503  // sanity checks if in debug mode. especially, we try to catch
5504  // the notorious problem with lines being twice refined,
5505  // i.e. there are cells adjacent at one line ("around the
5506  // edge", but not at a face), with two cells differing by more
5507  // than one refinement level
5508  //
5509  // this check is very simple to implement here, since we have
5510  // all lines flagged if they shall be refined
5511 #ifdef DEBUG
5513  triangulation.begin_active();
5514  cell != triangulation.end();
5515  ++cell)
5516  if (!cell->refine_flag_set())
5517  for (unsigned int line = 0;
5518  line < GeometryInfo<dim>::lines_per_cell;
5519  ++line)
5520  if (cell->line(line)->has_children())
5521  for (unsigned int c = 0; c < 2; ++c)
5522  Assert(cell->line(line)->child(c)->user_flag_set() == false,
5523  ExcInternalError());
5524 #endif
5525 
5527  // Do refinement on every level
5528  //
5529  // To make life a bit easier, we first refine those lines and
5530  // quads that were flagged for refinement and then compose the
5531  // newly to be created cells.
5532  //
5533  // index of next unused vertex
5534  unsigned int next_unused_vertex = 0;
5535 
5536  // first for lines
5537  {
5538  // only active objects can be refined further
5540  line = triangulation.begin_active_line(),
5541  endl = triangulation.end_line();
5542  typename Triangulation<dim, spacedim>::raw_line_iterator
5543  next_unused_line = triangulation.begin_raw_line();
5544 
5545  for (; line != endl; ++line)
5546  if (line->user_flag_set())
5547  {
5548  // this line needs to be refined
5549 
5550  // find the next unused vertex and set it
5551  // appropriately
5552  while (triangulation.vertices_used[next_unused_vertex] == true)
5553  ++next_unused_vertex;
5554  Assert(
5555  next_unused_vertex < triangulation.vertices.size(),
5556  ExcMessage(
5557  "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."));
5558  triangulation.vertices_used[next_unused_vertex] = true;
5559 
5560  triangulation.vertices[next_unused_vertex] = line->center(true);
5561 
5562  // now that we created the right point, make up the
5563  // two child lines (++ takes care of the end of the
5564  // vector)
5565  next_unused_line =
5566  triangulation.faces->lines.next_free_pair_object(
5567  triangulation);
5568  Assert(next_unused_line.state() == IteratorState::valid,
5569  ExcInternalError());
5570 
5571  // now we found two consecutive unused lines, such
5572  // that the children of a line will be consecutive.
5573  // then set the child pointer of the present line
5574  line->set_children(0, next_unused_line->index());
5575 
5576  // set the two new lines
5577  const typename Triangulation<dim, spacedim>::raw_line_iterator
5578  children[2] = {next_unused_line, ++next_unused_line};
5579 
5580  // some tests; if any of the iterators should be
5581  // invalid, then already dereferencing will fail
5582  Assert(
5583  children[0]->used() == false,
5584  ExcMessage(
5585  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5586  Assert(
5587  children[1]->used() == false,
5588  ExcMessage(
5589  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5590 
5591  children[0]->set(
5592  internal::TriangulationImplementation ::TriaObject<1>(
5593  line->vertex_index(0), next_unused_vertex));
5594  children[1]->set(
5595  internal::TriangulationImplementation ::TriaObject<1>(
5596  next_unused_vertex, line->vertex_index(1)));
5597 
5598  children[0]->set_used_flag();
5599  children[1]->set_used_flag();
5600  children[0]->clear_children();
5601  children[1]->clear_children();
5602  children[0]->clear_user_data();
5603  children[1]->clear_user_data();
5604  children[0]->clear_user_flag();
5605  children[1]->clear_user_flag();
5606 
5607  children[0]->set_boundary_id_internal(line->boundary_id());
5608  children[1]->set_boundary_id_internal(line->boundary_id());
5609 
5610  children[0]->set_manifold_id(line->manifold_id());
5611  children[1]->set_manifold_id(line->manifold_id());
5612 
5613  // finally clear flag
5614  // indicating the need
5615  // for refinement
5616  line->clear_user_flag();
5617  }
5618  }
5619 
5620 
5622  // now refine marked quads
5624 
5625  // here we encounter several cases:
5626 
5627  // a) the quad is unrefined and shall be refined isotropically
5628 
5629  // b) the quad is unrefined and shall be refined
5630  // anisotropically
5631 
5632  // c) the quad is unrefined and shall be refined both
5633  // anisotropically and isotropically (this is reduced to case
5634  // b) and then case b) for the children again)
5635 
5636  // d) the quad is refined anisotropically and shall be refined
5637  // isotropically (this is reduced to case b) for the
5638  // anisotropic children)
5639 
5640  // e) the quad is refined isotropically and shall be refined
5641  // anisotropically (this is transformed to case c), however we
5642  // might have to renumber/rename children...)
5643 
5644  // we need a loop in cases c) and d), as the anisotropic
5645  // children migt have a lower index than the mother quad
5646  for (unsigned int loop = 0; loop < 2; ++loop)
5647  {
5648  // usually, only active objects can be refined
5649  // further. however, in cases d) and e) that is not true,
5650  // so we have to use 'normal' iterators here
5652  quad = triangulation.begin_quad(),
5653  endq = triangulation.end_quad();
5654  typename Triangulation<dim, spacedim>::raw_line_iterator
5655  next_unused_line = triangulation.begin_raw_line();
5656  typename Triangulation<dim, spacedim>::raw_quad_iterator
5657  next_unused_quad = triangulation.begin_raw_quad();
5658 
5659  for (; quad != endq; ++quad)
5660  {
5661  if (quad->user_index())
5662  {
5663  RefinementCase<dim - 1> aniso_quad_ref_case =
5664  face_refinement_cases[quad->user_index()];
5665  // there is one unlikely event here, where we
5666  // already have refind the face: if the face was
5667  // refined anisotropically and we want to refine
5668  // it isotropically, both children are flagged for
5669  // anisotropic refinement. however, if those
5670  // children were already flagged for anisotropic
5671  // refinement, they might already be processed and
5672  // refined.
5673  if (aniso_quad_ref_case == quad->refinement_case())
5674  continue;
5675 
5676  Assert(quad->refinement_case() ==
5677  RefinementCase<dim - 1>::cut_xy ||
5678  quad->refinement_case() ==
5679  RefinementCase<dim - 1>::no_refinement,
5680  ExcInternalError());
5681 
5682  // this quad needs to be refined anisotropically
5683  Assert(quad->user_index() ==
5684  RefinementCase<dim - 1>::cut_x ||
5685  quad->user_index() ==
5686  RefinementCase<dim - 1>::cut_y,
5687  ExcInternalError());
5688 
5689  // make the new line interior to the quad
5690  typename Triangulation<dim, spacedim>::raw_line_iterator
5691  new_line;
5692 
5693  new_line =
5694  triangulation.faces->lines.next_free_single_object(
5695  triangulation);
5696  Assert(
5697  new_line->used() == false,
5698  ExcMessage(
5699  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5700 
5701  // first collect the
5702  // indices of the vertices:
5703  // *--1--*
5704  // | | |
5705  // | | | cut_x
5706  // | | |
5707  // *--0--*
5708  //
5709  // *-----*
5710  // | |
5711  // 0-----1 cut_y
5712  // | |
5713  // *-----*
5714  unsigned int vertex_indices[2];
5715  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5716  {
5717  vertex_indices[0] =
5718  quad->line(2)->child(0)->vertex_index(1);
5719  vertex_indices[1] =
5720  quad->line(3)->child(0)->vertex_index(1);
5721  }
5722  else
5723  {
5724  vertex_indices[0] =
5725  quad->line(0)->child(0)->vertex_index(1);
5726  vertex_indices[1] =
5727  quad->line(1)->child(0)->vertex_index(1);
5728  }
5729 
5730  new_line->set(
5732  vertex_indices[0], vertex_indices[1]));
5733  new_line->set_used_flag();
5734  new_line->clear_user_flag();
5735  new_line->clear_user_data();
5736  new_line->clear_children();
5737  new_line->set_boundary_id_internal(quad->boundary_id());
5738  new_line->set_manifold_id(quad->manifold_id());
5739 
5740  // child 0 and 1 of a line are switched if the
5741  // line orientation is false. set up a miniature
5742  // table, indicating which child to take for line
5743  // orientations false and true. first index: child
5744  // index in standard orientation, second index:
5745  // line orientation
5746  const unsigned int index[2][2] = {
5747  {1, 0}, // child 0, line_orientation=false and true
5748  {0, 1}}; // child 1, line_orientation=false and true
5749 
5750  // find some space (consecutive) for the two newly
5751  // to be created quads.
5752  typename Triangulation<dim, spacedim>::raw_quad_iterator
5753  new_quads[2];
5754 
5755  next_unused_quad =
5756  triangulation.faces->quads.next_free_pair_object(
5757  triangulation);
5758  new_quads[0] = next_unused_quad;
5759  Assert(
5760  new_quads[0]->used() == false,
5761  ExcMessage(
5762  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5763 
5764  ++next_unused_quad;
5765  new_quads[1] = next_unused_quad;
5766  Assert(
5767  new_quads[1]->used() == false,
5768  ExcMessage(
5769  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5770 
5771 
5772  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5773  {
5774  new_quads[0]->set(
5775  internal::TriangulationImplementation ::TriaObject<2>(
5776  quad->line_index(0),
5777  new_line->index(),
5778  quad->line(2)
5779  ->child(index[0][quad->line_orientation(2)])
5780  ->index(),
5781  quad->line(3)
5782  ->child(index[0][quad->line_orientation(3)])
5783  ->index()));
5784  new_quads[1]->set(
5785  internal::TriangulationImplementation ::TriaObject<2>(
5786  new_line->index(),
5787  quad->line_index(1),
5788  quad->line(2)
5789  ->child(index[1][quad->line_orientation(2)])
5790  ->index(),
5791  quad->line(3)
5792  ->child(index[1][quad->line_orientation(3)])
5793  ->index()));
5794  }
5795  else
5796  {
5797  new_quads[0]->set(
5798  internal::TriangulationImplementation ::TriaObject<2>(
5799  quad->line(0)
5800  ->child(index[0][quad->line_orientation(0)])
5801  ->index(),
5802  quad->line(1)
5803  ->child(index[0][quad->line_orientation(1)])
5804  ->index(),
5805  quad->line_index(2),
5806  new_line->index()));
5807  new_quads[1]->set(
5808  internal::TriangulationImplementation ::TriaObject<2>(
5809  quad->line(0)
5810  ->child(index[1][quad->line_orientation(0)])
5811  ->index(),
5812  quad->line(1)
5813  ->child(index[1][quad->line_orientation(1)])
5814  ->index(),
5815  new_line->index(),
5816  quad->line_index(3)));
5817  }
5818 
5819  for (const auto &new_quad : new_quads)
5820  {
5821  new_quad->set_used_flag();
5822  new_quad->clear_user_flag();
5823  new_quad->clear_user_data();
5824  new_quad->clear_children();
5825  new_quad->set_boundary_id_internal(quad->boundary_id());
5826  new_quad->set_manifold_id(quad->manifold_id());
5827  // set all line orientations to true, change
5828  // this after the loop, as we have to consider
5829  // different lines for each child
5830  for (unsigned int j = 0;
5831  j < GeometryInfo<dim>::lines_per_face;
5832  ++j)
5833  new_quad->set_line_orientation(j, true);
5834  }
5835  // now set the line orientation of children of
5836  // outer lines correctly, the lines in the
5837  // interior of the refined quad are automatically
5838  // oriented conforming to the standard
5839  new_quads[0]->set_line_orientation(
5840  0, quad->line_orientation(0));
5841  new_quads[0]->set_line_orientation(
5842  2, quad->line_orientation(2));
5843  new_quads[1]->set_line_orientation(
5844  1, quad->line_orientation(1));
5845  new_quads[1]->set_line_orientation(
5846  3, quad->line_orientation(3));
5847  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5848  {
5849  new_quads[0]->set_line_orientation(
5850  3, quad->line_orientation(3));
5851  new_quads[1]->set_line_orientation(
5852  2, quad->line_orientation(2));
5853  }
5854  else
5855  {
5856  new_quads[0]->set_line_orientation(
5857  1, quad->line_orientation(1));
5858  new_quads[1]->set_line_orientation(
5859  0, quad->line_orientation(0));
5860  }
5861 
5862  // test, whether this face is refined
5863  // isotropically already. if so, set the correct
5864  // children pointers.
5865  if (quad->refinement_case() ==
5866  RefinementCase<dim - 1>::cut_xy)
5867  {
5868  // we will put a new refinemnt level of
5869  // anisotropic refinement between the
5870  // unrefined and isotropically refined quad
5871  // ending up with the same fine quads but
5872  // introducing anisotropically refined ones as
5873  // children of the unrefined quad and mother
5874  // cells of the original fine ones.
5875 
5876  // this process includes the creation of a new
5877  // middle line which we will assign as the
5878  // mother line of two of the existing inner
5879  // lines. If those inner lines are not
5880  // consecutive in memory, we won't find them
5881  // later on, so we have to create new ones
5882  // instead and replace all occurrences of the
5883  // old ones with those new ones. As this is
5884  // kind of ugly, we hope we don't have to do
5885  // it often...
5887  old_child[2];
5888  if (aniso_quad_ref_case ==
5890  {
5891  old_child[0] = quad->child(0)->line(1);
5892  old_child[1] = quad->child(2)->line(1);
5893  }
5894  else
5895  {
5896  Assert(aniso_quad_ref_case ==
5898  ExcInternalError());
5899 
5900  old_child[0] = quad->child(0)->line(3);
5901  old_child[1] = quad->child(1)->line(3);
5902  }
5903 
5904  if (old_child[0]->index() + 1 != old_child[1]->index())
5905  {
5906  // this is exactly the ugly case we taked
5907  // about. so, no coimplaining, lets get
5908  // two new lines and copy all info
5909  typename Triangulation<dim,
5910  spacedim>::raw_line_iterator
5911  new_child[2];
5912 
5913  new_child[0] = new_child[1] =
5914  triangulation.faces->lines.next_free_pair_object(
5915  triangulation);
5916  ++new_child[1];
5917 
5918  new_child[0]->set_used_flag();
5919  new_child[1]->set_used_flag();
5920 
5921  const int old_index_0 = old_child[0]->index(),
5922  old_index_1 = old_child[1]->index(),
5923  new_index_0 = new_child[0]->index(),
5924  new_index_1 = new_child[1]->index();
5925 
5926  // loop over all quads and replace the old
5927  // lines
5928  for (unsigned int q = 0;
5929  q < triangulation.faces->quads.cells.size();
5930  ++q)
5931  for (unsigned int l = 0;
5932  l < GeometryInfo<dim>::lines_per_face;
5933  ++l)
5934  {
5935  const int this_index =
5936  triangulation.faces->quads.cells[q].face(l);
5937  if (this_index == old_index_0)
5938  triangulation.faces->quads.cells[q]
5939  .set_face(l, new_index_0);
5940  else if (this_index == old_index_1)
5941  triangulation.faces->quads.cells[q]
5942  .set_face(l, new_index_1);
5943  }
5944  // now we have to copy all information of
5945  // the two lines
5946  for (unsigned int i = 0; i < 2; ++i)
5947  {
5948  Assert(!old_child[i]->has_children(),
5949  ExcInternalError());
5950 
5951  new_child[i]->set(
5953  TriaObject<1>(old_child[i]->vertex_index(0),
5954  old_child[i]->vertex_index(
5955  1)));
5956  new_child[i]->set_boundary_id_internal(
5957  old_child[i]->boundary_id());
5958  new_child[i]->set_manifold_id(
5959  old_child[i]->manifold_id());
5960  new_child[i]->set_user_index(
5961  old_child[i]->user_index());
5962  if (old_child[i]->user_flag_set())
5963  new_child[i]->set_user_flag();
5964  else
5965  new_child[i]->clear_user_flag();
5966 
5967  new_child[i]->clear_children();
5968 
5969  old_child[i]->clear_user_flag();
5970  old_child[i]->clear_user_index();
5971  old_child[i]->clear_used_flag();
5972  }
5973  }
5974  // now that we cared about the lines, go on
5975  // with the quads themselves, where we might
5976  // encounter similar situations...
5977  if (aniso_quad_ref_case ==
5979  {
5980  new_line->set_children(
5981  0, quad->child(0)->line_index(1));
5982  Assert(new_line->child(1) ==
5983  quad->child(2)->line(1),
5984  ExcInternalError());
5985  // now evereything is quite
5986  // complicated. we have the children
5987  // numbered according to
5988  //
5989  // *---*---*
5990  // |n+2|n+3|
5991  // *---*---*
5992  // | n |n+1|
5993  // *---*---*
5994  //
5995  // from the original isotropic
5996  // refinement. we have to reorder them as
5997  //
5998  // *---*---*
5999  // |n+1|n+3|
6000  // *---*---*
6001  // | n |n+2|
6002  // *---*---*
6003  //
6004  // such that n and n+1 are consecutive
6005  // children of m and n+2 and n+3 are
6006  // consecutive children of m+1, where m
6007  // and m+1 are given as in
6008  //
6009  // *---*---*
6010  // | | |
6011  // | m |m+1|
6012  // | | |
6013  // *---*---*
6014  //
6015  // this is a bit ugly, of course: loop
6016  // over all cells on all levels and look
6017  // for faces n+1 (switch_1) and n+2
6018  // (switch_2).
6019  const typename Triangulation<dim, spacedim>::
6020  quad_iterator switch_1 = quad->child(1),
6021  switch_2 = quad->child(2);
6022  const int switch_1_index = switch_1->index();
6023  const int switch_2_index = switch_2->index();
6024  for (unsigned int l = 0;
6025  l < triangulation.levels.size();
6026  ++l)
6027  for (unsigned int h = 0;
6028  h <
6029  triangulation.levels[l]->cells.cells.size();
6030  ++h)
6031  for (unsigned int q = 0;
6032  q < GeometryInfo<dim>::faces_per_cell;
6033  ++q)
6034  {
6035  const int face_index =
6036  triangulation.levels[l]
6037  ->cells.cells[h]
6038  .face(q);
6039  if (face_index == switch_1_index)
6040  triangulation.levels[l]
6041  ->cells.cells[h]
6042  .set_face(q, switch_2_index);
6043  else if (face_index == switch_2_index)
6044  triangulation.levels[l]
6045  ->cells.cells[h]
6046  .set_face(q, switch_1_index);
6047  }
6048  // now we have to copy all information of
6049  // the two quads
6050  const unsigned int switch_1_lines[4] = {
6051  switch_1->line_index(0),
6052  switch_1->line_index(1),
6053  switch_1->line_index(2),
6054  switch_1->line_index(3)};
6055  const bool switch_1_line_orientations[4] = {
6056  switch_1->line_orientation(0),
6057  switch_1->line_orientation(1),
6058  switch_1->line_orientation(2),
6059  switch_1->line_orientation(3)};
6060  const types::boundary_id switch_1_boundary_id =
6061  switch_1->boundary_id();
6062  const unsigned int switch_1_user_index =
6063  switch_1->user_index();
6064  const bool switch_1_user_flag =
6065  switch_1->user_flag_set();
6066  const RefinementCase<dim - 1>
6067  switch_1_refinement_case =
6068  switch_1->refinement_case();
6069  const int switch_1_first_child_pair =
6070  (switch_1_refinement_case ?
6071  switch_1->child_index(0) :
6072  -1);
6073  const int switch_1_second_child_pair =
6074  (switch_1_refinement_case ==
6075  RefinementCase<dim - 1>::cut_xy ?
6076  switch_1->child_index(2) :
6077  -1);
6078 
6079  switch_1->set(
6081  2>(switch_2->line_index(0),
6082  switch_2->line_index(1),
6083  switch_2->line_index(2),
6084  switch_2->line_index(3)));
6085  switch_1->set_line_orientation(
6086  0, switch_2->line_orientation(0));
6087  switch_1->set_line_orientation(
6088  1, switch_2->line_orientation(1));
6089  switch_1->set_line_orientation(
6090  2, switch_2->line_orientation(2));
6091  switch_1->set_line_orientation(
6092  3, switch_2->line_orientation(3));
6093  switch_1->set_boundary_id_internal(
6094  switch_2->boundary_id());
6095  switch_1->set_manifold_id(switch_2->manifold_id());
6096  switch_1->set_user_index(switch_2->user_index());
6097  if (switch_2->user_flag_set())
6098  switch_1->set_user_flag();
6099  else
6100  switch_1->clear_user_flag();
6101  switch_1->clear_refinement_case();
6102  switch_1->set_refinement_case(
6103  switch_2->refinement_case());
6104  switch_1->clear_children();
6105  if (switch_2->refinement_case())
6106  switch_1->set_children(0,
6107  switch_2->child_index(0));
6108  if (switch_2->refinement_case() ==
6109  RefinementCase<dim - 1>::cut_xy)
6110  switch_1->set_children(2,
6111  switch_2->child_index(2));
6112 
6113  switch_2->set(
6115  2>(switch_1_lines[0],
6116  switch_1_lines[1],
6117  switch_1_lines[2],
6118  switch_1_lines[3]));
6119  switch_2->set_line_orientation(
6120  0, switch_1_line_orientations[0]);
6121  switch_2->set_line_orientation(
6122  1, switch_1_line_orientations[1]);
6123  switch_2->set_line_orientation(
6124  2, switch_1_line_orientations[2]);
6125  switch_2->set_line_orientation(
6126  3, switch_1_line_orientations[3]);
6127  switch_2->set_boundary_id_internal(
6128  switch_1_boundary_id);
6129  switch_2->set_manifold_id(switch_1->manifold_id());
6130  switch_2->set_user_index(switch_1_user_index);
6131  if (switch_1_user_flag)
6132  switch_2->set_user_flag();
6133  else
6134  switch_2->clear_user_flag();
6135  switch_2->clear_refinement_case();
6136  switch_2->set_refinement_case(
6137  switch_1_refinement_case);
6138  switch_2->clear_children();
6139  switch_2->set_children(0,
6140  switch_1_first_child_pair);
6141  switch_2->set_children(2,
6142  switch_1_second_child_pair);
6143 
6144  new_quads[0]->set_refinement_case(
6146  new_quads[0]->set_children(0, quad->child_index(0));
6147  new_quads[1]->set_refinement_case(
6149  new_quads[1]->set_children(0, quad->child_index(2));
6150  }
6151  else
6152  {
6153  new_quads[0]->set_refinement_case(
6155  new_quads[0]->set_children(0, quad->child_index(0));
6156  new_quads[1]->set_refinement_case(
6158  new_quads[1]->set_children(0, quad->child_index(2));
6159  new_line->set_children(
6160  0, quad->child(0)->line_index(3));
6161  Assert(new_line->child(1) ==
6162  quad->child(1)->line(3),
6163  ExcInternalError());
6164  }
6165  quad->clear_children();
6166  }
6167 
6168  // note these quads as children to the present one
6169  quad->set_children(0, new_quads[0]->index());
6170 
6171  quad->set_refinement_case(aniso_quad_ref_case);
6172 
6173  // finally clear flag indicating the need for
6174  // refinement
6175  quad->clear_user_data();
6176  } // if (anisotropic refinement)
6177 
6178  if (quad->user_flag_set())
6179  {
6180  // this quad needs to be refined isotropically
6181 
6182  // first of all: we only get here in the first run
6183  // of the loop
6184  Assert(loop == 0, ExcInternalError());
6185 
6186  // find the next unused vertex. we'll need this in
6187  // any case
6188  while (triangulation.vertices_used[next_unused_vertex] ==
6189  true)
6190  ++next_unused_vertex;
6191  Assert(
6192  next_unused_vertex < triangulation.vertices.size(),
6193  ExcMessage(
6194  "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."));
6195 
6196  // now: if the quad is refined anisotropically
6197  // already, set the anisotropic refinement flag
6198  // for both children. Additionally, we have to
6199  // refine the inner line, as it is an outer line
6200  // of the two (anisotropic) children
6201  const RefinementCase<dim - 1> quad_ref_case =
6202  quad->refinement_case();
6203 
6204  if (quad_ref_case == RefinementCase<dim - 1>::cut_x ||
6205  quad_ref_case == RefinementCase<dim - 1>::cut_y)
6206  {
6207  // set the 'opposite' refine case for children
6208  quad->child(0)->set_user_index(
6209  RefinementCase<dim - 1>::cut_xy - quad_ref_case);
6210  quad->child(1)->set_user_index(
6211  RefinementCase<dim - 1>::cut_xy - quad_ref_case);
6212  // refine the inner line
6214  middle_line;
6215  if (quad_ref_case == RefinementCase<dim - 1>::cut_x)
6216  middle_line = quad->child(0)->line(1);
6217  else
6218  middle_line = quad->child(0)->line(3);
6219 
6220  // if the face has been refined
6221  // anisotropically in the last refinement step
6222  // it might be, that it is flagged already and
6223  // that the middle line is thus refined
6224  // already. if not create children.
6225  if (!middle_line->has_children())
6226  {
6227  // set the middle vertex
6228  // appropriately. double refinement of
6229  // quads can only happen in the interior
6230  // of the domain, so we need not care
6231  // about boundary quads here
6232  triangulation.vertices[next_unused_vertex] =
6233  middle_line->center(true);
6234  triangulation.vertices_used[next_unused_vertex] =
6235  true;
6236 
6237  // now search a slot for the two
6238  // child lines
6239  next_unused_line =
6240  triangulation.faces->lines.next_free_pair_object(
6241  triangulation);
6242 
6243  // set the child pointer of the present
6244  // line
6245  middle_line->set_children(
6246  0, next_unused_line->index());
6247 
6248  // set the two new lines
6249  const typename Triangulation<dim, spacedim>::
6250  raw_line_iterator children[2] = {
6251  next_unused_line, ++next_unused_line};
6252 
6253  // some tests; if any of the iterators
6254  // should be invalid, then already
6255  // dereferencing will fail
6256  Assert(
6257  children[0]->used() == false,
6258  ExcMessage(
6259  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6260  Assert(
6261  children[1]->used() == false,
6262  ExcMessage(
6263  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6264 
6265  children[0]->set(
6267  1>(middle_line->vertex_index(0),
6268  next_unused_vertex));
6269  children[1]->set(
6271  1>(next_unused_vertex,
6272  middle_line->vertex_index(1)));
6273 
6274  children[0]->set_used_flag();
6275  children[1]->set_used_flag();
6276  children[0]->clear_children();
6277  children[1]->clear_children();
6278  children[0]->clear_user_data();
6279  children[1]->clear_user_data();
6280  children[0]->clear_user_flag();
6281  children[1]->clear_user_flag();
6282 
6283  children[0]->set_boundary_id_internal(
6284  middle_line->boundary_id());
6285  children[1]->set_boundary_id_internal(
6286  middle_line->boundary_id());
6287 
6288  children[0]->set_manifold_id(
6289  middle_line->manifold_id());
6290  children[1]->set_manifold_id(
6291  middle_line->manifold_id());
6292  }
6293  // now remove the flag from the quad and go to
6294  // the next quad, the actual refinement of the
6295  // quad takes place later on in this pass of
6296  // the loop or in the next one
6297  quad->clear_user_flag();
6298  continue;
6299  } // if (several refinement cases)
6300 
6301  // if we got here, we have an unrefined quad and
6302  // have to do the usual work like in an purely
6303  // isotropic refinement
6304  Assert(quad_ref_case ==
6306  ExcInternalError());
6307 
6308  // set the middle vertex appropriately: it might be that
6309  // the quad itself is not at the boundary, but that one of
6310  // its lines actually is. in this case, the newly created
6311  // vertices at the centers of the lines are not
6312  // necessarily the mean values of the adjacent vertices,
6313  // so do not compute the new vertex as the mean value of
6314  // the 4 vertices of the face, but rather as a weighted
6315  // mean value of the 8 vertices which we already have (the
6316  // four old ones, and the four ones inserted as middle
6317  // points for the four lines). summing up some more points
6318  // is generally cheaper than first asking whether one of
6319  // the lines is at the boundary
6320  //
6321  // note that the exact weights are chosen such as to
6322  // minimize the distortion of the four new quads from the
6323  // optimal shape. their description uses the formulas
6324  // underlying the TransfiniteInterpolationManifold
6325  // implementation
6326  triangulation.vertices[next_unused_vertex] =
6327  quad->center(true, true);
6328  triangulation.vertices_used[next_unused_vertex] = true;
6329 
6330  // now that we created the right point, make up
6331  // the four lines interior to the quad (++ takes
6332  // care of the end of the vector)
6333  typename Triangulation<dim, spacedim>::raw_line_iterator
6334  new_lines[4];
6335 
6336  for (unsigned int i = 0; i < 4; ++i)
6337  {
6338  if (i % 2 == 0)
6339  // search a free pair of lines for 0. and
6340  // 2. line, so that two of them end up
6341  // together, which is necessary if later on
6342  // we want to refine the quad
6343  // anisotropically and the two lines end up
6344  // as children of new line
6345  next_unused_line =
6346  triangulation.faces->lines.next_free_pair_object(
6347  triangulation);
6348 
6349  new_lines[i] = next_unused_line;
6350  ++next_unused_line;
6351 
6352  Assert(
6353  new_lines[i]->used() == false,
6354  ExcMessage(
6355  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6356  }
6357 
6358  // set the data of the four lines. first collect
6359  // the indices of the five vertices:
6360  //
6361  // *--3--*
6362  // | | |
6363  // 0--4--1
6364  // | | |
6365  // *--2--*
6366  //
6367  // the lines are numbered as follows:
6368  //
6369  // *--*--*
6370  // | 1 |
6371  // *2-*-3*
6372  // | 0 |
6373  // *--*--*
6374 
6375  const unsigned int vertex_indices[5] = {
6376  quad->line(0)->child(0)->vertex_index(1),
6377  quad->line(1)->child(0)->vertex_index(1),
6378  quad->line(2)->child(0)->vertex_index(1),
6379  quad->line(3)->child(0)->vertex_index(1),
6380  next_unused_vertex};
6381 
6382  new_lines[0]->set(
6384  vertex_indices[2], vertex_indices[4]));
6385  new_lines[1]->set(
6387  vertex_indices[4], vertex_indices[3]));
6388  new_lines[2]->set(
6390  vertex_indices[0], vertex_indices[4]));
6391  new_lines[3]->set(
6393  vertex_indices[4], vertex_indices[1]));
6394 
6395  for (const auto &new_line : new_lines)
6396  {
6397  new_line->set_used_flag();
6398  new_line->clear_user_flag();
6399  new_line->clear_user_data();
6400  new_line->clear_children();
6401  new_line->set_boundary_id_internal(quad->boundary_id());
6402  new_line->set_manifold_id(quad->manifold_id());
6403  }
6404 
6405  // now for the quads. again, first collect some
6406  // data about the indices of the lines, with the
6407  // following numbering:
6408  //
6409  // .-6-.-7-.
6410  // 1 9 3
6411  // .-10.11-.
6412  // 0 8 2
6413  // .-4-.-5-.
6414 
6415  // child 0 and 1 of a line are switched if the
6416  // line orientation is false. set up a miniature
6417  // table, indicating which child to take for line
6418  // orientations false and true. first index: child
6419  // index in standard orientation, second index:
6420  // line orientation
6421  const unsigned int index[2][2] = {
6422  {1, 0}, // child 0, line_orientation=false and true
6423  {0, 1}}; // child 1, line_orientation=false and true
6424 
6425  const int line_indices[12] = {
6426  quad->line(0)
6427  ->child(index[0][quad->line_orientation(0)])
6428  ->index(),
6429  quad->line(0)
6430  ->child(index[1][quad->line_orientation(0)])
6431  ->index(),
6432  quad->line(1)
6433  ->child(index[0][quad->line_orientation(1)])
6434  ->index(),
6435  quad->line(1)
6436  ->child(index[1][quad->line_orientation(1)])
6437  ->index(),
6438  quad->line(2)
6439  ->child(index[0][quad->line_orientation(2)])
6440  ->index(),
6441  quad->line(2)
6442  ->child(index[1][quad->line_orientation(2)])
6443  ->index(),
6444  quad->line(3)
6445  ->child(index[0][quad->line_orientation(3)])
6446  ->index(),
6447  quad->line(3)
6448  ->child(index[1][quad->line_orientation(3)])
6449  ->index(),
6450  new_lines[0]->index(),
6451  new_lines[1]->index(),
6452  new_lines[2]->index(),
6453  new_lines[3]->index()};
6454 
6455  // find some space (consecutive)
6456  // for the first two newly to be
6457  // created quads.
6458  typename Triangulation<dim, spacedim>::raw_quad_iterator
6459  new_quads[4];
6460 
6461  next_unused_quad =
6462  triangulation.faces->quads.next_free_pair_object(
6463  triangulation);
6464 
6465  new_quads[0] = next_unused_quad;
6466  Assert(
6467  new_quads[0]->used() == false,
6468  ExcMessage(
6469  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6470 
6471  ++next_unused_quad;
6472  new_quads[1] = next_unused_quad;
6473  Assert(
6474  new_quads[1]->used() == false,
6475  ExcMessage(
6476  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6477 
6478  next_unused_quad =
6479  triangulation.faces->quads.next_free_pair_object(
6480  triangulation);
6481  new_quads[2] = next_unused_quad;
6482  Assert(
6483  new_quads[2]->used() == false,
6484  ExcMessage(
6485  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6486 
6487  ++next_unused_quad;
6488  new_quads[3] = next_unused_quad;
6489  Assert(
6490  new_quads[3]->used() == false,
6491  ExcMessage(
6492  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6493 
6494  // note these quads as children to the present one
6495  quad->set_children(0, new_quads[0]->index());
6496  quad->set_children(2, new_quads[2]->index());
6497  new_quads[0]->set(
6498  internal::TriangulationImplementation ::TriaObject<2>(
6499  line_indices[0],
6500  line_indices[8],
6501  line_indices[4],
6502  line_indices[10]));
6503 
6504  quad->set_refinement_case(RefinementCase<2>::cut_xy);
6505 
6506  new_quads[0]->set(
6507  internal::TriangulationImplementation ::TriaObject<2>(
6508  line_indices[0],
6509  line_indices[8],
6510  line_indices[4],
6511  line_indices[10]));
6512  new_quads[1]->set(
6513  internal::TriangulationImplementation ::TriaObject<2>(
6514  line_indices[8],
6515  line_indices[2],
6516  line_indices[5],
6517  line_indices[11]));
6518  new_quads[2]->set(
6519  internal::TriangulationImplementation ::TriaObject<2>(
6520  line_indices[1],
6521  line_indices[9],
6522  line_indices[10],
6523  line_indices[6]));
6524  new_quads[3]->set(
6525  internal::TriangulationImplementation ::TriaObject<2>(
6526  line_indices[9],
6527  line_indices[3],
6528  line_indices[11],
6529  line_indices[7]));
6530  for (const auto &new_quad : new_quads)
6531  {
6532  new_quad->set_used_flag();
6533  new_quad->clear_user_flag();
6534  new_quad->clear_user_data();
6535  new_quad->clear_children();
6536  new_quad->set_boundary_id_internal(quad->boundary_id());
6537  new_quad->set_manifold_id(quad->manifold_id());
6538  // set all line orientations to true, change
6539  // this after the loop, as we have to consider
6540  // different lines for each child
6541  for (unsigned int j = 0;
6542  j < GeometryInfo<dim>::lines_per_face;
6543  ++j)
6544  new_quad->set_line_orientation(j, true);
6545  }
6546  // now set the line orientation of children of
6547  // outer lines correctly, the lines in the
6548  // interior of the refined quad are automatically
6549  // oriented conforming to the standard
6550  new_quads[0]->set_line_orientation(
6551  0, quad->line_orientation(0));
6552  new_quads[0]->set_line_orientation(
6553  2, quad->line_orientation(2));
6554  new_quads[1]->set_line_orientation(
6555  1, quad->line_orientation(1));
6556  new_quads[1]->set_line_orientation(
6557  2, quad->line_orientation(2));
6558  new_quads[2]->set_line_orientation(
6559  0, quad->line_orientation(0));
6560  new_quads[2]->set_line_orientation(
6561  3, quad->line_orientation(3));
6562  new_quads[3]->set_line_orientation(
6563  1, quad->line_orientation(1));
6564  new_quads[3]->set_line_orientation(
6565  3, quad->line_orientation(3));
6566 
6567  // finally clear flag indicating the need for
6568  // refinement
6569  quad->clear_user_flag();
6570  } // if (isotropic refinement)
6571  } // for all quads
6572  } // looped two times over all quads, all quads refined now
6573 
6575  // Now, finally, set up the new
6576  // cells
6578 
6580  cells_with_distorted_children;
6581 
6582  for (unsigned int level = 0; level != triangulation.levels.size() - 1;
6583  ++level)
6584  {
6585  // only active objects can be refined further; remember
6586  // that we won't operate on the finest level, so
6587  // triangulation.begin_*(level+1) is allowed
6589  hex = triangulation.begin_active_hex(level),
6590  endh = triangulation.begin_active_hex(level + 1);
6591  typename Triangulation<dim, spacedim>::raw_hex_iterator
6592  next_unused_hex = triangulation.begin_raw_hex(level + 1);
6593 
6594  for (; hex != endh; ++hex)
6595  if (hex->refine_flag_set())
6596  {
6597  // this hex needs to be refined
6598 
6599  // clear flag indicating the need for refinement. do
6600  // it here already, since we can't do it anymore
6601  // once the cell has children
6602  const RefinementCase<dim> ref_case = hex->refine_flag_set();
6603  hex->clear_refine_flag();
6604  hex->set_refinement_case(ref_case);
6605 
6606  // depending on the refine case we might have to
6607  // create additional vertices, lines and quads
6608  // interior of the hex before the actual children
6609  // can be set up.
6610 
6611  // in a first step: reserve the needed space for
6612  // lines, quads and hexes and initialize them
6613  // correctly
6614 
6615  unsigned int n_new_lines = 0;
6616  unsigned int n_new_quads = 0;
6617  unsigned int n_new_hexes = 0;
6618  switch (ref_case)
6619  {
6623  n_new_lines = 0;
6624  n_new_quads = 1;
6625  n_new_hexes = 2;
6626  break;
6630  n_new_lines = 1;
6631  n_new_quads = 4;
6632  n_new_hexes = 4;
6633  break;
6635  n_new_lines = 6;
6636  n_new_quads = 12;
6637  n_new_hexes = 8;
6638  break;
6639  default:
6640  Assert(false, ExcInternalError());
6641  break;
6642  }
6643 
6644  // find some space for the newly to be created
6645  // interior lines and initialize them.
6646  std::vector<
6647  typename Triangulation<dim, spacedim>::raw_line_iterator>
6648  new_lines(n_new_lines);
6649  for (unsigned int i = 0; i < n_new_lines; ++i)
6650  {
6651  new_lines[i] =
6652  triangulation.faces->lines.next_free_single_object(
6653  triangulation);
6654 
6655  Assert(
6656  new_lines[i]->used() == false,
6657  ExcMessage(
6658  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6659  new_lines[i]->set_used_flag();
6660  new_lines[i]->clear_user_flag();
6661  new_lines[i]->clear_user_data();
6662  new_lines[i]->clear_children();
6663  // interior line
6664  new_lines[i]->set_boundary_id_internal(
6666  // they inherit geometry description of the hex they
6667  // belong to
6668  new_lines[i]->set_manifold_id(hex->manifold_id());
6669  }
6670 
6671  // find some space for the newly to be created
6672  // interior quads and initialize them.
6673  std::vector<
6674  typename Triangulation<dim, spacedim>::raw_quad_iterator>
6675  new_quads(n_new_quads);
6676  for (unsigned int i = 0; i < n_new_quads; ++i)
6677  {
6678  new_quads[i] =
6679  triangulation.faces->quads.next_free_single_object(
6680  triangulation);
6681 
6682  Assert(
6683  new_quads[i]->used() == false,
6684  ExcMessage(
6685  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6686  new_quads[i]->set_used_flag();
6687  new_quads[i]->clear_user_flag();
6688  new_quads[i]->clear_user_data();
6689  new_quads[i]->clear_children();
6690  // interior quad
6691  new_quads[i]->set_boundary_id_internal(
6693  // they inherit geometry description of the hex they
6694  // belong to
6695  new_quads[i]->set_manifold_id(hex->manifold_id());
6696  // set all line orientation flags to true by
6697  // default, change this afterwards, if necessary
6698  for (unsigned int j = 0;
6699  j < GeometryInfo<dim>::lines_per_face;
6700  ++j)
6701  new_quads[i]->set_line_orientation(j, true);
6702  }
6703 
6704  types::subdomain_id subdomainid = hex->subdomain_id();
6705 
6706  // find some space for the newly to be created hexes
6707  // and initialize them.
6708  std::vector<
6709  typename Triangulation<dim, spacedim>::raw_hex_iterator>
6710  new_hexes(n_new_hexes);
6711  for (unsigned int i = 0; i < n_new_hexes; ++i)
6712  {
6713  if (i % 2 == 0)
6714  next_unused_hex =
6715  triangulation.levels[level + 1]->cells.next_free_hex(
6716  triangulation, level + 1);
6717  else
6718  ++next_unused_hex;
6719 
6720  new_hexes[i] = next_unused_hex;
6721 
6722  Assert(
6723  new_hexes[i]->used() == false,
6724  ExcMessage(
6725  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6726  new_hexes[i]->set_used_flag();
6727  new_hexes[i]->clear_user_flag();
6728  new_hexes[i]->clear_user_data();
6729  new_hexes[i]->clear_children();
6730  // inherit material
6731  // properties
6732  new_hexes[i]->set_material_id(hex->material_id());
6733  new_hexes[i]->set_manifold_id(hex->manifold_id());
6734  new_hexes[i]->set_subdomain_id(subdomainid);
6735 
6736  if (i % 2)
6737  new_hexes[i]->set_parent(hex->index());
6738  // set the face_orientation flag to true for all
6739  // faces initially, as this is the default value
6740  // which is true for all faces interior to the
6741  // hex. later on go the other way round and
6742  // reset faces that are at the boundary of the
6743  // mother cube
6744  //
6745  // the same is true for the face_flip and
6746  // face_rotation flags. however, the latter two
6747  // are set to false by default as this is the
6748  // standard value
6749  for (unsigned int f = 0;
6750  f < GeometryInfo<dim>::faces_per_cell;
6751  ++f)
6752  {
6753  new_hexes[i]->set_face_orientation(f, true);
6754  new_hexes[i]->set_face_flip(f, false);
6755  new_hexes[i]->set_face_rotation(f, false);
6756  }
6757  }
6758  // note these hexes as children to the present cell
6759  for (unsigned int i = 0; i < n_new_hexes / 2; ++i)
6760  hex->set_children(2 * i, new_hexes[2 * i]->index());
6761 
6762  // we have to take into account whether the
6763  // different faces are oriented correctly or in the
6764  // opposite direction, so store that up front
6765 
6766  // face_orientation
6767  const bool f_or[6] = {hex->face_orientation(0),
6768  hex->face_orientation(1),
6769  hex->face_orientation(2),
6770  hex->face_orientation(3),
6771  hex->face_orientation(4),
6772  hex->face_orientation(5)};
6773 
6774  // face_flip
6775  const bool f_fl[6] = {hex->face_flip(0),
6776  hex->face_flip(1),
6777  hex->face_flip(2),
6778  hex->face_flip(3),
6779  hex->face_flip(4),
6780  hex->face_flip(5)};
6781 
6782  // face_rotation
6783  const bool f_ro[6] = {hex->face_rotation(0),
6784  hex->face_rotation(1),
6785  hex->face_rotation(2),
6786  hex->face_rotation(3),
6787  hex->face_rotation(4),
6788  hex->face_rotation(5)};
6789 
6790  // little helper table, indicating, whether the
6791  // child with index 0 or with index 1 can be found
6792  // at the standard origin of an anisotropically
6793  // refined quads in real orientation index 1:
6794  // (RefineCase - 1) index 2: face_flip
6795 
6796  // index 3: face rotation
6797  // note: face orientation has no influence
6798  const unsigned int child_at_origin[2][2][2] = {
6799  {{0, 0}, // RefinementCase<dim>::cut_x, face_flip=false,
6800  // face_rotation=false and true
6801  {1, 1}}, // RefinementCase<dim>::cut_x, face_flip=true,
6802  // face_rotation=false and true
6803  {{0, 1}, // RefinementCase<dim>::cut_y, face_flip=false,
6804  // face_rotation=false and true
6805  {1, 0}}}; // RefinementCase<dim>::cut_y, face_flip=true,
6806  // face_rotation=false and true
6807 
6809  //
6810  // in the following we will do the same thing for
6811  // each refinement case: create a new vertex (if
6812  // needed), create new interior lines (if needed),
6813  // create new interior quads and afterwards build
6814  // the children hexes out of these and the existing
6815  // subfaces of the outer quads (which have been
6816  // created above). However, even if the steps are
6817  // quite similar, the actual work strongly depends
6818  // on the actual refinement case. therefore, we use
6819  // separate blocks of code for each of these cases,
6820  // which hopefully increases the readability to some
6821  // extend.
6822 
6823  switch (ref_case)
6824  {
6826  {
6828  //
6829  // RefinementCase<dim>::cut_x
6830  //
6831  // the refined cube will look
6832  // like this:
6833  //
6834  // *----*----*
6835  // / / /|
6836  // / / / |
6837  // / / / |
6838  // *----*----* |
6839  // | | | |
6840  // | | | *
6841  // | | | /
6842  // | | | /
6843  // | | |/
6844  // *----*----*
6845  //
6846  // again, first collect some data about the
6847  // indices of the lines, with the following
6848  // numbering:
6849 
6850  // face 2: front plane
6851  // (note: x,y exchanged)
6852  // *---*---*
6853  // | | |
6854  // | 0 |
6855  // | | |
6856  // *---*---*
6857  // m0
6858  // face 3: back plane
6859  // (note: x,y exchanged)
6860  // m1
6861  // *---*---*
6862  // | | |
6863  // | 1 |
6864  // | | |
6865  // *---*---*
6866  // face 4: bottom plane
6867  // *---*---*
6868  // / / /
6869  // / 2 /
6870  // / / /
6871  // *---*---*
6872  // m0
6873  // face 5: top plane
6874  // m1
6875  // *---*---*
6876  // / / /
6877  // / 3 /
6878  // / / /
6879  // *---*---*
6880 
6881  // set up a list of line iterators first. from
6882  // this, construct lists of line_indices and
6883  // line orientations later on
6884  const typename Triangulation<dim, spacedim>::
6885  raw_line_iterator lines[4] = {
6886  hex->face(2)->child(0)->line(
6887  (hex->face(2)->refinement_case() ==
6889  1 :
6890  3), // 0
6891  hex->face(3)->child(0)->line(
6892  (hex->face(3)->refinement_case() ==
6894  1 :
6895  3), // 1
6896  hex->face(4)->child(0)->line(
6897  (hex->face(4)->refinement_case() ==
6899  1 :
6900  3), // 2
6901  hex->face(5)->child(0)->line(
6902  (hex->face(5)->refinement_case() ==
6904  1 :
6905  3) // 3
6906  };
6907 
6908  unsigned int line_indices[4];
6909  for (unsigned int i = 0; i < 4; ++i)
6910  line_indices[i] = lines[i]->index();
6911 
6912  // the orientation of lines for the inner quads
6913  // is quite tricky. as these lines are newly
6914  // created ones and thus have no parents, they
6915  // cannot inherit this property. set up an array
6916  // and fill it with the respective values
6917  bool line_orientation[4];
6918 
6919  // the middle vertex marked as m0 above is the
6920  // start vertex for lines 0 and 2 in standard
6921  // orientation, whereas m1 is the end vertex of
6922  // lines 1 and 3 in standard orientation
6923  const unsigned int middle_vertices[2] = {
6924  hex->line(2)->child(0)->vertex_index(1),
6925  hex->line(7)->child(0)->vertex_index(1)};
6926 
6927  for (unsigned int i = 0; i < 4; ++i)
6928  if (lines[i]->vertex_index(i % 2) ==
6929  middle_vertices[i % 2])
6930  line_orientation[i] = true;
6931  else
6932  {
6933  // it must be the other
6934  // way round then
6935  Assert(lines[i]->vertex_index((i + 1) % 2) ==
6936  middle_vertices[i % 2],
6937  ExcInternalError());
6938  line_orientation[i] = false;
6939  }
6940 
6941  // set up the new quad, line numbering is as
6942  // indicated above
6943  new_quads[0]->set(
6944  internal::TriangulationImplementation ::TriaObject<
6945  2>(line_indices[0],
6946  line_indices[1],
6947  line_indices[2],
6948  line_indices[3]));
6949 
6950  new_quads[0]->set_line_orientation(
6951  0, line_orientation[0]);
6952  new_quads[0]->set_line_orientation(
6953  1, line_orientation[1]);
6954  new_quads[0]->set_line_orientation(
6955  2, line_orientation[2]);
6956  new_quads[0]->set_line_orientation(
6957  3, line_orientation[3]);
6958 
6959  // the quads are numbered as follows:
6960  //
6961  // planes in the interior of the old hex:
6962  //
6963  // *
6964  // /|
6965  // / | x
6966  // / | *-------* *---------*
6967  // * | | | / /
6968  // | 0 | | | / /
6969  // | * | | / /
6970  // | / *-------*y *---------*x
6971  // | /
6972  // |/
6973  // *
6974  //
6975  // children of the faces of the old hex
6976  //
6977  // *---*---* *---*---*
6978  // /| | | / / /|
6979  // / | | | / 9 / 10/ |
6980  // / | 5 | 6 | / / / |
6981  // * | | | *---*---* |
6982  // | 1 *---*---* | | | 2 *
6983  // | / / / | | | /
6984  // | / 7 / 8 / | 3 | 4 | /
6985  // |/ / / | | |/
6986  // *---*---* *---*---*
6987  //
6988  // note that we have to take care of the
6989  // orientation of faces.
6990  const int quad_indices[11] = {
6991  new_quads[0]->index(), // 0
6992 
6993  hex->face(0)->index(), // 1
6994 
6995  hex->face(1)->index(), // 2
6996 
6997  hex->face(2)->child_index(
6998  child_at_origin[hex->face(2)->refinement_case() -
6999  1][f_fl[2]][f_ro[2]]), // 3
7000  hex->face(2)->child_index(
7001  1 -
7002  child_at_origin[hex->face(2)->refinement_case() -
7003  1][f_fl[2]][f_ro[2]]),
7004 
7005  hex->face(3)->child_index(
7006  child_at_origin[hex->face(3)->refinement_case() -
7007  1][f_fl[3]][f_ro[3]]), // 5
7008  hex->face(3)->child_index(
7009  1 -
7010  child_at_origin[hex->face(3)->refinement_case() -
7011  1][f_fl[3]][f_ro[3]]),
7012 
7013  hex->face(4)->child_index(
7014  child_at_origin[hex->face(4)->refinement_case() -
7015  1][f_fl[4]][f_ro[4]]), // 7
7016  hex->face(4)->child_index(
7017  1 -
7018  child_at_origin[hex->face(4)->refinement_case() -
7019  1][f_fl[4]][f_ro[4]]),
7020 
7021  hex->face(5)->child_index(
7022  child_at_origin[hex->face(5)->refinement_case() -
7023  1][f_fl[5]][f_ro[5]]), // 9
7024  hex->face(5)->child_index(
7025  1 -
7026  child_at_origin[hex->face(5)->refinement_case() -
7027  1][f_fl[5]][f_ro[5]])
7028 
7029  };
7030 
7031  new_hexes[0]->set(
7032  internal::TriangulationImplementation ::TriaObject<
7033  3>(quad_indices[1],
7034  quad_indices[0],
7035  quad_indices[3],
7036  quad_indices[5],
7037  quad_indices[7],
7038  quad_indices[9]));
7039  new_hexes[1]->set(
7040  internal::TriangulationImplementation ::TriaObject<
7041  3>(quad_indices[0],
7042  quad_indices[2],
7043  quad_indices[4],
7044  quad_indices[6],
7045  quad_indices[8],
7046  quad_indices[10]));
7047  break;
7048  }
7049 
7051  {
7053  //
7054  // RefinementCase<dim>::cut_y
7055  //
7056  // the refined cube will look like this:
7057  //
7058  // *---------*
7059  // / /|
7060  // *---------* |
7061  // / /| |
7062  // *---------* | |
7063  // | | | |
7064  // | | | *
7065  // | | |/
7066  // | | *
7067  // | |/
7068  // *---------*
7069  //
7070  // again, first collect some data about the
7071  // indices of the lines, with the following
7072  // numbering:
7073 
7074  // face 0: left plane
7075  // *
7076  // /|
7077  // * |
7078  // /| |
7079  // * | |
7080  // | 0 |
7081  // | | *
7082  // | |/
7083  // | *m0
7084  // |/
7085  // *
7086  // face 1: right plane
7087  // *
7088  // /|
7089  // m1* |
7090  // /| |
7091  // * | |
7092  // | 1 |
7093  // | | *
7094  // | |/
7095  // | *
7096  // |/
7097  // *
7098  // face 4: bottom plane
7099  // *-------*
7100  // / /
7101  // m0*---2---*
7102  // / /
7103  // *-------*
7104  // face 5: top plane
7105  // *-------*
7106  // / /
7107  // *---3---*m1
7108  // / /
7109  // *-------*
7110 
7111  // set up a list of line iterators first. from
7112  // this, construct lists of line_indices and
7113  // line orientations later on
7114  const typename Triangulation<dim, spacedim>::
7115  raw_line_iterator lines[4] = {
7116  hex->face(0)->child(0)->line(
7117  (hex->face(0)->refinement_case() ==
7119  1 :
7120  3), // 0
7121  hex->face(1)->child(0)->line(
7122  (hex->face(1)->refinement_case() ==
7124  1 :
7125  3), // 1
7126  hex->face(4)->child(0)->line(
7127  (hex->face(4)->refinement_case() ==
7129  1 :
7130  3), // 2
7131  hex->face(5)->child(0)->line(
7132  (hex->face(5)->refinement_case() ==
7134  1 :
7135  3) // 3
7136  };
7137 
7138  unsigned int line_indices[4];
7139  for (unsigned int i = 0; i < 4; ++i)
7140  line_indices[i] = lines[i]->index();
7141 
7142  // the orientation of lines for the inner quads
7143  // is quite tricky. as these lines are newly
7144  // created ones and thus have no parents, they
7145  // cannot inherit this property. set up an array
7146  // and fill it with the respective values
7147  bool line_orientation[4];
7148 
7149  // the middle vertex marked as m0 above is the
7150  // start vertex for lines 0 and 2 in standard
7151  // orientation, whereas m1 is the end vertex of
7152  // lines 1 and 3 in standard orientation
7153  const unsigned int middle_vertices[2] = {
7154  hex->line(0)->child(0)->vertex_index(1),
7155  hex->line(5)->child(0)->vertex_index(1)};
7156 
7157  for (unsigned int i = 0; i < 4; ++i)
7158  if (lines[i]->vertex_index(i % 2) ==
7159  middle_vertices[i % 2])
7160  line_orientation[i] = true;
7161  else
7162  {
7163  // it must be the other way round then
7164  Assert(lines[i]->vertex_index((i + 1) % 2) ==
7165  middle_vertices[i % 2],
7166  ExcInternalError());
7167  line_orientation[i] = false;
7168  }
7169 
7170  // set up the new quad, line numbering is as
7171  // indicated above
7172  new_quads[0]->set(
7173  internal::TriangulationImplementation ::TriaObject<
7174  2>(line_indices[2],
7175  line_indices[3],
7176  line_indices[0],
7177  line_indices[1]));
7178 
7179  new_quads[0]->set_line_orientation(
7180  0, line_orientation[2]);
7181  new_quads[0]->set_line_orientation(
7182  1, line_orientation[3]);
7183  new_quads[0]->set_line_orientation(
7184  2, line_orientation[0]);
7185  new_quads[0]->set_line_orientation(
7186  3, line_orientation[1]);
7187 
7188  // the quads are numbered as follows:
7189  //
7190  // planes in the interior of the old hex:
7191  //
7192  // *
7193  // /|
7194  // / | x
7195  // / | *-------* *---------*
7196  // * | | | / /
7197  // | | | 0 | / /
7198  // | * | | / /
7199  // | / *-------*y *---------*x
7200  // | /
7201  // |/
7202  // *
7203  //
7204  // children of the faces of the old hex
7205  //
7206  // *-------* *-------*
7207  // /| | / 10 /|
7208  // * | | *-------* |
7209  // /| | 6 | / 9 /| |
7210  // * |2| | *-------* |4|
7211  // | | *-------* | | | *
7212  // |1|/ 8 / | |3|/
7213  // | *-------* | 5 | *
7214  // |/ 7 / | |/
7215  // *-------* *-------*
7216  //
7217  // note that we have to take care of the
7218  // orientation of faces.
7219  const int quad_indices[11] = {
7220  new_quads[0]->index(), // 0
7221 
7222  hex->face(0)->child_index(
7223  child_at_origin[hex->face(0)->refinement_case() -
7224  1][f_fl[0]][f_ro[0]]), // 1
7225  hex->face(0)->child_index(
7226  1 -
7227  child_at_origin[hex->face(0)->refinement_case() -
7228  1][f_fl[0]][f_ro[0]]),
7229 
7230  hex->face(1)->child_index(
7231  child_at_origin[hex->face(1)->refinement_case() -
7232  1][f_fl[1]][f_ro[1]]), // 3
7233  hex->face(1)->child_index(
7234  1 -
7235  child_at_origin[hex->face(1)->refinement_case() -
7236  1][f_fl[1]][f_ro[1]]),
7237 
7238  hex->face(2)->index(), // 5
7239 
7240  hex->face(3)->index(), // 6
7241 
7242  hex->face(4)->child_index(
7243  child_at_origin[hex->face(4)->refinement_case() -
7244  1][f_fl[4]][f_ro[4]]), // 7
7245  hex->face(4)->child_index(
7246  1 -
7247  child_at_origin[hex->face(4)->refinement_case() -
7248  1][f_fl[4]][f_ro[4]]),
7249 
7250  hex->face(5)->child_index(
7251  child_at_origin[hex->face(5)->refinement_case() -
7252  1][f_fl[5]][f_ro[5]]), // 9
7253  hex->face(5)->child_index(
7254  1 -
7255  child_at_origin[hex->face(5)->refinement_case() -
7256  1][f_fl[5]][f_ro[5]])
7257 
7258  };
7259 
7260  new_hexes[0]->set(
7261  internal::TriangulationImplementation ::TriaObject<
7262  3>(quad_indices[1],
7263  quad_indices[3],
7264  quad_indices[5],
7265  quad_indices[0],
7266  quad_indices[7],
7267  quad_indices[9]));
7268  new_hexes[1]->set(
7269  internal::TriangulationImplementation ::TriaObject<
7270  3>(quad_indices[2],
7271  quad_indices[4],
7272  quad_indices[0],
7273  quad_indices[6],
7274  quad_indices[8],
7275  quad_indices[10]));
7276  break;
7277  }
7278 
7280  {
7282  //
7283  // RefinementCase<dim>::cut_z
7284  //
7285  // the refined cube will look like this:
7286  //
7287  // *---------*
7288  // / /|
7289  // / / |
7290  // / / *
7291  // *---------* /|
7292  // | | / |
7293  // | |/ *
7294  // *---------* /
7295  // | | /
7296  // | |/
7297  // *---------*
7298  //
7299  // again, first collect some data about the
7300  // indices of the lines, with the following
7301  // numbering:
7302 
7303  // face 0: left plane
7304  // *
7305  // /|
7306  // / |
7307  // / *
7308  // * /|
7309  // | 0 |
7310  // |/ *
7311  // m0* /
7312  // | /
7313  // |/
7314  // *
7315  // face 1: right plane
7316  // *
7317  // /|
7318  // / |
7319  // / *m1
7320  // * /|
7321  // | 1 |
7322  // |/ *
7323  // * /
7324  // | /
7325  // |/
7326  // *
7327  // face 2: front plane
7328  // (note: x,y exchanged)
7329  // *-------*
7330  // | |
7331  // m0*---2---*
7332  // | |
7333  // *-------*
7334  // face 3: back plane
7335  // (note: x,y exchanged)
7336  // *-------*
7337  // | |
7338  // *---3---*m1
7339  // | |
7340  // *-------*
7341 
7342  // set up a list of line iterators first. from
7343  // this, construct lists of line_indices and
7344  // line orientations later on
7345  const typename Triangulation<dim, spacedim>::
7346  raw_line_iterator lines[4] = {
7347  hex->face(0)->child(0)->line(
7348  (hex->face(0)->refinement_case() ==
7350  1 :
7351  3), // 0
7352  hex->face(1)->child(0)->line(
7353  (hex->face(1)->refinement_case() ==
7355  1 :
7356  3), // 1
7357  hex->face(2)->child(0)->line(
7358  (hex->face(2)->refinement_case() ==
7360  1 :
7361  3), // 2
7362  hex->face(3)->child(0)->line(
7363  (hex->face(3)->refinement_case() ==
7365  1 :
7366  3) // 3
7367  };
7368 
7369  unsigned int line_indices[4];
7370  for (unsigned int i = 0; i < 4; ++i)
7371  line_indices[i] = lines[i]->index();
7372 
7373  // the orientation of lines for the inner quads
7374  // is quite tricky. as these lines are newly
7375  // created ones and thus have no parents, they
7376  // cannot inherit this property. set up an array
7377  // and fill it with the respective values
7378  bool line_orientation[4];
7379 
7380  // the middle vertex marked as m0 above is the
7381  // start vertex for lines 0 and 2 in standard
7382  // orientation, whereas m1 is the end vertex of
7383  // lines 1 and 3 in standard orientation
7384  const unsigned int middle_vertices[2] = {
7385  middle_vertex_index<dim, spacedim>(hex->line(8)),
7386  middle_vertex_index<dim, spacedim>(hex->line(11))};
7387 
7388  for (unsigned int i = 0; i < 4; ++i)
7389  if (lines[i]->vertex_index(i % 2) ==
7390  middle_vertices[i % 2])
7391  line_orientation[i] = true;
7392  else
7393  {
7394  // it must be the other way round then
7395  Assert(lines[i]->vertex_index((i + 1) % 2) ==
7396  middle_vertices[i % 2],
7397  ExcInternalError());
7398  line_orientation[i] = false;
7399  }
7400 
7401  // set up the new quad, line numbering is as
7402  // indicated above
7403  new_quads[0]->set(
7404  internal::TriangulationImplementation ::TriaObject<
7405  2>(line_indices[0],
7406  line_indices[1],
7407  line_indices[2],
7408  line_indices[3]));
7409 
7410  new_quads[0]->set_line_orientation(
7411  0, line_orientation[0]);
7412  new_quads[0]->set_line_orientation(
7413  1, line_orientation[1]);
7414  new_quads[0]->set_line_orientation(
7415  2, line_orientation[2]);
7416  new_quads[0]->set_line_orientation(
7417  3, line_orientation[3]);
7418 
7419  // the quads are numbered as follows:
7420  //
7421  // planes in the interior of the old hex:
7422  //
7423  // *
7424  // /|
7425  // / | x
7426  // / | *-------* *---------*
7427  // * | | | / /
7428  // | | | | / 0 /
7429  // | * | | / /
7430  // | / *-------*y *---------*x
7431  // | /
7432  // |/
7433  // *
7434  //
7435  // children of the faces of the old hex
7436  //
7437  // *---*---* *-------*
7438  // /| 8 | / /|
7439  // / | | / 10 / |
7440  // / *-------* / / *
7441  // * 2/| | *-------* 4/|
7442  // | / | 7 | | 6 | / |
7443  // |/1 *-------* | |/3 *
7444  // * / / *-------* /
7445  // | / 9 / | | /
7446  // |/ / | 5 |/
7447  // *-------* *---*---*
7448  //
7449  // note that we have to take care of the
7450  // orientation of faces.
7451  const int quad_indices[11] = {
7452  new_quads[0]->index(), // 0
7453 
7454  hex->face(0)->child_index(
7455  child_at_origin[hex->face(0)->refinement_case() -
7456  1][f_fl[0]][f_ro[0]]), // 1
7457  hex->face(0)->child_index(
7458  1 -
7459  child_at_origin[hex->face(0)->refinement_case() -
7460  1][f_fl[0]][f_ro[0]]),
7461 
7462  hex->face(1)->child_index(
7463  child_at_origin[hex->face(1)->refinement_case() -
7464  1][f_fl[1]][f_ro[1]]), // 3
7465  hex->face(1)->child_index(
7466  1 -
7467  child_at_origin[hex->face(1)->refinement_case() -
7468  1][f_fl[1]][f_ro[1]]),
7469 
7470  hex->face(2)->child_index(
7471  child_at_origin[hex->face(2)->refinement_case() -
7472  1][f_fl[2]][f_ro[2]]), // 5
7473  hex->face(2)->child_index(
7474  1 -
7475  child_at_origin[hex->face(2)->refinement_case() -
7476  1][f_fl[2]][f_ro[2]]),
7477 
7478  hex->face(3)->child_index(
7479  child_at_origin[hex->face(3)->refinement_case() -
7480  1][f_fl[3]][f_ro[3]]), // 7
7481  hex->face(3)->child_index(
7482  1 -
7483  child_at_origin[hex->face(3)->refinement_case() -
7484  1][f_fl[3]][f_ro[3]]),
7485 
7486  hex->face(4)->index(), // 9
7487 
7488  hex->face(5)->index() // 10
7489  };
7490 
7491  new_hexes[0]->set(
7492  internal::TriangulationImplementation ::TriaObject<
7493  3>(quad_indices[1],
7494  quad_indices[3],
7495  quad_indices[5],
7496  quad_indices[7],
7497  quad_indices[9],
7498  quad_indices[0]));
7499  new_hexes[1]->set(
7500  internal::TriangulationImplementation ::TriaObject<
7501  3>(quad_indices[2],
7502  quad_indices[4],
7503  quad_indices[6],
7504  quad_indices[8],
7505  quad_indices[0],
7506  quad_indices[10]));
7507  break;
7508  }
7509 
7511  {
7513  //
7514  // RefinementCase<dim>::cut_xy
7515  //
7516  // the refined cube will look like this:
7517  //
7518  // *----*----*
7519  // / / /|
7520  // *----*----* |
7521  // / / /| |
7522  // *----*----* | |
7523  // | | | | |
7524  // | | | | *
7525  // | | | |/
7526  // | | | *
7527  // | | |/
7528  // *----*----*
7529  //
7530 
7531  // first, create the new internal line
7532  new_lines[0]->set(
7534  1>(middle_vertex_index<dim, spacedim>(
7535  hex->face(4)),
7536  middle_vertex_index<dim, spacedim>(
7537  hex->face(5))));
7538 
7539  // again, first collect some data about the
7540  // indices of the lines, with the following
7541  // numbering:
7542 
7543  // face 0: left plane
7544  // *
7545  // /|
7546  // * |
7547  // /| |
7548  // * | |
7549  // | 0 |
7550  // | | *
7551  // | |/
7552  // | *
7553  // |/
7554  // *
7555  // face 1: right plane
7556  // *
7557  // /|
7558  // * |
7559  // /| |
7560  // * | |
7561  // | 1 |
7562  // | | *
7563  // | |/
7564  // | *
7565  // |/
7566  // *
7567  // face 2: front plane
7568  // (note: x,y exchanged)
7569  // *---*---*
7570  // | | |
7571  // | 2 |
7572  // | | |
7573  // *-------*
7574  // face 3: back plane
7575  // (note: x,y exchanged)
7576  // *---*---*
7577  // | | |
7578  // | 3 |
7579  // | | |
7580  // *---*---*
7581  // face 4: bottom plane
7582  // *---*---*
7583  // / 5 /
7584  // *-6-*-7-*
7585  // / 4 /
7586  // *---*---*
7587  // face 5: top plane
7588  // *---*---*
7589  // / 9 /
7590  // *10-*-11*
7591  // / 8 /
7592  // *---*---*
7593  // middle planes
7594  // *-------* *---*---*
7595  // / / | | |
7596  // / / | 12 |
7597  // / / | | |
7598  // *-------* *---*---*
7599 
7600  // set up a list of line iterators first. from
7601  // this, construct lists of line_indices and
7602  // line orientations later on
7603  const typename Triangulation<
7604  dim,
7605  spacedim>::raw_line_iterator lines[13] = {
7606  hex->face(0)->child(0)->line(
7607  (hex->face(0)->refinement_case() ==
7609  1 :
7610  3), // 0
7611  hex->face(1)->child(0)->line(
7612  (hex->face(1)->refinement_case() ==
7614  1 :
7615  3), // 1
7616  hex->face(2)->child(0)->line(
7617  (hex->face(2)->refinement_case() ==
7619  1 :
7620  3), // 2
7621  hex->face(3)->child(0)->line(
7622  (hex->face(3)->refinement_case() ==
7624  1 :
7625  3), // 3
7626 
7627  hex->face(4)
7628  ->isotropic_child(
7630  0, f_or[4], f_fl[4], f_ro[4]))
7631  ->line(
7633  1, f_or[4], f_fl[4], f_ro[4])), // 4
7634  hex->face(4)
7635  ->isotropic_child(
7637  3, f_or[4], f_fl[4], f_ro[4]))
7638  ->line(
7640  0, f_or[4], f_fl[4], f_ro[4])), // 5
7641  hex->face(4)
7642  ->isotropic_child(
7644  0, f_or[4], f_fl[4], f_ro[4]))
7645  ->line(
7647  3, f_or[4], f_fl[4], f_ro[4])), // 6
7648  hex->face(4)
7649  ->isotropic_child(
7651  3, f_or[4], f_fl[4], f_ro[4]))
7652  ->line(
7654  2, f_or[4], f_fl[4], f_ro[4])), // 7
7655 
7656  hex->face(5)
7657  ->isotropic_child(
7659  0, f_or[5], f_fl[5], f_ro[5]))
7660  ->line(
7662  1, f_or[5], f_fl[5], f_ro[5])), // 8
7663  hex->face(5)
7664  ->isotropic_child(
7666  3, f_or[5], f_fl[5], f_ro[5]))
7667  ->line(
7669  0, f_or[5], f_fl[5], f_ro[5])), // 9
7670  hex->face(5)
7671  ->isotropic_child(
7673  0, f_or[5], f_fl[5], f_ro[5]))
7674  ->line(
7676  3, f_or[5], f_fl[5], f_ro[5])), // 10
7677  hex->face(5)
7678  ->isotropic_child(
7680  3, f_or[5], f_fl[5], f_ro[5]))
7681  ->line(
7683  2, f_or[5], f_fl[5], f_ro[5])), // 11
7684 
7685  new_lines[0] // 12
7686  };
7687 
7688  unsigned int line_indices[13];
7689  for (unsigned int i = 0; i < 13; ++i)
7690  line_indices[i] = lines[i]->index();
7691 
7692  // the orientation of lines for the inner quads
7693  // is quite tricky. as these lines are newly
7694  // created ones and thus have no parents, they
7695  // cannot inherit this property. set up an array
7696  // and fill it with the respective values
7697  bool line_orientation[13];
7698 
7699  // the middle vertices of the lines of our
7700  // bottom face
7701  const unsigned int middle_vertices[4] = {
7702  hex->line(0)->child(0)->vertex_index(1),
7703  hex->line(1)->child(0)->vertex_index(1),
7704  hex->line(2)->child(0)->vertex_index(1),
7705  hex->line(3)->child(0)->vertex_index(1),
7706  };
7707 
7708  // note: for lines 0 to 3 the orientation of the
7709  // line is 'true', if vertex 0 is on the bottom
7710  // face
7711  for (unsigned int i = 0; i < 4; ++i)
7712  if (lines[i]->vertex_index(0) == middle_vertices[i])
7713  line_orientation[i] = true;
7714  else
7715  {
7716  // it must be the other way round then
7717  Assert(lines[i]->vertex_index(1) ==
7718  middle_vertices[i],
7719  ExcInternalError());
7720  line_orientation[i] = false;
7721  }
7722 
7723  // note: for lines 4 to 11 (inner lines of the
7724  // outer quads) the following holds: the second
7725  // vertex of the even lines in standard
7726  // orientation is the vertex in the middle of
7727  // the quad, whereas for odd lines the first
7728  // vertex is the same middle vertex.
7729  for (unsigned int i = 4; i < 12; ++i)
7730  if (lines[i]->vertex_index((i + 1) % 2) ==
7731  middle_vertex_index<dim, spacedim>(
7732  hex->face(3 + i / 4)))
7733  line_orientation[i] = true;
7734  else
7735  {
7736  // it must be the other way
7737  // round then
7738  Assert(lines[i]->vertex_index(i % 2) ==
7739  (middle_vertex_index<dim, spacedim>(
7740  hex->face(3 + i / 4))),
7741  ExcInternalError());
7742  line_orientation[i] = false;
7743  }
7744  // for the last line the line orientation is
7745  // always true, since it was just constructed
7746  // that way
7747  line_orientation[12] = true;
7748 
7749  // set up the 4 quads, numbered as follows (left
7750  // quad numbering, right line numbering
7751  // extracted from above)
7752  //
7753  // * *
7754  // /| 9|
7755  // * | * |
7756  // y/| | 8| 3
7757  // * |1| * | |
7758  // | | |x | 12|
7759  // |0| * | | *
7760  // | |/ 2 |5
7761  // | * | *
7762  // |/ |4
7763  // * *
7764  //
7765  // x
7766  // *---*---* *10-*-11*
7767  // | | | | | |
7768  // | 2 | 3 | 0 12 1
7769  // | | | | | |
7770  // *---*---*y *-6-*-7-*
7771 
7772  new_quads[0]->set(
7773  internal::TriangulationImplementation ::TriaObject<
7774  2>(line_indices[2],
7775  line_indices[12],
7776  line_indices[4],
7777  line_indices[8]));
7778  new_quads[1]->set(
7779  internal::TriangulationImplementation ::TriaObject<
7780  2>(line_indices[12],
7781  line_indices[3],
7782  line_indices[5],
7783  line_indices[9]));
7784  new_quads[2]->set(
7785  internal::TriangulationImplementation ::TriaObject<
7786  2>(line_indices[6],
7787  line_indices[10],
7788  line_indices[0],
7789  line_indices[12]));
7790  new_quads[3]->set(
7791  internal::TriangulationImplementation ::TriaObject<
7792  2>(line_indices[7],
7793  line_indices[11],
7794  line_indices[12],
7795  line_indices[1]));
7796 
7797  new_quads[0]->set_line_orientation(
7798  0, line_orientation[2]);
7799  new_quads[0]->set_line_orientation(
7800  2, line_orientation[4]);
7801  new_quads[0]->set_line_orientation(
7802  3, line_orientation[8]);
7803 
7804  new_quads[1]->set_line_orientation(
7805  1, line_orientation[3]);
7806  new_quads[1]->set_line_orientation(
7807  2, line_orientation[5]);
7808  new_quads[1]->set_line_orientation(
7809  3, line_orientation[9]);
7810 
7811  new_quads[2]->set_line_orientation(
7812  0, line_orientation[6]);
7813  new_quads[2]->set_line_orientation(
7814  1, line_orientation[10]);
7815  new_quads[2]->set_line_orientation(
7816  2, line_orientation[0]);
7817 
7818  new_quads[3]->set_line_orientation(
7819  0, line_orientation[7]);
7820  new_quads[3]->set_line_orientation(
7821  1, line_orientation[11]);
7822  new_quads[3]->set_line_orientation(
7823  3, line_orientation[1]);
7824 
7825  // the quads are numbered as follows:
7826  //
7827  // planes in the interior of the old hex:
7828  //
7829  // *
7830  // /|
7831  // * | x
7832  // /| | *---*---* *---------*
7833  // * |1| | | | / /
7834  // | | | | 2 | 3 | / /
7835  // |0| * | | | / /
7836  // | |/ *---*---*y *---------*x
7837  // | *
7838  // |/
7839  // *
7840  //
7841  // children of the faces of the old hex
7842  //
7843  // *---*---* *---*---*
7844  // /| | | /18 / 19/|
7845  // * |10 | 11| /---/---* |
7846  // /| | | | /16 / 17/| |
7847  // * |5| | | *---*---* |7|
7848  // | | *---*---* | | | | *
7849  // |4|/14 / 15/ | | |6|/
7850  // | *---/---/ | 8 | 9 | *
7851  // |/12 / 13/ | | |/
7852  // *---*---* *---*---*
7853  //
7854  // note that we have to take care of the
7855  // orientation of faces.
7856  const int quad_indices[20] = {
7857  new_quads[0]->index(), // 0
7858  new_quads[1]->index(),
7859  new_quads[2]->index(),
7860  new_quads[3]->index(),
7861 
7862  hex->face(0)->child_index(
7863  child_at_origin[hex->face(0)->refinement_case() -
7864  1][f_fl[0]][f_ro[0]]), // 4
7865  hex->face(0)->child_index(
7866  1 -
7867  child_at_origin[hex->face(0)->refinement_case() -
7868  1][f_fl[0]][f_ro[0]]),
7869 
7870  hex->face(1)->child_index(
7871  child_at_origin[hex->face(1)->refinement_case() -
7872  1][f_fl[1]][f_ro[1]]), // 6
7873  hex->face(1)->child_index(
7874  1 -
7875  child_at_origin[hex->face(1)->refinement_case() -
7876  1][f_fl[1]][f_ro[1]]),
7877 
7878  hex->face(2)->child_index(
7879  child_at_origin[hex->face(2)->refinement_case() -
7880  1][f_fl[2]][f_ro[2]]), // 8
7881  hex->face(2)->child_index(
7882  1 -
7883  child_at_origin[hex->face(2)->refinement_case() -
7884  1][f_fl[2]][f_ro[2]]),
7885 
7886  hex->face(3)->child_index(
7887  child_at_origin[hex->face(3)->refinement_case() -
7888  1][f_fl[3]][f_ro[3]]), // 10
7889  hex->face(3)->child_index(
7890  1 -
7891  child_at_origin[hex->face(3)->refinement_case() -
7892  1][f_fl[3]][f_ro[3]]),
7893 
7894  hex->face(4)->isotropic_child_index(
7896  0, f_or[4], f_fl[4], f_ro[4])), // 12
7897  hex->face(4)->isotropic_child_index(
7899  1, f_or[4], f_fl[4], f_ro[4])),
7900  hex->face(4)->isotropic_child_index(
7902  2, f_or[4], f_fl[4], f_ro[4])),
7903  hex->face(4)->isotropic_child_index(
7905  3, f_or[4], f_fl[4], f_ro[4])),
7906 
7907  hex->face(5)->isotropic_child_index(
7909  0, f_or[5], f_fl[5], f_ro[5])), // 16
7910  hex->face(5)->isotropic_child_index(
7912  1, f_or[5], f_fl[5], f_ro[5])),
7913  hex->face(5)->isotropic_child_index(
7915  2, f_or[5], f_fl[5], f_ro[5])),
7916  hex->face(5)->isotropic_child_index(
7918  3, f_or[5], f_fl[5], f_ro[5]))};
7919 
7920  new_hexes[0]->set(
7921  internal::TriangulationImplementation ::TriaObject<
7922  3>(quad_indices[4],
7923  quad_indices[0],
7924  quad_indices[8],
7925  quad_indices[2],
7926  quad_indices[12],
7927  quad_indices[16]));
7928  new_hexes[1]->set(
7929  internal::TriangulationImplementation ::TriaObject<
7930  3>(quad_indices[0],
7931  quad_indices[6],
7932  quad_indices[9],
7933  quad_indices[3],
7934  quad_indices[13],
7935  quad_indices[17]));
7936  new_hexes[2]->set(
7937  internal::TriangulationImplementation ::TriaObject<
7938  3>(quad_indices[5],
7939  quad_indices[1],
7940  quad_indices[2],
7941  quad_indices[10],
7942  quad_indices[14],
7943  quad_indices[18]));
7944  new_hexes[3]->set(
7945  internal::TriangulationImplementation ::TriaObject<
7946  3>(quad_indices[1],
7947  quad_indices[7],
7948  quad_indices[3],
7949  quad_indices[11],
7950  quad_indices[15],
7951  quad_indices[19]));
7952  break;
7953  }
7954 
7956  {
7958  //
7959  // RefinementCase<dim>::cut_xz
7960  //
7961  // the refined cube will look like this:
7962  //
7963  // *----*----*
7964  // / / /|
7965  // / / / |
7966  // / / / *
7967  // *----*----* /|
7968  // | | | / |
7969  // | | |/ *
7970  // *----*----* /
7971  // | | | /
7972  // | | |/
7973  // *----*----*
7974  //
7975 
7976  // first, create the new internal line
7977  new_lines[0]->set(
7979  1>(middle_vertex_index<dim, spacedim>(
7980  hex->face(2)),
7981  middle_vertex_index<dim, spacedim>(
7982  hex->face(3))));
7983 
7984  // again, first collect some data about the
7985  // indices of the lines, with the following
7986  // numbering:
7987 
7988  // face 0: left plane
7989  // *
7990  // /|
7991  // / |
7992  // / *
7993  // * /|
7994  // | 0 |
7995  // |/ *
7996  // * /
7997  // | /
7998  // |/
7999  // *
8000  // face 1: right plane
8001  // *
8002  // /|
8003  // / |
8004  // / *
8005  // * /|
8006  // | 1 |
8007  // |/ *
8008  // * /
8009  // | /
8010  // |/
8011  // *
8012  // face 2: front plane
8013  // (note: x,y exchanged)
8014  // *---*---*
8015  // | 5 |
8016  // *-6-*-7-*
8017  // | 4 |
8018  // *---*---*
8019  // face 3: back plane
8020  // (note: x,y exchanged)
8021  // *---*---*
8022  // | 9 |
8023  // *10-*-11*
8024  // | 8 |
8025  // *---*---*
8026  // face 4: bottom plane
8027  // *---*---*
8028  // / / /
8029  // / 2 /
8030  // / / /
8031  // *---*---*
8032  // face 5: top plane
8033  // *---*---*
8034  // / / /
8035  // / 3 /
8036  // / / /
8037  // *---*---*
8038  // middle planes
8039  // *---*---* *-------*
8040  // / / / | |
8041  // / 12 / | |
8042  // / / / | |
8043  // *---*---* *-------*
8044 
8045  // set up a list of line iterators first. from
8046  // this, construct lists of line_indices and
8047  // line orientations later on
8048  const typename Triangulation<
8049  dim,
8050  spacedim>::raw_line_iterator lines[13] = {
8051  hex->face(0)->child(0)->line(
8052  (hex->face(0)->refinement_case() ==
8054  1 :
8055  3), // 0
8056  hex->face(1)->child(0)->line(
8057  (hex->face(1)->refinement_case() ==
8059  1 :
8060  3), // 1
8061  hex->face(4)->child(0)->line(
8062  (hex->face(4)->refinement_case() ==
8064  1 :
8065  3), // 2
8066  hex->face(5)->child(0)->line(
8067  (hex->face(5)->refinement_case() ==
8069  1 :
8070  3), // 3
8071 
8072  hex->face(2)
8073  ->isotropic_child(
8075  0, f_or[2], f_fl[2], f_ro[2]))
8076  ->line(
8078  3, f_or[2], f_fl[2], f_ro[2])), // 4
8079  hex->face(2)
8080  ->isotropic_child(
8082  3, f_or[2], f_fl[2], f_ro[2]))
8083  ->line(
8085  2, f_or[2], f_fl[2], f_ro[2])), // 5
8086  hex->face(2)
8087  ->isotropic_child(
8089  0, f_or[2], f_fl[2], f_ro[2]))
8090  ->line(
8092  1, f_or[2], f_fl[2], f_ro[2])), // 6
8093  hex->face(2)
8094  ->isotropic_child(
8096  3, f_or[2], f_fl[2], f_ro[2]))
8097  ->line(
8099  0, f_or[2], f_fl[2], f_ro[2])), // 7
8100 
8101  hex->face(3)
8102  ->isotropic_child(
8104  0, f_or[3], f_fl[3], f_ro[3]))
8105  ->line(
8107  3, f_or[3], f_fl[3], f_ro[3])), // 8
8108  hex->face(3)
8109  ->isotropic_child(
8111  3, f_or[3], f_fl[3], f_ro[3]))
8112  ->line(
8114  2, f_or[3], f_fl[3], f_ro[3])), // 9
8115  hex->face(3)
8116  ->isotropic_child(
8118  0, f_or[3], f_fl[3], f_ro[3]))
8119  ->line(
8121  1, f_or[3], f_fl[3], f_ro[3])), // 10
8122  hex->face(3)
8123  ->isotropic_child(
8125  3, f_or[3], f_fl[3], f_ro[3]))
8126  ->line(
8128  0, f_or[3], f_fl[3], f_ro[3])), // 11
8129 
8130  new_lines[0] // 12
8131  };
8132 
8133  unsigned int line_indices[13];
8134  for (unsigned int i = 0; i < 13; ++i)
8135  line_indices[i] = lines[i]->index();
8136 
8137  // the orientation of lines for the inner quads
8138  // is quite tricky. as these lines are newly
8139  // created ones and thus have no parents, they
8140  // cannot inherit this property. set up an array
8141  // and fill it with the respective values
8142  bool line_orientation[13];
8143 
8144  // the middle vertices of the
8145  // lines of our front face
8146  const unsigned int middle_vertices[4] = {
8147  hex->line(8)->child(0)->vertex_index(1),
8148  hex->line(9)->child(0)->vertex_index(1),
8149  hex->line(2)->child(0)->vertex_index(1),
8150  hex->line(6)->child(0)->vertex_index(1),
8151  };
8152 
8153  // note: for lines 0 to 3 the orientation of the
8154  // line is 'true', if vertex 0 is on the front
8155  for (unsigned int i = 0; i < 4; ++i)
8156  if (lines[i]->vertex_index(0) == middle_vertices[i])
8157  line_orientation[i] = true;
8158  else
8159  {
8160  // it must be the other way round then
8161  Assert(lines[i]->vertex_index(1) ==
8162  middle_vertices[i],
8163  ExcInternalError());
8164  line_orientation[i] = false;
8165  }
8166 
8167  // note: for lines 4 to 11 (inner lines of the
8168  // outer quads) the following holds: the second
8169  // vertex of the even lines in standard
8170  // orientation is the vertex in the middle of
8171  // the quad, whereas for odd lines the first
8172  // vertex is the same middle vertex.
8173  for (unsigned int i = 4; i < 12; ++i)
8174  if (lines[i]->vertex_index((i + 1) % 2) ==
8175  middle_vertex_index<dim, spacedim>(
8176  hex->face(1 + i / 4)))
8177  line_orientation[i] = true;
8178  else
8179  {
8180  // it must be the other way
8181  // round then
8182  Assert(lines[i]->vertex_index(i % 2) ==
8183  (middle_vertex_index<dim, spacedim>(
8184  hex->face(1 + i / 4))),
8185  ExcInternalError());
8186  line_orientation[i] = false;
8187  }
8188  // for the last line the line orientation is
8189  // always true, since it was just constructed
8190  // that way
8191  line_orientation[12] = true;
8192 
8193  // set up the 4 quads, numbered as follows (left
8194  // quad numbering, right line numbering
8195  // extracted from above), the drawings denote
8196  // middle planes
8197  //
8198  // * *
8199  // /| /|
8200  // / | 3 9
8201  // y/ * / *
8202  // * 3/| * /|
8203  // | / |x 5 12|8
8204  // |/ * |/ *
8205  // * 2/ * /
8206  // | / 4 2
8207  // |/ |/
8208  // * *
8209  //
8210  // y
8211  // *----*----* *-10-*-11-*
8212  // / / / / / /
8213  // / 0 / 1 / 0 12 1
8214  // / / / / / /
8215  // *----*----*x *--6-*--7-*
8216 
8217  new_quads[0]->set(
8218  internal::TriangulationImplementation ::TriaObject<
8219  2>(line_indices[0],
8220  line_indices[12],
8221  line_indices[6],
8222  line_indices[10]));
8223  new_quads[1]->set(
8224  internal::TriangulationImplementation ::TriaObject<
8225  2>(line_indices[12],
8226  line_indices[1],
8227  line_indices[7],
8228  line_indices[11]));
8229  new_quads[2]->set(
8230  internal::TriangulationImplementation ::TriaObject<
8231  2>(line_indices[4],
8232  line_indices[8],
8233  line_indices[2],
8234  line_indices[12]));
8235  new_quads[3]->set(
8236  internal::TriangulationImplementation ::TriaObject<
8237  2>(line_indices[5],
8238  line_indices[9],
8239  line_indices[12],
8240  line_indices[3]));
8241 
8242  new_quads[0]->set_line_orientation(
8243  0, line_orientation[0]);
8244  new_quads[0]->set_line_orientation(
8245  2, line_orientation[6]);
8246  new_quads[0]->set_line_orientation(
8247  3, line_orientation[10]);
8248 
8249  new_quads[1]->set_line_orientation(
8250  1, line_orientation[1]);
8251  new_quads[1]->set_line_orientation(
8252  2, line_orientation[7]);
8253  new_quads[1]->set_line_orientation(
8254  3, line_orientation[11]);
8255 
8256  new_quads[2]->set_line_orientation(
8257  0, line_orientation[4]);
8258  new_quads[2]->set_line_orientation(
8259  1, line_orientation[8]);
8260  new_quads[2]->set_line_orientation(
8261  2, line_orientation[2]);
8262 
8263  new_quads[3]->set_line_orientation(
8264  0, line_orientation[5]);
8265  new_quads[3]->set_line_orientation(
8266  1, line_orientation[9]);
8267  new_quads[3]->set_line_orientation(
8268  3, line_orientation[3]);
8269 
8270  // the quads are numbered as follows:
8271  //
8272  // planes in the interior of the old hex:
8273  //
8274  // *
8275  // /|
8276  // / | x
8277  // /3 * *-------* *----*----*
8278  // * /| | | / / /
8279  // | / | | | / 0 / 1 /
8280  // |/ * | | / / /
8281  // * 2/ *-------*y *----*----*x
8282  // | /
8283  // |/
8284  // *
8285  //
8286  // children of the faces
8287  // of the old hex
8288  // *---*---* *---*---*
8289  // /|13 | 15| / / /|
8290  // / | | | /18 / 19/ |
8291  // / *---*---* / / / *
8292  // * 5/| | | *---*---* 7/|
8293  // | / |12 | 14| | 9 | 11| / |
8294  // |/4 *---*---* | | |/6 *
8295  // * / / / *---*---* /
8296  // | /16 / 17/ | | | /
8297  // |/ / / | 8 | 10|/
8298  // *---*---* *---*---*
8299  //
8300  // note that we have to take care of the
8301  // orientation of faces.
8302  const int quad_indices[20] = {
8303  new_quads[0]->index(), // 0
8304  new_quads[1]->index(),
8305  new_quads[2]->index(),
8306  new_quads[3]->index(),
8307 
8308  hex->face(0)->child_index(
8309  child_at_origin[hex->face(0)->refinement_case() -
8310  1][f_fl[0]][f_ro[0]]), // 4
8311  hex->face(0)->child_index(
8312  1 -
8313  child_at_origin[hex->face(0)->refinement_case() -
8314  1][f_fl[0]][f_ro[0]]),
8315 
8316  hex->face(1)->child_index(
8317  child_at_origin[hex->face(1)->refinement_case() -
8318  1][f_fl[1]][f_ro[1]]), // 6
8319  hex->face(1)->child_index(
8320  1 -
8321  child_at_origin[hex->face(1)->refinement_case() -
8322  1][f_fl[1]][f_ro[1]]),
8323 
8324  hex->face(2)->isotropic_child_index(
8326  0, f_or[2], f_fl[2], f_ro[2])), // 8
8327  hex->face(2)->isotropic_child_index(
8329  1, f_or[2], f_fl[2], f_ro[2])),
8330  hex->face(2)->isotropic_child_index(
8332  2, f_or[2], f_fl[2], f_ro[2])),
8333  hex->face(2)->isotropic_child_index(
8335  3, f_or[2], f_fl[2], f_ro[2])),
8336 
8337  hex->face(3)->isotropic_child_index(
8339  0, f_or[3], f_fl[3], f_ro[3])), // 12
8340  hex->face(3)->isotropic_child_index(
8342  1, f_or[3], f_fl[3], f_ro[3])),
8343  hex->face(3)->isotropic_child_index(
8345  2, f_or[3], f_fl[3], f_ro[3])),
8346  hex->face(3)->isotropic_child_index(
8348  3, f_or[3], f_fl[3], f_ro[3])),
8349 
8350  hex->face(4)->child_index(
8351  child_at_origin[hex->face(4)->refinement_case() -
8352  1][f_fl[4]][f_ro[4]]), // 16
8353  hex->face(4)->child_index(
8354  1 -
8355  child_at_origin[hex->face(4)->refinement_case() -
8356  1][f_fl[4]][f_ro[4]]),
8357 
8358  hex->face(5)->child_index(
8359  child_at_origin[hex->face(5)->refinement_case() -
8360  1][f_fl[5]][f_ro[5]]), // 18
8361  hex->face(5)->child_index(
8362  1 -
8363  child_at_origin[hex->face(5)->refinement_case() -
8364  1][f_fl[5]][f_ro[5]])};
8365 
8366  // due to the exchange of x and y for the front
8367  // and back face, we order the children
8368  // according to
8369  //
8370  // *---*---*
8371  // | 1 | 3 |
8372  // *---*---*
8373  // | 0 | 2 |
8374  // *---*---*
8375  new_hexes[0]->set(
8376  internal::TriangulationImplementation ::TriaObject<
8377  3>(quad_indices[4],
8378  quad_indices[2],
8379  quad_indices[8],
8380  quad_indices[12],
8381  quad_indices[16],
8382  quad_indices[0]));
8383  new_hexes[1]->set(
8384  internal::TriangulationImplementation ::TriaObject<
8385  3>(quad_indices[5],
8386  quad_indices[3],
8387  quad_indices[9],
8388  quad_indices[13],
8389  quad_indices[0],
8390  quad_indices[18]));
8391  new_hexes[2]->set(
8392  internal::TriangulationImplementation ::TriaObject<
8393  3>(quad_indices[2],
8394  quad_indices[6],
8395  quad_indices[10],
8396  quad_indices[14],
8397  quad_indices[17],
8398  quad_indices[1]));
8399  new_hexes[3]->set(
8400  internal::TriangulationImplementation ::TriaObject<
8401  3>(quad_indices[3],
8402  quad_indices[7],
8403  quad_indices[11],
8404  quad_indices[15],
8405  quad_indices[1],
8406  quad_indices[19]));
8407  break;
8408  }
8409 
8411  {
8413  //
8414  // RefinementCase<dim>::cut_yz
8415  //
8416  // the refined cube will look like this:
8417  //
8418  // *---------*
8419  // / /|
8420  // *---------* |
8421  // / /| |
8422  // *---------* |/|
8423  // | | * |
8424  // | |/| *
8425  // *---------* |/
8426  // | | *
8427  // | |/
8428  // *---------*
8429  //
8430 
8431  // first, create the new
8432  // internal line
8433  new_lines[0]->set(
8435  1>(middle_vertex_index<dim, spacedim>(
8436  hex->face(0)),
8437  middle_vertex_index<dim, spacedim>(
8438  hex->face(1))));
8439 
8440  // again, first collect some data about the
8441  // indices of the lines, with the following
8442  // numbering: (note that face 0 and 1 each are
8443  // shown twice for better readability)
8444 
8445  // face 0: left plane
8446  // * *
8447  // /| /|
8448  // * | * |
8449  // /| * /| *
8450  // * 5/| * |7|
8451  // | * | | * |
8452  // |/| * |6| *
8453  // * 4/ * |/
8454  // | * | *
8455  // |/ |/
8456  // * *
8457  // face 1: right plane
8458  // * *
8459  // /| /|
8460  // * | * |
8461  // /| * /| *
8462  // * 9/| * |11
8463  // | * | | * |
8464  // |/| * |10 *
8465  // * 8/ * |/
8466  // | * | *
8467  // |/ |/
8468  // * *
8469  // face 2: front plane
8470  // (note: x,y exchanged)
8471  // *-------*
8472  // | |
8473  // *---0---*
8474  // | |
8475  // *-------*
8476  // face 3: back plane
8477  // (note: x,y exchanged)
8478  // *-------*
8479  // | |
8480  // *---1---*
8481  // | |
8482  // *-------*
8483  // face 4: bottom plane
8484  // *-------*
8485  // / /
8486  // *---2---*
8487  // / /
8488  // *-------*
8489  // face 5: top plane
8490  // *-------*
8491  // / /
8492  // *---3---*
8493  // / /
8494  // *-------*
8495  // middle planes
8496  // *-------* *-------*
8497  // / / | |
8498  // *---12--* | |
8499  // / / | |
8500  // *-------* *-------*
8501 
8502  // set up a list of line iterators first. from
8503  // this, construct lists of line_indices and
8504  // line orientations later on
8505  const typename Triangulation<
8506  dim,
8507  spacedim>::raw_line_iterator lines[13] = {
8508  hex->face(2)->child(0)->line(
8509  (hex->face(2)->refinement_case() ==
8511  1 :
8512  3), // 0
8513  hex->face(3)->child(0)->line(
8514  (hex->face(3)->refinement_case() ==
8516  1 :
8517  3), // 1
8518  hex->face(4)->child(0)->line(
8519  (hex->face(4)->refinement_case() ==
8521  1 :
8522  3), // 2
8523  hex->face(5)->child(0)->line(
8524  (hex->face(5)->refinement_case() ==
8526  1 :
8527  3), // 3
8528 
8529  hex->face(0)
8530  ->isotropic_child(
8532  0, f_or[0], f_fl[0], f_ro[0]))
8533  ->line(
8535  1, f_or[0], f_fl[0], f_ro[0])), // 4
8536  hex->face(0)
8537  ->isotropic_child(
8539  3, f_or[0], f_fl[0], f_ro[0]))
8540  ->line(
8542  0, f_or[0], f_fl[0], f_ro[0])), // 5
8543  hex->face(0)
8544  ->isotropic_child(
8546  0, f_or[0], f_fl[0], f_ro[0]))
8547  ->line(
8549  3, f_or[0], f_fl[0], f_ro[0])), // 6
8550  hex->face(0)
8551  ->isotropic_child(
8553  3, f_or[0], f_fl[0], f_ro[0]))
8554  ->line(
8556  2, f_or[0], f_fl[0], f_ro[0])), // 7
8557 
8558  hex->face(1)
8559  ->isotropic_child(
8561  0, f_or[1], f_fl[1], f_ro[1]))
8562  ->line(
8564  1, f_or[1], f_fl[1], f_ro[1])), // 8
8565  hex->face(1)
8566  ->isotropic_child(
8568  3, f_or[1], f_fl[1], f_ro[1]))
8569  ->line(
8571  0, f_or[1], f_fl[1], f_ro[1])), // 9
8572  hex->face(1)
8573  ->isotropic_child(
8575  0, f_or[1], f_fl[1], f_ro[1]))
8576  ->line(
8578  3, f_or[1], f_fl[1], f_ro[1])), // 10
8579  hex->face(1)
8580  ->isotropic_child(
8582  3, f_or[1], f_fl[1], f_ro[1]))
8583  ->line(
8585  2, f_or[1], f_fl[1], f_ro[1])), // 11
8586 
8587  new_lines[0] // 12
8588  };
8589 
8590  unsigned int line_indices[13];
8591 
8592  for (unsigned int i = 0; i < 13; ++i)
8593  line_indices[i] = lines[i]->index();
8594 
8595  // the orientation of lines for the inner quads
8596  // is quite tricky. as these lines are newly
8597  // created ones and thus have no parents, they
8598  // cannot inherit this property. set up an array
8599  // and fill it with the respective values
8600  bool line_orientation[13];
8601 
8602  // the middle vertices of the lines of our front
8603  // face
8604  const unsigned int middle_vertices[4] = {
8605  hex->line(8)->child(0)->vertex_index(1),
8606  hex->line(10)->child(0)->vertex_index(1),
8607  hex->line(0)->child(0)->vertex_index(1),
8608  hex->line(4)->child(0)->vertex_index(1),
8609  };
8610 
8611  // note: for lines 0 to 3 the orientation of the
8612  // line is 'true', if vertex 0 is on the front
8613  for (unsigned int i = 0; i < 4; ++i)
8614  if (lines[i]->vertex_index(0) == middle_vertices[i])
8615  line_orientation[i] = true;
8616  else
8617  {
8618  // it must be the other way round then
8619  Assert(lines[i]->vertex_index(1) ==
8620  middle_vertices[i],
8621  ExcInternalError());
8622  line_orientation[i] = false;
8623  }
8624 
8625  // note: for lines 4 to 11 (inner lines of the
8626  // outer quads) the following holds: the second
8627  // vertex of the even lines in standard
8628  // orientation is the vertex in the middle of
8629  // the quad, whereas for odd lines the first
8630  // vertex is the same middle vertex.
8631  for (unsigned int i = 4; i < 12; ++i)
8632  if (lines[i]->vertex_index((i + 1) % 2) ==
8633  middle_vertex_index<dim, spacedim>(
8634  hex->face(i / 4 - 1)))
8635  line_orientation[i] = true;
8636  else
8637  {
8638  // it must be the other way
8639  // round then
8640  Assert(lines[i]->vertex_index(i % 2) ==
8641  (middle_vertex_index<dim, spacedim>(
8642  hex->face(i / 4 - 1))),
8643  ExcInternalError());
8644  line_orientation[i] = false;
8645  }
8646  // for the last line the line orientation is
8647  // always true, since it was just constructed
8648  // that way
8649  line_orientation[12] = true;
8650 
8651  // set up the 4 quads, numbered as follows (left
8652  // quad numbering, right line numbering
8653  // extracted from above)
8654  //
8655  // x
8656  // *-------* *---3---*
8657  // | 3 | 5 9
8658  // *-------* *---12--*
8659  // | 2 | 4 8
8660  // *-------*y *---2---*
8661  //
8662  // y
8663  // *---------* *----1----*
8664  // / 1 / 7 11
8665  // *---------* *----12---*
8666  // / 0 / 6 10
8667  // *---------*x *----0----*
8668 
8669  new_quads[0]->set(
8670  internal::TriangulationImplementation ::TriaObject<
8671  2>(line_indices[6],
8672  line_indices[10],
8673  line_indices[0],
8674  line_indices[12]));
8675  new_quads[1]->set(
8676  internal::TriangulationImplementation ::TriaObject<
8677  2>(line_indices[7],
8678  line_indices[11],
8679  line_indices[12],
8680  line_indices[1]));
8681  new_quads[2]->set(
8682  internal::TriangulationImplementation ::TriaObject<
8683  2>(line_indices[2],
8684  line_indices[12],
8685  line_indices[4],
8686  line_indices[8]));
8687  new_quads[3]->set(
8688  internal::TriangulationImplementation ::TriaObject<
8689  2>(line_indices[12],
8690  line_indices[3],
8691  line_indices[5],
8692  line_indices[9]));
8693 
8694  new_quads[0]->set_line_orientation(
8695  0, line_orientation[6]);
8696  new_quads[0]->set_line_orientation(
8697  1, line_orientation[10]);
8698  new_quads[0]->set_line_orientation(
8699  2, line_orientation[0]);
8700 
8701  new_quads[1]->set_line_orientation(
8702  0, line_orientation[7]);
8703  new_quads[1]->set_line_orientation(
8704  1, line_orientation[11]);
8705  new_quads[1]->set_line_orientation(
8706  3, line_orientation[1]);
8707 
8708  new_quads[2]->set_line_orientation(
8709  0, line_orientation[2]);
8710  new_quads[2]->set_line_orientation(
8711  2, line_orientation[4]);
8712  new_quads[2]->set_line_orientation(
8713  3, line_orientation[8]);
8714 
8715  new_quads[3]->set_line_orientation(
8716  1, line_orientation[3]);
8717  new_quads[3]->set_line_orientation(
8718  2, line_orientation[5]);
8719  new_quads[3]->set_line_orientation(
8720  3, line_orientation[9]);
8721 
8722  // the quads are numbered as follows:
8723  //
8724  // planes in the interior of the old hex:
8725  //
8726  // *
8727  // /|
8728  // / | x
8729  // / | *-------* *---------*
8730  // * | | 3 | / 1 /
8731  // | | *-------* *---------*
8732  // | * | 2 | / 0 /
8733  // | / *-------*y *---------*x
8734  // | /
8735  // |/
8736  // *
8737  //
8738  // children of the faces
8739  // of the old hex
8740  // *-------* *-------*
8741  // /| | / 19 /|
8742  // * | 15 | *-------* |
8743  // /|7*-------* / 18 /|11
8744  // * |/| | *-------* |/|
8745  // |6* | 14 | | 10* |
8746  // |/|5*-------* | 13 |/|9*
8747  // * |/ 17 / *-------* |/
8748  // |4*-------* | |8*
8749  // |/ 16 / | 12 |/
8750  // *-------* *-------*
8751  //
8752  // note that we have to take care of the
8753  // orientation of faces.
8754  const int quad_indices[20] = {
8755  new_quads[0]->index(), // 0
8756  new_quads[1]->index(),
8757  new_quads[2]->index(),
8758  new_quads[3]->index(),
8759 
8760  hex->face(0)->isotropic_child_index(
8762  0, f_or[0], f_fl[0], f_ro[0])), // 4
8763  hex->face(0)->isotropic_child_index(
8765  1, f_or[0], f_fl[0], f_ro[0])),
8766  hex->face(0)->isotropic_child_index(
8768  2, f_or[0], f_fl[0], f_ro[0])),
8769  hex->face(0)->isotropic_child_index(
8771  3, f_or[0], f_fl[0], f_ro[0])),
8772 
8773  hex->face(1)->isotropic_child_index(
8775  0, f_or[1], f_fl[1], f_ro[1])), // 8
8776  hex->face(1)->isotropic_child_index(
8778  1, f_or[1], f_fl[1], f_ro[1])),
8779  hex->face(1)->isotropic_child_index(
8781  2, f_or[1], f_fl[1], f_ro[1])),
8782  hex->face(1)->isotropic_child_index(
8784  3, f_or[1], f_fl[1], f_ro[1])),
8785 
8786  hex->face(2)->child_index(
8787  child_at_origin[hex->face(2)->refinement_case() -
8788  1][f_fl[2]][f_ro[2]]), // 12
8789  hex->face(2)->child_index(
8790  1 -
8791  child_at_origin[hex->face(2)->refinement_case() -
8792  1][f_fl[2]][f_ro[2]]),
8793 
8794  hex->face(3)->child_index(
8795  child_at_origin[hex->face(3)->refinement_case() -
8796  1][f_fl[3]][f_ro[3]]), // 14
8797  hex->face(3)->child_index(
8798  1 -
8799  child_at_origin[hex->face(3)->refinement_case() -
8800  1][f_fl[3]][f_ro[3]]),
8801 
8802  hex->face(4)->child_index(
8803  child_at_origin[hex->face(4)->refinement_case() -
8804  1][f_fl[4]][f_ro[4]]), // 16
8805  hex->face(4)->child_index(
8806  1 -
8807  child_at_origin[hex->face(4)->refinement_case() -
8808  1][f_fl[4]][f_ro[4]]),
8809 
8810  hex->face(5)->child_index(
8811  child_at_origin[hex->face(5)->refinement_case() -
8812  1][f_fl[5]][f_ro[5]]), // 18
8813  hex->face(5)->child_index(
8814  1 -
8815  child_at_origin[hex->face(5)->refinement_case() -
8816  1][f_fl[5]][f_ro[5]])};
8817 
8818  new_hexes[0]->set(
8819  internal::TriangulationImplementation ::TriaObject<
8820  3>(quad_indices[4],
8821  quad_indices[8],
8822  quad_indices[12],
8823  quad_indices[2],
8824  quad_indices[16],
8825  quad_indices[0]));
8826  new_hexes[1]->set(
8827  internal::TriangulationImplementation ::TriaObject<
8828  3>(quad_indices[5],
8829  quad_indices[9],
8830  quad_indices[2],
8831  quad_indices[14],
8832  quad_indices[17],
8833  quad_indices[1]));
8834  new_hexes[2]->set(
8835  internal::TriangulationImplementation ::TriaObject<
8836  3>(quad_indices[6],
8837  quad_indices[10],
8838  quad_indices[13],
8839  quad_indices[3],
8840  quad_indices[0],
8841  quad_indices[18]));
8842  new_hexes[3]->set(
8843  internal::TriangulationImplementation ::TriaObject<
8844  3>(quad_indices[7],
8845  quad_indices[11],
8846  quad_indices[3],
8847  quad_indices[15],
8848  quad_indices[1],
8849  quad_indices[19]));
8850  break;
8851  }
8852 
8854  {
8856  //
8857  // RefinementCase<dim>::cut_xyz
8858  // isotropic refinement
8859  //
8860  // the refined cube will look
8861  // like this:
8862  //
8863  // *----*----*
8864  // / / /|
8865  // *----*----* |
8866  // / / /| *
8867  // *----*----* |/|
8868  // | | | * |
8869  // | | |/| *
8870  // *----*----* |/
8871  // | | | *
8872  // | | |/
8873  // *----*----*
8874  //
8875 
8876  // find the next unused vertex and set it
8877  // appropriately
8878  while (
8879  triangulation.vertices_used[next_unused_vertex] ==
8880  true)
8881  ++next_unused_vertex;
8882  Assert(
8883  next_unused_vertex < triangulation.vertices.size(),
8884  ExcMessage(
8885  "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."));
8886  triangulation.vertices_used[next_unused_vertex] =
8887  true;
8888 
8889  // the new vertex is definitely in the interior,
8890  // so we need not worry about the
8891  // boundary. However we need to worry about
8892  // Manifolds. Let the cell compute its own
8893  // center, by querying the underlying manifold
8894  // object.
8895  triangulation.vertices[next_unused_vertex] =
8896  hex->center(true, true);
8897 
8898  // set the data of the six lines. first collect
8899  // the indices of the seven vertices (consider
8900  // the two planes to be crossed to form the
8901  // planes cutting the hex in two vertically and
8902  // horizontally)
8903  //
8904  // *--3--* *--5--*
8905  // / / / | | |
8906  // 0--6--1 0--6--1
8907  // / / / | | |
8908  // *--2--* *--4--*
8909  // the lines are numbered
8910  // as follows:
8911  // *--*--* *--*--*
8912  // / 1 / | 5 |
8913  // *2-*-3* *2-*-3*
8914  // / 0 / | 4 |
8915  // *--*--* *--*--*
8916  //
8917  const unsigned int vertex_indices[7] = {
8918  middle_vertex_index<dim, spacedim>(hex->face(0)),
8919  middle_vertex_index<dim, spacedim>(hex->face(1)),
8920  middle_vertex_index<dim, spacedim>(hex->face(2)),
8921  middle_vertex_index<dim, spacedim>(hex->face(3)),
8922  middle_vertex_index<dim, spacedim>(hex->face(4)),
8923  middle_vertex_index<dim, spacedim>(hex->face(5)),
8924  next_unused_vertex};
8925 
8926  new_lines[0]->set(
8928  1>(vertex_indices[2], vertex_indices[6]));
8929  new_lines[1]->set(
8931  1>(vertex_indices[6], vertex_indices[3]));
8932  new_lines[2]->set(
8934  1>(vertex_indices[0], vertex_indices[6]));
8935  new_lines[3]->set(
8937  1>(vertex_indices[6], vertex_indices[1]));
8938  new_lines[4]->set(
8940  1>(vertex_indices[4], vertex_indices[6]));
8941  new_lines[5]->set(
8943  1>(vertex_indices[6], vertex_indices[5]));
8944 
8945  // again, first collect some data about the
8946  // indices of the lines, with the following
8947  // numbering: (note that face 0 and 1 each are
8948  // shown twice for better readability)
8949 
8950  // face 0: left plane
8951  // * *
8952  // /| /|
8953  // * | * |
8954  // /| * /| *
8955  // * 1/| * |3|
8956  // | * | | * |
8957  // |/| * |2| *
8958  // * 0/ * |/
8959  // | * | *
8960  // |/ |/
8961  // * *
8962  // face 1: right plane
8963  // * *
8964  // /| /|
8965  // * | * |
8966  // /| * /| *
8967  // * 5/| * |7|
8968  // | * | | * |
8969  // |/| * |6| *
8970  // * 4/ * |/
8971  // | * | *
8972  // |/ |/
8973  // * *
8974  // face 2: front plane
8975  // (note: x,y exchanged)
8976  // *---*---*
8977  // | 11 |
8978  // *-8-*-9-*
8979  // | 10 |
8980  // *---*---*
8981  // face 3: back plane
8982  // (note: x,y exchanged)
8983  // *---*---*
8984  // | 15 |
8985  // *12-*-13*
8986  // | 14 |
8987  // *---*---*
8988  // face 4: bottom plane
8989  // *---*---*
8990  // / 17 /
8991  // *18-*-19*
8992  // / 16 /
8993  // *---*---*
8994  // face 5: top plane
8995  // *---*---*
8996  // / 21 /
8997  // *22-*-23*
8998  // / 20 /
8999  // *---*---*
9000  // middle planes
9001  // *---*---* *---*---*
9002  // / 25 / | 29 |
9003  // *26-*-27* *26-*-27*
9004  // / 24 / | 28 |
9005  // *---*---* *---*---*
9006 
9007  // set up a list of line iterators first. from
9008  // this, construct lists of line_indices and
9009  // line orientations later on
9010  const typename Triangulation<
9011  dim,
9012  spacedim>::raw_line_iterator lines[30] = {
9013  hex->face(0)
9014  ->isotropic_child(
9016  0, f_or[0], f_fl[0], f_ro[0]))
9017  ->line(
9019  1, f_or[0], f_fl[0], f_ro[0])), // 0
9020  hex->face(0)
9021  ->isotropic_child(
9023  3, f_or[0], f_fl[0], f_ro[0]))
9024  ->line(
9026  0, f_or[0], f_fl[0], f_ro[0])), // 1
9027  hex->face(0)
9028  ->isotropic_child(
9030  0, f_or[0], f_fl[0], f_ro[0]))
9031  ->line(
9033  3, f_or[0], f_fl[0], f_ro[0])), // 2
9034  hex->face(0)
9035  ->isotropic_child(
9037  3, f_or[0], f_fl[0], f_ro[0]))
9038  ->line(
9040  2, f_or[0], f_fl[0], f_ro[0])), // 3
9041 
9042  hex->face(1)
9043  ->isotropic_child(
9045  0, f_or[1], f_fl[1], f_ro[1]))
9046  ->line(
9048  1, f_or[1], f_fl[1], f_ro[1])), // 4
9049  hex->face(1)
9050  ->isotropic_child(
9052  3, f_or[1], f_fl[1], f_ro[1]))
9053  ->line(
9055  0, f_or[1], f_fl[1], f_ro[1])), // 5
9056  hex->face(1)
9057  ->isotropic_child(
9059  0, f_or[1], f_fl[1], f_ro[1]))
9060  ->line(
9062  3, f_or[1], f_fl[1], f_ro[1])), // 6
9063  hex->face(1)
9064  ->isotropic_child(
9066  3, f_or[1], f_fl[1], f_ro[1]))
9067  ->line(
9069  2, f_or[1], f_fl[1], f_ro[1])), // 7
9070 
9071  hex->face(2)
9072  ->isotropic_child(
9074  0, f_or[2], f_fl[2], f_ro[2]))
9075  ->line(
9077  1, f_or[2], f_fl[2], f_ro[2])), // 8
9078  hex->face(2)
9079  ->isotropic_child(
9081  3, f_or[2], f_fl[2], f_ro[2]))
9082  ->line(
9084  0, f_or[2], f_fl[2], f_ro[2])), // 9
9085  hex->face(2)
9086  ->isotropic_child(
9088  0, f_or[2], f_fl[2], f_ro[2]))
9089  ->line(
9091  3, f_or[2], f_fl[2], f_ro[2])), // 10
9092  hex->face(2)
9093  ->isotropic_child(
9095  3, f_or[2], f_fl[2], f_ro[2]))
9096  ->line(
9098  2, f_or[2], f_fl[2], f_ro[2])), // 11
9099 
9100  hex->face(3)
9101  ->isotropic_child(
9103  0, f_or[3], f_fl[3], f_ro[3]))
9104  ->line(
9106  1, f_or[3], f_fl[3], f_ro[3])), // 12
9107  hex->face(3)
9108  ->isotropic_child(
9110  3, f_or[3], f_fl[3], f_ro[3]))
9111  ->line(
9113  0, f_or[3], f_fl[3], f_ro[3])), // 13
9114  hex->face(3)
9115  ->isotropic_child(
9117  0, f_or[3], f_fl[3], f_ro[3]))
9118  ->line(
9120  3, f_or[3], f_fl[3], f_ro[3])), // 14
9121  hex->face(3)
9122  ->isotropic_child(
9124  3, f_or[3], f_fl[3], f_ro[3]))
9125  ->line(
9127  2, f_or[3], f_fl[3], f_ro[3])), // 15
9128 
9129  hex->face(4)
9130  ->isotropic_child(
9132  0, f_or[4], f_fl[4], f_ro[4]))
9133  ->line(
9135  1, f_or[4], f_fl[4], f_ro[4])), // 16
9136  hex->face(4)
9137  ->isotropic_child(
9139  3, f_or[4], f_fl[4], f_ro[4]))
9140  ->line(
9142  0, f_or[4], f_fl[4], f_ro[4])), // 17
9143  hex->face(4)
9144  ->isotropic_child(
9146  0, f_or[4], f_fl[4], f_ro[4]))
9147  ->line(
9149  3, f_or[4], f_fl[4], f_ro[4])), // 18
9150  hex->face(4)
9151  ->isotropic_child(
9153  3, f_or[4], f_fl[4], f_ro[4]))
9154  ->line(
9156  2, f_or[4], f_fl[4], f_ro[4])), // 19
9157 
9158  hex->face(5)
9159  ->isotropic_child(
9161  0, f_or[5], f_fl[5], f_ro[5]))
9162  ->line(
9164  1, f_or[5], f_fl[5], f_ro[5])), // 20
9165  hex->face(5)
9166  ->isotropic_child(
9168  3, f_or[5], f_fl[5], f_ro[5]))
9169  ->line(
9171  0, f_or[5], f_fl[5], f_ro[5])), // 21
9172  hex->face(5)
9173  ->isotropic_child(
9175  0, f_or[5], f_fl[5], f_ro[5]))
9176  ->line(
9178  3, f_or[5], f_fl[5], f_ro[5])), // 22
9179  hex->face(5)
9180  ->isotropic_child(
9182  3, f_or[5], f_fl[5], f_ro[5]))
9183  ->line(
9185  2, f_or[5], f_fl[5], f_ro[5])), // 23
9186 
9187  new_lines[0], // 24
9188  new_lines[1], // 25
9189  new_lines[2], // 26
9190  new_lines[3], // 27
9191  new_lines[4], // 28
9192  new_lines[5] // 29
9193  };
9194 
9195  unsigned int line_indices[30];
9196  for (unsigned int i = 0; i < 30; ++i)
9197  line_indices[i] = lines[i]->index();
9198 
9199  // the orientation of lines for the inner quads
9200  // is quite tricky. as these lines are newly
9201  // created ones and thus have no parents, they
9202  // cannot inherit this property. set up an array
9203  // and fill it with the respective values
9204  bool line_orientation[30];
9205 
9206  // note: for the first 24 lines (inner lines of
9207  // the outer quads) the following holds: the
9208  // second vertex of the even lines in standard
9209  // orientation is the vertex in the middle of
9210  // the quad, whereas for odd lines the first
9211  // vertex is the same middle vertex.
9212  for (unsigned int i = 0; i < 24; ++i)
9213  if (lines[i]->vertex_index((i + 1) % 2) ==
9214  vertex_indices[i / 4])
9215  line_orientation[i] = true;
9216  else
9217  {
9218  // it must be the other way
9219  // round then
9220  Assert(lines[i]->vertex_index(i % 2) ==
9221  vertex_indices[i / 4],
9222  ExcInternalError());
9223  line_orientation[i] = false;
9224  }
9225  // for the last 6 lines the line orientation is
9226  // always true, since they were just constructed
9227  // that way
9228  for (unsigned int i = 24; i < 30; ++i)
9229  line_orientation[i] = true;
9230 
9231  // set up the 12 quads, numbered as follows
9232  // (left quad numbering, right line numbering
9233  // extracted from above)
9234  //
9235  // * *
9236  // /| 21|
9237  // * | * 15
9238  // y/|3* 20| *
9239  // * |/| * |/|
9240  // |2* |x 11 * 14
9241  // |/|1* |/| *
9242  // * |/ * |17
9243  // |0* 10 *
9244  // |/ |16
9245  // * *
9246  //
9247  // x
9248  // *---*---* *22-*-23*
9249  // | 5 | 7 | 1 29 5
9250  // *---*---* *26-*-27*
9251  // | 4 | 6 | 0 28 4
9252  // *---*---*y *18-*-19*
9253  //
9254  // y
9255  // *----*----* *-12-*-13-*
9256  // / 10 / 11 / 3 25 7
9257  // *----*----* *-26-*-27-*
9258  // / 8 / 9 / 2 24 6
9259  // *----*----*x *--8-*--9-*
9260 
9261  new_quads[0]->set(
9262  internal::TriangulationImplementation ::TriaObject<
9263  2>(line_indices[10],
9264  line_indices[28],
9265  line_indices[16],
9266  line_indices[24]));
9267  new_quads[1]->set(
9268  internal::TriangulationImplementation ::TriaObject<
9269  2>(line_indices[28],
9270  line_indices[14],
9271  line_indices[17],
9272  line_indices[25]));
9273  new_quads[2]->set(
9274  internal::TriangulationImplementation ::TriaObject<
9275  2>(line_indices[11],
9276  line_indices[29],
9277  line_indices[24],
9278  line_indices[20]));
9279  new_quads[3]->set(
9280  internal::TriangulationImplementation ::TriaObject<
9281  2>(line_indices[29],
9282  line_indices[15],
9283  line_indices[25],
9284  line_indices[21]));
9285  new_quads[4]->set(
9286  internal::TriangulationImplementation ::TriaObject<
9287  2>(line_indices[18],
9288  line_indices[26],
9289  line_indices[0],
9290  line_indices[28]));
9291  new_quads[5]->set(
9292  internal::TriangulationImplementation ::TriaObject<
9293  2>(line_indices[26],
9294  line_indices[22],
9295  line_indices[1],
9296  line_indices[29]));
9297  new_quads[6]->set(
9298  internal::TriangulationImplementation ::TriaObject<
9299  2>(line_indices[19],
9300  line_indices[27],
9301  line_indices[28],
9302  line_indices[4]));
9303  new_quads[7]->set(
9304  internal::TriangulationImplementation ::TriaObject<
9305  2>(line_indices[27],
9306  line_indices[23],
9307  line_indices[29],
9308  line_indices[5]));
9309  new_quads[8]->set(
9310  internal::TriangulationImplementation ::TriaObject<
9311  2>(line_indices[2],
9312  line_indices[24],
9313  line_indices[8],
9314  line_indices[26]));
9315  new_quads[9]->set(
9316  internal::TriangulationImplementation ::TriaObject<
9317  2>(line_indices[24],
9318  line_indices[6],
9319  line_indices[9],
9320  line_indices[27]));
9321  new_quads[10]->set(
9322  internal::TriangulationImplementation ::TriaObject<
9323  2>(line_indices[3],
9324  line_indices[25],
9325  line_indices[26],
9326  line_indices[12]));
9327  new_quads[11]->set(
9328  internal::TriangulationImplementation ::TriaObject<
9329  2>(line_indices[25],
9330  line_indices[7],
9331  line_indices[27],
9332  line_indices[13]));
9333 
9334  // now reset the line_orientation flags of outer
9335  // lines as they cannot be set in a loop (at
9336  // least not easily)
9337  new_quads[0]->set_line_orientation(
9338  0, line_orientation[10]);
9339  new_quads[0]->set_line_orientation(
9340  2, line_orientation[16]);
9341 
9342  new_quads[1]->set_line_orientation(
9343  1, line_orientation[14]);
9344  new_quads[1]->set_line_orientation(
9345  2, line_orientation[17]);
9346 
9347  new_quads[2]->set_line_orientation(
9348  0, line_orientation[11]);
9349  new_quads[2]->set_line_orientation(
9350  3, line_orientation[20]);
9351 
9352  new_quads[3]->set_line_orientation(
9353  1, line_orientation[15]);
9354  new_quads[3]->set_line_orientation(
9355  3, line_orientation[21]);
9356 
9357  new_quads[4]->set_line_orientation(
9358  0, line_orientation[18]);
9359  new_quads[4]->set_line_orientation(
9360  2, line_orientation[0]);
9361 
9362  new_quads[5]->set_line_orientation(
9363  1, line_orientation[22]);
9364  new_quads[5]->set_line_orientation(
9365  2, line_orientation[1]);
9366 
9367  new_quads[6]->set_line_orientation(
9368  0, line_orientation[19]);
9369  new_quads[6]->set_line_orientation(
9370  3, line_orientation[4]);
9371 
9372  new_quads[7]->set_line_orientation(
9373  1, line_orientation[23]);
9374  new_quads[7]->set_line_orientation(
9375  3, line_orientation[5]);
9376 
9377  new_quads[8]->set_line_orientation(
9378  0, line_orientation[2]);
9379  new_quads[8]->set_line_orientation(
9380  2, line_orientation[8]);
9381 
9382  new_quads[9]->set_line_orientation(
9383  1, line_orientation[6]);
9384  new_quads[9]->set_line_orientation(
9385  2, line_orientation[9]);
9386 
9387  new_quads[10]->set_line_orientation(
9388  0, line_orientation[3]);
9389  new_quads[10]->set_line_orientation(
9390  3, line_orientation[12]);
9391 
9392  new_quads[11]->set_line_orientation(
9393  1, line_orientation[7]);
9394  new_quads[11]->set_line_orientation(
9395  3, line_orientation[13]);
9396 
9398  // create the eight new hexes
9399  //
9400  // again first collect some data. here, we need
9401  // the indices of a whole lotta quads.
9402 
9403  // the quads are numbered as follows:
9404  //
9405  // planes in the interior of the old hex:
9406  //
9407  // *
9408  // /|
9409  // * |
9410  // /|3* *---*---* *----*----*
9411  // * |/| | 5 | 7 | / 10 / 11 /
9412  // |2* | *---*---* *----*----*
9413  // |/|1* | 4 | 6 | / 8 / 9 /
9414  // * |/ *---*---*y *----*----*x
9415  // |0*
9416  // |/
9417  // *
9418  //
9419  // children of the faces
9420  // of the old hex
9421  // *-------* *-------*
9422  // /|25 27| /34 35/|
9423  // 15| | / /19
9424  // / | | /32 33/ |
9425  // * |24 26| *-------*18 |
9426  // 1413*-------* |21 23| 17*
9427  // | /30 31/ | | /
9428  // 12/ / | |16
9429  // |/28 29/ |20 22|/
9430  // *-------* *-------*
9431  //
9432  // note that we have to
9433  // take care of the
9434  // orientation of
9435  // faces.
9436  const int quad_indices[36] = {
9437  new_quads[0]->index(), // 0
9438  new_quads[1]->index(),
9439  new_quads[2]->index(),
9440  new_quads[3]->index(),
9441  new_quads[4]->index(),
9442  new_quads[5]->index(),
9443  new_quads[6]->index(),
9444  new_quads[7]->index(),
9445  new_quads[8]->index(),
9446  new_quads[9]->index(),
9447  new_quads[10]->index(),
9448  new_quads[11]->index(), // 11
9449 
9450  hex->face(0)->isotropic_child_index(
9452  0, f_or[0], f_fl[0], f_ro[0])), // 12
9453  hex->face(0)->isotropic_child_index(
9455  1, f_or[0], f_fl[0], f_ro[0])),
9456  hex->face(0)->isotropic_child_index(
9458  2, f_or[0], f_fl[0], f_ro[0])),
9459  hex->face(0)->isotropic_child_index(
9461  3, f_or[0], f_fl[0], f_ro[0])),
9462 
9463  hex->face(1)->isotropic_child_index(
9465  0, f_or[1], f_fl[1], f_ro[1])), // 16
9466  hex->face(1)->isotropic_child_index(
9468  1, f_or[1], f_fl[1], f_ro[1])),
9469  hex->face(1)->isotropic_child_index(
9471  2, f_or[1], f_fl[1], f_ro[1])),
9472  hex->face(1)->isotropic_child_index(
9474  3, f_or[1], f_fl[1], f_ro[1])),
9475 
9476  hex->face(2)->isotropic_child_index(
9478  0, f_or[2], f_fl[2], f_ro[2])), // 20
9479  hex->face(2)->isotropic_child_index(
9481  1, f_or[2], f_fl[2], f_ro[2])),
9482  hex->face(2)->isotropic_child_index(
9484  2, f_or[2], f_fl[2], f_ro[2])),
9485  hex->face(2)->isotropic_child_index(
9487  3, f_or[2], f_fl[2], f_ro[2])),
9488 
9489  hex->face(3)->isotropic_child_index(
9491  0, f_or[3], f_fl[3], f_ro[3])), // 24
9492  hex->face(3)->isotropic_child_index(
9494  1, f_or[3], f_fl[3], f_ro[3])),
9495  hex->face(3)->isotropic_child_index(
9497  2, f_or[3], f_fl[3], f_ro[3])),
9498  hex->face(3)->isotropic_child_index(
9500  3, f_or[3], f_fl[3], f_ro[3])),
9501 
9502  hex->face(4)->isotropic_child_index(
9504  0, f_or[4], f_fl[4], f_ro[4])), // 28
9505  hex->face(4)->isotropic_child_index(
9507  1, f_or[4], f_fl[4], f_ro[4])),
9508  hex->face(4)->isotropic_child_index(
9510  2, f_or[4], f_fl[4], f_ro[4])),
9511  hex->face(4)->isotropic_child_index(
9513  3, f_or[4], f_fl[4], f_ro[4])),
9514 
9515  hex->face(5)->isotropic_child_index(
9517  0, f_or[5], f_fl[5], f_ro[5])), // 32
9518  hex->face(5)->isotropic_child_index(
9520  1, f_or[5], f_fl[5], f_ro[5])),
9521  hex->face(5)->isotropic_child_index(
9523  2, f_or[5], f_fl[5], f_ro[5])),
9524  hex->face(5)->isotropic_child_index(
9526  3, f_or[5], f_fl[5], f_ro[5]))};
9527 
9528  // bottom children
9529  new_hexes[0]->set(
9530  internal::TriangulationImplementation ::TriaObject<
9531  3>(quad_indices[12],
9532  quad_indices[0],
9533  quad_indices[20],
9534  quad_indices[4],
9535  quad_indices[28],
9536  quad_indices[8]));
9537  new_hexes[1]->set(
9538  internal::TriangulationImplementation ::TriaObject<
9539  3>(quad_indices[0],
9540  quad_indices[16],
9541  quad_indices[22],
9542  quad_indices[6],
9543  quad_indices[29],
9544  quad_indices[9]));
9545  new_hexes[2]->set(
9546  internal::TriangulationImplementation ::TriaObject<
9547  3>(quad_indices[13],
9548  quad_indices[1],
9549  quad_indices[4],
9550  quad_indices[24],
9551  quad_indices[30],
9552  quad_indices[10]));
9553  new_hexes[3]->set(
9554  internal::TriangulationImplementation ::TriaObject<
9555  3>(quad_indices[1],
9556  quad_indices[17],
9557  quad_indices[6],
9558  quad_indices[26],
9559  quad_indices[31],
9560  quad_indices[11]));
9561 
9562  // top children
9563  new_hexes[4]->set(
9564  internal::TriangulationImplementation ::TriaObject<
9565  3>(quad_indices[14],
9566  quad_indices[2],
9567  quad_indices[21],
9568  quad_indices[5],
9569  quad_indices[8],
9570  quad_indices[32]));
9571  new_hexes[5]->set(
9572  internal::TriangulationImplementation ::TriaObject<
9573  3>(quad_indices[2],
9574  quad_indices[18],
9575  quad_indices[23],
9576  quad_indices[7],
9577  quad_indices[9],
9578  quad_indices[33]));
9579  new_hexes[6]->set(
9580  internal::TriangulationImplementation ::TriaObject<
9581  3>(quad_indices[15],
9582  quad_indices[3],
9583  quad_indices[5],
9584  quad_indices[25],
9585  quad_indices[10],
9586  quad_indices[34]));
9587  new_hexes[7]->set(
9588  internal::TriangulationImplementation ::TriaObject<
9589  3>(quad_indices[3],
9590  quad_indices[19],
9591  quad_indices[7],
9592  quad_indices[27],
9593  quad_indices[11],
9594  quad_indices[35]));
9595  break;
9596  }
9597  default:
9598  // all refinement cases have been treated, there
9599  // only remains
9600  // RefinementCase<dim>::no_refinement as
9601  // untreated enumeration value. However, in that
9602  // case we should have aborted much
9603  // earlier. thus we should never get here
9604  Assert(false, ExcInternalError());
9605  break;
9606  } // switch (ref_case)
9607 
9608  // and set face orientation flags. note that new
9609  // faces in the interior of the mother cell always
9610  // have a correctly oriented face, but the ones on
9611  // the outer faces will inherit this flag
9612  //
9613  // the flag have been set to true for all faces
9614  // initially, now go the other way round and reset
9615  // faces that are at the boundary of the mother cube
9616  //
9617  // the same is true for the face_flip and
9618  // face_rotation flags. however, the latter two are
9619  // set to false by default as this is the standard
9620  // value
9621 
9622  // loop over all faces and all (relevant) subfaces
9623  // of that in order to set the correct values for
9624  // face_orientation, face_flip and face_rotation,
9625  // which are inherited from the corresponding face
9626  // of the mother cube
9627  for (unsigned int f = 0;
9628  f < GeometryInfo<dim>::faces_per_cell;
9629  ++f)
9630  for (unsigned int s = 0;
9631  s < std::max(GeometryInfo<dim - 1>::n_children(
9633  ref_case, f)),
9634  1U);
9635  ++s)
9636  {
9637  const unsigned int current_child =
9639  ref_case,
9640  f,
9641  s,
9642  f_or[f],
9643  f_fl[f],
9644  f_ro[f],
9646  ref_case, f, f_or[f], f_fl[f], f_ro[f]));
9647  new_hexes[current_child]->set_face_orientation(f,
9648  f_or[f]);
9649  new_hexes[current_child]->set_face_flip(f, f_fl[f]);
9650  new_hexes[current_child]->set_face_rotation(f, f_ro[f]);
9651  }
9652 
9653  // now see if we have created cells that are
9654  // distorted and if so add them to our list
9655  if ((check_for_distorted_cells == true) &&
9656  has_distorted_children(
9657  hex,
9658  std::integral_constant<int, dim>(),
9659  std::integral_constant<int, spacedim>()))
9660  cells_with_distorted_children.distorted_cells.push_back(
9661  hex);
9662 
9663  // note that the refinement flag was already cleared
9664  // at the beginning of this loop
9665 
9666  // inform all listeners that cell refinement is done
9667  triangulation.signals.post_refinement_on_cell(hex);
9668  }
9669  }
9670 
9671  // clear user data on quads. we used some of this data to
9672  // indicate anisotropic refinemnt cases on faces. all data
9673  // should be cleared by now, but the information whether we
9674  // used indices or pointers is still present. reset it now to
9675  // enable the user to use whichever he likes later on.
9676  triangulation.faces->quads.clear_user_data();
9677 
9678  // return the list with distorted children
9679  return cells_with_distorted_children;
9680  }
9681 
9682 
9695  template <int spacedim>
9696  static void
9698 
9699 
9700  template <int dim, int spacedim>
9701  static void
9703  Triangulation<dim, spacedim> &triangulation)
9704  {
9705  // If the codimension is one, we cannot perform this check
9706  // yet.
9707  if (spacedim > dim)
9708  return;
9709 
9710  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
9711  triangulation.begin();
9712  cell != triangulation.end();
9713  ++cell)
9714  if (cell->at_boundary() && cell->refine_flag_set() &&
9715  cell->refine_flag_set() !=
9717  {
9718  // The cell is at the boundary and it is flagged for
9719  // anisotropic refinement. Therefore, we have a closer
9720  // look
9721  const RefinementCase<dim> ref_case = cell->refine_flag_set();
9722  for (unsigned int face_no = 0;
9723  face_no < GeometryInfo<dim>::faces_per_cell;
9724  ++face_no)
9725  if (cell->face(face_no)->at_boundary())
9726  {
9727  // this is the critical face at the boundary.
9729  face_no) !=
9730  RefinementCase<dim - 1>::isotropic_refinement)
9731  {
9732  // up to now, we do not want to refine this
9733  // cell along the face under consideration
9734  // here.
9735  const typename Triangulation<dim,
9736  spacedim>::face_iterator
9737  face = cell->face(face_no);
9738  // the new point on the boundary would be this
9739  // one.
9740  const Point<spacedim> new_bound = face->center(true);
9741  // to check it, transform to the unit cell
9742  // with Q1Mapping
9743  const Point<dim> new_unit =
9745  .transform_real_to_unit_cell(cell, new_bound);
9746 
9747  // Now, we have to calculate the distance from
9748  // the face in the unit cell.
9749 
9750  // take the correct coordinate direction (0
9751  // for faces 0 and 1, 1 for faces 2 and 3, 2
9752  // for faces 4 and 5) and subtract the correct
9753  // boundary value of the face (0 for faces 0,
9754  // 2, and 4; 1 for faces 1, 3 and 5)
9755  const double dist =
9756  std::fabs(new_unit[face_no / 2] - face_no % 2);
9757 
9758  // compare this with the empirical value
9759  // allowed. if it is too big, flag the face
9760  // for isotropic refinement
9761  const double allowed = 0.25;
9762 
9763  if (dist > allowed)
9764  cell->flag_for_face_refinement(face_no);
9765  } // if flagged for anistropic refinement
9766  } // if (cell->face(face)->at_boundary())
9767  } // for all cells
9768  }
9769 
9770 
9783  template <int dim, int spacedim>
9784  static void
9786  {
9787  Assert(dim < 3,
9788  ExcMessage("Wrong function called -- there should "
9789  "be a specialization."));
9790  }
9791 
9792 
9793  template <int spacedim>
9795  Triangulation<3, spacedim> &triangulation)
9796  {
9797  const unsigned int dim = 3;
9798 
9799  // first clear flags on lines, since we need them to determine
9800  // which lines will be refined
9801  triangulation.clear_user_flags_line();
9802 
9803  // also clear flags on hexes, since we need them to mark those
9804  // cells which are to be coarsened
9805  triangulation.clear_user_flags_hex();
9806 
9807  // variable to store whether the mesh was changed in the
9808  // present loop and in the whole process
9809  bool mesh_changed = false;
9810 
9811  do
9812  {
9813  mesh_changed = false;
9814 
9815  // for this following, we need to know which cells are
9816  // going to be coarsened, if we had to make a
9817  // decision. the following function sets these flags:
9818  triangulation.fix_coarsen_flags();
9819 
9820 
9821  // flag those lines that are refined and will not be
9822  // coarsened and those that will be refined
9823  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
9824  triangulation.begin();
9825  cell != triangulation.end();
9826  ++cell)
9827  if (cell->refine_flag_set())
9828  {
9829  for (unsigned int line = 0;
9830  line < GeometryInfo<dim>::lines_per_cell;
9831  ++line)
9833  cell->refine_flag_set(), line) ==
9835  // flag a line, that will be
9836  // refined
9837  cell->line(line)->set_user_flag();
9838  }
9839  else if (cell->has_children() &&
9840  !cell->child(0)->coarsen_flag_set())
9841  {
9842  for (unsigned int line = 0;
9843  line < GeometryInfo<dim>::lines_per_cell;
9844  ++line)
9846  cell->refinement_case(), line) ==
9848  // flag a line, that is refined
9849  // and will stay so
9850  cell->line(line)->set_user_flag();
9851  }
9852  else if (cell->has_children() &&
9853  cell->child(0)->coarsen_flag_set())
9854  cell->set_user_flag();
9855 
9856 
9857  // now check whether there are cells with lines that are
9858  // more than once refined or that will be more than once
9859  // refined. The first thing should never be the case, in
9860  // the second case we flag the cell for refinement
9862  cell = triangulation.last_active();
9863  cell != triangulation.end();
9864  --cell)
9865  for (unsigned int line = 0;
9866  line < GeometryInfo<dim>::lines_per_cell;
9867  ++line)
9868  {
9869  if (cell->line(line)->has_children())
9870  {
9871  // if this line is refined, its children should
9872  // not have further children
9873  //
9874  // however, if any of the children is flagged
9875  // for further refinement, we need to refine
9876  // this cell also (at least, if the cell is not
9877  // already flagged)
9878  bool offending_line_found = false;
9879 
9880  for (unsigned int c = 0; c < 2; ++c)
9881  {
9882  Assert(cell->line(line)->child(c)->has_children() ==
9883  false,
9884  ExcInternalError());
9885 
9886  if (cell->line(line)->child(c)->user_flag_set() &&
9888  cell->refine_flag_set(), line) ==
9890  {
9891  // tag this cell for refinement
9892  cell->clear_coarsen_flag();
9893  // if anisotropic coarsening is allowed:
9894  // extend the refine_flag in the needed
9895  // direction, else set refine_flag
9896  // (isotropic)
9897  if (triangulation.smooth_grid &
9899  allow_anisotropic_smoothing)
9900  cell->flag_for_line_refinement(line);
9901  else
9902  cell->set_refine_flag();
9903 
9904  for (unsigned int l = 0;
9905  l < GeometryInfo<dim>::lines_per_cell;
9906  ++l)
9908  cell->refine_flag_set(), line) ==
9910  // flag a line, that will be refined
9911  cell->line(l)->set_user_flag();
9912 
9913  // note that we have changed the grid
9914  offending_line_found = true;
9915 
9916  // it may save us several loop
9917  // iterations if we flag all lines of
9918  // this cell now (and not at the outset
9919  // of the next iteration) for refinement
9920  for (unsigned int l = 0;
9921  l < GeometryInfo<dim>::lines_per_cell;
9922  ++l)
9923  if (!cell->line(l)->has_children() &&
9925  cell->refine_flag_set(), l) !=
9927  cell->line(l)->set_user_flag();
9928 
9929  break;
9930  }
9931  }
9932 
9933  if (offending_line_found)
9934  {
9935  mesh_changed = true;
9936  break;
9937  }
9938  }
9939  }
9940 
9941 
9942  // there is another thing here: if any of the lines will
9943  // be refined, then we may not coarsen the present cell
9944  // similarly, if any of the lines *is* already refined, we
9945  // may not coarsen the current cell. however, there's a
9946  // catch: if the line is refined, but the cell behind it
9947  // is going to be coarsened, then the situation
9948  // changes. if we forget this second condition, the
9949  // refine_and_coarsen_3d test will start to fail. note
9950  // that to know which cells are going to be coarsened, the
9951  // call for fix_coarsen_flags above is necessary
9952  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
9953  triangulation.last();
9954  cell != triangulation.end();
9955  --cell)
9956  {
9957  if (cell->user_flag_set())
9958  for (unsigned int line = 0;
9959  line < GeometryInfo<dim>::lines_per_cell;
9960  ++line)
9961  if (cell->line(line)->has_children() &&
9962  (cell->line(line)->child(0)->user_flag_set() ||
9963  cell->line(line)->child(1)->user_flag_set()))
9964  {
9965  for (unsigned int c = 0; c < cell->n_children(); ++c)
9966  cell->child(c)->clear_coarsen_flag();
9967  cell->clear_user_flag();
9968  for (unsigned int l = 0;
9969  l < GeometryInfo<dim>::lines_per_cell;
9970  ++l)
9972  cell->refinement_case(), l) ==
9974  // flag a line, that is refined
9975  // and will stay so
9976  cell->line(l)->set_user_flag();
9977  mesh_changed = true;
9978  break;
9979  }
9980  }
9981  }
9982  while (mesh_changed == true);
9983  }
9984 
9985 
9986 
9993  template <int dim, int spacedim>
9994  static bool
9996  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
9997  {
9998  // in 1d, coarsening is always allowed since we don't enforce
9999  // the 2:1 constraint there
10000  if (dim == 1)
10001  return true;
10002 
10003  const RefinementCase<dim> ref_case = cell->refinement_case();
10004  for (unsigned int n = 0; n < GeometryInfo<dim>::faces_per_cell; ++n)
10005  {
10006  // if the cell is not refined along that face, coarsening
10007  // will not change anything, so do nothing. the same
10008  // applies, if the face is at the boandary
10009  const RefinementCase<dim - 1> face_ref_case =
10010  GeometryInfo<dim>::face_refinement_case(cell->refinement_case(),
10011  n);
10012 
10013  const unsigned int n_subfaces =
10014  GeometryInfo<dim - 1>::n_children(face_ref_case);
10015 
10016  if (n_subfaces == 0 || cell->at_boundary(n))
10017  continue;
10018  for (unsigned int c = 0; c < n_subfaces; ++c)
10019  {
10021  child = cell->child(
10022  GeometryInfo<dim>::child_cell_on_face(ref_case, n, c));
10023 
10025  child_neighbor = child->neighbor(n);
10026  if (!child->neighbor_is_coarser(n))
10027  // in 2d, if the child's neighbor is coarser, then
10028  // it has no children. however, in 3d it might be
10029  // otherwise. consider for example, that our face
10030  // might be refined with cut_x, but the neighbor is
10031  // refined with cut_xy at that face. then the
10032  // neighbor pointers of the children of our cell
10033  // will point to the common neighbor cell, not to
10034  // its children. what we really want to know in the
10035  // following is, whether the neighbor cell is
10036  // refined twice with reference to our cell. that
10037  // only has to be asked, if the child's neighbor is
10038  // not a coarser one.
10039  if ((child_neighbor->has_children() &&
10040  !child_neighbor->user_flag_set()) ||
10041  // neighbor has children, which are further
10042  // refined along the face, otherwise something
10043  // went wrong in the construction of neighbor
10044  // pointers. then only allow coarsening if this
10045  // neighbor will be coarsened as well
10046  // (user_pointer is set). the same applies, if
10047  // the neighbors children are not refined but
10048  // will be after refinement
10049  child_neighbor->refine_flag_set())
10050  return false;
10051  }
10052  }
10053  return true;
10054  }
10055  };
10056 
10057 
10058 
10059  template <int dim, int spacedim>
10060  const Manifold<dim, spacedim> &
10061  get_default_flat_manifold()
10062  {
10063  static const FlatManifold<dim, spacedim> flat_manifold;
10064  return flat_manifold;
10065  }
10066  } // namespace TriangulationImplementation
10067 } // namespace internal
10068 
10069 
10070 
10071 template <int dim, int spacedim>
10072 const unsigned int Triangulation<dim, spacedim>::dimension;
10073 
10074 
10075 
10076 template <int dim, int spacedim>
10078  const MeshSmoothing smooth_grid,
10079  const bool check_for_distorted_cells)
10080  : smooth_grid(smooth_grid)
10081  , anisotropic_refinement(false)
10082  , check_for_distorted_cells(check_for_distorted_cells)
10083 {
10084  if (dim == 1)
10085  {
10087  std_cxx14::make_unique<std::map<unsigned int, types::boundary_id>>();
10089  std_cxx14::make_unique<std::map<unsigned int, types::manifold_id>>();
10090  }
10091 
10092  // connect the any_change signal to the other top level signals
10093  signals.create.connect(signals.any_change);
10095  signals.clear.connect(signals.any_change);
10097 }
10098 
10099 
10100 
10101 template <int dim, int spacedim>
10103  Triangulation<dim, spacedim> &&tria) noexcept
10104  : Subscriptor(std::move(tria))
10105  , smooth_grid(tria.smooth_grid)
10106  , periodic_face_pairs_level_0(std::move(tria.periodic_face_pairs_level_0))
10107  , periodic_face_map(std::move(tria.periodic_face_map))
10108  , levels(std::move(tria.levels))
10109  , faces(std::move(tria.faces))
10110  , vertices(std::move(tria.vertices))
10111  , vertices_used(std::move(tria.vertices_used))
10112  , manifold(std::move(tria.manifold))
10113  , anisotropic_refinement(tria.anisotropic_refinement)
10114  , check_for_distorted_cells(tria.check_for_distorted_cells)
10115  , number_cache(std::move(tria.number_cache))
10116  , vertex_to_boundary_id_map_1d(std::move(tria.vertex_to_boundary_id_map_1d))
10117  , vertex_to_manifold_id_map_1d(std::move(tria.vertex_to_manifold_id_map_1d))
10118 {
10120 }
10121 
10122 
10123 template <int dim, int spacedim>
10127 {
10128  Subscriptor::operator=(std::move(tria));
10129 
10130  smooth_grid = tria.smooth_grid;
10131  periodic_face_pairs_level_0 = std::move(tria.periodic_face_pairs_level_0);
10132  periodic_face_map = std::move(tria.periodic_face_map);
10133  levels = std::move(tria.levels);
10134  faces = std::move(tria.faces);
10135  vertices = std::move(tria.vertices);
10136  vertices_used = std::move(tria.vertices_used);
10137  manifold = std::move(tria.manifold);
10138  anisotropic_refinement = tria.anisotropic_refinement;
10139  number_cache = tria.number_cache;
10140  vertex_to_boundary_id_map_1d = std::move(tria.vertex_to_boundary_id_map_1d);
10141  vertex_to_manifold_id_map_1d = std::move(tria.vertex_to_manifold_id_map_1d);
10142 
10144 
10145  return *this;
10146 }
10147 
10148 
10149 
10150 template <int dim, int spacedim>
10152 {
10153  // notify listeners that the triangulation is going down...
10154  try
10155  {
10156  signals.clear();
10157  }
10158  catch (...)
10159  {}
10160 
10161  levels.clear();
10162 
10163  // the vertex_to_boundary_id_map_1d field should be unused except in
10164  // 1d. double check this here, as destruction is a good place to
10165  // ensure that what we've done over the course of the lifetime of
10166  // this object makes sense
10167  AssertNothrow((dim == 1) || (vertex_to_boundary_id_map_1d == nullptr),
10168  ExcInternalError());
10169 
10170  // the vertex_to_manifold_id_map_1d field should be also unused
10171  // except in 1d. check this as well
10172  AssertNothrow((dim == 1) || (vertex_to_manifold_id_map_1d == nullptr),
10173  ExcInternalError());
10174 }
10175 
10176 
10177 
10178 template <int dim, int spacedim>
10179 void
10181 {
10182  // notify listeners that the triangulation is going down...
10183  signals.clear();
10184 
10185  // ...and then actually clear all content of it
10186  clear_despite_subscriptions();
10187  periodic_face_pairs_level_0.clear();
10188  periodic_face_map.clear();
10189 }
10190 
10191 
10192 
10193 template <int dim, int spacedim>
10194 void
10196  const MeshSmoothing mesh_smoothing)
10197 {
10198  Assert(n_levels() == 0,
10199  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
10200  smooth_grid = mesh_smoothing;
10201 }
10202 
10203 
10204 
10205 template <int dim, int spacedim>
10208 {
10209  return smooth_grid;
10210 }
10211 
10212 
10213 
10214 template <int dim, int spacedim>
10215 void
10217  const types::manifold_id m_number,
10218  const Manifold<dim, spacedim> &manifold_object)
10219 {
10220  Assert(m_number < numbers::flat_manifold_id,
10222 
10223  manifold[m_number] = manifold_object.clone();
10224 }
10225 
10226 
10227 
10228 template <int dim, int spacedim>
10229 void
10231 {
10232  reset_manifold(m_number);
10233 }
10234 
10235 
10236 template <int dim, int spacedim>
10237 void
10239 {
10240  Assert(m_number < numbers::flat_manifold_id,
10242 
10243  // delete the entry located at number.
10244  manifold.erase(m_number);
10245 }
10246 
10247 
10248 template <int dim, int spacedim>
10249 void
10251 {
10252  manifold.clear();
10253 }
10254 
10255 
10256 template <int dim, int spacedim>
10257 void
10259  const types::manifold_id m_number)
10260 {
10261  Assert(
10262  n_cells() > 0,
10263  ExcMessage(
10264  "Error: set_all_manifold_ids() can not be called on an empty Triangulation."));
10265 
10267  cell = this->begin_active(),
10268  endc = this->end();
10269 
10270  for (; cell != endc; ++cell)
10271  cell->set_all_manifold_ids(m_number);
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_on_boundary() 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  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
10291  if (cell->face(f)->at_boundary())
10292  cell->face(f)->set_all_manifold_ids(m_number);
10293 }
10294 
10295 
10296 template <int dim, int spacedim>
10297 void
10299  const types::boundary_id b_id,
10300  const types::manifold_id m_number)
10301 {
10302  Assert(
10303  n_cells() > 0,
10304  ExcMessage(
10305  "Error: set_all_manifold_ids_on_boundary() can not be called on an empty Triangulation."));
10306 
10307  bool boundary_found = false;
10309  cell = this->begin_active(),
10310  endc = this->end();
10311 
10312  for (; cell != endc; ++cell)
10313  {
10314  // loop on faces
10315  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
10316  if (cell->face(f)->at_boundary() &&
10317  cell->face(f)->boundary_id() == b_id)
10318  {
10319  boundary_found = true;
10320  cell->face(f)->set_manifold_id(m_number);
10321  }
10322 
10323  // loop on edges if dim >= 3
10324  if (dim >= 3)
10325  for (unsigned int e = 0; e < GeometryInfo<dim>::lines_per_cell; ++e)
10326  if (cell->line(e)->at_boundary() &&
10327  cell->line(e)->boundary_id() == b_id)
10328  {
10329  boundary_found = true;
10330  cell->line(e)->set_manifold_id(m_number);
10331  }
10332  }
10333 
10334  (void)boundary_found;
10335  Assert(boundary_found, ExcBoundaryIdNotFound(b_id));
10336 }
10337 
10338 
10339 
10340 template <int dim, int spacedim>
10343  const types::manifold_id m_number) const
10344 {
10345  // look, if there is a manifold stored at
10346  // manifold_id number.
10347  const auto it = manifold.find(m_number);
10348 
10349  if (it != manifold.end())
10350  {
10351  // if we have found an entry, return it
10352  return *(it->second);
10353  }
10354 
10355  // if we have not found an entry connected with number, we return
10356  // the default (flat) manifold
10357  return internal::TriangulationImplementation::
10358  get_default_flat_manifold<dim, spacedim>();
10359 }
10360 
10361 
10362 
10363 template <int dim, int spacedim>
10364 std::vector<types::boundary_id>
10366 {
10367  // in 1d, we store a map of all used boundary indicators. use it for
10368  // our purposes
10369  if (dim == 1)
10370  {
10371  std::vector<types::boundary_id> boundary_ids;
10372  for (std::map<unsigned int, types::boundary_id>::const_iterator p =
10373  vertex_to_boundary_id_map_1d->begin();
10374  p != vertex_to_boundary_id_map_1d->end();
10375  ++p)
10376  boundary_ids.push_back(p->second);
10377 
10378  return boundary_ids;
10379  }
10380  else
10381  {
10382  std::set<types::boundary_id> b_ids;
10383  active_cell_iterator cell = begin_active();
10384  for (; cell != end(); ++cell)
10385  for (unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
10386  ++face)
10387  if (cell->at_boundary(face))
10388  b_ids.insert(cell->face(face)->boundary_id());
10389  std::vector<types::boundary_id> boundary_ids(b_ids.begin(), b_ids.end());
10390  return boundary_ids;
10391  }
10392 }
10393 
10394 
10395 
10396 template <int dim, int spacedim>
10397 std::vector<types::manifold_id>
10399 {
10400  std::set<types::manifold_id> m_ids;
10401  active_cell_iterator cell = begin_active();
10402  for (; cell != end(); ++cell)
10403  {
10404  m_ids.insert(cell->manifold_id());
10405  if (dim > 1)
10406  for (unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
10407  ++face)
10408  if (cell->at_boundary(face))
10409  m_ids.insert(cell->face(face)->manifold_id());
10410  }
10411  std::vector<types::manifold_id> manifold_indicators(m_ids.begin(),
10412  m_ids.end());
10413  return manifold_indicators;
10414 }
10415 
10416 /*-----------------------------------------------------------------*/
10417 
10418 
10419 template <int dim, int spacedim>
10420 void
10422  const Triangulation<dim, spacedim> &other_tria)
10423 {
10424  Assert((vertices.size() == 0) && (levels.size() == 0) && (faces == nullptr),
10425  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
10426  Assert((other_tria.levels.size() != 0) && (other_tria.vertices.size() != 0) &&
10427  (dim == 1 || other_tria.faces != nullptr),
10428  ExcMessage(
10429  "When calling Triangulation::copy_triangulation(), "
10430  "the target triangulation must be empty but the source "
10431  "triangulation (the argument to this function) must contain "
10432  "something. Here, it seems like the source does not "
10433  "contain anything at all."));
10434 
10435 
10436  // copy normal elements
10437  vertices = other_tria.vertices;
10438  vertices_used = other_tria.vertices_used;
10439  anisotropic_refinement = other_tria.anisotropic_refinement;
10440  smooth_grid = other_tria.smooth_grid;
10441 
10442  if (dim > 1)
10443  faces = std_cxx14::make_unique<
10445 
10446  auto bdry_iterator = other_tria.manifold.begin();
10447  for (; bdry_iterator != other_tria.manifold.end(); ++bdry_iterator)
10448  manifold[bdry_iterator->first] = bdry_iterator->second->clone();
10449 
10450 
10451  levels.reserve(other_tria.levels.size());
10452  for (unsigned int level = 0; level < other_tria.levels.size(); ++level)
10453  levels.push_back(std_cxx14::make_unique<
10455  *other_tria.levels[level]));
10456 
10457  number_cache = other_tria.number_cache;
10458 
10459  if (dim == 1)
10460  {
10461  vertex_to_boundary_id_map_1d =
10462  std_cxx14::make_unique<std::map<unsigned int, types::boundary_id>>(
10463  *other_tria.vertex_to_boundary_id_map_1d);
10464 
10465  vertex_to_manifold_id_map_1d =
10466  std_cxx14::make_unique<std::map<unsigned int, types::manifold_id>>(
10467  *other_tria.vertex_to_manifold_id_map_1d);
10468  }
10469 
10470  // inform those who are listening on other_tria of the copy operation
10471  other_tria.signals.copy(*this);
10472  // also inform all listeners of the current triangulation that the
10473  // triangulation has been created
10474  signals.create();
10475 
10476  // note that we need not copy the
10477  // subscriptor!
10478 }
10479 
10480 
10481 
10482 template <int dim, int spacedim>
10483 void
10485  const std::vector<Point<spacedim>> &v,
10486  const std::vector<CellData<dim>> & cells,
10487  const SubCellData & subcelldata)
10488 {
10489  std::vector<CellData<dim>> reordered_cells(cells); // NOLINT
10490  SubCellData reordered_subcelldata(subcelldata); // NOLINT
10491 
10492  // in-place reordering of data
10493  reorder_compatibility(reordered_cells, reordered_subcelldata);
10494 
10495  // now create triangulation from
10496  // reordered data
10497  create_triangulation(v, reordered_cells, reordered_subcelldata);
10498 }
10499 
10500 
10501 
10502 template <int dim, int spacedim>
10503 void
10505  const std::vector<Point<spacedim>> &v,
10506  const std::vector<CellData<dim>> & cells,
10507  const SubCellData & subcelldata)
10508 {
10509  Assert((vertices.size() == 0) && (levels.size() == 0) && (faces == nullptr),
10510  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
10511  // check that no forbidden arrays
10512  // are used
10513  Assert(subcelldata.check_consistency(dim), ExcInternalError());
10514 
10515  // try to create a triangulation; if this fails, we still want to
10516  // throw an exception but if we just do so we'll get into trouble
10517  // because sometimes other objects are already attached to it:
10518  try
10519  {
10521  create_triangulation(v, cells, subcelldata, *this);
10522  }
10523  catch (...)
10524  {
10525  clear_despite_subscriptions();
10526  throw;
10527  }
10528 
10529  // update our counts of the various elements of a triangulation, and set
10530  // active_cell_indices of all cells
10532  *this, levels.size(), number_cache);
10533  reset_active_cell_indices();
10534 
10535  // now verify that there are indeed no distorted cells. as per the
10536  // documentation of this class, we first collect all distorted cells
10537  // and then throw an exception if there are any
10538  if (check_for_distorted_cells == true)
10539  {
10540  DistortedCellList distorted_cells = collect_distorted_coarse_cells(*this);
10541  // throw the array (and fill the various location fields) if
10542  // there are distorted cells. otherwise, just fall off the end
10543  // of the function
10544  AssertThrow(distorted_cells.distorted_cells.size() == 0, distorted_cells);
10545  }
10546 
10547 
10548  /*
10549  When the triangulation is a manifold (dim < spacedim), the normal field
10550  provided from the map class depends on the order of the vertices.
10551  It may happen that this normal field is discontinuous.
10552  The following code takes care that this is not the case by setting the
10553  cell direction flag on those cell that produce the wrong orientation.
10554 
10555  To determine if 2 neighbours have the same or opposite orientation
10556  we use a table of truth.
10557  Its entries are indexes by the local indices of the common face.
10558  For example if two elements share a face, and this face is
10559  face 0 for element 0 and face 1 for element 1, then
10560  table(0,1) will tell whether the orientation are the same (true) or
10561  opposite (false).
10562 
10563  Even though there may be a combinatorial/graph theory argument to get
10564  this table in any dimension, I tested by hand all the different possible
10565  cases in 1D and 2D to generate the table.
10566 
10567  Assuming that a surface respects the standard orientation for 2d meshes,
10568  the tables of truth are symmetric and their true values are the following
10569  1D curves: (0,1)
10570  2D surface: (0,1),(0,2),(1,3),(2,3)
10571 
10572  We store this data using an n_faces x n_faces full matrix, which is
10573  actually much bigger than the minimal data required, but it makes the code
10574  more readable.
10575 
10576  */
10577  if (dim < spacedim)
10578  {
10581  switch (dim)
10582  {
10583  case 1:
10584  {
10585  bool values[][2] = {{false, true}, {true, false}};
10586  for (unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell;
10587  ++i)
10588  for (unsigned int j = 0; j < GeometryInfo<dim>::faces_per_cell;
10589  ++j)
10590  correct(i, j) = (values[i][j]);
10591  break;
10592  }
10593  case 2:
10594  {
10595  bool values[][4] = {{false, true, true, false},
10596  {true, false, false, true},
10597  {true, false, false, true},
10598  {false, true, true, false}};
10599  for (unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell;
10600  ++i)
10601  for (unsigned int j = 0; j < GeometryInfo<dim>::faces_per_cell;
10602  ++j)
10603  correct(i, j) = (values[i][j]);
10604  break;
10605  }
10606  default:
10607  Assert(false, ExcNotImplemented());
10608  }
10609 
10610 
10611  std::list<active_cell_iterator> this_round, next_round;
10612  active_cell_iterator neighbor;
10613 
10614  this_round.push_back(begin_active());
10615  begin_active()->set_direction_flag(true);
10616  begin_active()->set_user_flag();
10617 
10618  while (this_round.size() > 0)
10619  {
10620  for (typename std::list<active_cell_iterator>::iterator cell =
10621  this_round.begin();
10622  cell != this_round.end();
10623  ++cell)
10624  {
10625  for (unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell;
10626  ++i)
10627  {
10628  if (!((*cell)->face(i)->at_boundary()))
10629  {
10630  neighbor = (*cell)->neighbor(i);
10631 
10632  unsigned int cf = (*cell)->face_index(i);
10633  unsigned int j = 0;
10634  while (neighbor->face_index(j) != cf)
10635  {
10636  ++j;
10637  }
10638 
10639 
10640  // If we already saw this guy, check that everything is
10641  // fine
10642  if (neighbor->user_flag_set())
10643  {
10644  // If we have visited this guy, then the ordering and
10645  // the orientation should agree
10646  Assert(!(correct(i, j) ^
10647  (neighbor->direction_flag() ==
10648  (*cell)->direction_flag())),
10649  ExcNonOrientableTriangulation());
10650  }
10651  else
10652  {
10653  next_round.push_back(neighbor);
10654  neighbor->set_user_flag();
10655  if ((correct(i, j) ^ (neighbor->direction_flag() ==
10656  (*cell)->direction_flag())))
10657  neighbor->set_direction_flag(
10658  !neighbor->direction_flag());
10659  }
10660  }
10661  }
10662  }
10663 
10664  // Before we quit let's check
10665  // that if the triangulation
10666  // is disconnected that we
10667  // still get all cells
10668  if (next_round.size() == 0)
10669  for (active_cell_iterator cell = begin_active(); cell != end();
10670  ++cell)
10671  if (cell->user_flag_set() == false)
10672  {
10673  next_round.push_back(cell);
10674  cell->set_direction_flag(true);
10675  cell->set_user_flag();
10676  break;
10677  }
10678 
10679  this_round = next_round;
10680  next_round.clear();
10681  }
10682  }
10683 
10684  // inform all listeners that the triangulation has been created
10685  signals.create();
10686 }
10687 
10688 
10689 
10690 template <int dim, int spacedim>
10691 void
10693 {
10694  AssertThrow(dim + 1 == spacedim,
10695  ExcMessage("Only works for dim == spacedim-1"));
10696  for (active_cell_iterator cell = begin_active(); cell != end(); ++cell)
10697  cell->set_direction_flag(!cell->direction_flag());
10698 }
10699 
10700 
10701 
10702 template <int dim, int spacedim>
10703 void
10705 {
10706  Assert(n_cells() > 0,
10707  ExcMessage("Error: An empty Triangulation can not be refined."));
10708  active_cell_iterator cell = begin_active(), endc = end();
10709 
10710  for (; cell != endc; ++cell)
10711  {
10712  cell->clear_coarsen_flag();
10713  cell->set_refine_flag();
10714  }
10715 }
10716 
10717 
10718 
10719 template <int dim, int spacedim>
10720 void
10722 {
10723  for (unsigned int i = 0; i < times; ++i)
10724  {
10725  set_all_refine_flags();
10726  execute_coarsening_and_refinement();
10727  }
10728 }
10729 
10730 
10731 
10732 /*-------------------- refine/coarsen flags -------------------------*/
10733 
10734 
10735 
10736 template <int dim, int spacedim>
10737 void
10739 {
10740  v.resize(dim * n_active_cells(), false);
10741  std::vector<bool>::iterator i = v.begin();
10742  active_cell_iterator cell = begin_active(), endc = end();
10743  for (; cell != endc; ++cell)
10744  for (unsigned int j = 0; j < dim; ++j, ++i)
10745  if (cell->refine_flag_set() & (1 << j))
10746  *i = true;
10747 
10748  Assert(i == v.end(), ExcInternalError());
10749 }
10750 
10751 
10752 
10753 template <int dim, int spacedim>
10754 void
10756 {
10757  std::vector<bool> v;
10758  save_refine_flags(v);
10759  write_bool_vector(mn_tria_refine_flags_begin,
10760  v,
10761  mn_tria_refine_flags_end,
10762  out);
10763 }
10764 
10765 
10766 
10767 template <int dim, int spacedim>
10768 void
10770 {
10771  std::vector<bool> v;
10772  read_bool_vector(mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end, in);
10773  load_refine_flags(v);
10774 }
10775 
10776 
10777 
10778 template <int dim, int spacedim>
10779 void
10781 {
10782  AssertThrow(v.size() == dim * n_active_cells(), ExcGridReadError());
10783 
10784  active_cell_iterator cell = begin_active(), endc = end();
10785  std::vector<bool>::const_iterator i = v.begin();
10786  for (; cell != endc; ++cell)
10787  {
10788  unsigned int ref_case = 0;
10789 
10790  for (unsigned int j = 0; j < dim; ++j, ++i)
10791  if (*i == true)
10792  ref_case += 1 << j;
10794  ExcGridReadError());
10795  if (ref_case > 0)
10796  cell->set_refine_flag(RefinementCase<dim>(ref_case));
10797  else
10798  cell->clear_refine_flag();
10799  }
10800 
10801  Assert(i == v.end(), ExcInternalError());
10802 }
10803 
10804 
10805 
10806 template <int dim, int spacedim>
10807 void
10809 {
10810  v.resize(n_active_cells(), false);
10811  std::vector<bool>::iterator i = v.begin();
10812  active_cell_iterator cell = begin_active(), endc = end();
10813  for (; cell != endc; ++cell, ++i)
10814  *i = cell->coarsen_flag_set();
10815 
10816  Assert(i == v.end(), ExcInternalError());
10817 }
10818 
10819 
10820 
10821 template <int dim, int spacedim>
10822 void
10824 {
10825  std::vector<bool> v;
10826  save_coarsen_flags(v);
10827  write_bool_vector(mn_tria_coarsen_flags_begin,
10828  v,
10829  mn_tria_coarsen_flags_end,
10830  out);
10831 }
10832 
10833 
10834 
10835 template <int dim, int spacedim>
10836 void
10838 {
10839  std::vector<bool> v;
10840  read_bool_vector(mn_tria_coarsen_flags_begin,
10841  v,
10842  mn_tria_coarsen_flags_end,
10843  in);
10844  load_coarsen_flags(v);
10845 }
10846 
10847 
10848 
10849 template <int dim, int spacedim>
10850 void
10852 {
10853  Assert(v.size() == n_active_cells(), ExcGridReadError());
10854 
10855  active_cell_iterator cell = begin_active(), endc = end();
10856  std::vector<bool>::const_iterator i = v.begin();
10857  for (; cell != endc; ++cell, ++i)
10858  if (*i == true)
10859  cell->set_coarsen_flag();
10860  else
10861  cell->clear_coarsen_flag();
10862 
10863  Assert(i == v.end(), ExcInternalError());
10864 }
10865 
10866 
10867 template <int dim, int spacedim>
10868 bool
10870 {
10871  return anisotropic_refinement;
10872 }
10873 
10874 
10875 
10876 /*-------------------- user data/flags -------------------------*/
10877 
10878 
10879 namespace
10880 {
10881  // clear user data of cells
10882  template <int dim>
10883  void
10884  clear_user_data(
10885  std::vector<
10887  &levels)
10888  {
10889  for (unsigned int level = 0; level < levels.size(); ++level)
10890  levels[level]->cells.clear_user_data();
10891  }
10892 
10893 
10894  // clear user data of faces
10896  {
10897  // nothing to do in 1d
10898  }
10899 
10900 
10901  void
10903  {
10904  faces->lines.clear_user_data();
10905  }
10906 
10907 
10908  void
10910  {
10911  faces->lines.clear_user_data();
10912  faces->quads.clear_user_data();
10913  }
10914 } // namespace
10915 
10916 
10917 template <int dim, int spacedim>
10918 void
10920 {
10921  // let functions in anonymous namespace do their work
10922  ::clear_user_data(levels);
10923  ::clear_user_data(faces.get());
10924 }
10925 
10926 
10927 
10928 namespace
10929 {
10930  void clear_user_flags_line(
10931  std::vector<
10933  &levels,
10935  {
10936  for (const auto &level : levels)
10937  level->cells.clear_user_flags();
10938  }
10939 
10940  template <int dim>
10941  void
10942  clear_user_flags_line(
10943  std::vector<
10946  {
10947  faces->lines.clear_user_flags();
10948  }
10949 } // namespace
10950 
10951 
10952 template <int dim, int spacedim>
10953 void
10955 {
10956  ::clear_user_flags_line(levels, faces.get());
10957 }
10958 
10959 
10960 
10961 namespace
10962 {
10963  void clear_user_flags_quad(
10964  std::vector<
10967  {
10968  // nothing to do in 1d
10969  }
10970 
10971  void clear_user_flags_quad(
10972  std::vector<
10974  &levels,
10976  {
10977  for (const auto &level : levels)
10978  level->cells.clear_user_flags();
10979  }
10980 
10981  template <int dim>
10982  void
10983  clear_user_flags_quad(
10984  std::vector<
10987  {
10988  faces->quads.clear_user_flags();
10989  }
10990 } // namespace
10991 
10992 
10993 template <int dim, int spacedim>
10994 void
10996 {
10997  ::clear_user_flags_quad(levels, faces.get());
10998 }
10999 
11000 
11001 
11002 namespace
11003 {
11004  void clear_user_flags_hex(
11005  std::vector<
11008  {
11009  // nothing to do in 1d
11010  }
11011 
11012 
11013  void clear_user_flags_hex(
11014  std::vector<
11017  {
11018  // nothing to do in 2d
11019  }
11020 
11021  void clear_user_flags_hex(
11022  std::vector<
11024  &levels,
11026  {
11027  for (const auto &level : levels)
11028  level->cells.clear_user_flags();
11029  }
11030 } // namespace
11031 
11032 
11033 template <int dim, int spacedim>
11034 void
11036 {
11037  ::clear_user_flags_hex(levels, faces.get());
11038 }
11039 
11040 
11041 
11042 template <int dim, int spacedim>
11043 void
11045 {
11046  clear_user_flags_line();
11047  clear_user_flags_quad();
11048  clear_user_flags_hex();
11049 }
11050 
11051 
11052 
11053 template <int dim, int spacedim>
11054 void
11056 {
11057  save_user_flags_line(out);
11058 
11059  if (dim >= 2)
11060  save_user_flags_quad(out);
11061 
11062  if (dim >= 3)
11063  save_user_flags_hex(out);
11064 
11065  if (dim >= 4)
11066  Assert(false, ExcNotImplemented());
11067 }
11068 
11069 
11070 
11071 template <int dim, int spacedim>
11072 void
11074 {
11075  // clear vector and append
11076  // all the stuff later on
11077  v.clear();
11078 
11079  std::vector<bool> tmp;
11080 
11081  save_user_flags_line(tmp);
11082  v.insert(v.end(), tmp.begin(), tmp.end());
11083 
11084  if (dim >= 2)
11085  {
11086  save_user_flags_quad(tmp);
11087  v.insert(v.end(), tmp.begin(), tmp.end());
11088  }
11089 
11090  if (dim >= 3)
11091  {
11092  save_user_flags_hex(tmp);
11093  v.insert(v.end(), tmp.begin(), tmp.end());
11094  }
11095 
11096  if (dim >= 4)
11097  Assert(false, ExcNotImplemented());
11098 }
11099 
11100 
11101 
11102 template <int dim, int spacedim>
11103 void
11105 {
11106  load_user_flags_line(in);
11107 
11108  if (dim >= 2)
11109  load_user_flags_quad(in);
11110 
11111  if (dim >= 3)
11112  load_user_flags_hex(in);
11113 
11114  if (dim >= 4)
11115  Assert(false, ExcNotImplemented());
11116 }
11117 
11118 
11119 
11120 template <int dim, int spacedim>
11121 void
11123 {
11124  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
11125  std::vector<bool> tmp;
11126 
11127  // first extract the flags
11128  // belonging to lines
11129  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
11130  // and set the lines
11131  load_user_flags_line(tmp);
11132 
11133  if (dim >= 2)
11134  {
11135  tmp.clear();
11136  tmp.insert(tmp.end(),
11137  v.begin() + n_lines(),
11138  v.begin() + n_lines() + n_quads());
11139  load_user_flags_quad(tmp);
11140  }
11141 
11142  if (dim >= 3)
11143  {
11144  tmp.clear();
11145  tmp.insert(tmp.end(),
11146  v.begin() + n_lines() + n_quads(),
11147  v.begin() + n_lines() + n_quads() + n_hexs());
11148  load_user_flags_hex(tmp);
11149  }
11150 
11151  if (dim >= 4)
11152  Assert(false, ExcNotImplemented());
11153 }
11154 
11155 
11156 
11157 template <int dim, int spacedim>
11158 void
11160 {
11161  v.resize(n_lines(), false);
11162  std::vector<bool>::iterator i = v.begin();
11163  line_iterator line = begin_line(), endl = end_line();
11164  for (; line != endl; ++line, ++i)
11165  *i = line->user_flag_set();
11166 
11167  Assert(i == v.end(), ExcInternalError());
11168 }
11169 
11170 
11171 
11172 template <int dim, int spacedim>
11173 void
11175 {
11176  std::vector<bool> v;
11177  save_user_flags_line(v);
11178  write_bool_vector(mn_tria_line_user_flags_begin,
11179  v,
11180  mn_tria_line_user_flags_end,
11181  out);
11182 }
11183 
11184 
11185 
11186 template <int dim, int spacedim>
11187 void
11189 {
11190  std::vector<bool> v;
11191  read_bool_vector(mn_tria_line_user_flags_begin,
11192  v,
11193  mn_tria_line_user_flags_end,
11194  in);
11195  load_user_flags_line(v);
11196 }
11197 
11198 
11199 
11200 template <int dim, int spacedim>
11201 void
11203 {
11204  Assert(v.size() == n_lines(), ExcGridReadError());
11205 
11206  line_iterator line = begin_line(), endl = end_line();
11207  std::vector<bool>::const_iterator i = v.begin();
11208  for (; line != endl; ++line, ++i)
11209  if (*i == true)
11210  line->set_user_flag();
11211  else
11212  line->clear_user_flag();
11213 
11214  Assert(i == v.end(), ExcInternalError());
11215 }
11216 
11217 
11218 namespace
11219 {
11220  template <typename Iterator>
11221  bool
11222  get_user_flag(const Iterator &i)
11223  {
11224  return i->user_flag_set();
11225  }
11226 
11227 
11228 
11229  template <int structdim, int dim, int spacedim>
11230  bool
11232  {
11233  Assert(false, ExcInternalError());
11234  return false;
11235  }
11236 
11237 
11238 
11239  template <typename Iterator>
11240  void
11241  set_user_flag(const Iterator &i)
11242  {
11243  i->set_user_flag();
11244  }
11245 
11246 
11247 
11248  template <int structdim, int dim, int spacedim>
11249  void
11251  {
11252  Assert(false, ExcInternalError());
11253  }
11254 
11255 
11256 
11257  template <typename Iterator>
11258  void
11259  clear_user_flag(const Iterator &i)
11260  {
11261  i->clear_user_flag();
11262  }
11263 
11264 
11265 
11266  template <int structdim, int dim, int spacedim>
11267  void
11268  clear_user_flag(
11270  {
11271  Assert(false, ExcInternalError());
11272  }
11273 } // namespace
11274 
11275 
11276 template <int dim, int spacedim>
11277 void
11279 {
11280  v.resize(n_quads(), false);
11281 
11282  if (dim >= 2)
11283  {
11284  std::vector<bool>::iterator i = v.begin();
11285  quad_iterator quad = begin_quad(), endq = end_quad();
11286  for (; quad != endq; ++quad, ++i)
11287  *i = get_user_flag(quad);
11288 
11289  Assert(i == v.end(), ExcInternalError());
11290  }
11291 }
11292 
11293 
11294 
11295 template <int dim, int spacedim>
11296 void
11298 {
11299  std::vector<bool> v;
11300  save_user_flags_quad(v);
11301  write_bool_vector(mn_tria_quad_user_flags_begin,
11302  v,
11303  mn_tria_quad_user_flags_end,
11304  out);
11305 }
11306 
11307 
11308 
11309 template <int dim, int spacedim>
11310 void
11312 {
11313  std::vector<bool> v;
11314  read_bool_vector(mn_tria_quad_user_flags_begin,
11315  v,
11316  mn_tria_quad_user_flags_end,
11317  in);
11318  load_user_flags_quad(v);
11319 }
11320 
11321 
11322 
11323 template <int dim, int spacedim>
11324 void
11326 {
11327  Assert(v.size() == n_quads(), ExcGridReadError());
11328 
11329  if (dim >= 2)
11330  {
11331  quad_iterator quad = begin_quad(), endq = end_quad();
11332  std::vector<bool>::const_iterator i = v.begin();
11333  for (; quad != endq; ++quad, ++i)
11334  if (*i == true)
11335  set_user_flag(quad);
11336  else
11337  clear_user_flag(quad);
11338 
11339  Assert(i == v.end(), ExcInternalError());
11340  }
11341 }
11342 
11343 
11344 
11345 template <int dim, int spacedim>
11346 void
11348 {
11349  v.resize(n_hexs(), false);
11350 
11351  if (dim >= 3)
11352  {
11353  std::vector<bool>::iterator i = v.begin();
11354  hex_iterator hex = begin_hex(), endh = end_hex();
11355  for (; hex != endh; ++hex, ++i)
11356  *i = get_user_flag(hex);
11357 
11358  Assert(i == v.end(), ExcInternalError());
11359  }
11360 }
11361 
11362 
11363 
11364 template <int dim, int spacedim>
11365 void
11367 {
11368  std::vector<bool> v;
11369  save_user_flags_hex(v);
11370  write_bool_vector(mn_tria_hex_user_flags_begin,
11371  v,
11372  mn_tria_hex_user_flags_end,
11373  out);
11374 }
11375 
11376 
11377 
11378 template <int dim, int spacedim>
11379 void
11381 {
11382  std::vector<bool> v;
11383  read_bool_vector(mn_tria_hex_user_flags_begin,
11384  v,
11385  mn_tria_hex_user_flags_end,
11386  in);
11387  load_user_flags_hex(v);
11388 }
11389 
11390 
11391 
11392 template <int dim, int spacedim>
11393 void
11395 {
11396  Assert(v.size() == n_hexs(), ExcGridReadError());
11397 
11398  if (dim >= 3)
11399  {
11400  hex_iterator hex = begin_hex(), endh = end_hex();
11401  std::vector<bool>::const_iterator i = v.begin();
11402  for (; hex != endh; ++hex, ++i)
11403  if (*i == true)
11404  set_user_flag(hex);
11405  else
11406  clear_user_flag(hex);
11407 
11408  Assert(i == v.end(), ExcInternalError());
11409  }
11410 }
11411 
11412 
11413 
11414 template <int dim, int spacedim>
11415 void
11417  std::vector<unsigned int> &v) const
11418 {
11419  // clear vector and append all the
11420  // stuff later on
11421  v.clear();
11422 
11423  std::vector<unsigned int> tmp;
11424 
11425  save_user_indices_line(tmp);
11426  v.insert(v.end(), tmp.begin(), tmp.end());
11427 
11428  if (dim >= 2)
11429  {
11430  save_user_indices_quad(tmp);
11431  v.insert(v.end(), tmp.begin(), tmp.end());
11432  }
11433 
11434  if (dim >= 3)
11435  {
11436  save_user_indices_hex(tmp);
11437  v.insert(v.end(), tmp.begin(), tmp.end());
11438  }
11439 
11440  if (dim >= 4)
11441  Assert(false, ExcNotImplemented());
11442 }
11443 
11444 
11445 
11446 template <int dim, int spacedim>
11447 void
11449  const std::vector<unsigned int> &v)
11450 {
11451  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
11452  std::vector<unsigned int> tmp;
11453 
11454  // first extract the indices
11455  // belonging to lines
11456  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
11457  // and set the lines
11458  load_user_indices_line(tmp);
11459 
11460  if (dim >= 2)
11461  {
11462  tmp.clear();
11463  tmp.insert(tmp.end(),
11464  v.begin() + n_lines(),
11465  v.begin() + n_lines() + n_quads());
11466  load_user_indices_quad(tmp);
11467  }
11468 
11469  if (dim >= 3)
11470  {
11471  tmp.clear();
11472  tmp.insert(tmp.end(),
11473  v.begin() + n_lines() + n_quads(),
11474  v.begin() + n_lines() + n_quads() + n_hexs());
11475  load_user_indices_hex(tmp);
11476  }
11477 
11478  if (dim >= 4)
11479  Assert(false, ExcNotImplemented());
11480 }
11481 
11482 
11483 
11484 namespace
11485 {
11486  template <typename Iterator>
11487  unsigned int
11488  get_user_index(const Iterator &i)
11489  {
11490  return i->user_index();
11491  }
11492 
11493 
11494 
11495  template <int structdim, int dim, int spacedim>
11496  unsigned int
11497  get_user_index(
11499  {
11500  Assert(false, ExcInternalError());
11502  }
11503 
11504 
11505 
11506  template <typename Iterator>
11507  void
11508  set_user_index(const Iterator &i, const unsigned int x)
11509  {
11510  i->set_user_index(x);
11511  }
11512 
11513 
11514 
11515  template <int structdim, int dim, int spacedim>
11516  void
11517  set_user_index(
11519  const unsigned int)
11520  {
11521  Assert(false, ExcInternalError());
11522  }
11523 } // namespace
11524 
11525 
11526 template <int dim, int spacedim>
11527 void
11529  std::vector<unsigned int> &v) const
11530 {
11531  v.resize(n_lines(), 0);
11532  std::vector<unsigned int>::iterator i = v.begin();
11533  line_iterator line = begin_line(), endl = end_line();
11534  for (; line != endl; ++line, ++i)
11535  *i = line->user_index();
11536 }
11537 
11538 
11539 
11540 template <int dim, int spacedim>
11541 void
11543  const std::vector<unsigned int> &v)
11544 {
11545  Assert(v.size() == n_lines(), ExcGridReadError());
11546 
11547  line_iterator line = begin_line(), endl = end_line();
11548  std::vector<unsigned int>::const_iterator i = v.begin();
11549  for (; line != endl; ++line, ++i)
11550  line->set_user_index(*i);
11551 }
11552 
11553 
11554 template <int dim, int spacedim>
11555 void
11557  std::vector<unsigned int> &v) const
11558 {
11559  v.resize(n_quads(), 0);
11560 
11561  if (dim >= 2)
11562  {
11563  std::vector<unsigned int>::iterator i = v.begin();
11564  quad_iterator quad = begin_quad(), endq = end_quad();
11565  for (; quad != endq; ++quad, ++i)
11566  *i = get_user_index(quad);
11567  }
11568 }
11569 
11570 
11571 
11572 template <int dim, int spacedim>
11573 void
11575  const std::vector<unsigned int> &v)
11576 {
11577  Assert(v.size() == n_quads(), ExcGridReadError());
11578 
11579  if (dim >= 2)
11580  {
11581  quad_iterator quad = begin_quad(), endq = end_quad();
11582  std::vector<unsigned int>::const_iterator i = v.begin();
11583  for (; quad != endq; ++quad, ++i)
11584  set_user_index(quad, *i);
11585  }
11586 }
11587 
11588 
11589 template <int dim, int spacedim>
11590 void
11592  std::vector<unsigned int> &v) const
11593 {
11594  v.resize(n_hexs(), 0);
11595 
11596  if (dim >= 3)
11597  {
11598  std::vector<unsigned int>::iterator i = v.begin();
11599  hex_iterator hex = begin_hex(), endh = end_hex();
11600  for (; hex != endh; ++hex, ++i)
11601  *i = get_user_index(hex);
11602  }
11603 }
11604 
11605 
11606 
11607 template <int dim, int spacedim>
11608 void
11610  const std::vector<unsigned int> &v)
11611 {
11612  Assert(v.size() == n_hexs(), ExcGridReadError());
11613 
11614  if (dim >= 3)
11615  {
11616  hex_iterator hex = begin_hex(), endh = end_hex();
11617  std::vector<unsigned int>::const_iterator i = v.begin();
11618  for (; hex != endh; ++hex, ++i)
11619  set_user_index(hex, *i);
11620  }
11621 }
11622 
11623 
11624 
11625 //---------------- user pointers ----------------------------------------//
11626 
11627 
11628 namespace
11629 {
11630  template <typename Iterator>
11631  void *
11632  get_user_pointer(const Iterator &i)
11633  {
11634  return i->user_pointer();
11635  }
11636 
11637 
11638 
11639  template <int structdim, int dim, int spacedim>
11640  void *
11641  get_user_pointer(
11643  {
11644  Assert(false, ExcInternalError());
11645  return nullptr;
11646  }
11647 
11648 
11649 
11650  template <typename Iterator>
11651  void
11652  set_user_pointer(const Iterator &i, void *x)
11653  {
11654  i->set_user_pointer(x);
11655  }
11656 
11657 
11658 
11659  template <int structdim, int dim, int spacedim>
11660  void
11661  set_user_pointer(
11663  void *)
11664  {
11665  Assert(false, ExcInternalError());
11666  }
11667 } // namespace
11668 
11669 
11670 template <int dim, int spacedim>
11671 void
11673 {
11674  // clear vector and append all the
11675  // stuff later on
11676  v.clear();
11677 
11678  std::vector<void *> tmp;
11679 
11680  save_user_pointers_line(tmp);
11681  v.insert(v.end(), tmp.begin(), tmp.end());
11682 
11683  if (dim >= 2)
11684  {
11685  save_user_pointers_quad(tmp);
11686  v.insert(v.end(), tmp.begin(), tmp.end());
11687  }
11688 
11689  if (dim >= 3)
11690  {
11691  save_user_pointers_hex(tmp);
11692  v.insert(v.end(), tmp.begin(), tmp.end());
11693  }
11694 
11695  if (dim >= 4)
11696  Assert(false, ExcNotImplemented());
11697 }
11698 
11699 
11700 
11701 template <int dim, int spacedim>
11702 void
11704 {
11705  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
11706  std::vector<void *> tmp;
11707 
11708  // first extract the pointers
11709  // belonging to lines
11710  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
11711  // and set the lines
11712  load_user_pointers_line(tmp);
11713 
11714  if (dim >= 2)
11715  {
11716  tmp.clear();
11717  tmp.insert(tmp.end(),
11718  v.begin() + n_lines(),
11719  v.begin() + n_lines() + n_quads());
11720  load_user_pointers_quad(tmp);
11721  }
11722 
11723  if (dim >= 3)
11724  {
11725  tmp.clear();
11726  tmp.insert(tmp.end(),
11727  v.begin() + n_lines() + n_quads(),
11728  v.begin() + n_lines() + n_quads() + n_hexs());
11729  load_user_pointers_hex(tmp);
11730  }
11731 
11732  if (dim >= 4)
11733  Assert(false, ExcNotImplemented());
11734 }
11735 
11736 
11737 
11738 template <int dim, int spacedim>
11739 void
11741  std::vector<void *> &v) const
11742 {
11743  v.resize(n_lines(), nullptr);
11744  std::vector<void *>::iterator i = v.begin();
11745  line_iterator line = begin_line(), endl = end_line();
11746  for (; line != endl; ++line, ++i)
11747  *i = line->user_pointer();
11748 }
11749 
11750 
11751 
11752 template <int dim, int spacedim>
11753 void
11755  const std::vector<void *> &v)
11756 {
11757  Assert(v.size() == n_lines(), ExcGridReadError());
11758 
11759  line_iterator line = begin_line(), endl = end_line();
11760  std::vector<void *>::const_iterator i = v.begin();
11761  for (; line != endl; ++line, ++i)
11762  line->set_user_pointer(*i);
11763 }
11764 
11765 
11766 
11767 template <int dim, int spacedim>
11768 void
11770  std::vector<void *> &v) const
11771 {
11772  v.resize(n_quads(), nullptr);
11773 
11774  if (dim >= 2)
11775  {
11776  std::vector<void *>::iterator i = v.begin();
11777  quad_iterator quad = begin_quad(), endq = end_quad();
11778  for (; quad != endq; ++quad, ++i)
11779  *i = get_user_pointer(quad);
11780  }
11781 }
11782 
11783 
11784 
11785 template <int dim, int spacedim>
11786 void
11788  const std::vector<void *> &v)
11789 {
11790  Assert(v.size() == n_quads(), ExcGridReadError());
11791 
11792  if (dim >= 2)
11793  {
11794  quad_iterator quad = begin_quad(), endq = end_quad();
11795  std::vector<void *>::const_iterator i = v.begin();
11796  for (; quad != endq; ++quad, ++i)
11797  set_user_pointer(quad, *i);
11798  }
11799 }
11800 
11801 
11802 template <int dim, int spacedim>
11803 void
11805  std::vector<void *> &v) const
11806 {
11807  v.resize(n_hexs(), nullptr);
11808 
11809  if (dim >= 3)
11810  {
11811  std::vector<void *>::iterator i = v.begin();
11812  hex_iterator hex = begin_hex(), endh = end_hex();
11813  for (; hex != endh; ++hex, ++i)
11814  *i = get_user_pointer(hex);
11815  }
11816 }
11817 
11818 
11819 
11820 template <int dim, int spacedim>
11821 void
11823  const std::vector<void *> &v)
11824 {
11825  Assert(v.size() == n_hexs(), ExcGridReadError());
11826 
11827  if (dim >= 3)
11828  {
11829  hex_iterator hex = begin_hex(), endh = end_hex();
11830  std::vector<void *>::const_iterator i = v.begin();
11831  for (; hex != endh; ++hex, ++i)
11832  set_user_pointer(hex, *i);
11833  }
11834 }
11835 
11836 
11837 
11838 /*------------------------ Cell iterator functions ------------------------*/
11839 
11840 
11841 template <int dim, int spacedim>
11843 Triangulation<dim, spacedim>::begin_raw(const unsigned int level) const
11844 {
11845  switch (dim)
11846  {
11847  case 1:
11848  return begin_raw_line(level);
11849  case 2:
11850  return begin_raw_quad(level);
11851  case 3:
11852  return begin_raw_hex(level);
11853  default:
11854  Assert(false, ExcNotImplemented());
11855  return raw_cell_iterator();
11856  }
11857 }
11858 
11859 
11860 
11861 template <int dim, int spacedim>
11863 Triangulation<dim, spacedim>::begin(const unsigned int level) const
11864 {
11865  switch (dim)
11866  {
11867  case 1:
11868  return begin_line(level);
11869  case 2:
11870  return begin_quad(level);
11871  case 3:
11872  return begin_hex(level);
11873  default:
11874  Assert(false, ExcImpossibleInDim(dim));
11875  return cell_iterator();
11876  }
11877 }
11878 
11879 
11880 
11881 template <int dim, int spacedim>
11883 Triangulation<dim, spacedim>::begin_active(const unsigned int level) const
11884 {
11885  switch (dim)
11886  {
11887  case 1:
11888  return begin_active_line(level);
11889  case 2:
11890  return begin_active_quad(level);
11891  case 3:
11892  return begin_active_hex(level);
11893  default:
11894  Assert(false, ExcNotImplemented());
11895  return active_cell_iterator();
11896  }
11897 }
11898 
11899 
11900 
11901 template <int dim, int spacedim>
11904 {
11905  const unsigned int level = levels.size() - 1;
11906  if (levels[level]->cells.cells.size() == 0)
11907  return end(level);
11908 
11909  // find the last raw iterator on
11910  // this level
11911  raw_cell_iterator ri(const_cast<Triangulation<dim, spacedim> *>(this),
11912  level,
11913  levels[level]->cells.cells.size() - 1);
11914 
11915  // then move to the last used one
11916  if (ri->used() == true)
11917  return ri;
11918  while ((--ri).state() == IteratorState::valid)
11919  if (ri->used() == true)
11920  return ri;
11921  return ri;
11922 }
11923 
11924 
11925 
11926 template <int dim, int spacedim>
11929 {
11930  // get the last used cell
11931  cell_iterator cell = last();
11932 
11933  if (cell != end())
11934  {
11935  // then move to the last active one
11936  if (cell->active() == true)
11937  return cell;
11938  while ((--cell).state() == IteratorState::valid)
11939  if (cell->active() == true)
11940  return cell;
11941  }
11942  return cell;
11943 }
11944 
11945 
11946 
11947 template <int dim, int spacedim>
11950 {
11951  return cell_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
11952  -1,
11953  -1);
11954 }
11955 
11956 
11957 
11958 template <int dim, int spacedim>
11960 Triangulation<dim, spacedim>::end_raw(const unsigned int level) const
11961 {
11962  // This function may be called on parallel triangulations on levels
11963  // that exist globally, but not on the local portion of the
11964  // triangulation. In that case, just return the end iterator.
11965  //
11966  // We need to use levels.size() instead of n_levels() because the
11967  // latter function uses the cache, but we need to be able to call
11968  // this function at a time when the cache is not currently up to
11969  // date.
11970  if (level >= levels.size())
11971  {
11972  Assert(level < n_global_levels(),
11973  ExcInvalidLevel(level, n_global_levels()));
11974  return end();
11975  }
11976 
11977  // Query whether the given level is valid for the local portion of the
11978  // triangulation.
11979  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
11980  if (level < levels.size() - 1)
11981  return begin_raw(level + 1);
11982  else
11983  return end();
11984 }
11985 
11986 
11987 template <int dim, int spacedim>
11989 Triangulation<dim, spacedim>::end(const unsigned int level) const
11990 {
11991  // This function may be called on parallel triangulations on levels
11992  // that exist globally, but not on the local portion of the
11993  // triangulation. In that case, just retrn the end iterator.
11994  //
11995  // We need to use levels.size() instead of n_levels() because the
11996  // latter function uses the cache, but we need to be able to call
11997  // this function at a time when the cache is not currently up to
11998  // date.
11999  if (level >= levels.size())
12000  {
12001  Assert(level < n_global_levels(),
12002  ExcInvalidLevel(level, n_global_levels()));
12003  return end();
12004  }
12005 
12006  // Query whether the given level is valid for the local portion of the
12007  // triangulation.
12008  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12009  if (level < levels.size() - 1)
12010  return begin(level + 1);
12011  else
12012  return end();
12013 }
12014 
12015 
12016 template <int dim, int spacedim>
12018 Triangulation<dim, spacedim>::end_active(const unsigned int level) const
12019 {
12020  // This function may be called on parallel triangulations on levels
12021  // that exist globally, but not on the local portion of the
12022  // triangulation. In that case, just return the end iterator.
12023  //
12024  // We need to use levels.size() instead of n_levels() because the
12025  // latter function uses the cache, but we need to be able to call
12026  // this function at a time when the cache is not currently up to
12027  // date.
12028  if (level >= levels.size())
12029  {
12030  Assert(level < n_global_levels(),
12031  ExcInvalidLevel(level, n_global_levels()));
12032  return end();
12033  }
12034 
12035  // Query whether the given level is valid for the local portion of the
12036  // triangulation.
12037  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12038  return (level >= levels.size() - 1 ? active_cell_iterator(end()) :
12039  begin_active(level + 1));
12040 }
12041 
12042 
12043 
12044 template <int dim, int spacedim>
12047 {
12049  begin(), end());
12050 }
12051 
12052 
12053 template <int dim, int spacedim>
12056 {
12057  return IteratorRange<
12058  typename Triangulation<dim, spacedim>::active_cell_iterator>(begin_active(),
12059  end());
12060 }
12061 
12062 
12063 
12064 template <int dim, int spacedim>
12067  const unsigned int level) const
12068 {
12070  begin(level), end(level));
12071 }
12072 
12073 
12074 
12075 template <int dim, int spacedim>
12078  const unsigned int level) const
12079 {
12080  return IteratorRange<
12082  begin_active(level), end_active(level));
12083 }
12084 
12085 
12086 /*------------------------ Face iterator functions ------------------------*/
12087 
12088 
12089 template <int dim, int spacedim>
12092 {
12093  switch (dim)
12094  {
12095  case 1:
12096  Assert(false, ExcImpossibleInDim(1));
12097  return raw_face_iterator();
12098  case 2:
12099  return begin_line();
12100  case 3:
12101  return begin_quad();
12102  default:
12103  Assert(false, ExcNotImplemented());
12104  return face_iterator();
12105  }
12106 }
12107 
12108 
12109 
12110 template <int dim, int spacedim>
12113 {
12114  switch (dim)
12115  {
12116  case 1:
12117  Assert(false, ExcImpossibleInDim(1));
12118  return raw_face_iterator();
12119  case 2:
12120  return begin_active_line();
12121  case 3:
12122  return begin_active_quad();
12123  default:
12124  Assert(false, ExcNotImplemented());
12125  return active_face_iterator();
12126  }
12127 }
12128 
12129 
12130 
12131 template <int dim, int spacedim>
12134 {
12135  switch (dim)
12136  {
12137  case 1:
12138  Assert(false, ExcImpossibleInDim(1));
12139  return raw_face_iterator();
12140  case 2:
12141  return end_line();
12142  case 3:
12143  return end_quad();
12144  default:
12145  Assert(false, ExcNotImplemented());
12146  return raw_face_iterator();
12147  }
12148 }
12149 
12150 
12151 
12152 template <int dim, int spacedim>
12155 {
12156  return IteratorRange<
12158  begin_active_face(), end_face());
12159 }
12160 
12161 /*------------------------ Vertex iterator functions ------------------------*/
12162 
12163 
12164 template <int dim, int spacedim>
12167 {
12168  vertex_iterator i =
12169  raw_vertex_iterator(const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
12170  if (i.state() != IteratorState::valid)
12171  return i;
12172  // This loop will end because every triangulation has used vertices.
12173  while (i->used() == false)
12174  if ((++i).state() != IteratorState::valid)
12175  return i;
12176  return i;
12177 }
12178 
12179 
12180 
12181 template <int dim, int spacedim>
12184 {
12185  // every vertex is active
12186  return begin_vertex();
12187 }
12188 
12189 
12190 
12191 template <int dim, int spacedim>
12194 {
12195  return raw_vertex_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12196  -1,
12198 }
12199 
12200 
12201 
12202 /*------------------------ Line iterator functions ------------------------*/
12203 
12204 
12205 
12206 template <int dim, int spacedim>
12207 typename Triangulation<dim, spacedim>::raw_line_iterator
12208 Triangulation<dim, spacedim>::begin_raw_line(const unsigned int level) const
12209 {
12210  // This function may be called on parallel triangulations on levels
12211  // that exist globally, but not on the local portion of the
12212  // triangulation. In that case, just return the end iterator.
12213  //
12214  // We need to use levels.size() instead of n_levels() because the
12215  // latter function uses the cache, but we need to be able to call
12216  // this function at a time when the cache is not currently up to
12217  // date.
12218  if (level >= levels.size())
12219  {
12220  Assert(level < n_global_levels(),
12221  ExcInvalidLevel(level, n_global_levels()));
12222  return end_line();
12223  }
12224 
12225  switch (dim)
12226  {
12227  case 1:
12228  // Query whether the given level is valid for the local portion of the
12229  // triangulation.
12230  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12231 
12232  if (level >= levels.size() || levels[level]->cells.cells.size() == 0)
12233  return end_line();
12234 
12235  return raw_line_iterator(
12236  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
12237 
12238  default:
12239  Assert(level == 0, ExcFacesHaveNoLevel());
12240  return raw_line_iterator(
12241  const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
12242  }
12243 }
12244 
12245 
12246 template <int dim, int spacedim>
12248 Triangulation<dim, spacedim>::begin_line(const unsigned int level) const
12249 {
12250  // level is checked in begin_raw
12251  raw_line_iterator ri = begin_raw_line(level);
12252  if (ri.state() != IteratorState::valid)
12253  return ri;
12254  while (ri->used() == false)
12255  if ((++ri).state() != IteratorState::valid)
12256  return ri;
12257  return ri;
12258 }
12259 
12260 
12261 
12262 template <int dim, int spacedim>
12265 {
12266  // level is checked in begin_raw
12267  line_iterator i = begin_line(level);
12268  if (i.state() != IteratorState::valid)
12269  return i;
12270  while (i->has_children())
12271  if ((++i).state() != IteratorState::valid)
12272  return i;
12273  return i;
12274 }
12275 
12276 
12277 
12278 template <int dim, int spacedim>
12281 {
12282  return raw_line_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12283  -1,
12284  -1);
12285 }
12286 
12287 
12288 
12289 /*------------------------ Quad iterator functions ------------------------*/
12290 
12291 
12292 template <int dim, int spacedim>
12293 typename Triangulation<dim, spacedim>::raw_quad_iterator
12294 Triangulation<dim, spacedim>::begin_raw_quad(const unsigned int level) const
12295 {
12296  // This function may be called on parallel triangulations on levels
12297  // that exist globally, but not on the local portion of the
12298  // triangulation. In that case, just return the end iterator.
12299  //
12300  // We need to use levels.size() instead of n_levels() because the
12301  // latter function uses the cache, but we need to be able to call
12302  // this function at a time when the cache is not currently up to
12303  // date.
12304  if (level >= levels.size())
12305  {
12306  Assert(level < n_global_levels(),
12307  ExcInvalidLevel(level, n_global_levels()));
12308  return end_quad();
12309  }
12310 
12311  switch (dim)
12312  {
12313  case 1:
12314  Assert(false, ExcImpossibleInDim(1));
12315  return raw_hex_iterator();
12316  case 2:
12317  {
12318  // Query whether the given level is valid for the local portion of the
12319  // triangulation.
12320  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12321 
12322  if (level >= levels.size() || levels[level]->cells.cells.size() == 0)
12323  return end_quad();
12324 
12325  return raw_quad_iterator(
12326  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
12327  }
12328 
12329  case 3:
12330  {
12331  Assert(level == 0, ExcFacesHaveNoLevel());
12332 
12333  return raw_quad_iterator(
12334  const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
12335  }
12336 
12337 
12338  default:
12339  Assert(false, ExcNotImplemented());
12340  return raw_hex_iterator();
12341  }
12342 }
12343 
12344 
12345 
12346 template <int dim, int spacedim>
12348 Triangulation<dim, spacedim>::begin_quad(const unsigned int level) const
12349 {
12350  // level is checked in begin_raw
12351  raw_quad_iterator ri = begin_raw_quad(level);
12352  if (ri.state() != IteratorState::valid)
12353  return ri;
12354  while (ri->used() == false)
12355  if ((++ri).state() != IteratorState::valid)
12356  return ri;
12357  return ri;
12358 }
12359 
12360 
12361 
12362 template <int dim, int spacedim>
12365 {
12366  // level is checked in begin_raw
12367  quad_iterator i = begin_quad(level);
12368  if (i.state() != IteratorState::valid)
12369  return i;
12370  while (i->has_children())
12371  if ((++i).state() != IteratorState::valid)
12372  return i;
12373  return i;
12374 }
12375 
12376 
12377 
12378 template <int dim, int spacedim>
12381 {
12382  return raw_quad_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12383  -1,
12384  -1);
12385 }
12386 
12387 
12388 /*------------------------ Hex iterator functions ------------------------*/
12389 
12390 
12391 template <int dim, int spacedim>
12392 typename Triangulation<dim, spacedim>::raw_hex_iterator
12393 Triangulation<dim, spacedim>::begin_raw_hex(const unsigned int level) const
12394 {
12395  // This function may be called on parallel triangulations on levels
12396  // that exist globally, but not on the local portion of the
12397  // triangulation. In that case, just return the end iterator.
12398  //
12399  // We need to use levels.size() instead of n_levels() because the
12400  // latter function uses the cache, but we need to be able to call
12401  // this function at a time when the cache is not currently up to
12402  // date.
12403  if (level >= levels.size())
12404  {
12405  Assert(level < n_global_levels(),
12406  ExcInvalidLevel(level, n_global_levels()));
12407  return end_hex();
12408  }
12409 
12410  switch (dim)
12411  {
12412  case 1:
12413  case 2:
12414  Assert(false, ExcImpossibleInDim(1));
12415  return raw_hex_iterator();
12416  case 3:
12417  {
12418  // Query whether the given level is valid for the local portion of the
12419  // triangulation.
12420  Assert(level < levels.size(), ExcInvalidLevel(level, levels.size()));
12421 
12422  if (level >= levels.size() || levels[level]->cells.cells.size() == 0)
12423  return end_hex();
12424 
12425  return raw_hex_iterator(
12426  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
12427  }
12428 
12429  default:
12430  Assert(false, ExcNotImplemented());
12431  return raw_hex_iterator();
12432  }
12433 }
12434 
12435 
12436 
12437 template <int dim, int spacedim>
12439 Triangulation<dim, spacedim>::begin_hex(const unsigned int level) const
12440 {
12441  // level is checked in begin_raw
12442  raw_hex_iterator ri = begin_raw_hex(level);
12443  if (ri.state() != IteratorState::valid)
12444  return ri;
12445  while (ri->used() == false)
12446  if ((++ri).state() != IteratorState::valid)
12447  return ri;
12448  return ri;
12449 }
12450 
12451 
12452 
12453 template <int dim, int spacedim>
12455 Triangulation<dim, spacedim>::begin_active_hex(const unsigned int level) const
12456 {
12457  // level is checked in begin_raw
12458  hex_iterator i = begin_hex(level);
12459  if (i.state() != IteratorState::valid)
12460  return i;
12461  while (i->has_children())
12462  if ((++i).state() != IteratorState::valid)
12463  return i;
12464  return i;
12465 }
12466 
12467 
12468 
12469 template <int dim, int spacedim>
12472 {
12473  return raw_hex_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12474  -1,
12475  -1);
12476 }
12477 
12478 
12479 
12480 // -------------------------------- number of cells etc ---------------
12481 
12482 
12483 namespace internal
12484 {
12485  namespace TriangulationImplementation
12486  {
12487  inline unsigned int
12489  {
12490  return c.n_lines;
12491  }
12492 
12493 
12494  inline unsigned int
12495  n_active_cells(
12497  {
12498  return c.n_active_lines;
12499  }
12500 
12501 
12502  inline unsigned int
12504  {
12505  return c.n_quads;
12506  }
12507 
12508 
12509  inline unsigned int
12510  n_active_cells(
12512  {
12513  return c.n_active_quads;
12514  }
12515 
12516 
12517  inline unsigned int
12519  {
12520  return c.n_hexes;
12521  }
12522 
12523 
12524  inline unsigned int
12525  n_active_cells(
12527  {
12528  return c.n_active_hexes;
12529  }
12530  } // namespace TriangulationImplementation
12531 } // namespace internal
12532 
12533 
12534 
12535 template <int dim, int spacedim>
12536 unsigned int
12538 {
12539  return internal::TriangulationImplementation::n_cells(number_cache);
12540 }
12541 
12542 
12543 template <int dim, int spacedim>
12544 unsigned int
12546 {
12547  return internal::TriangulationImplementation::n_active_cells(number_cache);
12548 }
12549 
12550 template <int dim, int spacedim>
12553 {
12554  return n_active_cells();
12555 }
12556 
12557 
12558 
12559 template <int dim, int spacedim>
12560 unsigned int
12562 {
12563  switch (dim)
12564  {
12565  case 1:
12566  return n_used_vertices();
12567  case 2:
12568  return n_lines();
12569  case 3:
12570  return n_quads();
12571  default:
12572  Assert(false, ExcNotImplemented());
12573  }
12574  return 0;
12575 }
12576 
12577 
12578 template <int dim, int spacedim>
12579 unsigned int
12581 {
12582  switch (dim)
12583  {
12584  case 1:
12585  return n_vertices();
12586  case 2:
12587  return n_raw_lines();
12588  case 3:
12589  return n_raw_quads();
12590  default:
12591  Assert(false, ExcNotImplemented());
12592  }
12593  return 0;
12594 }
12595 
12596 
12597 template <int dim, int spacedim>
12598 unsigned int
12600 {
12601  switch (dim)
12602  {
12603  case 1:
12604  return n_used_vertices();
12605  case 2:
12606  return n_active_lines();
12607  case 3:
12608  return n_active_quads();
12609  default:
12610  Assert(false, ExcNotImplemented());
12611  }
12612  return 0;
12613 }
12614 
12615 
12616 template <int dim, int spacedim>
12617 unsigned int
12618 Triangulation<dim, spacedim>::n_raw_cells(const unsigned int level) const
12619 {
12620  switch (dim)
12621  {
12622  case 1:
12623  return n_raw_lines(level);
12624  case 2:
12625  return n_raw_quads(level);
12626  case 3:
12627  return n_raw_hexs(level);
12628  default:
12629  Assert(false, ExcNotImplemented());
12630  }
12631  return 0;
12632 }
12633 
12634 
12635 
12636 template <int dim, int spacedim>
12637 unsigned int
12638 Triangulation<dim, spacedim>::n_cells(const unsigned int level) const
12639 {
12640  switch (dim)
12641  {
12642  case 1:
12643  return n_lines(level);
12644  case 2:
12645  return n_quads(level);
12646  case 3:
12647  return n_hexs(level);
12648  default:
12649  Assert(false, ExcNotImplemented());
12650  }
12651  return 0;
12652 }
12653 
12654 
12655 
12656 template <int dim, int spacedim>
12657 unsigned int
12658 Triangulation<dim, spacedim>::n_active_cells(const unsigned int level) const
12659 {
12660  switch (dim)
12661  {
12662  case 1:
12663  return n_active_lines(level);
12664  case 2:
12665  return n_active_quads(level);
12666  case 3:
12667  return n_active_hexs(level);
12668  default:
12669  Assert(false, ExcNotImplemented());
12670  }
12671  return 0;
12672 }
12673 
12674 
12675 template <int dim, int spacedim>
12676 bool
12678 {
12679  for (unsigned int lvl = 0; lvl < n_global_levels() - 1; lvl++)
12680  if (n_active_cells(lvl) != 0)
12681  return true;
12682 
12683  return false;
12684 }
12685 
12686 
12687 template <int dim, int spacedim>
12688 unsigned int
12690 {
12691  return number_cache.n_lines;
12692 }
12693 
12694 
12695 // TODO: Merge the following 6 functions somehow
12696 template <>
12697 unsigned int
12698 Triangulation<1, 1>::n_raw_lines(const unsigned int level) const
12699 {
12700  Assert(level < n_levels(), ExcIndexRange(level, 0, n_levels()));
12701  return levels[level]->cells.cells.size();
12702 }
12703 
12704 
12705 template <>
12706 unsigned int
12708 {
12709  Assert(false, ExcNotImplemented());
12710  return 0;
12711 }
12712 
12713 
12714 
12715 template <>
12716 unsigned int
12717 Triangulation<1, 2>::n_raw_lines(const unsigned int level) const
12718 {
12719  Assert(level < n_levels(), ExcIndexRange(level, 0, n_levels()));
12720  return levels[level]->cells.cells.size();
12721 }
12722 
12723 
12724 template <>
12725 unsigned int
12727 {
12728  Assert(false, ExcNotImplemented());
12729  return 0;
12730 }
12731 
12732 
12733 template <>
12734 unsigned int
12735 Triangulation<1, 3>::n_raw_lines(const unsigned int level) const
12736 {
12737  Assert(level < n_levels(), ExcIndexRange(level, 0, n_levels()));
12738  return levels[level]->cells.cells.size();
12739 }
12740 
12741 template <>
12742 unsigned int
12744 {
12745  Assert(false, ExcNotImplemented());
12746  return 0;
12747 }
12748 
12749 
12750 
12751 template <int dim, int spacedim>
12752 unsigned int
12754 {
12755  Assert(false, ExcFacesHaveNoLevel());
12756  return 0;
12757 }
12758 
12759 
12760 template <int dim, int spacedim>
12761 unsigned int
12763 {
12764  return faces->lines.cells.size();
12765 }
12766 
12767 
12768 template <int dim, int spacedim>
12769 unsigned int
12770 Triangulation<dim, spacedim>::n_lines(const unsigned int level) const
12771 {
12772  Assert(level < number_cache.n_lines_level.size(),
12773  ExcIndexRange(level, 0, number_cache.n_lines_level.size()));
12774  Assert(dim == 1, ExcFacesHaveNoLevel());
12775  return number_cache.n_lines_level[level];
12776 }
12777 
12778 
12779 template <int dim, int spacedim>
12780 unsigned int
12782 {
12783  return number_cache.n_active_lines;
12784 }
12785 
12786 
12787 template <int dim, int spacedim>
12788 unsigned int
12789 Triangulation<dim, spacedim>::n_active_lines(const unsigned int level) const
12790 {
12791  Assert(level < number_cache.n_lines_level.size(),
12792  ExcIndexRange(level, 0, number_cache.n_lines_level.size()));
12793  Assert(dim == 1, ExcFacesHaveNoLevel());
12794 
12795  return number_cache.n_active_lines_level[level];
12796 }
12797 
12798 
12799 template <>
12800 unsigned int
12802 {
12803  return 0;
12804 }
12805 
12806 
12807 template <>
12808 unsigned int
12809 Triangulation<1, 1>::n_quads(const unsigned int) const
12810 {
12811  return 0;
12812 }
12813 
12814 
12815 template <>
12816 unsigned int
12817 Triangulation<1, 1>::n_raw_quads(const unsigned int) const
12818 {
12819  return 0;
12820 }
12821 
12822 
12823 template <>
12824 unsigned int
12825 Triangulation<1, 1>::n_raw_hexs(const unsigned int) const
12826 {
12827  return 0;
12828 }
12829 
12830 
12831 template <>
12832 unsigned int
12833 Triangulation<1, 1>::n_active_quads(const unsigned int) const
12834 {
12835  return 0;
12836 }
12837 
12838 
12839 template <>
12840 unsigned int
12842 {
12843  return 0;
12844 }
12845 
12846 
12847 
12848 template <>
12849 unsigned int
12851 {
12852  return 0;
12853 }
12854 
12855 
12856 template <>
12857 unsigned int
12858 Triangulation<1, 2>::n_quads(const unsigned int) const
12859 {
12860  return 0;
12861 }
12862 
12863 
12864 template <>
12865 unsigned int
12866 Triangulation<1, 2>::n_raw_quads(const unsigned int) const
12867 {
12868  return 0;
12869 }
12870 
12871 
12872 template <>
12873 unsigned int
12874 Triangulation<1, 2>::n_raw_hexs(const unsigned int) const
12875 {
12876  return 0;
12877 }
12878 
12879 
12880 template <>
12881 unsigned int
12882 Triangulation<1, 2>::n_active_quads(const unsigned int) const
12883 {
12884  return 0;
12885 }
12886 
12887 
12888 template <>
12889 unsigned int
12891 {
12892  return 0;
12893 }
12894 
12895 
12896 template <>
12897 unsigned int
12899 {
12900  return 0;
12901 }
12902 
12903 
12904 template <>
12905 unsigned int
12906 Triangulation<1, 3>::n_quads(const unsigned int) const
12907 {
12908  return 0;
12909 }
12910 
12911 
12912 template <>
12913 unsigned int
12914 Triangulation<1, 3>::n_raw_quads(const unsigned int) const
12915 {
12916  return 0;
12917 }
12918 
12919 
12920 template <>
12921 unsigned int
12922 Triangulation<1, 3>::n_raw_hexs(const unsigned int) const
12923 {
12924  return 0;
12925 }
12926 
12927 
12928 template <>
12929 unsigned int
12930 Triangulation<1, 3>::n_active_quads(const unsigned int) const
12931 {
12932  return 0;
12933 }
12934 
12935 
12936 template <>
12937 unsigned int
12939 {
12940  return 0;
12941 }
12942 
12943 
12944 
12945 template <int dim, int spacedim>
12946 unsigned int
12948 {
12949  return number_cache.n_quads;
12950 }
12951 
12952 
12953 template <int dim, int spacedim>
12954 unsigned int
12955 Triangulation<dim, spacedim>::n_quads(const unsigned int level) const
12956 {
12957  Assert(dim == 2, ExcFacesHaveNoLevel());
12958  Assert(level < number_cache.n_quads_level.size(),
12959  ExcIndexRange(level, 0, number_cache.n_quads_level.size()));
12960  return number_cache.n_quads_level[level];
12961 }
12962 
12963 
12964 
12965 template <>
12966 unsigned int
12967 Triangulation<2, 2>::n_raw_quads(const unsigned int level) const
12968 {
12969  Assert(level < n_levels(), ExcIndexRange(level, 0, n_levels()));
12970  return levels[level]->cells.cells.size();
12971 }
12972 
12973 
12974 
12975 template <>
12976 unsigned int
12977 Triangulation<2, 3>::n_raw_quads(const unsigned int level) const
12978 {
12979  Assert(level < n_levels(), ExcIndexRange(level, 0, n_levels()));
12980  return levels[level]->cells.cells.size();
12981 }
12982 
12983 
12984 template <>
12985 unsigned int
12986 Triangulation<3, 3>::n_raw_quads(const unsigned int) const
12987 {
12988  Assert(false, ExcFacesHaveNoLevel());
12989  return 0;
12990 }
12991 
12992 
12993 
12994 template <int dim, int spacedim>
12995 unsigned int
12997 {
12998  Assert(false, ExcNotImplemented());
12999  return 0;
13000 }
13001 
13002 
13003 
13004 template <>
13005 unsigned int
13007 {
13008  return faces->quads.cells.size();
13009 }
13010 
13011 
13012 
13013 template <int dim, int spacedim>
13014 unsigned int
13016 {
13017  return number_cache.n_active_quads;
13018 }
13019 
13020 
13021 template <int dim, int spacedim>
13022 unsigned int
13023 Triangulation<dim, spacedim>::n_active_quads(const unsigned int level) const
13024 {
13025  Assert(level < number_cache.n_quads_level.size(),
13026  ExcIndexRange(level, 0, number_cache.n_quads_level.size()));
13027  Assert(dim == 2, ExcFacesHaveNoLevel());
13028 
13029  return number_cache.n_active_quads_level[level];
13030 }
13031 
13032 
13033 template <int dim, int spacedim>
13034 unsigned int
13036 {
13037  return 0;
13038 }
13039 
13040 
13041 
13042 template <int dim, int spacedim>
13043 unsigned int
13044 Triangulation<dim, spacedim>::n_hexs(const unsigned int) const
13045 {
13046  return 0;
13047 }
13048 
13049 
13050 
13051 template <int dim, int spacedim>
13052 unsigned int
13054 {
13055  return 0;
13056 }
13057 
13058 
13059 template <int dim, int spacedim>
13060 unsigned int
13062 {
13063  return 0;
13064 }
13065 
13066 
13067 
13068 template <int dim, int spacedim>
13069 unsigned int
13071 {
13072  return 0;
13073 }
13074 
13075 
13076 template <>
13077 unsigned int
13079 {
13080  return number_cache.n_hexes;
13081 }
13082 
13083 
13084 
13085 template <>
13086 unsigned int
13087 Triangulation<3, 3>::n_hexs(const unsigned int level) const
13088 {
13089  Assert(level < number_cache.n_hexes_level.size(),
13090  ExcIndexRange(level, 0, number_cache.n_hexes_level.size()));
13091 
13092  return number_cache.n_hexes_level[level];
13093 }
13094 
13095 
13096 
13097 template <>
13098 unsigned int
13099 Triangulation<3, 3>::n_raw_hexs(const unsigned int level) const
13100 {
13101  Assert(level < n_levels(), ExcIndexRange(level, 0, n_levels()));
13102  return levels[level]->cells.cells.size();
13103 }
13104 
13105 
13106 template <>
13107 unsigned int
13109 {
13110  return number_cache.n_active_hexes;
13111 }
13112 
13113 
13114 
13115 template <>
13116 unsigned int
13117 Triangulation<3, 3>::n_active_hexs(const unsigned int level) const
13118 {
13119  Assert(level < number_cache.n_hexes_level.size(),
13120  ExcIndexRange(level, 0, number_cache.n_hexes_level.size()));
13121 
13122  return number_cache.n_active_hexes_level[level];
13123 }
13124 
13125 
13126 
13127 template <int dim, int spacedim>
13128 unsigned int
13130 {
13131  return std::count_if(vertices_used.begin(),
13132  vertices_used.end(),
13133  std::bind(std::equal_to<bool>(),
13134  std::placeholders::_1,
13135  true));
13136 }
13137 
13138 
13139 
13140 template <int dim, int spacedim>
13141 const std::vector<bool> &
13143 {
13144  return vertices_used;
13145 }
13146 
13147 
13148 
13149 template <>
13150 unsigned int
13152 {
13153  return 2;
13154 }
13155 
13156 
13157 
13158 template <>
13159 unsigned int
13161 {
13162  return 2;
13163 }
13164 
13165 
13166 template <>
13167 unsigned int
13169 {
13170  return 2;
13171 }
13172 
13173 
13174 template <int dim, int spacedim>
13175 unsigned int
13177 {
13178  cell_iterator cell = begin(0),
13179  endc = (n_levels() > 1 ? begin(1) : cell_iterator(end()));
13180  // store the largest index of the
13181  // vertices used on level 0
13182  unsigned int max_vertex_index = 0;
13183  for (; cell != endc; ++cell)
13184  for (unsigned int vertex = 0; vertex < GeometryInfo<dim>::vertices_per_cell;
13185  ++vertex)
13186  if (cell->vertex_index(vertex) > max_vertex_index)
13187  max_vertex_index = cell->vertex_index(vertex);
13188 
13189  // store the number of times a cell
13190  // touches a vertex. An unsigned
13191  // int should suffice, even for
13192  // larger dimensions
13193  std::vector<unsigned short int> usage_count(max_vertex_index + 1, 0);
13194  // touch a vertex's usage count
13195  // every time we find an adjacent
13196  // element
13197  for (cell = begin(); cell != endc; ++cell)
13198  for (unsigned int vertex = 0; vertex < GeometryInfo<dim>::vertices_per_cell;
13199  ++vertex)
13200  ++usage_count[cell->vertex_index(vertex)];
13201 
13202  return std::max(GeometryInfo<dim>::vertices_per_cell,
13203  static_cast<unsigned int>(
13204  *std::max_element(usage_count.begin(), usage_count.end())));
13205 }
13206 
13207 
13208 
13209 template <int dim, int spacedim>
13212 {
13214 }
13215 
13216 
13217 
13218 template <int dim, int spacedim>
13221 {
13222  return *this;
13223 }
13224 
13225 
13226 
13227 template <int dim, int spacedim>
13230 {
13231  return *this;
13232 }
13233 
13234 
13235 
13236 template <int dim, int spacedim>
13237 void
13240  &periodicity_vector)
13241 {
13242  periodic_face_pairs_level_0.insert(periodic_face_pairs_level_0.end(),
13243  periodicity_vector.begin(),
13244  periodicity_vector.end());
13245 
13246  // Now initialize periodic_face_map
13247  update_periodic_face_map();
13248 }
13249 
13250 
13251 
13252 template <int dim, int spacedim>
13253 const typename std::map<
13254  std::pair<typename Triangulation<dim, spacedim>::cell_iterator, unsigned int>,
13255  std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
13256  unsigned int>,
13257  std::bitset<3>>> &
13259 {
13260  return periodic_face_map;
13261 }
13262 
13263 
13264 
13265 template <int dim, int spacedim>
13266 void
13268 {
13269  prepare_coarsening_and_refinement();
13270 
13271  // verify a case with which we have had
13272  // some difficulty in the past (see the
13273  // deal.II/coarsening_* tests)
13274  if (smooth_grid & limit_level_difference_at_vertices)
13275  Assert(satisfies_level1_at_vertex_rule(*this) == true, ExcInternalError());
13276 
13277  // Inform all listeners about beginning of refinement.
13278  signals.pre_refinement();
13279 
13280  execute_coarsening();
13281 
13282  const DistortedCellList cells_with_distorted_children = execute_refinement();
13283 
13284  // verify a case with which we have had
13285  // some difficulty in the past (see the
13286  // deal.II/coarsening_* tests)
13287  if (smooth_grid & limit_level_difference_at_vertices)
13288  Assert(satisfies_level1_at_vertex_rule(*this) == true, ExcInternalError());
13289 
13290  // finally build up neighbor connectivity information, and set
13291  // active cell indices
13292  update_neighbors(*this);
13293  reset_active_cell_indices();
13294 
13295  // Inform all listeners about end of refinement.
13296  signals.post_refinement();
13297 
13298  AssertThrow(cells_with_distorted_children.distorted_cells.size() == 0,
13299  cells_with_distorted_children);
13300 
13301  update_periodic_face_map();
13302 }
13303 
13304 
13305 
13306 template <int dim, int spacedim>
13307 void
13309 {
13310  unsigned int active_cell_index = 0;
13311  for (raw_cell_iterator cell = begin_raw(); cell != end(); ++cell)
13312  if ((cell->used() == false) || cell->has_children())
13313  cell->set_active_cell_index(numbers::invalid_unsigned_int);
13314  else
13315  {
13316  cell->set_active_cell_index(active_cell_index);
13317  ++active_cell_index;
13318  }
13319 
13320  Assert(active_cell_index == n_active_cells(), ExcInternalError());
13321 }
13322 
13323 
13324 template <int dim, int spacedim>
13325 void
13327 {
13328  // first empty the currently stored objects
13329  periodic_face_map.clear();
13330 
13331  typename std::vector<
13332  GridTools::PeriodicFacePair<cell_iterator>>::const_iterator it;
13333  for (it = periodic_face_pairs_level_0.begin();
13334  it != periodic_face_pairs_level_0.end();
13335  ++it)
13336  {
13337  update_periodic_face_map_recursively<dim, spacedim>(it->cell[0],
13338  it->cell[1],
13339  it->face_idx[0],
13340  it->face_idx[1],
13341  it->orientation,
13342  periodic_face_map);
13343 
13344  // for the other way, we need to invert the orientation
13345  std::bitset<3> inverted_orientation;
13346  {
13347  bool orientation, flip, rotation;
13348  orientation = it->orientation[0];
13349  rotation = it->orientation[2];
13350  flip = orientation ? rotation ^ it->orientation[1] : it->orientation[1];
13351  inverted_orientation[0] = orientation;
13352  inverted_orientation[1] = flip;
13353  inverted_orientation[2] = rotation;
13354  }
13355  update_periodic_face_map_recursively<dim, spacedim>(it->cell[1],
13356  it->cell[0],
13357  it->face_idx[1],
13358  it->face_idx[0],
13359  inverted_orientation,
13360  periodic_face_map);
13361  }
13362 
13363  // check consistency
13364  typename std::map<std::pair<cell_iterator, unsigned int>,
13365  std::pair<std::pair<cell_iterator, unsigned int>,
13366  std::bitset<3>>>::const_iterator it_test;
13367  for (it_test = periodic_face_map.begin(); it_test != periodic_face_map.end();
13368  ++it_test)
13369  {
13371  it_test->first.first;
13373  it_test->second.first.first;
13374  if (cell_1->level() == cell_2->level())
13375  {
13376  // if both cells have the same neighbor, then the same pair
13377  // order swapped has to be in the map
13378  Assert(periodic_face_map[it_test->second.first].first ==
13379  it_test->first,
13380  ExcInternalError());
13381  }
13382  }
13383 }
13384 
13385 
13386 
13387 template <int dim, int spacedim>
13388 void
13390 {
13391  levels.clear();
13392  faces.reset();
13393 
13394  vertices.clear();
13395  vertices_used.clear();
13396 
13397  manifold.clear();
13398 
13400 }
13401 
13402 
13403 template <int dim, int spacedim>
13406 {
13407  const DistortedCellList cells_with_distorted_children =
13409  *this, check_for_distorted_cells);
13410 
13411 
13412 
13413  // re-compute number of lines
13415  *this, levels.size(), number_cache);
13416 
13417 #ifdef DEBUG
13418  for (unsigned int level = 0; level < levels.size(); ++level)
13419  levels[level]->cells.monitor_memory(dim);
13420 
13421  // check whether really all refinement flags are reset (also of
13422  // previously non-active cells which we may not have touched. If the
13423  // refinement flag of a non-active cell is set, something went wrong
13424  // since the cell-accessors should have caught this)
13425  cell_iterator cell = begin(), endc = end();
13426  while (cell != endc)
13427  Assert(!(cell++)->refine_flag_set(), ExcInternalError());
13428 #endif
13429 
13430  return cells_with_distorted_children;
13431 }
13432 
13433 
13434 
13435 template <int dim, int spacedim>
13436 void
13438 {
13439  // create a vector counting for each line how many cells contain
13440  // this line. in 3D, this is used later on to decide which lines can
13441  // be deleted after coarsening a cell. in other dimensions it will
13442  // be ignored
13443  std::vector<unsigned int> line_cell_count =
13444  count_cells_bounded_by_line(*this);
13445  std::vector<unsigned int> quad_cell_count =
13446  count_cells_bounded_by_quad(*this);
13447 
13448  // loop over all cells. Flag all cells of which all children are
13449  // flagged for coarsening and delete the childrens' flags. In
13450  // effect, only those cells are flagged of which originally all
13451  // children were flagged and for which all children are on the same
13452  // refinement level. For flagging, the user flags are used, to avoid
13453  // confusion and because non-active cells can't be flagged for
13454  // coarsening. Note that because of the effects of
13455  // @p{fix_coarsen_flags}, of a cell either all or no children must
13456  // be flagged for coarsening, so it is ok to only check the first
13457  // child
13458  clear_user_flags();
13459 
13460  cell_iterator cell = begin(), endc = end();
13461  for (; cell != endc; ++cell)
13462  if (!cell->active())
13463  if (cell->child(0)->coarsen_flag_set())
13464  {
13465  cell->set_user_flag();
13466  for (unsigned int child = 0; child < cell->n_children(); ++child)
13467  {
13468  Assert(cell->child(child)->coarsen_flag_set(),
13469  ExcInternalError());
13470  cell->child(child)->clear_coarsen_flag();
13471  }
13472  }
13473 
13474 
13475  // now do the actual coarsening step. Since the loop goes over used
13476  // cells we only need not worry about deleting some cells since the
13477  // ++operator will then just hop over them if we should hit one. Do
13478  // the loop in the reverse way since we may only delete some cells
13479  // if their neighbors have already been deleted (if the latter are
13480  // on a higher level for example)
13481  //
13482  // since we delete the *children* of cells, we can ignore cells
13483  // on the highest level, i.e., level must be less than or equal
13484  // to n_levels()-2.
13485  if (levels.size() >= 2)
13486  for (cell = last(); cell != endc; --cell)
13487  if (cell->level() <= static_cast<int>(levels.size() - 2) &&
13488  cell->user_flag_set())
13489  {
13490  // inform all listeners that cell coarsening is going to happen
13491  signals.pre_coarsening_on_cell(cell);
13492  // use a separate function, since this is dimension specific
13494  delete_children(*this, cell, line_cell_count, quad_cell_count);
13495  }
13496 
13497  // re-compute number of lines and quads
13499  *this, levels.size(), number_cache);
13500 
13501  // in principle no user flags should be set any more at this point
13502 #if DEBUG
13503  for (cell = begin(); cell != endc; ++cell)
13504  Assert(cell->user_flag_set() == false, ExcInternalError());
13505 #endif
13506 }
13507 
13508 
13509 
13510 template <int dim, int spacedim>
13511 void
13513 {
13514  // copy a piece of code from prepare_coarsening_and_refinement that
13515  // ensures that the level difference at vertices is limited if so
13516  // desired. we need this code here since at least in 1d we don't
13517  // call the dimension-independent version of
13518  // prepare_coarsening_and_refinement function. in 2d and 3d, having
13519  // this hunk here makes our lives a bit easier as well as it takes
13520  // care of these cases earlier than it would otherwise happen.
13521  //
13522  // the main difference to the code in p_c_and_r is that here we
13523  // absolutely have to make sure that we get things right, i.e. that
13524  // in particular we set flags right if
13525  // limit_level_difference_at_vertices is set. to do so we iterate
13526  // until the flags don't change any more
13527  std::vector<bool> previous_coarsen_flags(n_active_cells());
13528  save_coarsen_flags(previous_coarsen_flags);
13529 
13530  std::vector<int> vertex_level(vertices.size(), 0);
13531 
13532  bool continue_iterating = true;
13533 
13534  do
13535  {
13536  if (smooth_grid & limit_level_difference_at_vertices)
13537  {
13538  Assert(!anisotropic_refinement,
13539  ExcMessage("In case of anisotropic refinement the "
13540  "limit_level_difference_at_vertices flag for "
13541  "mesh smoothing must not be set!"));
13542 
13543  // store highest level one of the cells adjacent to a vertex
13544  // belongs to
13545  std::fill(vertex_level.begin(), vertex_level.end(), 0);
13546  active_cell_iterator cell = begin_active(), endc = end();
13547  for (; cell != endc; ++cell)
13548  {
13549  if (cell->refine_flag_set())
13550  for (unsigned int vertex = 0;
13551  vertex < GeometryInfo<dim>::vertices_per_cell;
13552  ++vertex)
13553  vertex_level[cell->vertex_index(vertex)] =
13554  std::max(vertex_level[cell->vertex_index(vertex)],
13555  cell->level() + 1);
13556  else if (!cell->coarsen_flag_set())
13557  for (unsigned int vertex = 0;
13558  vertex < GeometryInfo<dim>::vertices_per_cell;
13559  ++vertex)
13560  vertex_level[cell->vertex_index(vertex)] =
13561  std::max(vertex_level[cell->vertex_index(vertex)],
13562  cell->level());
13563  else
13564  {
13565  // if coarsen flag is set then tentatively assume
13566  // that the cell will be coarsened. this isn't
13567  // always true (the coarsen flag could be removed
13568  // again) and so we may make an error here. we try
13569  // to correct this by iterating over the entire
13570  // process until we are converged
13571  Assert(cell->coarsen_flag_set(), ExcInternalError());
13572  for (unsigned int vertex = 0;
13573  vertex < GeometryInfo<dim>::vertices_per_cell;
13574  ++vertex)
13575  vertex_level[cell->vertex_index(vertex)] =
13576  std::max(vertex_level[cell->vertex_index(vertex)],
13577  cell->level() - 1);
13578  }
13579  }
13580 
13581 
13582  // loop over all cells in reverse order. do so because we
13583  // can then update the vertex levels on the adjacent
13584  // vertices and maybe already flag additional cells in this
13585  // loop
13586  //
13587  // note that not only may we have to add additional
13588  // refinement flags, but we will also have to remove
13589  // coarsening flags on cells adjacent to vertices that will
13590  // see refinement
13591  for (cell = last_active(); cell != endc; --cell)
13592  if (cell->refine_flag_set() == false)
13593  {
13594  for (unsigned int vertex = 0;
13595  vertex < GeometryInfo<dim>::vertices_per_cell;
13596  ++vertex)
13597  if (vertex_level[cell->vertex_index(vertex)] >=
13598  cell->level() + 1)
13599  {
13600  // remove coarsen flag...
13601  cell->clear_coarsen_flag();
13602 
13603  // ...and if necessary also refine the current
13604  // cell, at the same time updating the level
13605  // information about vertices
13606  if (vertex_level[cell->vertex_index(vertex)] >
13607  cell->level() + 1)
13608  {
13609  cell->set_refine_flag();
13610 
13611  for (unsigned int v = 0;
13612  v < GeometryInfo<dim>::vertices_per_cell;
13613  ++v)
13614  vertex_level[cell->vertex_index(v)] =
13615  std::max(vertex_level[cell->vertex_index(v)],
13616  cell->level() + 1);
13617  }
13618 
13619  // continue and see whether we may, for example,
13620  // go into the inner 'if' above based on a
13621  // different vertex
13622  }
13623  }
13624  }
13625 
13626  // loop over all cells. Flag all cells of which all children are
13627  // flagged for coarsening and delete the childrens' flags. Also
13628  // delete all flags of cells for which not all children of a
13629  // cell are flagged. In effect, only those cells are flagged of
13630  // which originally all children were flagged and for which all
13631  // children are on the same refinement level. For flagging, the
13632  // user flags are used, to avoid confusion and because
13633  // non-active cells can't be flagged for coarsening
13634  //
13635  // In effect, all coarsen flags are turned into user flags of
13636  // the mother cell if coarsening is possible or deleted
13637  // otherwise.
13638  clear_user_flags();
13639  // Coarsen flags of cells with no mother cell, i.e. on the
13640  // coarsest level are deleted explicitly.
13641  active_cell_iterator acell = begin_active(0), end_ac = end_active(0);
13642  for (; acell != end_ac; ++acell)
13643  acell->clear_coarsen_flag();
13644 
13645  cell_iterator cell = begin(), endc = end();
13646  for (; cell != endc; ++cell)
13647  {
13648  // nothing to do if we are already on the finest level
13649  if (cell->active())
13650  continue;
13651 
13652  const unsigned int n_children = cell->n_children();
13653  unsigned int flagged_children = 0;
13654  for (unsigned int child = 0; child < n_children; ++child)
13655  if (cell->child(child)->active() &&
13656  cell->child(child)->coarsen_flag_set())
13657  {
13658  ++flagged_children;
13659  // clear flag since we don't need it anymore
13660  cell->child(child)->clear_coarsen_flag();
13661  }
13662 
13663  // flag this cell for coarsening if all children were
13664  // flagged
13665  if (flagged_children == n_children)
13666  cell->set_user_flag();
13667  }
13668 
13669  // in principle no coarsen flags should be set any more at this
13670  // point
13671 #if DEBUG
13672  for (cell = begin(); cell != endc; ++cell)
13673  Assert(cell->coarsen_flag_set() == false, ExcInternalError());
13674 #endif
13675 
13676  // now loop over all cells which have the user flag set. their
13677  // children were flagged for coarsening. set the coarsen flag
13678  // again if we are sure that none of the neighbors of these
13679  // children are refined, or will be refined, since then we would
13680  // get a two-level jump in refinement. on the other hand, if one
13681  // of the children's neighbors has their user flag set, then we
13682  // know that its children will go away by coarsening, and we
13683  // will be ok.
13684  //
13685  // note on the other hand that we do allow level-2 jumps in
13686  // refinement between neighbors in 1d, so this whole procedure
13687  // is only necessary if we are not in 1d
13688  //
13689  // since we remove some coarsening/user flags in the process, we
13690  // have to work from the finest level to the coarsest one, since
13691  // we occasionally inspect user flags of cells on finer levels
13692  // and need to be sure that these flags are final
13693  for (cell = last(); cell != endc; --cell)
13694  if (cell->user_flag_set())
13695  // if allowed: flag the
13696  // children for coarsening
13698  template coarsening_allowed<dim, spacedim>(cell))
13699  for (unsigned int c = 0; c < cell->n_children(); ++c)
13700  {
13701  Assert(cell->child(c)->refine_flag_set() == false,
13702  ExcInternalError());
13703 
13704  cell->child(c)->set_coarsen_flag();
13705  }
13706 
13707  // clear all user flags again, now that we don't need them any
13708  // more
13709  clear_user_flags();
13710 
13711 
13712  // now see if anything has changed in the last iteration of this
13713  // function
13714  std::vector<bool> current_coarsen_flags(n_active_cells());
13715  save_coarsen_flags(current_coarsen_flags);
13716 
13717  continue_iterating = (current_coarsen_flags != previous_coarsen_flags);
13718  previous_coarsen_flags = current_coarsen_flags;
13719  }
13720  while (continue_iterating == true);
13721 }
13722 
13723 
13724 // TODO: merge the following 3 functions since they are the same
13725 template <>
13726 bool
13728 {
13729  // save the flags to determine whether something was changed in the
13730  // course of this function
13731  std::vector<bool> flags_before;
13732  save_coarsen_flags(flags_before);
13733 
13734  // do nothing in 1d, except setting the coarsening flags correctly
13735  fix_coarsen_flags();
13736 
13737  std::vector<bool> flags_after;
13738  save_coarsen_flags(flags_after);
13739 
13740  return (flags_before != flags_after);
13741 }
13742 
13743 
13744 template <>
13745 bool
13747 {
13748  // save the flags to determine whether something was changed in the
13749  // course of this function
13750  std::vector<bool> flags_before;
13751  save_coarsen_flags(flags_before);
13752 
13753  // do nothing in 1d, except setting the coarsening flags correctly
13754  fix_coarsen_flags();
13755 
13756  std::vector<bool> flags_after;
13757  save_coarsen_flags(flags_after);
13758 
13759  return (flags_before != flags_after);
13760 }
13761 
13762 
13763 template <>
13764 bool
13766 {
13767  // save the flags to determine whether something was changed in the
13768  // course of this function
13769  std::vector<bool> flags_before;
13770  save_coarsen_flags(flags_before);
13771 
13772  // do nothing in 1d, except setting the coarsening flags correctly
13773  fix_coarsen_flags();
13774 
13775  std::vector<bool> flags_after;
13776  save_coarsen_flags(flags_after);
13777 
13778  return (flags_before != flags_after);
13779 }
13780 
13781 
13782 
13783 namespace
13784 {
13785  // check if the given @param cell marked for coarsening would
13786  // produce an unrefined island. To break up long chains of these
13787  // cells we recursively check our neighbors in case we change this
13788  // cell. This reduces the number of outer iterations dramatically.
13789  template <int dim, int spacedim>
13790  void
13791  possibly_do_not_produce_unrefined_islands(
13792  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
13793  {
13794  Assert(cell->has_children(), ExcInternalError());
13795 
13796  unsigned int n_neighbors = 0;
13797  // count all neighbors that will be refined along the face of our
13798  // cell after the next step
13799  unsigned int count = 0;
13800  for (unsigned int n = 0; n < GeometryInfo<dim>::faces_per_cell; ++n)
13801  {
13802  const typename Triangulation<dim, spacedim>::cell_iterator neighbor =
13803  cell->neighbor(n);
13804  if (neighbor.state() == IteratorState::valid)
13805  {
13806  ++n_neighbors;
13807  if (face_will_be_refined_by_neighbor(cell, n))
13808  ++count;
13809  }
13810  }
13811  // clear coarsen flags if either all existing neighbors will be
13812  // refined or all but one will be and the cell is in the interior
13813  // of the domain
13814  if (count == n_neighbors ||
13815  (count >= n_neighbors - 1 &&
13816  n_neighbors == GeometryInfo<dim>::faces_per_cell))
13817  {
13818  for (unsigned int c = 0; c < cell->n_children(); ++c)
13819  cell->child(c)->clear_coarsen_flag();
13820 
13821  for (unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
13822  ++face)
13823  if (!cell->at_boundary(face) && (!cell->neighbor(face)->active()) &&
13824  (cell_will_be_coarsened(cell->neighbor(face))))
13825  possibly_do_not_produce_unrefined_islands<dim, spacedim>(
13826  cell->neighbor(face));
13827  }
13828  }
13829 
13830 
13831  // see if the current cell needs to be refined to avoid unrefined
13832  // islands.
13833  //
13834  // there are sometimes chains of cells that induce refinement of
13835  // each other. to avoid running the loop in
13836  // prepare_coarsening_and_refinement over and over again for each
13837  // one of them, at least for the isotropic refinement case we seek
13838  // to flag neighboring elements as well as necessary. this takes
13839  // care of (slightly pathological) cases like
13840  // deal.II/mesh_smoothing_03
13841  template <int dim, int spacedim>
13842  void
13843  possibly_refine_unrefined_island(
13844  const typename Triangulation<dim, spacedim>::cell_iterator &cell,
13845  const bool allow_anisotropic_smoothing)
13846  {
13847  Assert(cell->has_children() == false, ExcInternalError());
13848  Assert(cell->refine_flag_set() == false, ExcInternalError());
13849 
13850 
13851  // now we provide two algorithms. the first one is the standard
13852  // one, coming from the time, where only isotropic refinement was
13853  // possible. it simply counts the neighbors that are or will be
13854  // refined and compares to the number of other ones. the second
13855  // one does this check independently for each direction: if all
13856  // neighbors in one direction (normally two, at the boundary only
13857  // one) are refined, the current cell is flagged to be refined in
13858  // an according direction.
13859 
13860  if (allow_anisotropic_smoothing == false)
13861  {
13862  // use first algorithm
13863  unsigned int refined_neighbors = 0, unrefined_neighbors = 0;
13864  for (unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
13865  ++face)
13866  if (!cell->at_boundary(face))
13867  {
13868  if (face_will_be_refined_by_neighbor(cell, face))
13869  ++refined_neighbors;
13870  else
13871  ++unrefined_neighbors;
13872  }
13873 
13874  if (unrefined_neighbors < refined_neighbors)
13875  {
13876  cell->clear_coarsen_flag();
13877  cell->set_refine_flag();
13878 
13879  // ok, so now we have flagged this cell. if we know that
13880  // there were any unrefined neighbors at all, see if any
13881  // of those will have to be refined as well
13882  if (unrefined_neighbors > 0)
13883  for (unsigned int face = 0;
13884  face < GeometryInfo<dim>::faces_per_cell;
13885  ++face)
13886  if (!cell->at_boundary(face) &&
13887  (face_will_be_refined_by_neighbor(cell, face) == false) &&
13888  (cell->neighbor(face)->has_children() == false) &&
13889  (cell->neighbor(face)->refine_flag_set() == false))
13890  possibly_refine_unrefined_island<dim, spacedim>(
13891  cell->neighbor(face), allow_anisotropic_smoothing);
13892  }
13893  }
13894  else
13895  {
13896  // variable to store the cell refine case needed to fulfill
13897  // all smoothing requirements
13898  RefinementCase<dim> smoothing_cell_refinement_case =
13900 
13901  // use second algorithm, do the check individually for each
13902  // direction
13903  for (unsigned int face_pair = 0;
13904  face_pair < GeometryInfo<dim>::faces_per_cell / 2;
13905  ++face_pair)
13906  {
13907  // variable to store the cell refine case needed to refine
13908  // at the current face pair in the same way as the
13909  // neighbors do...
13910  RefinementCase<dim> directional_cell_refinement_case =
13912 
13913  for (unsigned int face_index = 0; face_index < 2; ++face_index)
13914  {
13915  unsigned int face = 2 * face_pair + face_index;
13916  // variable to store the refine case (to come) of the
13917  // face under consideration
13918  RefinementCase<dim - 1> expected_face_ref_case =
13919  RefinementCase<dim - 1>::no_refinement;
13920 
13921  if (cell->neighbor(face).state() == IteratorState::valid)
13922  face_will_be_refined_by_neighbor<dim, spacedim>(
13923  cell, face, expected_face_ref_case);
13924  // now extract which refine case would be necessary to
13925  // achieve the same face refinement. set the
13926  // intersection with other requirements for the same
13927  // direction.
13928 
13929  // note: using the intersection is not an obvious
13930  // decision, we could also argue that it is more
13931  // natural to use the union. however, intersection is
13932  // the less aggressive tactic and favours a smaller
13933  // number of refined cells over an intensive
13934  // smoothing. this way we try not to lose too much of
13935  // the effort we put in anisotropic refinement
13936  // indicators due to overly aggressive smoothing...
13937  directional_cell_refinement_case =
13938  (directional_cell_refinement_case &
13941  expected_face_ref_case,
13942  face,
13943  cell->face_orientation(face),
13944  cell->face_flip(face),
13945  cell->face_rotation(face)));
13946  } // for both face indices
13947  // if both requirements sum up to something useful, add
13948  // this to the refine case for smoothing. note: if
13949  // directional_cell_refinement_case is isotropic still,
13950  // then something went wrong...
13951  Assert(directional_cell_refinement_case <
13953  ExcInternalError());
13954  smoothing_cell_refinement_case =
13955  smoothing_cell_refinement_case | directional_cell_refinement_case;
13956  } // for all face_pairs
13957  // no we collected contributions from all directions. combine
13958  // the new flags with the existing refine case, but only if
13959  // smoothing is required
13960  if (smoothing_cell_refinement_case)
13961  {
13962  cell->clear_coarsen_flag();
13963  cell->set_refine_flag(cell->refine_flag_set() |
13964  smoothing_cell_refinement_case);
13965  }
13966  }
13967  }
13968 } // namespace
13969 
13970 
13971 template <int dim, int spacedim>
13972 bool
13974 {
13975  // save the flags to determine whether something was changed in the
13976  // course of this function
13977  std::vector<bool> flags_before[2];
13978  save_coarsen_flags(flags_before[0]);
13979  save_refine_flags(flags_before[1]);
13980 
13981  // save the flags at the outset of each loop. we do so in order to
13982  // find out whether something was changed in the present loop, in
13983  // which case we would have to re-run the loop. the other
13984  // possibility to find this out would be to set a flag
13985  // @p{something_changed} to true each time we change something.
13986  // however, sometimes one change in one of the parts of the loop is
13987  // undone by another one, so we might end up in an endless loop. we
13988  // could be tempted to break this loop at an arbitrary number of
13989  // runs, but that would not be a clean solution, since we would
13990  // either have to 1/ break the loop too early, in which case the
13991  // promise that a second call to this function immediately after the
13992  // first one does not change anything, would be broken, or 2/ we do
13993  // as many loops as there are levels. we know that information is
13994  // transported over one level in each run of the loop, so this is
13995  // enough. Unfortunately, each loop is rather expensive, so we chose
13996  // the way presented here
13997  std::vector<bool> flags_before_loop[2] = {flags_before[0], flags_before[1]};
13998 
13999  // now for what is done in each loop: we have to fulfill several
14000  // tasks at the same time, namely several mesh smoothing algorithms
14001  // and mesh regularization, by which we mean that the next mesh
14002  // fulfills several requirements such as no double refinement at
14003  // each face or line, etc.
14004  //
14005  // since doing these things at once seems almost impossible (in the
14006  // first year of this library, they were done in two functions, one
14007  // for refinement and one for coarsening, and most things within
14008  // these were done at once, so the code was rather impossible to
14009  // join into this, only, function), we do them one after each
14010  // other. the order in which we do them is such that the important
14011  // tasks, namely regularization, are done last and the least
14012  // important things are done the first. the following order is
14013  // chosen:
14014  //
14015  // 0/ Only if coarsest_level_1 or patch_level_1 is set: clear all
14016  // coarsen flags on level 1 to avoid level 0 cells being created
14017  // by coarsening. As coarsen flags will never be added, this can
14018  // be done once and for all before the actual loop starts.
14019  //
14020  // 1/ do not coarsen a cell if 'most of the neighbors' will be
14021  // refined after the step. This is to prevent occurrence of
14022  // unrefined islands.
14023  //
14024  // 2/ eliminate refined islands in the interior and at the
14025  // boundary. since they don't do much harm besides increasing the
14026  // number of degrees of freedom, doing this has a rather low
14027  // priority.
14028  //
14029  // 3/ limit the level difference of neighboring cells at each
14030  // vertex.
14031  //
14032  // 4/ eliminate unrefined islands. this has higher priority since
14033  // this diminishes the approximation properties not only of the
14034  // unrefined island, but also of the surrounding patch.
14035  //
14036  // 5/ ensure patch level 1. Then the triangulation consists of
14037  // patches, i.e. of cells that are refined once. It follows that
14038  // if at least one of the children of a cell is or will be
14039  // refined than all children need to be refined. This step only
14040  // sets refinement flags and does not set coarsening flags. If
14041  // the patch_level_1 flag is set, then
14042  // eliminate_unrefined_islands, eliminate_refined_inner_islands
14043  // and eliminate_refined_boundary_islands will be fulfilled
14044  // automatically and do not need to be enforced separately.
14045  //
14046  // 6/ take care of the requirement that no double refinement is done
14047  // at each face
14048  //
14049  // 7/ take care that no double refinement is done at each line in 3d
14050  // or higher dimensions.
14051  //
14052  // 8/ make sure that all children of each cell are either flagged
14053  // for coarsening or none of the children is
14054  //
14055  // For some of these steps, it is known that they interact. Namely,
14056  // it is not possible to guarantee that after step 6 another step 5
14057  // would have no effect; the same holds for the opposite order and
14058  // also when taking into account step 7. however, it is important to
14059  // guarantee that step five or six do not undo something that step 5
14060  // did, and step 7 not something of step 6, otherwise the
14061  // requirements will not be satisfied even if the loop
14062  // terminates. this is accomplished by the fact that steps 5 and 6
14063  // only *add* refinement flags and delete coarsening flags
14064  // (therefore, step 6 can't undo something that step 4 already did),
14065  // and step 7 only deletes coarsening flags, never adds some. step 7
14066  // needs also take care that it won't tag cells for refinement for
14067  // which some neighbors are more refined or will be refined.
14068 
14070  // STEP 0:
14071  // Only if coarsest_level_1 or patch_level_1 is set: clear all
14072  // coarsen flags on level 1 to avoid level 0 cells being created
14073  // by coarsening.
14074  if (((smooth_grid & coarsest_level_1) || (smooth_grid & patch_level_1)) &&
14075  n_levels() >= 2)
14076  {
14077  for (const auto &cell : active_cell_iterators_on_level(1))
14078  cell->clear_coarsen_flag();
14079  }
14080 
14081  bool mesh_changed_in_this_loop = false;
14082  do
14083  {
14085  // STEP 1:
14086  // do not coarsen a cell if 'most of the neighbors' will be
14087  // refined after the step. This is to prevent the occurrence
14088  // of unrefined islands. If patch_level_1 is set, this will
14089  // be automatically fulfilled.
14090  if (smooth_grid & do_not_produce_unrefined_islands &&
14091  !(smooth_grid & patch_level_1))
14092  {
14093  for (const auto &cell : cell_iterators())
14094  {
14095  // only do something if this
14096  // cell will be coarsened
14097  if (!cell->active() && cell_will_be_coarsened(cell))
14098  possibly_do_not_produce_unrefined_islands<dim, spacedim>(cell);
14099  }
14100  }
14101 
14102 
14104  // STEP 2:
14105  // eliminate refined islands in the interior and at the
14106  // boundary. since they don't do much harm besides increasing
14107  // the number of degrees of freedom, doing this has a rather
14108  // low priority. If patch_level_1 is set, this will be
14109  // automatically fulfilled.
14110  //
14111  // there is one corner case to consider: if this is a
14112  // distributed triangulation, there may be refined islands on
14113  // the boundary of which we own only part (e.g. a single cell
14114  // in the corner of a domain). the rest of the island is
14115  // ghost cells and it *looks* like the area around it
14116  // (artificial cells) are coarser but this is only because
14117  // they may actually be equally fine on other
14118  // processors. it's hard to detect this case but we can do
14119  // the following: only set coarsen flags to remove this
14120  // refined island if all cells we want to set flags on are
14121  // locally owned
14122  if (smooth_grid & (eliminate_refined_inner_islands |
14123  eliminate_refined_boundary_islands) &&
14124  !(smooth_grid & patch_level_1))
14125  {
14126  for (const auto &cell : cell_iterators())
14127  if (!cell->active() || (cell->active() && cell->refine_flag_set() &&
14128  cell->is_locally_owned()))
14129  {
14130  // check whether all children are active, i.e. not
14131  // refined themselves. This is a precondition that the
14132  // children may be coarsened away. If the cell is only
14133  // flagged for refinement, then all future children
14134  // will be active
14135  bool all_children_active = true;
14136  if (!cell->active())
14137  for (unsigned int c = 0; c < cell->n_children(); ++c)
14138  if (!cell->child(c)->active() ||
14139  cell->child(c)->is_ghost() ||
14140  cell->child(c)->is_artificial())
14141  {
14142  all_children_active = false;
14143  break;
14144  }
14145 
14146  if (all_children_active)
14147  {
14148  // count number of refined and unrefined neighbors
14149  // of cell. neighbors on lower levels are counted
14150  // as unrefined since they can only get to the
14151  // same level as this cell by the next refinement
14152  // cycle
14153  unsigned int unrefined_neighbors = 0, total_neighbors = 0;
14154 
14155  for (unsigned int n = 0;
14156  n < GeometryInfo<dim>::faces_per_cell;
14157  ++n)
14158  {
14159  const cell_iterator neighbor = cell->neighbor(n);
14160  if (neighbor.state() == IteratorState::valid)
14161  {
14162  ++total_neighbors;
14163 
14164  if (!face_will_be_refined_by_neighbor(cell, n))
14165  ++unrefined_neighbors;
14166  }
14167  }
14168 
14169  // if all neighbors unrefined: mark this cell for
14170  // coarsening or don't refine if marked for that
14171  //
14172  // also do the distinction between the two
14173  // versions of the eliminate_refined_*_islands
14174  // flag
14175  //
14176  // the last check is whether there are any
14177  // neighbors at all. if not so, then we are (e.g.)
14178  // on the coarsest grid with one cell, for which,
14179  // of course, we do not remove the refine flag.
14180  if ((unrefined_neighbors == total_neighbors) &&
14181  (((unrefined_neighbors ==
14183  (smooth_grid & eliminate_refined_inner_islands)) ||
14184  ((unrefined_neighbors <
14186  (smooth_grid &
14187  eliminate_refined_boundary_islands))) &&
14188  (total_neighbors != 0))
14189  {
14190  if (!cell->active())
14191  for (unsigned int c = 0; c < cell->n_children(); ++c)
14192  {
14193  cell->child(c)->clear_refine_flag();
14194  cell->child(c)->set_coarsen_flag();
14195  }
14196  else
14197  cell->clear_refine_flag();
14198  }
14199  }
14200  }
14201  }
14202 
14204  // STEP 3:
14205  // limit the level difference of neighboring cells at each
14206  // vertex.
14207  //
14208  // in case of anisotropic refinement this does not make
14209  // sense. as soon as one cell is anisotropically refined, an
14210  // Assertion is thrown. therefore we can ignore this problem
14211  // later on
14212  if (smooth_grid & limit_level_difference_at_vertices)
14213  {
14214  Assert(!anisotropic_refinement,
14215  ExcMessage("In case of anisotropic refinement the "
14216  "limit_level_difference_at_vertices flag for "
14217  "mesh smoothing must not be set!"));
14218 
14219  // store highest level one of the cells adjacent to a vertex
14220  // belongs to
14221  std::vector<int> vertex_level(vertices.size(), 0);
14222  for (const auto &cell : active_cell_iterators())
14223  {
14224  if (cell->refine_flag_set())
14225  for (unsigned int vertex = 0;
14226  vertex < GeometryInfo<dim>::vertices_per_cell;
14227  ++vertex)
14228  vertex_level[cell->vertex_index(vertex)] =
14229  std::max(vertex_level[cell->vertex_index(vertex)],
14230  cell->level() + 1);
14231  else if (!cell->coarsen_flag_set())
14232  for (unsigned int vertex = 0;
14233  vertex < GeometryInfo<dim>::vertices_per_cell;
14234  ++vertex)
14235  vertex_level[cell->vertex_index(vertex)] =
14236  std::max(vertex_level[cell->vertex_index(vertex)],
14237  cell->level());
14238  else
14239  {
14240  // if coarsen flag is set then tentatively assume
14241  // that the cell will be coarsened. this isn't
14242  // always true (the coarsen flag could be removed
14243  // again) and so we may make an error here
14244  Assert(cell->coarsen_flag_set(), ExcInternalError());
14245  for (unsigned int vertex = 0;
14246  vertex < GeometryInfo<dim>::vertices_per_cell;
14247  ++vertex)
14248  vertex_level[cell->vertex_index(vertex)] =
14249  std::max(vertex_level[cell->vertex_index(vertex)],
14250  cell->level() - 1);
14251  }
14252  }
14253 
14254 
14255  // loop over all cells in reverse order. do so because we
14256  // can then update the vertex levels on the adjacent
14257  // vertices and maybe already flag additional cells in this
14258  // loop
14259  //
14260  // note that not only may we have to add additional
14261  // refinement flags, but we will also have to remove
14262  // coarsening flags on cells adjacent to vertices that will
14263  // see refinement
14264  for (active_cell_iterator cell = last_active(); cell != end(); --cell)
14265  if (cell->refine_flag_set() == false)
14266  {
14267  for (unsigned int vertex = 0;
14268  vertex < GeometryInfo<dim>::vertices_per_cell;
14269  ++vertex)
14270  if (vertex_level[cell->vertex_index(vertex)] >=
14271  cell->level() + 1)
14272  {
14273  // remove coarsen flag...
14274  cell->clear_coarsen_flag();
14275 
14276  // ...and if necessary also refine the current
14277  // cell, at the same time updating the level
14278  // information about vertices
14279  if (vertex_level[cell->vertex_index(vertex)] >
14280  cell->level() + 1)
14281  {
14282  cell->set_refine_flag();
14283 
14284  for (unsigned int v = 0;
14285  v < GeometryInfo<dim>::vertices_per_cell;
14286  ++v)
14287  vertex_level[cell->vertex_index(v)] =
14288  std::max(vertex_level[cell->vertex_index(v)],
14289  cell->level() + 1);
14290  }
14291 
14292  // continue and see whether we may, for example,
14293  // go into the inner'if'
14294  // above based on a
14295  // different vertex
14296  }
14297  }
14298  }
14299 
14301  // STEP 4:
14302  // eliminate unrefined islands. this has higher priority
14303  // since this diminishes the approximation properties not
14304  // only of the unrefined island, but also of the surrounding
14305  // patch.
14306  //
14307  // do the loop from finest to coarsest cells since we may
14308  // trigger a cascade by marking cells for refinement which
14309  // may trigger more cells further down below
14310  if (smooth_grid & eliminate_unrefined_islands)
14311  {
14312  for (active_cell_iterator cell = last_active(); cell != end(); --cell)
14313  // only do something if cell is not already flagged for
14314  // (isotropic) refinement
14315  if (cell->refine_flag_set() !=
14317  possibly_refine_unrefined_island<dim, spacedim>(
14318  cell, (smooth_grid & allow_anisotropic_smoothing) != 0);
14319  }
14320 
14322  // STEP 5:
14323  // ensure patch level 1.
14324  //
14325  // Introduce some terminology:
14326  // - a cell that is refined
14327  // once is a patch of
14328  // level 1 simply called patch.
14329  // - a cell that is globally
14330  // refined twice is called
14331  // a patch of level 2.
14332  // - patch level n says that
14333  // the triangulation consists
14334  // of patches of level n.
14335  // This makes sense only
14336  // if the grid is already at
14337  // least n times globally
14338  // refined.
14339  //
14340  // E.g. from patch level 1 follows: if at least one of the
14341  // children of a cell is or will be refined than enforce all
14342  // children to be refined.
14343 
14344  // This step 4 only sets refinement flags and does not set
14345  // coarsening flags.
14346  if (smooth_grid & patch_level_1)
14347  {
14348  // An important assumption (A) is that before calling this
14349  // function the grid was already of patch level 1.
14350 
14351  // loop over all cells whose children are all active. (By
14352  // assumption (A) either all or none of the children are
14353  // active). If the refine flag of at least one of the
14354  // children is set then set_refine_flag and
14355  // clear_coarsen_flag of all children.
14356  for (const auto &cell : cell_iterators())
14357  if (!cell->active())
14358  {
14359  // ensure the invariant. we can then check whether all
14360  // of its children are further refined or not by
14361  // simply looking at the first child
14362  Assert(cell_is_patch_level_1(cell), ExcInternalError());
14363  if (cell->child(0)->has_children() == true)
14364  continue;
14365 
14366  // cell is found to be a patch. combine the refine
14367  // cases of all children
14368  RefinementCase<dim> combined_ref_case =
14370  for (unsigned int i = 0; i < cell->n_children(); ++i)
14371  combined_ref_case =
14372  combined_ref_case | cell->child(i)->refine_flag_set();
14373  if (combined_ref_case != RefinementCase<dim>::no_refinement)
14374  for (unsigned int i = 0; i < cell->n_children(); ++i)
14375  {
14376  cell_iterator child = cell->child(i);
14377 
14378  child->clear_coarsen_flag();
14379  child->set_refine_flag(combined_ref_case);
14380  }
14381  }
14382 
14383  // The code above dealt with the case where we may get a
14384  // non-patch_level_1 mesh from refinement. Now also deal
14385  // with the case where we could get such a mesh by
14386  // coarsening. Coarsen the children (and remove the
14387  // grandchildren) only if all cell->grandchild(i)
14388  // ->coarsen_flag_set() are set.
14389  //
14390  // for a case where this is a bit tricky, take a look at the
14391  // mesh_smoothing_0[12] testcases
14392  for (const auto &cell : cell_iterators())
14393  {
14394  // check if this cell has active grandchildren. note
14395  // that we know that it is patch_level_1, i.e. if one of
14396  // its children is active then so are all, and it isn't
14397  // going to have any grandchildren at all:
14398  if (cell->active() || cell->child(0)->active())
14399  continue;
14400 
14401  // cell is not active, and so are none of its
14402  // children. check the grandchildren. note that the
14403  // children are also patch_level_1, and so we only ever
14404  // need to check their first child
14405  const unsigned int n_children = cell->n_children();
14406  bool has_active_grandchildren = false;
14407 
14408  for (unsigned int i = 0; i < n_children; ++i)
14409  if (cell->child(i)->child(0)->active())
14410  {
14411  has_active_grandchildren = true;
14412  break;
14413  }
14414 
14415  if (has_active_grandchildren == false)
14416  continue;
14417 
14418 
14419  // ok, there are active grandchildren. see if either all
14420  // or none of them are flagged for coarsening
14421  unsigned int n_grandchildren = 0;
14422 
14423  // count all coarsen flags of the grandchildren.
14424  unsigned int n_coarsen_flags = 0;
14425 
14426  // cell is not a patch (of level 1) as it has a
14427  // grandchild. Is cell a patch of level 2?? Therefore:
14428  // find out whether all cell->child(i) are patches
14429  for (unsigned int c = 0; c < n_children; ++c)
14430  {
14431  // get at the child. by assumption (A), and the
14432  // check by which we got here, the child is not
14433  // active
14434  cell_iterator child = cell->child(c);
14435 
14436  const unsigned int nn_children = child->n_children();
14437  n_grandchildren += nn_children;
14438 
14439  // if child is found to be a patch of active cells
14440  // itself, then add up how many of its children are
14441  // supposed to be coarsened
14442  if (child->child(0)->active())
14443  for (unsigned int cc = 0; cc < nn_children; ++cc)
14444  if (child->child(cc)->coarsen_flag_set())
14445  ++n_coarsen_flags;
14446  }
14447 
14448  // if not all grandchildren are supposed to be coarsened
14449  // (e.g. because some simply don't have the flag set, or
14450  // because they are not active and therefore cannot
14451  // carry the flag), then remove the coarsen flag from
14452  // all of the active grandchildren. note that there may
14453  // be coarsen flags on the grandgrandchildren -- we
14454  // don't clear them here, but we'll get to them in later
14455  // iterations if necessary
14456  //
14457  // there is nothing we have to do if no coarsen flags
14458  // have been set at all
14459  if ((n_coarsen_flags != n_grandchildren) && (n_coarsen_flags > 0))
14460  for (unsigned int c = 0; c < n_children; ++c)
14461  {
14462  const cell_iterator child = cell->child(c);
14463  if (child->child(0)->active())
14464  for (unsigned int cc = 0; cc < child->n_children(); ++cc)
14465  child->child(cc)->clear_coarsen_flag();
14466  }
14467  }
14468  }
14469 
14471  //
14472  // at the boundary we could end up with cells with negative
14473  // volume or at least with a part, that is negative, if the
14474  // cell is refined anisotropically. we have to check, whether
14475  // that can happen
14478 
14480  // STEP 6:
14481  // take care of the requirement that no
14482  // double refinement is done at each face
14483  //
14484  // in case of anisotropic refinement it is only likely, but
14485  // not sure, that the cells, which are more refined along a
14486  // certain face common to two cells are on a higher
14487  // level. therefore we cannot be sure, that the requirement
14488  // of no double refinement is fulfilled after a single pass
14489  // of the following actions. We could just wait for the next
14490  // global loop. when this function terminates, the
14491  // requirement will be fulfilled. However, it might be faster
14492  // to insert an inner loop here.
14493  bool changed = true;
14494  while (changed)
14495  {
14496  changed = false;
14497  active_cell_iterator cell = last_active(), endc = end();
14498 
14499  for (; cell != endc; --cell)
14500  if (cell->refine_flag_set())
14501  {
14502  // loop over neighbors of cell
14503  for (unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell;
14504  ++i)
14505  {
14506  // only do something if the face is not at the
14507  // boundary and if the face will be refined with
14508  // the RefineCase currently flagged for
14509  const bool has_periodic_neighbor =
14510  cell->has_periodic_neighbor(i);
14511  const bool has_neighbor_or_periodic_neighbor =
14512  !cell->at_boundary(i) || has_periodic_neighbor;
14513  if (has_neighbor_or_periodic_neighbor &&
14515  cell->refine_flag_set(), i) !=
14517  {
14518  // 1) if the neighbor has children: nothing to
14519  // worry about. 2) if the neighbor is active
14520  // and a coarser one, ensure, that its
14521  // refine_flag is set 3) if the neighbor is
14522  // active and as refined along the face as our
14523  // current cell, make sure, that no
14524  // coarsen_flag is set. if we remove the
14525  // coarsen flag of our neighbor,
14526  // fix_coarsen_flags() makes sure, that the
14527  // mother cell will not be coarsened
14528  if (cell->neighbor_or_periodic_neighbor(i)->active())
14529  {
14530  if ((!has_periodic_neighbor &&
14531  cell->neighbor_is_coarser(i)) ||
14532  (has_periodic_neighbor &&
14533  cell->periodic_neighbor_is_coarser(i)))
14534  {
14535  if (cell->neighbor_or_periodic_neighbor(i)
14536  ->coarsen_flag_set())
14537  cell->neighbor_or_periodic_neighbor(i)
14538  ->clear_coarsen_flag();
14539  // we'll set the refine flag for this
14540  // neighbor below. we note, that we
14541  // have changed something by setting
14542  // the changed flag to true. We do not
14543  // need to do so, if we just removed
14544  // the coarsen flag, as the changed
14545  // flag only indicates the need to
14546  // re-run the inner loop. however, we
14547  // only loop over cells flagged for
14548  // refinement here, so nothing to
14549  // worry about if we remove coarsen
14550  // flags
14551 
14552  if (dim == 2)
14553  {
14554  if (smooth_grid &
14555  allow_anisotropic_smoothing)
14556  changed =
14557  has_periodic_neighbor ?
14558  cell->periodic_neighbor(i)
14559  ->flag_for_face_refinement(
14560  cell
14561  ->periodic_neighbor_of_coarser_periodic_neighbor(
14562  i)
14563  .first,
14565  cell->neighbor(i)
14566  ->flag_for_face_refinement(
14567  cell
14568  ->neighbor_of_coarser_neighbor(
14569  i)
14570  .first,
14572  else
14573  {
14574  if (!cell
14575  ->neighbor_or_periodic_neighbor(
14576  i)
14577  ->refine_flag_set())
14578  changed = true;
14579  cell->neighbor_or_periodic_neighbor(i)
14580  ->set_refine_flag();
14581  }
14582  }
14583  else // i.e. if (dim==3)
14584  {
14585  // ugly situations might arise here,
14586  // consider the following situation, which
14587  // shows neighboring cells at the common
14588  // face, where the upper right element is
14589  // coarser at the given face. Now the upper
14590  // child element of the lower left wants to
14591  // refine according to cut_z, such that
14592  // there is a 'horizontal' refinement of the
14593  // face marked with #####
14594  //
14595  // / /
14596  // / /
14597  // *---------------*
14598  // | |
14599  // | |
14600  // | |
14601  // | |
14602  // | |
14603  // | | /
14604  // | |/
14605  // *---------------*
14606  //
14607  //
14608  // *---------------*
14609  // /| /|
14610  // / | ##### / |
14611  // | |
14612  // *---------------*
14613  // /| /|
14614  // / | / |
14615  // | |
14616  // *---------------*
14617  // / /
14618  // / /
14619  //
14620  // this introduces too many hanging nodes
14621  // and the neighboring (coarser) cell (upper
14622  // right) has to be refined. If it is only
14623  // refined according to cut_z, then
14624  // everything is ok:
14625  //
14626  // / /
14627  // / /
14628  // *---------------*
14629  // | |
14630  // | | /
14631  // | |/
14632  // *---------------*
14633  // | |
14634  // | | /
14635  // | |/
14636  // *---------------*
14637  //
14638  //
14639  // *---------------*
14640  // /| /|
14641  // / *---------------*
14642  // /| /|
14643  // *---------------*
14644  // /| /|
14645  // / | / |
14646  // | |
14647  // *---------------*
14648  // / /
14649  // / /
14650  //
14651  // if however the cell wants to refine
14652  // itself in an other way, or if we disallow
14653  // anisotropic smoothing, then simply
14654  // refining the neighbor isotropically is
14655  // not going to work, since this introduces
14656  // a refinement of face ##### with both
14657  // cut_x and cut_y, which is not possible:
14658  //
14659  // / / /
14660  // / / /
14661  // *-------*-------*
14662  // | | |
14663  // | | | /
14664  // | | |/
14665  // *-------*-------*
14666  // | | |
14667  // | | | /
14668  // | | |/
14669  // *-------*-------*
14670  //
14671  //
14672  // *---------------*
14673  // /| /|
14674  // / *---------------*
14675  // /| /|
14676  // *---------------*
14677  // /| /|
14678  // / | / |
14679  // | |
14680  // *---------------*
14681  // / /
14682  // / /
14683  //
14684  // thus, in this case we also need to refine
14685  // our current cell in the new direction:
14686  //
14687  // / / /
14688  // / / /
14689  // *-------*-------*
14690  // | | |
14691  // | | | /
14692  // | | |/
14693  // *-------*-------*
14694  // | | |
14695  // | | | /
14696  // | | |/
14697  // *-------*-------*
14698  //
14699  //
14700  // *-------*-------*
14701  // /| /| /|
14702  // / *-------*-------*
14703  // /| /| /|
14704  // *-------*-------*
14705  // /| / /|
14706  // / | / |
14707  // | |
14708  // *---------------*
14709  // / /
14710  // / /
14711 
14712  std::pair<unsigned int, unsigned int>
14713  nb_indices =
14714  has_periodic_neighbor ?
14715  cell
14716  ->periodic_neighbor_of_coarser_periodic_neighbor(
14717  i) :
14718  cell->neighbor_of_coarser_neighbor(i);
14719  unsigned int refined_along_x = 0,
14720  refined_along_y = 0,
14721  to_be_refined_along_x = 0,
14722  to_be_refined_along_y = 0;
14723 
14724  const int this_face_index =
14725  cell->face_index(i);
14726 
14727  // step 1: detect, along which axis the face
14728  // is currently refined
14729 
14730  // first, we need an iterator pointing to
14731  // the parent face. This requires a slight
14732  // detour in case the neighbor is behind a
14733  // periodic face.
14734  const auto parent_face = [&]() {
14735  if (has_periodic_neighbor)
14736  {
14737  const auto neighbor =
14738  cell->periodic_neighbor(i);
14739  const auto parent_face_no =
14740  neighbor
14741  ->periodic_neighbor_of_periodic_neighbor(
14742  nb_indices.first);
14743  auto parent =
14744  neighbor->periodic_neighbor(
14745  nb_indices.first);
14746  return parent->face(parent_face_no);
14747  }
14748  else
14749  return cell->neighbor(i)->face(
14750  nb_indices.first);
14751  }();
14752 
14753  if ((this_face_index ==
14754  parent_face->child_index(0)) ||
14755  (this_face_index ==
14756  parent_face->child_index(1)))
14757  {
14758  // this might be an
14759  // anisotropic child. get the
14760  // face refine case of the
14761  // neighbors face and count
14762  // refinements in x and y
14763  // direction.
14764  RefinementCase<dim - 1> frc =
14765  parent_face->refinement_case();
14766  if (frc & RefinementCase<dim>::cut_x)
14767  ++refined_along_x;
14768  if (frc & RefinementCase<dim>::cut_y)
14769  ++refined_along_y;
14770  }
14771  else
14772  // this has to be an isotropic
14773  // child
14774  {
14775  ++refined_along_x;
14776  ++refined_along_y;
14777  }
14778  // step 2: detect, along which axis the face
14779  // has to be refined given the current
14780  // refine flag
14781  RefinementCase<dim - 1> flagged_frc =
14783  cell->refine_flag_set(),
14784  i,
14785  cell->face_orientation(i),
14786  cell->face_flip(i),
14787  cell->face_rotation(i));
14788  if (flagged_frc &
14790  ++to_be_refined_along_x;
14791  if (flagged_frc &
14793  ++to_be_refined_along_y;
14794 
14795  // step 3: set the refine flag of the
14796  // (coarser and active) neighbor.
14797  if ((smooth_grid &
14798  allow_anisotropic_smoothing) ||
14799  cell->neighbor_or_periodic_neighbor(i)
14800  ->refine_flag_set())
14801  {
14802  if (refined_along_x +
14803  to_be_refined_along_x >
14804  1)
14805  changed |=
14806  cell
14807  ->neighbor_or_periodic_neighbor(i)
14808  ->flag_for_face_refinement(
14809  nb_indices.first,
14810  RefinementCase<dim -
14811  1>::cut_axis(0));
14812  if (refined_along_y +
14813  to_be_refined_along_y >
14814  1)
14815  changed |=
14816  cell
14817  ->neighbor_or_periodic_neighbor(i)
14818  ->flag_for_face_refinement(
14819  nb_indices.first,
14820  RefinementCase<dim -
14821  1>::cut_axis(1));
14822  }
14823  else
14824  {
14825  if (cell
14826  ->neighbor_or_periodic_neighbor(i)
14827  ->refine_flag_set() !=
14829  dim>::isotropic_refinement)
14830  changed = true;
14831  cell->neighbor_or_periodic_neighbor(i)
14832  ->set_refine_flag();
14833  }
14834 
14835  // step 4: if necessary (see above) add to
14836  // the refine flag of the current cell
14837  cell_iterator nb =
14838  cell->neighbor_or_periodic_neighbor(i);
14839  RefinementCase<dim - 1> nb_frc =
14841  nb->refine_flag_set(),
14842  nb_indices.first,
14843  nb->face_orientation(nb_indices.first),
14844  nb->face_flip(nb_indices.first),
14845  nb->face_rotation(nb_indices.first));
14846  if ((nb_frc & RefinementCase<dim>::cut_x) &&
14847  !(refined_along_x ||
14848  to_be_refined_along_x))
14849  changed |= cell->flag_for_face_refinement(
14850  i,
14852  if ((nb_frc & RefinementCase<dim>::cut_y) &&
14853  !(refined_along_y ||
14854  to_be_refined_along_y))
14855  changed |= cell->flag_for_face_refinement(
14856  i,
14858  }
14859  } // if neighbor is coarser
14860  else // -> now the neighbor is not coarser
14861  {
14862  cell->neighbor_or_periodic_neighbor(i)
14863  ->clear_coarsen_flag();
14864  const unsigned int nb_nb =
14865  has_periodic_neighbor ?
14866  cell
14867  ->periodic_neighbor_of_periodic_neighbor(
14868  i) :
14869  cell->neighbor_of_neighbor(i);
14870  const cell_iterator neighbor =
14871  cell->neighbor_or_periodic_neighbor(i);
14872  RefinementCase<dim - 1> face_ref_case =
14874  neighbor->refine_flag_set(),
14875  nb_nb,
14876  neighbor->face_orientation(nb_nb),
14877  neighbor->face_flip(nb_nb),
14878  neighbor->face_rotation(nb_nb));
14879  RefinementCase<dim - 1> needed_face_ref_case =
14881  cell->refine_flag_set(),
14882  i,
14883  cell->face_orientation(i),
14884  cell->face_flip(i),
14885  cell->face_rotation(i));
14886  // if the neighbor wants to refine the
14887  // face with cut_x and we want cut_y
14888  // or vice versa, we have to refine
14889  // isotropically at the given face
14890  if ((face_ref_case ==
14892  needed_face_ref_case ==
14894  (face_ref_case ==
14896  needed_face_ref_case ==
14898  {
14899  changed = cell->flag_for_face_refinement(
14900  i, face_ref_case);
14901  neighbor->flag_for_face_refinement(
14902  nb_nb, needed_face_ref_case);
14903  }
14904  }
14905  }
14906  else //-> the neighbor is not active
14907  {
14908  RefinementCase<dim - 1>
14909  face_ref_case = cell->face(i)->refinement_case(),
14910  needed_face_ref_case =
14912  cell->refine_flag_set(),
14913  i,
14914  cell->face_orientation(i),
14915  cell->face_flip(i),
14916  cell->face_rotation(i));
14917  // if the face is refined with cut_x and
14918  // we want cut_y or vice versa, we have to
14919  // refine isotropically at the given face
14920  if ((face_ref_case == RefinementCase<dim>::cut_x &&
14921  needed_face_ref_case ==
14923  (face_ref_case == RefinementCase<dim>::cut_y &&
14924  needed_face_ref_case ==
14926  changed =
14927  cell->flag_for_face_refinement(i,
14928  face_ref_case);
14929  }
14930  }
14931  }
14932  }
14933  }
14934 
14936  // STEP 7:
14937  // take care that no double refinement
14938  // is done at each line in 3d or higher
14939  // dimensions.
14942 
14944  // STEP 8:
14945  // make sure that all children of each
14946  // cell are either flagged for coarsening
14947  // or none of the children is
14948  fix_coarsen_flags();
14949  // get the refinement and coarsening
14950  // flags
14951  std::vector<bool> flags_after_loop[2];
14952  save_coarsen_flags(flags_after_loop[0]);
14953  save_refine_flags(flags_after_loop[1]);
14954 
14955  // find out whether something was
14956  // changed in this loop
14957  mesh_changed_in_this_loop =
14958  ((flags_before_loop[0] != flags_after_loop[0]) ||
14959  (flags_before_loop[1] != flags_after_loop[1]));
14960 
14961  // set the flags for the next loop
14962  // already
14963  flags_before_loop[0].swap(flags_after_loop[0]);
14964  flags_before_loop[1].swap(flags_after_loop[1]);
14965  }
14966  while (mesh_changed_in_this_loop);
14967 
14968 
14969  // find out whether something was really changed in this
14970  // function. Note that @p{flags_before_loop} represents the state
14971  // after the last loop, i.e. the present state
14972  return ((flags_before[0] != flags_before_loop[0]) ||
14973  (flags_before[1] != flags_before_loop[1]));
14974 }
14975 
14976 
14977 
14978 template <int dim, int spacedim>
14979 void
14981  const unsigned int magic_number1,
14982  const std::vector<bool> &v,
14983  const unsigned int magic_number2,
14984  std::ostream & out)
14985 {
14986  const unsigned int N = v.size();
14987  unsigned char * flags = new unsigned char[N / 8 + 1];
14988  for (unsigned int i = 0; i < N / 8 + 1; ++i)
14989  flags[i] = 0;
14990 
14991  for (unsigned int position = 0; position < N; ++position)
14992  flags[position / 8] |= (v[position] ? (1 << (position % 8)) : 0);
14993 
14994  AssertThrow(out, ExcIO());
14995 
14996  // format:
14997  // 0. magic number
14998  // 1. number of flags
14999  // 2. the flags
15000  // 3. magic number
15001  out << magic_number1 << ' ' << N << std::endl;
15002  for (unsigned int i = 0; i < N / 8 + 1; ++i)
15003  out << static_cast<unsigned int>(flags[i]) << ' ';
15004 
15005  out << std::endl << magic_number2 << std::endl;
15006 
15007  delete[] flags;
15008 
15009  AssertThrow(out, ExcIO());
15010 }
15011 
15012 
15013 template <int dim, int spacedim>
15014 void
15015 Triangulation<dim, spacedim>::read_bool_vector(const unsigned int magic_number1,
15016  std::vector<bool> &v,
15017  const unsigned int magic_number2,
15018  std::istream & in)
15019 {
15020  AssertThrow(in, ExcIO());
15021 
15022  unsigned int magic_number;
15023  in >> magic_number;
15024  AssertThrow(magic_number == magic_number1, ExcGridReadError());
15025 
15026  unsigned int N;
15027  in >> N;
15028  v.resize(N);
15029 
15030  unsigned char * flags = new unsigned char[N / 8 + 1];
15031  unsigned short int tmp;
15032  for (unsigned int i = 0; i < N / 8 + 1; ++i)
15033  {
15034  in >> tmp;
15035  flags[i] = tmp;
15036  }
15037 
15038  for (unsigned int position = 0; position != N; ++position)
15039  v[position] = (flags[position / 8] & (1 << (position % 8)));
15040 
15041  in >> magic_number;
15042  AssertThrow(magic_number == magic_number2, ExcGridReadError());
15043 
15044  delete[] flags;
15045 
15046  AssertThrow(in, ExcIO());
15047 }
15048 
15049 
15050 
15051 template <int dim, int spacedim>
15052 std::size_t
15054 {
15055  std::size_t mem = 0;
15057  for (unsigned int i = 0; i < levels.size(); ++i)
15058  mem += MemoryConsumption::memory_consumption(*levels[i]);
15059  mem += MemoryConsumption::memory_consumption(vertices);
15060  mem += MemoryConsumption::memory_consumption(vertices_used);
15061  mem += sizeof(manifold);
15062  mem += sizeof(smooth_grid);
15063  mem += MemoryConsumption::memory_consumption(number_cache);
15064  mem += sizeof(faces);
15065  if (faces)
15067 
15068  return mem;
15069 }
15070 
15071 
15072 // explicit instantiations
15073 #include "tria.inst"
15074 
15075 DEAL_II_NAMESPACE_CLOSE
std::vector< CellData< 1 > > boundary_lines
Definition: tria.h:258
static ::ExceptionBase & ExcInconsistentQuadInfoOfQuad(int arg1, int arg2, int arg3, int arg4, std::string arg5)
::internal::TriangulationImplementation::NumberCache< dim > number_cache
Definition: tria.h:3998
unsigned int n_active_cells() const
Definition: tria.cc:12545
boost::signals2::signal< void()> post_refinement
Definition: tria.h:2214
virtual void copy_triangulation(const Triangulation< dim, spacedim > &other_tria)
Definition: tria.cc:10421
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
unsigned int n_used_vertices() const
Definition: tria.cc:13129
const types::manifold_id flat_manifold_id
Definition: types.h:246
static const unsigned int invalid_unsigned_int
Definition: types.h:173
void load_user_flags_line(std::istream &in)
Definition: tria.cc:11188
unsigned int manifold_id
Definition: types.h:123
#define AssertNothrow(cond, exc)
Definition: exceptions.h:1471
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:541
static ::ExceptionBase & ExcInternalErrorOnCell(int arg1)
hex_iterator begin_hex(const unsigned int level=0) const
Definition: tria.cc:12439
const types::subdomain_id invalid_subdomain_id
Definition: types.h:258
void clear_user_flags()
Definition: tria.cc:11044
active_face_iterator begin_active_face() const
Definition: tria.cc:12112
typename IteratorSelector::line_iterator line_iterator
Definition: tria.h:1592
virtual void create_triangulation_compatibility(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
Definition: tria.cc:10484
void save_user_flags_quad(std::ostream &out) const
Definition: tria.cc:11297
virtual bool has_hanging_nodes() const
Definition: tria.cc:12677
unsigned int n_raw_cells(const unsigned int level) const
Definition: tria.cc:12618
cell_iterator last() const
Definition: tria.cc:11903
void save_user_pointers_hex(std::vector< void *> &v) const
Definition: tria.cc:11804
vertex_iterator begin_vertex() const
Definition: tria.cc:12166
static void prepare_refinement_dim_dependent(const Triangulation< dim, spacedim > &)
Definition: tria.cc:9785
static RefinementCase< 1 > line_refinement_case(const RefinementCase< dim > &cell_refinement_case, const unsigned int line_no)
unsigned int n_cells() const
Definition: tria.cc:12537
static ::ExceptionBase & ExcIO()
Subscriptor & operator=(const Subscriptor &)
Definition: subscriptor.h:283
Task< RT > new_task(const std::function< RT()> &function)
std::vector< Point< spacedim > > vertices
Definition: tria.h:3963
std::map< types::manifold_id, std::unique_ptr< const Manifold< dim, spacedim > > > manifold
Definition: tria.h:3975
typename IteratorSelector::hex_iterator hex_iterator
Definition: tria.h:1640
static unsigned int line_to_cell_vertices(const unsigned int line, const unsigned int vertex)
IteratorRange< active_cell_iterator > active_cell_iterators() const
Definition: tria.cc:12055
void set_all_refine_flags()
Definition: tria.cc:10704
void load_user_flags(std::istream &in)
Definition: tria.cc:11104
typename IteratorSelector::active_line_iterator active_line_iterator
Definition: tria.h:1607
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const =0
bool anisotropic_refinement
Definition: tria.h:3980
int face(const unsigned int i) const
Definition: tria_object.h:168
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:15015
line_iterator begin_line(const unsigned int level=0) const
Definition: tria.cc:12248
line_iterator end_line() const
Definition: tria.cc:12280
void join() const
void clear_user_flags_quad()
Definition: tria.cc:10995
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:4198
unsigned int n_faces() const
Definition: tria.cc:12561
static ::ExceptionBase & ExcCellHasNegativeMeasure(int arg1)
void flip_all_direction_flags()
Definition: tria.cc:10692
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: tria.cc:11883
#define AssertThrow(cond, exc)
Definition: exceptions.h:1519
static ::ExceptionBase & ExcInvalidVertexIndex(int arg1, int arg2, int arg3)
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 1 > &number_cache)
Definition: tria.cc:1401
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:14980
unsigned int n_active_hexs() const
Definition: tria.cc:13061
void save_user_pointers_quad(std::vector< void *> &v) const
Definition: tria.cc:11769
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
static ::ExceptionBase & ExcFacesHaveNoLevel()
void execute_coarsening()
Definition: tria.cc:13437
static Triangulation< 2, spacedim >::DistortedCellList execute_refinement(Triangulation< 2, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:4887
cell_iterator begin(const unsigned int level=0) const
Definition: tria.cc:11863
void load_user_flags_quad(std::istream &in)
Definition: tria.cc:11311
#define DeclException5( Exception5, type1, type2, type3, type4, type5, outsequence)
Definition: exceptions.h:613
void set_manifold(const types::manifold_id number, const Manifold< dim, spacedim > &manifold_object)
Definition: tria.cc:10216
raw_hex_iterator begin_raw_hex(const unsigned int level=0) const
Definition: tria.cc:12393
void load_user_pointers_line(const std::vector< void *> &v)
Definition: tria.cc:11754
unsigned int n_active_faces() const
Definition: tria.cc:12599
raw_quad_iterator begin_raw_quad(const unsigned int level=0) const
Definition: tria.cc:12294
std::unique_ptr<::internal::TriangulationImplementation::TriaFaces< dim > > faces
Definition: tria.h:3957
static ::ExceptionBase & ExcInteriorQuadCantBeBoundary(int arg1, int arg2, int arg3, int arg4, types::boundary_id arg5)
cell_iterator end() const
Definition: tria.cc:11949
static ::ExceptionBase & ExcInconsistentLineInfoOfLine(int arg1, int arg2, std::string arg3)
virtual void add_periodicity(const std::vector< GridTools::PeriodicFacePair< cell_iterator >> &)
Definition: tria.cc:13238
static Triangulation< 3, spacedim >::DistortedCellList execute_refinement(Triangulation< 3, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:5215
void load_coarsen_flags(std::istream &out)
Definition: tria.cc:10837
void load_user_flags_hex(std::istream &in)
Definition: tria.cc:11380
active_quad_iterator begin_active_quad(const unsigned int level=0) const
Definition: tria.cc:12364
virtual void execute_coarsening_and_refinement()
Definition: tria.cc:13267
static ::ExceptionBase & ExcGridHasInvalidCell(int arg1)
unsigned int n_active_lines() const
Definition: tria.cc:12781
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
Definition: tria.cc:12066
virtual bool prepare_coarsening_and_refinement()
Definition: tria.cc:13973
static ::ExceptionBase & ExcMessage(std::string arg1)
bool check_consistency(const unsigned int dim) const
Definition: tria.cc:47
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
void reset_active_cell_indices()
Definition: tria.cc:13308
DistortedCellList execute_refinement()
Definition: tria.cc:13405
unsigned int subdomain_id
Definition: types.h:43
void save_user_flags_line(std::ostream &out) const
Definition: tria.cc:11174
void save_user_pointers_line(std::vector< void *> &v) const
Definition: tria.cc:11740
Triangulation(const MeshSmoothing smooth_grid=none, const bool check_for_distorted_cells=false)
Definition: tria.cc:10077
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:518
void clear_user_flags_hex()
Definition: tria.cc:11035
void load_user_indices_line(const std::vector< unsigned int > &v)
Definition: tria.cc:11542
vertex_iterator end_vertex() const
Definition: tria.cc:12193
unsigned int n_raw_quads() const
Definition: tria.cc:12996
virtual void create_triangulation(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
Definition: tria.cc:10504
#define Assert(cond, exc)
Definition: exceptions.h:1407
Signals signals
Definition: tria.h:2394
active_hex_iterator begin_active_hex(const unsigned int level=0) const
Definition: tria.cc:12455
void save_user_indices_line(std::vector< unsigned int > &v) const
Definition: tria.cc:11528
static void prevent_distorted_boundary_cells(const Triangulation< 1, spacedim > &)
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)
boost::signals2::signal< void()> clear
Definition: tria.h:2277
void set_all_manifold_ids(const types::manifold_id number)
Definition: tria.cc:10258
static ::ExceptionBase & ExcInteriorLineCantBeBoundary(int arg1, int arg2, types::boundary_id arg3)
unsigned int n_raw_hexs(const unsigned int level) const
Definition: tria.cc:13053
unsigned int max_adjacent_cells() const
Definition: tria.cc:13176
bool get_anisotropic_refinement_flag() const
Definition: tria.cc:10869
std::list< typename Triangulation< dim, spacedim >::cell_iterator > distorted_cells
Definition: tria.h:1686
unsigned int n_quads() const
Definition: tria.cc:12947
std::unique_ptr< std::map< unsigned int, types::manifold_id > > vertex_to_manifold_id_map_1d
Definition: tria.h:4038
std::vector< bool > vertices_used
Definition: tria.h:3968
static void alternating_form_at_vertices(const Point< spacedim >(&vertices)[vertices_per_cell], Tensor< spacedim - dim, spacedim >(&forms)[vertices_per_cell])
void save_coarsen_flags(std::ostream &out) const
Definition: tria.cc:10823
void reset_all_manifolds()
Definition: tria.cc:10250
typename IteratorSelector::active_quad_iterator active_quad_iterator
Definition: tria.h:1631
void save_user_indices(std::vector< unsigned int > &v) const
Definition: tria.cc:11416
boost::signals2::signal< void()> mesh_movement
Definition: tria.h:2231
void load_user_indices(const std::vector< unsigned int > &v)
Definition: tria.cc:11448
void save_refine_flags(std::ostream &out) const
Definition: tria.cc:10755
unsigned int n_lines() const
Definition: tria.cc:12689
static ::ExceptionBase & ExcMultiplySetLineInfoOfLine(int arg1, int arg2)
void clear_despite_subscriptions()
Definition: tria.cc:13389
raw_cell_iterator begin_raw(const unsigned int level=0) const
Definition: tria.cc:11843
unsigned int n_raw_lines() const
Definition: tria.cc:12762
virtual std::size_t memory_consumption() const
Definition: tria.cc:15053
IteratorRange< active_face_iterator > active_face_iterators() const
Definition: tria.cc:12154
typename IteratorSelector::quad_iterator quad_iterator
Definition: tria.h:1616
virtual void set_mesh_smoothing(const MeshSmoothing mesh_smoothing)
Definition: tria.cc:10195
void load_user_pointers_hex(const std::vector< void *> &v)
Definition: tria.cc:11822
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:1906
void save_user_flags_hex(std::ostream &out) const
Definition: tria.cc:11366
face_iterator begin_face() const
Definition: tria.cc:12091
boost::signals2::signal< void()> create
Definition: tria.h:2198
std::unique_ptr< std::map< unsigned int, types::boundary_id > > vertex_to_boundary_id_map_1d
Definition: tria.h:4015
virtual types::global_dof_index n_global_active_cells() const
Definition: tria.cc:12552
unsigned int n_hexs() const
Definition: tria.cc:13035
std::vector< std::unique_ptr< ::internal::TriangulationImplementation::TriaLevel< dim > > > levels
Definition: tria.h:3949
unsigned int n_active_quads() const
Definition: tria.cc:13015
active_line_iterator begin_active_line(const unsigned int level=0) const
Definition: tria.cc:12264
raw_cell_iterator end_raw(const unsigned int level) const
Definition: tria.cc:11960
unsigned int n_raw_faces() const
Definition: tria.cc:12580
void load_user_indices_hex(const std::vector< unsigned int > &v)
Definition: tria.cc:11609
static ::ExceptionBase & ExcLineInexistant(int arg1, int arg2)
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
typename IteratorSelector::active_hex_iterator active_hex_iterator
Definition: tria.h:1651
void swap(Vector< Number > &u, Vector< Number > &v)
Definition: vector.h:1376
active_vertex_iterator begin_active_vertex() const
Definition: tria.cc:12183
void reset_manifold(const types::manifold_id manifold_number)
Definition: tria.cc:10238
unsigned int global_dof_index
Definition: types.h:89
static bool coarsening_allowed(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
Definition: tria.cc:9995
void load_user_pointers_quad(const std::vector< void *> &v)
Definition: tria.cc:11787
void fix_coarsen_flags()
Definition: tria.cc:13512
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:2286
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:1696
active_cell_iterator end_active(const unsigned int level) const
Definition: tria.cc:12018
void update_periodic_face_map()
Definition: tria.cc:13326
std::vector< unsigned int > n_active_hexes_level
Definition: tria.h:467
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 3 > &number_cache)
Definition: tria.cc:1596
Definition: mpi.h:90
void save_user_indices_quad(std::vector< unsigned int > &v) const
Definition: tria.cc:11556
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)
const std::vector< bool > & get_used_vertices() const
Definition: tria.cc:13142
hex_iterator end_hex() const
Definition: tria.cc:12471
std::vector< CellData< 2 > > boundary_quads
Definition: tria.h:266
MeshSmoothing smooth_grid
Definition: tria.h:3568
virtual ~Triangulation() override
Definition: tria.cc:10151
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:587
IteratorRange< active_cell_iterator > active_cell_iterators_on_level(const unsigned int level) const
Definition: tria.cc:12077
void load_user_pointers(const std::vector< void *> &v)
Definition: tria.cc:11703
std::vector< unsigned int > n_active_lines_level
Definition: tria.h:348
void refine_global(const unsigned int times=1)
Definition: tria.cc:10721
void save_user_pointers(std::vector< void *> &v) const
Definition: tria.cc:11672
void save_user_flags(std::ostream &out) const
Definition: tria.cc:11055
static RefinementCase< dim > min_cell_refinement_case_for_face_refinement(const RefinementCase< dim - 1 > &face_refinement_case, const unsigned int face_no, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static ::ExceptionBase & ExcNotImplemented()
Iterator points to a valid object.
quad_iterator end_quad() const
Definition: tria.cc:12380
Definition: table.h:37
IteratorRange< cell_iterator > cell_iterators() const
Definition: tria.cc:12046
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:564
face_iterator end_face() const
Definition: tria.cc:12133
void set_all_manifold_ids_on_boundary(const types::manifold_id number)
Definition: tria.cc:10277
static ::ExceptionBase & ExcQuadInexistant(int arg1, int arg2, int arg3, int arg4)
active_cell_iterator last_active() const
Definition: tria.cc:11928
const types::boundary_id internal_face_boundary_id
Definition: types.h:223
std::vector< unsigned int > n_active_quads_level
Definition: tria.h:407
void clear_user_flags_line()
Definition: tria.cc:10954
IteratorState::IteratorStates state() const
quad_iterator begin_quad(const unsigned int level=0) const
Definition: tria.cc:12348
static Triangulation< 1, spacedim >::DistortedCellList execute_refinement(Triangulation< 1, spacedim > &triangulation, const bool)
Definition: tria.cc:4641
void clear()
Definition: tensor.h:1437
void set_face(const unsigned int i, const int index)
Definition: tria_object.h:179
unsigned int boundary_id
Definition: types.h:111
void clear_user_data()
Definition: tria.cc:10919
Triangulation & operator=(Triangulation< dim, spacedim > &&tria) noexcept
Definition: tria.cc:10126
std::vector< types::manifold_id > get_manifold_ids() const
Definition: tria.cc:10398
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:3322
const Manifold< dim, spacedim > & get_manifold(const types::manifold_id number) const
Definition: tria.cc:10342
void load_user_indices_quad(const std::vector< unsigned int > &v)
Definition: tria.cc:11574
virtual types::subdomain_id locally_owned_subdomain() const
Definition: tria.cc:13211
std::vector< types::boundary_id > get_boundary_ids() const
Definition: tria.cc:10365
boost::signals2::signal< void()> any_change
Definition: tria.h:2288
raw_line_iterator begin_raw_line(const unsigned int level=0) const
Definition: tria.cc:12208
virtual void clear()
Definition: tria.cc:10180
virtual const MeshSmoothing & get_mesh_smoothing() const
Definition: tria.cc:10207
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
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:13258
void load_refine_flags(std::istream &in)
Definition: tria.cc:10769
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
static ::ExceptionBase & ExcInternalError()
Triangulation< dim, spacedim > & get_triangulation()
Definition: tria.cc:13220
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 2 > &number_cache)
Definition: tria.cc:1489
void save_user_indices_hex(std::vector< unsigned int > &v) const
Definition: tria.cc:11591