Reference documentation for deal.II version 9.1.0-pre
tria.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2018 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 #include <deal.II/base/table.h>
21 
22 #include <deal.II/fe/mapping_q1.h>
23 
24 #include <deal.II/grid/grid_tools.h>
25 #include <deal.II/grid/magic_numbers.h>
26 #include <deal.II/grid/manifold.h>
27 #include <deal.II/grid/tria.h>
28 #include <deal.II/grid/tria_accessor.h>
29 #include <deal.II/grid/tria_faces.h>
30 #include <deal.II/grid/tria_iterator.h>
31 #include <deal.II/grid/tria_levels.h>
32 
33 #include <deal.II/lac/full_matrix.h>
34 #include <deal.II/lac/vector.h>
35 
36 #include <algorithm>
37 #include <array>
38 #include <cmath>
39 #include <functional>
40 #include <list>
41 #include <map>
42 #include <numeric>
43 
44 
45 DEAL_II_NAMESPACE_OPEN
46 
47 bool
48 SubCellData::check_consistency(const unsigned int dim) const
49 {
50  switch (dim)
51  {
52  case 1:
53  return ((boundary_lines.size() == 0) && (boundary_quads.size() == 0));
54  case 2:
55  return (boundary_quads.size() == 0);
56  };
57  return true;
58 }
59 
60 
61 namespace internal
62 {
63  namespace TriangulationImplementation
64  {
66  : n_levels(0)
67  , n_lines(0)
68  , n_active_lines(0)
69  // all other fields are
70  // default constructed
71  {}
72 
73 
74 
75  std::size_t
77  {
78  return (MemoryConsumption::memory_consumption(n_levels) +
82  MemoryConsumption::memory_consumption(n_active_lines_level));
83  }
84 
85 
87  : n_quads(0)
88  , n_active_quads(0)
89  // all other fields are
90  // default constructed
91  {}
92 
93 
94 
95  std::size_t
97  {
101  MemoryConsumption::memory_consumption(n_active_quads) +
102  MemoryConsumption::memory_consumption(n_active_quads_level));
103  }
104 
105 
106 
108  : n_hexes(0)
109  , n_active_hexes(0)
110  // all other fields are
111  // default constructed
112  {}
113 
114 
115 
116  std::size_t
118  {
122  MemoryConsumption::memory_consumption(n_active_hexes) +
123  MemoryConsumption::memory_consumption(n_active_hexes_level));
124  }
125  } // namespace TriangulationImplementation
126 } // namespace internal
127 
128 // anonymous namespace for internal helper functions
129 namespace
130 {
131  // return whether the given cell is
132  // patch_level_1, i.e. determine
133  // whether either all or none of
134  // its children are further
135  // refined. this function can only
136  // be called for non-active cells.
137  template <int dim, int spacedim>
138  bool
139  cell_is_patch_level_1(
141  {
142  Assert(cell->active() == false, ExcInternalError());
143 
144  unsigned int n_active_children = 0;
145  for (unsigned int i = 0; i < cell->n_children(); ++i)
146  if (cell->child(i)->active())
147  ++n_active_children;
148 
149  return (n_active_children == 0) ||
150  (n_active_children == cell->n_children());
151  }
152 
153 
154 
155  // return, whether a given @p cell will be
156  // coarsened, which is the case if all
157  // children are active and have their coarsen
158  // flag set. In case only part of the coarsen
159  // flags are set, remove them.
160  template <int dim, int spacedim>
161  bool
162  cell_will_be_coarsened(
164  {
165  // only cells with children should be
166  // considered for coarsening
167 
168  if (cell->has_children())
169  {
170  unsigned int children_to_coarsen = 0;
171  const unsigned int n_children = cell->n_children();
172 
173  for (unsigned int c = 0; c < n_children; ++c)
174  if (cell->child(c)->active() && cell->child(c)->coarsen_flag_set())
175  ++children_to_coarsen;
176  if (children_to_coarsen == n_children)
177  return true;
178  else
179  for (unsigned int c = 0; c < n_children; ++c)
180  if (cell->child(c)->active())
181  cell->child(c)->clear_coarsen_flag();
182  }
183  // no children, so no coarsening
184  // possible. however, no children also
185  // means that this cell will be in the same
186  // state as if it had children and was
187  // coarsened. So, what should we return -
188  // false or true?
189  // make sure we do not have to do this at
190  // all...
191  Assert(cell->has_children(), ExcInternalError());
192  // ... and then simply return false
193  return false;
194  }
195 
196 
197  // return, whether the face @p face_no of the
198  // given @p cell will be refined after the
199  // current refinement step, considering
200  // refine and coarsen flags and considering
201  // only those refinemnts that will be caused
202  // by the neighboring cell.
203 
204  // this function is used on both active cells
205  // and cells with children. on cells with
206  // children it also of interest to know 'how'
207  // the face will be refined. thus there is an
208  // additional third argument @p
209  // expected_face_ref_case returning just
210  // that. be aware, that this vriable will
211  // only contain useful information if this
212  // function is called for an active cell.
213  //
214  // thus, this is an internal function, users
215  // should call one of the two alternatives
216  // following below.
217  template <int dim, int spacedim>
218  bool
219  face_will_be_refined_by_neighbor_internal(
221  const unsigned int face_no,
222  RefinementCase<dim - 1> &expected_face_ref_case)
223  {
224  // first of all: set the default value for
225  // expected_face_ref_case, which is no
226  // refinement at all
227  expected_face_ref_case = RefinementCase<dim - 1>::no_refinement;
228 
229  const typename Triangulation<dim, spacedim>::cell_iterator neighbor =
230  cell->neighbor(face_no);
231 
232  // If we are at the boundary, there is no
233  // neighbor which could refine the face
234  if (neighbor.state() != IteratorState::valid)
235  return false;
236 
237  if (neighbor->has_children())
238  {
239  // if the neighbor is refined, it may be
240  // coarsened. if so, then it won't refine
241  // the face, no matter what else happens
242  if (cell_will_be_coarsened(neighbor))
243  return false;
244  else
245  // if the neighor is refined, then he
246  // is also refined at our current
247  // face. He will stay so without
248  // coarsening, so return true in that
249  // case.
250  {
251  expected_face_ref_case = cell->face(face_no)->refinement_case();
252  return true;
253  }
254  }
255 
256  // now, the neighbor is not refined, but
257  // perhaps he will be
258  const RefinementCase<dim> nb_ref_flag = neighbor->refine_flag_set();
259  if (nb_ref_flag != RefinementCase<dim>::no_refinement)
260  {
261  // now we need to know, which of the
262  // neighbors faces points towards us
263  const unsigned int neighbor_neighbor = cell->neighbor_face_no(face_no);
264  // check, whether the cell will be
265  // refined in a way that refines our
266  // face
267  const RefinementCase<dim - 1> face_ref_case =
269  nb_ref_flag,
270  neighbor_neighbor,
271  neighbor->face_orientation(neighbor_neighbor),
272  neighbor->face_flip(neighbor_neighbor),
273  neighbor->face_rotation(neighbor_neighbor));
274  if (face_ref_case != RefinementCase<dim - 1>::no_refinement)
275  {
277  neighbor_face = neighbor->face(neighbor_neighbor);
278  const int this_face_index = cell->face_index(face_no);
279 
280  // there are still two basic
281  // possibilities here: the neighbor
282  // might be coarser or as coarse
283  // as we are
284  if (neighbor_face->index() == this_face_index)
285  // the neighbor is as coarse as
286  // we are and will be refined at
287  // the face of consideration, so
288  // return true
289  {
290  expected_face_ref_case = face_ref_case;
291  return true;
292  }
293  else
294  {
295  // the neighbor is coarser.
296  // this is the most complicated
297  // case. It might be, that the
298  // neighbor's face will be
299  // refined, but that we will
300  // not see this, as we are
301  // refined in a similar way.
302 
303  // so, the neighbor's face must
304  // have children. check, if our
305  // cell's face is one of these
306  // (it could also be a
307  // grand_child)
308  for (unsigned int c = 0; c < neighbor_face->n_children(); ++c)
309  if (neighbor_face->child_index(c) == this_face_index)
310  {
311  // if the flagged refine
312  // case of the face is a
313  // subset or the same as
314  // the current refine case,
315  // then the face, as seen
316  // from our cell, won't be
317  // refined by the neighbor
318  if ((neighbor_face->refinement_case() | face_ref_case) ==
319  neighbor_face->refinement_case())
320  return false;
321  else
322  {
323  // if we are active, we
324  // must be an
325  // anisotropic child
326  // and the coming
327  // face_ref_case is
328  // isotropic. Thus,
329  // from our cell we
330  // will see exactly the
331  // opposite refine case
332  // that the face has
333  // now...
334  Assert(
335  face_ref_case ==
337  ExcInternalError());
338  expected_face_ref_case =
339  ~neighbor_face->refinement_case();
340  return true;
341  }
342  }
343 
344  // so, obviously we were not
345  // one of the children, but a
346  // grandchild. This is only
347  // possible in 3d.
348  Assert(dim == 3, ExcInternalError());
349  // In that case, however, no
350  // matter what the neighbor
351  // does, he won't be finer
352  // after the next refinement
353  // step.
354  return false;
355  }
356  } // if face will be refined
357  } // if neighbor is flagged for refinement
358 
359  // no cases left, so the neighbor will not
360  // refine the face
361  return false;
362  }
363 
364  // version of above function for both active
365  // and non-active cells
366  template <int dim, int spacedim>
367  bool
368  face_will_be_refined_by_neighbor(
370  const unsigned int face_no)
371  {
372  RefinementCase<dim - 1> dummy = RefinementCase<dim - 1>::no_refinement;
373  return face_will_be_refined_by_neighbor_internal(cell, face_no, dummy);
374  }
375 
376  // version of above function for active cells
377  // only. Additionally returning the refine
378  // case (to come) of the face under
379  // consideration
380  template <int dim, int spacedim>
381  bool
382  face_will_be_refined_by_neighbor(
384  const unsigned int face_no,
385  RefinementCase<dim - 1> &expected_face_ref_case)
386  {
387  return face_will_be_refined_by_neighbor_internal(cell,
388  face_no,
389  expected_face_ref_case);
390  }
391 
392 
393 
394  template <int dim, int spacedim>
395  bool
396  satisfies_level1_at_vertex_rule(
397  const Triangulation<dim, spacedim> &triangulation)
398  {
399  std::vector<unsigned int> min_adjacent_cell_level(
400  triangulation.n_vertices(), triangulation.n_levels());
401  std::vector<unsigned int> max_adjacent_cell_level(
402  triangulation.n_vertices(), 0);
403 
405  triangulation.begin_active();
406  cell != triangulation.end();
407  ++cell)
408  for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; ++v)
409  {
410  min_adjacent_cell_level[cell->vertex_index(v)] =
411  std::min<unsigned int>(
412  min_adjacent_cell_level[cell->vertex_index(v)], cell->level());
413  max_adjacent_cell_level[cell->vertex_index(v)] =
414  std::max<unsigned int>(
415  min_adjacent_cell_level[cell->vertex_index(v)], cell->level());
416  }
417 
418  for (unsigned int k = 0; k < triangulation.n_vertices(); ++k)
419  if (triangulation.vertex_used(k))
420  if (max_adjacent_cell_level[k] - min_adjacent_cell_level[k] > 1)
421  return false;
422  return true;
423  }
424 
425 
426 
433  template <int dim, int spacedim>
434  std::vector<unsigned int>
435  count_cells_bounded_by_line(const Triangulation<dim, spacedim> &triangulation)
436  {
437  if (dim >= 2)
438  {
439  std::vector<unsigned int> line_cell_count(triangulation.n_raw_lines(),
440  0);
442  cell = triangulation.begin(),
443  endc = triangulation.end();
444  for (; cell != endc; ++cell)
445  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
446  ++line_cell_count[cell->line_index(l)];
447  return line_cell_count;
448  }
449  else
450  return std::vector<unsigned int>();
451  }
452 
453 
454 
461  template <int dim, int spacedim>
462  std::vector<unsigned int>
463  count_cells_bounded_by_quad(const Triangulation<dim, spacedim> &triangulation)
464  {
465  if (dim >= 3)
466  {
467  std::vector<unsigned int> quad_cell_count(triangulation.n_raw_quads(),
468  0);
470  cell = triangulation.begin(),
471  endc = triangulation.end();
472  for (; cell != endc; ++cell)
473  for (unsigned int q = 0; q < GeometryInfo<dim>::faces_per_cell; ++q)
474  ++quad_cell_count[cell->quad_index(q)];
475  return quad_cell_count;
476  }
477  else
478  return std::vector<unsigned int>();
479  }
480 
481 
482 
494  void
495  reorder_compatibility(const std::vector<CellData<1>> &, const SubCellData &)
496  {
497  // nothing to do here: the format
498  // hasn't changed for 1d
499  }
500 
501 
502  void reorder_compatibility(std::vector<CellData<2>> &cells,
503  const SubCellData &)
504  {
505  for (unsigned int cell = 0; cell < cells.size(); ++cell)
506  std::swap(cells[cell].vertices[2], cells[cell].vertices[3]);
507  }
508 
509 
510  void reorder_compatibility(std::vector<CellData<3>> &cells,
511  SubCellData & subcelldata)
512  {
513  unsigned int tmp[GeometryInfo<3>::vertices_per_cell];
514  for (unsigned int cell = 0; cell < cells.size(); ++cell)
515  {
516  for (unsigned int i = 0; i < GeometryInfo<3>::vertices_per_cell; ++i)
517  tmp[i] = cells[cell].vertices[i];
518  for (unsigned int i = 0; i < GeometryInfo<3>::vertices_per_cell; ++i)
519  cells[cell].vertices[GeometryInfo<3>::ucd_to_deal[i]] = tmp[i];
520  }
521 
522  // now points in boundary quads
523  std::vector<CellData<2>>::iterator boundary_quad =
524  subcelldata.boundary_quads.begin();
525  std::vector<CellData<2>>::iterator end_quad =
526  subcelldata.boundary_quads.end();
527  for (unsigned int quad_no = 0; boundary_quad != end_quad;
528  ++boundary_quad, ++quad_no)
529  std::swap(boundary_quad->vertices[2], boundary_quad->vertices[3]);
530  }
531 
532 
533 
551  template <int dim, int spacedim>
552  unsigned int
553  middle_vertex_index(
554  const typename Triangulation<dim, spacedim>::line_iterator &line)
555  {
556  if (line->has_children())
557  return line->child(0)->vertex_index(1);
559  }
560 
561 
562  template <int dim, int spacedim>
563  unsigned int
564  middle_vertex_index(
565  const typename Triangulation<dim, spacedim>::quad_iterator &quad)
566  {
567  switch (static_cast<unsigned char>(quad->refinement_case()))
568  {
570  return middle_vertex_index<dim, spacedim>(quad->child(0)->line(1));
571  break;
573  return middle_vertex_index<dim, spacedim>(quad->child(0)->line(3));
574  break;
576  return quad->child(0)->vertex_index(3);
577  break;
578  default:
579  break;
580  }
582  }
583 
584 
585  template <int dim, int spacedim>
586  unsigned int
587  middle_vertex_index(
588  const typename Triangulation<dim, spacedim>::hex_iterator &hex)
589  {
590  switch (static_cast<unsigned char>(hex->refinement_case()))
591  {
593  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(1));
594  break;
596  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(3));
597  break;
599  return middle_vertex_index<dim, spacedim>(hex->child(0)->quad(5));
600  break;
602  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(11));
603  break;
605  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(5));
606  break;
608  return middle_vertex_index<dim, spacedim>(hex->child(0)->line(7));
609  break;
611  return hex->child(0)->vertex_index(7);
612  break;
613  default:
614  break;
615  }
617  }
618 
619 
632  template <class TRIANGULATION>
633  inline typename TRIANGULATION::DistortedCellList
634  collect_distorted_coarse_cells(const TRIANGULATION &)
635  {
636  return typename TRIANGULATION::DistortedCellList();
637  }
638 
639 
640 
649  template <int dim>
651  collect_distorted_coarse_cells(const Triangulation<dim, dim> &triangulation)
652  {
653  typename Triangulation<dim, dim>::DistortedCellList distorted_cells;
654  for (typename Triangulation<dim, dim>::cell_iterator cell =
655  triangulation.begin(0);
656  cell != triangulation.end(0);
657  ++cell)
658  {
660  for (unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
661  vertices[i] = cell->vertex(i);
662 
664  GeometryInfo<dim>::alternating_form_at_vertices(vertices, determinants);
665 
666  for (unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
667  if (determinants[i] <= 1e-9 * std::pow(cell->diameter(), 1. * dim))
668  {
669  distorted_cells.distorted_cells.push_back(cell);
670  break;
671  }
672  }
673 
674  return distorted_cells;
675  }
676 
677 
684  template <int dim>
685  bool
686  has_distorted_children(
687  const typename Triangulation<dim, dim>::cell_iterator &cell,
688  std::integral_constant<int, dim>,
689  std::integral_constant<int, dim>)
690  {
691  Assert(cell->has_children(), ExcInternalError());
692 
693  for (unsigned int c = 0; c < cell->n_children(); ++c)
694  {
696  for (unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
697  vertices[i] = cell->child(c)->vertex(i);
698 
700  GeometryInfo<dim>::alternating_form_at_vertices(vertices, determinants);
701 
702  for (unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
703  if (determinants[i] <=
704  1e-9 * std::pow(cell->child(c)->diameter(), 1. * dim))
705  return true;
706  }
707 
708  return false;
709  }
710 
711 
719  template <int dim, int spacedim>
720  bool
721  has_distorted_children(
723  std::integral_constant<int, dim>,
724  std::integral_constant<int, spacedim>)
725  {
726  return false;
727  }
728 
729 
730 
735  template <int spacedim>
736  void update_neighbors(Triangulation<1, spacedim> &)
737  {}
738 
739 
740  template <int dim, int spacedim>
741  void
742  update_neighbors(Triangulation<dim, spacedim> &triangulation)
743  {
744  // each face can be neighbored on two sides
745  // by cells. according to the face's
746  // intrinsic normal we define the left
747  // neighbor as the one for which the face
748  // normal points outward, and store that
749  // one first; the second one is then
750  // the right neighbor for which the
751  // face normal points inward. This
752  // information depends on the type of cell
753  // and local number of face for the
754  // 'standard ordering and orientation' of
755  // faces and then on the face_orientation
756  // information for the real mesh. Set up a
757  // table to have fast access to those
758  // offsets (0 for left and 1 for
759  // right). Some of the values are invalid
760  // as they reference too large face
761  // numbers, but we just leave them at a
762  // zero value.
763  //
764  // Note, that in 2d for lines as faces the
765  // normal direction given in the
766  // GeometryInfo class is not consistent. We
767  // thus define here that the normal for a
768  // line points to the right if the line
769  // points upwards.
770  //
771  // There is one more point to
772  // consider, however: if we have
773  // dim<spacedim, then we may have
774  // cases where cells are
775  // inverted. In effect, both
776  // cells think they are the left
777  // neighbor of an edge, for
778  // example, which leads us to
779  // forget neighborship
780  // information (a case that shows
781  // this is
782  // codim_one/hanging_nodes_02). We
783  // store whether a cell is
784  // inverted using the
785  // direction_flag, so if a cell
786  // has a false direction_flag,
787  // then we need to invert our
788  // selection whether we are a
789  // left or right neighbor in all
790  // following computations.
791  //
792  // first index: dimension (minus 2)
793  // second index: local face index
794  // third index: face_orientation (false and true)
795  static const unsigned int left_right_offset[2][6][2] = {
796  // quadrilateral
797  {{0, 1}, // face 0, face_orientation = false and true
798  {1, 0}, // face 1, face_orientation = false and true
799  {1, 0}, // face 2, face_orientation = false and true
800  {0, 1}, // face 3, face_orientation = false and true
801  {0, 0}, // face 4, invalid face
802  {0, 0}}, // face 5, invalid face
803  // hexahedron
804  {{0, 1}, {1, 0}, {0, 1}, {1, 0}, {0, 1}, {1, 0}}};
805 
806  // now create a vector of the two active
807  // neighbors (left and right) for each face
808  // and fill it by looping over all cells. For
809  // cases with anisotropic refinement and more
810  // then one cell neighboring at a given side
811  // of the face we will automatically get the
812  // active one on the highest level as we loop
813  // over cells from lower levels first.
814  const typename Triangulation<dim, spacedim>::cell_iterator dummy;
815  std::vector<typename Triangulation<dim, spacedim>::cell_iterator>
816  adjacent_cells(2 * triangulation.n_raw_faces(), dummy);
817 
818  typename Triangulation<dim, spacedim>::cell_iterator cell = triangulation
819  .begin(),
820  endc =
821  triangulation.end();
822  for (; cell != endc; ++cell)
823  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
824  {
825  const typename Triangulation<dim, spacedim>::face_iterator face =
826  cell->face(f);
827 
828  const unsigned int offset =
829  (cell->direction_flag() ?
830  left_right_offset[dim - 2][f][cell->face_orientation(f)] :
831  1 - left_right_offset[dim - 2][f][cell->face_orientation(f)]);
832 
833  adjacent_cells[2 * face->index() + offset] = cell;
834 
835  // if this cell is not refined, but the
836  // face is, then we'll have to set our
837  // cell as neighbor for the child faces
838  // as well. Fortunately the normal
839  // orientation of children will be just
840  // the same.
841  if (dim == 2)
842  {
843  if (cell->active() && face->has_children())
844  {
845  adjacent_cells[2 * face->child(0)->index() + offset] = cell;
846  adjacent_cells[2 * face->child(1)->index() + offset] = cell;
847  }
848  }
849  else // -> dim == 3
850  {
851  // We need the same as in 2d
852  // here. Furthermore, if the face is
853  // refined with cut_x or cut_y then
854  // those children again in the other
855  // direction, and if this cell is
856  // refined isotropically (along the
857  // face) then the neighbor will
858  // (probably) be refined as cut_x or
859  // cut_y along the face. For those
860  // neighboring children cells, their
861  // neighbor will be the current,
862  // inactive cell, as our children are
863  // too fine to be neighbors. Catch that
864  // case by also acting on inactive
865  // cells with isotropic refinement
866  // along the face. If the situation
867  // described is not present, the data
868  // will be overwritten later on when we
869  // visit cells on finer levels, so no
870  // harm will be done.
871  if (face->has_children() &&
872  (cell->active() ||
874  cell->refinement_case(), f) ==
876  {
877  for (unsigned int c = 0; c < face->n_children(); ++c)
878  adjacent_cells[2 * face->child(c)->index() + offset] = cell;
879  if (face->child(0)->has_children())
880  {
881  adjacent_cells[2 * face->child(0)->child(0)->index() +
882  offset] = cell;
883  adjacent_cells[2 * face->child(0)->child(1)->index() +
884  offset] = cell;
885  }
886  if (face->child(1)->has_children())
887  {
888  adjacent_cells[2 * face->child(1)->child(0)->index() +
889  offset] = cell;
890  adjacent_cells[2 * face->child(1)->child(1)->index() +
891  offset] = cell;
892  }
893  } // if cell active and face refined
894  } // else -> dim==3
895  } // for all faces of all cells
896 
897  // now loop again over all cells and set the
898  // corresponding neighbor cell. Note, that we
899  // have to use the opposite of the
900  // left_right_offset in this case as we want
901  // the offset of the neighbor, not our own.
902  for (cell = triangulation.begin(); cell != endc; ++cell)
903  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
904  {
905  const unsigned int offset =
906  (cell->direction_flag() ?
907  left_right_offset[dim - 2][f][cell->face_orientation(f)] :
908  1 - left_right_offset[dim - 2][f][cell->face_orientation(f)]);
909  cell->set_neighbor(
910  f, adjacent_cells[2 * cell->face(f)->index() + 1 - offset]);
911  }
912  }
913 
914 
915  template <int dim, int spacedim>
916  void
917  update_periodic_face_map_recursively(
918  const typename Triangulation<dim, spacedim>::cell_iterator &cell_1,
919  const typename Triangulation<dim, spacedim>::cell_iterator &cell_2,
920  unsigned int n_face_1,
921  unsigned int n_face_2,
922  const std::bitset<3> & orientation,
923  typename std::map<
925  unsigned int>,
926  std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
927  unsigned int>,
928  std::bitset<3>>> &periodic_face_map)
929  {
930  using FaceIterator = typename Triangulation<dim, spacedim>::face_iterator;
931  const FaceIterator face_1 = cell_1->face(n_face_1);
932  const FaceIterator face_2 = cell_2->face(n_face_2);
933 
934  const bool face_orientation = orientation[0];
935  const bool face_flip = orientation[1];
936  const bool face_rotation = orientation[2];
937 
938  Assert((dim != 1) || (face_orientation == true && face_flip == false &&
939  face_rotation == false),
940  ExcMessage("The supplied orientation "
941  "(face_orientation, face_flip, face_rotation) "
942  "is invalid for 1D"));
943 
944  Assert((dim != 2) || (face_orientation == true && face_rotation == false),
945  ExcMessage("The supplied orientation "
946  "(face_orientation, face_flip, face_rotation) "
947  "is invalid for 2D"));
948 
949  Assert(face_1 != face_2, ExcMessage("face_1 and face_2 are equal!"));
950 
951  Assert(face_1->at_boundary() && face_2->at_boundary(),
952  ExcMessage("Periodic faces must be on the boundary"));
953 
954  // insert periodic face pair for both cells
955  using CellFace =
956  std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
957  unsigned int>;
958  const CellFace cell_face_1(cell_1, n_face_1);
959  const CellFace cell_face_2(cell_2, n_face_2);
960  const std::pair<CellFace, std::bitset<3>> cell_face_orientation_2(
961  cell_face_2, orientation);
962 
963  const std::pair<CellFace, std::pair<CellFace, std::bitset<3>>>
964  periodic_faces(cell_face_1, cell_face_orientation_2);
965 
966  // Only one periodic neighbor is allowed
967  Assert(periodic_face_map.count(cell_face_1) == 0, ExcInternalError());
968  periodic_face_map.insert(periodic_faces);
969 
970  // A lookup table on how to go through the child cells depending on the
971  // orientation:
972  // see Documentation of GeometryInfo for details
973 
974  static const int lookup_table_2d[2][2] =
975  // flip:
976  {
977  {0, 1}, // false
978  {1, 0} // true
979  };
980 
981  static const int lookup_table_3d[2][2][2][4] =
982  // orientation flip rotation
983  {{{
984  {0, 2, 1, 3}, // false false false
985  {2, 3, 0, 1} // false false true
986  },
987  {
988  {3, 1, 2, 0}, // false true false
989  {1, 0, 3, 2} // false true true
990  }},
991  {{
992  {0, 1, 2, 3}, // true false false
993  {1, 3, 0, 2} // true false true
994  },
995  {
996  {3, 2, 1, 0}, // true true false
997  {2, 0, 3, 1} // true true true
998  }}};
999 
1000  if (cell_1->has_children())
1001  {
1002  if (cell_2->has_children())
1003  {
1004  // In the case that both faces have children, we loop over all
1005  // children and apply update_periodic_face_map_recursively
1006  // recursively:
1007 
1008  Assert(face_1->n_children() ==
1010  face_2->n_children() ==
1012  ExcNotImplemented());
1013 
1014  for (unsigned int i = 0;
1015  i < GeometryInfo<dim>::max_children_per_face;
1016  ++i)
1017  {
1018  // Lookup the index for the second face
1019  unsigned int j = 0;
1020  switch (dim)
1021  {
1022  case 2:
1023  j = lookup_table_2d[face_flip][i];
1024  break;
1025  case 3:
1026  j = lookup_table_3d[face_orientation][face_flip]
1027  [face_rotation][i];
1028  break;
1029  default:
1030  AssertThrow(false, ExcNotImplemented());
1031  }
1032 
1033  // find subcell ids that belong to the subface indices
1034  unsigned int child_cell_1 =
1036  cell_1->refinement_case(),
1037  n_face_1,
1038  i,
1039  cell_1->face_orientation(n_face_1),
1040  cell_1->face_flip(n_face_1),
1041  cell_1->face_rotation(n_face_1),
1042  face_1->refinement_case());
1043  unsigned int child_cell_2 =
1045  cell_2->refinement_case(),
1046  n_face_2,
1047  j,
1048  cell_2->face_orientation(n_face_2),
1049  cell_2->face_flip(n_face_2),
1050  cell_2->face_rotation(n_face_2),
1051  face_2->refinement_case());
1052 
1053  Assert(cell_1->child(child_cell_1)->face(n_face_1) ==
1054  face_1->child(i),
1055  ExcInternalError());
1056  Assert(cell_2->child(child_cell_2)->face(n_face_2) ==
1057  face_2->child(j),
1058  ExcInternalError());
1059 
1060  // precondition: subcell has the same orientation as cell (so
1061  // that the face numbers coincide) recursive call
1062  update_periodic_face_map_recursively<dim, spacedim>(
1063  cell_1->child(child_cell_1),
1064  cell_2->child(child_cell_2),
1065  n_face_1,
1066  n_face_2,
1067  orientation,
1068  periodic_face_map);
1069  }
1070  }
1071  else // only face_1 has children
1072  {
1073  for (unsigned int i = 0;
1074  i < GeometryInfo<dim>::max_children_per_face;
1075  ++i)
1076  {
1077  // find subcell ids that belong to the subface indices
1078  unsigned int child_cell_1 =
1080  cell_1->refinement_case(),
1081  n_face_1,
1082  i,
1083  cell_1->face_orientation(n_face_1),
1084  cell_1->face_flip(n_face_1),
1085  cell_1->face_rotation(n_face_1),
1086  face_1->refinement_case());
1087 
1088  // recursive call
1089  update_periodic_face_map_recursively<dim, spacedim>(
1090  cell_1->child(child_cell_1),
1091  cell_2,
1092  n_face_1,
1093  n_face_2,
1094  orientation,
1095  periodic_face_map);
1096  }
1097  }
1098  }
1099  }
1100 
1101 
1102 } // end of anonymous namespace
1103 
1104 
1105 namespace internal
1106 {
1107  namespace TriangulationImplementation
1108  {
1109  // make sure that if in the following we
1110  // write Triangulation<dim,spacedim>
1111  // we mean the *class*
1112  // ::Triangulation, not the
1113  // enclosing namespace
1114  // internal::TriangulationImplementation
1115  using ::Triangulation;
1116 
1122  int,
1123  << "Something went wrong when making cell " << arg1
1124  << ". Read the docs and the source code "
1125  << "for more information.");
1131  int,
1132  << "Something went wrong upon construction of cell "
1133  << arg1);
1144  int,
1145  << "Cell " << arg1
1146  << " has negative measure. This typically "
1147  << "indicates some distortion in the cell, or a mistakenly "
1148  << "swapped pair of vertices in the input to "
1149  << "Triangulation::create_triangulation().");
1158  int,
1159  int,
1160  int,
1161  << "Error while creating cell " << arg1
1162  << ": the vertex index " << arg2 << " must be between 0 and "
1163  << arg3 << ".");
1169  int,
1170  int,
1171  << "While trying to assign a boundary indicator to a line: "
1172  << "the line with end vertices " << arg1 << " and " << arg2
1173  << " does not exist.");
1179  int,
1180  int,
1181  int,
1182  int,
1183  << "While trying to assign a boundary indicator to a quad: "
1184  << "the quad with bounding lines " << arg1 << ", " << arg2
1185  << ", " << arg3 << ", " << arg4 << " does not exist.");
1192  int,
1193  int,
1195  << "The input data for creating a triangulation contained "
1196  << "information about a line with indices " << arg1 << " and " << arg2
1197  << " that is described to have boundary indicator " << (int)arg3
1198  << ". However, this is an internal line not located on the "
1199  << "boundary. You cannot assign a boundary indicator to it." << std::endl
1200  << std::endl
1201  << "If this happened at a place where you call "
1202  << "Triangulation::create_triangulation() yourself, you need "
1203  << "to check the SubCellData object you pass to this function."
1204  << std::endl
1205  << std::endl
1206  << "If this happened in a place where you are reading a mesh "
1207  << "from a file, then you need to investigate why such a line "
1208  << "ended up in the input file. A typical case is a geometry "
1209  << "that consisted of multiple parts and for which the mesh "
1210  << "generator program assumes that the interface between "
1211  << "two parts is a boundary when that isn't supposed to be "
1212  << "the case, or where the mesh generator simply assigns "
1213  << "'geometry indicators' to lines at the perimeter of "
1214  << "a part that are not supposed to be interpreted as "
1215  << "'boundary indicators'.");
1222  int,
1223  int,
1224  int,
1225  int,
1227  << "The input data for creating a triangulation contained "
1228  << "information about a quad with indices " << arg1 << ", " << arg2
1229  << ", " << arg3 << ", and " << arg4
1230  << " that is described to have boundary indicator " << (int)arg5
1231  << ". However, this is an internal quad not located on the "
1232  << "boundary. You cannot assign a boundary indicator to it." << std::endl
1233  << std::endl
1234  << "If this happened at a place where you call "
1235  << "Triangulation::create_triangulation() yourself, you need "
1236  << "to check the SubCellData object you pass to this function."
1237  << std::endl
1238  << std::endl
1239  << "If this happened in a place where you are reading a mesh "
1240  << "from a file, then you need to investigate why such a quad "
1241  << "ended up in the input file. A typical case is a geometry "
1242  << "that consisted of multiple parts and for which the mesh "
1243  << "generator program assumes that the interface between "
1244  << "two parts is a boundary when that isn't supposed to be "
1245  << "the case, or where the mesh generator simply assigns "
1246  << "'geometry indicators' to quads at the surface of "
1247  << "a part that are not supposed to be interpreted as "
1248  << "'boundary indicators'.");
1255  int,
1256  int,
1257  << "In SubCellData the line info of the line with vertex indices " << arg1
1258  << " and " << arg2 << " appears more than once. "
1259  << "This is not allowed.");
1260 
1261 
1358  {
1370  template <int dim, int spacedim>
1371  static void
1373  const Triangulation<dim, spacedim> & triangulation,
1374  const unsigned int level_objects,
1376  {
1377  using line_iterator =
1378  typename Triangulation<dim, spacedim>::line_iterator;
1379 
1380  number_cache.n_levels = 0;
1381  if (level_objects > 0)
1382  // find the last level on which there are used cells
1383  for (unsigned int level = 0; level < level_objects; ++level)
1384  if (triangulation.begin(level) != triangulation.end(level))
1385  number_cache.n_levels = level + 1;
1386 
1387  // no cells at all?
1388  Assert(number_cache.n_levels > 0, ExcInternalError());
1389 
1391  // update the number of lines on the different levels in the
1392  // cache
1393  number_cache.n_lines = 0;
1394  number_cache.n_active_lines = 0;
1395 
1396  // for 1d, lines have levels so take count the objects per
1397  // level and globally
1398  if (dim == 1)
1399  {
1400  number_cache.n_lines_level.resize(number_cache.n_levels);
1401  number_cache.n_active_lines_level.resize(number_cache.n_levels);
1402 
1403  for (unsigned int level = 0; level < number_cache.n_levels; ++level)
1404  {
1405  // count lines on this level
1406  number_cache.n_lines_level[level] = 0;
1407  number_cache.n_active_lines_level[level] = 0;
1408 
1409  line_iterator line = triangulation.begin_line(level),
1410  endc =
1411  (level == number_cache.n_levels - 1 ?
1412  line_iterator(triangulation.end_line()) :
1413  triangulation.begin_line(level + 1));
1414  for (; line != endc; ++line)
1415  {
1416  ++number_cache.n_lines_level[level];
1417  if (line->has_children() == false)
1418  ++number_cache.n_active_lines_level[level];
1419  }
1420 
1421  // update total number of lines
1422  number_cache.n_lines += number_cache.n_lines_level[level];
1423  number_cache.n_active_lines +=
1424  number_cache.n_active_lines_level[level];
1425  }
1426  }
1427  else
1428  {
1429  // for dim>1, there are no levels for lines
1430  number_cache.n_lines_level.clear();
1431  number_cache.n_active_lines_level.clear();
1432 
1433  line_iterator line = triangulation.begin_line(),
1434  endc = triangulation.end_line();
1435  for (; line != endc; ++line)
1436  {
1437  ++number_cache.n_lines;
1438  if (line->has_children() == false)
1439  ++number_cache.n_active_lines;
1440  }
1441  }
1442  }
1443 
1458  template <int dim, int spacedim>
1459  static void
1461  const Triangulation<dim, spacedim> & triangulation,
1462  const unsigned int level_objects,
1464  {
1465  // update lines and n_levels in number_cache. since we don't
1466  // access any of these numbers, we can do this in the
1467  // background
1468  Threads::Task<void> update_lines = Threads::new_task(
1469  (void (*)(const Triangulation<dim, spacedim> &,
1470  const unsigned int,
1472  &compute_number_cache<dim, spacedim>),
1473  triangulation,
1474  level_objects,
1476  number_cache));
1477 
1478  using quad_iterator =
1479  typename Triangulation<dim, spacedim>::quad_iterator;
1480 
1482  // update the number of quads on the different levels in the
1483  // cache
1484  number_cache.n_quads = 0;
1485  number_cache.n_active_quads = 0;
1486 
1487  // for 2d, quads have levels so take count the objects per
1488  // level and globally
1489  if (dim == 2)
1490  {
1491  // count the number of levels; the function we called above
1492  // on a separate Task for lines also does this and puts it into
1493  // number_cache.n_levels, but this datum may not yet be
1494  // available as we call the function on a separate task
1495  unsigned int n_levels = 0;
1496  if (level_objects > 0)
1497  // find the last level on which there are used cells
1498  for (unsigned int level = 0; level < level_objects; ++level)
1499  if (triangulation.begin(level) != triangulation.end(level))
1500  n_levels = level + 1;
1501 
1502  number_cache.n_quads_level.resize(n_levels);
1503  number_cache.n_active_quads_level.resize(n_levels);
1504 
1505  for (unsigned int level = 0; level < n_levels; ++level)
1506  {
1507  // count quads on this level
1508  number_cache.n_quads_level[level] = 0;
1509  number_cache.n_active_quads_level[level] = 0;
1510 
1511  quad_iterator quad = triangulation.begin_quad(level),
1512  endc =
1513  (level == n_levels - 1 ?
1514  quad_iterator(triangulation.end_quad()) :
1515  triangulation.begin_quad(level + 1));
1516  for (; quad != endc; ++quad)
1517  {
1518  ++number_cache.n_quads_level[level];
1519  if (quad->has_children() == false)
1520  ++number_cache.n_active_quads_level[level];
1521  }
1522 
1523  // update total number of quads
1524  number_cache.n_quads += number_cache.n_quads_level[level];
1525  number_cache.n_active_quads +=
1526  number_cache.n_active_quads_level[level];
1527  }
1528  }
1529  else
1530  {
1531  // for dim>2, there are no levels for quads
1532  number_cache.n_quads_level.clear();
1533  number_cache.n_active_quads_level.clear();
1534 
1535  quad_iterator quad = triangulation.begin_quad(),
1536  endc = triangulation.end_quad();
1537  for (; quad != endc; ++quad)
1538  {
1539  ++number_cache.n_quads;
1540  if (quad->has_children() == false)
1541  ++number_cache.n_active_quads;
1542  }
1543  }
1544 
1545  // wait for the background computation for lines
1546  update_lines.join();
1547  }
1548 
1564  template <int dim, int spacedim>
1565  static void
1567  const Triangulation<dim, spacedim> & triangulation,
1568  const unsigned int level_objects,
1570  {
1571  // update quads, lines and n_levels in number_cache. since we
1572  // don't access any of these numbers, we can do this in the
1573  // background
1574  Threads::Task<void> update_quads_and_lines = Threads::new_task(
1575  (void (*)(const Triangulation<dim, spacedim> &,
1576  const unsigned int,
1578  &compute_number_cache<dim, spacedim>),
1579  triangulation,
1580  level_objects,
1582  number_cache));
1583 
1584  using hex_iterator =
1585  typename Triangulation<dim, spacedim>::hex_iterator;
1586 
1588  // update the number of hexes on the different levels in the
1589  // cache
1590  number_cache.n_hexes = 0;
1591  number_cache.n_active_hexes = 0;
1592 
1593  // for 3d, hexes have levels so take count the objects per
1594  // level and globally
1595  if (dim == 3)
1596  {
1597  // count the number of levels; the function we called
1598  // above on a separate Task for quads (recursively, via
1599  // the lines function) also does this and puts it into
1600  // number_cache.n_levels, but this datum may not yet be
1601  // available as we call the function on a separate task
1602  unsigned int n_levels = 0;
1603  if (level_objects > 0)
1604  // find the last level on which there are used cells
1605  for (unsigned int level = 0; level < level_objects; ++level)
1606  if (triangulation.begin(level) != triangulation.end(level))
1607  n_levels = level + 1;
1608 
1609  number_cache.n_hexes_level.resize(n_levels);
1610  number_cache.n_active_hexes_level.resize(n_levels);
1611 
1612  for (unsigned int level = 0; level < n_levels; ++level)
1613  {
1614  // count hexes on this level
1615  number_cache.n_hexes_level[level] = 0;
1616  number_cache.n_active_hexes_level[level] = 0;
1617 
1618  hex_iterator hex = triangulation.begin_hex(level),
1619  endc = (level == n_levels - 1 ?
1620  hex_iterator(triangulation.end_hex()) :
1621  triangulation.begin_hex(level + 1));
1622  for (; hex != endc; ++hex)
1623  {
1624  ++number_cache.n_hexes_level[level];
1625  if (hex->has_children() == false)
1626  ++number_cache.n_active_hexes_level[level];
1627  }
1628 
1629  // update total number of hexes
1630  number_cache.n_hexes += number_cache.n_hexes_level[level];
1631  number_cache.n_active_hexes +=
1632  number_cache.n_active_hexes_level[level];
1633  }
1634  }
1635  else
1636  {
1637  // for dim>3, there are no levels for hexes
1638  number_cache.n_hexes_level.clear();
1639  number_cache.n_active_hexes_level.clear();
1640 
1641  hex_iterator hex = triangulation.begin_hex(),
1642  endc = triangulation.end_hex();
1643  for (; hex != endc; ++hex)
1644  {
1645  ++number_cache.n_hexes;
1646  if (hex->has_children() == false)
1647  ++number_cache.n_active_hexes;
1648  }
1649  }
1650 
1651  // wait for the background computation for quads
1652  update_quads_and_lines.join();
1653  }
1654 
1655 
1663  template <int spacedim>
1664  static void
1665  create_triangulation(const std::vector<Point<spacedim>> &v,
1666  const std::vector<CellData<1>> & cells,
1667  const SubCellData & /*subcelldata*/,
1668  Triangulation<1, spacedim> &triangulation)
1669  {
1670  AssertThrow(v.size() > 0, ExcMessage("No vertices given"));
1671  AssertThrow(cells.size() > 0, ExcMessage("No cells given"));
1672 
1673  // note: since no boundary
1674  // information can be given in one
1675  // dimension, the @p{subcelldata}
1676  // field is ignored. (only used for
1677  // error checking, which is a good
1678  // idea in any case)
1679  const unsigned int dim = 1;
1680 
1681  // copy vertices
1682  triangulation.vertices = v;
1683  triangulation.vertices_used = std::vector<bool>(v.size(), true);
1684 
1685  // Check that all cells have positive volume. This check is not run in
1686  // the codimension one or two cases since cell_measure is not
1687  // implemented for those.
1688 #ifndef _MSC_VER
1689  // TODO: The following code does not compile with MSVC. Find a way
1690  // around it
1691  if (dim == spacedim)
1692  {
1693  for (unsigned int cell_no = 0; cell_no < cells.size(); ++cell_no)
1694  {
1695  // If we should check for distorted cells, then we permit them
1696  // to exist. If a cell has negative measure, then it must be
1697  // distorted (the converse is not necessarily true); hence
1698  // throw an exception if no such cells should exist.
1699  if (!triangulation.check_for_distorted_cells)
1700  {
1701  const double cell_measure =
1702  GridTools::cell_measure<1>(triangulation.vertices,
1703  cells[cell_no].vertices);
1704  AssertThrow(cell_measure > 0,
1705  ExcGridHasInvalidCell(cell_no));
1706  }
1707  }
1708  }
1709 #endif
1710 
1711 
1712  // store the indices of the lines
1713  // which are adjacent to a given
1714  // vertex
1715  std::vector<std::vector<int>> lines_at_vertex(v.size());
1716 
1717  // reserve enough space
1718  triangulation.levels.push_back(
1719  std_cxx14::make_unique<
1721  triangulation.levels[0]->reserve_space(cells.size(), dim, spacedim);
1722  triangulation.levels[0]->cells.reserve_space(0, cells.size());
1723 
1724  // make up cells
1725  typename Triangulation<dim, spacedim>::raw_line_iterator
1726  next_free_line = triangulation.begin_raw_line();
1727  for (unsigned int cell = 0; cell < cells.size(); ++cell)
1728  {
1729  while (next_free_line->used())
1730  ++next_free_line;
1731 
1732  next_free_line->set(
1734  cells[cell].vertices[0], cells[cell].vertices[1]));
1735  next_free_line->set_used_flag();
1736  next_free_line->set_material_id(cells[cell].material_id);
1737  next_free_line->set_manifold_id(cells[cell].manifold_id);
1738  next_free_line->clear_user_data();
1739  next_free_line->set_subdomain_id(0);
1740 
1741  // note that this cell is
1742  // adjacent to these vertices
1743  lines_at_vertex[cells[cell].vertices[0]].push_back(cell);
1744  lines_at_vertex[cells[cell].vertices[1]].push_back(cell);
1745  }
1746 
1747 
1748  // some security tests
1749  {
1750  unsigned int boundary_nodes = 0;
1751  for (unsigned int i = 0; i < lines_at_vertex.size(); ++i)
1752  switch (lines_at_vertex[i].size())
1753  {
1754  case 1:
1755  // this vertex has only
1756  // one adjacent line
1757  ++boundary_nodes;
1758  break;
1759  case 2:
1760  break;
1761  default:
1762  AssertThrow(
1763  false,
1764  ExcMessage(
1765  "You have a vertex in your triangulation "
1766  "at which more than two cells come together. "
1767  "(For one dimensional triangulation, cells are "
1768  "line segments.)"
1769  "\n\n"
1770  "This is not currently supported because the "
1771  "Triangulation class makes the assumption that "
1772  "every cell has zero or one neighbors behind "
1773  "each face (here, behind each vertex), but in your "
1774  "situation there would be more than one."
1775  "\n\n"
1776  "Support for this is not currently implemented. "
1777  "If you need to work with triangulations where "
1778  "more than two cells come together at a vertex, "
1779  "duplicate the vertices once per cell (i.e., put "
1780  "multiple vertices at the same physical location, "
1781  "but using different vertex indices for each) "
1782  "and then ensure continuity of the solution by "
1783  "explicitly creating constraints that the degrees "
1784  "of freedom at these vertices have the same "
1785  "value, using the AffineConstraints class."));
1786  }
1787 
1788  // assert there are no more
1789  // than two boundary
1790  // nodes. note that if the
1791  // space dimension is
1792  // bigger than 1, then we
1793  // can have fewer than 2
1794  // nodes (for example a
1795  // ring of cells -- no end
1796  // points at all)
1797  AssertThrow(((spacedim == 1) && (boundary_nodes == 2)) ||
1798  (spacedim > 1),
1799  ExcMessage("The Triangulation has too many end points"));
1800  }
1801 
1802 
1803 
1804  // update neighborship info
1805  typename Triangulation<dim, spacedim>::active_line_iterator line =
1806  triangulation.begin_active_line();
1807  // for all lines
1808  for (; line != triangulation.end(); ++line)
1809  // for each of the two vertices
1810  for (unsigned int vertex = 0;
1811  vertex < GeometryInfo<dim>::vertices_per_cell;
1812  ++vertex)
1813  // if first cell adjacent to
1814  // this vertex is the present
1815  // one, then the neighbor is
1816  // the second adjacent cell and
1817  // vice versa
1818  if (lines_at_vertex[line->vertex_index(vertex)][0] == line->index())
1819  if (lines_at_vertex[line->vertex_index(vertex)].size() == 2)
1820  {
1822  neighbor(&triangulation,
1823  0, // level
1824  lines_at_vertex[line->vertex_index(vertex)][1]);
1825  line->set_neighbor(vertex, neighbor);
1826  }
1827  else
1828  // no second adjacent cell
1829  // entered -> cell at
1830  // boundary
1831  line->set_neighbor(vertex, triangulation.end());
1832  else
1833  // present line is not first
1834  // adjacent one -> first
1835  // adjacent one is neighbor
1836  {
1838  neighbor(&triangulation,
1839  0, // level
1840  lines_at_vertex[line->vertex_index(vertex)][0]);
1841  line->set_neighbor(vertex, neighbor);
1842  }
1843 
1844  // finally set the
1845  // vertex_to_boundary_id_map_1d
1846  // and vertex_to_manifold_id_map_1d
1847  // maps
1848  triangulation.vertex_to_boundary_id_map_1d->clear();
1849  triangulation.vertex_to_manifold_id_map_1d->clear();
1851  triangulation.begin_active();
1852  cell != triangulation.end();
1853  ++cell)
1854  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
1855  {
1856  (*triangulation.vertex_to_manifold_id_map_1d)
1857  [cell->face(f)->vertex_index()] = numbers::invalid_manifold_id;
1858 
1859  if (cell->at_boundary(f))
1860  (*triangulation.vertex_to_boundary_id_map_1d)
1861  [cell->face(f)->vertex_index()] = f;
1862  }
1863  }
1864 
1865 
1873  template <int spacedim>
1874  static void
1875  create_triangulation(const std::vector<Point<spacedim>> &v,
1876  const std::vector<CellData<2>> & cells,
1877  const SubCellData & subcelldata,
1878  Triangulation<2, spacedim> & triangulation)
1879  {
1880  AssertThrow(v.size() > 0, ExcMessage("No vertices given"));
1881  AssertThrow(cells.size() > 0, ExcMessage("No cells given"));
1882 
1883  const unsigned int dim = 2;
1884 
1885  // copy vertices
1886  triangulation.vertices = v;
1887  triangulation.vertices_used = std::vector<bool>(v.size(), true);
1888 
1889  // Check that all cells have positive volume. This check is not run in
1890  // the codimension one or two cases since cell_measure is not
1891  // implemented for those.
1892 #ifndef _MSC_VER
1893  // TODO: The following code does not compile with MSVC. Find a way
1894  // around it
1895  if (dim == spacedim)
1896  {
1897  for (unsigned int cell_no = 0; cell_no < cells.size(); ++cell_no)
1898  {
1899  // See the note in the 1D function on this if statement.
1900  if (!triangulation.check_for_distorted_cells)
1901  {
1902  const double cell_measure =
1903  GridTools::cell_measure<2>(triangulation.vertices,
1904  cells[cell_no].vertices);
1905  AssertThrow(cell_measure > 0,
1906  ExcGridHasInvalidCell(cell_no));
1907  }
1908  }
1909  }
1910 #endif
1911 
1912  // make up a list of the needed
1913  // lines each line is a pair of
1914  // vertices. The list is kept
1915  // sorted and it is guaranteed that
1916  // each line is inserted only once.
1917  // While the key of such an entry
1918  // is the pair of vertices, the
1919  // thing it points to is an
1920  // iterator pointing to the line
1921  // object itself. In the first run,
1922  // these iterators are all invalid
1923  // ones, but they are filled
1924  // afterwards
1925  std::map<std::pair<int, int>,
1926  typename Triangulation<dim, spacedim>::line_iterator>
1927  needed_lines;
1928  for (unsigned int cell = 0; cell < cells.size(); ++cell)
1929  {
1930  for (unsigned int vertex = 0; vertex < 4; ++vertex)
1931  AssertThrow(cells[cell].vertices[vertex] <
1932  triangulation.vertices.size(),
1933  ExcInvalidVertexIndex(cell,
1934  cells[cell].vertices[vertex],
1935  triangulation.vertices.size()));
1936 
1937  for (unsigned int line = 0;
1938  line < GeometryInfo<dim>::faces_per_cell;
1939  ++line)
1940  {
1941  // given a line vertex number (0,1) on a specific line
1942  // we get the cell vertex number (0-4) through the
1943  // line_to_cell_vertices function
1944  std::pair<int, int> line_vertices(
1945  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(
1946  line, 0)],
1947  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(
1948  line, 1)]);
1949 
1950  // assert that the line was not already inserted in
1951  // reverse order. This happens in spite of the vertex
1952  // rotation above, if the sense of the cell was
1953  // incorrect.
1954  //
1955  // Here is what usually happened when this exception
1956  // is thrown: consider these two cells and the
1957  // vertices
1958  // 3---4---5
1959  // | | |
1960  // 0---1---2
1961  // If in the input vector the two cells are given with
1962  // vertices <0 1 3 4> and <4 1 5 2>, in the first cell
1963  // the middle line would have direction 1->4, while in
1964  // the second it would be 4->1. This will cause the
1965  // exception.
1966  AssertThrow(needed_lines.find(std::make_pair(
1967  line_vertices.second, line_vertices.first)) ==
1968  needed_lines.end(),
1969  ExcGridHasInvalidCell(cell));
1970 
1971  // insert line, with
1972  // invalid iterator if line
1973  // already exists, then
1974  // nothing bad happens here
1975  needed_lines[line_vertices] = triangulation.end_line();
1976  }
1977  }
1978 
1979 
1980  // check that every vertex has at
1981  // least two adjacent lines
1982  {
1983  std::vector<unsigned short int> vertex_touch_count(v.size(), 0);
1984  typename std::map<
1985  std::pair<int, int>,
1986  typename Triangulation<dim, spacedim>::line_iterator>::iterator i;
1987  for (i = needed_lines.begin(); i != needed_lines.end(); ++i)
1988  {
1989  // touch the vertices of
1990  // this line
1991  ++vertex_touch_count[i->first.first];
1992  ++vertex_touch_count[i->first.second];
1993  }
1994 
1995  // assert minimum touch count
1996  // is at least two. if not so,
1997  // then clean triangulation and
1998  // exit with an exception
1999  AssertThrow(*(std::min_element(vertex_touch_count.begin(),
2000  vertex_touch_count.end())) >= 2,
2001  ExcMessage(
2002  "During creation of a triangulation, a part of the "
2003  "algorithm encountered a vertex that is part of only "
2004  "a single adjacent line. However, in 2d, every vertex "
2005  "needs to be at least part of two lines."));
2006  }
2007 
2008  // reserve enough space
2009  triangulation.levels.push_back(
2010  std_cxx14::make_unique<
2012  triangulation.faces = std_cxx14::make_unique<
2014  triangulation.levels[0]->reserve_space(cells.size(), dim, spacedim);
2015  triangulation.faces->lines.reserve_space(0, needed_lines.size());
2016  triangulation.levels[0]->cells.reserve_space(0, cells.size());
2017 
2018  // make up lines
2019  {
2020  typename Triangulation<dim, spacedim>::raw_line_iterator line =
2021  triangulation.begin_raw_line();
2022  typename std::map<
2023  std::pair<int, int>,
2024  typename Triangulation<dim, spacedim>::line_iterator>::iterator i;
2025  for (i = needed_lines.begin(); line != triangulation.end_line();
2026  ++line, ++i)
2027  {
2029  i->first.first, i->first.second));
2030  line->set_used_flag();
2031  line->clear_user_flag();
2032  line->clear_user_data();
2033  i->second = line;
2034  }
2035  }
2036 
2037 
2038  // store for each line index
2039  // the adjacent cells
2040  std::map<
2041  int,
2042  std::vector<typename Triangulation<dim, spacedim>::cell_iterator>>
2043  adjacent_cells;
2044 
2045  // finally make up cells
2046  {
2048  triangulation.begin_raw_quad();
2049  for (unsigned int c = 0; c < cells.size(); ++c, ++cell)
2050  {
2051  typename Triangulation<dim, spacedim>::line_iterator
2053  for (unsigned int line = 0;
2054  line < GeometryInfo<dim>::lines_per_cell;
2055  ++line)
2056  lines[line] = needed_lines[std::make_pair(
2057  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2058  line, 0)],
2059  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2060  line, 1)])];
2061 
2063  lines[0]->index(),
2064  lines[1]->index(),
2065  lines[2]->index(),
2066  lines[3]->index()));
2067 
2068  cell->set_used_flag();
2069  cell->set_material_id(cells[c].material_id);
2070  cell->set_manifold_id(cells[c].manifold_id);
2071  cell->clear_user_data();
2072  cell->set_subdomain_id(0);
2073 
2074  // note that this cell is
2075  // adjacent to the four
2076  // lines
2077  for (unsigned int line = 0;
2078  line < GeometryInfo<dim>::lines_per_cell;
2079  ++line)
2080  adjacent_cells[lines[line]->index()].push_back(cell);
2081  }
2082  }
2083 
2084 
2085  for (typename Triangulation<dim, spacedim>::line_iterator line =
2086  triangulation.begin_line();
2087  line != triangulation.end_line();
2088  ++line)
2089  {
2090  const unsigned int n_adj_cells =
2091  adjacent_cells[line->index()].size();
2092 
2093  // assert that every line has one or two adjacent cells.
2094  // this has to be the case for 2d triangulations in 2d.
2095  // in higher dimensions, this may happen but is not
2096  // implemented
2097  if (spacedim == 2)
2098  {
2099  AssertThrow((n_adj_cells >= 1) && (n_adj_cells <= 2),
2100  ExcInternalError());
2101  }
2102  else
2103  {
2104  AssertThrow(
2105  (n_adj_cells >= 1) && (n_adj_cells <= 2),
2106  ExcMessage("You have a line in your triangulation at which "
2107  "more than two cells come together."
2108  "\n\n"
2109  "This is not currently supported because the "
2110  "Triangulation class makes the assumption that "
2111  "every cell has zero or one neighbors behind each "
2112  "face (here, behind each line), but in your "
2113  "situation there would be more than one."
2114  "\n\n"
2115  "Support for this is not currently implemented. "
2116  "If you need to work with triangulations where "
2117  "more than two cells come together at a line, "
2118  "duplicate the vertices once per cell (i.e., put "
2119  "multiple vertices at the same physical location, "
2120  "but using different vertex indices for each) "
2121  "and then ensure continuity of the solution by "
2122  "explicitly creating constraints that the degrees "
2123  "of freedom at these lines have the same "
2124  "value, using the AffineConstraints class."));
2125  }
2126 
2127  // if only one cell: line is at boundary -> give it the boundary
2128  // indicator zero by default
2129  line->set_boundary_id_internal(
2130  (n_adj_cells == 1) ? 0 : numbers::internal_face_boundary_id);
2131  line->set_manifold_id(numbers::flat_manifold_id);
2132  }
2133 
2134  // set boundary indicators where given
2135  for (const auto &subcell_line : subcelldata.boundary_lines)
2136  {
2137  typename Triangulation<dim, spacedim>::line_iterator line;
2138  std::pair<int, int> line_vertices(
2139  std::make_pair(subcell_line.vertices[0],
2140  subcell_line.vertices[1]));
2141  if (needed_lines.find(line_vertices) != needed_lines.end())
2142  // line found in this direction
2143  line = needed_lines[line_vertices];
2144  else
2145  {
2146  // look whether it exists in reverse direction
2147  std::swap(line_vertices.first, line_vertices.second);
2148  if (needed_lines.find(line_vertices) != needed_lines.end())
2149  line = needed_lines[line_vertices];
2150  else
2151  // line does not exist
2152  AssertThrow(false,
2153  ExcLineInexistant(line_vertices.first,
2154  line_vertices.second));
2155  }
2156 
2157  // assert that we only set boundary info once
2158  AssertThrow(!(line->boundary_id() != 0 &&
2159  line->boundary_id() !=
2161  ExcMultiplySetLineInfoOfLine(line_vertices.first,
2162  line_vertices.second));
2163 
2164  // Assert that only exterior lines are given a boundary
2165  // indicator; however, it is possible that someone may
2166  // want to give an interior line a manifold id (and thus
2167  // lists this line in the subcell_data structure), and we
2168  // need to allow that
2169  if (subcell_line.boundary_id != numbers::internal_face_boundary_id)
2170  {
2171  if (line->boundary_id() == numbers::internal_face_boundary_id)
2172  {
2173  // if we are here, it means that we want to assign a
2174  // boundary indicator different from
2175  // numbers::internal_face_boundary_id to an internal line.
2176  // As said, this would be not allowed, and an exception
2177  // should be immediately thrown. Still, there is the
2178  // possibility that one only wants to specify a manifold_id
2179  // here. If that is the case (manifold_id !=
2180  // numbers::flat_manifold_id) the operation is allowed.
2181  // Otherwise, we really tried to specify a boundary_id (and
2182  // not a manifold_id) to an internal face. The exception
2183  // must be thrown.
2184  if (subcell_line.manifold_id == numbers::flat_manifold_id)
2185  {
2186  // If we are here, this assertion will surely fail, for
2187  // the aforementioned reasons
2188  AssertThrow(!(line->boundary_id() ==
2191  line->vertex_index(0),
2192  line->vertex_index(1),
2193  subcell_line.boundary_id));
2194  }
2195  else
2196  {
2197  line->set_manifold_id(subcell_line.manifold_id);
2198  }
2199  }
2200  else
2201  line->set_boundary_id_internal(subcell_line.boundary_id);
2202  }
2203  line->set_manifold_id(subcell_line.manifold_id);
2204  }
2205 
2206 
2207  // finally update neighborship info
2208  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
2209  triangulation.begin();
2210  cell != triangulation.end();
2211  ++cell)
2212  for (unsigned int side = 0; side < 4; ++side)
2213  if (adjacent_cells[cell->line(side)->index()][0] == cell)
2214  // first adjacent cell is
2215  // this one
2216  {
2217  if (adjacent_cells[cell->line(side)->index()].size() == 2)
2218  // there is another
2219  // adjacent cell
2220  cell->set_neighbor(
2221  side, adjacent_cells[cell->line(side)->index()][1]);
2222  }
2223  // first adjacent cell is not this
2224  // one, -> it must be the neighbor
2225  // we are looking for
2226  else
2227  cell->set_neighbor(side,
2228  adjacent_cells[cell->line(side)->index()][0]);
2229  }
2230 
2231 
2243  {
2244  inline bool
2245  operator()(
2248  {
2249  // here is room to
2250  // optimize the repeated
2251  // equality test of the
2252  // previous lines; the
2253  // compiler will probably
2254  // take care of most of
2255  // it anyway
2256  if ((q1.face(0) < q2.face(0)) ||
2257  ((q1.face(0) == q2.face(0)) && (q1.face(1) < q2.face(1))) ||
2258  ((q1.face(0) == q2.face(0)) && (q1.face(1) == q2.face(1)) &&
2259  (q1.face(2) < q2.face(2))) ||
2260  ((q1.face(0) == q2.face(0)) && (q1.face(1) == q2.face(1)) &&
2261  (q1.face(2) == q2.face(2)) && (q1.face(3) < q2.face(3))))
2262  return true;
2263  else
2264  return false;
2265  }
2266  };
2267 
2268 
2276  template <int spacedim>
2277  static void
2278  create_triangulation(const std::vector<Point<spacedim>> &v,
2279  const std::vector<CellData<3>> & cells,
2280  const SubCellData & subcelldata,
2281  Triangulation<3, spacedim> & triangulation)
2282  {
2283  AssertThrow(v.size() > 0, ExcMessage("No vertices given"));
2284  AssertThrow(cells.size() > 0, ExcMessage("No cells given"));
2285 
2286  const unsigned int dim = 3;
2287 
2288  // copy vertices
2289  triangulation.vertices = v;
2290  triangulation.vertices_used = std::vector<bool>(v.size(), true);
2291 
2292  // Check that all cells have positive volume.
2293 #ifndef _MSC_VER
2294  // TODO: The following code does not compile with MSVC. Find a way
2295  // around it
2296  for (unsigned int cell_no = 0; cell_no < cells.size(); ++cell_no)
2297  {
2298  // See the note in the 1D function on this if statement.
2299  if (!triangulation.check_for_distorted_cells)
2300  {
2301  const double cell_measure =
2302  GridTools::cell_measure<3>(triangulation.vertices,
2303  cells[cell_no].vertices);
2304  AssertThrow(cell_measure > 0, ExcGridHasInvalidCell(cell_no));
2305  }
2306  }
2307 #endif
2308 
2310  // first set up some collections of data
2311  //
2312  // make up a list of the needed
2313  // lines
2314  //
2315  // each line is a pair of
2316  // vertices. The list is kept
2317  // sorted and it is guaranteed that
2318  // each line is inserted only once.
2319  // While the key of such an entry
2320  // is the pair of vertices, the
2321  // thing it points to is an
2322  // iterator pointing to the line
2323  // object itself. In the first run,
2324  // these iterators are all invalid
2325  // ones, but they are filled
2326  // afterwards same applies for the
2327  // quads
2328  typename std::map<std::pair<int, int>,
2329  typename Triangulation<dim, spacedim>::line_iterator>
2330  needed_lines;
2331  for (unsigned int cell = 0; cell < cells.size(); ++cell)
2332  {
2333  // check whether vertex indices
2334  // are valid ones
2335  for (unsigned int vertex = 0;
2336  vertex < GeometryInfo<dim>::vertices_per_cell;
2337  ++vertex)
2338  AssertThrow(cells[cell].vertices[vertex] <
2339  triangulation.vertices.size(),
2340  ExcInvalidVertexIndex(cell,
2341  cells[cell].vertices[vertex],
2342  triangulation.vertices.size()));
2343 
2344  for (unsigned int line = 0;
2345  line < GeometryInfo<dim>::lines_per_cell;
2346  ++line)
2347  {
2348  // given a line vertex number
2349  // (0,1) on a specific line we
2350  // get the cell vertex number
2351  // (0-7) through the
2352  // line_to_cell_vertices
2353  // function
2354  std::pair<int, int> line_vertices(
2355  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2356  line, 0)],
2357  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2358  line, 1)]);
2359 
2360  // if that line was already inserted
2361  // in reverse order do nothing, else
2362  // insert the line
2363  if ((needed_lines.find(std::make_pair(line_vertices.second,
2364  line_vertices.first)) ==
2365  needed_lines.end()))
2366  {
2367  // insert line, with
2368  // invalid iterator. if line
2369  // already exists, then
2370  // nothing bad happens here
2371  needed_lines[line_vertices] = triangulation.end_line();
2372  }
2373  }
2374  }
2375 
2376 
2378  // now for some sanity-checks:
2379  //
2380  // check that every vertex has at
2381  // least tree adjacent lines
2382  {
2383  std::vector<unsigned short int> vertex_touch_count(v.size(), 0);
2384  typename std::map<
2385  std::pair<int, int>,
2386  typename Triangulation<dim, spacedim>::line_iterator>::iterator i;
2387  for (i = needed_lines.begin(); i != needed_lines.end(); ++i)
2388  {
2389  // touch the vertices of
2390  // this line
2391  ++vertex_touch_count[i->first.first];
2392  ++vertex_touch_count[i->first.second];
2393  }
2394 
2395  // assert minimum touch count
2396  // is at least three. if not so,
2397  // then clean triangulation and
2398  // exit with an exception
2399  AssertThrow(
2400  *(std::min_element(vertex_touch_count.begin(),
2401  vertex_touch_count.end())) >= 3,
2402  ExcMessage(
2403  "During creation of a triangulation, a part of the "
2404  "algorithm encountered a vertex that is part of only "
2405  "one or two adjacent lines. However, in 3d, every vertex "
2406  "needs to be at least part of three lines."));
2407  }
2408 
2409 
2411  // actually set up data structures
2412  // for the lines
2413  // reserve enough space
2414  triangulation.levels.push_back(
2415  std_cxx14::make_unique<
2417  triangulation.faces = std_cxx14::make_unique<
2419  triangulation.levels[0]->reserve_space(cells.size(), dim, spacedim);
2420  triangulation.faces->lines.reserve_space(0, needed_lines.size());
2421 
2422  // make up lines
2423  {
2424  typename Triangulation<dim, spacedim>::raw_line_iterator line =
2425  triangulation.begin_raw_line();
2426  typename std::map<
2427  std::pair<int, int>,
2428  typename Triangulation<dim, spacedim>::line_iterator>::iterator i;
2429  for (i = needed_lines.begin(); line != triangulation.end_line();
2430  ++line, ++i)
2431  {
2433  i->first.first, i->first.second));
2434  line->set_used_flag();
2435  line->clear_user_flag();
2436  line->clear_user_data();
2437 
2438  // now set the iterator for
2439  // this line
2440  i->second = line;
2441  }
2442  }
2443 
2444 
2446  // make up the quads of this triangulation
2447  //
2448  // same thing: the iterators are
2449  // set to the invalid value at
2450  // first, we only collect the data
2451  // now
2452 
2453  // the bool array stores, whether the lines
2454  // are in the standard orientation or not
2455 
2456  // note that QuadComparator is a
2457  // class declared and defined in
2458  // this file
2459  std::map<internal::TriangulationImplementation::TriaObject<2>,
2460  std::pair<typename Triangulation<dim, spacedim>::quad_iterator,
2461  std::array<bool, GeometryInfo<dim>::lines_per_face>>,
2463  needed_quads;
2464  for (unsigned int cell = 0; cell < cells.size(); ++cell)
2465  {
2466  // the faces are quads which
2467  // consist of four numbers
2468  // denoting the index of the
2469  // four lines bounding the
2470  // quad. we can get this index
2471  // by asking @p{needed_lines}
2472  // for an iterator to this
2473  // line, dereferencing it and
2474  // thus return an iterator into
2475  // the @p{lines} array of the
2476  // triangulation, which is
2477  // already set up. we can then
2478  // ask this iterator for its
2479  // index within the present
2480  // level (the level is zero, of
2481  // course)
2482  //
2483  // to make things easier, we
2484  // don't create the lines
2485  // (pairs of their vertex
2486  // indices) in place, but
2487  // before they are really
2488  // needed.
2489  std::pair<int, int> line_list[GeometryInfo<dim>::lines_per_cell],
2490  inverse_line_list[GeometryInfo<dim>::lines_per_cell];
2491  unsigned int face_line_list[GeometryInfo<dim>::lines_per_face];
2492  std::array<bool, GeometryInfo<dim>::lines_per_face> orientation;
2493 
2494  for (unsigned int line = 0;
2495  line < GeometryInfo<dim>::lines_per_cell;
2496  ++line)
2497  {
2498  line_list[line] = std::pair<int, int>(
2499  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2500  line, 0)],
2501  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2502  line, 1)]);
2503  inverse_line_list[line] = std::pair<int, int>(
2504  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2505  line, 1)],
2506  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2507  line, 0)]);
2508  }
2509 
2510  for (unsigned int face = 0;
2511  face < GeometryInfo<dim>::faces_per_cell;
2512  ++face)
2513  {
2514  // set up a list of the lines to be
2515  // used for this face. check the
2516  // direction for each line
2517  //
2518  // given a face line number (0-3) on
2519  // a specific face we get the cell
2520  // line number (0-11) through the
2521  // face_to_cell_lines function
2522  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_face;
2523  ++l)
2524  if (needed_lines.find(
2525  inverse_line_list[GeometryInfo<dim>::face_to_cell_lines(
2526  face, l)]) == needed_lines.end())
2527  {
2528  face_line_list[l] =
2529  needed_lines[line_list[GeometryInfo<
2530  dim>::face_to_cell_lines(face, l)]]
2531  ->index();
2532  orientation[l] = true;
2533  }
2534  else
2535  {
2536  face_line_list[l] =
2537  needed_lines[inverse_line_list[GeometryInfo<
2538  dim>::face_to_cell_lines(face, l)]]
2539  ->index();
2540  orientation[l] = false;
2541  }
2542 
2543 
2545  face_line_list[0],
2546  face_line_list[1],
2547  face_line_list[2],
2548  face_line_list[3]);
2549 
2550  // insert quad, with
2551  // invalid iterator
2552  //
2553  // if quad already exists,
2554  // then nothing bad happens
2555  // here, as this will then
2556  // simply become an
2557  // interior face of the
2558  // triangulation. however,
2559  // we will run into major
2560  // trouble if the face was
2561  // already inserted in the
2562  // opposite
2563  // direction. there are
2564  // really only two
2565  // orientations for a face
2566  // to be in, since the edge
2567  // directions are already
2568  // set. thus, vertex 0 is
2569  // the one from which two
2570  // edges originate, and
2571  // vertex 3 is the one to
2572  // which they converge. we
2573  // are then left with
2574  // orientations 0-1-2-3 and
2575  // 2-3-0-1 for the order of
2576  // lines. the
2577  // corresponding quad can
2578  // be easily constructed by
2579  // exchanging lines. we do
2580  // so here, just to check
2581  // that that flipped quad
2582  // isn't already in the
2583  // triangulation. if it is,
2584  // then don't insert the
2585  // new one and instead
2586  // later set the
2587  // face_orientation flag
2589  test_quad_1(quad.face(2),
2590  quad.face(3),
2591  quad.face(0),
2592  quad.face(
2593  1)), // face_orientation=false, face_flip=false,
2594  // face_rotation=false
2595  test_quad_2(quad.face(0),
2596  quad.face(1),
2597  quad.face(3),
2598  quad.face(
2599  2)), // face_orientation=false, face_flip=false,
2600  // face_rotation=true
2601  test_quad_3(quad.face(3),
2602  quad.face(2),
2603  quad.face(1),
2604  quad.face(
2605  0)), // face_orientation=false, face_flip=true,
2606  // face_rotation=false
2607  test_quad_4(quad.face(1),
2608  quad.face(0),
2609  quad.face(2),
2610  quad.face(
2611  3)), // face_orientation=false, face_flip=true,
2612  // face_rotation=true
2613  test_quad_5(quad.face(2),
2614  quad.face(3),
2615  quad.face(1),
2616  quad.face(
2617  0)), // face_orientation=true, face_flip=false,
2618  // face_rotation=true
2619  test_quad_6(quad.face(1),
2620  quad.face(0),
2621  quad.face(3),
2622  quad.face(
2623  2)), // face_orientation=true, face_flip=true,
2624  // face_rotation=false
2625  test_quad_7(quad.face(3),
2626  quad.face(2),
2627  quad.face(0),
2628  quad.face(
2629  1)); // face_orientation=true, face_flip=true,
2630  // face_rotation=true
2631  if (needed_quads.find(test_quad_1) == needed_quads.end() &&
2632  needed_quads.find(test_quad_2) == needed_quads.end() &&
2633  needed_quads.find(test_quad_3) == needed_quads.end() &&
2634  needed_quads.find(test_quad_4) == needed_quads.end() &&
2635  needed_quads.find(test_quad_5) == needed_quads.end() &&
2636  needed_quads.find(test_quad_6) == needed_quads.end() &&
2637  needed_quads.find(test_quad_7) == needed_quads.end())
2638  needed_quads[quad] =
2639  std::make_pair(triangulation.end_quad(), orientation);
2640  }
2641  }
2642 
2643 
2645  // enter the resulting quads into
2646  // the arrays of the Triangulation
2647  //
2648  // first reserve enough space
2649  triangulation.faces->quads.reserve_space(0, needed_quads.size());
2650 
2651  {
2652  typename Triangulation<dim, spacedim>::raw_quad_iterator quad =
2653  triangulation.begin_raw_quad();
2654  typename std::map<
2656  std::pair<typename Triangulation<dim, spacedim>::quad_iterator,
2657  std::array<bool, GeometryInfo<dim>::lines_per_face>>,
2658  QuadComparator>::iterator q;
2659  for (q = needed_quads.begin(); quad != triangulation.end_quad();
2660  ++quad, ++q)
2661  {
2662  quad->set(q->first);
2663  quad->set_used_flag();
2664  quad->clear_user_flag();
2665  quad->clear_user_data();
2666  // set the line orientation
2667  quad->set_line_orientation(0, q->second.second[0]);
2668  quad->set_line_orientation(1, q->second.second[1]);
2669  quad->set_line_orientation(2, q->second.second[2]);
2670  quad->set_line_orientation(3, q->second.second[3]);
2671 
2672 
2673  // now set the iterator for
2674  // this quad
2675  q->second.first = quad;
2676  }
2677  }
2678 
2680  // finally create the cells
2681  triangulation.levels[0]->cells.reserve_space(cells.size());
2682 
2683  // store for each quad index the
2684  // adjacent cells
2685  std::map<
2686  int,
2687  std::vector<typename Triangulation<dim, spacedim>::cell_iterator>>
2688  adjacent_cells;
2689 
2690  // finally make up cells
2691  {
2693  triangulation.begin_raw_hex();
2694  for (unsigned int c = 0; c < cells.size(); ++c, ++cell)
2695  {
2696  // first find for each of
2697  // the cells the quad
2698  // iterator of the
2699  // respective faces.
2700  //
2701  // to this end, set up the
2702  // lines of this cell and
2703  // find the quads that are
2704  // bounded by these lines;
2705  // these are then the faces
2706  // of the present cell
2707  std::pair<int, int> line_list[GeometryInfo<dim>::lines_per_cell],
2708  inverse_line_list[GeometryInfo<dim>::lines_per_cell];
2709  unsigned int face_line_list[4];
2710  for (unsigned int line = 0;
2711  line < GeometryInfo<dim>::lines_per_cell;
2712  ++line)
2713  {
2714  line_list[line] = std::make_pair(
2715  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2716  line, 0)],
2717  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2718  line, 1)]);
2719  inverse_line_list[line] = std::pair<int, int>(
2720  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2721  line, 1)],
2722  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(
2723  line, 0)]);
2724  }
2725 
2726  // get the iterators
2727  // corresponding to the
2728  // faces. also store
2729  // whether they are
2730  // reversed or not
2731  typename Triangulation<dim, spacedim>::quad_iterator
2732  face_iterator[GeometryInfo<dim>::faces_per_cell];
2733  bool face_orientation[GeometryInfo<dim>::faces_per_cell];
2734  bool face_flip[GeometryInfo<dim>::faces_per_cell];
2735  bool face_rotation[GeometryInfo<dim>::faces_per_cell];
2736  for (unsigned int face = 0;
2737  face < GeometryInfo<dim>::faces_per_cell;
2738  ++face)
2739  {
2740  for (unsigned int l = 0;
2741  l < GeometryInfo<dim>::lines_per_face;
2742  ++l)
2743  if (needed_lines.find(inverse_line_list[GeometryInfo<
2744  dim>::face_to_cell_lines(face, l)]) ==
2745  needed_lines.end())
2746  face_line_list[l] =
2747  needed_lines[line_list[GeometryInfo<
2748  dim>::face_to_cell_lines(face, l)]]
2749  ->index();
2750  else
2751  face_line_list[l] =
2752  needed_lines[inverse_line_list[GeometryInfo<
2753  dim>::face_to_cell_lines(face, l)]]
2754  ->index();
2755 
2757  face_line_list[0],
2758  face_line_list[1],
2759  face_line_list[2],
2760  face_line_list[3]);
2761 
2762  if (needed_quads.find(quad) != needed_quads.end())
2763  {
2764  // face is in standard
2765  // orientation (and not
2766  // flipped or rotated). this
2767  // must be true for at least
2768  // one of the two cells
2769  // containing this face
2770  // (i.e. for the cell which
2771  // originally inserted the
2772  // face)
2773  face_iterator[face] = needed_quads[quad].first;
2774  face_orientation[face] = true;
2775  face_flip[face] = false;
2776  face_rotation[face] = false;
2777  }
2778  else
2779  {
2780  // face must be available in
2781  // reverse order
2782  // then. construct all
2783  // possibilities and check
2784  // them one after the other
2786  test_quad_1(
2787  quad.face(2),
2788  quad.face(3),
2789  quad.face(0),
2790  quad.face(1)), // face_orientation=false,
2791  // face_flip=false, face_rotation=false
2792  test_quad_2(
2793  quad.face(0),
2794  quad.face(1),
2795  quad.face(3),
2796  quad.face(2)), // face_orientation=false,
2797  // face_flip=false, face_rotation=true
2798  test_quad_3(
2799  quad.face(3),
2800  quad.face(2),
2801  quad.face(1),
2802  quad.face(0)), // face_orientation=false,
2803  // face_flip=true, face_rotation=false
2804  test_quad_4(quad.face(1),
2805  quad.face(0),
2806  quad.face(2),
2807  quad.face(
2808  3)), // face_orientation=false,
2809  // face_flip=true, face_rotation=true
2810  test_quad_5(
2811  quad.face(2),
2812  quad.face(3),
2813  quad.face(1),
2814  quad.face(0)), // face_orientation=true,
2815  // face_flip=false, face_rotation=true
2816  test_quad_6(
2817  quad.face(1),
2818  quad.face(0),
2819  quad.face(3),
2820  quad.face(2)), // face_orientation=true,
2821  // face_flip=true, face_rotation=false
2822  test_quad_7(quad.face(3),
2823  quad.face(2),
2824  quad.face(0),
2825  quad.face(
2826  1)); // face_orientation=true,
2827  // face_flip=true, face_rotation=true
2828  if (needed_quads.find(test_quad_1) != needed_quads.end())
2829  {
2830  face_iterator[face] = needed_quads[test_quad_1].first;
2831  face_orientation[face] = false;
2832  face_flip[face] = false;
2833  face_rotation[face] = false;
2834  }
2835  else if (needed_quads.find(test_quad_2) !=
2836  needed_quads.end())
2837  {
2838  face_iterator[face] = needed_quads[test_quad_2].first;
2839  face_orientation[face] = false;
2840  face_flip[face] = false;
2841  face_rotation[face] = true;
2842  }
2843  else if (needed_quads.find(test_quad_3) !=
2844  needed_quads.end())
2845  {
2846  face_iterator[face] = needed_quads[test_quad_3].first;
2847  face_orientation[face] = false;
2848  face_flip[face] = true;
2849  face_rotation[face] = false;
2850  }
2851  else if (needed_quads.find(test_quad_4) !=
2852  needed_quads.end())
2853  {
2854  face_iterator[face] = needed_quads[test_quad_4].first;
2855  face_orientation[face] = false;
2856  face_flip[face] = true;
2857  face_rotation[face] = true;
2858  }
2859  else if (needed_quads.find(test_quad_5) !=
2860  needed_quads.end())
2861  {
2862  face_iterator[face] = needed_quads[test_quad_5].first;
2863  face_orientation[face] = true;
2864  face_flip[face] = false;
2865  face_rotation[face] = true;
2866  }
2867  else if (needed_quads.find(test_quad_6) !=
2868  needed_quads.end())
2869  {
2870  face_iterator[face] = needed_quads[test_quad_6].first;
2871  face_orientation[face] = true;
2872  face_flip[face] = true;
2873  face_rotation[face] = false;
2874  }
2875  else if (needed_quads.find(test_quad_7) !=
2876  needed_quads.end())
2877  {
2878  face_iterator[face] = needed_quads[test_quad_7].first;
2879  face_orientation[face] = true;
2880  face_flip[face] = true;
2881  face_rotation[face] = true;
2882  }
2883 
2884  else
2885  // we didn't find the
2886  // face in any direction,
2887  // so something went
2888  // wrong above
2889  Assert(false, ExcInternalError());
2890  }
2891  } // for all faces
2892 
2893  // make the cell out of
2894  // these iterators
2896  face_iterator[0]->index(),
2897  face_iterator[1]->index(),
2898  face_iterator[2]->index(),
2899  face_iterator[3]->index(),
2900  face_iterator[4]->index(),
2901  face_iterator[5]->index()));
2902 
2903  cell->set_used_flag();
2904  cell->set_material_id(cells[c].material_id);
2905  cell->set_manifold_id(cells[c].manifold_id);
2906  cell->clear_user_flag();
2907  cell->clear_user_data();
2908  cell->set_subdomain_id(0);
2909 
2910  // set orientation flag for
2911  // each of the faces
2912  for (unsigned int quad = 0;
2913  quad < GeometryInfo<dim>::faces_per_cell;
2914  ++quad)
2915  {
2916  cell->set_face_orientation(quad, face_orientation[quad]);
2917  cell->set_face_flip(quad, face_flip[quad]);
2918  cell->set_face_rotation(quad, face_rotation[quad]);
2919  }
2920 
2921 
2922  // note that this cell is
2923  // adjacent to the six
2924  // quads
2925  for (unsigned int quad = 0;
2926  quad < GeometryInfo<dim>::faces_per_cell;
2927  ++quad)
2928  adjacent_cells[face_iterator[quad]->index()].push_back(cell);
2929 
2930 #ifdef DEBUG
2931  // make some checks on the
2932  // lines and their
2933  // ordering
2934 
2935  // first map all cell lines
2936  // to the two face lines
2937  // which should
2938  // coincide. all face lines
2939  // are included with a cell
2940  // line number (0-11)
2941  // key. At the end all keys
2942  // will be included twice
2943  // (for each of the two
2944  // coinciding lines once)
2945  std::multimap<unsigned int, std::pair<unsigned int, unsigned int>>
2946  cell_to_face_lines;
2947  for (unsigned int face = 0;
2948  face < GeometryInfo<dim>::faces_per_cell;
2949  ++face)
2950  for (unsigned int line = 0;
2951  line < GeometryInfo<dim>::lines_per_face;
2952  ++line)
2953  cell_to_face_lines.insert(
2954  std::pair<unsigned int,
2955  std::pair<unsigned int, unsigned int>>(
2957  std::pair<unsigned int, unsigned int>(face, line)));
2958  std::multimap<unsigned int,
2959  std::pair<unsigned int, unsigned int>>::
2960  const_iterator map_iter = cell_to_face_lines.begin();
2961 
2962  for (; map_iter != cell_to_face_lines.end(); ++map_iter)
2963  {
2964  const unsigned int cell_line = map_iter->first;
2965  const unsigned int face1 = map_iter->second.first;
2966  const unsigned int line1 = map_iter->second.second;
2967  ++map_iter;
2968  Assert(map_iter != cell_to_face_lines.end(),
2970  Assert(map_iter->first == cell_line,
2972  const unsigned int face2 = map_iter->second.first;
2973  const unsigned int line2 = map_iter->second.second;
2974 
2975  // check that the pair
2976  // of lines really
2977  // coincide. Take care
2978  // about the face
2979  // orientation;
2980  Assert(face_iterator[face1]->line(
2982  line1,
2983  face_orientation[face1],
2984  face_flip[face1],
2985  face_rotation[face1])) ==
2986  face_iterator[face2]->line(
2988  line2,
2989  face_orientation[face2],
2990  face_flip[face2],
2991  face_rotation[face2])),
2993  }
2994 #endif
2995  }
2996  }
2997 
2998 
3000  // find those quads which are at the
3001  // boundary and mark them appropriately
3002  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
3003  triangulation.begin_quad();
3004  quad != triangulation.end_quad();
3005  ++quad)
3006  {
3007  const unsigned int n_adj_cells =
3008  adjacent_cells[quad->index()].size();
3009  // assert that every quad has
3010  // one or two adjacent cells
3011  AssertThrow((n_adj_cells >= 1) && (n_adj_cells <= 2),
3012  ExcInternalError());
3013 
3014  // if only one cell: quad is at boundary -> give it the boundary
3015  // indicator zero by default
3016  quad->set_boundary_id_internal(
3017  (n_adj_cells == 1) ? 0 : numbers::internal_face_boundary_id);
3018 
3019  // Manifold ids are set independently of where they are
3020  quad->set_manifold_id(numbers::flat_manifold_id);
3021  }
3022 
3024  // next find those lines which are at
3025  // the boundary and mark all others as
3026  // interior ones
3027  //
3028  // for this: first mark all lines as interior. use this loop
3029  // to also set all manifold ids of all lines
3030  for (typename Triangulation<dim, spacedim>::line_iterator line =
3031  triangulation.begin_line();
3032  line != triangulation.end_line();
3033  ++line)
3034  {
3035  line->set_boundary_id_internal(numbers::internal_face_boundary_id);
3036  line->set_manifold_id(numbers::flat_manifold_id);
3037  }
3038 
3039  // next reset all lines bounding
3040  // boundary quads as on the
3041  // boundary also. note that since
3042  // we are in 3d, there are cases
3043  // where one or more lines of a
3044  // quad that is not on the
3045  // boundary, are actually boundary
3046  // lines. they will not be marked
3047  // when visiting this
3048  // face. however, since we do not
3049  // support dim-2 dimensional
3050  // boundaries (i.e. internal lines
3051  // constituting boundaries), every
3052  // such line is also part of a face
3053  // that is actually on the
3054  // boundary, so sooner or later we
3055  // get to mark that line for being
3056  // on the boundary
3057  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
3058  triangulation.begin_quad();
3059  quad != triangulation.end_quad();
3060  ++quad)
3061  if (quad->at_boundary())
3062  {
3063  for (unsigned int l = 0; l < 4; ++l)
3064  {
3065  typename Triangulation<dim, spacedim>::line_iterator line =
3066  quad->line(l);
3067  line->set_boundary_id_internal(0);
3068  }
3069  }
3070 
3072  // now set boundary indicators
3073  // where given
3074  //
3075  // first do so for lines
3076  for (const auto &subcell_line : subcelldata.boundary_lines)
3077  {
3078  typename Triangulation<dim, spacedim>::line_iterator line;
3079  std::pair<int, int> line_vertices(
3080  std::make_pair(subcell_line.vertices[0],
3081  subcell_line.vertices[1]));
3082  if (needed_lines.find(line_vertices) != needed_lines.end())
3083  // line found in this
3084  // direction
3085  line = needed_lines[line_vertices];
3086 
3087  else
3088  {
3089  // look whether it exists in
3090  // reverse direction
3091  std::swap(line_vertices.first, line_vertices.second);
3092  if (needed_lines.find(line_vertices) != needed_lines.end())
3093  line = needed_lines[line_vertices];
3094  else
3095  // line does not exist
3096  AssertThrow(false,
3097  ExcLineInexistant(line_vertices.first,
3098  line_vertices.second));
3099  }
3100  // Only exterior lines can be given a boundary indicator
3101  if (line->at_boundary())
3102  {
3103  // make sure that we don't attempt to reset the boundary
3104  // indicator to a different than the previously set value
3105  if (line->boundary_id() != 0)
3106  AssertThrow(line->boundary_id() == subcell_line.boundary_id,
3107  ExcMessage(
3108  "Duplicate boundary lines are only allowed "
3109  "if they carry the same boundary indicator."));
3110 
3111  line->set_boundary_id_internal(subcell_line.boundary_id);
3112  }
3113  // Set manifold id if given
3114  if (line->manifold_id() != numbers::flat_manifold_id)
3115  AssertThrow(line->manifold_id() == subcell_line.manifold_id,
3116  ExcMessage(
3117  "Duplicate lines are only allowed "
3118  "if they carry the same manifold indicator."));
3119  line->set_manifold_id(subcell_line.manifold_id);
3120  }
3121 
3122 
3123  // now go on with the faces
3124  for (const auto &subcell_quad : subcelldata.boundary_quads)
3125  {
3126  typename Triangulation<dim, spacedim>::quad_iterator quad;
3127  typename Triangulation<dim, spacedim>::line_iterator line[4];
3128 
3129  // first find the lines that
3130  // are made up of the given
3131  // vertices, then build up a
3132  // quad from these lines
3133  // finally use the find
3134  // function of the map template
3135  // to find the quad
3136  for (unsigned int i = 0; i < 4; ++i)
3137  {
3138  std::pair<int, int> line_vertices(
3139  subcell_quad
3141  0)],
3142  subcell_quad
3144  1)]);
3145 
3146  // check whether line
3147  // already exists
3148  if (needed_lines.find(line_vertices) != needed_lines.end())
3149  line[i] = needed_lines[line_vertices];
3150  else
3151  // look whether it exists
3152  // in reverse direction
3153  {
3154  std::swap(line_vertices.first, line_vertices.second);
3155  if (needed_lines.find(line_vertices) != needed_lines.end())
3156  line[i] = needed_lines[line_vertices];
3157  else
3158  // line does
3159  // not exist
3160  AssertThrow(false,
3161  ExcLineInexistant(line_vertices.first,
3162  line_vertices.second));
3163  }
3164  }
3165 
3166 
3167  // Set up 2 quads that are
3168  // built up from the lines for
3169  // reasons of comparison to
3170  // needed_quads. The second
3171  // quad is the reversed version
3172  // of the first quad in order
3173  // find the quad regardless of
3174  // its orientation. This is
3175  // introduced for convenience
3176  // and because boundary quad
3177  // orientation does not carry
3178  // any information.
3180  line[0]->index(),
3181  line[1]->index(),
3182  line[2]->index(),
3183  line[3]->index());
3185  line[2]->index(),
3186  line[3]->index(),
3187  line[0]->index(),
3188  line[1]->index());
3189 
3190  // try to find the quad with
3191  // lines situated as
3192  // constructed above. if it
3193  // could not be found, rotate
3194  // the boundary lines 3 times
3195  // until it is found or it does
3196  // not exist.
3197 
3198  // mapping from counterclock to
3199  // lexicographic ordering of
3200  // quad lines
3201  static const unsigned int lex2cclock[4] = {3, 1, 0, 2};
3202  // copy lines from
3203  // lexicographic to
3204  // counterclock ordering, as
3205  // rotation is much simpler in
3206  // counterclock ordering
3207  typename Triangulation<dim, spacedim>::line_iterator
3208  line_counterclock[4];
3209  for (unsigned int i = 0; i < 4; ++i)
3210  line_counterclock[lex2cclock[i]] = line[i];
3211  unsigned int n_rotations = 0;
3212  bool not_found_quad_1;
3213  while ((not_found_quad_1 = (needed_quads.find(quad_compare_1) ==
3214  needed_quads.end())) &&
3215  (needed_quads.find(quad_compare_2) == needed_quads.end()) &&
3216  (n_rotations < 4))
3217  {
3218  // use the rotate defined
3219  // in <algorithms>
3220  std::rotate(line_counterclock,
3221  line_counterclock + 1,
3222  line_counterclock + 4);
3223  // update the quads with
3224  // rotated lines (i runs in
3225  // lexicographic ordering)
3226  for (unsigned int i = 0; i < 4; ++i)
3227  {
3228  quad_compare_1.set_face(
3229  i, line_counterclock[lex2cclock[i]]->index());
3230  quad_compare_2.set_face(
3231  (i + 2) % 4, line_counterclock[lex2cclock[i]]->index());
3232  }
3233 
3234  ++n_rotations;
3235  }
3236 
3237  AssertThrow(n_rotations != 4,
3238  ExcQuadInexistant(line[0]->index(),
3239  line[1]->index(),
3240  line[2]->index(),
3241  line[3]->index()));
3242 
3243  if (not_found_quad_1)
3244  quad = needed_quads[quad_compare_2].first;
3245  else
3246  quad = needed_quads[quad_compare_1].first;
3247 
3248  // check whether this face is
3249  // really an exterior one
3250  if (quad->at_boundary())
3251  {
3252  // and make sure that we don't attempt to reset the boundary
3253  // indicator to a different than the previously set value
3254  if (quad->boundary_id() != 0)
3255  AssertThrow(quad->boundary_id() == subcell_quad.boundary_id,
3256  ExcMessage(
3257  "Duplicate boundary quads are only allowed "
3258  "if they carry the same boundary indicator."));
3259 
3260  quad->set_boundary_id_internal(subcell_quad.boundary_id);
3261  }
3262  // Set manifold id if given
3263  if (quad->manifold_id() != numbers::flat_manifold_id)
3264  AssertThrow(quad->manifold_id() == subcell_quad.manifold_id,
3265  ExcMessage(
3266  "Duplicate boundary quads are only allowed "
3267  "if they carry the same manifold indicator."));
3268 
3269  quad->set_manifold_id(subcell_quad.manifold_id);
3270  }
3271 
3272 
3274  // finally update neighborship info
3275  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
3276  triangulation.begin();
3277  cell != triangulation.end();
3278  ++cell)
3279  for (unsigned int face = 0; face < 6; ++face)
3280  if (adjacent_cells[cell->quad(face)->index()][0] == cell)
3281  // first adjacent cell is
3282  // this one
3283  {
3284  if (adjacent_cells[cell->quad(face)->index()].size() == 2)
3285  // there is another
3286  // adjacent cell
3287  cell->set_neighbor(
3288  face, adjacent_cells[cell->quad(face)->index()][1]);
3289  }
3290  // first adjacent cell is not this
3291  // one, -> it must be the neighbor
3292  // we are looking for
3293  else
3294  cell->set_neighbor(face,
3295  adjacent_cells[cell->quad(face)->index()][0]);
3296  }
3297 
3298 
3314  template <int spacedim>
3315  static void delete_children(
3316  Triangulation<1, spacedim> & triangulation,
3318  std::vector<unsigned int> &,
3319  std::vector<unsigned int> &)
3320  {
3321  const unsigned int dim = 1;
3322 
3323  // first we need to reset the
3324  // neighbor pointers of the
3325  // neighbors of this cell's
3326  // children to this cell. This is
3327  // different for one dimension,
3328  // since there neighbors can have a
3329  // refinement level differing from
3330  // that of this cell's children by
3331  // more than one level.
3332 
3333  Assert(!cell->child(0)->has_children() &&
3334  !cell->child(1)->has_children(),
3335  ExcInternalError());
3336 
3337  // first do it for the cells to the
3338  // left
3339  if (cell->neighbor(0).state() == IteratorState::valid)
3340  if (cell->neighbor(0)->has_children())
3341  {
3343  cell->neighbor(0);
3344  Assert(neighbor->level() == cell->level(), ExcInternalError());
3345 
3346  // right child
3347  neighbor = neighbor->child(1);
3348  while (true)
3349  {
3350  Assert(neighbor->neighbor(1) == cell->child(0),
3351  ExcInternalError());
3352  neighbor->set_neighbor(1, cell);
3353 
3354  // move on to further
3355  // children on the
3356  // boundary between this
3357  // cell and its neighbor
3358  if (neighbor->has_children())
3359  neighbor = neighbor->child(1);
3360  else
3361  break;
3362  }
3363  }
3364 
3365  // now do it for the cells to the
3366  // left
3367  if (cell->neighbor(1).state() == IteratorState::valid)
3368  if (cell->neighbor(1)->has_children())
3369  {
3371  cell->neighbor(1);
3372  Assert(neighbor->level() == cell->level(), ExcInternalError());
3373 
3374  // left child
3375  neighbor = neighbor->child(0);
3376  while (true)
3377  {
3378  Assert(neighbor->neighbor(0) == cell->child(1),
3379  ExcInternalError());
3380  neighbor->set_neighbor(0, cell);
3381 
3382  // move on to further
3383  // children on the
3384  // boundary between this
3385  // cell and its neighbor
3386  if (neighbor->has_children())
3387  neighbor = neighbor->child(0);
3388  else
3389  break;
3390  }
3391  }
3392 
3393 
3394  // delete the vertex which will not
3395  // be needed anymore. This vertex
3396  // is the second of the first child
3397  triangulation.vertices_used[cell->child(0)->vertex_index(1)] = false;
3398 
3399  // invalidate children. clear user
3400  // pointers, to avoid that they may
3401  // appear at unwanted places later
3402  // on...
3403  for (unsigned int child = 0; child < cell->n_children(); ++child)
3404  {
3405  cell->child(child)->clear_user_data();
3406  cell->child(child)->clear_user_flag();
3407  cell->child(child)->clear_used_flag();
3408  }
3409 
3410 
3411  // delete pointer to children
3412  cell->clear_children();
3413  cell->clear_user_flag();
3414  }
3415 
3416 
3417 
3418  template <int spacedim>
3419  static void delete_children(
3420  Triangulation<2, spacedim> & triangulation,
3422  std::vector<unsigned int> & line_cell_count,
3423  std::vector<unsigned int> &)
3424  {
3425  const unsigned int dim = 2;
3426  const RefinementCase<dim> ref_case = cell->refinement_case();
3427 
3428  Assert(line_cell_count.size() == triangulation.n_raw_lines(),
3429  ExcInternalError());
3430 
3431  // vectors to hold all lines which
3432  // may be deleted
3433  std::vector<typename Triangulation<dim, spacedim>::line_iterator>
3434  lines_to_delete(0);
3435 
3436  lines_to_delete.reserve(4 * 2 + 4);
3437 
3438  // now we decrease the counters for
3439  // lines contained in the child
3440  // cells
3441  for (unsigned int c = 0; c < cell->n_children(); ++c)
3442  {
3444  cell->child(c);
3445  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
3446  --line_cell_count[child->line_index(l)];
3447  }
3448 
3449 
3450  // delete the vertex which will not
3451  // be needed anymore. This vertex
3452  // is the second of the second line
3453  // of the first child, if the cell
3454  // is refined with cut_xy, else there
3455  // is no inner vertex.
3456  // additionally delete unneeded inner
3457  // lines
3458  if (ref_case == RefinementCase<dim>::cut_xy)
3459  {
3460  triangulation
3461  .vertices_used[cell->child(0)->line(1)->vertex_index(1)] = false;
3462 
3463  lines_to_delete.push_back(cell->child(0)->line(1));
3464  lines_to_delete.push_back(cell->child(0)->line(3));
3465  lines_to_delete.push_back(cell->child(3)->line(0));
3466  lines_to_delete.push_back(cell->child(3)->line(2));
3467  }
3468  else
3469  {
3470  unsigned int inner_face_no =
3471  ref_case == RefinementCase<dim>::cut_x ? 1 : 3;
3472 
3473  // the inner line will not be
3474  // used any more
3475  lines_to_delete.push_back(cell->child(0)->line(inner_face_no));
3476  }
3477 
3478  // invalidate children
3479  for (unsigned int child = 0; child < cell->n_children(); ++child)
3480  {
3481  cell->child(child)->clear_user_data();
3482  cell->child(child)->clear_user_flag();
3483  cell->child(child)->clear_used_flag();
3484  }
3485 
3486 
3487  // delete pointer to children
3488  cell->clear_children();
3489  cell->clear_refinement_case();
3490  cell->clear_user_flag();
3491 
3492  // look at the refinement of outer
3493  // lines. if nobody needs those
3494  // anymore we can add them to the
3495  // list of lines to be deleted.
3496  for (unsigned int line_no = 0;
3497  line_no < GeometryInfo<dim>::lines_per_cell;
3498  ++line_no)
3499  {
3500  typename Triangulation<dim, spacedim>::line_iterator line =
3501  cell->line(line_no);
3502 
3503  if (line->has_children())
3504  {
3505  // if one of the cell counters is
3506  // zero, the other has to be as well
3507 
3508  Assert((line_cell_count[line->child_index(0)] == 0 &&
3509  line_cell_count[line->child_index(1)] == 0) ||
3510  (line_cell_count[line->child_index(0)] > 0 &&
3511  line_cell_count[line->child_index(1)] > 0),
3512  ExcInternalError());
3513 
3514  if (line_cell_count[line->child_index(0)] == 0)
3515  {
3516  for (unsigned int c = 0; c < 2; ++c)
3517  Assert(!line->child(c)->has_children(),
3518  ExcInternalError());
3519 
3520  // we may delete the line's
3521  // children and the middle vertex
3522  // as no cell references them
3523  // anymore
3524  triangulation
3525  .vertices_used[line->child(0)->vertex_index(1)] = false;
3526 
3527  lines_to_delete.push_back(line->child(0));
3528  lines_to_delete.push_back(line->child(1));
3529 
3530  line->clear_children();
3531  }
3532  }
3533  }
3534 
3535  // finally, delete unneeded lines
3536 
3537  // clear user pointers, to avoid that
3538  // they may appear at unwanted places
3539  // later on...
3540  // same for user flags, then finally
3541  // delete the lines
3542  typename std::vector<
3543  typename Triangulation<dim, spacedim>::line_iterator>::iterator
3544  line = lines_to_delete.begin(),
3545  endline = lines_to_delete.end();
3546  for (; line != endline; ++line)
3547  {
3548  (*line)->clear_user_data();
3549  (*line)->clear_user_flag();
3550  (*line)->clear_used_flag();
3551  }
3552  }
3553 
3554 
3555 
3556  template <int spacedim>
3557  static void delete_children(
3558  Triangulation<3, spacedim> & triangulation,
3560  std::vector<unsigned int> & line_cell_count,
3561  std::vector<unsigned int> & quad_cell_count)
3562  {
3563  const unsigned int dim = 3;
3564 
3565  Assert(line_cell_count.size() == triangulation.n_raw_lines(),
3566  ExcInternalError());
3567  Assert(quad_cell_count.size() == triangulation.n_raw_quads(),
3568  ExcInternalError());
3569 
3570  // first of all, we store the RefineCase of
3571  // this cell
3572  const RefinementCase<dim> ref_case = cell->refinement_case();
3573  // vectors to hold all lines and quads which
3574  // may be deleted
3575  std::vector<typename Triangulation<dim, spacedim>::line_iterator>
3576  lines_to_delete(0);
3577  std::vector<typename Triangulation<dim, spacedim>::quad_iterator>
3578  quads_to_delete(0);
3579 
3580  lines_to_delete.reserve(12 * 2 + 6 * 4 + 6);
3581  quads_to_delete.reserve(6 * 4 + 12);
3582 
3583  // now we decrease the counters for lines and
3584  // quads contained in the child cells
3585  for (unsigned int c = 0; c < cell->n_children(); ++c)
3586  {
3588  cell->child(c);
3589  for (unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
3590  --line_cell_count[child->line_index(l)];
3591  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
3592  --quad_cell_count[child->quad_index(f)];
3593  }
3594 
3596  // delete interior quads and lines and the
3597  // interior vertex, depending on the
3598  // refinement case of the cell
3599  //
3600  // for append quads and lines: only append
3601  // them to the list of objects to be deleted
3602 
3603  switch (ref_case)
3604  {
3606  quads_to_delete.push_back(cell->child(0)->face(1));
3607  break;
3609  quads_to_delete.push_back(cell->child(0)->face(3));
3610  break;
3612  quads_to_delete.push_back(cell->child(0)->face(5));
3613  break;
3615  quads_to_delete.push_back(cell->child(0)->face(1));
3616  quads_to_delete.push_back(cell->child(0)->face(3));
3617  quads_to_delete.push_back(cell->child(3)->face(0));
3618  quads_to_delete.push_back(cell->child(3)->face(2));
3619 
3620  lines_to_delete.push_back(cell->child(0)->line(11));
3621  break;
3623  quads_to_delete.push_back(cell->child(0)->face(1));
3624  quads_to_delete.push_back(cell->child(0)->face(5));
3625  quads_to_delete.push_back(cell->child(3)->face(0));
3626  quads_to_delete.push_back(cell->child(3)->face(4));
3627 
3628  lines_to_delete.push_back(cell->child(0)->line(5));
3629  break;
3631  quads_to_delete.push_back(cell->child(0)->face(3));
3632  quads_to_delete.push_back(cell->child(0)->face(5));
3633  quads_to_delete.push_back(cell->child(3)->face(2));
3634  quads_to_delete.push_back(cell->child(3)->face(4));
3635 
3636  lines_to_delete.push_back(cell->child(0)->line(7));
3637  break;
3639  quads_to_delete.push_back(cell->child(0)->face(1));
3640  quads_to_delete.push_back(cell->child(2)->face(1));
3641  quads_to_delete.push_back(cell->child(4)->face(1));
3642  quads_to_delete.push_back(cell->child(6)->face(1));
3643 
3644  quads_to_delete.push_back(cell->child(0)->face(3));
3645  quads_to_delete.push_back(cell->child(1)->face(3));
3646  quads_to_delete.push_back(cell->child(4)->face(3));
3647  quads_to_delete.push_back(cell->child(5)->face(3));
3648 
3649  quads_to_delete.push_back(cell->child(0)->face(5));
3650  quads_to_delete.push_back(cell->child(1)->face(5));
3651  quads_to_delete.push_back(cell->child(2)->face(5));
3652  quads_to_delete.push_back(cell->child(3)->face(5));
3653 
3654  lines_to_delete.push_back(cell->child(0)->line(5));
3655  lines_to_delete.push_back(cell->child(0)->line(7));
3656  lines_to_delete.push_back(cell->child(0)->line(11));
3657  lines_to_delete.push_back(cell->child(7)->line(0));
3658  lines_to_delete.push_back(cell->child(7)->line(2));
3659  lines_to_delete.push_back(cell->child(7)->line(8));
3660  // delete the vertex which will not
3661  // be needed anymore. This vertex
3662  // is the vertex at the heart of
3663  // this cell, which is the sixth of
3664  // the first child
3665  triangulation.vertices_used[cell->child(0)->vertex_index(7)] =
3666  false;
3667  break;
3668  default:
3669  // only remaining case is
3670  // no_refinement, thus an error
3671  Assert(false, ExcInternalError());
3672  break;
3673  }
3674 
3675 
3676  // invalidate children
3677  for (unsigned int child = 0; child < cell->n_children(); ++child)
3678  {
3679  cell->child(child)->clear_user_data();
3680  cell->child(child)->clear_user_flag();
3681 
3682  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
3683  {
3684  // set flags denoting deviations from
3685  // standard orientation of faces back
3686  // to initialization values
3687  cell->child(child)->set_face_orientation(f, true);
3688  cell->child(child)->set_face_flip(f, false);
3689  cell->child(child)->set_face_rotation(f, false);
3690  }
3691 
3692  cell->child(child)->clear_used_flag();
3693  }
3694 
3695 
3696  // delete pointer to children
3697  cell->clear_children();
3698  cell->clear_refinement_case();
3699  cell->clear_user_flag();
3700 
3701  // so far we only looked at inner quads,
3702  // lines and vertices. Now we have to
3703  // consider outer ones as well. here, we have
3704  // to check, whether there are other cells
3705  // still needing these objects. oherwise we
3706  // can delete them. first for quads (and
3707  // their inner lines).
3708 
3709  for (unsigned int quad_no = 0;
3710  quad_no < GeometryInfo<dim>::faces_per_cell;
3711  ++quad_no)
3712  {
3713  typename Triangulation<dim, spacedim>::quad_iterator quad =
3714  cell->face(quad_no);
3715 
3716  Assert(
3717  (GeometryInfo<dim>::face_refinement_case(ref_case, quad_no) &&
3718  quad->has_children()) ||
3719  GeometryInfo<dim>::face_refinement_case(ref_case, quad_no) ==
3720  RefinementCase<dim - 1>::no_refinement,
3721  ExcInternalError());
3722 
3723  switch (quad->refinement_case())
3724  {
3725  case RefinementCase<dim - 1>::no_refinement:
3726  // nothing to do as the quad
3727  // is not refined
3728  break;
3729  case RefinementCase<dim - 1>::cut_x:
3730  case RefinementCase<dim - 1>::cut_y:
3731  {
3732  // if one of the cell counters is
3733  // zero, the other has to be as
3734  // well
3735  Assert((quad_cell_count[quad->child_index(0)] == 0 &&
3736  quad_cell_count[quad->child_index(1)] == 0) ||
3737  (quad_cell_count[quad->child_index(0)] > 0 &&
3738  quad_cell_count[quad->child_index(1)] > 0),
3739  ExcInternalError());
3740  // it might be, that the quad is
3741  // refined twice anisotropically,
3742  // first check, whether we may
3743  // delete possible grand_children
3744  unsigned int deleted_grandchildren = 0;
3745  unsigned int number_of_child_refinements = 0;
3746 
3747  for (unsigned int c = 0; c < 2; ++c)
3748  if (quad->child(c)->has_children())
3749  {
3750  ++number_of_child_refinements;
3751  // if one of the cell counters is
3752  // zero, the other has to be as
3753  // well
3754  Assert(
3755  (quad_cell_count[quad->child(c)->child_index(0)] ==
3756  0 &&
3757  quad_cell_count[quad->child(c)->child_index(1)] ==
3758  0) ||
3759  (quad_cell_count[quad->child(c)->child_index(0)] >
3760  0 &&
3761  quad_cell_count[quad->child(c)->child_index(1)] >
3762  0),
3763  ExcInternalError());
3764  if (quad_cell_count[quad->child(c)->child_index(0)] ==
3765  0)
3766  {
3767  // Assert, that the two
3768  // anisotropic
3769  // refinements add up to
3770  // isotropic refinement
3771  Assert(quad->refinement_case() +
3772  quad->child(c)->refinement_case() ==
3774  ExcInternalError());
3775  // we may delete the
3776  // quad's children and
3777  // the inner line as no
3778  // cell references them
3779  // anymore
3780  quads_to_delete.push_back(
3781  quad->child(c)->child(0));
3782  quads_to_delete.push_back(
3783  quad->child(c)->child(1));
3784  if (quad->child(c)->refinement_case() ==
3786  lines_to_delete.push_back(
3787  quad->child(c)->child(0)->line(1));
3788  else
3789  lines_to_delete.push_back(
3790  quad->child(c)->child(0)->line(3));
3791  quad->child(c)->clear_children();
3792  quad->child(c)->clear_refinement_case();
3793  ++deleted_grandchildren;
3794  }
3795  }
3796  // if no grandchildren are left, we
3797  // may as well delete the
3798  // refinement of the inner line
3799  // between our children and the
3800  // corresponding vertex
3801  if (number_of_child_refinements > 0 &&
3802  deleted_grandchildren == number_of_child_refinements)
3803  {
3804  typename Triangulation<dim, spacedim>::line_iterator
3805  middle_line;
3806  if (quad->refinement_case() == RefinementCase<2>::cut_x)
3807  middle_line = quad->child(0)->line(1);
3808  else
3809  middle_line = quad->child(0)->line(3);
3810 
3811  lines_to_delete.push_back(middle_line->child(0));
3812  lines_to_delete.push_back(middle_line->child(1));
3813  triangulation
3814  .vertices_used[middle_vertex_index<dim, spacedim>(
3815  middle_line)] = false;
3816  middle_line->clear_children();
3817  }
3818 
3819  // now consider the direct children
3820  // of the given quad
3821  if (quad_cell_count[quad->child_index(0)] == 0)
3822  {
3823  // we may delete the quad's
3824  // children and the inner line
3825  // as no cell references them
3826  // anymore
3827  quads_to_delete.push_back(quad->child(0));
3828  quads_to_delete.push_back(quad->child(1));
3829  if (quad->refinement_case() == RefinementCase<2>::cut_x)
3830  lines_to_delete.push_back(quad->child(0)->line(1));
3831  else
3832  lines_to_delete.push_back(quad->child(0)->line(3));
3833 
3834  // if the counters just dropped
3835  // to zero, otherwise the
3836  // children would have been
3837  // deleted earlier, then this
3838  // cell's children must have
3839  // contained the anisotropic
3840  // quad children. thus, if
3841  // those have again anisotropic
3842  // children, which are in
3843  // effect isotropic children of
3844  // the original quad, those are
3845  // still needed by a
3846  // neighboring cell and we
3847  // cannot delete them. instead,
3848  // we have to reset this quad's
3849  // refine case to isotropic and
3850  // set the children
3851  // accordingly.
3852  if (quad->child(0)->has_children())
3853  if (quad->refinement_case() ==
3855  {
3856  // now evereything is
3857  // quite complicated. we
3858  // have the children
3859  // numbered according to
3860  //
3861  // *---*---*
3862  // |n+1|m+1|
3863  // *---*---*
3864  // | n | m |
3865  // *---*---*
3866  //
3867  // from the original
3868  // anisotropic
3869  // refinement. we have to
3870  // reorder them as
3871  //
3872  // *---*---*
3873  // | m |m+1|
3874  // *---*---*
3875  // | n |n+1|
3876  // *---*---*
3877  //
3878  // for isotropic refinement.
3879  //
3880  // this is a bit ugly, of
3881  // course: loop over all
3882  // cells on all levels
3883  // and look for faces n+1
3884  // (switch_1) and m
3885  // (switch_2).
3886  const typename Triangulation<dim, spacedim>::
3887  quad_iterator switch_1 =
3888  quad->child(0)->child(1),
3889  switch_2 =
3890  quad->child(1)->child(0);
3891 
3892  Assert(!switch_1->has_children(),
3893  ExcInternalError());
3894  Assert(!switch_2->has_children(),
3895  ExcInternalError());
3896 
3897  const int switch_1_index = switch_1->index();
3898  const int switch_2_index = switch_2->index();
3899  for (unsigned int l = 0;
3900  l < triangulation.levels.size();
3901  ++l)
3902  for (unsigned int h = 0;
3903  h < triangulation.levels[l]
3904  ->cells.cells.size();
3905  ++h)
3906  for (unsigned int q = 0;
3907  q < GeometryInfo<dim>::faces_per_cell;
3908  ++q)
3909  {
3910  const int index = triangulation.levels[l]
3911  ->cells.cells[h]
3912  .face(q);
3913  if (index == switch_1_index)
3914  triangulation.levels[l]
3915  ->cells.cells[h]
3916  .set_face(q, switch_2_index);
3917  else if (index == switch_2_index)
3918  triangulation.levels[l]
3919  ->cells.cells[h]
3920  .set_face(q, switch_1_index);
3921  }
3922  // now we have to copy
3923  // all information of the
3924  // two quads
3925  const int switch_1_lines[4] = {
3926  static_cast<signed int>(
3927  switch_1->line_index(0)),
3928  static_cast<signed int>(
3929  switch_1->line_index(1)),
3930  static_cast<signed int>(
3931  switch_1->line_index(2)),
3932  static_cast<signed int>(
3933  switch_1->line_index(3))};
3934  const bool switch_1_line_orientations[4] = {
3935  switch_1->line_orientation(0),
3936  switch_1->line_orientation(1),
3937  switch_1->line_orientation(2),
3938  switch_1->line_orientation(3)};
3939  const types::boundary_id switch_1_boundary_id =
3940  switch_1->boundary_id();
3941  const unsigned int switch_1_user_index =
3942  switch_1->user_index();
3943  const bool switch_1_user_flag =
3944  switch_1->user_flag_set();
3945 
3946  switch_1->set(
3948  TriaObject<2>(switch_2->line_index(0),
3949  switch_2->line_index(1),
3950  switch_2->line_index(2),
3951  switch_2->line_index(3)));
3952  switch_1->set_line_orientation(
3953  0, switch_2->line_orientation(0));
3954  switch_1->set_line_orientation(
3955  1, switch_2->line_orientation(1));
3956  switch_1->set_line_orientation(
3957  2, switch_2->line_orientation(2));
3958  switch_1->set_line_orientation(
3959  3, switch_2->line_orientation(3));
3960  switch_1->set_boundary_id_internal(
3961  switch_2->boundary_id());
3962  switch_1->set_manifold_id(
3963  switch_2->manifold_id());
3964  switch_1->set_user_index(switch_2->user_index());
3965  if (switch_2->user_flag_set())
3966  switch_1->set_user_flag();
3967  else
3968  switch_1->clear_user_flag();
3969 
3970  switch_2->set(
3972  TriaObject<2>(switch_1_lines[0],
3973  switch_1_lines[1],
3974  switch_1_lines[2],
3975  switch_1_lines[3]));
3976  switch_2->set_line_orientation(
3977  0, switch_1_line_orientations[0]);
3978  switch_2->set_line_orientation(
3979  1, switch_1_line_orientations[1]);
3980  switch_2->set_line_orientation(
3981  2, switch_1_line_orientations[2]);
3982  switch_2->set_line_orientation(
3983  3, switch_1_line_orientations[3]);
3984  switch_2->set_boundary_id_internal(
3985  switch_1_boundary_id);
3986  switch_2->set_manifold_id(
3987  switch_1->manifold_id());
3988  switch_2->set_user_index(switch_1_user_index);
3989  if (switch_1_user_flag)
3990  switch_2->set_user_flag();
3991  else
3992  switch_2->clear_user_flag();
3993 
3994  const unsigned int child_0 =
3995  quad->child(0)->child_index(0);
3996  const unsigned int child_2 =
3997  quad->child(1)->child_index(0);
3998  quad->clear_children();
3999  quad->clear_refinement_case();
4000  quad->set_refinement_case(
4002  quad->set_children(0, child_0);
4003  quad->set_children(2, child_2);
4004  std::swap(quad_cell_count[child_0 + 1],
4005  quad_cell_count[child_2]);
4006  }
4007  else
4008  {
4009  // the face was refined
4010  // with cut_y, thus the
4011  // children are already
4012  // in correct order. we
4013  // only have to set them
4014  // correctly, deleting
4015  // the indirection of two
4016  // anisotropic refinement
4017  // and going directly
4018  // from the quad to
4019  // isotropic children
4020  const unsigned int child_0 =
4021  quad->child(0)->child_index(0);
4022  const unsigned int child_2 =
4023  quad->child(1)->child_index(0);
4024  quad->clear_children();
4025  quad->clear_refinement_case();
4026  quad->set_refinement_case(
4028  quad->set_children(0, child_0);
4029  quad->set_children(2, child_2);
4030  }
4031  else
4032  {
4033  quad->clear_children();
4034  quad->clear_refinement_case();
4035  }
4036  }
4037  break;
4038  }
4039  case RefinementCase<dim - 1>::cut_xy:
4040  {
4041  // if one of the cell counters is
4042  // zero, the others have to be as
4043  // well
4044 
4045  Assert((quad_cell_count[quad->child_index(0)] == 0 &&
4046  quad_cell_count[quad->child_index(1)] == 0 &&
4047  quad_cell_count[quad->child_index(2)] == 0 &&
4048  quad_cell_count[quad->child_index(3)] == 0) ||
4049  (quad_cell_count[quad->child_index(0)] > 0 &&
4050  quad_cell_count[quad->child_index(1)] > 0 &&
4051  quad_cell_count[quad->child_index(2)] > 0 &&
4052  quad_cell_count[quad->child_index(3)] > 0),
4053  ExcInternalError());
4054 
4055  if (quad_cell_count[quad->child_index(0)] == 0)
4056  {
4057  // we may delete the quad's
4058  // children, the inner lines
4059  // and the middle vertex as no
4060  // cell references them anymore
4061  lines_to_delete.push_back(quad->child(0)->line(1));
4062  lines_to_delete.push_back(quad->child(3)->line(0));
4063  lines_to_delete.push_back(quad->child(0)->line(3));
4064  lines_to_delete.push_back(quad->child(3)->line(2));
4065 
4066  for (unsigned int child = 0; child < quad->n_children();
4067  ++child)
4068  quads_to_delete.push_back(quad->child(child));
4069 
4070  triangulation
4071  .vertices_used[quad->child(0)->vertex_index(3)] =
4072  false;
4073 
4074  quad->clear_children();
4075  quad->clear_refinement_case();
4076  }
4077  }
4078  break;
4079 
4080  default:
4081  Assert(false, ExcInternalError());
4082  break;
4083  }
4084  }
4085 
4086  // now we repeat a similar procedure
4087  // for the outer lines of this cell.
4088 
4089  // if in debug mode: check that each
4090  // of the lines for which we consider
4091  // deleting the children in fact has
4092  // children (the bits/coarsening_3d
4093  // test tripped over this initially)
4094  for (unsigned int line_no = 0;
4095  line_no < GeometryInfo<dim>::lines_per_cell;
4096  ++line_no)
4097  {
4098  typename Triangulation<dim, spacedim>::line_iterator line =
4099  cell->line(line_no);
4100 
4101  Assert(
4102  (GeometryInfo<dim>::line_refinement_case(ref_case, line_no) &&
4103  line->has_children()) ||
4104  GeometryInfo<dim>::line_refinement_case(ref_case, line_no) ==
4106  ExcInternalError());
4107 
4108  if (line->has_children())
4109  {
4110  // if one of the cell counters is
4111  // zero, the other has to be as well
4112 
4113  Assert((line_cell_count[line->child_index(0)] == 0 &&
4114  line_cell_count[line->child_index(1)] == 0) ||
4115  (line_cell_count[line->child_index(0)] > 0 &&
4116  line_cell_count[line->child_index(1)] > 0),
4117  ExcInternalError());
4118 
4119  if (line_cell_count[line->child_index(0)] == 0)
4120  {
4121  for (unsigned int c = 0; c < 2; ++c)
4122  Assert(!line->child(c)->has_children(),
4123  ExcInternalError());
4124 
4125  // we may delete the line's
4126  // children and the middle vertex
4127  // as no cell references them
4128  // anymore
4129  triangulation
4130  .vertices_used[line->child(0)->vertex_index(1)] = false;
4131 
4132  lines_to_delete.push_back(line->child(0));
4133  lines_to_delete.push_back(line->child(1));
4134 
4135  line->clear_children();
4136  }
4137  }
4138  }
4139 
4140  // finally, delete unneeded quads and lines
4141 
4142  // clear user pointers, to avoid that
4143  // they may appear at unwanted places
4144  // later on...
4145  // same for user flags, then finally
4146  // delete the quads and lines
4147  typename std::vector<
4148  typename Triangulation<dim, spacedim>::line_iterator>::iterator
4149  line = lines_to_delete.begin(),
4150  endline = lines_to_delete.end();
4151  for (; line != endline; ++line)
4152  {
4153  (*line)->clear_user_data();
4154  (*line)->clear_user_flag();
4155  (*line)->clear_used_flag();
4156  }
4157 
4158  typename std::vector<
4159  typename Triangulation<dim, spacedim>::quad_iterator>::iterator
4160  quad = quads_to_delete.begin(),
4161  endquad = quads_to_delete.end();
4162  for (; quad != endquad; ++quad)
4163  {
4164  (*quad)->clear_user_data();
4165  (*quad)->clear_children();
4166  (*quad)->clear_refinement_case();
4167  (*quad)->clear_user_flag();
4168  (*quad)->clear_used_flag();
4169  }
4170  }
4171 
4172 
4190  template <int spacedim>
4191  static void create_children(
4192  Triangulation<2, spacedim> &triangulation,
4193  unsigned int & next_unused_vertex,
4194  typename Triangulation<2, spacedim>::raw_line_iterator
4195  &next_unused_line,
4197  & next_unused_cell,
4199  {
4200  const unsigned int dim = 2;
4201  // clear refinement flag
4202  const RefinementCase<dim> ref_case = cell->refine_flag_set();
4203  cell->clear_refine_flag();
4204 
4205  /* For the refinement process: since we go the levels up from the
4206  lowest, there are (unlike above) only two possibilities: a neighbor
4207  cell is on the same level or one level up (in both cases, it may or
4208  may not be refined later on, but we don't care here).
4209 
4210  First:
4211  Set up an array of the 3x3 vertices, which are distributed on the
4212  cell (the array consists of indices into the @p{vertices} std::vector
4213 
4214  2--7--3
4215  | | |
4216  4--8--5
4217  | | |
4218  0--6--1
4219 
4220  note: in case of cut_x or cut_y not all these vertices are needed for
4221  the new cells
4222 
4223  Second:
4224  Set up an array of the new lines (the array consists of iterator
4225  pointers into the lines arrays)
4226 
4227  .-6-.-7-. The directions are: .->-.->-.
4228  1 9 3 ^ ^ ^
4229  .-10.11-. .->-.->-.
4230  0 8 2 ^ ^ ^
4231  .-4-.-5-. .->-.->-.
4232 
4233  cut_x:
4234  .-4-.-5-.
4235  | | |
4236  0 6 1
4237  | | |
4238  .-2-.-3-.
4239 
4240  cut_y:
4241  .---5---.
4242  1 3
4243  .---6---.
4244  0 2
4245  .---4---.
4246 
4247 
4248  Third:
4249  Set up an array of neighbors:
4250 
4251  6 7
4252  .--.--.
4253  1| | |3
4254  .--.--.
4255  0| | |2
4256  .--.--.
4257  4 5
4258 
4259  We need this array for two reasons: first to get the lines which will
4260  bound the four subcells (if the neighboring cell is refined, these
4261  lines already exist), and second to update neighborship information.
4262  Since if a neighbor is not refined, its neighborship record only
4263  points to the present, unrefined, cell rather than the children we
4264  are presently creating, we only need the neighborship information
4265  if the neighbor cells are refined. In all other cases, we store
4266  the unrefined neighbor address
4267 
4268  We also need for every neighbor (if refined) which number among its
4269  neighbors the present (unrefined) cell has, since that number is to
4270  be replaced and because that also is the number of the subline which
4271  will be the interface between that neighbor and the to be created
4272  cell. We will store this number (between 0 and 3) in the field
4273  @p{neighbors_neighbor}.
4274 
4275  It would be sufficient to use the children of the common line to the
4276  neighbor, if we only wanted to get the new sublines and the new
4277  vertex, but because we need to update the neighborship information of
4278  the two refined subcells of the neighbor, we need to search these
4279  anyway.
4280 
4281  Convention:
4282  The created children are numbered like this:
4283 
4284  .--.--.
4285  |2 . 3|
4286  .--.--.
4287  |0 | 1|
4288  .--.--.
4289  */
4290  // collect the
4291  // indices of the
4292  // eight
4293  // surrounding
4294  // vertices
4295  // 2--7--3
4296  // | | |
4297  // 4--9--5
4298  // | | |
4299  // 0--6--1
4300  int new_vertices[9];
4301  for (unsigned int vertex_no = 0; vertex_no < 4; ++vertex_no)
4302  new_vertices[vertex_no] = cell->vertex_index(vertex_no);
4303  for (unsigned int line_no = 0; line_no < 4; ++line_no)
4304  if (cell->line(line_no)->has_children())
4305  new_vertices[4 + line_no] =
4306  cell->line(line_no)->child(0)->vertex_index(1);
4307 
4308  if (ref_case == RefinementCase<dim>::cut_xy)
4309  {
4310  // find the next
4311  // unused vertex and
4312  // allocate it for
4313  // the new vertex we
4314  // need here
4315  while (triangulation.vertices_used[next_unused_vertex] == true)
4316  ++next_unused_vertex;
4317  Assert(
4318  next_unused_vertex < triangulation.vertices.size(),
4319  ExcMessage(
4320  "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."));
4321  triangulation.vertices_used[next_unused_vertex] = true;
4322 
4323  new_vertices[8] = next_unused_vertex;
4324 
4325  // if this quad lives
4326  // in 2d, then we can
4327  // compute the new
4328  // central vertex
4329  // location just from
4330  // the surrounding
4331  // ones. If this is
4332  // not the case, then
4333  // we need to ask a
4334  // boundary object
4335  if (dim == spacedim)
4336  {
4337  // triangulation.vertices[next_unused_vertex] = new_point;
4338  triangulation.vertices[next_unused_vertex] = cell->center(true);
4339 
4340  // if the user_flag is set, i.e. if the cell is at the
4341  // boundary, use a different calculation of the middle vertex
4342  // here. this is of advantage if the boundary is strongly
4343  // curved (whereas the cell is not) and the cell has a high
4344  // aspect ratio.
4345  if (cell->user_flag_set())
4346  {
4347  // first reset the user_flag and then refine
4348  cell->clear_user_flag();
4349  triangulation.vertices[next_unused_vertex] =
4350  cell->center(true, true);
4351  }
4352  }
4353  else
4354  {
4355  // if this quad lives in a higher dimensional space
4356  // then we don't need to worry if it is at the
4357  // boundary of the manifold -- we always have to use
4358  // the boundary object anyway; so ignore whether the
4359  // user flag is set or not
4360  cell->clear_user_flag();
4361 
4362  // new vertex is placed on the surface according to
4363  // the information stored in the boundary class
4364  triangulation.vertices[next_unused_vertex] = cell->center(true);
4365  }
4366  }
4367 
4368 
4369  // Now the lines:
4370  typename Triangulation<dim, spacedim>::raw_line_iterator new_lines[12];
4371  unsigned int lmin = 8;
4372  unsigned int lmax = 12;
4373  if (ref_case != RefinementCase<dim>::cut_xy)
4374  {
4375  lmin = 6;
4376  lmax = 7;
4377  }
4378 
4379  for (unsigned int l = lmin; l < lmax; ++l)
4380  {
4381  while (next_unused_line->used() == true)
4382  ++next_unused_line;
4383  new_lines[l] = next_unused_line;
4384  ++next_unused_line;
4385 
4386  Assert(
4387  new_lines[l]->used() == false,
4388  ExcMessage(
4389  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4390  }
4391 
4392  if (ref_case == RefinementCase<dim>::cut_xy)
4393  {
4394  // .-6-.-7-.
4395  // 1 9 3
4396  // .-10.11-.
4397  // 0 8 2
4398  // .-4-.-5-.
4399 
4400  // lines 0-7 already exist, create only the four interior
4401  // lines 8-11
4402  unsigned int l = 0;
4403  for (unsigned int face_no = 0;
4404  face_no < GeometryInfo<dim>::faces_per_cell;
4405  ++face_no)
4406  for (unsigned int c = 0; c < 2; ++c, ++l)
4407  new_lines[l] = cell->line(face_no)->child(c);
4408  Assert(l == 8, ExcInternalError());
4409 
4410  new_lines[8]->set(
4412  new_vertices[6], new_vertices[8]));
4413  new_lines[9]->set(
4415  new_vertices[8], new_vertices[7]));
4416  new_lines[10]->set(
4418  new_vertices[4], new_vertices[8]));
4419  new_lines[11]->set(
4421  new_vertices[8], new_vertices[5]));
4422  }
4423  else if (ref_case == RefinementCase<dim>::cut_x)
4424  {
4425  // .-4-.-5-.
4426  // | | |
4427  // 0 6 1
4428  // | | |
4429  // .-2-.-3-.
4430  new_lines[0] = cell->line(0);
4431  new_lines[1] = cell->line(1);
4432  new_lines[2] = cell->line(2)->child(0);
4433  new_lines[3] = cell->line(2)->child(1);
4434  new_lines[4] = cell->line(3)->child(0);
4435  new_lines[5] = cell->line(3)->child(1);
4436  new_lines[6]->set(
4438  new_vertices[6], new_vertices[7]));
4439  }
4440  else
4441  {
4443  // .---5---.
4444  // 1 3
4445  // .---6---.
4446  // 0 2
4447  // .---4---.
4448  new_lines[0] = cell->line(0)->child(0);
4449  new_lines[1] = cell->line(0)->child(1);
4450  new_lines[2] = cell->line(1)->child(0);
4451  new_lines[3] = cell->line(1)->child(1);
4452  new_lines[4] = cell->line(2);
4453  new_lines[5] = cell->line(3);
4454  new_lines[6]->set(
4456  new_vertices[4], new_vertices[5]));
4457  }
4458 
4459  for (unsigned int l = lmin; l < lmax; ++l)
4460  {
4461  new_lines[l]->set_used_flag();
4462  new_lines[l]->clear_user_flag();
4463  new_lines[l]->clear_user_data();
4464  new_lines[l]->clear_children();
4465  // interior line
4466  new_lines[l]->set_boundary_id_internal(
4468  new_lines[l]->set_manifold_id(cell->manifold_id());
4469  }
4470 
4471  // Now add the four (two)
4472  // new cells!
4475  while (next_unused_cell->used() == true)
4476  ++next_unused_cell;
4477 
4478  const unsigned int n_children = GeometryInfo<dim>::n_children(ref_case);
4479  for (unsigned int i = 0; i < n_children; ++i)
4480  {
4481  Assert(
4482  next_unused_cell->used() == false,
4483  ExcMessage(
4484  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4485  subcells[i] = next_unused_cell;
4486  ++next_unused_cell;
4487  if (i % 2 == 1 && i < n_children - 1)
4488  while (next_unused_cell->used() == true)
4489  ++next_unused_cell;
4490  }
4491 
4492  if (ref_case == RefinementCase<dim>::cut_xy)
4493  {
4494  // children:
4495  // .--.--.
4496  // |2 . 3|
4497  // .--.--.
4498  // |0 | 1|
4499  // .--.--.
4500  // lines:
4501  // .-6-.-7-.
4502  // 1 9 3
4503  // .-10.11-.
4504  // 0 8 2
4505  // .-4-.-5-.
4506  subcells[0]->set(
4508  new_lines[0]->index(),
4509  new_lines[8]->index(),
4510  new_lines[4]->index(),
4511  new_lines[10]->index()));
4512  subcells[1]->set(
4514  new_lines[8]->index(),
4515  new_lines[2]->index(),
4516  new_lines[5]->index(),
4517  new_lines[11]->index()));
4518  subcells[2]->set(
4520  new_lines[1]->index(),
4521  new_lines[9]->index(),
4522  new_lines[10]->index(),
4523  new_lines[6]->index()));
4524  subcells[3]->set(
4526  new_lines[9]->index(),
4527  new_lines[3]->index(),
4528  new_lines[11]->index(),
4529  new_lines[7]->index()));
4530  }
4531  else if (ref_case == RefinementCase<dim>::cut_x)
4532  {
4533  // children:
4534  // .--.--.
4535  // | . |
4536  // .0 . 1.
4537  // | | |
4538  // .--.--.
4539  // lines:
4540  // .-4-.-5-.
4541  // | | |
4542  // 0 6 1
4543  // | | |
4544  // .-2-.-3-.
4545  subcells[0]->set(
4547  new_lines[0]->index(),
4548  new_lines[6]->index(),
4549  new_lines[2]->index(),
4550  new_lines[4]->index()));
4551  subcells[1]->set(
4553  new_lines[6]->index(),
4554  new_lines[1]->index(),
4555  new_lines[3]->index(),
4556  new_lines[5]->index()));
4557  }
4558  else
4559  {
4561  // children:
4562  // .-----.
4563  // | 1 |
4564  // .-----.
4565  // | 0 |
4566  // .-----.
4567  // lines:
4568  // .---5---.
4569  // 1 3
4570  // .---6---.
4571  // 0 2
4572  // .---4---.
4573  subcells[0]->set(
4575  new_lines[0]->index(),
4576  new_lines[2]->index(),
4577  new_lines[4]->index(),
4578  new_lines[6]->index()));
4579  subcells[1]->set(
4581  new_lines[1]->index(),
4582  new_lines[3]->index(),
4583  new_lines[6]->index(),
4584  new_lines[5]->index()));
4585  }
4586 
4587  types::subdomain_id subdomainid = cell->subdomain_id();
4588 
4589  for (unsigned int i = 0; i < n_children; ++i)
4590  {
4591  subcells[i]->set_used_flag();
4592  subcells[i]->clear_refine_flag();
4593  subcells[i]->clear_user_flag();
4594  subcells[i]->clear_user_data();
4595  subcells[i]->clear_children();
4596  // inherit material
4597  // properties
4598  subcells[i]->set_material_id(cell->material_id());
4599  subcells[i]->set_manifold_id(cell->manifold_id());
4600  subcells[i]->set_subdomain_id(subdomainid);
4601 
4602  if (i % 2 == 0)
4603  subcells[i]->set_parent(cell->index());
4604  }
4605 
4606 
4607 
4608  // set child index for
4609  // even children children
4610  // i=0,2 (0)
4611  for (unsigned int i = 0; i < n_children / 2; ++i)
4612  cell->set_children(2 * i, subcells[2 * i]->index());
4613  // set the refine case
4614  cell->set_refinement_case(ref_case);
4615 
4616  // note that the
4617  // refinement flag was
4618  // already cleared at the
4619  // beginning of this function
4620 
4621  if (dim < spacedim)
4622  for (unsigned int c = 0; c < n_children; ++c)
4623  cell->child(c)->set_direction_flag(cell->direction_flag());
4624  }
4625 
4626 
4627 
4632  template <int spacedim>
4635  const bool /*check_for_distorted_cells*/)
4636  {
4637  const unsigned int dim = 1;
4638 
4639  // check whether a new level is needed we have to check for
4640  // this on the highest level only (on this, all used cells are
4641  // also active, so we only have to check for this)
4642  {
4644  cell = triangulation.begin_active(triangulation.levels.size() - 1),
4645  endc = triangulation.end();
4646  for (; cell != endc; ++cell)
4647  if (cell->used())
4648  if (cell->refine_flag_set())
4649  {
4650  triangulation.levels.push_back(
4651  std_cxx14::make_unique<
4653  break;
4654  }
4655  }
4656 
4657 
4658  // check how much space is needed on every level we need not
4659  // check the highest level since either - on the highest level
4660  // no cells are flagged for refinement - there are, but
4661  // prepare_refinement added another empty level
4662  unsigned int needed_vertices = 0;
4663  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4664  {
4665  // count number of flagged
4666  // cells on this level
4667  unsigned int flagged_cells = 0;
4669  acell = triangulation.begin_active(level),
4670  aendc = triangulation.begin_active(level + 1);
4671  for (; acell != aendc; ++acell)
4672  if (acell->refine_flag_set())
4673  ++flagged_cells;
4674 
4675  // count number of used cells
4676  // on the next higher level
4677  const unsigned int used_cells = std::count_if(
4678  triangulation.levels[level + 1]->cells.used.begin(),
4679  triangulation.levels[level + 1]->cells.used.end(),
4680  std::bind(std::equal_to<bool>(), std::placeholders::_1, true));
4681 
4682  // reserve space for the used_cells cells already existing
4683  // on the next higher level as well as for the
4684  // 2*flagged_cells that will be created on that level
4685  triangulation.levels[level + 1]->reserve_space(
4686  used_cells +
4688  1,
4689  spacedim);
4690  // reserve space for 2*flagged_cells new lines on the next
4691  // higher level
4692  triangulation.levels[level + 1]->cells.reserve_space(
4693  GeometryInfo<1>::max_children_per_cell * flagged_cells, 0);
4694 
4695  needed_vertices += flagged_cells;
4696  }
4697 
4698  // add to needed vertices how many
4699  // vertices are already in use
4700  needed_vertices += std::count_if(triangulation.vertices_used.begin(),
4701  triangulation.vertices_used.end(),
4702  std::bind(std::equal_to<bool>(),
4703  std::placeholders::_1,
4704  true));
4705  // if we need more vertices: create them, if not: leave the
4706  // array as is, since shrinking is not really possible because
4707  // some of the vertices at the end may be in use
4708  if (needed_vertices > triangulation.vertices.size())
4709  {
4710  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
4711  triangulation.vertices_used.resize(needed_vertices, false);
4712  }
4713 
4714 
4715  // Do REFINEMENT on every level; exclude highest level as
4716  // above
4717 
4718  // index of next unused vertex
4719  unsigned int next_unused_vertex = 0;
4720 
4721  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4722  {
4724  cell = triangulation.begin_active(level),
4725  endc = triangulation.begin_active(level + 1);
4726 
4728  next_unused_cell = triangulation.begin_raw(level + 1);
4729 
4730  for (; (cell != endc) && (cell->level() == level); ++cell)
4731  if (cell->refine_flag_set())
4732  {
4733  // clear refinement flag
4734  cell->clear_refine_flag();
4735 
4736  // search for next unused
4737  // vertex
4738  while (triangulation.vertices_used[next_unused_vertex] ==
4739  true)
4740  ++next_unused_vertex;
4741  Assert(
4742  next_unused_vertex < triangulation.vertices.size(),
4743  ExcMessage(
4744  "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."));
4745 
4746  // Now we always ask the cell itself where to put
4747  // the new point. The cell in turn will query the
4748  // manifold object internally.
4749  triangulation.vertices[next_unused_vertex] =
4750  cell->center(true);
4751 
4752  triangulation.vertices_used[next_unused_vertex] = true;
4753 
4754  // search for next two unused cell (++ takes care of
4755  // the end of the vector)
4757  first_child,
4758  second_child;
4759  while (next_unused_cell->used() == true)
4760  ++next_unused_cell;
4761  first_child = next_unused_cell;
4762  first_child->set_used_flag();
4763  first_child->clear_user_data();
4764  ++next_unused_cell;
4765  Assert(
4766  next_unused_cell->used() == false,
4767  ExcMessage(
4768  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4769  second_child = next_unused_cell;
4770  second_child->set_used_flag();
4771  second_child->clear_user_data();
4772 
4773  types::subdomain_id subdomainid = cell->subdomain_id();
4774 
4775  // insert first child
4776  cell->set_children(0, first_child->index());
4777  first_child->clear_children();
4778  first_child->set(
4780  cell->vertex_index(0), next_unused_vertex));
4781  first_child->set_material_id(cell->material_id());
4782  first_child->set_manifold_id(cell->manifold_id());
4783  first_child->set_subdomain_id(subdomainid);
4784  first_child->set_direction_flag(cell->direction_flag());
4785 
4786  first_child->set_parent(cell->index());
4787 
4788  // Set manifold id of the right face. Only do this
4789  // on the first child.
4790  first_child->face(1)->set_manifold_id(cell->manifold_id());
4791 
4792  // reset neighborship info (refer to
4793  // internal::TriangulationImplementation::TriaLevel<0> for
4794  // details)
4795  first_child->set_neighbor(1, second_child);
4796  if (cell->neighbor(0).state() != IteratorState::valid)
4797  first_child->set_neighbor(0, cell->neighbor(0));
4798  else if (cell->neighbor(0)->active())
4799  {
4800  // since the neighbors level is always <=level,
4801  // if the cell is active, then there are no
4802  // cells to the left which may want to know
4803  // about this new child cell.
4804  Assert(cell->neighbor(0)->level() <= cell->level(),
4805  ExcInternalError());
4806  first_child->set_neighbor(0, cell->neighbor(0));
4807  }
4808  else
4809  // left neighbor is refined
4810  {
4811  // set neighbor to cell on same level
4812  const unsigned int nbnb = cell->neighbor_of_neighbor(0);
4813  first_child->set_neighbor(0,
4814  cell->neighbor(0)->child(nbnb));
4815 
4816  // reset neighbor info of all right descendant
4817  // of the left neighbor of cell
4819  left_neighbor = cell->neighbor(0);
4820  while (left_neighbor->has_children())
4821  {
4822  left_neighbor = left_neighbor->child(nbnb);
4823  left_neighbor->set_neighbor(nbnb, first_child);
4824  }
4825  }
4826 
4827  // insert second child
4828  second_child->clear_children();
4829  second_child->set(
4831  next_unused_vertex, cell->vertex_index(1)));
4832  second_child->set_neighbor(0, first_child);
4833  second_child->set_material_id(cell->material_id());
4834  second_child->set_manifold_id(cell->manifold_id());
4835  second_child->set_subdomain_id(subdomainid);
4836  second_child->set_direction_flag(cell->direction_flag());
4837 
4838  if (cell->neighbor(1).state() != IteratorState::valid)
4839  second_child->set_neighbor(1, cell->neighbor(1));
4840  else if (cell->neighbor(1)->active())
4841  {
4842  Assert(cell->neighbor(1)->level() <= cell->level(),
4843  ExcInternalError());
4844  second_child->set_neighbor(1, cell->neighbor(1));
4845  }
4846  else
4847  // right neighbor is refined same as above
4848  {
4849  const unsigned int nbnb = cell->neighbor_of_neighbor(1);
4850  second_child->set_neighbor(
4851  1, cell->neighbor(1)->child(nbnb));
4852 
4854  right_neighbor = cell->neighbor(1);
4855  while (right_neighbor->has_children())
4856  {
4857  right_neighbor = right_neighbor->child(nbnb);
4858  right_neighbor->set_neighbor(nbnb, second_child);
4859  }
4860  }
4861  // inform all listeners that cell refinement is done
4862  triangulation.signals.post_refinement_on_cell(cell);
4863  }
4864  }
4865 
4866  // in 1d, we can not have distorted children unless the parent
4867  // was already distorted (that is because we don't use
4868  // boundary information for 1d triangulations). so return an
4869  // empty list
4871  }
4872 
4873 
4878  template <int spacedim>
4881  const bool check_for_distorted_cells)
4882  {
4883  const unsigned int dim = 2;
4884 
4885  // check whether a new level is needed we have to check for
4886  // this on the highest level only (on this, all used cells are
4887  // also active, so we only have to check for this)
4888  if (true)
4889  {
4891  cell =
4892  triangulation.begin_active(triangulation.levels.size() - 1),
4893  endc = triangulation.end();
4894  for (; cell != endc; ++cell)
4895  if (cell->used())
4896  if (cell->refine_flag_set())
4897  {
4898  triangulation.levels.push_back(
4899  std_cxx14::make_unique<
4901  dim>>());
4902  break;
4903  }
4904  }
4905 
4906 
4907  // first clear user flags and pointers of lines; we're going
4908  // to use them to flag which lines need refinement
4909  for (typename Triangulation<dim, spacedim>::line_iterator line =
4910  triangulation.begin_line();
4911  line != triangulation.end_line();
4912  ++line)
4913  {
4914  line->clear_user_flag();
4915  line->clear_user_data();
4916  }
4917  // running over all cells and lines count the number
4918  // n_single_lines of lines which can be stored as single
4919  // lines, e.g. inner lines
4920  unsigned int n_single_lines = 0;
4921 
4922  // New lines to be created: number lines which are stored in
4923  // pairs (the children of lines must be stored in pairs)
4924  unsigned int n_lines_in_pairs = 0;
4925 
4926  // check how much space is needed on every level we need not
4927  // check the highest level since either - on the highest level
4928  // no cells are flagged for refinement - there are, but
4929  // prepare_refinement added another empty level
4930  unsigned int needed_vertices = 0;
4931  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
4932  {
4933  // count number of flagged cells on this level and compute
4934  // how many new vertices and new lines will be needed
4935  unsigned int needed_cells = 0;
4936 
4938  cell = triangulation.begin_active(level),
4939  endc = triangulation.begin_active(level + 1);
4940  for (; cell != endc; ++cell)
4941  if (cell->refine_flag_set())
4942  {
4943  if (cell->refine_flag_set() == RefinementCase<dim>::cut_xy)
4944  {
4945  needed_cells += 4;
4946 
4947  // new vertex at center of cell is needed in any
4948  // case
4949  ++needed_vertices;
4950 
4951  // the four inner lines can be stored as singles
4952  n_single_lines += 4;
4953  }
4954  else // cut_x || cut_y
4955  {
4956  // set the flag showing that anisotropic
4957  // refinement is used for at least one cell
4958  triangulation.anisotropic_refinement = true;
4959 
4960  needed_cells += 2;
4961  // no vertex at center
4962 
4963  // the inner line can be stored as single
4964  n_single_lines += 1;
4965  }
4966 
4967  // mark all faces (lines) for refinement; checking
4968  // locally whether the neighbor would also like to
4969  // refine them is rather difficult for lines so we
4970  // only flag them and after visiting all cells, we
4971  // decide which lines need refinement;
4972  for (unsigned int line_no = 0;
4973  line_no < GeometryInfo<dim>::faces_per_cell;
4974  ++line_no)
4975  {
4977  cell->refine_flag_set(), line_no) ==
4979  {
4980  typename Triangulation<dim, spacedim>::line_iterator
4981  line = cell->line(line_no);
4982  if (line->has_children() == false)
4983  {
4984  line->set_user_flag();
4985  // TODO[WB]: we overwrite the user_index here
4986  // because we later on need
4987  // to find out which boundary object we have to
4988  // ask to refine this line. we can't use the
4989  // boundary_id field because that can only be used
4990  // for lines at the boundary of the domain, but we
4991  // also need a domain description for interior
4992  // lines in the codim-1 case
4993  if (spacedim > dim)
4994  {
4995  if (line->at_boundary())
4996  // if possible honor boundary
4997  // indicator
4998  line->set_user_index(line->boundary_id());
4999  else
5000  // otherwise take manifold
5001  // description from the adjacent
5002  // cell
5003  line->set_user_index(cell->material_id());
5004  }
5005  }
5006  }
5007  }
5008  }
5009 
5010 
5011  // count number of used cells on the next higher level
5012  const unsigned int used_cells = std::count_if(
5013  triangulation.levels[level + 1]->cells.used.begin(),
5014  triangulation.levels[level + 1]->cells.used.end(),
5015  std::bind(std::equal_to<bool>(), std::placeholders::_1, true));
5016 
5017 
5018  // reserve space for the used_cells cells already existing
5019  // on the next higher level as well as for the
5020  // needed_cells that will be created on that level
5021  triangulation.levels[level + 1]->reserve_space(
5022  used_cells + needed_cells, 2, spacedim);
5023 
5024  // reserve space for needed_cells new quads on the next
5025  // higher level
5026  triangulation.levels[level + 1]->cells.reserve_space(needed_cells,
5027  0);
5028  }
5029 
5030  // now count the lines which were flagged for refinement
5031  for (typename Triangulation<dim, spacedim>::line_iterator line =
5032  triangulation.begin_line();
5033  line != triangulation.end_line();
5034  ++line)
5035  if (line->user_flag_set())
5036  {
5037  Assert(line->has_children() == false, ExcInternalError());
5038  n_lines_in_pairs += 2;
5039  needed_vertices += 1;
5040  }
5041  // reserve space for n_lines_in_pairs new lines. note, that
5042  // we can't reserve space for the single lines here as well,
5043  // as all the space reserved for lines in pairs would be
5044  // counted as unused and we would end up with too little space
5045  // to store all lines. memory reservation for n_single_lines
5046  // can only be done AFTER we refined the lines of the current
5047  // cells
5048  triangulation.faces->lines.reserve_space(n_lines_in_pairs, 0);
5049 
5050  // add to needed vertices how many vertices are already in use
5051  needed_vertices += std::count_if(triangulation.vertices_used.begin(),
5052  triangulation.vertices_used.end(),
5053  std::bind(std::equal_to<bool>(),
5054  std::placeholders::_1,
5055  true));
5056  // if we need more vertices: create them, if not: leave the
5057  // array as is, since shrinking is not really possible because
5058  // some of the vertices at the end may be in use
5059  if (needed_vertices > triangulation.vertices.size())
5060  {
5061  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
5062  triangulation.vertices_used.resize(needed_vertices, false);
5063  }
5064 
5065 
5066  // Do REFINEMENT on every level; exclude highest level as
5067  // above
5068 
5069  // index of next unused vertex
5070  unsigned int next_unused_vertex = 0;
5071 
5072  // first the refinement of lines. children are stored
5073  // pairwise
5074  if (true)
5075  {
5076  // only active objects can be refined further
5077  typename Triangulation<dim, spacedim>::active_line_iterator
5078  line = triangulation.begin_active_line(),
5079  endl = triangulation.end_line();
5080  typename Triangulation<dim, spacedim>::raw_line_iterator
5081  next_unused_line = triangulation.begin_raw_line();
5082 
5083  for (; line != endl; ++line)
5084  if (line->user_flag_set())
5085  {
5086  // this line needs to be refined
5087 
5088  // find the next unused vertex and set it
5089  // appropriately
5090  while (triangulation.vertices_used[next_unused_vertex] ==
5091  true)
5092  ++next_unused_vertex;
5093  Assert(
5094  next_unused_vertex < triangulation.vertices.size(),
5095  ExcMessage(
5096  "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."));
5097  triangulation.vertices_used[next_unused_vertex] = true;
5098 
5099  if (spacedim == dim)
5100  {
5101  // for the case of a domain in an
5102  // equal-dimensional space we only have to treat
5103  // boundary lines differently; for interior
5104  // lines we can compute the midpoint as the mean
5105  // of the two vertices: if (line->at_boundary())
5106  triangulation.vertices[next_unused_vertex] =
5107  line->center(true);
5108  }
5109  else
5110  // however, if spacedim>dim, we always have to ask
5111  // the boundary object for its answer. We use the
5112  // same object of the cell (which was stored in
5113  // line->user_index() before) unless a manifold_id
5114  // has been set on this very line.
5115  if (line->manifold_id() == numbers::invalid_manifold_id)
5116  triangulation.vertices[next_unused_vertex] =
5117  triangulation.get_manifold(line->user_index())
5118  .get_new_point_on_line(line);
5119  else
5120  triangulation.vertices[next_unused_vertex] =
5121  line->center(true);
5122 
5123  // now that we created the right point, make up the
5124  // two child lines. To this end, find a pair of
5125  // unused lines
5126  bool pair_found = false;
5127  (void)pair_found;
5128  for (; next_unused_line != endl; ++next_unused_line)
5129  if (!next_unused_line->used() &&
5130  !(++next_unused_line)->used())
5131  {
5132  // go back to the first of the two unused
5133  // lines
5134  --next_unused_line;
5135  pair_found = true;
5136  break;
5137  }
5138  Assert(pair_found, ExcInternalError());
5139 
5140  // there are now two consecutive unused lines, such
5141  // that the children of a line will be consecutive.
5142  // then set the child pointer of the present line
5143  line->set_children(0, next_unused_line->index());
5144 
5145  // set the two new lines
5146  const typename Triangulation<dim, spacedim>::raw_line_iterator
5147  children[2] = {next_unused_line, ++next_unused_line};
5148  // some tests; if any of the iterators should be
5149  // invalid, then already dereferencing will fail
5150  Assert(
5151  children[0]->used() == false,
5152  ExcMessage(
5153  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5154  Assert(
5155  children[1]->used() == false,
5156  ExcMessage(
5157  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5158 
5159  children[0]->set(
5161  line->vertex_index(0), next_unused_vertex));
5162  children[1]->set(
5164  next_unused_vertex, line->vertex_index(1)));
5165 
5166  children[0]->set_used_flag();
5167  children[1]->set_used_flag();
5168  children[0]->clear_children();
5169  children[1]->clear_children();
5170  children[0]->clear_user_data();
5171  children[1]->clear_user_data();
5172  children[0]->clear_user_flag();
5173  children[1]->clear_user_flag();
5174 
5175 
5176  children[0]->set_boundary_id_internal(line->boundary_id());
5177  children[1]->set_boundary_id_internal(line->boundary_id());
5178 
5179  children[0]->set_manifold_id(line->manifold_id());
5180  children[1]->set_manifold_id(line->manifold_id());
5181 
5182  // finally clear flag indicating the need for
5183  // refinement
5184  line->clear_user_flag();
5185  }
5186  }
5187 
5188 
5189  // Now set up the new cells
5190 
5191  // reserve space for inner lines (can be stored as single
5192  // lines)
5193  triangulation.faces->lines.reserve_space(0, n_single_lines);
5194 
5196  cells_with_distorted_children;
5197 
5198  // reset next_unused_line, as now also single empty places in
5199  // the vector can be used
5200  typename Triangulation<dim, spacedim>::raw_line_iterator
5201  next_unused_line = triangulation.begin_raw_line();
5202 
5203  for (int level = 0;
5204  level < static_cast<int>(triangulation.levels.size()) - 1;
5205  ++level)
5206  {
5207  // Remember: as we don't operate on the finest level,
5208  // begin_*(level+1) is allowed
5210  cell = triangulation.begin_active(level),
5211  endc = triangulation.begin_active(level + 1);
5212 
5214  next_unused_cell = triangulation.begin_raw(level + 1);
5215 
5216  for (; cell != endc; ++cell)
5217  if (cell->refine_flag_set())
5218  {
5219  // set the user flag to indicate, that at least one
5220  // line is at the boundary
5221 
5222  // TODO[Tobias Leicht] find a better place to set
5223  // this flag, so that we do not need so much time to
5224  // check each cell here
5225  if (cell->at_boundary())
5226  cell->set_user_flag();
5227 
5228  // actually set up the children and update neighbor
5229  // information
5230  create_children(triangulation,
5231  next_unused_vertex,
5232  next_unused_line,
5233  next_unused_cell,
5234  cell);
5235 
5236  if ((check_for_distorted_cells == true) &&
5237  has_distorted_children(
5238  cell,
5239  std::integral_constant<int, dim>(),
5240  std::integral_constant<int, spacedim>()))
5241  cells_with_distorted_children.distorted_cells.push_back(
5242  cell);
5243  // inform all listeners that cell refinement is done
5244  triangulation.signals.post_refinement_on_cell(cell);
5245  }
5246  }
5247 
5248  return cells_with_distorted_children;
5249  }
5250 
5251 
5256  template <int spacedim>
5259  const bool check_for_distorted_cells)
5260  {
5261  const unsigned int dim = 3;
5262 
5263  // this function probably also works for spacedim>3 but it
5264  // isn't tested. it will probably be necessary to pull new
5265  // vertices onto the manifold just as we do for the other
5266  // functions above.
5267  Assert(spacedim == 3, ExcNotImplemented());
5268 
5269  // check whether a new level is needed we have to check for
5270  // this on the highest level only (on this, all used cells are
5271  // also active, so we only have to check for this)
5272  if (true)
5273  {
5275  cell =
5276  triangulation.begin_active(triangulation.levels.size() - 1),
5277  endc = triangulation.end();
5278  for (; cell != endc; ++cell)
5279  if (cell->used())
5280  if (cell->refine_flag_set())
5281  {
5282  triangulation.levels.push_back(
5283  std_cxx14::make_unique<
5285  dim>>());
5286  break;
5287  }
5288  }
5289 
5290 
5291  // first clear user flags for quads and lines; we're going to
5292  // use them to flag which lines and quads need refinement
5293  triangulation.faces->quads.clear_user_data();
5294 
5295  for (typename Triangulation<dim, spacedim>::line_iterator line =
5296  triangulation.begin_line();
5297  line != triangulation.end_line();
5298  ++line)
5299  line->clear_user_flag();
5300  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
5301  triangulation.begin_quad();
5302  quad != triangulation.end_quad();
5303  ++quad)
5304  quad->clear_user_flag();
5305 
5306  // create an array of face refine cases. User indices of faces
5307  // will be set to values corresponding with indices in this
5308  // array.
5309  const RefinementCase<dim - 1> face_refinement_cases[4] = {
5310  RefinementCase<dim - 1>::no_refinement,
5311  RefinementCase<dim - 1>::cut_x,
5312  RefinementCase<dim - 1>::cut_y,
5313  RefinementCase<dim - 1>::cut_xy};
5314 
5315  // check how much space is needed on every level we need not
5316  // check the highest level since either
5317  // - on the highest level no cells are flagged for refinement
5318  // - there are, but prepare_refinement added another empty
5319  // level which then is the highest level
5320 
5321  // variables to hold the number of newly to be created
5322  // vertices, lines and quads. as these are stored globally,
5323  // declare them outside the loop over al levels. we need lines
5324  // and quads in pairs for refinement of old ones and lines and
5325  // quads, that can be stored as single ones, as they are newly
5326  // created in the inside of an existing cell
5327  unsigned int needed_vertices = 0;
5328  unsigned int needed_lines_single = 0;
5329  unsigned int needed_quads_single = 0;
5330  unsigned int needed_lines_pair = 0;
5331  unsigned int needed_quads_pair = 0;
5332  for (int level = triangulation.levels.size() - 2; level >= 0; --level)
5333  {
5334  // count number of flagged cells on this level and compute
5335  // how many new vertices and new lines will be needed
5336  unsigned int new_cells = 0;
5337 
5339  acell = triangulation.begin_active(level),
5340  aendc = triangulation.begin_active(level + 1);
5341  for (; acell != aendc; ++acell)
5342  if (acell->refine_flag_set())
5343  {
5344  RefinementCase<dim> ref_case = acell->refine_flag_set();
5345 
5346  // now for interior vertices, lines and quads, which
5347  // are needed in any case
5348  if (ref_case == RefinementCase<dim>::cut_x ||
5349  ref_case == RefinementCase<dim>::cut_y ||
5350  ref_case == RefinementCase<dim>::cut_z)
5351  {
5352  ++needed_quads_single;
5353  new_cells += 2;
5354  triangulation.anisotropic_refinement = true;
5355  }
5356  else if (ref_case == RefinementCase<dim>::cut_xy ||
5357  ref_case == RefinementCase<dim>::cut_xz ||
5358  ref_case == RefinementCase<dim>::cut_yz)
5359  {
5360  ++needed_lines_single;
5361  needed_quads_single += 4;
5362  new_cells += 4;
5363  triangulation.anisotropic_refinement = true;
5364  }
5365  else if (ref_case == RefinementCase<dim>::cut_xyz)
5366  {
5367  ++needed_vertices;
5368  needed_lines_single += 6;
5369  needed_quads_single += 12;
5370  new_cells += 8;
5371  }
5372  else
5373  {
5374  // we should never get here
5375  Assert(false, ExcInternalError());
5376  }
5377 
5378  // mark all faces for refinement; checking locally
5379  // if and how the neighbor would like to refine
5380  // these is difficult so we only flag them and after
5381  // visiting all cells, we decide which faces need
5382  // which refinement;
5383  for (unsigned int face = 0;
5384  face < GeometryInfo<dim>::faces_per_cell;
5385  ++face)
5386  {
5388  aface = acell->face(face);
5389  // get the RefineCase this faces has for the
5390  // given RefineCase of the cell
5391  RefinementCase<dim - 1> face_ref_case =
5393  ref_case,
5394  face,
5395  acell->face_orientation(face),
5396  acell->face_flip(face),
5397  acell->face_rotation(face));
5398  // only do something, if this face has to be
5399  // refined
5400  if (face_ref_case)
5401  {
5402  if (face_ref_case ==
5404  {
5405  if (aface->number_of_children() < 4)
5406  // we use user_flags to denote needed
5407  // isotropic refinement
5408  aface->set_user_flag();
5409  }
5410  else if (aface->refinement_case() != face_ref_case)
5411  // we use user_indices to denote needed
5412  // anisotropic refinement. note, that we
5413  // can have at most one anisotropic
5414  // refinement case for this face, as
5415  // otherwise prepare_refinement() would
5416  // have changed one of the cells to yield
5417  // isotropic refinement at this
5418  // face. therefore we set the user_index
5419  // uniquely
5420  {
5421  Assert(aface->refinement_case() ==
5423  dim - 1>::isotropic_refinement ||
5424  aface->refinement_case() ==
5425  RefinementCase<dim - 1>::no_refinement,
5426  ExcInternalError());
5427  aface->set_user_index(face_ref_case);
5428  }
5429  }
5430  } // for all faces
5431 
5432  // flag all lines, that have to be refined
5433  for (unsigned int line = 0;
5434  line < GeometryInfo<dim>::lines_per_cell;
5435  ++line)
5437  line) &&
5438  !acell->line(line)->has_children())
5439  acell->line(line)->set_user_flag();
5440 
5441  } // if refine_flag set and for all cells on this level
5442 
5443 
5444  // count number of used cells on the next higher level
5445  const unsigned int used_cells = std::count_if(
5446  triangulation.levels[level + 1]->cells.used.begin(),
5447  triangulation.levels[level + 1]->cells.used.end(),
5448  std::bind(std::equal_to<bool>(), std::placeholders::_1, true));
5449 
5450 
5451  // reserve space for the used_cells cells already existing
5452  // on the next higher level as well as for the
5453  // 8*flagged_cells that will be created on that level
5454  triangulation.levels[level + 1]->reserve_space(
5455  used_cells + new_cells, 3, spacedim);
5456  // reserve space for 8*flagged_cells new hexes on the next
5457  // higher level
5458  triangulation.levels[level + 1]->cells.reserve_space(new_cells);
5459  } // for all levels
5460  // now count the quads and lines which were flagged for
5461  // refinement
5462  for (typename Triangulation<dim, spacedim>::quad_iterator quad =
5463  triangulation.begin_quad();
5464  quad != triangulation.end_quad();
5465  ++quad)
5466  {
5467  if (quad->user_flag_set())
5468  {
5469  // isotropic refinement: 1 interior vertex, 4 quads
5470  // and 4 interior lines. we store the interior lines
5471  // in pairs in case the face is already or will be
5472  // refined anisotropically
5473  needed_quads_pair += 4;
5474  needed_lines_pair += 4;
5475  needed_vertices += 1;
5476  }
5477  if (quad->user_index())
5478  {
5479  // anisotropic refinement: 1 interior
5480  // line and two quads
5481  needed_quads_pair += 2;
5482  needed_lines_single += 1;
5483  // there is a kind of complicated situation here which
5484  // requires our attention. if the quad is refined
5485  // isotropcally, two of the interior lines will get a
5486  // new mother line - the interior line of our
5487  // anisotropically refined quad. if those two lines
5488  // are not consecutive, we cannot do so and have to
5489  // replace them by two lines that are consecutive. we
5490  // try to avoid that situation, but it may happen
5491  // nevertheless through repeated refinement and
5492  // coarsening. thus we have to check here, as we will
5493  // need some additional space to store those new lines
5494  // in case we need them...
5495  if (quad->has_children())
5496  {
5497  Assert(quad->refinement_case() ==
5498  RefinementCase<dim - 1>::isotropic_refinement,
5499  ExcInternalError());
5500  if ((face_refinement_cases[quad->user_index()] ==
5501  RefinementCase<dim - 1>::cut_x &&
5502  (quad->child(0)->line_index(1) + 1 !=
5503  quad->child(2)->line_index(1))) ||
5504  (face_refinement_cases[quad->user_index()] ==
5505  RefinementCase<dim - 1>::cut_y &&
5506  (quad->child(0)->line_index(3) + 1 !=
5507  quad->child(1)->line_index(3))))
5508  needed_lines_pair += 2;
5509  }
5510  }
5511  }
5512 
5513  for (typename Triangulation<dim, spacedim>::line_iterator line =
5514  triangulation.begin_line();
5515  line != triangulation.end_line();
5516  ++line)
5517  if (line->user_flag_set())
5518  {
5519  needed_lines_pair += 2;
5520  needed_vertices += 1;
5521  }
5522 
5523  // reserve space for needed_lines new lines stored in pairs
5524  triangulation.faces->lines.reserve_space(needed_lines_pair,
5525  needed_lines_single);
5526  // reserve space for needed_quads new quads stored in pairs
5527  triangulation.faces->quads.reserve_space(needed_quads_pair,
5528  needed_quads_single);
5529 
5530 
5531  // add to needed vertices how many vertices are already in use
5532  needed_vertices += std::count_if(triangulation.vertices_used.begin(),
5533  triangulation.vertices_used.end(),
5534  std::bind(std::equal_to<bool>(),
5535  std::placeholders::_1,
5536  true));
5537  // if we need more vertices: create them, if not: leave the
5538  // array as is, since shrinking is not really possible because
5539  // some of the vertices at the end may be in use
5540  if (needed_vertices > triangulation.vertices.size())
5541  {
5542  triangulation.vertices.resize(needed_vertices, Point<spacedim>());
5543  triangulation.vertices_used.resize(needed_vertices, false);
5544  }
5545 
5546 
5548  // Before we start with the actual refinement, we do some
5549  // sanity checks if in debug mode. especially, we try to catch
5550  // the notorious problem with lines being twice refined,
5551  // i.e. there are cells adjacent at one line ("around the
5552  // edge", but not at a face), with two cells differing by more
5553  // than one refinement level
5554  //
5555  // this check is very simple to implement here, since we have
5556  // all lines flagged if they shall be refined
5557 #ifdef DEBUG
5559  triangulation.begin_active();
5560  cell != triangulation.end();
5561  ++cell)
5562  if (!cell->refine_flag_set())
5563  for (unsigned int line = 0;
5564  line < GeometryInfo<dim>::lines_per_cell;
5565  ++line)
5566  if (cell->line(line)->has_children())
5567  for (unsigned int c = 0; c < 2; ++c)
5568  Assert(cell->line(line)->child(c)->user_flag_set() == false,
5569  ExcInternalError());
5570 #endif
5571 
5573  // Do refinement on every level
5574  //
5575  // To make life a bit easier, we first refine those lines and
5576  // quads that were flagged for refinement and then compose the
5577  // newly to be created cells.
5578  //
5579  // index of next unused vertex
5580  unsigned int next_unused_vertex = 0;
5581 
5582  // first for lines
5583  if (true)
5584  {
5585  // only active objects can be refined further
5586  typename Triangulation<dim, spacedim>::active_line_iterator
5587  line = triangulation.begin_active_line(),
5588  endl = triangulation.end_line();
5589  typename Triangulation<dim, spacedim>::raw_line_iterator
5590  next_unused_line = triangulation.begin_raw_line();
5591 
5592  for (; line != endl; ++line)
5593  if (line->user_flag_set())
5594  {
5595  // this line needs to be refined
5596 
5597  // find the next unused vertex and set it
5598  // appropriately
5599  while (triangulation.vertices_used[next_unused_vertex] ==
5600  true)
5601  ++next_unused_vertex;
5602  Assert(
5603  next_unused_vertex < triangulation.vertices.size(),
5604  ExcMessage(
5605  "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."));
5606  triangulation.vertices_used[next_unused_vertex] = true;
5607 
5608  triangulation.vertices[next_unused_vertex] =
5609  line->center(true);
5610 
5611  // now that we created the right point, make up the
5612  // two child lines (++ takes care of the end of the
5613  // vector)
5614  next_unused_line =
5615  triangulation.faces->lines.next_free_pair_object(
5616  triangulation);
5617  Assert(next_unused_line.state() == IteratorState::valid,
5618  ExcInternalError());
5619 
5620  // now we found two consecutive unused lines, such
5621  // that the children of a line will be consecutive.
5622  // then set the child pointer of the present line
5623  line->set_children(0, next_unused_line->index());
5624 
5625  // set the two new lines
5626  const typename Triangulation<dim, spacedim>::raw_line_iterator
5627  children[2] = {next_unused_line, ++next_unused_line};
5628 
5629  // some tests; if any of the iterators should be
5630  // invalid, then already dereferencing will fail
5631  Assert(
5632  children[0]->used() == false,
5633  ExcMessage(
5634  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5635  Assert(
5636  children[1]->used() == false,
5637  ExcMessage(
5638  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5639 
5640  children[0]->set(
5642  line->vertex_index(0), next_unused_vertex));
5643  children[1]->set(
5645  next_unused_vertex, line->vertex_index(1)));
5646 
5647  children[0]->set_used_flag();
5648  children[1]->set_used_flag();
5649  children[0]->clear_children();
5650  children[1]->clear_children();
5651  children[0]->clear_user_data();
5652  children[1]->clear_user_data();
5653  children[0]->clear_user_flag();
5654  children[1]->clear_user_flag();
5655 
5656  children[0]->set_boundary_id_internal(line->boundary_id());
5657  children[1]->set_boundary_id_internal(line->boundary_id());
5658 
5659  children[0]->set_manifold_id(line->manifold_id());
5660  children[1]->set_manifold_id(line->manifold_id());
5661 
5662  // finally clear flag
5663  // indicating the need
5664  // for refinement
5665  line->clear_user_flag();
5666  }
5667  }
5668 
5669 
5671  // now refine marked quads
5673 
5674  // here we encounter several cases:
5675 
5676  // a) the quad is unrefined and shall be refined isotropically
5677 
5678  // b) the quad is unrefined and shall be refined
5679  // anisotropically
5680 
5681  // c) the quad is unrefined and shall be refined both
5682  // anisotropically and isotropically (this is reduced to case
5683  // b) and then case b) for the children again)
5684 
5685  // d) the quad is refined anisotropically and shall be refined
5686  // isotropically (this is reduced to case b) for the
5687  // anisotropic children)
5688 
5689  // e) the quad is refined isotropically and shall be refined
5690  // anisotropically (this is transformed to case c), however we
5691  // might have to renumber/rename children...)
5692 
5693  // we need a loop in cases c) and d), as the anisotropic
5694  // children migt have a lower index than the mother quad
5695  for (unsigned int loop = 0; loop < 2; ++loop)
5696  {
5697  // usually, only active objects can be refined
5698  // further. however, in cases d) and e) that is not true,
5699  // so we have to use 'normal' iterators here
5700  typename Triangulation<dim, spacedim>::quad_iterator
5701  quad = triangulation.begin_quad(),
5702  endq = triangulation.end_quad();
5703  typename Triangulation<dim, spacedim>::raw_line_iterator
5704  next_unused_line = triangulation.begin_raw_line();
5705  typename Triangulation<dim, spacedim>::raw_quad_iterator
5706  next_unused_quad = triangulation.begin_raw_quad();
5707 
5708  for (; quad != endq; ++quad)
5709  {
5710  if (quad->user_index())
5711  {
5712  RefinementCase<dim - 1> aniso_quad_ref_case =
5713  face_refinement_cases[quad->user_index()];
5714  // there is one unlikely event here, where we
5715  // already have refind the face: if the face was
5716  // refined anisotropically and we want to refine
5717  // it isotropically, both children are flagged for
5718  // anisotropic refinement. however, if those
5719  // children were already flagged for anisotropic
5720  // refinement, they might already be processed and
5721  // refined.
5722  if (aniso_quad_ref_case == quad->refinement_case())
5723  continue;
5724 
5725  Assert(quad->refinement_case() ==
5726  RefinementCase<dim - 1>::cut_xy ||
5727  quad->refinement_case() ==
5728  RefinementCase<dim - 1>::no_refinement,
5729  ExcInternalError());
5730 
5731  // this quad needs to be refined anisotropically
5732  Assert(quad->user_index() ==
5733  RefinementCase<dim - 1>::cut_x ||
5734  quad->user_index() ==
5735  RefinementCase<dim - 1>::cut_y,
5736  ExcInternalError());
5737 
5738  // make the new line interior to the quad
5739  typename Triangulation<dim, spacedim>::raw_line_iterator
5740  new_line;
5741 
5742  new_line =
5743  triangulation.faces->lines.next_free_single_object(
5744  triangulation);
5745  Assert(
5746  new_line->used() == false,
5747  ExcMessage(
5748  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5749 
5750  // first collect the
5751  // indices of the vertices:
5752  // *--1--*
5753  // | | |
5754  // | | | cut_x
5755  // | | |
5756  // *--0--*
5757  //
5758  // *-----*
5759  // | |
5760  // 0-----1 cut_y
5761  // | |
5762  // *-----*
5763  unsigned int vertex_indices[2];
5764  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5765  {
5766  vertex_indices[0] =
5767  quad->line(2)->child(0)->vertex_index(1);
5768  vertex_indices[1] =
5769  quad->line(3)->child(0)->vertex_index(1);
5770  }
5771  else
5772  {
5773  vertex_indices[0] =
5774  quad->line(0)->child(0)->vertex_index(1);
5775  vertex_indices[1] =
5776  quad->line(1)->child(0)->vertex_index(1);
5777  }
5778 
5779  new_line->set(
5781  vertex_indices[0], vertex_indices[1]));
5782  new_line->set_used_flag();
5783  new_line->clear_user_flag();
5784  new_line->clear_user_data();
5785  new_line->clear_children();
5786  new_line->set_boundary_id_internal(quad->boundary_id());
5787  new_line->set_manifold_id(quad->manifold_id());
5788 
5789  // child 0 and 1 of a line are switched if the
5790  // line orientation is false. set up a miniature
5791  // table, indicating which child to take for line
5792  // orientations false and true. first index: child
5793  // index in standard orientation, second index:
5794  // line orientation
5795  const unsigned int index[2][2] = {
5796  {1, 0}, // child 0, line_orientation=false and true
5797  {0, 1}}; // child 1, line_orientation=false and true
5798 
5799  // find some space (consecutive) for the two newly
5800  // to be created quads.
5801  typename Triangulation<dim, spacedim>::raw_quad_iterator
5802  new_quads[2];
5803 
5804  next_unused_quad =
5805  triangulation.faces->quads.next_free_pair_object(
5806  triangulation);
5807  new_quads[0] = next_unused_quad;
5808  Assert(
5809  new_quads[0]->used() == false,
5810  ExcMessage(
5811  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5812 
5813  ++next_unused_quad;
5814  new_quads[1] = next_unused_quad;
5815  Assert(
5816  new_quads[1]->used() == false,
5817  ExcMessage(
5818  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5819 
5820 
5821  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5822  {
5823  new_quads[0]->set(
5825  quad->line_index(0),
5826  new_line->index(),
5827  quad->line(2)
5828  ->child(index[0][quad->line_orientation(2)])
5829  ->index(),
5830  quad->line(3)
5831  ->child(index[0][quad->line_orientation(3)])
5832  ->index()));
5833  new_quads[1]->set(
5835  new_line->index(),
5836  quad->line_index(1),
5837  quad->line(2)
5838  ->child(index[1][quad->line_orientation(2)])
5839  ->index(),
5840  quad->line(3)
5841  ->child(index[1][quad->line_orientation(3)])
5842  ->index()));
5843  }
5844  else
5845  {
5846  new_quads[0]->set(
5848  quad->line(0)
5849  ->child(index[0][quad->line_orientation(0)])
5850  ->index(),
5851  quad->line(1)
5852  ->child(index[0][quad->line_orientation(1)])
5853  ->index(),
5854  quad->line_index(2),
5855  new_line->index()));
5856  new_quads[1]->set(
5858  quad->line(0)
5859  ->child(index[1][quad->line_orientation(0)])
5860  ->index(),
5861  quad->line(1)
5862  ->child(index[1][quad->line_orientation(1)])
5863  ->index(),
5864  new_line->index(),
5865  quad->line_index(3)));
5866  }
5867 
5868  for (unsigned int i = 0; i < 2; ++i)
5869  {
5870  new_quads[i]->set_used_flag();
5871  new_quads[i]->clear_user_flag();
5872  new_quads[i]->clear_user_data();
5873  new_quads[i]->clear_children();
5874  new_quads[i]->set_boundary_id_internal(
5875  quad->boundary_id());
5876  new_quads[i]->set_manifold_id(quad->manifold_id());
5877  // set all line orientations to true, change
5878  // this after the loop, as we have to consider
5879  // different lines for each child
5880  for (unsigned int j = 0;
5881  j < GeometryInfo<dim>::lines_per_face;
5882  ++j)
5883  new_quads[i]->set_line_orientation(j, true);
5884  }
5885  // now set the line orientation of children of
5886  // outer lines correctly, the lines in the
5887  // interior of the refined quad are automatically
5888  // oriented conforming to the standard
5889  new_quads[0]->set_line_orientation(
5890  0, quad->line_orientation(0));
5891  new_quads[0]->set_line_orientation(
5892  2, quad->line_orientation(2));
5893  new_quads[1]->set_line_orientation(
5894  1, quad->line_orientation(1));
5895  new_quads[1]->set_line_orientation(
5896  3, quad->line_orientation(3));
5897  if (aniso_quad_ref_case == RefinementCase<dim - 1>::cut_x)
5898  {
5899  new_quads[0]->set_line_orientation(
5900  3, quad->line_orientation(3));
5901  new_quads[1]->set_line_orientation(
5902  2, quad->line_orientation(2));
5903  }
5904  else
5905  {
5906  new_quads[0]->set_line_orientation(
5907  1, quad->line_orientation(1));
5908  new_quads[1]->set_line_orientation(
5909  0, quad->line_orientation(0));
5910  }
5911 
5912  // test, whether this face is refined
5913  // isotropically already. if so, set the correct
5914  // children pointers.
5915  if (quad->refinement_case() ==
5916  RefinementCase<dim - 1>::cut_xy)
5917  {
5918  // we will put a new refinemnt level of
5919  // anisotropic refinement between the
5920  // unrefined and isotropically refined quad
5921  // ending up with the same fine quads but
5922  // introducing anisotropically refined ones as
5923  // children of the unrefined quad and mother
5924  // cells of the original fine ones.
5925 
5926  // this process includes the creation of a new
5927  // middle line which we will assign as the
5928  // mother line of two of the existing inner
5929  // lines. If those inner lines are not
5930  // consecutive in memory, we won't find them
5931  // later on, so we have to create new ones
5932  // instead and replace all occurrences of the
5933  // old ones with those new ones. As this is
5934  // kind of ugly, we hope we don't have to do
5935  // it often...
5936  typename Triangulation<dim, spacedim>::line_iterator
5937  old_child[2];
5938  if (aniso_quad_ref_case ==
5940  {
5941  old_child[0] = quad->child(0)->line(1);
5942  old_child[1] = quad->child(2)->line(1);
5943  }
5944  else
5945  {
5946  Assert(aniso_quad_ref_case ==
5948  ExcInternalError());
5949 
5950  old_child[0] = quad->child(0)->line(3);
5951  old_child[1] = quad->child(1)->line(3);
5952  }
5953 
5954  if (old_child[0]->index() + 1 != old_child[1]->index())
5955  {
5956  // this is exactly the ugly case we taked
5957  // about. so, no coimplaining, lets get
5958  // two new lines and copy all info
5959  typename Triangulation<dim,
5960  spacedim>::raw_line_iterator
5961  new_child[2];
5962 
5963  new_child[0] = new_child[1] =
5964  triangulation.faces->lines.next_free_pair_object(
5965  triangulation);
5966  ++new_child[1];
5967 
5968  new_child[0]->set_used_flag();
5969  new_child[1]->set_used_flag();
5970 
5971  const int old_index_0 = old_child[0]->index(),
5972  old_index_1 = old_child[1]->index(),
5973  new_index_0 = new_child[0]->index(),
5974  new_index_1 = new_child[1]->index();
5975 
5976  // loop over all quads and replace the old
5977  // lines
5978  for (unsigned int q = 0;
5979  q < triangulation.faces->quads.cells.size();
5980  ++q)
5981  for (unsigned int l = 0;
5982  l < GeometryInfo<dim>::lines_per_face;
5983  ++l)
5984  {
5985  const int this_index =
5986  triangulation.faces->quads.cells[q].face(l);
5987  if (this_index == old_index_0)
5988  triangulation.faces->quads.cells[q]
5989  .set_face(l, new_index_0);
5990  else if (this_index == old_index_1)
5991  triangulation.faces->quads.cells[q]
5992  .set_face(l, new_index_1);
5993  }
5994  // now we have to copy all information of
5995  // the two lines
5996  for (unsigned int i = 0; i < 2; ++i)
5997  {
5998  Assert(!old_child[i]->has_children(),
5999  ExcInternalError());
6000 
6001  new_child[i]->set(
6003  TriaObject<1>(old_child[i]->vertex_index(0),
6004  old_child[i]->vertex_index(
6005  1)));
6006  new_child[i]->set_boundary_id_internal(
6007  old_child[i]->boundary_id());
6008  new_child[i]->set_manifold_id(
6009  old_child[i]->manifold_id());
6010  new_child[i]->set_user_index(
6011  old_child[i]->user_index());
6012  if (old_child[i]->user_flag_set())
6013  new_child[i]->set_user_flag();
6014  else
6015  new_child[i]->clear_user_flag();
6016 
6017  new_child[i]->clear_children();
6018 
6019  old_child[i]->clear_user_flag();
6020  old_child[i]->clear_user_index();
6021  old_child[i]->clear_used_flag();
6022  }
6023  }
6024  // now that we cared about the lines, go on
6025  // with the quads themselves, where we might
6026  // encounter similar situations...
6027  if (aniso_quad_ref_case ==
6029  {
6030  new_line->set_children(
6031  0, quad->child(0)->line_index(1));
6032  Assert(new_line->child(1) ==
6033  quad->child(2)->line(1),
6034  ExcInternalError());
6035  // now evereything is quite
6036  // complicated. we have the children
6037  // numbered according to
6038  //
6039  // *---*---*
6040  // |n+2|n+3|
6041  // *---*---*
6042  // | n |n+1|
6043  // *---*---*
6044  //
6045  // from the original isotropic
6046  // refinement. we have to reorder them as
6047  //
6048  // *---*---*
6049  // |n+1|n+3|
6050  // *---*---*
6051  // | n |n+2|
6052  // *---*---*
6053  //
6054  // such that n and n+1 are consecutive
6055  // children of m and n+2 and n+3 are
6056  // consecutive children of m+1, where m
6057  // and m+1 are given as in
6058  //
6059  // *---*---*
6060  // | | |
6061  // | m |m+1|
6062  // | | |
6063  // *---*---*
6064  //
6065  // this is a bit ugly, of course: loop
6066  // over all cells on all levels and look
6067  // for faces n+1 (switch_1) and n+2
6068  // (switch_2).
6069  const typename Triangulation<dim, spacedim>::
6070  quad_iterator switch_1 = quad->child(1),
6071  switch_2 = quad->child(2);
6072  const int switch_1_index = switch_1->index();
6073  const int switch_2_index = switch_2->index();
6074  for (unsigned int l = 0;
6075  l < triangulation.levels.size();
6076  ++l)
6077  for (unsigned int h = 0;
6078  h <
6079  triangulation.levels[l]->cells.cells.size();
6080  ++h)
6081  for (unsigned int q = 0;
6082  q < GeometryInfo<dim>::faces_per_cell;
6083  ++q)
6084  {
6085  const int face_index =
6086  triangulation.levels[l]
6087  ->cells.cells[h]
6088  .face(q);
6089  if (face_index == switch_1_index)
6090  triangulation.levels[l]
6091  ->cells.cells[h]
6092  .set_face(q, switch_2_index);
6093  else if (face_index == switch_2_index)
6094  triangulation.levels[l]
6095  ->cells.cells[h]
6096  .set_face(q, switch_1_index);
6097  }
6098  // now we have to copy all information of
6099  // the two quads
6100  const unsigned int switch_1_lines[4] = {
6101  switch_1->line_index(0),
6102  switch_1->line_index(1),
6103  switch_1->line_index(2),
6104  switch_1->line_index(3)};
6105  const bool switch_1_line_orientations[4] = {
6106  switch_1->line_orientation(0),
6107  switch_1->line_orientation(1),
6108  switch_1->line_orientation(2),
6109  switch_1->line_orientation(3)};
6110  const types::boundary_id switch_1_boundary_id =
6111  switch_1->boundary_id();
6112  const unsigned int switch_1_user_index =
6113  switch_1->user_index();
6114  const bool switch_1_user_flag =
6115  switch_1->user_flag_set();
6116  const RefinementCase<dim - 1>
6117  switch_1_refinement_case =
6118  switch_1->refinement_case();
6119  const int switch_1_first_child_pair =
6120  (switch_1_refinement_case ?
6121  switch_1->child_index(0) :
6122  -1);
6123  const int switch_1_second_child_pair =
6124  (switch_1_refinement_case ==
6125  RefinementCase<dim - 1>::cut_xy ?
6126  switch_1->child_index(2) :
6127  -1);
6128 
6129  switch_1->set(
6131  2>(switch_2->line_index(0),
6132  switch_2->line_index(1),
6133  switch_2->line_index(2),
6134  switch_2->line_index(3)));
6135  switch_1->set_line_orientation(
6136  0, switch_2->line_orientation(0));
6137  switch_1->set_line_orientation(
6138  1, switch_2->line_orientation(1));
6139  switch_1->set_line_orientation(
6140  2, switch_2->line_orientation(2));
6141  switch_1->set_line_orientation(
6142  3, switch_2->line_orientation(3));
6143  switch_1->set_boundary_id_internal(
6144  switch_2->boundary_id());
6145  switch_1->set_manifold_id(switch_2->manifold_id());
6146  switch_1->set_user_index(switch_2->user_index());
6147  if (switch_2->user_flag_set())
6148  switch_1->set_user_flag();
6149  else
6150  switch_1->clear_user_flag();
6151  switch_1->clear_refinement_case();
6152  switch_1->set_refinement_case(
6153  switch_2->refinement_case());
6154  switch_1->clear_children();
6155  if (switch_2->refinement_case())
6156  switch_1->set_children(0,
6157  switch_2->child_index(0));
6158  if (switch_2->refinement_case() ==
6159  RefinementCase<dim - 1>::cut_xy)
6160  switch_1->set_children(2,
6161  switch_2->child_index(2));
6162 
6163  switch_2->set(
6165  2>(switch_1_lines[0],
6166  switch_1_lines[1],
6167  switch_1_lines[2],
6168  switch_1_lines[3]));
6169  switch_2->set_line_orientation(
6170  0, switch_1_line_orientations[0]);
6171  switch_2->set_line_orientation(
6172  1, switch_1_line_orientations[1]);
6173  switch_2->set_line_orientation(
6174  2, switch_1_line_orientations[2]);
6175  switch_2->set_line_orientation(
6176  3, switch_1_line_orientations[3]);
6177  switch_2->set_boundary_id_internal(
6178  switch_1_boundary_id);
6179  switch_2->set_manifold_id(switch_1->manifold_id());
6180  switch_2->set_user_index(switch_1_user_index);
6181  if (switch_1_user_flag)
6182  switch_2->set_user_flag();
6183  else
6184  switch_2->clear_user_flag();
6185  switch_2->clear_refinement_case();
6186  switch_2->set_refinement_case(
6187  switch_1_refinement_case);
6188  switch_2->clear_children();
6189  switch_2->set_children(0,
6190  switch_1_first_child_pair);
6191  switch_2->set_children(2,
6192  switch_1_second_child_pair);
6193 
6194  new_quads[0]->set_refinement_case(
6196  new_quads[0]->set_children(0, quad->child_index(0));
6197  new_quads[1]->set_refinement_case(
6199  new_quads[1]->set_children(0, quad->child_index(2));
6200  }
6201  else
6202  {
6203  new_quads[0]->set_refinement_case(
6205  new_quads[0]->set_children(0, quad->child_index(0));
6206  new_quads[1]->set_refinement_case(
6208  new_quads[1]->set_children(0, quad->child_index(2));
6209  new_line->set_children(
6210  0, quad->child(0)->line_index(3));
6211  Assert(new_line->child(1) ==
6212  quad->child(1)->line(3),
6213  ExcInternalError());
6214  }
6215  quad->clear_children();
6216  }
6217 
6218  // note these quads as children to the present one
6219  quad->set_children(0, new_quads[0]->index());
6220 
6221  quad->set_refinement_case(aniso_quad_ref_case);
6222 
6223  // finally clear flag indicating the need for
6224  // refinement
6225  quad->clear_user_data();
6226  } // if (anisotropic refinement)
6227 
6228  if (quad->user_flag_set())
6229  {
6230  // this quad needs to be refined isotropically
6231 
6232  // first of all: we only get here in the first run
6233  // of the loop
6234  Assert(loop == 0, ExcInternalError());
6235 
6236  // find the next unused vertex. we'll need this in
6237  // any case
6238  while (triangulation.vertices_used[next_unused_vertex] ==
6239  true)
6240  ++next_unused_vertex;
6241  Assert(
6242  next_unused_vertex < triangulation.vertices.size(),
6243  ExcMessage(
6244  "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."));
6245 
6246  // now: if the quad is refined anisotropically
6247  // already, set the anisotropic refinement flag
6248  // for both children. Additionally, we have to
6249  // refine the inner line, as it is an outer line
6250  // of the two (anisotropic) children
6251  const RefinementCase<dim - 1> quad_ref_case =
6252  quad->refinement_case();
6253 
6254  if (quad_ref_case == RefinementCase<dim - 1>::cut_x ||
6255  quad_ref_case == RefinementCase<dim - 1>::cut_y)
6256  {
6257  // set the 'opposite' refine case for children
6258  quad->child(0)->set_user_index(
6259  RefinementCase<dim - 1>::cut_xy - quad_ref_case);
6260  quad->child(1)->set_user_index(
6261  RefinementCase<dim - 1>::cut_xy - quad_ref_case);
6262  // refine the inner line
6263  typename Triangulation<dim, spacedim>::line_iterator
6264  middle_line;
6265  if (quad_ref_case == RefinementCase<dim - 1>::cut_x)
6266  middle_line = quad->child(0)->line(1);
6267  else
6268  middle_line = quad->child(0)->line(3);
6269 
6270  // if the face has been refined
6271  // anisotropically in the last refinement step
6272  // it might be, that it is flagged already and
6273  // that the middle line is thus refined
6274  // already. if not create children.
6275  if (!middle_line->has_children())
6276  {
6277  // set the middle vertex
6278  // appropriately. double refinement of
6279  // quads can only happen in the interior
6280  // of the domain, so we need not care
6281  // about boundary quads here
6282  triangulation.vertices[next_unused_vertex] =
6283  middle_line->center(true);
6284  triangulation.vertices_used[next_unused_vertex] =
6285  true;
6286 
6287  // now search a slot for the two
6288  // child lines
6289  next_unused_line =
6290  triangulation.faces->lines.next_free_pair_object(
6291  triangulation);
6292 
6293  // set the child pointer of the present
6294  // line
6295  middle_line->set_children(
6296  0, next_unused_line->index());
6297 
6298  // set the two new lines
6299  const typename Triangulation<dim, spacedim>::
6300  raw_line_iterator children[2] = {
6301  next_unused_line, ++next_unused_line};
6302 
6303  // some tests; if any of the iterators
6304  // should be invalid, then already
6305  // dereferencing will fail
6306  Assert(
6307  children[0]->used() == false,
6308  ExcMessage(
6309  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6310  Assert(
6311  children[1]->used() == false,
6312  ExcMessage(
6313  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6314 
6315  children[0]->set(
6317  1>(middle_line->vertex_index(0),
6318  next_unused_vertex));
6319  children[1]->set(
6321  1>(next_unused_vertex,
6322  middle_line->vertex_index(1)));
6323 
6324  children[0]->set_used_flag();
6325  children[1]->set_used_flag();
6326  children[0]->clear_children();
6327  children[1]->clear_children();
6328  children[0]->clear_user_data();
6329  children[1]->clear_user_data();
6330  children[0]->clear_user_flag();
6331  children[1]->clear_user_flag();
6332 
6333  children[0]->set_boundary_id_internal(
6334  middle_line->boundary_id());
6335  children[1]->set_boundary_id_internal(
6336  middle_line->boundary_id());
6337 
6338  children[0]->set_manifold_id(
6339  middle_line->manifold_id());
6340  children[1]->set_manifold_id(
6341  middle_line->manifold_id());
6342  }
6343  // now remove the flag from the quad and go to
6344  // the next quad, the actual refinement of the
6345  // quad takes place later on in this pass of
6346  // the loop or in the next one
6347  quad->clear_user_flag();
6348  continue;
6349  } // if (several refinement cases)
6350 
6351  // if we got here, we have an unrefined quad and
6352  // have to do the usual work like in an purely
6353  // isotropic refinement
6354  Assert(quad_ref_case ==
6356  ExcInternalError());
6357 
6358  // set the middle vertex appropriately: it might be that
6359  // the quad itself is not at the boundary, but that one of
6360  // its lines actually is. in this case, the newly created
6361  // vertices at the centers of the lines are not
6362  // necessarily the mean values of the adjacent vertices,
6363  // so do not compute the new vertex as the mean value of
6364  // the 4 vertices of the face, but rather as a weighted
6365  // mean value of the 8 vertices which we already have (the
6366  // four old ones, and the four ones inserted as middle
6367  // points for the four lines). summing up some more points
6368  // is generally cheaper than first asking whether one of
6369  // the lines is at the boundary
6370  //
6371  // note that the exact weights are chosen such as to
6372  // minimize the distortion of the four new quads from the
6373  // optimal shape. their description uses the formulas
6374  // underlying the TransfiniteInterpolationManifold
6375  // implementation
6376  triangulation.vertices[next_unused_vertex] =
6377  quad->center(true, true);
6378  triangulation.vertices_used[next_unused_vertex] = true;
6379 
6380  // now that we created the right point, make up
6381  // the four lines interior to the quad (++ takes
6382  // care of the end of the vector)
6383  typename Triangulation<dim, spacedim>::raw_line_iterator
6384  new_lines[4];
6385 
6386  for (unsigned int i = 0; i < 4; ++i)
6387  {
6388  if (i % 2 == 0)
6389  // search a free pair of lines for 0. and
6390  // 2. line, so that two of them end up
6391  // together, which is necessary if later on
6392  // we want to refine the quad
6393  // anisotropically and the two lines end up
6394  // as children of new line
6395  next_unused_line =
6396  triangulation.faces->lines.next_free_pair_object(
6397  triangulation);
6398 
6399  new_lines[i] = next_unused_line;
6400  ++next_unused_line;
6401 
6402  Assert(
6403  new_lines[i]->used() == false,
6404  ExcMessage(
6405  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6406  }
6407 
6408  // set the data of the four lines. first collect
6409  // the indices of the five vertices:
6410  //
6411  // *--3--*
6412  // | | |
6413  // 0--4--1
6414  // | | |
6415  // *--2--*
6416  //
6417  // the lines are numbered as follows:
6418  //
6419  // *--*--*
6420  // | 1 |
6421  // *2-*-3*
6422  // | 0 |
6423  // *--*--*
6424 
6425  const unsigned int vertex_indices[5] = {
6426  quad->line(0)->child(0)->vertex_index(1),
6427  quad->line(1)->child(0)->vertex_index(1),
6428  quad->line(2)->child(0)->vertex_index(1),
6429  quad->line(3)->child(0)->vertex_index(1),
6430  next_unused_vertex};
6431 
6432  new_lines[0]->set(
6434  vertex_indices[2], vertex_indices[4]));
6435  new_lines[1]->set(
6437  vertex_indices[4], vertex_indices[3]));
6438  new_lines[2]->set(
6440  vertex_indices[0], vertex_indices[4]));
6441  new_lines[3]->set(
6443  vertex_indices[4], vertex_indices[1]));
6444 
6445  for (unsigned int i = 0; i < 4; ++i)
6446  {
6447  new_lines[i]->set_used_flag();
6448  new_lines[i]->clear_user_flag();
6449  new_lines[i]->clear_user_data();
6450  new_lines[i]->clear_children();
6451  new_lines[i]->set_boundary_id_internal(
6452  quad->boundary_id());
6453  new_lines[i]->set_manifold_id(quad->manifold_id());
6454  }
6455 
6456  // now for the quads. again, first collect some
6457  // data about the indices of the lines, with the
6458  // following numbering:
6459  //
6460  // .-6-.-7-.
6461  // 1 9 3
6462  // .-10.11-.
6463  // 0 8 2
6464  // .-4-.-5-.
6465 
6466  // child 0 and 1 of a line are switched if the
6467  // line orientation is false. set up a miniature
6468  // table, indicating which child to take for line
6469  // orientations false and true. first index: child
6470  // index in standard orientation, second index:
6471  // line orientation
6472  const unsigned int index[2][2] = {
6473  {1, 0}, // child 0, line_orientation=false and true
6474  {0, 1}}; // child 1, line_orientation=false and true
6475 
6476  const int line_indices[12] = {
6477  quad->line(0)
6478  ->child(index[0][quad->line_orientation(0)])
6479  ->index(),
6480  quad->line(0)
6481  ->child(index[1][quad->line_orientation(0)])
6482  ->index(),
6483  quad->line(1)
6484  ->child(index[0][quad->line_orientation(1)])
6485  ->index(),
6486  quad->line(1)
6487  ->child(index[1][quad->line_orientation(1)])
6488  ->index(),
6489  quad->line(2)
6490  ->child(index[0][quad->line_orientation(2)])
6491  ->index(),
6492  quad->line(2)
6493  ->child(index[1][quad->line_orientation(2)])
6494  ->index(),
6495  quad->line(3)
6496  ->child(index[0][quad->line_orientation(3)])
6497  ->index(),
6498  quad->line(3)
6499  ->child(index[1][quad->line_orientation(3)])
6500  ->index(),
6501  new_lines[0]->index(),
6502  new_lines[1]->index(),
6503  new_lines[2]->index(),
6504  new_lines[3]->index()};
6505 
6506  // find some space (consecutive)
6507  // for the first two newly to be
6508  // created quads.
6509  typename Triangulation<dim, spacedim>::raw_quad_iterator
6510  new_quads[4];
6511 
6512  next_unused_quad =
6513  triangulation.faces->quads.next_free_pair_object(
6514  triangulation);
6515 
6516  new_quads[0] = next_unused_quad;
6517  Assert(
6518  new_quads[0]->used() == false,
6519  ExcMessage(
6520  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6521 
6522  ++next_unused_quad;
6523  new_quads[1] = next_unused_quad;
6524  Assert(
6525  new_quads[1]->used() == false,
6526  ExcMessage(
6527  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6528 
6529  next_unused_quad =
6530  triangulation.faces->quads.next_free_pair_object(
6531  triangulation);
6532  new_quads[2] = next_unused_quad;
6533  Assert(
6534  new_quads[2]->used() == false,
6535  ExcMessage(
6536  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6537 
6538  ++next_unused_quad;
6539  new_quads[3] = next_unused_quad;
6540  Assert(
6541  new_quads[3]->used() == false,
6542  ExcMessage(
6543  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6544 
6545  // note these quads as children to the present one
6546  quad->set_children(0, new_quads[0]->index());
6547  quad->set_children(2, new_quads[2]->index());
6548  new_quads[0]->set(
6550  line_indices[0],
6551  line_indices[8],
6552  line_indices[4],
6553  line_indices[10]));
6554 
6555  quad->set_refinement_case(RefinementCase<2>::cut_xy);
6556 
6557  new_quads[0]->set(
6559  line_indices[0],
6560  line_indices[8],
6561  line_indices[4],
6562  line_indices[10]));
6563  new_quads[1]->set(
6565  line_indices[8],
6566  line_indices[2],
6567  line_indices[5],
6568  line_indices[11]));
6569  new_quads[2]->set(
6571  line_indices[1],
6572  line_indices[9],
6573  line_indices[10],
6574  line_indices[6]));
6575  new_quads[3]->set(
6577  line_indices[9],
6578  line_indices[3],
6579  line_indices[11],
6580  line_indices[7]));
6581  for (unsigned int i = 0; i < 4; ++i)
6582  {
6583  new_quads[i]->set_used_flag();
6584  new_quads[i]->clear_user_flag();
6585  new_quads[i]->clear_user_data();
6586  new_quads[i]->clear_children();
6587  new_quads[i]->set_boundary_id_internal(
6588  quad->boundary_id());
6589  new_quads[i]->set_manifold_id(quad->manifold_id());
6590  // set all line orientations to true, change
6591  // this after the loop, as we have to consider
6592  // different lines for each child
6593  for (unsigned int j = 0;
6594  j < GeometryInfo<dim>::lines_per_face;
6595  ++j)
6596  new_quads[i]->set_line_orientation(j, true);
6597  }
6598  // now set the line orientation of children of
6599  // outer lines correctly, the lines in the
6600  // interior of the refined quad are automatically
6601  // oriented conforming to the standard
6602  new_quads[0]->set_line_orientation(
6603  0, quad->line_orientation(0));
6604  new_quads[0]->set_line_orientation(
6605  2, quad->line_orientation(2));
6606  new_quads[1]->set_line_orientation(
6607  1, quad->line_orientation(1));
6608  new_quads[1]->set_line_orientation(
6609  2, quad->line_orientation(2));
6610  new_quads[2]->set_line_orientation(
6611  0, quad->line_orientation(0));
6612  new_quads[2]->set_line_orientation(
6613  3, quad->line_orientation(3));
6614  new_quads[3]->set_line_orientation(
6615  1, quad->line_orientation(1));
6616  new_quads[3]->set_line_orientation(
6617  3, quad->line_orientation(3));
6618 
6619  // finally clear flag indicating the need for
6620  // refinement
6621  quad->clear_user_flag();
6622  } // if (isotropic refinement)
6623  } // for all quads
6624  } // looped two times over all quads, all quads refined now
6625 
6627  // Now, finally, set up the new
6628  // cells
6630 
6632  cells_with_distorted_children;
6633 
6634  for (unsigned int level = 0; level != triangulation.levels.size() - 1;
6635  ++level)
6636  {
6637  // only active objects can be refined further; remember
6638  // that we won't operate on the finest level, so
6639  // triangulation.begin_*(level+1) is allowed
6640  typename Triangulation<dim, spacedim>::active_hex_iterator
6641  hex = triangulation.begin_active_hex(level),
6642  endh = triangulation.begin_active_hex(level + 1);
6643  typename Triangulation<dim, spacedim>::raw_hex_iterator
6644  next_unused_hex = triangulation.begin_raw_hex(level + 1);
6645 
6646  for (; hex != endh; ++hex)
6647  if (hex->refine_flag_set())
6648  {
6649  // this hex needs to be refined
6650 
6651  // clear flag indicating the need for refinement. do
6652  // it here already, since we can't do it anymore
6653  // once the cell has children
6654  const RefinementCase<dim> ref_case = hex->refine_flag_set();
6655  hex->clear_refine_flag();
6656  hex->set_refinement_case(ref_case);
6657 
6658  // depending on the refine case we might have to
6659  // create additional vertices, lines and quads
6660  // interior of the hex before the actual children
6661  // can be set up.
6662 
6663  // in a first step: reserve the needed space for
6664  // lines, quads and hexes and initialize them
6665  // correctly
6666 
6667  unsigned int n_new_lines = 0;
6668  unsigned int n_new_quads = 0;
6669  unsigned int n_new_hexes = 0;
6670  switch (ref_case)
6671  {
6675  n_new_lines = 0;
6676  n_new_quads = 1;
6677  n_new_hexes = 2;
6678  break;
6682  n_new_lines = 1;
6683  n_new_quads = 4;
6684  n_new_hexes = 4;
6685  break;
6687  n_new_lines = 6;
6688  n_new_quads = 12;
6689  n_new_hexes = 8;
6690  break;
6691  default:
6692  Assert(false, ExcInternalError());
6693  break;
6694  }
6695 
6696  // find some space for the newly to be created
6697  // interior lines and initialize them.
6698  std::vector<
6699  typename Triangulation<dim, spacedim>::raw_line_iterator>
6700  new_lines(n_new_lines);
6701  for (unsigned int i = 0; i < n_new_lines; ++i)
6702  {
6703  new_lines[i] =
6704  triangulation.faces->lines.next_free_single_object(
6705  triangulation);
6706 
6707  Assert(
6708  new_lines[i]->used() == false,
6709  ExcMessage(
6710  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6711  new_lines[i]->set_used_flag();
6712  new_lines[i]->clear_user_flag();
6713  new_lines[i]->clear_user_data();
6714  new_lines[i]->clear_children();
6715  // interior line
6716  new_lines[i]->set_boundary_id_internal(
6718  // they inherit geometry description of the hex they
6719  // belong to
6720  new_lines[i]->set_manifold_id(hex->manifold_id());
6721  }
6722 
6723  // find some space for the newly to be created
6724  // interior quads and initialize them.
6725  std::vector<
6726  typename Triangulation<dim, spacedim>::raw_quad_iterator>
6727  new_quads(n_new_quads);
6728  for (unsigned int i = 0; i < n_new_quads; ++i)
6729  {
6730  new_quads[i] =
6731  triangulation.faces->quads.next_free_single_object(
6732  triangulation);
6733 
6734  Assert(
6735  new_quads[i]->used() == false,
6736  ExcMessage(
6737  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6738  new_quads[i]->set_used_flag();
6739  new_quads[i]->clear_user_flag();
6740  new_quads[i]->clear_user_data();
6741  new_quads[i]->clear_children();
6742  // interior quad
6743  new_quads[i]->set_boundary_id_internal(
6745  // they inherit geometry description of the hex they
6746  // belong to
6747  new_quads[i]->set_manifold_id(hex->manifold_id());
6748  // set all line orientation flags to true by
6749  // default, change this afterwards, if necessary
6750  for (unsigned int j = 0;
6751  j < GeometryInfo<dim>::lines_per_face;
6752  ++j)
6753  new_quads[i]->set_line_orientation(j, true);
6754  }
6755 
6756  types::subdomain_id subdomainid = hex->subdomain_id();
6757 
6758  // find some space for the newly to be created hexes
6759  // and initialize them.
6760  std::vector<
6761  typename Triangulation<dim, spacedim>::raw_hex_iterator>
6762  new_hexes(n_new_hexes);
6763  for (unsigned int i = 0; i < n_new_hexes; ++i)
6764  {
6765  if (i % 2 == 0)
6766  next_unused_hex =
6767  triangulation.levels[level + 1]->cells.next_free_hex(
6768  triangulation, level + 1);
6769  else
6770  ++next_unused_hex;
6771 
6772  new_hexes[i] = next_unused_hex;
6773 
6774  Assert(
6775  new_hexes[i]->used() == false,
6776  ExcMessage(
6777  "Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6778  new_hexes[i]->set_used_flag();
6779  new_hexes[i]->clear_user_flag();
6780  new_hexes[i]->clear_user_data();
6781  new_hexes[i]->clear_children();
6782  // inherit material
6783  // properties
6784  new_hexes[i]->set_material_id(hex->material_id());
6785  new_hexes[i]->set_manifold_id(hex->manifold_id());
6786  new_hexes[i]->set_subdomain_id(subdomainid);
6787 
6788  if (i % 2)
6789  new_hexes[i]->set_parent(hex->index());
6790  // set the face_orientation flag to true for all
6791  // faces initially, as this is the default value
6792  // which is true for all faces interior to the
6793  // hex. later on go the other way round and
6794  // reset faces that are at the boundary of the
6795  // mother cube
6796  //
6797  // the same is true for the face_flip and
6798  // face_rotation flags. however, the latter two
6799  // are set to false by default as this is the
6800  // standard value
6801  for (unsigned int f = 0;
6802  f < GeometryInfo<dim>::faces_per_cell;
6803  ++f)
6804  {
6805  new_hexes[i]->set_face_orientation(f, true);
6806  new_hexes[i]->set_face_flip(f, false);
6807  new_hexes[i]->set_face_rotation(f, false);
6808  }
6809  }
6810  // note these hexes as children to the present cell
6811  for (unsigned int i = 0; i < n_new_hexes / 2; ++i)
6812  hex->set_children(2 * i, new_hexes[2 * i]->index());
6813 
6814  // we have to take into account whether the
6815  // different faces are oriented correctly or in the
6816  // opposite direction, so store that up front
6817 
6818  // face_orientation
6819  const bool f_or[6] = {hex->face_orientation(0),
6820  hex->face_orientation(1),
6821  hex->face_orientation(2),
6822  hex->face_orientation(3),
6823  hex->face_orientation(4),
6824  hex->face_orientation(5)};
6825 
6826  // face_flip
6827  const bool f_fl[6] = {hex->face_flip(0),
6828  hex->face_flip(1),
6829  hex->face_flip(2),
6830  hex->face_flip(3),
6831  hex->face_flip(4),
6832  hex->face_flip(5)};
6833 
6834  // face_rotation
6835  const bool f_ro[6] = {hex->face_rotation(0),
6836  hex->face_rotation(1),
6837  hex->face_rotation(2),
6838  hex->face_rotation(3),
6839  hex->face_rotation(4),
6840  hex->face_rotation(5)};
6841 
6842  // little helper table, indicating, whether the
6843  // child with index 0 or with index 1 can be found
6844  // at the standard origin of an anisotropically
6845  // refined quads in real orientation index 1:
6846  // (RefineCase - 1) index 2: face_flip
6847 
6848  // index 3: face rotation
6849  // note: face orientation has no influence
6850  const unsigned int child_at_origin[2][2][2] = {
6851  {{0, 0}, // RefinementCase<dim>::cut_x, face_flip=false,
6852  // face_rotation=false and true
6853  {1, 1}}, // RefinementCase<dim>::cut_x, face_flip=true,
6854  // face_rotation=false and true
6855  {{0, 1}, // RefinementCase<dim>::cut_y, face_flip=false,
6856  // face_rotation=false and true
6857  {1, 0}}}; // RefinementCase<dim>::cut_y, face_flip=true,
6858  // face_rotation=false and true
6859 
6861  //
6862  // in the following we will do the same thing for
6863  // each refinement case: create a new vertex (if
6864  // needed), create new interior lines (if needed),
6865  // create new interior quads and afterwards build
6866  // the children hexes out of these and the existing
6867  // subfaces of the outer quads (which have been
6868  // created above). However, even if the steps are
6869  // quite similar, the actual work strongly depends
6870  // on the actual refinement case. therefore, we use
6871  // separate blocks of code for each of these cases,
6872  // which hopefully increases the readability to some
6873  // extend.
6874 
6875  switch (ref_case)
6876  {
6878  {
6880  //
6881  // RefinementCase<dim>::cut_x
6882  //
6883  // the refined cube will look
6884  // like this:
6885  //
6886  // *----*----*
6887  // / / /|
6888  // / / / |
6889  // / / / |
6890  // *----*----* |
6891  // | | | |
6892  // | | | *
6893  // | | | /
6894  // | | | /
6895  // | | |/
6896  // *----*----*
6897  //
6898  // again, first collect some data about the
6899  // indices of the lines, with the following
6900  // numbering:
6901 
6902  // face 2: front plane
6903  // (note: x,y exchanged)
6904  // *---*---*
6905  // | | |
6906  // | 0 |
6907  // | | |
6908  // *---*---*
6909  // m0
6910  // face 3: back plane
6911  // (note: x,y exchanged)
6912  // m1
6913  // *---*---*
6914  // | | |
6915  // | 1 |
6916  // | | |
6917  // *---*---*
6918  // face 4: bottom plane
6919  // *---*---*
6920  // / / /
6921  // / 2 /
6922  // / / /
6923  // *---*---*
6924  // m0
6925  // face 5: top plane
6926  // m1
6927  // *---*---*
6928  // / / /
6929  // / 3 /
6930  // / / /
6931  // *---*---*
6932 
6933  // set up a list of line iterators first. from
6934  // this, construct lists of line_indices and
6935  // line orientations later on
6936  const typename Triangulation<dim, spacedim>::
6937  raw_line_iterator lines[4] = {
6938  hex->face(2)->child(0)->line(
6939  (hex->face(2)->refinement_case() ==
6941  1 :
6942  3), // 0
6943  hex->face(3)->child(0)->line(
6944  (hex->face(3)->refinement_case() ==
6946  1 :
6947  3), // 1
6948  hex->face(4)->child(0)->line(
6949  (hex->face(4)->refinement_case() ==
6951  1 :
6952  3), // 2
6953  hex->face(5)->child(0)->line(
6954  (hex->face(5)->refinement_case() ==
6956  1 :
6957  3) // 3
6958  };
6959 
6960  unsigned int line_indices[4];
6961  for (unsigned int i = 0; i < 4; ++i)
6962  line_indices[i] = lines[i]->index();
6963 
6964  // the orientation of lines for the inner quads
6965  // is quite tricky. as these lines are newly
6966  // created ones and thus have no parents, they
6967  // cannot inherit this property. set up an array
6968  // and fill it with the respective values
6969  bool line_orientation[4];
6970 
6971  // the middle vertice marked as m0 above is the
6972  // start vertex for lines 0 and 2 in standard
6973  // orientation, whereas m1 is the end vertex of
6974  // lines 1 and 3 in standard orientation
6975  const unsigned int middle_vertices[2] = {
6976  hex->line(2)->child(0)->vertex_index(1),
6977  hex->line(7)->child(0)->vertex_index(1)};
6978 
6979  for (unsigned int i = 0; i < 4; ++i)
6980  if (lines[i]->vertex_index(i % 2) ==
6981  middle_vertices[i % 2])
6982  line_orientation[i] = true;
6983  else
6984  {
6985  // it must be the other
6986  // way round then
6987  Assert(lines[i]->vertex_index((i + 1) % 2) ==
6988  middle_vertices[i % 2],
6989  ExcInternalError());
6990  line_orientation[i] = false;
6991  }
6992 
6993  // set up the new quad, line numbering is as
6994  // indicated above
6995  new_quads[0]->set(
6997  2>(line_indices[0],
6998  line_indices[1],
6999  line_indices[2],
7000  line_indices[3]));
7001 
7002  new_quads[0]->set_line_orientation(
7003  0, line_orientation[0]);
7004  new_quads[0]->set_line_orientation(
7005  1, line_orientation[1]);
7006  new_quads[0]->set_line_orientation(
7007  2, line_orientation[2]);
7008  new_quads[0]->set_line_orientation(
7009  3, line_orientation[3]);
7010 
7011  // the quads are numbered as follows:
7012  //
7013  // planes in the interior of the old hex:
7014  //
7015  // *
7016  // /|
7017  // / | x
7018  // / | *-------* *---------*
7019  // * | | | / /
7020  // | 0 | | | / /
7021  // | * | | / /
7022  // | / *-------*y *---------*x
7023  // | /
7024  // |/
7025  // *
7026  //
7027  // children of the faces of the old hex
7028  //
7029  // *---*---* *---*---*
7030  // /| | | / / /|
7031  // / | | | / 9 / 10/ |
7032  // / | 5 | 6 | / / / |
7033  // * | | | *---*---* |
7034  // | 1 *---*---* | | | 2 *
7035  // | / / / | | | /
7036  // | / 7 / 8 / | 3 | 4 | /
7037  // |/ / / | | |/
7038  // *---*---* *---*---*
7039  //
7040  // note that we have to take care of the
7041  // orientation of faces.
7042  const int quad_indices[11] = {
7043  new_quads[0]->index(), // 0
7044 
7045  hex->face(0)->index(), // 1
7046 
7047  hex->face(1)->index(), // 2
7048 
7049  hex->face(2)->child_index(
7050  child_at_origin[hex->face(2)->refinement_case() -
7051  1][f_fl[2]][f_ro[2]]), // 3
7052  hex->face(2)->child_index(
7053  1 -
7054  child_at_origin[hex->face(2)->refinement_case() -
7055  1][f_fl[2]][f_ro[2]]),
7056 
7057  hex->face(3)->child_index(
7058  child_at_origin[hex->face(3)->refinement_case() -
7059  1][f_fl[3]][f_ro[3]]), // 5
7060  hex->face(3)->child_index(
7061  1 -
7062  child_at_origin[hex->face(3)->refinement_case() -
7063  1][f_fl[3]][f_ro[3]]),
7064 
7065  hex->face(4)->child_index(
7066  child_at_origin[hex->face(4)->refinement_case() -
7067  1][f_fl[4]][f_ro[4]]), // 7
7068  hex->face(4)->child_index(
7069  1 -
7070  child_at_origin[hex->face(4)->refinement_case() -
7071  1][f_fl[4]][f_ro[4]]),
7072 
7073  hex->face(5)->child_index(
7074  child_at_origin[hex->face(5)->refinement_case() -
7075  1][f_fl[5]][f_ro[5]]), // 9
7076  hex->face(5)->child_index(
7077  1 -
7078  child_at_origin[hex->face(5)->refinement_case() -
7079  1][f_fl[5]][f_ro[5]])
7080 
7081  };
7082 
7083  new_hexes[0]->set(
7085  3>(quad_indices[1],
7086  quad_indices[0],
7087  quad_indices[3],
7088  quad_indices[5],
7089  quad_indices[7],
7090  quad_indices[9]));
7091  new_hexes[1]->set(
7093  3>(quad_indices[0],
7094  quad_indices[2],
7095  quad_indices[4],
7096  quad_indices[6],
7097  quad_indices[8],
7098  quad_indices[10]));
7099  break;
7100  }
7101 
7103  {
7105  //
7106  // RefinementCase<dim>::cut_y
7107  //
7108  // the refined cube will look like this:
7109  //
7110  // *---------*
7111  // / /|
7112  // *---------* |
7113  // / /| |
7114  // *---------* | |
7115  // | | | |
7116  // | | | *
7117  // | | |/
7118  // | | *
7119  // | |/
7120  // *---------*
7121  //
7122  // again, first collect some data about the
7123  // indices of the lines, with the following
7124  // numbering:
7125 
7126  // face 0: left plane
7127  // *
7128  // /|
7129  // * |
7130  // /| |
7131  // * | |
7132  // | 0 |
7133  // | | *
7134  // | |/
7135  // | *m0
7136  // |/
7137  // *
7138  // face 1: right plane
7139  // *
7140  // /|
7141  // m1* |
7142  // /| |
7143  // * | |
7144  // | 1 |
7145  // | | *
7146  // | |/
7147  // | *
7148  // |/
7149  // *
7150  // face 4: bottom plane
7151  // *-------*
7152  // / /
7153  // m0*---2---*
7154  // / /
7155  // *-------*
7156  // face 5: top plane
7157  // *-------*
7158  // / /
7159  // *---3---*m1
7160  // / /
7161  // *-------*
7162 
7163  // set up a list of line iterators first. from
7164  // this, construct lists of line_indices and
7165  // line orientations later on
7166  const typename Triangulation<dim, spacedim>::
7167  raw_line_iterator lines[4] = {
7168  hex->face(0)->child(0)->line(
7169  (hex->face(0)->refinement_case() ==
7171  1 :
7172  3), // 0
7173  hex->face(1)->child(0)->line(
7174  (hex->face(1)->refinement_case() ==
7176  1 :
7177  3), // 1
7178  hex->face(4)->child(0)->line(
7179  (hex->face(4)->refinement_case() ==
7181  1 :
7182  3), // 2
7183  hex->face(5)->child(0)->line(
7184  (hex->face(5)->refinement_case() ==
7186  1 :
7187  3) // 3
7188  };
7189 
7190  unsigned int line_indices[4];
7191  for (unsigned int i = 0; i < 4; ++i)
7192  line_indices[i] = lines[i]->index();
7193 
7194  // the orientation of lines for the inner quads
7195  // is quite tricky. as these lines are newly
7196  // created ones and thus have no parents, they
7197  // cannot inherit this property. set up an array
7198  // and fill it with the respective values
7199  bool line_orientation[4];
7200 
7201  // the middle vertice marked as m0 above is the
7202  // start vertex for lines 0 and 2 in standard
7203  // orientation, whereas m1 is the end vertex of
7204  // lines 1 and 3 in standard orientation
7205  const unsigned int middle_vertices[2] = {
7206  hex->line(0)->child(0)->vertex_index(1),
7207  hex->line(5)->child(0)->vertex_index(1)};
7208 
7209  for (unsigned int i = 0; i < 4; ++i)
7210  if (lines[i]->vertex_index(i % 2) ==
7211  middle_vertices[i % 2])
7212  line_orientation[i] = true;
7213  else
7214  {
7215  // it must be the other way round then
7216  Assert(lines[i]->vertex_index((i + 1) % 2) ==
7217  middle_vertices[i % 2],
7218  ExcInternalError());
7219  line_orientation[i] = false;
7220  }
7221 
7222  // set up the new quad, line numbering is as
7223  // indicated above
7224  new_quads[0]->set(
7226  2>(line_indices[2],
7227  line_indices[3],
7228  line_indices[0],
7229  line_indices[1]));
7230 
7231  new_quads[0]->set_line_orientation(
7232  0, line_orientation[2]);
7233  new_quads[0]->set_line_orientation(
7234  1, line_orientation[3]);
7235  new_quads[0]->set_line_orientation(
7236  2, line_orientation[0]);
7237  new_quads[0]->set_line_orientation(
7238  3, line_orientation[1]);
7239 
7240  // the quads are numbered as follows:
7241  //
7242  // planes in the interior of the old hex:
7243  //
7244  // *
7245  // /|
7246  // / | x
7247  // / | *-------* *---------*
7248  // * | | | / /
7249  // | | | 0 | / /
7250  // | * | | / /
7251  // | / *-------*y *---------*x
7252  // | /
7253  // |/
7254  // *
7255  //
7256  // children of the faces of the old hex
7257  //
7258  // *-------* *-------*
7259  // /| | / 10 /|
7260  // * | | *-------* |
7261  // /| | 6 | / 9 /| |
7262  // * |2| | *-------* |4|
7263  // | | *-------* | | | *
7264  // |1|/ 8 / | |3|/
7265  // | *-------* | 5 | *
7266  // |/ 7 / | |/
7267  // *-------* *-------*
7268  //
7269  // note that we have to take care of the
7270  // orientation of faces.
7271  const int quad_indices[11] = {
7272  new_quads[0]->index(), // 0
7273 
7274  hex->face(0)->child_index(
7275  child_at_origin[hex->face(0)->refinement_case() -
7276  1][f_fl[0]][f_ro[0]]), // 1
7277  hex->face(0)->child_index(
7278  1 -
7279  child_at_origin[hex->face(0)->refinement_case() -
7280  1][f_fl[0]][f_ro[0]]),
7281 
7282  hex->face(1)->child_index(
7283  child_at_origin[hex->face(1)->refinement_case() -
7284  1][f_fl[1]][f_ro[1]]), // 3
7285  hex->face(1)->child_index(
7286  1 -
7287  child_at_origin[hex->face(1)->refinement_case() -
7288  1][f_fl[1]][f_ro[1]]),
7289 
7290  hex->face(2)->index(), // 5
7291 
7292  hex->face(3)->index(), // 6
7293 
7294  hex->face(4)->child_index(
7295  child_at_origin[hex->face(4)->refinement_case() -
7296  1][f_fl[4]][f_ro[4]]), // 7
7297  hex->face(4)->child_index(
7298  1 -
7299  child_at_origin[hex->face(4)->refinement_case() -
7300  1][f_fl[4]][f_ro[4]]),
7301 
7302  hex->face(5)->child_index(
7303  child_at_origin[hex->face(5)->refinement_case() -
7304  1][f_fl[5]][f_ro[5]]), // 9
7305  hex->face(5)->child_index(
7306  1 -
7307  child_at_origin[hex->face(5)->refinement_case() -
7308  1][f_fl[5]][f_ro[5]])
7309 
7310  };
7311 
7312  new_hexes[0]->set(
7314  3>(quad_indices[1],
7315  quad_indices[3],
7316  quad_indices[5],
7317  quad_indices[0],
7318  quad_indices[7],
7319  quad_indices[9]));
7320  new_hexes[1]->set(
7322  3>(quad_indices[2],
7323  quad_indices[4],
7324  quad_indices[0],
7325  quad_indices[6],
7326  quad_indices[8],
7327  quad_indices[10]));
7328  break;
7329  }
7330 
7332  {
7334  //
7335  // RefinementCase<dim>::cut_z
7336  //
7337  // the refined cube will look like this:
7338  //
7339  // *---------*
7340  // / /|
7341  // / / |
7342  // / / *
7343  // *---------* /|
7344  // | | / |
7345  // | |/ *
7346  // *---------* /
7347  // | | /
7348  // | |/
7349  // *---------*
7350  //
7351  // again, first collect some data about the
7352  // indices of the lines, with the following
7353  // numbering:
7354 
7355  // face 0: left plane
7356  // *
7357  // /|
7358  // / |
7359  // / *
7360  // * /|
7361  // | 0 |
7362  // |/ *
7363  // m0* /
7364  // | /
7365  // |/
7366  // *
7367  // face 1: right plane
7368  // *
7369  // /|
7370  // / |
7371  // / *m1
7372  // * /|
7373  // | 1 |
7374  // |/ *
7375  // * /
7376  // | /
7377  // |/
7378  // *
7379  // face 2: front plane
7380  // (note: x,y exchanged)
7381  // *-------*
7382  // | |
7383  // m0*---2---*
7384  // | |
7385  // *-------*
7386  // face 3: back plane
7387  // (note: x,y exchanged)
7388  // *-------*
7389  // | |
7390  // *---3---*m1
7391  // | |
7392  // *-------*
7393 
7394  // set up a list of line iterators first. from
7395  // this, construct lists of line_indices and
7396  // line orientations later on
7397  const typename Triangulation<dim, spacedim>::
7398  raw_line_iterator lines[4] = {
7399  hex->face(0)->child(0)->line(
7400  (hex->face(0)->refinement_case() ==
7402  1 :
7403  3), // 0
7404  hex->face(1)->child(0)->line(
7405  (hex->face(1)->refinement_case() ==
7407  1 :
7408  3), // 1
7409  hex->face(2)->child(0)->line(
7410  (hex->face(2)->refinement_case() ==
7412  1 :
7413  3), // 2
7414  hex->face(3)->child(0)->line(
7415  (hex->face(3)->refinement_case() ==
7417  1 :
7418  3) // 3
7419  };
7420 
7421  unsigned int line_indices[4];
7422  for (unsigned int i = 0; i < 4; ++i)
7423  line_indices[i] = lines[i]->index();
7424 
7425  // the orientation of lines for the inner quads
7426  // is quite tricky. as these lines are newly
7427  // created ones and thus have no parents, they
7428  // cannot inherit this property. set up an array
7429  // and fill it with the respective values
7430  bool line_orientation[4];
7431 
7432  // the middle vertex marked as m0 above is the
7433  // start vertex for lines 0 and 2 in standard
7434  // orientation, whereas m1 is the end vertex of
7435  // lines 1 and 3 in standard orientation
7436  const unsigned int middle_vertices[2] = {
7437  middle_vertex_index<dim, spacedim>(hex->line(8)),
7438  middle_vertex_index<dim, spacedim>(hex->line(11))};
7439 
7440  for (unsigned int i = 0; i < 4; ++i)
7441  if (lines[i]->vertex_index(i % 2) ==
7442  middle_vertices[i % 2])
7443  line_orientation[i] = true;
7444  else
7445  {
7446  // it must be the other way round then
7447  Assert(lines[i]->vertex_index((i + 1) % 2) ==
7448  middle_vertices[i % 2],
7449  ExcInternalError());
7450  line_orientation[i] = false;
7451  }
7452 
7453  // set up the new quad, line numbering is as
7454  // indicated above
7455  new_quads[0]->set(
7457  2>(line_indices[0],
7458  line_indices[1],
7459  line_indices[2],
7460  line_indices[3]));
7461 
7462  new_quads[0]->set_line_orientation(
7463  0, line_orientation[0]);
7464  new_quads[0]->set_line_orientation(
7465  1, line_orientation[1]);
7466  new_quads[0]->set_line_orientation(
7467  2, line_orientation[2]);
7468  new_quads[0]->set_line_orientation(
7469  3, line_orientation[3]);
7470 
7471  // the quads are numbered as follows:
7472  //
7473  // planes in the interior of the old hex:
7474  //
7475  // *
7476  // /|
7477  // / | x
7478  // / | *-------* *---------*
7479  // * | | | / /
7480  // | | | | / 0 /
7481  // | * | | / /
7482  // | / *-------*y *---------*x
7483  // | /
7484  // |/
7485  // *
7486  //
7487  // children of the faces of the old hex
7488  //
7489  // *---*---* *-------*
7490  // /| 8 | / /|
7491  // / | | / 10 / |
7492  // / *-------* / / *
7493  // * 2/| | *-------* 4/|
7494  // | / | 7 | | 6 | / |
7495  // |/1 *-------* | |/3 *
7496  // * / / *-------* /
7497  // | / 9 / | | /
7498  // |/ / | 5 |/
7499  // *-------* *---*---*
7500  //
7501  // note that we have to take care of the
7502  // orientation of faces.
7503  const int quad_indices[11] = {
7504  new_quads[0]->index(), // 0
7505 
7506  hex->face(0)->child_index(
7507  child_at_origin[hex->face(0)->refinement_case() -
7508  1][f_fl[0]][f_ro[0]]), // 1
7509  hex->face(0)->child_index(
7510  1 -
7511  child_at_origin[hex->face(0)->refinement_case() -
7512  1][f_fl[0]][f_ro[0]]),
7513 
7514  hex->face(1)->child_index(
7515  child_at_origin[hex->face(1)->refinement_case() -
7516  1][f_fl[1]][f_ro[1]]), // 3
7517  hex->face(1)->child_index(
7518  1 -
7519  child_at_origin[hex->face(1)->refinement_case() -
7520  1][f_fl[1]][f_ro[1]]),
7521 
7522  hex->face(2)->child_index(
7523  child_at_origin[hex->face(2)->refinement_case() -
7524  1][f_fl[2]][f_ro[2]]), // 5
7525  hex->face(2)->child_index(
7526  1 -
7527  child_at_origin[hex->face(2)->refinement_case() -
7528  1][f_fl[2]][f_ro[2]]),
7529 
7530  hex->face(3)->child_index(
7531  child_at_origin[hex->face(3)->refinement_case() -
7532  1][f_fl[3]][f_ro[3]]), // 7
7533  hex->face(3)->child_index(
7534  1 -
7535  child_at_origin[hex->face(3)->refinement_case() -
7536  1][f_fl[3]][f_ro[3]]),
7537 
7538  hex->face(4)->index(), // 9
7539 
7540  hex->face(5)->index() // 10
7541  };
7542 
7543  new_hexes[0]->set(
7545  3>(quad_indices[1],
7546  quad_indices[3],
7547  quad_indices[5],
7548  quad_indices[7],
7549  quad_indices[9],
7550  quad_indices[0]));
7551  new_hexes[1]->set(
7553  3>(quad_indices[2],
7554  quad_indices[4],
7555  quad_indices[6],
7556  quad_indices[8],
7557  quad_indices[0],
7558  quad_indices[10]));
7559  break;
7560  }
7561 
7563  {
7565  //
7566  // RefinementCase<dim>::cut_xy
7567  //
7568  // the refined cube will look like this:
7569  //
7570  // *----*----*
7571  // / / /|
7572  // *----*----* |
7573  // / / /| |
7574  // *----*----* | |
7575  // | | | | |
7576  // | | | | *
7577  // | | | |/
7578  // | | | *
7579  // | | |/
7580  // *----*----*
7581  //
7582 
7583  // first, create the new internal line
7584  new_lines[0]->set(
7586  1>(middle_vertex_index<dim, spacedim>(
7587  hex->face(4)),
7588  middle_vertex_index<dim, spacedim>(
7589  hex->face(5))));
7590 
7591  // again, first collect some data about the
7592  // indices of the lines, with the following
7593  // numbering:
7594 
7595  // face 0: left plane
7596  // *
7597  // /|
7598  // * |
7599  // /| |
7600  // * | |
7601  // | 0 |
7602  // | | *
7603  // | |/
7604  // | *
7605  // |/
7606  // *
7607  // face 1: right plane
7608  // *
7609  // /|
7610  // * |
7611  // /| |
7612  // * | |
7613  // | 1 |
7614  // | | *
7615  // | |/
7616  // | *
7617  // |/
7618  // *
7619  // face 2: front plane
7620  // (note: x,y exchanged)
7621  // *---*---*
7622  // | | |
7623  // | 2 |
7624  // | | |
7625  // *-------*
7626  // face 3: back plane
7627  // (note: x,y exchanged)
7628  // *---*---*
7629  // | | |
7630  // | 3 |
7631  // | | |
7632  // *---*---*
7633  // face 4: bottom plane
7634  // *---*---*
7635  // / 5 /
7636  // *-6-*-7-*
7637  // / 4 /
7638  // *---*---*
7639  // face 5: top plane
7640  // *---*---*
7641  // / 9 /
7642  // *10-*-11*
7643  // / 8 /
7644  // *---*---*
7645  // middle planes
7646  // *-------* *---*---*
7647  // / / | | |
7648  // / / | 12 |
7649  // / / | | |
7650  // *-------* *---*---*
7651 
7652  // set up a list of line iterators first. from
7653  // this, construct lists of line_indices and
7654  // line orientations later on
7655  const typename Triangulation<
7656  dim,
7657  spacedim>::raw_line_iterator lines[13] = {
7658  hex->face(0)->child(0)->line(
7659  (hex->face(0)->refinement_case() ==
7661  1 :
7662  3), // 0
7663  hex->face(1)->child(0)->line(
7664  (hex->face(1)->refinement_case() ==
7666  1 :
7667  3), // 1
7668  hex->face(2)->child(0)->line(
7669  (hex->face(2)->refinement_case() ==
7671  1 :
7672  3), // 2
7673  hex->face(3)->child(0)->line(
7674  (hex->face(3)->refinement_case() ==
7676  1 :
7677  3), // 3
7678 
7679  hex->face(4)
7680  ->isotropic_child(
7682  0, f_or[4], f_fl[4], f_ro[4]))
7683  ->line(
7685  1, f_or[4], f_fl[4], f_ro[4])), // 4
7686  hex->face(4)
7687  ->isotropic_child(
7689  3, f_or[4], f_fl[4], f_ro[4]))
7690  ->line(
7692  0, f_or[4], f_fl[4], f_ro[4])), // 5
7693  hex->face(4)
7694  ->isotropic_child(
7696  0, f_or[4], f_fl[4], f_ro[4]))
7697  ->line(
7699  3, f_or[4], f_fl[4], f_ro[4])), // 6
7700  hex->face(4)
7701  ->isotropic_child(
7703  3, f_or[4], f_fl[4], f_ro[4]))
7704  ->line(
7706  2, f_or[4], f_fl[4], f_ro[4])), // 7
7707 
7708  hex->face(5)
7709  ->isotropic_child(
7711  0, f_or[5], f_fl[5], f_ro[5]))
7712  ->line(
7714  1, f_or[5], f_fl[5], f_ro[5])), // 8
7715  hex->face(5)
7716  ->isotropic_child(
7718  3, f_or[5], f_fl[5], f_ro[5]))
7719  ->line(
7721  0, f_or[5], f_fl[5], f_ro[5])), // 9
7722  hex->face(5)
7723  ->isotropic_child(
7725  0, f_or[5], f_fl[5], f_ro[5]))
7726  ->line(
7728  3, f_or[5], f_fl[5], f_ro[5])), // 10
7729  hex->face(5)
7730  ->isotropic_child(
7732  3, f_or[5], f_fl[5], f_ro[5]))
7733  ->line(
7735  2, f_or[5], f_fl[5], f_ro[5])), // 11
7736 
7737  new_lines[0] // 12
7738  };
7739 
7740  unsigned int line_indices[13];
7741  for (unsigned int i = 0; i < 13; ++i)
7742  line_indices[i] = lines[i]->index();
7743 
7744  // the orientation of lines for the inner quads
7745  // is quite tricky. as these lines are newly
7746  // created ones and thus have no parents, they
7747  // cannot inherit this property. set up an array
7748  // and fill it with the respective values
7749  bool line_orientation[13];
7750 
7751  // the middle vertices of the lines of our
7752  // bottom face
7753  const unsigned int middle_vertices[4] = {
7754  hex->line(0)->child(0)->vertex_index(1),
7755  hex->line(1)->child(0)->vertex_index(1),
7756  hex->line(2)->child(0)->vertex_index(1),
7757  hex->line(3)->child(0)->vertex_index(1),
7758  };
7759 
7760  // note: for lines 0 to 3 the orientation of the
7761  // line is 'true', if vertex 0 is on the bottom
7762  // face
7763  for (unsigned int i = 0; i < 4; ++i)
7764  if (lines[i]->vertex_index(0) == middle_vertices[i])
7765  line_orientation[i] = true;
7766  else
7767  {
7768  // it must be the other way round then
7769  Assert(lines[i]->vertex_index(1) ==
7770  middle_vertices[i],
7771  ExcInternalError());
7772  line_orientation[i] = false;
7773  }
7774 
7775  // note: for lines 4 to 11 (inner lines of the
7776  // outer quads) the following holds: the second
7777  // vertex of the even lines in standard
7778  // orientation is the vertex in the middle of
7779  // the quad, whereas for odd lines the first
7780  // vertex is the same middle vertex.
7781  for (unsigned int i = 4; i < 12; ++i)
7782  if (lines[i]->vertex_index((i + 1) % 2) ==
7783  middle_vertex_index<dim, spacedim>(
7784  hex->face(3 + i / 4)))
7785  line_orientation[i] = true;
7786  else
7787  {
7788  // it must be the other way
7789  // round then
7790  Assert(lines[i]->vertex_index(i % 2) ==
7791  (middle_vertex_index<dim, spacedim>(
7792  hex->face(3 + i / 4))),
7793  ExcInternalError());
7794  line_orientation[i] = false;
7795  }
7796  // for the last line the line orientation is
7797  // always true, since it was just constructed
7798  // that way
7799  line_orientation[12] = true;
7800 
7801  // set up the 4 quads, numbered as follows (left
7802  // quad numbering, right line numbering
7803  // extracted from above)
7804  //
7805  // * *
7806  // /| 9|
7807  // * | * |
7808  // y/| | 8| 3
7809  // * |1| * | |
7810  // | | |x | 12|
7811  // |0| * | | *
7812  // | |/ 2 |5
7813  // | * | *
7814  // |/ |4
7815  // * *
7816  //
7817  // x
7818  // *---*---* *10-*-11*
7819  // | | | | | |
7820  // | 2 | 3 | 0 12 1
7821  // | | | | | |
7822  // *---*---*y *-6-*-7-*
7823 
7824  new_quads[0]->set(
7826  2>(line_indices[2],
7827  line_indices[12],
7828  line_indices[4],
7829  line_indices[8]));
7830  new_quads[1]->set(
7832  2>(line_indices[12],
7833  line_indices[3],
7834  line_indices[5],
7835  line_indices[9]));
7836  new_quads[2]->set(
7838  2>(line_indices[6],
7839  line_indices[10],
7840  line_indices[0],
7841  line_indices[12]));
7842  new_quads[3]->set(
7844  2>(line_indices[7],
7845  line_indices[11],
7846  line_indices[12],
7847  line_indices[1]));
7848 
7849  new_quads[0]->set_line_orientation(
7850  0, line_orientation[2]);
7851  new_quads[0]->set_line_orientation(
7852  2, line_orientation[4]);
7853  new_quads[0]->set_line_orientation(
7854  3, line_orientation[8]);
7855 
7856  new_quads[1]->set_line_orientation(
7857  1, line_orientation[3]);
7858  new_quads[1]->set_line_orientation(
7859  2, line_orientation[5]);
7860  new_quads[1]->set_line_orientation(
7861  3, line_orientation[9]);
7862 
7863  new_quads[2]->set_line_orientation(
7864  0, line_orientation[6]);
7865  new_quads[2]->set_line_orientation(
7866  1, line_orientation[10]);
7867  new_quads[2]->set_line_orientation(
7868  2, line_orientation[0]);
7869 
7870  new_quads[3]->set_line_orientation(
7871  0, line_orientation[7]);
7872  new_quads[3]->set_line_orientation(
7873  1, line_orientation[11]);
7874  new_quads[3]->set_line_orientation(
7875  3, line_orientation[1]);
7876 
7877  // the quads are numbered as follows:
7878  //
7879  // planes in the interior of the old hex:
7880  //
7881  // *
7882  // /|
7883  // * | x
7884  // /| | *---*---* *---------*
7885  // * |1| | | | / /
7886  // | | | | 2 | 3 | / /
7887  // |0| * | | | / /
7888  // | |/ *---*---*y *---------*x
7889  // | *
7890  // |/
7891  // *
7892  //
7893  // children of the faces of the old hex
7894  //
7895  // *---*---* *---*---*
7896  // /| | | /18 / 19/|
7897  // * |10 | 11| /---/---* |
7898  // /| | | | /16 / 17/| |
7899  // * |5| | | *---*---* |7|
7900  // | | *---*---* | | | | *
7901  // |4|/14 / 15/ | | |6|/
7902  // | *---/---/ | 8 | 9 | *
7903  // |/12 / 13/ | | |/
7904  // *---*---* *---*---*
7905  //
7906  // note that we have to take care of the
7907  // orientation of faces.
7908  const int quad_indices[20] = {
7909  new_quads[0]->index(), // 0
7910  new_quads[1]->index(),
7911  new_quads[2]->index(),
7912  new_quads[3]->index(),
7913 
7914  hex->face(0)->child_index(
7915  child_at_origin[hex->face(0)->refinement_case() -
7916  1][f_fl[0]][f_ro[0]]), // 4
7917  hex->face(0)->child_index(
7918  1 -
7919  child_at_origin[hex->face(0)->refinement_case() -
7920  1][f_fl[0]][f_ro[0]]),
7921 
7922  hex->face(1)->child_index(
7923  child_at_origin[hex->face(1)->refinement_case() -
7924  1][f_fl[1]][f_ro[1]]), // 6
7925  hex->face(1)->child_index(
7926  1 -
7927  child_at_origin[hex->face(1)->refinement_case() -
7928  1][f_fl[1]][f_ro[1]]),
7929 
7930  hex->face(2)->child_index(
7931  child_at_origin[hex->face(2)->refinement_case() -
7932  1][f_fl[2]][f_ro[2]]), // 8
7933  hex->face(2)->child_index(
7934  1 -
7935  child_at_origin[hex->face(2)->refinement_case() -
7936  1][f_fl[2]][f_ro[2]]),
7937 
7938  hex->face(3)->child_index(
7939  child_at_origin[hex->face(3)->refinement_case() -
7940  1][f_fl[3]][f_ro[3]]), // 10
7941  hex->face(3)->child_index(
7942  1 -
7943  child_at_origin[hex->face(3)->refinement_case() -
7944  1][f_fl[3]][f_ro[3]]),
7945 
7946  hex->face(4)->isotropic_child_index(
7948  0, f_or[4], f_fl[4], f_ro[4])), // 12
7949  hex->face(4)->isotropic_child_index(
7951  1, f_or[4], f_fl[4], f_ro[4])),
7952  hex->face(4)->isotropic_child_index(
7954  2, f_or[4], f_fl[4], f_ro[4])),
7955  hex->face(4)->isotropic_child_index(
7957  3, f_or[4], f_fl[4], f_ro[4])),
7958 
7959  hex->face(5)->isotropic_child_index(
7961  0, f_or[5], f_fl[5], f_ro[5])), // 16
7962  hex->face(5)->isotropic_child_index(
7964  1, f_or[5], f_fl[5], f_ro[5])),
7965  hex->face(5)->isotropic_child_index(
7967  2, f_or[5], f_fl[5], f_ro[5])),
7968  hex->face(5)->isotropic_child_index(
7970  3, f_or[5], f_fl[5], f_ro[5]))};
7971 
7972  new_hexes[0]->set(
7974  3>(quad_indices[4],
7975  quad_indices[0],
7976  quad_indices[8],
7977  quad_indices[2],
7978  quad_indices[12],
7979  quad_indices[16]));
7980  new_hexes[1]->set(
7982  3>(quad_indices[0],
7983  quad_indices[6],
7984  quad_indices[9],
7985  quad_indices[3],
7986  quad_indices[13],
7987  quad_indices[17]));
7988  new_hexes[2]->set(
7990  3>(quad_indices[5],
7991  quad_indices[1],
7992  quad_indices[2],
7993  quad_indices[10],
7994  quad_indices[14],
7995  quad_indices[18]));
7996  new_hexes[3]->set(
7998  3>(quad_indices[1],
7999  quad_indices[7],
8000  quad_indices[3],
8001  quad_indices[11],
8002  quad_indices[15],
8003  quad_indices[19]));
8004  break;
8005  }
8006 
8008  {
8010  //
8011  // RefinementCase<dim>::cut_xz
8012  //
8013  // the refined cube will look like this:
8014  //
8015  // *----*----*
8016  // / / /|
8017  // / / / |
8018  // / / / *
8019  // *----*----* /|
8020  // | | | / |
8021  // | | |/ *
8022  // *----*----* /
8023  // | | | /
8024  // | | |/
8025  // *----*----*
8026  //
8027 
8028  // first, create the new internal line
8029  new_lines[0]->set(
8031  1>(middle_vertex_index<dim, spacedim>(
8032  hex->face(2)),
8033  middle_vertex_index<dim, spacedim>(
8034  hex->face(3))));
8035 
8036  // again, first collect some data about the
8037  // indices of the lines, with the following
8038  // numbering:
8039 
8040  // face 0: left plane
8041  // *
8042  // /|
8043  // / |
8044  // / *
8045  // * /|
8046  // | 0 |
8047  // |/ *
8048  // * /
8049  // | /
8050  // |/
8051  // *
8052  // face 1: right plane
8053  // *
8054  // /|
8055  // / |
8056  // / *
8057  // * /|
8058  // | 1 |
8059  // |/ *
8060  // * /
8061  // | /
8062  // |/
8063  // *
8064  // face 2: front plane
8065  // (note: x,y exchanged)
8066  // *---*---*
8067  // | 5 |
8068  // *-6-*-7-*
8069  // | 4 |
8070  // *---*---*
8071  // face 3: back plane
8072  // (note: x,y exchanged)
8073  // *---*---*
8074  // | 9 |
8075  // *10-*-11*
8076  // | 8 |
8077  // *---*---*
8078  // face 4: bottom plane
8079  // *---*---*
8080  // / / /
8081  // / 2 /
8082  // / / /
8083  // *---*---*
8084  // face 5: top plane
8085  // *---*---*
8086  // / / /
8087  // / 3 /
8088  // / / /
8089  // *---*---*
8090  // middle planes
8091  // *---*---* *-------*
8092  // / / / | |
8093  // / 12 / | |
8094  // / / / | |
8095  // *---*---* *-------*
8096 
8097  // set up a list of line iterators first. from
8098  // this, construct lists of line_indices and
8099  // line orientations later on
8100  const typename Triangulation<
8101  dim,
8102  spacedim>::raw_line_iterator lines[13] = {
8103  hex->face(0)->child(0)->line(
8104  (hex->face(0)->refinement_case() ==
8106  1 :
8107  3), // 0
8108  hex->face(1)->child(0)->line(
8109  (hex->face(1)->refinement_case() ==
8111  1 :
8112  3), // 1
8113  hex->face(4)->child(0)->line(
8114  (hex->face(4)->refinement_case() ==
8116  1 :
8117  3), // 2
8118  hex->face(5)->child(0)->line(
8119  (hex->face(5)->refinement_case() ==
8121  1 :
8122  3), // 3
8123 
8124  hex->face(2)
8125  ->isotropic_child(
8127  0, f_or[2], f_fl[2], f_ro[2]))
8128  ->line(
8130  3, f_or[2], f_fl[2], f_ro[2])), // 4
8131  hex->face(2)
8132  ->isotropic_child(
8134  3, f_or[2], f_fl[2], f_ro[2]))
8135  ->line(
8137  2, f_or[2], f_fl[2], f_ro[2])), // 5
8138  hex->face(2)
8139  ->isotropic_child(
8141  0, f_or[2], f_fl[2], f_ro[2]))
8142  ->line(
8144  1, f_or[2], f_fl[2], f_ro[2])), // 6
8145  hex->face(2)
8146  ->isotropic_child(
8148  3, f_or[2], f_fl[2], f_ro[2]))
8149  ->line(
8151  0, f_or[2], f_fl[2], f_ro[2])), // 7
8152 
8153  hex->face(3)
8154  ->isotropic_child(
8156  0, f_or[3], f_fl[3], f_ro[3]))
8157  ->line(
8159  3, f_or[3], f_fl[3], f_ro[3])), // 8
8160  hex->face(3)
8161  ->isotropic_child(
8163  3, f_or[3], f_fl[3], f_ro[3]))
8164  ->line(
8166  2, f_or[3], f_fl[3], f_ro[3])), // 9
8167  hex->face(3)
8168  ->isotropic_child(
8170  0, f_or[3], f_fl[3], f_ro[3]))
8171  ->line(
8173  1, f_or[3], f_fl[3], f_ro[3])), // 10
8174  hex->face(3)
8175  ->isotropic_child(
8177  3, f_or[3], f_fl[3], f_ro[3]))
8178  ->line(
8180  0, f_or[3], f_fl[3], f_ro[3])), // 11
8181 
8182  new_lines[0] // 12
8183  };
8184 
8185  unsigned int line_indices[13];
8186  for (unsigned int i = 0; i < 13; ++i)
8187  line_indices[i] = lines[i]->index();
8188 
8189  // the orientation of lines for the inner quads
8190  // is quite tricky. as these lines are newly
8191  // created ones and thus have no parents, they
8192  // cannot inherit this property. set up an array
8193  // and fill it with the respective values
8194  bool line_orientation[13];
8195 
8196  // the middle vertices of the
8197  // lines of our front face
8198  const unsigned int middle_vertices[4] = {
8199  hex->line(8)->child(0)->vertex_index(1),
8200  hex->line(9)->child(0)->vertex_index(1),
8201  hex->line(2)->child(0)->vertex_index(1),
8202  hex->line(6)->child(0)->vertex_index(1),
8203  };
8204 
8205  // note: for lines 0 to 3 the orientation of the
8206  // line is 'true', if vertex 0 is on the front
8207  for (unsigned int i = 0; i < 4; ++i)
8208  if (lines[i]->vertex_index(0) == middle_vertices[i])
8209  line_orientation[i] = true;
8210  else
8211  {
8212  // it must be the other way round then
8213  Assert(lines[i]->vertex_index(1) ==
8214  middle_vertices[i],
8215  ExcInternalError());
8216  line_orientation[i] = false;
8217  }
8218 
8219  // note: for lines 4 to 11 (inner lines of the
8220  // outer quads) the following holds: the second
8221  // vertex of the even lines in standard
8222  // orientation is the vertex in the middle of
8223  // the quad, whereas for odd lines the first
8224  // vertex is the same middle vertex.
8225  for (unsigned int i = 4; i < 12; ++i)
8226  if (lines[i]->vertex_index((i + 1) % 2) ==
8227  middle_vertex_index<dim, spacedim>(
8228  hex->face(1 + i / 4)))
8229  line_orientation[i] = true;
8230  else
8231  {
8232  // it must be the other way
8233  // round then
8234  Assert(lines[i]->vertex_index(i % 2) ==
8235  (middle_vertex_index<dim, spacedim>(
8236  hex->face(1 + i / 4))),
8237  ExcInternalError());
8238  line_orientation[i] = false;
8239  }
8240  // for the last line the line orientation is
8241  // always true, since it was just constructed
8242  // that way
8243  line_orientation[12] = true;
8244 
8245  // set up the 4 quads, numbered as follows (left
8246  // quad numbering, right line numbering
8247  // extracted from above), the drawings denote
8248  // middle planes
8249  //
8250  // * *
8251  // /| /|
8252  // / | 3 9
8253  // y/ * / *
8254  // * 3/| * /|
8255  // | / |x 5 12|8
8256  // |/ * |/ *
8257  // * 2/ * /
8258  // | / 4 2
8259  // |/ |/
8260  // * *
8261  //
8262  // y
8263  // *----*----* *-10-*-11-*
8264  // / / / / / /
8265  // / 0 / 1 / 0 12 1
8266  // / / / / / /
8267  // *----*----*x *--6-*--7-*
8268 
8269  new_quads[0]->set(
8271  2>(line_indices[0],
8272  line_indices[12],
8273  line_indices[6],
8274  line_indices[10]));
8275  new_quads[1]->set(
8277  2>(line_indices[12],
8278  line_indices[1],
8279  line_indices[7],
8280  line_indices[11]));
8281  new_quads[2]->set(
8283  2>(line_indices[4],
8284  line_indices[8],
8285  line_indices[2],
8286  line_indices[12]));
8287  new_quads[3]->set(
8289  2>(line_indices[5],
8290  line_indices[9],
8291  line_indices[12],
8292  line_indices[3]));
8293 
8294  new_quads[0]->set_line_orientation(
8295  0, line_orientation[0]);
8296  new_quads[0]->set_line_orientation(
8297  2, line_orientation[6]);
8298  new_quads[0]->set_line_orientation(
8299  3, line_orientation[10]);
8300 
8301  new_quads[1]->set_line_orientation(
8302  1, line_orientation[1]);
8303  new_quads[1]->set_line_orientation(
8304  2, line_orientation[7]);
8305  new_quads[1]->set_line_orientation(
8306  3, line_orientation[11]);
8307 
8308  new_quads[2]->set_line_orientation(
8309  0, line_orientation[4]);
8310  new_quads[2]->set_line_orientation(
8311  1, line_orientation[8]);
8312  new_quads[2]->set_line_orientation(
8313  2, line_orientation[2]);
8314 
8315  new_quads[3]->set_line_orientation(
8316  0, line_orientation[5]);
8317  new_quads[3]->set_line_orientation(
8318  1, line_orientation[9]);
8319  new_quads[3]->set_line_orientation(
8320  3, line_orientation[3]);
8321 
8322  // the quads are numbered as follows:
8323  //
8324  // planes in the interior of the old hex:
8325  //
8326  // *
8327  // /|
8328  // / | x
8329  // /3 * *-------* *----*----*
8330  // * /| | | / / /
8331  // | / | | | / 0 / 1 /
8332  // |/ * | | / / /
8333  // * 2/ *-------*y *----*----*x
8334  // | /
8335  // |/
8336  // *
8337  //
8338  // children of the faces
8339  // of the old hex
8340  // *---*---* *---*---*
8341  // /|13 | 15| / / /|
8342  // / | | | /18 / 19/ |
8343  // / *---*---* / / / *
8344  // * 5/| | | *---*---* 7/|
8345  // | / |12 | 14| | 9 | 11| / |
8346  // |/4 *---*---* | | |/6 *
8347  // * / / / *---*---* /
8348  // | /16 / 17/ | | | /
8349  // |/ / / | 8 | 10|/
8350  // *---*---* *---*---*
8351  //
8352  // note that we have to take care of the
8353  // orientation of faces.
8354  const int quad_indices[20] = {
8355  new_quads[0]->index(), // 0
8356  new_quads[1]->index(),
8357  new_quads[2]->index(),
8358  new_quads[3]->index(),
8359 
8360  hex->face(0)->child_index(
8361  child_at_origin[hex->face(0)->refinement_case() -
8362  1][f_fl[0]][f_ro[0]]), // 4
8363  hex->face(0)->child_index(
8364  1 -
8365  child_at_origin[hex->face(0)->refinement_case() -
8366  1][f_fl[0]][f_ro[0]]),
8367 
8368  hex->face(1)->child_index(
8369  child_at_origin[hex->face(1)->refinement_case() -
8370  1][f_fl[1]][f_ro[1]]), // 6
8371  hex->face(1)->child_index(
8372  1 -
8373  child_at_origin[hex->face(1)->refinement_case() -
8374  1][f_fl[1]][f_ro[1]]),
8375 
8376  hex->face(2)->isotropic_child_index(
8378  0, f_or[2], f_fl[2], f_ro[2])), // 8
8379  hex->face(2)->isotropic_child_index(
8381  1, f_or[2], f_fl[2], f_ro[2])),
8382  hex->face(2)->isotropic_child_index(
8384  2, f_or[2], f_fl[2], f_ro[2])),
8385  hex->face(2)->isotropic_child_index(
8387  3, f_or[2], f_fl[2], f_ro[2])),
8388 
8389  hex->face(3)->isotropic_child_index(
8391  0, f_or[3], f_fl[3], f_ro[3])), // 12
8392  hex->face(3)->isotropic_child_index(
8394  1, f_or[3], f_fl[3], f_ro[3])),
8395  hex->face(3)->isotropic_child_index(
8397  2, f_or[3], f_fl[3], f_ro[3])),
8398  hex->face(3)->isotropic_child_index(
8400  3, f_or[3], f_fl[3], f_ro[3])),
8401 
8402  hex->face(4)->child_index(
8403  child_at_origin[hex->face(4)->refinement_case() -
8404  1][f_fl[4]][f_ro[4]]), // 16
8405  hex->face(4)->child_index(
8406  1 -
8407  child_at_origin[hex->face(4)->refinement_case() -
8408  1][f_fl[4]][f_ro[4]]),
8409 
8410  hex->face(5)->child_index(
8411  child_at_origin[hex->face(5)->refinement_case() -
8412  1][f_fl[5]][f_ro[5]]), // 18
8413  hex->face(5)->child_index(
8414  1 -
8415  child_at_origin[hex->face(5)->refinement_case() -
8416  1][f_fl[5]][f_ro[5]])};
8417 
8418  // due to the exchange of x and y for the front
8419  // and back face, we order the children
8420  // according to
8421  //
8422  // *---*---*
8423  // | 1 | 3 |
8424  // *---*---*
8425  // | 0 | 2 |
8426  // *---*---*
8427  new_hexes[0]->set(
8429  3>(quad_indices[4],
8430  quad_indices[2],
8431  quad_indices[8],
8432  quad_indices[12],
8433  quad_indices[16],
8434  quad_indices[0]));
8435  new_hexes[1]->set(
8437  3>(quad_indices[5],
8438  quad_indices[3],
8439  quad_indices[9],
8440  quad_indices[13],
8441  quad_indices[0],
8442  quad_indices[18]));
8443  new_hexes[2]->set(
8445  3>(quad_indices[2],
8446  quad_indices[6],
8447  quad_indices[10],
8448  quad_indices[14],
8449  quad_indices[17],
8450  quad_indices[1]));
8451  new_hexes[3]->set(
8453  3>(quad_indices[3],
8454  quad_indices[7],
8455  quad_indices[11],
8456  quad_indices[15],
8457  quad_indices[1],
8458  quad_indices[19]));
8459  break;
8460  }
8461 
8463  {
8465  //
8466  // RefinementCase<dim>::cut_yz
8467  //
8468  // the refined cube will look like this:
8469  //
8470  // *---------*
8471  // / /|
8472  // *---------* |
8473  // / /| |
8474  // *---------* |/|
8475  // | | * |
8476  // | |/| *
8477  // *---------* |/
8478  // | | *
8479  // | |/
8480  // *---------*
8481  //
8482 
8483  // first, create the new
8484  // internal line
8485  new_lines[0]->set(
8487  1>(middle_vertex_index<dim, spacedim>(
8488  hex->face(0)),
8489  middle_vertex_index<dim, spacedim>(
8490  hex->face(1))));
8491 
8492  // again, first collect some data about the
8493  // indices of the lines, with the following
8494  // numbering: (note that face 0 and 1 each are
8495  // shown twice for better readability)
8496 
8497  // face 0: left plane
8498  // * *
8499  // /| /|
8500  // * | * |
8501  // /| * /| *
8502  // * 5/| * |7|
8503  // | * | | * |
8504  // |/| * |6| *
8505  // * 4/ * |/
8506  // | * | *
8507  // |/ |/
8508  // * *
8509  // face 1: right plane
8510  // * *
8511  // /| /|
8512  // * | * |
8513  // /| * /| *
8514  // * 9/| * |11
8515  // | * | | * |
8516  // |/| * |10 *
8517  // * 8/ * |/
8518  // | * | *
8519  // |/ |/
8520  // * *
8521  // face 2: front plane
8522  // (note: x,y exchanged)
8523  // *-------*
8524  // | |
8525  // *---0---*
8526  // | |
8527  // *-------*
8528  // face 3: back plane
8529  // (note: x,y exchanged)
8530  // *-------*
8531  // | |
8532  // *---1---*
8533  // | |
8534  // *-------*
8535  // face 4: bottom plane
8536  // *-------*
8537  // / /
8538  // *---2---*
8539  // / /
8540  // *-------*
8541  // face 5: top plane
8542  // *-------*
8543  // / /
8544  // *---3---*
8545  // / /
8546  // *-------*
8547  // middle planes
8548  // *-------* *-------*
8549  // / / | |
8550  // *---12--* | |
8551  // / / | |
8552  // *-------* *-------*
8553 
8554  // set up a list of line iterators first. from
8555  // this, construct lists of line_indices and
8556  // line orientations later on
8557  const typename Triangulation<
8558  dim,
8559  spacedim>::raw_line_iterator lines[13] = {
8560  hex->face(2)->child(0)->line(
8561  (hex->face(2)->refinement_case() ==
8563  1 :
8564  3), // 0
8565  hex->face(3)->child(0)->line(
8566  (hex->face(3)->refinement_case() ==
8568  1 :
8569  3), // 1
8570  hex->face(4)->child(0)->line(
8571  (hex->face(4)->refinement_case() ==
8573  1 :
8574  3), // 2
8575  hex->face(5)->child(0)->line(
8576  (hex->face(5)->refinement_case() ==
8578  1 :
8579  3), // 3
8580 
8581  hex->face(0)
8582  ->isotropic_child(
8584  0, f_or[0], f_fl[0], f_ro[0]))
8585  ->line(
8587  1, f_or[0], f_fl[0], f_ro[0])), // 4
8588  hex->face(0)
8589  ->isotropic_child(
8591  3, f_or[0], f_fl[0], f_ro[0]))
8592  ->line(
8594  0, f_or[0], f_fl[0], f_ro[0])), // 5
8595  hex->face(0)
8596  ->isotropic_child(
8598  0, f_or[0], f_fl[0], f_ro[0]))
8599  ->line(
8601  3, f_or[0], f_fl[0], f_ro[0])), // 6
8602  hex->face(0)
8603  ->isotropic_child(
8605  3, f_or[0], f_fl[0], f_ro[0]))
8606  ->line(
8608  2, f_or[0], f_fl[0], f_ro[0])), // 7
8609 
8610  hex->face(1)
8611  ->isotropic_child(
8613  0, f_or[1], f_fl[1], f_ro[1]))
8614  ->line(
8616  1, f_or[1], f_fl[1], f_ro[1])), // 8
8617  hex->face(1)
8618  ->isotropic_child(
8620  3, f_or[1], f_fl[1], f_ro[1]))
8621  ->line(
8623  0, f_or[1], f_fl[1], f_ro[1])), // 9
8624  hex->face(1)
8625  ->isotropic_child(
8627  0, f_or[1], f_fl[1], f_ro[1]))
8628  ->line(
8630  3, f_or[1], f_fl[1], f_ro[1])), // 10
8631  hex->face(1)
8632  ->isotropic_child(
8634  3, f_or[1], f_fl[1], f_ro[1]))
8635  ->line(
8637  2, f_or[1], f_fl[1], f_ro[1])), // 11
8638 
8639  new_lines[0] // 12
8640  };
8641 
8642  unsigned int line_indices[13];
8643 
8644  for (unsigned int i = 0; i < 13; ++i)
8645  line_indices[i] = lines[i]->index();
8646 
8647  // the orientation of lines for the inner quads
8648  // is quite tricky. as these lines are newly
8649  // created ones and thus have no parents, they
8650  // cannot inherit this property. set up an array
8651  // and fill it with the respective values
8652  bool line_orientation[13];
8653 
8654  // the middle vertices of the lines of our front
8655  // face
8656  const unsigned int middle_vertices[4] = {
8657  hex->line(8)->child(0)->vertex_index(1),
8658  hex->line(10)->child(0)->vertex_index(1),
8659  hex->line(0)->child(0)->vertex_index(1),
8660  hex->line(4)->child(0)->vertex_index(1),
8661  };
8662 
8663  // note: for lines 0 to 3 the orientation of the
8664  // line is 'true', if vertex 0 is on the front
8665  for (unsigned int i = 0; i < 4; ++i)
8666  if (lines[i]->vertex_index(0) == middle_vertices[i])
8667  line_orientation[i] = true;
8668  else
8669  {
8670  // it must be the other way round then
8671  Assert(lines[i]->vertex_index(1) ==
8672  middle_vertices[i],
8673  ExcInternalError());
8674  line_orientation[i] = false;
8675  }
8676 
8677  // note: for lines 4 to 11 (inner lines of the
8678  // outer quads) the following holds: the second
8679  // vertex of the even lines in standard
8680  // orientation is the vertex in the middle of
8681  // the quad, whereas for odd lines the first
8682  // vertex is the same middle vertex.
8683  for (unsigned int i = 4; i < 12; ++i)
8684  if (lines[i]->vertex_index((i + 1) % 2) ==
8685  middle_vertex_index<dim, spacedim>(
8686  hex->face(i / 4 - 1)))
8687  line_orientation[i] = true;
8688  else
8689  {
8690  // it must be the other way
8691  // round then
8692  Assert(lines[i]->vertex_index(i % 2) ==
8693  (middle_vertex_index<dim, spacedim>(
8694  hex->face(i / 4 - 1))),
8695  ExcInternalError());
8696  line_orientation[i] = false;
8697  }
8698  // for the last line the line orientation is
8699  // always true, since it was just constructed
8700  // that way
8701  line_orientation[12] = true;
8702 
8703  // set up the 4 quads, numbered as follows (left
8704  // quad numbering, right line numbering
8705  // extracted from above)
8706  //
8707  // x
8708  // *-------* *---3---*
8709  // | 3 | 5 9
8710  // *-------* *---12--*
8711  // | 2 | 4 8
8712  // *-------*y *---2---*
8713  //
8714  // y
8715  // *---------* *----1----*
8716  // / 1 / 7 11
8717  // *---------* *----12---*
8718  // / 0 / 6 10
8719  // *---------*x *----0----*
8720 
8721  new_quads[0]->set(
8723  2>(line_indices[6],
8724  line_indices[10],
8725  line_indices[0],
8726  line_indices[12]));
8727  new_quads[1]->set(
8729  2>(line_indices[7],
8730  line_indices[11],
8731  line_indices[12],
8732  line_indices[1]));
8733  new_quads[2]->set(
8735  2>(line_indices[2],
8736  line_indices[12],
8737  line_indices[4],
8738  line_indices[8]));
8739  new_quads[3]->set(
8741  2>(line_indices[12],
8742  line_indices[3],
8743  line_indices[5],
8744  line_indices[9]));
8745 
8746  new_quads[0]->set_line_orientation(
8747  0, line_orientation[6]);
8748  new_quads[0]->set_line_orientation(
8749  1, line_orientation[10]);
8750  new_quads[0]->set_line_orientation(
8751  2, line_orientation[0]);
8752 
8753  new_quads[1]->set_line_orientation(
8754  0, line_orientation[7]);
8755  new_quads[1]->set_line_orientation(
8756  1, line_orientation[11]);
8757  new_quads[1]->set_line_orientation(
8758  3, line_orientation[1]);
8759 
8760  new_quads[2]->set_line_orientation(
8761  0, line_orientation[2]);
8762  new_quads[2]->set_line_orientation(
8763  2, line_orientation[4]);
8764  new_quads[2]->set_line_orientation(
8765  3, line_orientation[8]);
8766 
8767  new_quads[3]->set_line_orientation(
8768  1, line_orientation[3]);
8769  new_quads[3]->set_line_orientation(
8770  2, line_orientation[5]);
8771  new_quads[3]->set_line_orientation(
8772  3, line_orientation[9]);
8773 
8774  // the quads are numbered as follows:
8775  //
8776  // planes in the interior of the old hex:
8777  //
8778  // *
8779  // /|
8780  // / | x
8781  // / | *-------* *---------*
8782  // * | | 3 | / 1 /
8783  // | | *-------* *---------*
8784  // | * | 2 | / 0 /
8785  // | / *-------*y *---------*x
8786  // | /
8787  // |/
8788  // *
8789  //
8790  // children of the faces
8791  // of the old hex
8792  // *-------* *-------*
8793  // /| | / 19 /|
8794  // * | 15 | *-------* |
8795  // /|7*-------* / 18 /|11
8796  // * |/| | *-------* |/|
8797  // |6* | 14 | | 10* |
8798  // |/|5*-------* | 13 |/|9*
8799  // * |/ 17 / *-------* |/
8800  // |4*-------* | |8*
8801  // |/ 16 / | 12 |/
8802  // *-------* *-------*
8803  //
8804  // note that we have to take care of the
8805  // orientation of faces.
8806  const int quad_indices[20] = {
8807  new_quads[0]->index(), // 0
8808  new_quads[1]->index(),
8809  new_quads[2]->index(),
8810  new_quads[3]->index(),
8811 
8812  hex->face(0)->isotropic_child_index(
8814  0, f_or[0], f_fl[0], f_ro[0])), // 4
8815  hex->face(0)->isotropic_child_index(
8817  1, f_or[0], f_fl[0], f_ro[0])),
8818  hex->face(0)->isotropic_child_index(
8820  2, f_or[0], f_fl[0], f_ro[0])),
8821  hex->face(0)->isotropic_child_index(
8823  3, f_or[0], f_fl[0], f_ro[0])),
8824 
8825  hex->face(1)->isotropic_child_index(
8827  0, f_or[1], f_fl[1], f_ro[1])), // 8
8828  hex->face(1)->isotropic_child_index(
8830  1, f_or[1], f_fl[1], f_ro[1])),
8831  hex->face(1)->isotropic_child_index(
8833  2, f_or[1], f_fl[1], f_ro[1])),
8834  hex->face(1)->isotropic_child_index(
8836  3, f_or[1], f_fl[1], f_ro[1])),
8837 
8838  hex->face(2)->child_index(
8839  child_at_origin[hex->face(2)->refinement_case() -
8840  1][f_fl[2]][f_ro[2]]), // 12
8841  hex->face(2)->child_index(
8842  1 -
8843  child_at_origin[hex->face(2)->refinement_case() -
8844  1][f_fl[2]][f_ro[2]]),
8845 
8846  hex->face(3)->child_index(
8847  child_at_origin[hex->face(3)->refinement_case() -
8848  1][f_fl[3]][f_ro[3]]), // 14
8849  hex->face(3)->child_index(
8850  1 -
8851  child_at_origin[hex->face(3)->refinement_case() -
8852  1][f_fl[3]][f_ro[3]]),
8853 
8854  hex->face(4)->child_index(
8855  child_at_origin[hex->face(4)->refinement_case() -
8856  1][f_fl[4]][f_ro[4]]), // 16
8857  hex->face(4)->child_index(
8858  1 -
8859  child_at_origin[hex->face(4)->refinement_case() -
8860  1][f_fl[4]][f_ro[4]]),
8861 
8862  hex->face(5)->child_index(
8863  child_at_origin[hex->face(5)->refinement_case() -
8864  1][f_fl[5]][f_ro[5]]), // 18
8865  hex->face(5)->child_index(
8866  1 -
8867  child_at_origin[hex->face(5)->refinement_case() -
8868  1][f_fl[5]][f_ro[5]])};
8869 
8870  new_hexes[0]->set(
8872  3>(quad_indices[4],
8873  quad_indices[8],
8874  quad_indices[12],
8875  quad_indices[2],
8876  quad_indices[16],
8877  quad_indices[0]));
8878  new_hexes[1]->set(
8880  3>(quad_indices[5],
8881  quad_indices[9],
8882  quad_indices[2],
8883  quad_indices[14],
8884  quad_indices[17],
8885  quad_indices[1]));
8886  new_hexes[2]->set(
8888  3>(quad_indices[6],
8889  quad_indices[10],
8890  quad_indices[13],
8891  quad_indices[3],
8892  quad_indices[0],
8893  quad_indices[18]));
8894  new_hexes[3]->set(
8896  3>(quad_indices[7],
8897  quad_indices[11],
8898  quad_indices[3],
8899  quad_indices[15],
8900  quad_indices[1],
8901  quad_indices[19]));
8902  break;
8903  }
8904 
8906  {
8908  //
8909  // RefinementCase<dim>::cut_xyz
8910  // isotropic refinement
8911  //
8912  // the refined cube will look
8913  // like this:
8914  //
8915  // *----*----*
8916  // / / /|
8917  // *----*----* |
8918  // / / /| *
8919  // *----*----* |/|
8920  // | | | * |
8921  // | | |/| *
8922  // *----*----* |/
8923  // | | | *
8924  // | | |/
8925  // *----*----*
8926  //
8927 
8928  // find the next unused vertex and set it
8929  // appropriately
8930  while (
8931  triangulation.vertices_used[next_unused_vertex] ==
8932  true)
8933  ++next_unused_vertex;
8934  Assert(
8935  next_unused_vertex < triangulation.vertices.size(),
8936  ExcMessage(
8937  "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."));
8938  triangulation.vertices_used[next_unused_vertex] =
8939  true;
8940 
8941  // the new vertex is definitely in the interior,
8942  // so we need not worry about the
8943  // boundary. However we need to worry about
8944  // Manifolds. Let the cell compute its own
8945  // center, by querying the underlying manifold
8946  // object.
8947  triangulation.vertices[next_unused_vertex] =
8948  hex->center(true, true);
8949 
8950  // set the data of the six lines. first collect
8951  // the indices of the seven vertices (consider
8952  // the two planes to be crossed to form the
8953  // planes cutting the hex in two vertically and
8954  // horizontally)
8955  //
8956  // *--3--* *--5--*
8957  // / / / | | |
8958  // 0--6--1 0--6--1
8959  // / / / | | |
8960  // *--2--* *--4--*
8961  // the lines are numbered
8962  // as follows:
8963  // *--*--* *--*--*
8964  // / 1 / | 5 |
8965  // *2-*-3* *2-*-3*
8966  // / 0 / | 4 |
8967  // *--*--* *--*--*
8968  //
8969  const unsigned int vertex_indices[7] = {
8970  middle_vertex_index<dim, spacedim>(hex->face(0)),
8971  middle_vertex_index<dim, spacedim>(hex->face(1)),
8972  middle_vertex_index<dim, spacedim>(hex->face(2)),
8973  middle_vertex_index<dim, spacedim>(hex->face(3)),
8974  middle_vertex_index<dim, spacedim>(hex->face(4)),
8975  middle_vertex_index<dim, spacedim>(hex->face(5)),
8976  next_unused_vertex};
8977 
8978  new_lines[0]->set(
8980  1>(vertex_indices[2], vertex_indices[6]));
8981  new_lines[1]->set(
8983  1>(vertex_indices[6], vertex_indices[3]));
8984  new_lines[2]->set(
8986  1>(vertex_indices[0], vertex_indices[6]));
8987  new_lines[3]->set(
8989  1>(vertex_indices[6], vertex_indices[1]));
8990  new_lines[4]->set(
8992  1>(vertex_indices[4], vertex_indices[6]));
8993  new_lines[5]->set(
8995  1>(vertex_indices[6], vertex_indices[5]));
8996 
8997  // again, first collect some data about the
8998  // indices of the lines, with the following
8999  // numbering: (note that face 0 and 1 each are
9000  // shown twice for better readability)
9001 
9002  // face 0: left plane
9003  // * *
9004  // /| /|
9005  // * | * |
9006  // /| * /| *
9007  // * 1/| * |3|
9008  // | * | | * |
9009  // |/| * |2| *
9010  // * 0/ * |/
9011  // | * | *
9012  // |/ |/
9013  // * *
9014  // face 1: right plane
9015  // * *
9016  // /| /|
9017  // * | * |
9018  // /| * /| *
9019  // * 5/| * |7|
9020  // | * | | * |
9021  // |/| * |6| *
9022  // * 4/ * |/
9023  // | * | *
9024  // |/ |/
9025  // * *
9026  // face 2: front plane
9027  // (note: x,y exchanged)
9028  // *---*---*
9029  // | 11 |
9030  // *-8-*-9-*
9031  // | 10 |
9032  // *---*---*
9033  // face 3: back plane
9034  // (note: x,y exchanged)
9035  // *---*---*
9036  // | 15 |
9037  // *12-*-13*
9038  // | 14 |
9039  // *---*---*
9040  // face 4: bottom plane
9041  // *---*---*
9042  // / 17 /
9043  // *18-*-19*
9044  // / 16 /
9045  // *---*---*
9046  // face 5: top plane
9047  // *---*---*
9048  // / 21 /
9049  // *22-*-23*
9050  // / 20 /
9051  // *---*---*
9052  // middle planes
9053  // *---*---* *---*---*
9054  // / 25 / | 29 |
9055  // *26-*-27* *26-*-27*
9056  // / 24 / | 28 |
9057  // *---*---* *---*---*
9058 
9059  // set up a list of line iterators first. from
9060  // this, construct lists of line_indices and
9061  // line orientations later on
9062  const typename Triangulation<
9063  dim,
9064  spacedim>::raw_line_iterator lines[30] = {
9065  hex->face(0)
9066  ->isotropic_child(
9068  0, f_or[0], f_fl[0], f_ro[0]))
9069  ->line(
9071  1, f_or[0], f_fl[0], f_ro[0])), // 0
9072  hex->face(0)
9073  ->isotropic_child(
9075  3, f_or[0], f_fl[0], f_ro[0]))
9076  ->line(
9078  0, f_or[0], f_fl[0], f_ro[0])), // 1
9079  hex->face(0)
9080  ->isotropic_child(
9082  0, f_or[0], f_fl[0], f_ro[0]))
9083  ->line(
9085  3, f_or[0], f_fl[0], f_ro[0])), // 2
9086  hex->face(0)
9087  ->isotropic_child(
9089  3, f_or[0], f_fl[0], f_ro[0]))
9090  ->line(
9092  2, f_or[0], f_fl[0], f_ro[0])), // 3
9093 
9094  hex->face(1)
9095  ->isotropic_child(
9097  0, f_or[1], f_fl[1], f_ro[1]))
9098  ->line(
9100  1, f_or[1], f_fl[1], f_ro[1])), // 4
9101  hex->face(1)
9102  ->isotropic_child(
9104  3, f_or[1], f_fl[1], f_ro[1]))
9105  ->line(
9107  0, f_or[1], f_fl[1], f_ro[1])), // 5
9108  hex->face(1)
9109  ->isotropic_child(
9111  0, f_or[1], f_fl[1], f_ro[1]))
9112  ->line(
9114  3, f_or[1], f_fl[1], f_ro[1])), // 6
9115  hex->face(1)
9116  ->isotropic_child(
9118  3, f_or[1], f_fl[1], f_ro[1]))
9119  ->line(
9121  2, f_or[1], f_fl[1], f_ro[1])), // 7
9122 
9123  hex->face(2)
9124  ->isotropic_child(
9126  0, f_or[2], f_fl[2], f_ro[2]))
9127  ->line(
9129  1, f_or[2], f_fl[2], f_ro[2])), // 8
9130  hex->face(2)
9131  ->isotropic_child(
9133  3, f_or[2], f_fl[2], f_ro[2]))
9134  ->line(
9136  0, f_or[2], f_fl[2], f_ro[2])), // 9
9137  hex->face(2)
9138  ->isotropic_child(
9140  0, f_or[2], f_fl[2], f_ro[2]))
9141  ->line(
9143  3, f_or[2], f_fl[2], f_ro[2])), // 10
9144  hex->face(2)
9145  ->isotropic_child(
9147  3, f_or[2], f_fl[2], f_ro[2]))
9148  ->line(
9150  2, f_or[2], f_fl[2], f_ro[2])), // 11
9151 
9152  hex->face(3)
9153  ->isotropic_child(
9155  0, f_or[3], f_fl[3], f_ro[3]))
9156  ->line(
9158  1, f_or[3], f_fl[3], f_ro[3])), // 12
9159  hex->face(3)
9160  ->isotropic_child(
9162  3, f_or[3], f_fl[3], f_ro[3]))
9163  ->line(
9165  0, f_or[3], f_fl[3], f_ro[3])), // 13
9166  hex->face(3)
9167  ->isotropic_child(
9169  0, f_or[3], f_fl[3], f_ro[3]))
9170  ->line(
9172  3, f_or[3], f_fl[3], f_ro[3])), // 14
9173  hex->face(3)
9174  ->isotropic_child(
9176  3, f_or[3], f_fl[3], f_ro[3]))
9177  ->line(
9179  2, f_or[3], f_fl[3], f_ro[3])), // 15
9180 
9181  hex->face(4)
9182  ->isotropic_child(
9184  0, f_or[4], f_fl[4], f_ro[4]))
9185  ->line(
9187  1, f_or[4], f_fl[4], f_ro[4])), // 16
9188  hex->face(4)
9189  ->isotropic_child(
9191  3, f_or[4], f_fl[4], f_ro[4]))
9192  ->line(
9194  0, f_or[4], f_fl[4], f_ro[4])), // 17
9195  hex->face(4)
9196  ->isotropic_child(
9198  0, f_or[4], f_fl[4], f_ro[4]))
9199  ->line(
9201  3, f_or[4], f_fl[4], f_ro[4])), // 18
9202  hex->face(4)
9203  ->isotropic_child(
9205  3, f_or[4], f_fl[4], f_ro[4]))
9206  ->line(
9208  2, f_or[4], f_fl[4], f_ro[4])), // 19
9209 
9210  hex->face(5)
9211  ->isotropic_child(
9213  0, f_or[5], f_fl[5], f_ro[5]))
9214  ->line(
9216  1, f_or[5], f_fl[5], f_ro[5])), // 20
9217  hex->face(5)
9218  ->isotropic_child(
9220  3, f_or[5], f_fl[5], f_ro[5]))
9221  ->line(
9223  0, f_or[5], f_fl[5], f_ro[5])), // 21
9224  hex->face(5)
9225  ->isotropic_child(
9227  0, f_or[5], f_fl[5], f_ro[5]))
9228  ->line(
9230  3, f_or[5], f_fl[5], f_ro[5])), // 22
9231  hex->face(5)
9232  ->isotropic_child(
9234  3, f_or[5], f_fl[5], f_ro[5]))
9235  ->line(
9237  2, f_or[5], f_fl[5], f_ro[5])), // 23
9238 
9239  new_lines[0], // 24
9240  new_lines[1], // 25
9241  new_lines[2], // 26
9242  new_lines[3], // 27
9243  new_lines[4], // 28
9244  new_lines[5] // 29
9245  };
9246 
9247  unsigned int line_indices[30];
9248  for (unsigned int i = 0; i < 30; ++i)
9249  line_indices[i] = lines[i]->index();
9250 
9251  // the orientation of lines for the inner quads
9252  // is quite tricky. as these lines are newly
9253  // created ones and thus have no parents, they
9254  // cannot inherit this property. set up an array
9255  // and fill it with the respective values
9256  bool line_orientation[30];
9257 
9258  // note: for the first 24 lines (inner lines of
9259  // the outer quads) the following holds: the
9260  // second vertex of the even lines in standard
9261  // orientation is the vertex in the middle of
9262  // the quad, whereas for odd lines the first
9263  // vertex is the same middle vertex.
9264  for (unsigned int i = 0; i < 24; ++i)
9265  if (lines[i]->vertex_index((i + 1) % 2) ==
9266  vertex_indices[i / 4])
9267  line_orientation[i] = true;
9268  else
9269  {
9270  // it must be the other way
9271  // round then
9272  Assert(lines[i]->vertex_index(i % 2) ==
9273  vertex_indices[i / 4],
9274  ExcInternalError());
9275  line_orientation[i] = false;
9276  }
9277  // for the last 6 lines the line orientation is
9278  // always true, since they were just constructed
9279  // that way
9280  for (unsigned int i = 24; i < 30; ++i)
9281  line_orientation[i] = true;
9282 
9283  // set up the 12 quads, numbered as follows
9284  // (left quad numbering, right line numbering
9285  // extracted from above)
9286  //
9287  // * *
9288  // /| 21|
9289  // * | * 15
9290  // y/|3* 20| *
9291  // * |/| * |/|
9292  // |2* |x 11 * 14
9293  // |/|1* |/| *
9294  // * |/ * |17
9295  // |0* 10 *
9296  // |/ |16
9297  // * *
9298  //
9299  // x
9300  // *---*---* *22-*-23*
9301  // | 5 | 7 | 1 29 5
9302  // *---*---* *26-*-27*
9303  // | 4 | 6 | 0 28 4
9304  // *---*---*y *18-*-19*
9305  //
9306  // y
9307  // *----*----* *-12-*-13-*
9308  // / 10 / 11 / 3 25 7
9309  // *----*----* *-26-*-27-*
9310  // / 8 / 9 / 2 24 6
9311  // *----*----*x *--8-*--9-*
9312 
9313  new_quads[0]->set(
9315  2>(line_indices[10],
9316  line_indices[28],
9317  line_indices[16],
9318  line_indices[24]));
9319  new_quads[1]->set(
9321  2>(line_indices[28],
9322  line_indices[14],
9323  line_indices[17],
9324  line_indices[25]));
9325  new_quads[2]->set(
9327  2>(line_indices[11],
9328  line_indices[29],
9329  line_indices[24],
9330  line_indices[20]));
9331  new_quads[3]->set(
9333  2>(line_indices[29],
9334  line_indices[15],
9335  line_indices[25],
9336  line_indices[21]));
9337  new_quads[4]->set(
9339  2>(line_indices[18],
9340  line_indices[26],
9341  line_indices[0],
9342  line_indices[28]));
9343  new_quads[5]->set(
9345  2>(line_indices[26],
9346  line_indices[22],
9347  line_indices[1],
9348  line_indices[29]));
9349  new_quads[6]->set(
9351  2>(line_indices[19],
9352  line_indices[27],
9353  line_indices[28],
9354  line_indices[4]));
9355  new_quads[7]->set(
9357  2>(line_indices[27],
9358  line_indices[23],
9359  line_indices[29],
9360  line_indices[5]));
9361  new_quads[8]->set(
9363  2>(line_indices[2],
9364  line_indices[24],
9365  line_indices[8],
9366  line_indices[26]));
9367  new_quads[9]->set(
9369  2>(line_indices[24],
9370  line_indices[6],
9371  line_indices[9],
9372  line_indices[27]));
9373  new_quads[10]->set(
9375  2>(line_indices[3],
9376  line_indices[25],
9377  line_indices[26],
9378  line_indices[12]));
9379  new_quads[11]->set(
9381  2>(line_indices[25],
9382  line_indices[7],
9383  line_indices[27],
9384  line_indices[13]));
9385 
9386  // now reset the line_orientation flags of outer
9387  // lines as they cannot be set in a loop (at
9388  // least not easily)
9389  new_quads[0]->set_line_orientation(
9390  0, line_orientation[10]);
9391  new_quads[0]->set_line_orientation(
9392  2, line_orientation[16]);
9393 
9394  new_quads[1]->set_line_orientation(
9395  1, line_orientation[14]);
9396  new_quads[1]->set_line_orientation(
9397  2, line_orientation[17]);
9398 
9399  new_quads[2]->set_line_orientation(
9400  0, line_orientation[11]);
9401  new_quads[2]->set_line_orientation(
9402  3, line_orientation[20]);
9403 
9404  new_quads[3]->set_line_orientation(
9405  1, line_orientation[15]);
9406  new_quads[3]->set_line_orientation(
9407  3, line_orientation[21]);
9408 
9409  new_quads[4]->set_line_orientation(
9410  0, line_orientation[18]);
9411  new_quads[4]->set_line_orientation(
9412  2, line_orientation[0]);
9413 
9414  new_quads[5]->set_line_orientation(
9415  1, line_orientation[22]);
9416  new_quads[5]->set_line_orientation(
9417  2, line_orientation[1]);
9418 
9419  new_quads[6]->set_line_orientation(
9420  0, line_orientation[19]);
9421  new_quads[6]->set_line_orientation(
9422  3, line_orientation[4]);
9423 
9424  new_quads[7]->set_line_orientation(
9425  1, line_orientation[23]);
9426  new_quads[7]->set_line_orientation(
9427  3, line_orientation[5]);
9428 
9429  new_quads[8]->set_line_orientation(
9430  0, line_orientation[2]);
9431  new_quads[8]->set_line_orientation(
9432  2, line_orientation[8]);
9433 
9434  new_quads[9]->set_line_orientation(
9435  1, line_orientation[6]);
9436  new_quads[9]->set_line_orientation(
9437  2, line_orientation[9]);
9438 
9439  new_quads[10]->set_line_orientation(
9440  0, line_orientation[3]);
9441  new_quads[10]->set_line_orientation(
9442  3, line_orientation[12]);
9443 
9444  new_quads[11]->set_line_orientation(
9445  1, line_orientation[7]);
9446  new_quads[11]->set_line_orientation(
9447  3, line_orientation[13]);
9448 
9450  // create the eight new hexes
9451  //
9452  // again first collect some data. here, we need
9453  // the indices of a whole lotta quads.
9454 
9455  // the quads are numbered as follows:
9456  //
9457  // planes in the interior of the old hex:
9458  //
9459  // *
9460  // /|
9461  // * |
9462  // /|3* *---*---* *----*----*
9463  // * |/| | 5 | 7 | / 10 / 11 /
9464  // |2* | *---*---* *----*----*
9465  // |/|1* | 4 | 6 | / 8 / 9 /
9466  // * |/ *---*---*y *----*----*x
9467  // |0*
9468  // |/
9469  // *
9470  //
9471  // children of the faces
9472  // of the old hex
9473  // *-------* *-------*
9474  // /|25 27| /34 35/|
9475  // 15| | / /19
9476  // / | | /32 33/ |
9477  // * |24 26| *-------*18 |
9478  // 1413*-------* |21 23| 17*
9479  // | /30 31/ | | /
9480  // 12/ / | |16
9481  // |/28 29/ |20 22|/
9482  // *-------* *-------*
9483  //
9484  // note that we have to
9485  // take care of the
9486  // orientation of
9487  // faces.
9488  const int quad_indices[36] = {
9489  new_quads[0]->index(), // 0
9490  new_quads[1]->index(),
9491  new_quads[2]->index(),
9492  new_quads[3]->index(),
9493  new_quads[4]->index(),
9494  new_quads[5]->index(),
9495  new_quads[6]->index(),
9496  new_quads[7]->index(),
9497  new_quads[8]->index(),
9498  new_quads[9]->index(),
9499  new_quads[10]->index(),
9500  new_quads[11]->index(), // 11
9501 
9502  hex->face(0)->isotropic_child_index(
9504  0, f_or[0], f_fl[0], f_ro[0])), // 12
9505  hex->face(0)->isotropic_child_index(
9507  1, f_or[0], f_fl[0], f_ro[0])),
9508  hex->face(0)->isotropic_child_index(
9510  2, f_or[0], f_fl[0], f_ro[0])),
9511  hex->face(0)->isotropic_child_index(
9513  3, f_or[0], f_fl[0], f_ro[0])),
9514 
9515  hex->face(1)->isotropic_child_index(
9517  0, f_or[1], f_fl[1], f_ro[1])), // 16
9518  hex->face(1)->isotropic_child_index(
9520  1, f_or[1], f_fl[1], f_ro[1])),
9521  hex->face(1)->isotropic_child_index(
9523  2, f_or[1], f_fl[1], f_ro[1])),
9524  hex->face(1)->isotropic_child_index(
9526  3, f_or[1], f_fl[1], f_ro[1])),
9527 
9528  hex->face(2)->isotropic_child_index(
9530  0, f_or[2], f_fl[2], f_ro[2])), // 20
9531  hex->face(2)->isotropic_child_index(
9533  1, f_or[2], f_fl[2], f_ro[2])),
9534  hex->face(2)->isotropic_child_index(
9536  2, f_or[2], f_fl[2], f_ro[2])),
9537  hex->face(2)->isotropic_child_index(
9539  3, f_or[2], f_fl[2], f_ro[2])),
9540 
9541  hex->face(3)->isotropic_child_index(
9543  0, f_or[3], f_fl[3], f_ro[3])), // 24
9544  hex->face(3)->isotropic_child_index(
9546  1, f_or[3], f_fl[3], f_ro[3])),
9547  hex->face(3)->isotropic_child_index(
9549  2, f_or[3], f_fl[3], f_ro[3])),
9550  hex->face(3)->isotropic_child_index(
9552  3, f_or[3], f_fl[3], f_ro[3])),
9553 
9554  hex->face(4)->isotropic_child_index(
9556  0, f_or[4], f_fl[4], f_ro[4])), // 28
9557  hex->face(4)->isotropic_child_index(
9559  1, f_or[4], f_fl[4], f_ro[4])),
9560  hex->face(4)->isotropic_child_index(
9562  2, f_or[4], f_fl[4], f_ro[4])),
9563  hex->face(4)->isotropic_child_index(
9565  3, f_or[4], f_fl[4], f_ro[4])),
9566 
9567  hex->face(5)->isotropic_child_index(
9569  0, f_or[5], f_fl[5], f_ro[5])), // 32
9570  hex->face(5)->isotropic_child_index(
9572  1, f_or[5], f_fl[5], f_ro[5])),
9573  hex->face(5)->isotropic_child_index(
9575  2, f_or[5], f_fl[5], f_ro[5])),
9576  hex->face(5)->isotropic_child_index(
9578  3, f_or[5], f_fl[5], f_ro[5]))};
9579 
9580  // bottom children
9581  new_hexes[0]->set(
9583  3>(quad_indices[12],
9584  quad_indices[0],
9585  quad_indices[20],
9586  quad_indices[4],
9587  quad_indices[28],
9588  quad_indices[8]));
9589  new_hexes[1]->set(
9591  3>(quad_indices[0],
9592  quad_indices[16],
9593  quad_indices[22],
9594  quad_indices[6],
9595  quad_indices[29],
9596  quad_indices[9]));
9597  new_hexes[2]->set(
9599  3>(quad_indices[13],
9600  quad_indices[1],
9601  quad_indices[4],
9602  quad_indices[24],
9603  quad_indices[30],
9604  quad_indices[10]));
9605  new_hexes[3]->set(
9607  3>(quad_indices[1],
9608  quad_indices[17],
9609  quad_indices[6],
9610  quad_indices[26],
9611  quad_indices[31],
9612  quad_indices[11]));
9613 
9614  // top children
9615  new_hexes[4]->set(
9617  3>(quad_indices[14],
9618  quad_indices[2],
9619  quad_indices[21],
9620  quad_indices[5],
9621  quad_indices[8],
9622  quad_indices[32]));
9623  new_hexes[5]->set(
9625  3>(quad_indices[2],
9626  quad_indices[18],
9627  quad_indices[23],
9628  quad_indices[7],
9629  quad_indices[9],
9630  quad_indices[33]));
9631  new_hexes[6]->set(
9633  3>(quad_indices[15],
9634  quad_indices[3],
9635  quad_indices[5],
9636  quad_indices[25],
9637  quad_indices[10],
9638  quad_indices[34]));
9639  new_hexes[7]->set(
9641  3>(quad_indices[3],
9642  quad_indices[19],
9643  quad_indices[7],
9644  quad_indices[27],
9645  quad_indices[11],
9646  quad_indices[35]));
9647  break;
9648  }
9649  default:
9650  // all refinement cases have been treated, there
9651  // only remains
9652  // RefinementCase<dim>::no_refinement as
9653  // untreated enumeration value. However, in that
9654  // case we should have aborted much
9655  // earlier. thus we should never get here
9656  Assert(false, ExcInternalError());
9657  break;
9658  } // switch (ref_case)
9659 
9660  // and set face orientation flags. note that new
9661  // faces in the interior of the mother cell always
9662  // have a correctly oriented face, but the ones on
9663  // the outer faces will inherit this flag
9664  //
9665  // the flag have been set to true for all faces
9666  // initially, now go the other way round and reset
9667  // faces that are at the boundary of the mother cube
9668  //
9669  // the same is true for the face_flip and
9670  // face_rotation flags. however, the latter two are
9671  // set to false by default as this is the standard
9672  // value
9673 
9674  // loop over all faces and all (relevant) subfaces
9675  // of that in order to set the correct values for
9676  // face_orientation, face_flip and face_rotation,
9677  // which are inherited from the corresponding face
9678  // of the mother cube
9679  for (unsigned int f = 0;
9680  f < GeometryInfo<dim>::faces_per_cell;
9681  ++f)
9682  for (unsigned int s = 0;
9683  s < std::max(GeometryInfo<dim - 1>::n_children(
9685  ref_case, f)),
9686  1U);
9687  ++s)
9688  {
9689  const unsigned int current_child =
9691  ref_case,
9692  f,
9693  s,
9694  f_or[f],
9695  f_fl[f],
9696  f_ro[f],
9698  ref_case, f, f_or[f], f_fl[f], f_ro[f]));
9699  new_hexes[current_child]->set_face_orientation(f,
9700  f_or[f]);
9701  new_hexes[current_child]->set_face_flip(f, f_fl[f]);
9702  new_hexes[current_child]->set_face_rotation(f, f_ro[f]);
9703  }
9704 
9705  // now see if we have created cells that are
9706  // distorted and if so add them to our list
9707  if ((check_for_distorted_cells == true) &&
9708  has_distorted_children(
9709  hex,
9710  std::integral_constant<int, dim>(),
9711  std::integral_constant<int, spacedim>()))
9712  cells_with_distorted_children.distorted_cells.push_back(
9713  hex);
9714 
9715  // note that the refinement flag was already cleared
9716  // at the beginning of this loop
9717 
9718  // inform all listeners that cell refinement is done
9719  triangulation.signals.post_refinement_on_cell(hex);
9720  }
9721  }
9722 
9723  // clear user data on quads. we used some of this data to
9724  // indicate anisotropic refinemnt cases on faces. all data
9725  // should be cleared by now, but the information whether we
9726  // used indices or pointers is still present. reset it now to
9727  // enable the user to use whichever he likes later on.
9728  triangulation.faces->quads.clear_user_data();
9729 
9730  // return the list with distorted children
9731  return cells_with_distorted_children;
9732  }
9733 
9734 
9747  template <int spacedim>
9748  static void
9749  prevent_distorted_boundary_cells(const Triangulation<1, spacedim> &);
9750 
9751 
9752  template <int dim, int spacedim>
9753  static void
9754  prevent_distorted_boundary_cells(
9755  Triangulation<dim, spacedim> &triangulation)
9756  {
9757  // If the codimension is one, we cannot perform this check
9758  // yet.
9759  if (spacedim > dim)
9760  return;
9761 
9762  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
9763  triangulation.begin();
9764  cell != triangulation.end();
9765  ++cell)
9766  if (cell->at_boundary() && cell->refine_flag_set() &&
9767  cell->refine_flag_set() !=
9769  {
9770  // The cell is at the boundary and it is flagged for
9771  // anisotropic refinement. Therefore, we have a closer
9772  // look
9773  const RefinementCase<dim> ref_case = cell->refine_flag_set();
9774  for (unsigned int face_no = 0;
9775  face_no < GeometryInfo<dim>::faces_per_cell;
9776  ++face_no)
9777  if (cell->face(face_no)->at_boundary())
9778  {
9779  // this is the critical face at the boundary.
9781  face_no) !=
9782  RefinementCase<dim - 1>::isotropic_refinement)
9783  {
9784  // up to now, we do not want to refine this
9785  // cell along the face under consideration
9786  // here.
9787  const typename Triangulation<dim,
9788  spacedim>::face_iterator
9789  face = cell->face(face_no);
9790  // the new point on the boundary would be this
9791  // one.
9792  const Point<spacedim> new_bound = face->center(true);
9793  // to check it, transform to the unit cell
9794  // with Q1Mapping
9795  const Point<dim> new_unit =
9797  .transform_real_to_unit_cell(cell, new_bound);
9798 
9799  // Now, we have to calculate the distance from
9800  // the face in the unit cell.
9801 
9802  // take the correct coordinate direction (0
9803  // for faces 0 and 1, 1 for faces 2 and 3, 2
9804  // for faces 4 and 5) and subtract the correct
9805  // boundary value of the face (0 for faces 0,
9806  // 2, and 4; 1 for faces 1, 3 and 5)
9807  const double dist =
9808  std::fabs(new_unit[face_no / 2] - face_no % 2);
9809 
9810  // compare this with the empirical value
9811  // allowed. if it is too big, flag the face
9812  // for isotropic refinement
9813  const double allowed = 0.25;
9814 
9815  if (dist > allowed)
9816  cell->flag_for_face_refinement(face_no);
9817  } // if flagged for anistropic refinement
9818  } // if (cell->face(face)->at_boundary())
9819  } // for all cells
9820  }
9821 
9822 
9835  template <int dim, int spacedim>
9836  static void
9838  {
9839  Assert(dim < 3,
9840  ExcMessage("Wrong function called -- there should "
9841  "be a specialization."));
9842  }
9843 
9844 
9845  template <int spacedim>
9846  static void prepare_refinement_dim_dependent(
9847  Triangulation<3, spacedim> &triangulation)
9848  {
9849  const unsigned int dim = 3;
9850 
9851  // first clear flags on lines, since we need them to determine
9852  // which lines will be refined
9853  triangulation.clear_user_flags_line();
9854 
9855  // also clear flags on hexes, since we need them to mark those
9856  // cells which are to be coarsened
9857  triangulation.clear_user_flags_hex();
9858 
9859  // variable to store whether the mesh was changed in the
9860  // present loop and in the whole process
9861  bool mesh_changed = false;
9862 
9863  do
9864  {
9865  mesh_changed = false;
9866 
9867  // for this following, we need to know which cells are
9868  // going to be coarsened, if we had to make a
9869  // decision. the following function sets these flags:
9870  triangulation.fix_coarsen_flags();
9871 
9872 
9873  // flag those lines that are refined and will not be
9874  // coarsened and those that will be refined
9875  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
9876  triangulation.begin();
9877  cell != triangulation.end();
9878  ++cell)
9879  if (cell->refine_flag_set())
9880  {
9881  for (unsigned int line = 0;
9882  line < GeometryInfo<dim>::lines_per_cell;
9883  ++line)
9885  cell->refine_flag_set(), line) ==
9887  // flag a line, that will be
9888  // refined
9889  cell->line(line)->set_user_flag();
9890  }
9891  else if (cell->has_children() &&
9892  !cell->child(0)->coarsen_flag_set())
9893  {
9894  for (unsigned int line = 0;
9895  line < GeometryInfo<dim>::lines_per_cell;
9896  ++line)
9898  cell->refinement_case(), line) ==
9900  // flag a line, that is refined
9901  // and will stay so
9902  cell->line(line)->set_user_flag();
9903  }
9904  else if (cell->has_children() &&
9905  cell->child(0)->coarsen_flag_set())
9906  cell->set_user_flag();
9907 
9908 
9909  // now check whether there are cells with lines that are
9910  // more than once refined or that will be more than once
9911  // refined. The first thing should never be the case, in
9912  // the second case we flag the cell for refinement
9914  cell = triangulation.last_active();
9915  cell != triangulation.end();
9916  --cell)
9917  for (unsigned int line = 0;
9918  line < GeometryInfo<dim>::lines_per_cell;
9919  ++line)
9920  {
9921  if (cell->line(line)->has_children())
9922  {
9923  // if this line is refined, its children should
9924  // not have further children
9925  //
9926  // however, if any of the children is flagged
9927  // for further refinement, we need to refine
9928  // this cell also (at least, if the cell is not
9929  // already flagged)
9930  bool offending_line_found = false;
9931 
9932  for (unsigned int c = 0; c < 2; ++c)
9933  {
9934  Assert(cell->line(line)->child(c)->has_children() ==
9935  false,
9936  ExcInternalError());
9937 
9938  if (cell->line(line)->child(c)->user_flag_set() &&
9940  cell->refine_flag_set(), line) ==
9942  {
9943  // tag this cell for refinement
9944  cell->clear_coarsen_flag();
9945  // if anisotropic coarsening is allowed:
9946  // extend the refine_flag in the needed
9947  // direction, else set refine_flag
9948  // (isotropic)
9949  if (triangulation.smooth_grid &
9951  allow_anisotropic_smoothing)
9952  cell->flag_for_line_refinement(line);
9953  else
9954  cell->set_refine_flag();
9955 
9956  for (unsigned int l = 0;
9957  l < GeometryInfo<dim>::lines_per_cell;
9958  ++l)
9960  cell->refine_flag_set(), line) ==
9962  // flag a line, that will be refined
9963  cell->line(l)->set_user_flag();
9964 
9965  // note that we have changed the grid
9966  offending_line_found = true;
9967 
9968  // it may save us several loop
9969  // iterations if we flag all lines of
9970  // this cell now (and not at the outset
9971  // of the next iteration) for refinement
9972  for (unsigned int l = 0;
9973  l < GeometryInfo<dim>::lines_per_cell;
9974  ++l)
9975  if (!cell->line(l)->has_children() &&
9977  cell->refine_flag_set(), l) !=
9979  cell->line(l)->set_user_flag();
9980 
9981  break;
9982  }
9983  }
9984 
9985  if (offending_line_found)
9986  {
9987  mesh_changed = true;
9988  break;
9989  }
9990  }
9991  }
9992 
9993 
9994  // there is another thing here: if any of the lines will
9995  // be refined, then we may not coarsen the present cell
9996  // similarly, if any of the lines *is* already refined, we
9997  // may not coarsen the current cell. however, there's a
9998  // catch: if the line is refined, but the cell behind it
9999  // is going to be coarsened, then the situation
10000  // changes. if we forget this second condition, the
10001  // refine_and_coarsen_3d test will start to fail. note
10002  // that to know which cells are going to be coarsened, the
10003  // call for fix_coarsen_flags above is necessary
10004  for (typename Triangulation<dim, spacedim>::cell_iterator cell =
10005  triangulation.last();
10006  cell != triangulation.end();
10007  --cell)
10008  {
10009  if (cell->user_flag_set())
10010  for (unsigned int line = 0;
10011  line < GeometryInfo<dim>::lines_per_cell;
10012  ++line)
10013  if (cell->line(line)->has_children() &&
10014  (cell->line(line)->child(0)->user_flag_set() ||
10015  cell->line(line)->child(1)->user_flag_set()))
10016  {
10017  for (unsigned int c = 0; c < cell->n_children(); ++c)
10018  cell->child(c)->clear_coarsen_flag();
10019  cell->clear_user_flag();
10020  for (unsigned int l = 0;
10021  l < GeometryInfo<dim>::lines_per_cell;
10022  ++l)
10024  cell->refinement_case(), l) ==
10026  // flag a line, that is refined
10027  // and will stay so
10028  cell->line(l)->set_user_flag();
10029  mesh_changed = true;
10030  break;
10031  }
10032  }
10033  }
10034  while (mesh_changed == true);
10035  }
10036 
10037 
10038 
10045  template <int dim, int spacedim>
10046  static bool
10048  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
10049  {
10050  // in 1d, coarsening is always allowed since we don't enforce
10051  // the 2:1 constraint there
10052  if (dim == 1)
10053  return true;
10054 
10055  const RefinementCase<dim> ref_case = cell->refinement_case();
10056  for (unsigned int n = 0; n < GeometryInfo<dim>::faces_per_cell; ++n)
10057  {
10058  // if the cell is not refined along that face, coarsening
10059  // will not change anything, so do nothing. the same
10060  // applies, if the face is at the boandary
10061  const RefinementCase<dim - 1> face_ref_case =
10062  GeometryInfo<dim>::face_refinement_case(cell->refinement_case(),
10063  n);
10064 
10065  const unsigned int n_subfaces =
10066  GeometryInfo<dim - 1>::n_children(face_ref_case);
10067 
10068  if (n_subfaces == 0 || cell->at_boundary(n))
10069  continue;
10070  for (unsigned int c = 0; c < n_subfaces; ++c)
10071  {
10073  child = cell->child(
10074  GeometryInfo<dim>::child_cell_on_face(ref_case, n, c));
10075 
10077  child_neighbor = child->neighbor(n);
10078  if (!child->neighbor_is_coarser(n))
10079  // in 2d, if the child's neighbor is coarser, then
10080  // it has no children. however, in 3d it might be
10081  // otherwise. consider for example, that our face
10082  // might be refined with cut_x, but the neighbor is
10083  // refined with cut_xy at that face. then the
10084  // neighbor pointers of the children of our cell
10085  // will point to the common neighbor cell, not to
10086  // its children. what we really want to know in the
10087  // following is, whether the neighbor cell is
10088  // refined twice with reference to our cell. that
10089  // only has to be asked, if the child's neighbor is
10090  // not a coarser one.
10091  if ((child_neighbor->has_children() &&
10092  !child_neighbor->user_flag_set()) ||
10093  // neighbor has children, which are further
10094  // refined along the face, otherwise something
10095  // went wrong in the construction of neighbor
10096  // pointers. then only allow coarsening if this
10097  // neighbor will be coarsened as well
10098  // (user_pointer is set). the same applies, if
10099  // the neighbors children are not refined but
10100  // will be after refinement
10101  child_neighbor->refine_flag_set())
10102  return false;
10103  }
10104  }
10105  return true;
10106  }
10107  };
10108 
10109 
10110 
10111  template <int dim, int spacedim>
10112  const Manifold<dim, spacedim> &
10113  get_default_flat_manifold()
10114  {
10115  static const FlatManifold<dim, spacedim> flat_manifold;
10116  return flat_manifold;
10117  }
10118  } // namespace TriangulationImplementation
10119 } // namespace internal
10120 
10121 
10122 
10123 template <int dim, int spacedim>
10124 const unsigned int Triangulation<dim, spacedim>::dimension;
10125 
10126 
10127 
10128 template <int dim, int spacedim>
10130  const MeshSmoothing smooth_grid,
10131  const bool check_for_distorted_cells)
10132  : smooth_grid(smooth_grid)
10133  , anisotropic_refinement(false)
10134  , check_for_distorted_cells(check_for_distorted_cells)
10135 {
10136  if (dim == 1)
10137  {
10139  std_cxx14::make_unique<std::map<unsigned int, types::boundary_id>>();
10141  std_cxx14::make_unique<std::map<unsigned int, types::manifold_id>>();
10142  }
10143 
10144  // connect the any_change signal to the other top level signals
10145  signals.create.connect(signals.any_change);
10147  signals.clear.connect(signals.any_change);
10149 }
10150 
10151 
10152 
10153 template <int dim, int spacedim>
10155  Triangulation<dim, spacedim> &&tria) noexcept
10156  : Subscriptor(std::move(tria))
10157  , smooth_grid(tria.smooth_grid)
10159  , periodic_face_map(std::move(tria.periodic_face_map))
10160  , levels(std::move(tria.levels))
10161  , faces(std::move(tria.faces))
10162  , vertices(std::move(tria.vertices))
10163  , vertices_used(std::move(tria.vertices_used))
10164  , manifold(std::move(tria.manifold))
10167  , number_cache(std::move(tria.number_cache))
10170 {
10172 }
10173 
10174 
10175 template <int dim, int spacedim>
10179 {
10180  Subscriptor::operator=(std::move(tria));
10181 
10182  smooth_grid = tria.smooth_grid;
10183  periodic_face_pairs_level_0 = std::move(tria.periodic_face_pairs_level_0);
10184  periodic_face_map = std::move(tria.periodic_face_map);
10185  levels = std::move(tria.levels);
10186  faces = std::move(tria.faces);
10187  vertices = std::move(tria.vertices);
10188  vertices_used = std::move(tria.vertices_used);
10189  manifold = std::move(tria.manifold);
10190  anisotropic_refinement = tria.anisotropic_refinement;
10191  number_cache = tria.number_cache;
10192  vertex_to_boundary_id_map_1d = std::move(tria.vertex_to_boundary_id_map_1d);
10193  vertex_to_manifold_id_map_1d = std::move(tria.vertex_to_manifold_id_map_1d);
10194 
10196 
10197  return *this;
10198 }
10199 
10200 
10201 
10202 template <int dim, int spacedim>
10204 {
10205  // notify listeners that the triangulation is going down...
10206  try
10207  {
10208  signals.clear();
10209  }
10210  catch (...)
10211  {}
10212 
10213  levels.clear();
10214 
10215  // the vertex_to_boundary_id_map_1d field should be unused except in
10216  // 1d. double check this here, as destruction is a good place to
10217  // ensure that what we've done over the course of the lifetime of
10218  // this object makes sense
10219  AssertNothrow((dim == 1) || (vertex_to_boundary_id_map_1d == nullptr),
10220  ExcInternalError());
10221 
10222  // the vertex_to_manifold_id_map_1d field should be also unused
10223  // except in 1d. check this as well
10224  AssertNothrow((dim == 1) || (vertex_to_manifold_id_map_1d == nullptr),
10225  ExcInternalError());
10226 }
10227 
10228 
10229 
10230 template <int dim, int spacedim>
10231 void
10233 {
10234  // notify listeners that the triangulation is going down...
10235  signals.clear();
10236 
10237  // ...and then actually clear all content of it
10240  periodic_face_map.clear();
10241 }
10242 
10243 
10244 
10245 template <int dim, int spacedim>
10246 void
10248  const MeshSmoothing mesh_smoothing)
10249 {
10250  Assert(n_levels() == 0,
10251  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
10252  smooth_grid = mesh_smoothing;
10253 }
10254 
10255 
10256 
10257 template <int dim, int spacedim>
10260 {
10261  return smooth_grid;
10262 }
10263 
10264 
10265 
10266 template <int dim, int spacedim>
10267 void
10269  const types::manifold_id m_number,
10270  const Manifold<dim, spacedim> &manifold_object)
10271 {
10274 
10275  manifold[m_number] = manifold_object.clone();
10276 }
10277 
10278 
10279 
10280 template <int dim, int spacedim>
10281 void
10283 {
10284  reset_manifold(m_number);
10285 }
10286 
10287 
10288 template <int dim, int spacedim>
10289 void
10291 {
10294 
10295  // delete the entry located at number.
10296  manifold.erase(m_number);
10297 }
10298 
10299 
10300 template <int dim, int spacedim>
10301 void
10303 {
10304  manifold.clear();
10305 }
10306 
10307 
10308 template <int dim, int spacedim>
10309 void
10311  const types::manifold_id m_number)
10312 {
10313  Assert(
10314  n_cells() > 0,
10315  ExcMessage(
10316  "Error: set_all_manifold_ids() can not be called on an empty Triangulation."));
10317 
10319  cell = this->begin_active(),
10320  endc = this->end();
10321 
10322  for (; cell != endc; ++cell)
10323  cell->set_all_manifold_ids(m_number);
10324 }
10325 
10326 
10327 template <int dim, int spacedim>
10328 void
10330  const types::manifold_id m_number)
10331 {
10332  Assert(
10333  n_cells() > 0,
10334  ExcMessage(
10335  "Error: set_all_manifold_ids_on_boundary() can not be called on an empty Triangulation."));
10336 
10338  cell = this->begin_active(),
10339  endc = this->end();
10340 
10341  for (; cell != endc; ++cell)
10342  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
10343  if (cell->face(f)->at_boundary())
10344  cell->face(f)->set_all_manifold_ids(m_number);
10345 }
10346 
10347 
10348 template <int dim, int spacedim>
10349 void
10351  const types::boundary_id b_id,
10352  const types::manifold_id m_number)
10353 {
10354  Assert(
10355  n_cells() > 0,
10356  ExcMessage(
10357  "Error: set_all_manifold_ids_on_boundary() can not be called on an empty Triangulation."));
10358 
10359  bool boundary_found = false;
10361  cell = this->begin_active(),
10362  endc = this->end();
10363 
10364  for (; cell != endc; ++cell)
10365  {
10366  // loop on faces
10367  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
10368  if (cell->face(f)->at_boundary() &&
10369  cell->face(f)->boundary_id() == b_id)
10370  {
10371  boundary_found = true;
10372  cell->face(f)->set_manifold_id(m_number);
10373  }
10374 
10375  // loop on edges if dim >= 3
10376  if (dim >= 3)
10377  for (unsigned int e = 0; e < GeometryInfo<dim>::lines_per_cell; ++e)
10378  if (cell->line(e)->at_boundary() &&
10379  cell->line(e)->boundary_id() == b_id)
10380  {
10381  boundary_found = true;
10382  cell->line(e)->set_manifold_id(m_number);
10383  }
10384  }
10385 
10386  (void)boundary_found;
10387  Assert(boundary_found, ExcBoundaryIdNotFound(b_id));
10388 }
10389 
10390 
10391 
10392 template <int dim, int spacedim>
10395  const types::manifold_id m_number) const
10396 {
10397  // look, if there is a manifold stored at
10398  // manifold_id number.
10399  const auto it = manifold.find(m_number);
10400 
10401  if (it != manifold.end())
10402  {
10403  // if we have found an entry, return it
10404  return *(it->second);
10405  }
10406 
10407  // if we have not found an entry connected with number, we return
10408  // the default (flat) manifold
10409  return internal::TriangulationImplementation::
10410  get_default_flat_manifold<dim, spacedim>();
10411 }
10412 
10413 
10414 
10415 template <int dim, int spacedim>
10416 std::vector<types::boundary_id>
10418 {
10419  // in 1d, we store a map of all used boundary indicators. use it for
10420  // our purposes
10421  if (dim == 1)
10422  {
10423  std::vector<types::boundary_id> boundary_ids;
10424  for (std::map<unsigned int, types::boundary_id>::const_iterator p =
10426  p != vertex_to_boundary_id_map_1d->end();
10427  ++p)
10428  boundary_ids.push_back(p->second);
10429 
10430  return boundary_ids;
10431  }
10432  else
10433  {
10434  std::set<types::boundary_id> b_ids;
10436  for (; cell != end(); ++cell)
10437  for (unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
10438  ++face)
10439  if (cell->at_boundary(face))
10440  b_ids.insert(cell->face(face)->boundary_id());
10441  std::vector<types::boundary_id> boundary_ids(b_ids.begin(), b_ids.end());
10442  return boundary_ids;
10443  }
10444 }
10445 
10446 
10447 
10448 template <int dim, int spacedim>
10449 std::vector<types::manifold_id>
10451 {
10452  std::set<types::manifold_id> m_ids;
10454  for (; cell != end(); ++cell)
10455  {
10456  m_ids.insert(cell->manifold_id());
10457  if (dim > 1)
10458  for (unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
10459  ++face)
10460  if (cell->at_boundary(face))
10461  m_ids.insert(cell->face(face)->manifold_id());
10462  }
10463  std::vector<types::manifold_id> manifold_indicators(m_ids.begin(),
10464  m_ids.end());
10465  return manifold_indicators;
10466 }
10467 
10468 /*-----------------------------------------------------------------*/
10469 
10470 
10471 template <int dim, int spacedim>
10472 void
10474  const Triangulation<dim, spacedim> &other_tria)
10475 {
10476  Assert((vertices.size() == 0) && (levels.size() == 0) && (faces == nullptr),
10477  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
10478  Assert((other_tria.levels.size() != 0) && (other_tria.vertices.size() != 0) &&
10479  (dim == 1 || other_tria.faces != nullptr),
10480  ExcMessage(
10481  "When calling Triangulation::copy_triangulation(), "
10482  "the target triangulation must be empty but the source "
10483  "triangulation (the argument to this function) must contain "
10484  "something. Here, it seems like the source does not "
10485  "contain anything at all."));
10486 
10487 
10488  // copy normal elements
10489  vertices = other_tria.vertices;
10490  vertices_used = other_tria.vertices_used;
10492  smooth_grid = other_tria.smooth_grid;
10493 
10494  if (dim > 1)
10495  faces = std_cxx14::make_unique<
10497 
10498  auto bdry_iterator = other_tria.manifold.begin();
10499  for (; bdry_iterator != other_tria.manifold.end(); ++bdry_iterator)
10500  manifold[bdry_iterator->first] = bdry_iterator->second->clone();
10501 
10502 
10503  levels.reserve(other_tria.levels.size());
10504  for (unsigned int level = 0; level < other_tria.levels.size(); ++level)
10505  levels.push_back(std_cxx14::make_unique<
10507  *other_tria.levels[level]));
10508 
10509  number_cache = other_tria.number_cache;
10510 
10511  if (dim == 1)
10512  {
10514  std_cxx14::make_unique<std::map<unsigned int, types::boundary_id>>(
10515  *other_tria.vertex_to_boundary_id_map_1d);
10516 
10518  std_cxx14::make_unique<std::map<unsigned int, types::manifold_id>>(
10519  *other_tria.vertex_to_manifold_id_map_1d);
10520  }
10521 
10522  // inform those who are listening on other_tria of the copy operation
10523  other_tria.signals.copy(*this);
10524  // also inform all listeners of the current triangulation that the
10525  // triangulation has been created
10526  signals.create();
10527 
10528  // note that we need not copy the
10529  // subscriptor!
10530 }
10531 
10532 
10533 
10534 template <int dim, int spacedim>
10535 void
10537  const std::vector<Point<spacedim>> &v,
10538  const std::vector<CellData<dim>> & cells,
10539  const SubCellData & subcelldata)
10540 {
10541  std::vector<CellData<dim>> reordered_cells(cells); // NOLINT
10542  SubCellData reordered_subcelldata(subcelldata); // NOLINT
10543 
10544  // in-place reordering of data
10545  reorder_compatibility(reordered_cells, reordered_subcelldata);
10546 
10547  // now create triangulation from
10548  // reordered data
10549  create_triangulation(v, reordered_cells, reordered_subcelldata);
10550 }
10551 
10552 
10553 
10554 template <int dim, int spacedim>
10555 void
10557  const std::vector<Point<spacedim>> &v,
10558  const std::vector<CellData<dim>> & cells,
10559  const SubCellData & subcelldata)
10560 {
10561  Assert((vertices.size() == 0) && (levels.size() == 0) && (faces == nullptr),
10562  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
10563  // check that no forbidden arrays
10564  // are used
10565  Assert(subcelldata.check_consistency(dim), ExcInternalError());
10566 
10567  // try to create a triangulation; if this fails, we still want to
10568  // throw an exception but if we just do so we'll get into trouble
10569  // because sometimes other objects are already attached to it:
10570  try
10571  {
10573  create_triangulation(v, cells, subcelldata, *this);
10574  }
10575  catch (...)
10576  {
10578  throw;
10579  }
10580 
10581  // update our counts of the various elements of a triangulation, and set
10582  // active_cell_indices of all cells
10584  *this, levels.size(), number_cache);
10586 
10587  // now verify that there are indeed no distorted cells. as per the
10588  // documentation of this class, we first collect all distorted cells
10589  // and then throw an exception if there are any
10590  if (check_for_distorted_cells == true)
10591  {
10592  DistortedCellList distorted_cells = collect_distorted_coarse_cells(*this);
10593  // throw the array (and fill the various location fields) if
10594  // there are distorted cells. otherwise, just fall off the end
10595  // of the function
10596  AssertThrow(distorted_cells.distorted_cells.size() == 0, distorted_cells);
10597  }
10598 
10599 
10600  /*
10601  When the triangulation is a manifold (dim < spacedim), the normal field
10602  provided from the map class depends on the order of the vertices.
10603  It may happen that this normal field is discontinuous.
10604  The following code takes care that this is not the case by setting the
10605  cell direction flag on those cell that produce the wrong orientation.
10606 
10607  To determine if 2 neighbours have the same or opposite orientation
10608  we use a table of truth.
10609  Its entries are indexes by the local indices of the common face.
10610  For example if two elements share a face, and this face is
10611  face 0 for element 0 and face 1 for element 1, then
10612  table(0,1) will tell whether the orientation are the same (true) or
10613  opposite (false).
10614 
10615  Even though there may be a combinatorial/graph theory argument to get
10616  this table in any dimension, I tested by hand all the different possible
10617  cases in 1D and 2D to generate the table.
10618 
10619  Assuming that a surface respects the standard orientation for 2d meshes,
10620  the tables of truth are symmetric and their true values are the following
10621  1D curves: (0,1)
10622  2D surface: (0,1),(0,2),(1,3),(2,3)
10623 
10624  We store this data using an n_faces x n_faces full matrix, which is
10625  actually much bigger than the minimal data required, but it makes the code
10626  more readable.
10627 
10628  */
10629  if (dim < spacedim)
10630  {
10633  switch (dim)
10634  {
10635  case 1:
10636  {
10637  bool values[][2] = {{false, true}, {true, false}};
10638  for (unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell;
10639  ++i)
10640  for (unsigned int j = 0; j < GeometryInfo<dim>::faces_per_cell;
10641  ++j)
10642  correct(i, j) = (values[i][j]);
10643  break;
10644  }
10645  case 2:
10646  {
10647  bool values[][4] = {{false, true, true, false},
10648  {true, false, false, true},
10649  {true, false, false, true},
10650  {false, true, true, false}};
10651  for (unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell;
10652  ++i)
10653  for (unsigned int j = 0; j < GeometryInfo<dim>::faces_per_cell;
10654  ++j)
10655  correct(i, j) = (values[i][j]);
10656  break;
10657  }
10658  default:
10659  Assert(false, ExcNotImplemented());
10660  }
10661 
10662 
10663  std::list<active_cell_iterator> this_round, next_round;
10664  active_cell_iterator neighbor;
10665 
10666  this_round.push_back(begin_active());
10667  begin_active()->set_direction_flag(true);
10668  begin_active()->set_user_flag();
10669 
10670  while (this_round.size() > 0)
10671  {
10672  for (typename std::list<active_cell_iterator>::iterator cell =
10673  this_round.begin();
10674  cell != this_round.end();
10675  ++cell)
10676  {
10677  for (unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell;
10678  ++i)
10679  {
10680  if (!((*cell)->face(i)->at_boundary()))
10681  {
10682  neighbor = (*cell)->neighbor(i);
10683 
10684  unsigned int cf = (*cell)->face_index(i);
10685  unsigned int j = 0;
10686  while (neighbor->face_index(j) != cf)
10687  {
10688  ++j;
10689  }
10690 
10691 
10692  // If we already saw this guy, check that everything is
10693  // fine
10694  if (neighbor->user_flag_set())
10695  {
10696  // If we have visited this guy, then the ordering and
10697  // the orientation should agree
10698  Assert(!(correct(i, j) ^
10699  (neighbor->direction_flag() ==
10700  (*cell)->direction_flag())),
10702  }
10703  else
10704  {
10705  next_round.push_back(neighbor);
10706  neighbor->set_user_flag();
10707  if ((correct(i, j) ^ (neighbor->direction_flag() ==
10708  (*cell)->direction_flag())))
10709  neighbor->set_direction_flag(
10710  !neighbor->direction_flag());
10711  }
10712  }
10713  }
10714  }
10715 
10716  // Before we quit let's check
10717  // that if the triangulation
10718  // is disconnected that we
10719  // still get all cells
10720  if (next_round.size() == 0)
10721  for (active_cell_iterator cell = begin_active(); cell != end();
10722  ++cell)
10723  if (cell->user_flag_set() == false)
10724  {
10725  next_round.push_back(cell);
10726  cell->set_direction_flag(true);
10727  cell->set_user_flag();
10728  break;
10729  }
10730 
10731  this_round = next_round;
10732  next_round.clear();
10733  }
10734  }
10735 
10736  // inform all listeners that the triangulation has been created
10737  signals.create();
10738 }
10739 
10740 
10741 
10742 template <int dim, int spacedim>
10743 void
10745 {
10746  AssertThrow(dim + 1 == spacedim,
10747  ExcMessage("Only works for dim == spacedim-1"));
10748  for (active_cell_iterator cell = begin_active(); cell != end(); ++cell)
10749  cell->set_direction_flag(!cell->direction_flag());
10750 }
10751 
10752 
10753 
10754 template <int dim, int spacedim>
10755 void
10757 {
10758  Assert(n_cells() > 0,
10759  ExcMessage("Error: An empty Triangulation can not be refined."));
10760  active_cell_iterator cell = begin_active(), endc = end();
10761 
10762  for (; cell != endc; ++cell)
10763  {
10764  cell->clear_coarsen_flag();
10765  cell->set_refine_flag();
10766  }
10767 }
10768 
10769 
10770 
10771 template <int dim, int spacedim>
10772 void
10774 {
10775  for (unsigned int i = 0; i < times; ++i)
10776  {
10779  }
10780 }
10781 
10782 
10783 
10784 /*-------------------- refine/coarsen flags -------------------------*/
10785 
10786 
10787 
10788 template <int dim, int spacedim>
10789 void
10791 {
10792  v.resize(dim * n_active_cells(), false);
10793  std::vector<bool>::iterator i = v.begin();
10794  active_cell_iterator cell = begin_active(), endc = end();
10795  for (; cell != endc; ++cell)
10796  for (unsigned int j = 0; j < dim; ++j, ++i)
10797  if (cell->refine_flag_set() & (1 << j))
10798  *i = true;
10799 
10800  Assert(i == v.end(), ExcInternalError());
10801 }
10802 
10803 
10804 
10805 template <int dim, int spacedim>
10806 void
10808 {
10809  std::vector<bool> v;
10810  save_refine_flags(v);
10811  write_bool_vector(mn_tria_refine_flags_begin,
10812  v,
10813  mn_tria_refine_flags_end,
10814  out);
10815 }
10816 
10817 
10818 
10819 template <int dim, int spacedim>
10820 void
10822 {
10823  std::vector<bool> v;
10824  read_bool_vector(mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end, in);
10825  load_refine_flags(v);
10826 }
10827 
10828 
10829 
10830 template <int dim, int spacedim>
10831 void
10833 {
10834  AssertThrow(v.size() == dim * n_active_cells(), ExcGridReadError());
10835 
10836  active_cell_iterator cell = begin_active(), endc = end();
10837  std::vector<bool>::const_iterator i = v.begin();
10838  for (; cell != endc; ++cell)
10839  {
10840  unsigned int ref_case = 0;
10841 
10842  for (unsigned int j = 0; j < dim; ++j, ++i)
10843  if (*i == true)
10844  ref_case += 1 << j;
10846  ExcGridReadError());
10847  if (ref_case > 0)
10848  cell->set_refine_flag(RefinementCase<dim>(ref_case));
10849  else
10850  cell->clear_refine_flag();
10851  }
10852 
10853  Assert(i == v.end(), ExcInternalError());
10854 }
10855 
10856 
10857 
10858 template <int dim, int spacedim>
10859 void
10861 {
10862  v.resize(n_active_cells(), false);
10863  std::vector<bool>::iterator i = v.begin();
10864  active_cell_iterator cell = begin_active(), endc = end();
10865  for (; cell != endc; ++cell, ++i)
10866  *i = cell->coarsen_flag_set();
10867 
10868  Assert(i == v.end(), ExcInternalError());
10869 }
10870 
10871 
10872 
10873 template <int dim, int spacedim>
10874 void
10876 {
10877  std::vector<bool> v;
10878  save_coarsen_flags(v);
10879  write_bool_vector(mn_tria_coarsen_flags_begin,
10880  v,
10881  mn_tria_coarsen_flags_end,
10882  out);
10883 }
10884 
10885 
10886 
10887 template <int dim, int spacedim>
10888 void
10890 {
10891  std::vector<bool> v;
10892  read_bool_vector(mn_tria_coarsen_flags_begin,
10893  v,
10894  mn_tria_coarsen_flags_end,
10895  in);
10896  load_coarsen_flags(v);
10897 }
10898 
10899 
10900 
10901 template <int dim, int spacedim>
10902 void
10904 {
10905  Assert(v.size() == n_active_cells(), ExcGridReadError());
10906 
10907  active_cell_iterator cell = begin_active(), endc = end();
10908  std::vector<bool>::const_iterator i = v.begin();
10909  for (; cell != endc; ++cell, ++i)
10910  if (*i == true)
10911  cell->set_coarsen_flag();
10912  else
10913  cell->clear_coarsen_flag();
10914 
10915  Assert(i == v.end(), ExcInternalError());
10916 }
10917 
10918 
10919 template <int dim, int spacedim>
10920 bool
10922 {
10923  return anisotropic_refinement;
10924 }
10925 
10926 
10927 
10928 /*-------------------- user data/flags -------------------------*/
10929 
10930 
10931 namespace
10932 {
10933  // clear user data of cells
10934  template <int dim>
10935  void
10937  std::vector<
10939  &levels)
10940  {
10941  for (unsigned int level = 0; level < levels.size(); ++level)
10942  levels[level]->cells.clear_user_data();
10943  }
10944 
10945 
10946  // clear user data of faces
10948  {
10949  // nothing to do in 1d
10950  }
10951 
10952 
10953  void
10955  {
10956  faces->lines.clear_user_data();
10957  }
10958 
10959 
10960  void
10962  {
10963  faces->lines.clear_user_data();
10964  faces->quads.clear_user_data();
10965  }
10966 } // namespace
10967 
10968 
10969 template <int dim, int spacedim>
10970 void
10972 {
10973  // let functions in anonymous namespace do their work
10975  ::clear_user_data(faces.get());
10976 }
10977 
10978 
10979 
10980 namespace
10981 {
10982  void clear_user_flags_line(
10983  std::vector<
10985  &levels,
10987  {
10988  for (unsigned int level = 0; level < levels.size(); ++level)
10989  levels[level]->cells.clear_user_flags();
10990  }
10991 
10992  template <int dim>
10993  void
10995  std::vector<
10998  {
10999  faces->lines.clear_user_flags();
11000  }
11001 } // namespace
11002 
11003 
11004 template <int dim, int spacedim>
11005 void
11007 {
11009 }
11010 
11011 
11012 
11013 namespace
11014 {
11015  void clear_user_flags_quad(
11016  std::vector<
11019  {
11020  // nothing to do in 1d
11021  }
11022 
11023  void clear_user_flags_quad(
11024  std::vector<
11026  &levels,
11028  {
11029  for (unsigned int level = 0; level < levels.size(); ++level)
11030  levels[level]->cells.clear_user_flags();
11031  }
11032 
11033  template <int dim>
11034  void
11036  std::vector<
11039  {
11040  faces->quads.clear_user_flags();
11041  }
11042 } // namespace
11043 
11044 
11045 template <int dim, int spacedim>
11046 void
11048 {
11050 }
11051 
11052 
11053 
11054 namespace
11055 {
11056  void clear_user_flags_hex(
11057  std::vector<
11060  {
11061  // nothing to do in 1d
11062  }
11063 
11064 
11065  void clear_user_flags_hex(
11066  std::vector<
11069  {
11070  // nothing to do in 2d
11071  }
11072 
11073  void clear_user_flags_hex(
11074  std::vector<
11076  &levels,
11078  {
11079  for (unsigned int level = 0; level < levels.size(); ++level)
11080  levels[level]->cells.clear_user_flags();
11081  }
11082 } // namespace
11083 
11084 
11085 template <int dim, int spacedim>
11086 void
11088 {
11090 }
11091 
11092 
11093 
11094 template <int dim, int spacedim>
11095 void
11097 {
11101 }
11102 
11103 
11104 
11105 template <int dim, int spacedim>
11106 void
11108 {
11109  save_user_flags_line(out);
11110 
11111  if (dim >= 2)
11112  save_user_flags_quad(out);
11113 
11114  if (dim >= 3)
11115  save_user_flags_hex(out);
11116 
11117  if (dim >= 4)
11118  Assert(false, ExcNotImplemented());
11119 }
11120 
11121 
11122 
11123 template <int dim, int spacedim>
11124 void
11126 {
11127  // clear vector and append
11128  // all the stuff later on
11129  v.clear();
11130 
11131  std::vector<bool> tmp;
11132 
11133  save_user_flags_line(tmp);
11134  v.insert(v.end(), tmp.begin(), tmp.end());
11135 
11136  if (dim >= 2)
11137  {
11138  save_user_flags_quad(tmp);
11139  v.insert(v.end(), tmp.begin(), tmp.end());
11140  }
11141 
11142  if (dim >= 3)
11143  {
11144  save_user_flags_hex(tmp);
11145  v.insert(v.end(), tmp.begin(), tmp.end());
11146  }
11147 
11148  if (dim >= 4)
11149  Assert(false, ExcNotImplemented());
11150 }
11151 
11152 
11153 
11154 template <int dim, int spacedim>
11155 void
11157 {
11159 
11160  if (dim >= 2)
11162 
11163  if (dim >= 3)
11164  load_user_flags_hex(in);
11165 
11166  if (dim >= 4)
11167  Assert(false, ExcNotImplemented());
11168 }
11169 
11170 
11171 
11172 template <int dim, int spacedim>
11173 void
11175 {
11176  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
11177  std::vector<bool> tmp;
11178 
11179  // first extract the flags
11180  // belonging to lines
11181  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
11182  // and set the lines
11183  load_user_flags_line(tmp);
11184 
11185  if (dim >= 2)
11186  {
11187  tmp.clear();
11188  tmp.insert(tmp.end(),
11189  v.begin() + n_lines(),
11190  v.begin() + n_lines() + n_quads());
11191  load_user_flags_quad(tmp);
11192  }
11193 
11194  if (dim >= 3)
11195  {
11196  tmp.clear();
11197  tmp.insert(tmp.end(),
11198  v.begin() + n_lines() + n_quads(),
11199  v.begin() + n_lines() + n_quads() + n_hexs());
11200  load_user_flags_hex(tmp);
11201  }
11202 
11203  if (dim >= 4)
11204  Assert(false, ExcNotImplemented());
11205 }
11206 
11207 
11208 
11209 template <int dim, int spacedim>
11210 void
11212 {
11213  v.resize(n_lines(), false);
11214  std::vector<bool>::iterator i = v.begin();
11215  line_iterator line = begin_line(), endl = end_line();
11216  for (; line != endl; ++line, ++i)
11217  *i = line->user_flag_set();
11218 
11219  Assert(i == v.end(), ExcInternalError());
11220 }
11221 
11222 
11223 
11224 template <int dim, int spacedim>
11225 void
11227 {
11228  std::vector<bool> v;
11230  write_bool_vector(mn_tria_line_user_flags_begin,
11231  v,
11232  mn_tria_line_user_flags_end,
11233  out);
11234 }
11235 
11236 
11237 
11238 template <int dim, int spacedim>
11239 void
11241 {
11242  std::vector<bool> v;
11243  read_bool_vector(mn_tria_line_user_flags_begin,
11244  v,
11245  mn_tria_line_user_flags_end,
11246  in);
11248 }
11249 
11250 
11251 
11252 template <int dim, int spacedim>
11253 void
11255 {
11256  Assert(v.size() == n_lines(), ExcGridReadError());
11257 
11258  line_iterator line = begin_line(), endl = end_line();
11259  std::vector<bool>::const_iterator i = v.begin();
11260  for (; line != endl; ++line, ++i)
11261  if (*i == true)
11262  line->set_user_flag();
11263  else
11264  line->clear_user_flag();
11265 
11266  Assert(i == v.end(), ExcInternalError());
11267 }
11268 
11269 
11270 namespace
11271 {
11272  template <typename Iterator>
11273  bool
11274  get_user_flag(const Iterator &i)
11275  {
11276  return i->user_flag_set();
11277  }
11278 
11279 
11280 
11281  template <int structdim, int dim, int spacedim>
11282  bool
11284  {
11285  Assert(false, ExcInternalError());
11286  return false;
11287  }
11288 
11289 
11290 
11291  template <typename Iterator>
11292  void
11293  set_user_flag(const Iterator &i)
11294  {
11295  i->set_user_flag();
11296  }
11297 
11298 
11299 
11300  template <int structdim, int dim, int spacedim>
11301  void
11303  {
11304  Assert(false, ExcInternalError());
11305  }
11306 
11307 
11308 
11309  template <typename Iterator>
11310  void
11311  clear_user_flag(const Iterator &i)
11312  {
11313  i->clear_user_flag();
11314  }
11315 
11316 
11317 
11318  template <int structdim, int dim, int spacedim>
11319  void
11320  clear_user_flag(
11322  {
11323  Assert(false, ExcInternalError());
11324  }
11325 } // namespace
11326 
11327 
11328 template <int dim, int spacedim>
11329 void
11331 {
11332  v.resize(n_quads(), false);
11333 
11334  if (dim >= 2)
11335  {
11336  std::vector<bool>::iterator i = v.begin();
11337  quad_iterator quad = begin_quad(), endq = end_quad();
11338  for (; quad != endq; ++quad, ++i)
11339  *i = get_user_flag(quad);
11340 
11341  Assert(i == v.end(), ExcInternalError());
11342  }
11343 }
11344 
11345 
11346 
11347 template <int dim, int spacedim>
11348 void
11350 {
11351  std::vector<bool> v;
11353  write_bool_vector(mn_tria_quad_user_flags_begin,
11354  v,
11355  mn_tria_quad_user_flags_end,
11356  out);
11357 }
11358 
11359 
11360 
11361 template <int dim, int spacedim>
11362 void
11364 {
11365  std::vector<bool> v;
11366  read_bool_vector(mn_tria_quad_user_flags_begin,
11367  v,
11368  mn_tria_quad_user_flags_end,
11369  in);
11371 }
11372 
11373 
11374 
11375 template <int dim, int spacedim>
11376 void
11378 {
11379  Assert(v.size() == n_quads(), ExcGridReadError());
11380 
11381  if (dim >= 2)
11382  {
11383  quad_iterator quad = begin_quad(), endq = end_quad();
11384  std::vector<bool>::const_iterator i = v.begin();
11385  for (; quad != endq; ++quad, ++i)
11386  if (*i == true)
11387  set_user_flag(quad);
11388  else
11389  clear_user_flag(quad);
11390 
11391  Assert(i == v.end(), ExcInternalError());
11392  }
11393 }
11394 
11395 
11396 
11397 template <int dim, int spacedim>
11398 void
11400 {
11401  v.resize(n_hexs(), false);
11402 
11403  if (dim >= 3)
11404  {
11405  std::vector<bool>::iterator i = v.begin();
11406  hex_iterator hex = begin_hex(), endh = end_hex();
11407  for (; hex != endh; ++hex, ++i)
11408  *i = get_user_flag(hex);
11409 
11410  Assert(i == v.end(), ExcInternalError());
11411  }
11412 }
11413 
11414 
11415 
11416 template <int dim, int spacedim>
11417 void
11419 {
11420  std::vector<bool> v;
11422  write_bool_vector(mn_tria_hex_user_flags_begin,
11423  v,
11424  mn_tria_hex_user_flags_end,
11425  out);
11426 }
11427 
11428 
11429 
11430 template <int dim, int spacedim>
11431 void
11433 {
11434  std::vector<bool> v;
11435  read_bool_vector(mn_tria_hex_user_flags_begin,
11436  v,
11437  mn_tria_hex_user_flags_end,
11438  in);
11440 }
11441 
11442 
11443 
11444 template <int dim, int spacedim>
11445 void
11447 {
11448  Assert(v.size() == n_hexs(), ExcGridReadError());
11449 
11450  if (dim >= 3)
11451  {
11452  hex_iterator hex = begin_hex(), endh = end_hex();
11453  std::vector<bool>::const_iterator i = v.begin();
11454  for (; hex != endh; ++hex, ++i)
11455  if (*i == true)
11456  set_user_flag(hex);
11457  else
11458  clear_user_flag(hex);
11459 
11460  Assert(i == v.end(), ExcInternalError());
11461  }
11462 }
11463 
11464 
11465 
11466 template <int dim, int spacedim>
11467 void
11469  std::vector<unsigned int> &v) const
11470 {
11471  // clear vector and append all the
11472  // stuff later on
11473  v.clear();
11474 
11475  std::vector<unsigned int> tmp;
11476 
11478  v.insert(v.end(), tmp.begin(), tmp.end());
11479 
11480  if (dim >= 2)
11481  {
11483  v.insert(v.end(), tmp.begin(), tmp.end());
11484  }
11485 
11486  if (dim >= 3)
11487  {
11488  save_user_indices_hex(tmp);
11489  v.insert(v.end(), tmp.begin(), tmp.end());
11490  }
11491 
11492  if (dim >= 4)
11493  Assert(false, ExcNotImplemented());
11494 }
11495 
11496 
11497 
11498 template <int dim, int spacedim>
11499 void
11501  const std::vector<unsigned int> &v)
11502 {
11503  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
11504  std::vector<unsigned int> tmp;
11505 
11506  // first extract the indices
11507  // belonging to lines
11508  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
11509  // and set the lines
11511 
11512  if (dim >= 2)
11513  {
11514  tmp.clear();
11515  tmp.insert(tmp.end(),
11516  v.begin() + n_lines(),
11517  v.begin() + n_lines() + n_quads());
11519  }
11520 
11521  if (dim >= 3)
11522  {
11523  tmp.clear();
11524  tmp.insert(tmp.end(),
11525  v.begin() + n_lines() + n_quads(),
11526  v.begin() + n_lines() + n_quads() + n_hexs());
11527  load_user_indices_hex(tmp);
11528  }
11529 
11530  if (dim >= 4)
11531  Assert(false, ExcNotImplemented());
11532 }
11533 
11534 
11535 
11536 namespace
11537 {
11538  template <typename Iterator>
11539  unsigned int
11540  get_user_index(const Iterator &i)
11541  {
11542  return i->user_index();
11543  }
11544 
11545 
11546 
11547  template <int structdim, int dim, int spacedim>
11548  unsigned int
11549  get_user_index(
11551  {
11552  Assert(false, ExcInternalError());
11554  }
11555 
11556 
11557 
11558  template <typename Iterator>
11559  void
11560  set_user_index(const Iterator &i, const unsigned int x)
11561  {
11562  i->set_user_index(x);
11563  }
11564 
11565 
11566 
11567  template <int structdim, int dim, int spacedim>
11568  void
11569  set_user_index(
11571  const unsigned int)
11572  {
11573  Assert(false, ExcInternalError());
11574  }
11575 } // namespace
11576 
11577 
11578 template <int dim, int spacedim>
11579 void
11581  std::vector<unsigned int> &v) const
11582 {
11583  v.resize(n_lines(), 0);
11584  std::vector<unsigned int>::iterator i = v.begin();
11585  line_iterator line = begin_line(), endl = end_line();
11586  for (; line != endl; ++line, ++i)
11587  *i = line->user_index();
11588 }
11589 
11590 
11591 
11592 template <int dim, int spacedim>
11593 void
11595  const std::vector<unsigned int> &v)
11596 {
11597  Assert(v.size() == n_lines(), ExcGridReadError());
11598 
11599  line_iterator line = begin_line(), endl = end_line();
11600  std::vector<unsigned int>::const_iterator i = v.begin();
11601  for (; line != endl; ++line, ++i)
11602  line->set_user_index(*i);
11603 }
11604 
11605 
11606 template <int dim, int spacedim>
11607 void
11609  std::vector<unsigned int> &v) const
11610 {
11611  v.resize(n_quads(), 0);
11612 
11613  if (dim >= 2)
11614  {
11615  std::vector<unsigned int>::iterator i = v.begin();
11616  quad_iterator quad = begin_quad(), endq = end_quad();
11617  for (; quad != endq; ++quad, ++i)
11618  *i = get_user_index(quad);
11619  }
11620 }
11621 
11622 
11623 
11624 template <int dim, int spacedim>
11625 void
11627  const std::vector<unsigned int> &v)
11628 {
11629  Assert(v.size() == n_quads(), ExcGridReadError());
11630 
11631  if (dim >= 2)
11632  {
11633  quad_iterator quad = begin_quad(), endq = end_quad();
11634  std::vector<unsigned int>::const_iterator i = v.begin();
11635  for (; quad != endq; ++quad, ++i)
11636  set_user_index(quad, *i);
11637  }
11638 }
11639 
11640 
11641 template <int dim, int spacedim>
11642 void
11644  std::vector<unsigned int> &v) const
11645 {
11646  v.resize(n_hexs(), 0);
11647 
11648  if (dim >= 3)
11649  {
11650  std::vector<unsigned int>::iterator i = v.begin();
11651  hex_iterator hex = begin_hex(), endh = end_hex();
11652  for (; hex != endh; ++hex, ++i)
11653  *i = get_user_index(hex);
11654  }
11655 }
11656 
11657 
11658 
11659 template <int dim, int spacedim>
11660 void
11662  const std::vector<unsigned int> &v)
11663 {
11664  Assert(v.size() == n_hexs(), ExcGridReadError());
11665 
11666  if (dim >= 3)
11667  {
11668  hex_iterator hex = begin_hex(), endh = end_hex();
11669  std::vector<unsigned int>::const_iterator i = v.begin();
11670  for (; hex != endh; ++hex, ++i)
11671  set_user_index(hex, *i);
11672  }
11673 }
11674 
11675 
11676 
11677 //---------------- user pointers ----------------------------------------//
11678 
11679 
11680 namespace
11681 {
11682  template <typename Iterator>
11683  void *
11684  get_user_pointer(const Iterator &i)
11685  {
11686  return i->user_pointer();
11687  }
11688 
11689 
11690 
11691  template <int structdim, int dim, int spacedim>
11692  void *
11693  get_user_pointer(
11695  {
11696  Assert(false, ExcInternalError());
11697  return nullptr;
11698  }
11699 
11700 
11701 
11702  template <typename Iterator>
11703  void
11704  set_user_pointer(const Iterator &i, void *x)
11705  {
11706  i->set_user_pointer(x);
11707  }
11708 
11709 
11710 
11711  template <int structdim, int dim, int spacedim>
11712  void
11713  set_user_pointer(
11715  void *)
11716  {
11717  Assert(false, ExcInternalError());
11718  }
11719 } // namespace
11720 
11721 
11722 template <int dim, int spacedim>
11723 void
11725 {
11726  // clear vector and append all the
11727  // stuff later on
11728  v.clear();
11729 
11730  std::vector<void *> tmp;
11731 
11733  v.insert(v.end(), tmp.begin(), tmp.end());
11734 
11735  if (dim >= 2)
11736  {
11738  v.insert(v.end(), tmp.begin(), tmp.end());
11739  }
11740 
11741  if (dim >= 3)
11742  {
11744  v.insert(v.end(), tmp.begin(), tmp.end());
11745  }
11746 
11747  if (dim >= 4)
11748  Assert(false, ExcNotImplemented());
11749 }
11750 
11751 
11752 
11753 template <int dim, int spacedim>
11754 void
11756 {
11757  Assert(v.size() == n_lines() + n_quads() + n_hexs(), ExcInternalError());
11758  std::vector<void *> tmp;
11759 
11760  // first extract the pointers
11761  // belonging to lines
11762  tmp.insert(tmp.end(), v.begin(), v.begin() + n_lines());
11763  // and set the lines
11765 
11766  if (dim >= 2)
11767  {
11768  tmp.clear();
11769  tmp.insert(tmp.end(),
11770  v.begin() + n_lines(),
11771  v.begin() + n_lines() + n_quads());
11773  }
11774 
11775  if (dim >= 3)
11776  {
11777  tmp.clear();
11778  tmp.insert(tmp.end(),
11779  v.begin() + n_lines() + n_quads(),
11780  v.begin() + n_lines() + n_quads() + n_hexs());
11782  }
11783 
11784  if (dim >= 4)
11785  Assert(false, ExcNotImplemented());
11786 }
11787 
11788 
11789 
11790 template <int dim, int spacedim>
11791 void
11793  std::vector<void *> &v) const
11794 {
11795  v.resize(n_lines(), nullptr);
11796  std::vector<void *>::iterator i = v.begin();
11797  line_iterator line = begin_line(), endl = end_line();
11798  for (; line != endl; ++line, ++i)
11799  *i = line->user_pointer();
11800 }
11801 
11802 
11803 
11804 template <int dim, int spacedim>
11805 void
11807  const std::vector<void *> &v)
11808 {
11809  Assert(v.size() == n_lines(), ExcGridReadError());
11810 
11811  line_iterator line = begin_line(), endl = end_line();
11812  std::vector<void *>::const_iterator i = v.begin();
11813  for (; line != endl; ++line, ++i)
11814  line->set_user_pointer(*i);
11815 }
11816 
11817 
11818 
11819 template <int dim, int spacedim>
11820 void
11822  std::vector<void *> &v) const
11823 {
11824  v.resize(n_quads(), nullptr);
11825 
11826  if (dim >= 2)
11827  {
11828  std::vector<void *>::iterator i = v.begin();
11829  quad_iterator quad = begin_quad(), endq = end_quad();
11830  for (; quad != endq; ++quad, ++i)
11831  *i = get_user_pointer(quad);
11832  }
11833 }
11834 
11835 
11836 
11837 template <int dim, int spacedim>
11838 void
11840  const std::vector<void *> &v)
11841 {
11842  Assert(v.size() == n_quads(), ExcGridReadError());
11843 
11844  if (dim >= 2)
11845  {
11846  quad_iterator quad = begin_quad(), endq = end_quad();
11847  std::vector<void *>::const_iterator i = v.begin();
11848  for (; quad != endq; ++quad, ++i)
11849  set_user_pointer(quad, *i);
11850  }
11851 }
11852 
11853 
11854 template <int dim, int spacedim>
11855 void
11857  std::vector<void *> &v) const
11858 {
11859  v.resize(n_hexs(), nullptr);
11860 
11861  if (dim >= 3)
11862  {
11863  std::vector<void *>::iterator i = v.begin();
11864  hex_iterator hex = begin_hex(), endh = end_hex();
11865  for (; hex != endh; ++hex, ++i)
11866  *i = get_user_pointer(hex);
11867  }
11868 }
11869 
11870 
11871 
11872 template <int dim, int spacedim>
11873 void
11875  const std::vector<void *> &v)
11876 {
11877  Assert(v.size() == n_hexs(), ExcGridReadError());
11878 
11879  if (dim >= 3)
11880  {
11881  hex_iterator hex = begin_hex(), endh = end_hex();
11882  std::vector<void *>::const_iterator i = v.begin();
11883  for (; hex != endh; ++hex, ++i)
11884  set_user_pointer(hex, *i);
11885  }
11886 }
11887 
11888 
11889 
11890 /*------------------------ Cell iterator functions ------------------------*/
11891 
11892 
11893 template <int dim, int spacedim>
11895 Triangulation<dim, spacedim>::begin_raw(const unsigned int level) const
11896 {
11897  switch (dim)
11898  {
11899  case 1:
11900  return begin_raw_line(level);
11901  case 2:
11902  return begin_raw_quad(level);
11903  case 3:
11904  return begin_raw_hex(level);
11905  default:
11906  Assert(false, ExcNotImplemented());
11907  return raw_cell_iterator();
11908  }
11909 }
11910 
11911 
11912 
11913 template <int dim, int spacedim>
11915 Triangulation<dim, spacedim>::begin(const unsigned int level) const
11916 {
11917  switch (dim)
11918  {
11919  case 1:
11920  return begin_line(level);
11921  case 2:
11922  return begin_quad(level);
11923  case 3:
11924  return begin_hex(level);
11925  default:
11926  Assert(false, ExcImpossibleInDim(dim));
11927  return cell_iterator();
11928  }
11929 }
11930 
11931 
11932 
11933 template <int dim, int spacedim>
11935 Triangulation<dim, spacedim>::begin_active(const unsigned int level) const
11936 {
11937  switch (dim)
11938  {
11939  case 1:
11940  return begin_active_line(level);
11941  case 2:
11942  return begin_active_quad(level);
11943  case 3:
11944  return begin_active_hex(level);
11945  default:
11946  Assert(false, ExcNotImplemented());
11947  return active_cell_iterator();
11948  }
11949 }
11950 
11951 
11952 
11953 template <int dim, int spacedim>
11956 {
11957  const unsigned int level = levels.size() - 1;
11958 
11959  Assert(level < n_global_levels() || level < levels.size(),
11960  ExcInvalidLevel(level));
11961  if (levels[level]->cells.cells.size() == 0)
11962  return end(level);
11963 
11964  // find the last raw iterator on
11965  // this level
11966  raw_cell_iterator ri(const_cast<Triangulation<dim, spacedim> *>(this),
11967  level,
11968  levels[level]->cells.cells.size() - 1);
11969 
11970  // then move to the last used one
11971  if (ri->used() == true)
11972  return ri;
11973  while ((--ri).state() == IteratorState::valid)
11974  if (ri->used() == true)
11975  return ri;
11976  return ri;
11977 }
11978 
11979 
11980 
11981 template <int dim, int spacedim>
11984 {
11985  // get the last used cell
11986  cell_iterator cell = last();
11987 
11988  if (cell != end())
11989  {
11990  // then move to the last active one
11991  if (cell->active() == true)
11992  return cell;
11993  while ((--cell).state() == IteratorState::valid)
11994  if (cell->active() == true)
11995  return cell;
11996  }
11997  return cell;
11998 }
11999 
12000 
12001 
12002 template <int dim, int spacedim>
12005 {
12006  return cell_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12007  -1,
12008  -1);
12009 }
12010 
12011 
12012 
12013 template <int dim, int spacedim>
12015 Triangulation<dim, spacedim>::end_raw(const unsigned int level) const
12016 {
12017  Assert(level < n_global_levels(), ExcInvalidLevel(level));
12018  if (level < levels.size() - 1)
12019  return begin_raw(level + 1);
12020  else
12021  return end();
12022 }
12023 
12024 
12025 template <int dim, int spacedim>
12027 Triangulation<dim, spacedim>::end(const unsigned int level) const
12028 {
12029  if (level < levels.size() - 1)
12030  return begin(level + 1);
12031  Assert(level < n_global_levels() || level < levels.size(),
12032  ExcInvalidLevel(level));
12033  return end();
12034 }
12035 
12036 
12037 template <int dim, int spacedim>
12039 Triangulation<dim, spacedim>::end_active(const unsigned int level) const
12040 {
12041  Assert(level < n_global_levels() || level < levels.size(),
12042  ExcInvalidLevel(level));
12043  return (level >= levels.size() - 1 ? active_cell_iterator(end()) :
12044  begin_active(level + 1));
12045 }
12046 
12047 
12048 
12049 template <int dim, int spacedim>
12052 {
12054  begin(), end());
12055 }
12056 
12057 
12058 template <int dim, int spacedim>
12061 {
12062  return IteratorRange<
12064  end());
12065 }
12066 
12067 
12068 
12069 template <int dim, int spacedim>
12072  const unsigned int level) const
12073 {
12075  begin(level), end(level));
12076 }
12077 
12078 
12079 
12080 template <int dim, int spacedim>
12083  const unsigned int level) const
12084 {
12085  return IteratorRange<
12087  begin_active(level), end_active(level));
12088 }
12089 
12090 
12091 /*------------------------ Face iterator functions ------------------------*/
12092 
12093 
12094 template <int dim, int spacedim>
12097 {
12098  switch (dim)
12099  {
12100  case 1:
12101  Assert(false, ExcImpossibleInDim(1));
12102  return raw_face_iterator();
12103  case 2:
12104  return begin_line();
12105  case 3:
12106  return begin_quad();
12107  default:
12108  Assert(false, ExcNotImplemented());
12109  return face_iterator();
12110  }
12111 }
12112 
12113 
12114 
12115 template <int dim, int spacedim>
12118 {
12119  switch (dim)
12120  {
12121  case 1:
12122  Assert(false, ExcImpossibleInDim(1));
12123  return raw_face_iterator();
12124  case 2:
12125  return begin_active_line();
12126  case 3:
12127  return begin_active_quad();
12128  default:
12129  Assert(false, ExcNotImplemented());
12130  return active_face_iterator();
12131  }
12132 }
12133 
12134 
12135 
12136 template <int dim, int spacedim>
12139 {
12140  switch (dim)
12141  {
12142  case 1:
12143  Assert(false, ExcImpossibleInDim(1));
12144  return raw_face_iterator();
12145  case 2:
12146  return end_line();
12147  case 3:
12148  return end_quad();
12149  default:
12150  Assert(false, ExcNotImplemented());
12151  return raw_face_iterator();
12152  }
12153 }
12154 
12155 
12156 /*------------------------ Vertex iterator functions ------------------------*/
12157 
12158 
12159 template <int dim, int spacedim>
12162 {
12163  if (dim == 1)
12164  {
12165  // This does not work if dim==1 because TriaAccessor<0,1,spacedim> does
12166  // not implement operator++
12167  Assert(false, ExcNotImplemented());
12168  return raw_vertex_iterator();
12169  }
12170  else
12171  {
12172  vertex_iterator i =
12174  0,
12175  0);
12176  if (i.state() != IteratorState::valid)
12177  return i;
12178  // This loop will end because every triangulation has used vertices.
12179  while (i->used() == false)
12180  if ((++i).state() != IteratorState::valid)
12181  return i;
12182  return i;
12183  }
12184 }
12185 
12186 
12187 
12188 template <int dim, int spacedim>
12191 {
12192  return begin_vertex();
12193 }
12194 
12195 
12196 
12197 template <int dim, int spacedim>
12200 {
12201  if (dim == 1)
12202  {
12203  Assert(false, ExcNotImplemented());
12204  return raw_vertex_iterator();
12205  }
12206  else
12207  return raw_vertex_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12208  -1,
12210 }
12211 
12212 
12213 
12214 /*------------------------ Line iterator functions ------------------------*/
12215 
12216 
12217 
12218 template <int dim, int spacedim>
12219 typename Triangulation<dim, spacedim>::raw_line_iterator
12220 Triangulation<dim, spacedim>::begin_raw_line(const unsigned int level) const
12221 {
12222  switch (dim)
12223  {
12224  case 1:
12225  Assert(level < n_global_levels() || level < levels.size(),
12226  ExcInvalidLevel(level));
12227 
12228  if (level >= levels.size() || levels[level]->cells.cells.size() == 0)
12229  return end_line();
12230 
12231  return raw_line_iterator(
12232  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
12233 
12234  default:
12235  Assert(level == 0, ExcFacesHaveNoLevel());
12236  return raw_line_iterator(
12237  const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
12238  }
12239 }
12240 
12241 
12242 template <int dim, int spacedim>
12243 typename Triangulation<dim, spacedim>::line_iterator
12244 Triangulation<dim, spacedim>::begin_line(const unsigned int level) const
12245 {
12246  // level is checked in begin_raw
12247  raw_line_iterator ri = begin_raw_line(level);
12248  if (ri.state() != IteratorState::valid)
12249  return ri;
12250  while (ri->used() == false)
12251  if ((++ri).state() != IteratorState::valid)
12252  return ri;
12253  return ri;
12254 }
12255 
12256 
12257 
12258 template <int dim, int spacedim>
12259 typename Triangulation<dim, spacedim>::active_line_iterator
12261 {
12262  // level is checked in begin_raw
12263  line_iterator i = begin_line(level);
12264  if (i.state() != IteratorState::valid)
12265  return i;
12266  while (i->has_children())
12267  if ((++i).state() != IteratorState::valid)
12268  return i;
12269  return i;
12270 }
12271 
12272 
12273 
12274 template <int dim, int spacedim>
12275 typename Triangulation<dim, spacedim>::line_iterator
12277 {
12278  return raw_line_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12279  -1,
12280  -1);
12281 }
12282 
12283 
12284 
12285 /*------------------------ Quad iterator functions ------------------------*/
12286 
12287 
12288 template <int dim, int spacedim>
12289 typename Triangulation<dim, spacedim>::raw_quad_iterator
12290 Triangulation<dim, spacedim>::begin_raw_quad(const unsigned int level) const
12291 {
12292  switch (dim)
12293  {
12294  case 1:
12295  Assert(false, ExcImpossibleInDim(1));
12296  return raw_hex_iterator();
12297  case 2:
12298  {
12299  Assert(level < n_global_levels() || level < levels.size(),
12300  ExcInvalidLevel(level));
12301 
12302  if (level >= levels.size() || levels[level]->cells.cells.size() == 0)
12303  return end_quad();
12304 
12305  return raw_quad_iterator(
12306  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
12307  }
12308 
12309  case 3:
12310  {
12311  Assert(level == 0, ExcFacesHaveNoLevel());
12312 
12313  return raw_quad_iterator(
12314  const_cast<Triangulation<dim, spacedim> *>(this), 0, 0);
12315  }
12316 
12317 
12318  default:
12319  Assert(false, ExcNotImplemented());
12320  return raw_hex_iterator();
12321  }
12322 }
12323 
12324 
12325 
12326 template <int dim, int spacedim>
12327 typename Triangulation<dim, spacedim>::quad_iterator
12328 Triangulation<dim, spacedim>::begin_quad(const unsigned int level) const
12329 {
12330  // level is checked in begin_raw
12331  raw_quad_iterator ri = begin_raw_quad(level);
12332  if (ri.state() != IteratorState::valid)
12333  return ri;
12334  while (ri->used() == false)
12335  if ((++ri).state() != IteratorState::valid)
12336  return ri;
12337  return ri;
12338 }
12339 
12340 
12341 
12342 template <int dim, int spacedim>
12343 typename Triangulation<dim, spacedim>::active_quad_iterator
12345 {
12346  // level is checked in begin_raw
12347  quad_iterator i = begin_quad(level);
12348  if (i.state() != IteratorState::valid)
12349  return i;
12350  while (i->has_children())
12351  if ((++i).state() != IteratorState::valid)
12352  return i;
12353  return i;
12354 }
12355 
12356 
12357 
12358 template <int dim, int spacedim>
12359 typename Triangulation<dim, spacedim>::quad_iterator
12361 {
12362  return raw_quad_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12363  -1,
12364  -1);
12365 }
12366 
12367 
12368 /*------------------------ Hex iterator functions ------------------------*/
12369 
12370 
12371 template <int dim, int spacedim>
12372 typename Triangulation<dim, spacedim>::raw_hex_iterator
12373 Triangulation<dim, spacedim>::begin_raw_hex(const unsigned int level) const
12374 {
12375  switch (dim)
12376  {
12377  case 1:
12378  case 2:
12379  Assert(false, ExcImpossibleInDim(1));
12380  return raw_hex_iterator();
12381  case 3:
12382  {
12383  Assert(level < n_global_levels() || level < levels.size(),
12384  ExcInvalidLevel(level));
12385 
12386  if (level >= levels.size() || levels[level]->cells.cells.size() == 0)
12387  return end_hex();
12388 
12389  return raw_hex_iterator(
12390  const_cast<Triangulation<dim, spacedim> *>(this), level, 0);
12391  }
12392 
12393  default:
12394  Assert(false, ExcNotImplemented());
12395  return raw_hex_iterator();
12396  }
12397 }
12398 
12399 
12400 
12401 template <int dim, int spacedim>
12402 typename Triangulation<dim, spacedim>::hex_iterator
12403 Triangulation<dim, spacedim>::begin_hex(const unsigned int level) const
12404 {
12405  // level is checked in begin_raw
12406  raw_hex_iterator ri = begin_raw_hex(level);
12407  if (ri.state() != IteratorState::valid)
12408  return ri;
12409  while (ri->used() == false)
12410  if ((++ri).state() != IteratorState::valid)
12411  return ri;
12412  return ri;
12413 }
12414 
12415 
12416 
12417 template <int dim, int spacedim>
12418 typename Triangulation<dim, spacedim>::active_hex_iterator
12419 Triangulation<dim, spacedim>::begin_active_hex(const unsigned int level) const
12420 {
12421  // level is checked in begin_raw
12422  hex_iterator i = begin_hex(level);
12423  if (i.state() != IteratorState::valid)
12424  return i;
12425  while (i->has_children())
12426  if ((++i).state() != IteratorState::valid)
12427  return i;
12428  return i;
12429 }
12430 
12431 
12432 
12433 template <int dim, int spacedim>
12434 typename Triangulation<dim, spacedim>::hex_iterator
12436 {
12437  return raw_hex_iterator(const_cast<Triangulation<dim, spacedim> *>(this),
12438  -1,
12439  -1);
12440 }
12441 
12442 
12443 
12444 // -------------------------------- number of cells etc ---------------
12445 
12446 
12447 namespace internal
12448 {
12449  namespace TriangulationImplementation
12450  {
12451  inline unsigned int
12453  {
12454  return c.n_lines;
12455  }
12456 
12457 
12458  inline unsigned int
12461  {
12462  return c.n_active_lines;
12463  }
12464 
12465 
12466  inline unsigned int
12468  {
12469  return c.n_quads;
12470  }
12471 
12472 
12473  inline unsigned int
12476  {
12477  return c.n_active_quads;
12478  }
12479 
12480 
12481  inline unsigned int
12483  {
12484  return c.n_hexes;
12485  }
12486 
12487 
12488  inline unsigned int
12491  {
12492  return c.n_active_hexes;
12493  }
12494  } // namespace TriangulationImplementation
12495 } // namespace internal
12496 
12497 
12498 
12499 template <int dim, int spacedim>
12500 unsigned int
12502 {
12503  return internal::TriangulationImplementation::n_cells(number_cache);
12504 }
12505 
12506 
12507 template <int dim, int spacedim>
12508 unsigned int
12510 {
12511  return internal::TriangulationImplementation::n_active_cells(number_cache);
12512 }
12513 
12514 template <int dim, int spacedim>
12517 {
12518  return n_active_cells();
12519 }
12520 
12521 
12522 
12523 template <int dim, int spacedim>
12524 unsigned int
12526 {
12527  switch (dim)
12528  {
12529  case 1:
12530  return 0;
12531  case 2:
12532  return n_lines();
12533  case 3:
12534  return n_quads();
12535  default:
12536  Assert(false, ExcNotImplemented());
12537  }
12538  return 0;
12539 }
12540 
12541 
12542 template <int dim, int spacedim>
12543 unsigned int
12545 {
12546  switch (dim)
12547  {
12548  case 2:
12549  return n_raw_lines();
12550  case 3:
12551  return n_raw_quads();
12552  default:
12553  Assert(false, ExcNotImplemented());
12554  }
12555  return 0;
12556 }
12557 
12558 
12559 template <int dim, int spacedim>
12560 unsigned int
12562 {
12563  switch (dim)
12564  {
12565  case 1:
12566  return 0;
12567  case 2:
12568  return n_active_lines();
12569  case 3:
12570  return n_active_quads();
12571  default:
12572  Assert(false, ExcNotImplemented());
12573  }
12574  return 0;
12575 }
12576 
12577 
12578 template <int dim, int spacedim>
12579 unsigned int
12580 Triangulation<dim, spacedim>::n_raw_cells(const unsigned int level) const
12581 {
12582  switch (dim)
12583  {
12584  case 1:
12585  return n_raw_lines(level);
12586  case 2:
12587  return n_raw_quads(level);
12588  case 3:
12589  return n_raw_hexs(level);
12590  default:
12591  Assert(false, ExcNotImplemented());
12592  }
12593  return 0;
12594 }
12595 
12596 
12597 
12598 template <int dim, int spacedim>
12599 unsigned int
12600 Triangulation<dim, spacedim>::n_cells(const unsigned int level) const
12601 {
12602  switch (dim)
12603  {
12604  case 1:
12605  return n_lines(level);
12606  case 2:
12607  return n_quads(level);
12608  case 3:
12609  return n_hexs(level);
12610  default:
12611  Assert(false, ExcNotImplemented());
12612  }
12613  return 0;
12614 }
12615 
12616 
12617 
12618 template <int dim, int spacedim>
12619 unsigned int
12620 Triangulation<dim, spacedim>::n_active_cells(const unsigned int level) const
12621 {
12622  switch (dim)
12623  {
12624  case 1:
12625  return n_active_lines(level);
12626  case 2:
12627  return n_active_quads(level);
12628  case 3:
12629  return n_active_hexs(level);
12630  default:
12631  Assert(false, ExcNotImplemented());
12632  }
12633  return 0;
12634 }
12635 
12636 
12637 template <int dim, int spacedim>
12638 bool
12640 {
12641  for (unsigned int lvl = 0; lvl < n_global_levels() - 1; lvl++)
12642  if (n_active_cells(lvl) != 0)
12643  return true;
12644 
12645  return false;
12646 }
12647 
12648 
12649 template <int dim, int spacedim>
12650 unsigned int
12652 {
12653  return number_cache.n_lines;
12654 }
12655 
12656 
12657 // TODO: Merge the following 6 functions somehow
12658 template <>
12659 unsigned int
12660 Triangulation<1, 1>::n_raw_lines(const unsigned int level) const
12661 {
12662  Assert(level < n_levels(), ExcIndexRange(level, 0, n_levels()));
12663  return levels[level]->cells.cells.size();
12664 }
12665 
12666 
12667 template <>
12668 unsigned int
12670 {
12671  Assert(false, ExcNotImplemented());
12672  return 0;
12673 }
12674 
12675 
12676 
12677 template <>
12678 unsigned int
12679 Triangulation<1, 2>::n_raw_lines(const unsigned int level) const
12680 {
12681  Assert(level < n_levels(), ExcIndexRange(level, 0, n_levels()));
12682  return levels[level]->cells.cells.size();
12683 }
12684 
12685 
12686 template <>
12687 unsigned int
12689 {
12690  Assert(false, ExcNotImplemented());
12691  return 0;
12692 }
12693 
12694 
12695 template <>
12696 unsigned int
12697 Triangulation<1, 3>::n_raw_lines(const unsigned int level) const
12698 {
12699  Assert(level < n_levels(), ExcIndexRange(level, 0, n_levels()));
12700  return levels[level]->cells.cells.size();
12701 }
12702 
12703 template <>
12704 unsigned int
12706 {
12707  Assert(false, ExcNotImplemented());
12708  return 0;
12709 }
12710 
12711 
12712 
12713 template <int dim, int spacedim>
12714 unsigned int
12716 {
12717  Assert(false, ExcFacesHaveNoLevel());
12718  return 0;
12719 }
12720 
12721 
12722 template <int dim, int spacedim>
12723 unsigned int
12725 {
12726  return faces->lines.cells.size();
12727 }
12728 
12729 
12730 template <int dim, int spacedim>
12731 unsigned int
12732 Triangulation<dim, spacedim>::n_lines(const unsigned int level) const
12733 {
12734  Assert(level < number_cache.n_lines_level.size(),
12735  ExcIndexRange(level, 0, number_cache.n_lines_level.size()));
12736  Assert(dim == 1, ExcFacesHaveNoLevel());
12737  return number_cache.n_lines_level[level];
12738 }
12739 
12740 
12741 template <int dim, int spacedim>
12742 unsigned int
12744 {
12745  return number_cache.n_active_lines;
12746 }
12747 
12748 
12749 template <int dim, int spacedim>
12750 unsigned int
12751 Triangulation<dim, spacedim>::n_active_lines(const unsigned int level) const
12752 {
12753  Assert(level < number_cache.n_lines_level.size(),
12754  ExcIndexRange(level, 0, number_cache.n_lines_level.size()));
12755  Assert(dim == 1, ExcFacesHaveNoLevel());
12756 
12757  return number_cache.n_active_lines_level[level];
12758 }
12759 
12760 
12761 template <>
12762 unsigned int
12764 {
12765  return 0;
12766 }
12767 
12768 
12769 template <>
12770 unsigned int
12771 Triangulation<1, 1>::n_quads(const unsigned int) const
12772 {
12773  return 0;
12774 }
12775 
12776 
12777 template <>
12778 unsigned int
12779 Triangulation<1, 1>::n_raw_quads(const unsigned int) const
12780 {
12781  return 0;
12782 }
12783 
12784 
12785 template <>
12786 unsigned int
12787 Triangulation<1, 1>::n_raw_hexs(const unsigned int) const
12788 {
12789  return 0;
12790 }
12791 
12792 
12793 template <>
12794 unsigned int
12795 Triangulation<1, 1>::n_active_quads(const unsigned int) const
12796 {
12797  return 0;
12798 }
12799 
12800 
12801 template <>
12802 unsigned int
12804 {
12805  return 0;
12806 }
12807 
12808 
12809 
12810 template <>
12811 unsigned int
12813 {
12814  return 0;
12815 }
12816 
12817 
12818 template <>
12819 unsigned int
12820 Triangulation<1, 2>::n_quads(const unsigned int) const
12821 {
12822  return 0;
12823 }
12824 
12825 
12826 template <>
12827 unsigned int
12828 Triangulation<1, 2>::n_raw_quads(const unsigned int) const
12829 {
12830  return 0;
12831 }
12832 
12833 
12834 template <>
12835 unsigned int
12836 Triangulation<1, 2>::n_raw_hexs(const unsigned int) const
12837 {
12838  return 0;
12839 }
12840 
12841 
12842 template <>
12843 unsigned int
12844 Triangulation<1, 2>::n_active_quads(const unsigned int) const
12845 {
12846  return 0;
12847 }
12848 
12849 
12850 template <>
12851 unsigned int
12853 {
12854  return 0;
12855 }
12856 
12857 
12858 template <>
12859 unsigned int
12861 {
12862  return 0;
12863 }
12864 
12865 
12866 template <>
12867 unsigned int
12868 Triangulation<1, 3>::n_quads(const unsigned int) const
12869 {
12870  return 0;
12871 }
12872 
12873 
12874 template <>
12875 unsigned int
12876 Triangulation<1, 3>::n_raw_quads(const unsigned int) const
12877 {
12878  return 0;
12879 }
12880 
12881 
12882 template <>
12883 unsigned int
12884 Triangulation<1, 3>::n_raw_hexs(const unsigned int) const
12885 {
12886  return 0;
12887 }
12888 
12889 
12890 template <>
12891 unsigned int
12892 Triangulation<1, 3>::n_active_quads(const unsigned int) const
12893 {
12894  return 0;
12895 }
12896 
12897 
12898 template <>
12899 unsigned int
12901 {
12902  return 0;
12903 }
12904 
12905 
12906 
12907 template <int dim, int spacedim>
12908 unsigned int
12910 {
12911  return number_cache.n_quads;
12912 }
12913 
12914 
12915 template <int dim, int spacedim>
12916 unsigned int
12917 Triangulation<dim, spacedim>::n_quads(const unsigned int level) const
12918 {
12919  Assert(dim == 2, ExcFacesHaveNoLevel());
12920  Assert(level < number_cache.n_quads_level.size(),
12921  ExcIndexRange(level, 0, number_cache.n_quads_level.size()));
12922  return number_cache.n_quads_level[level];
12923 }
12924 
12925 
12926 
12927 template <>
12928 unsigned int
12929 Triangulation<2, 2>::n_raw_quads(const unsigned int level) const
12930 {
12931  Assert(level < n_levels(), ExcIndexRange(level, 0, n_levels()));
12932  return levels[level]->cells.cells.size();
12933 }
12934 
12935 
12936 
12937 template <>
12938 unsigned int
12939 Triangulation<2, 3>::n_raw_quads(const unsigned int level) const
12940 {
12941  Assert(level < n_levels(), ExcIndexRange(level, 0, n_levels()));
12942  return levels[level]->cells.cells.size();
12943 }
12944 
12945 
12946 template <>
12947 unsigned int
12948 Triangulation<3, 3>::n_raw_quads(const unsigned int) const
12949 {
12950  Assert(false, ExcFacesHaveNoLevel());
12951  return 0;
12952 }
12953 
12954 
12955 
12956 template <int dim, int spacedim>
12957 unsigned int
12959 {
12960  Assert(false, ExcNotImplemented());
12961  return 0;
12962 }
12963 
12964 
12965 
12966 template <>
12967 unsigned int
12969 {
12970  return faces->quads.cells.size();
12971 }
12972 
12973 
12974 
12975 template <int dim, int spacedim>
12976 unsigned int
12978 {
12979  return number_cache.n_active_quads;
12980 }
12981 
12982 
12983 template <int dim, int spacedim>
12984 unsigned int
12985 Triangulation<dim, spacedim>::n_active_quads(const unsigned int level) const
12986 {
12987  Assert(level < number_cache.n_quads_level.size(),
12988  ExcIndexRange(level, 0, number_cache.n_quads_level.size()));
12989  Assert(dim == 2, ExcFacesHaveNoLevel());
12990 
12991  return number_cache.n_active_quads_level[level];
12992 }
12993 
12994 
12995 template <int dim, int spacedim>
12996 unsigned int
12998 {
12999  return 0;
13000 }
13001 
13002 
13003 
13004 template <int dim, int spacedim>
13005 unsigned int
13006 Triangulation<dim, spacedim>::n_hexs(const unsigned int) const
13007 {
13008  return 0;
13009 }
13010 
13011 
13012 
13013 template <int dim, int spacedim>
13014 unsigned int
13016 {
13017  return 0;
13018 }
13019 
13020 
13021 template <int dim, int spacedim>
13022 unsigned int
13024 {
13025  return 0;
13026 }
13027 
13028 
13029 
13030 template <int dim, int spacedim>
13031 unsigned int
13033 {
13034  return 0;
13035 }
13036 
13037 
13038 template <>
13039 unsigned int
13041 {
13042  return number_cache.n_hexes;
13043 }
13044 
13045 
13046 
13047 template <>
13048 unsigned int
13049 Triangulation<3, 3>::n_hexs(const unsigned int level) const
13050 {
13051  Assert(level < number_cache.n_hexes_level.size(),
13052  ExcIndexRange(level, 0, number_cache.n_hexes_level.size()));
13053 
13054  return number_cache.n_hexes_level[level];
13055 }
13056 
13057 
13058 
13059 template <>
13060 unsigned int
13061 Triangulation<3, 3>::n_raw_hexs(const unsigned int level) const
13062 {
13063  Assert(level < n_levels(), ExcIndexRange(level, 0, n_levels()));
13064  return levels[level]->cells.cells.size();
13065 }
13066 
13067 
13068 template <>
13069 unsigned int
13071 {
13072  return number_cache.n_active_hexes;
13073 }
13074 
13075 
13076 
13077 template <>
13078 unsigned int
13079 Triangulation<3, 3>::n_active_hexs(const unsigned int level) const
13080 {
13081  Assert(level < number_cache.n_hexes_level.size(),
13082  ExcIndexRange(level, 0, number_cache.n_hexes_level.size()));
13083 
13084  return number_cache.n_active_hexes_level[level];
13085 }
13086 
13087 
13088 
13089 template <int dim, int spacedim>
13090 unsigned int
13092 {
13093  return std::count_if(vertices_used.begin(),
13094  vertices_used.end(),
13095  std::bind(std::equal_to<bool>(),
13096  std::placeholders::_1,
13097  true));
13098 }
13099 
13100 
13101 
13102 template <int dim, int spacedim>
13103 const std::vector<bool> &
13105 {
13106  return vertices_used;
13107 }
13108 
13109 
13110 
13111 template <>
13112 unsigned int
13114 {
13115  return 2;
13116 }
13117 
13118 
13119 
13120 template <>
13121 unsigned int
13123 {
13124  return 2;
13125 }
13126 
13127 
13128 template <>
13129 unsigned int
13131 {
13132  return 2;
13133 }
13134 
13135 
13136 template <int dim, int spacedim>
13137 unsigned int
13139 {
13140  cell_iterator cell = begin(0),
13141  endc = (n_levels() > 1 ? begin(1) : cell_iterator(end()));
13142  // store the largest index of the
13143  // vertices used on level 0
13144  unsigned int max_vertex_index = 0;
13145  for (; cell != endc; ++cell)
13146  for (unsigned int vertex = 0; vertex < GeometryInfo<dim>::vertices_per_cell;
13147  ++vertex)
13148  if (cell->vertex_index(vertex) > max_vertex_index)
13149  max_vertex_index = cell->vertex_index(vertex);
13150 
13151  // store the number of times a cell
13152  // touches a vertex. An unsigned
13153  // int should suffice, even for
13154  // larger dimensions
13155  std::vector<unsigned short int> usage_count(max_vertex_index + 1, 0);
13156  // touch a vertex's usage count
13157  // every time we find an adjacent
13158  // element
13159  for (cell = begin(); cell != endc; ++cell)
13160  for (unsigned int vertex = 0; vertex < GeometryInfo<dim>::vertices_per_cell;
13161  ++vertex)
13162  ++usage_count[cell->vertex_index(vertex)];
13163 
13164  return std::max(GeometryInfo<dim>::vertices_per_cell,
13165  static_cast<unsigned int>(
13166  *std::max_element(usage_count.begin(), usage_count.end())));
13167 }
13168 
13169 
13170 
13171 template <int dim, int spacedim>
13174 {
13176 }
13177 
13178 
13179 
13180 template <int dim, int spacedim>
13183 {
13184  return *this;
13185 }
13186 
13187 
13188 
13189 template <int dim, int spacedim>
13192 {
13193  return *this;
13194 }
13195 
13196 
13197 
13198 template <int dim, int spacedim>
13199 void
13202  &periodicity_vector)
13203 {
13205  periodicity_vector.begin(),
13206  periodicity_vector.end());
13207 
13208  // Now initialize periodic_face_map
13210 }
13211 
13212 
13213 
13214 template <int dim, int spacedim>
13215 const typename std::map<
13216  std::pair<typename Triangulation<dim, spacedim>::cell_iterator, unsigned int>,
13217  std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
13218  unsigned int>,
13219  std::bitset<3>>> &
13221 {
13222  return periodic_face_map;
13223 }
13224 
13225 
13226 
13227 template <int dim, int spacedim>
13228 void
13230 {
13232 
13233  // verify a case with which we have had
13234  // some difficulty in the past (see the
13235  // deal.II/coarsening_* tests)
13237  Assert(satisfies_level1_at_vertex_rule(*this) == true, ExcInternalError());
13238 
13239  // Inform all listeners about beginning of refinement.
13241 
13243 
13244  const DistortedCellList cells_with_distorted_children = execute_refinement();
13245 
13246  // verify a case with which we have had
13247  // some difficulty in the past (see the
13248  // deal.II/coarsening_* tests)
13249  if (smooth_grid & limit_level_difference_at_vertices)
13250  Assert(satisfies_level1_at_vertex_rule(*this) == true, ExcInternalError());
13251 
13252  // finally build up neighbor connectivity information, and set
13253  // active cell indices
13254  update_neighbors(*this);
13256 
13257  // Inform all listeners about end of refinement.
13259 
13260  AssertThrow(cells_with_distorted_children.distorted_cells.size() == 0,
13261  cells_with_distorted_children);
13262 
13264 }
13265 
13266 
13267 
13268 template <int dim, int spacedim>
13269 void
13271 {
13272  unsigned int active_cell_index = 0;
13273  for (raw_cell_iterator cell = begin_raw(); cell != end(); ++cell)
13274  if ((cell->used() == false) || cell->has_children())
13275  cell->set_active_cell_index(numbers::invalid_unsigned_int);
13276  else
13277  {
13278  cell->set_active_cell_index(active_cell_index);
13279  ++active_cell_index;
13280  }
13281 
13282  Assert(active_cell_index == n_active_cells(), ExcInternalError());
13283 }
13284 
13285 
13286 template <int dim, int spacedim>
13287 void
13289 {
13290  // first empty the currently stored objects
13291  periodic_face_map.clear();
13292 
13293  typename std::vector<
13294  GridTools::PeriodicFacePair<cell_iterator>>::const_iterator it;
13295  for (it = periodic_face_pairs_level_0.begin();
13296  it != periodic_face_pairs_level_0.end();
13297  ++it)
13298  {
13299  update_periodic_face_map_recursively<dim, spacedim>(it->cell[0],
13300  it->cell[1],
13301  it->face_idx[0],
13302  it->face_idx[1],
13303  it->orientation,
13305 
13306  // for the other way, we need to invert the orientation
13307  std::bitset<3> inverted_orientation;
13308  {
13309  bool orientation, flip, rotation;
13310  orientation = it->orientation[0];
13311  rotation = it->orientation[2];
13312  flip = orientation ? rotation ^ it->orientation[1] : it->orientation[1];
13313  inverted_orientation[0] = orientation;
13314  inverted_orientation[1] = flip;
13315  inverted_orientation[2] = rotation;
13316  }
13317  update_periodic_face_map_recursively<dim, spacedim>(it->cell[1],
13318  it->cell[0],
13319  it->face_idx[1],
13320  it->face_idx[0],
13321  inverted_orientation,
13323  }
13324 
13325  // check consistency
13326  typename std::map<std::pair<cell_iterator, unsigned int>,
13327  std::pair<std::pair<cell_iterator, unsigned int>,
13328  std::bitset<3>>>::const_iterator it_test;
13329  for (it_test = periodic_face_map.begin(); it_test != periodic_face_map.end();
13330  ++it_test)
13331  {
13333  it_test->first.first;
13335  it_test->second.first.first;
13336  if (cell_1->level() == cell_2->level())
13337  {
13338  // if both cells have the same neighbor, then the same pair
13339  // order swapped has to be in the map
13340  Assert(periodic_face_map[it_test->second.first].first ==
13341  it_test->first,
13342  ExcInternalError());
13343  }
13344  }
13345 }
13346 
13347 
13348 
13349 template <int dim, int spacedim>
13350 void
13352 {
13353  levels.clear();
13354  faces.reset();
13355 
13356  vertices.clear();
13357  vertices_used.clear();
13358 
13359  manifold.clear();
13360 
13362 }
13363 
13364 
13365 template <int dim, int spacedim>
13368 {
13369  const DistortedCellList cells_with_distorted_children =
13371  *this, check_for_distorted_cells);
13372 
13373 
13374 
13375  // re-compute number of lines
13377  *this, levels.size(), number_cache);
13378 
13379 #ifdef DEBUG
13380  for (unsigned int level = 0; level < levels.size(); ++level)
13381  levels[level]->cells.monitor_memory(dim);
13382 
13383  // check whether really all refinement flags are reset (also of
13384  // previously non-active cells which we may not have touched. If the
13385  // refinement flag of a non-active cell is set, something went wrong
13386  // since the cell-accessors should have caught this)
13387  cell_iterator cell = begin(), endc = end();
13388  while (cell != endc)
13389  Assert(!(cell++)->refine_flag_set(), ExcInternalError());
13390 #endif
13391 
13392  return cells_with_distorted_children;
13393 }
13394 
13395 
13396 
13397 template <int dim, int spacedim>
13398 void
13400 {
13401  // create a vector counting for each line how many cells contain
13402  // this line. in 3D, this is used later on to decide which lines can
13403  // be deleted after coarsening a cell. in other dimensions it will
13404  // be ignored
13405  std::vector<unsigned int> line_cell_count =
13406  count_cells_bounded_by_line(*this);
13407  std::vector<unsigned int> quad_cell_count =
13408  count_cells_bounded_by_quad(*this);
13409 
13410  // loop over all cells. Flag all cells of which all children are
13411  // flagged for coarsening and delete the childrens' flags. In
13412  // effect, only those cells are flagged of which originally all
13413  // children were flagged and for which all children are on the same
13414  // refinement level. For flagging, the user flags are used, to avoid
13415  // confusion and because non-active cells can't be flagged for
13416  // coarsening. Note that because of the effects of
13417  // @p{fix_coarsen_flags}, of a cell either all or no children must
13418  // be flagged for coarsening, so it is ok to only check the first
13419  // child
13420  clear_user_flags();
13421 
13422  cell_iterator cell = begin(), endc = end();
13423  for (; cell != endc; ++cell)
13424  if (!cell->active())
13425  if (cell->child(0)->coarsen_flag_set())
13426  {
13427  cell->set_user_flag();
13428  for (unsigned int child = 0; child < cell->n_children(); ++child)
13429  {
13430  Assert(cell->child(child)->coarsen_flag_set(),
13431  ExcInternalError());
13432  cell->child(child)->clear_coarsen_flag();
13433  }
13434  }
13435 
13436 
13437  // now do the actual coarsening step. Since the loop goes over used
13438  // cells we only need not worry about deleting some cells since the
13439  // ++operator will then just hop over them if we should hit one. Do
13440  // the loop in the reverse way since we may only delete some cells
13441  // if their neighbors have already been deleted (if the latter are
13442  // on a higher level for example)
13443  //
13444  // since we delete the *children* of cells, we can ignore cells
13445  // on the highest level, i.e., level must be less than or equal
13446  // to n_levels()-2.
13447  if (levels.size() >= 2)
13448  for (cell = last(); cell != endc; --cell)
13449  if (cell->level() <= static_cast<int>(levels.size() - 2) &&
13450  cell->user_flag_set())
13451  {
13452  // inform all listeners that cell coarsening is going to happen
13454  // use a separate function, since this is dimension specific
13456  delete_children(*this, cell, line_cell_count, quad_cell_count);
13457  }
13458 
13459  // re-compute number of lines and quads
13461  *this, levels.size(), number_cache);
13462 
13463  // in principle no user flags should be set any more at this point
13464 #if DEBUG
13465  for (cell = begin(); cell != endc; ++cell)
13466  Assert(cell->user_flag_set() == false, ExcInternalError());
13467 #endif
13468 }
13469 
13470 
13471 
13472 template <int dim, int spacedim>
13473 void
13475 {
13476  // copy a piece of code from prepare_coarsening_and_refinement that
13477  // ensures that the level difference at vertices is limited if so
13478  // desired. we need this code here since at least in 1d we don't
13479  // call the dimension-independent version of
13480  // prepare_coarsening_and_refinement function. in 2d and 3d, having
13481  // this hunk here makes our lives a bit easier as well as it takes
13482  // care of these cases earlier than it would otherwise happen.
13483  //
13484  // the main difference to the code in p_c_and_r is that here we
13485  // absolutely have to make sure that we get things right, i.e. that
13486  // in particular we set flags right if
13487  // limit_level_difference_at_vertices is set. to do so we iterate
13488  // until the flags don't change any more
13489  std::vector<bool> previous_coarsen_flags(n_active_cells());
13490  save_coarsen_flags(previous_coarsen_flags);
13491 
13492  std::vector<int> vertex_level(vertices.size(), 0);
13493 
13494  bool continue_iterating = true;
13495 
13496  do
13497  {
13499  {
13501  ExcMessage("In case of anisotropic refinement the "
13502  "limit_level_difference_at_vertices flag for "
13503  "mesh smoothing must not be set!"));
13504 
13505  // store highest level one of the cells adjacent to a vertex
13506  // belongs to
13507  std::fill(vertex_level.begin(), vertex_level.end(), 0);
13508  active_cell_iterator cell = begin_active(), endc = end();
13509  for (; cell != endc; ++cell)
13510  {
13511  if (cell->refine_flag_set())
13512  for (unsigned int vertex = 0;
13513  vertex < GeometryInfo<dim>::vertices_per_cell;
13514  ++vertex)
13515  vertex_level[cell->vertex_index(vertex)] =
13516  std::max(vertex_level[cell->vertex_index(vertex)],
13517  cell->level() + 1);
13518  else if (!cell->coarsen_flag_set())
13519  for (unsigned int vertex = 0;
13520  vertex < GeometryInfo<dim>::vertices_per_cell;
13521  ++vertex)
13522  vertex_level[cell->vertex_index(vertex)] =
13523  std::max(vertex_level[cell->vertex_index(vertex)],
13524  cell->level());
13525  else
13526  {
13527  // if coarsen flag is set then tentatively assume
13528  // that the cell will be coarsened. this isn't
13529  // always true (the coarsen flag could be removed
13530  // again) and so we may make an error here. we try
13531  // to correct this by iterating over the entire
13532  // process until we are converged
13533  Assert(cell->coarsen_flag_set(), ExcInternalError());
13534  for (unsigned int vertex = 0;
13535  vertex < GeometryInfo<dim>::vertices_per_cell;
13536  ++vertex)
13537  vertex_level[cell->vertex_index(vertex)] =
13538  std::max(vertex_level[cell->vertex_index(vertex)],
13539  cell->level() - 1);
13540  }
13541  }
13542 
13543 
13544  // loop over all cells in reverse order. do so because we
13545  // can then update the vertex levels on the adjacent
13546  // vertices and maybe already flag additional cells in this
13547  // loop
13548  //
13549  // note that not only may we have to add additional
13550  // refinement flags, but we will also have to remove
13551  // coarsening flags on cells adjacent to vertices that will
13552  // see refinement
13553  for (cell = last_active(); cell != endc; --cell)
13554  if (cell->refine_flag_set() == false)
13555  {
13556  for (unsigned int vertex = 0;
13557  vertex < GeometryInfo<dim>::vertices_per_cell;
13558  ++vertex)
13559  if (vertex_level[cell->vertex_index(vertex)] >=
13560  cell->level() + 1)
13561  {
13562  // remove coarsen flag...
13563  cell->clear_coarsen_flag();
13564 
13565  // ...and if necessary also refine the current
13566  // cell, at the same time updating the level
13567  // information about vertices
13568  if (vertex_level[cell->vertex_index(vertex)] >
13569  cell->level() + 1)
13570  {
13571  cell->set_refine_flag();
13572 
13573  for (unsigned int v = 0;
13574  v < GeometryInfo<dim>::vertices_per_cell;
13575  ++v)
13576  vertex_level[cell->vertex_index(v)] =
13577  std::max(vertex_level[cell->vertex_index(v)],
13578  cell->level() + 1);
13579  }
13580 
13581  // continue and see whether we may, for example,
13582  // go into the inner 'if' above based on a
13583  // different vertex
13584  }
13585  }
13586  }
13587 
13588  // loop over all cells. Flag all cells of which all children are
13589  // flagged for coarsening and delete the childrens' flags. Also
13590  // delete all flags of cells for which not all children of a
13591  // cell are flagged. In effect, only those cells are flagged of
13592  // which originally all children were flagged and for which all
13593  // children are on the same refinement level. For flagging, the
13594  // user flags are used, to avoid confusion and because
13595  // non-active cells can't be flagged for coarsening
13596  //
13597  // In effect, all coarsen flags are turned into user flags of
13598  // the mother cell if coarsening is possible or deleted
13599  // otherwise.
13600  clear_user_flags();
13601  // Coarsen flags of cells with no mother cell, i.e. on the
13602  // coarsest level are deleted explicitly.
13603  active_cell_iterator acell = begin_active(0), end_ac = end_active(0);
13604  for (; acell != end_ac; ++acell)
13605  acell->clear_coarsen_flag();
13606 
13607  cell_iterator cell = begin(), endc = end();
13608  for (; cell != endc; ++cell)
13609  {
13610  // nothing to do if we are already on the finest level
13611  if (cell->active())
13612  continue;
13613 
13614  const unsigned int n_children = cell->n_children();
13615  unsigned int flagged_children = 0;
13616  for (unsigned int child = 0; child < n_children; ++child)
13617  if (cell->child(child)->active() &&
13618  cell->child(child)->coarsen_flag_set())
13619  {
13620  ++flagged_children;
13621  // clear flag since we don't need it anymore
13622  cell->child(child)->clear_coarsen_flag();
13623  }
13624 
13625  // flag this cell for coarsening if all children were
13626  // flagged
13627  if (flagged_children == n_children)
13628  cell->set_user_flag();
13629  }
13630 
13631  // in principle no coarsen flags should be set any more at this
13632  // point
13633 #if DEBUG
13634  for (cell = begin(); cell != endc; ++cell)
13635  Assert(cell->coarsen_flag_set() == false, ExcInternalError());
13636 #endif
13637 
13638  // now loop over all cells which have the user flag set. their
13639  // children were flagged for coarsening. set the coarsen flag
13640  // again if we are sure that none of the neighbors of these
13641  // children are refined, or will be refined, since then we would
13642  // get a two-level jump in refinement. on the other hand, if one
13643  // of the children's neighbors has their user flag set, then we
13644  // know that its children will go away by coarsening, and we
13645  // will be ok.
13646  //
13647  // note on the other hand that we do allow level-2 jumps in
13648  // refinement between neighbors in 1d, so this whole procedure
13649  // is only necessary if we are not in 1d
13650  //
13651  // since we remove some coarsening/user flags in the process, we
13652  // have to work from the finest level to the coarsest one, since
13653  // we occasionally inspect user flags of cells on finer levels
13654  // and need to be sure that these flags are final
13655  for (cell = last(); cell != endc; --cell)
13656  if (cell->user_flag_set())
13657  // if allowed: flag the
13658  // children for coarsening
13660  template coarsening_allowed<dim, spacedim>(cell))
13661  for (unsigned int c = 0; c < cell->n_children(); ++c)
13662  {
13663  Assert(cell->child(c)->refine_flag_set() == false,
13664  ExcInternalError());
13665 
13666  cell->child(c)->set_coarsen_flag();
13667  }
13668 
13669  // clear all user flags again, now that we don't need them any
13670  // more
13671  clear_user_flags();
13672 
13673 
13674  // now see if anything has changed in the last iteration of this
13675  // function
13676  std::vector<bool> current_coarsen_flags(n_active_cells());
13677  save_coarsen_flags(current_coarsen_flags);
13678 
13679  continue_iterating = (current_coarsen_flags != previous_coarsen_flags);
13680  previous_coarsen_flags = current_coarsen_flags;
13681  }
13682  while (continue_iterating == true);
13683 }
13684 
13685 
13686 // TODO: merge the following 3 functions since they are the same
13687 template <>
13688 bool
13690 {
13691  // save the flags to determine whether something was changed in the
13692  // course of this function
13693  std::vector<bool> flags_before;
13694  save_coarsen_flags(flags_before);
13695 
13696  // do nothing in 1d, except setting the coarsening flags correctly
13698 
13699  std::vector<bool> flags_after;
13700  save_coarsen_flags(flags_after);
13701 
13702  return (flags_before != flags_after);
13703 }
13704 
13705 
13706 template <>
13707 bool
13709 {
13710  // save the flags to determine whether something was changed in the
13711  // course of this function
13712  std::vector<bool> flags_before;
13713  save_coarsen_flags(flags_before);
13714 
13715  // do nothing in 1d, except setting the coarsening flags correctly
13717 
13718  std::vector<bool> flags_after;
13719  save_coarsen_flags(flags_after);
13720 
13721  return (flags_before != flags_after);
13722 }
13723 
13724 
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
13736 
13737  std::vector<bool> flags_after;
13738  save_coarsen_flags(flags_after);
13739 
13740  return (flags_before != flags_after);
13741 }
13742 
13743 
13744 
13745 namespace
13746 {
13747  // check if the given @param cell marked for coarsening would
13748  // produce an unrefined island. To break up long chains of these
13749  // cells we recursively check our neighbors in case we change this
13750  // cell. This reduces the number of outer iterations dramatically.
13751  template <int dim, int spacedim>
13752  void
13753  possibly_do_not_produce_unrefined_islands(
13754  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
13755  {
13756  Assert(cell->has_children(), ExcInternalError());
13757 
13758  unsigned int n_neighbors = 0;
13759  // count all neighbors that will be refined along the face of our
13760  // cell after the next step
13761  unsigned int count = 0;
13762  for (unsigned int n = 0; n < GeometryInfo<dim>::faces_per_cell; ++n)
13763  {
13764  const typename Triangulation<dim, spacedim>::cell_iterator neighbor =
13765  cell->neighbor(n);
13766  if (neighbor.state() == IteratorState::valid)
13767  {
13768  ++n_neighbors;
13769  if (face_will_be_refined_by_neighbor(cell, n))
13770  ++count;
13771  }
13772  }
13773  // clear coarsen flags if either all existing neighbors will be
13774  // refined or all but one will be and the cell is in the interior
13775  // of the domain
13776  if (count == n_neighbors ||
13777  (count >= n_neighbors - 1 &&
13778  n_neighbors == GeometryInfo<dim>::faces_per_cell))
13779  {
13780  for (unsigned int c = 0; c < cell->n_children(); ++c)
13781  cell->child(c)->clear_coarsen_flag();
13782 
13783  for (unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
13784  ++face)
13785  if (!cell->at_boundary(face) && (!cell->neighbor(face)->active()) &&
13786  (cell_will_be_coarsened(cell->neighbor(face))))
13787  possibly_do_not_produce_unrefined_islands<dim, spacedim>(
13788  cell->neighbor(face));
13789  }
13790  }
13791 
13792 
13793  // see if the current cell needs to be refined to avoid unrefined
13794  // islands.
13795  //
13796  // there are sometimes chains of cells that induce refinement of
13797  // each other. to avoid running the loop in
13798  // prepare_coarsening_and_refinement over and over again for each
13799  // one of them, at least for the isotropic refinement case we seek
13800  // to flag neighboring elements as well as necessary. this takes
13801  // care of (slightly pathological) cases like
13802  // deal.II/mesh_smoothing_03
13803  template <int dim, int spacedim>
13804  void
13805  possibly_refine_unrefined_island(
13806  const typename Triangulation<dim, spacedim>::cell_iterator &cell,
13807  const bool allow_anisotropic_smoothing)
13808  {
13809  Assert(cell->has_children() == false, ExcInternalError());
13810  Assert(cell->refine_flag_set() == false, ExcInternalError());
13811 
13812 
13813  // now we provide two algorithms. the first one is the standard
13814  // one, coming from the time, where only isotropic refinement was
13815  // possible. it simply counts the neighbors that are or will be
13816  // refined and compares to the number of other ones. the second
13817  // one does this check independently for each direction: if all
13818  // neighbors in one direction (normally two, at the boundary only
13819  // one) are refined, the current cell is flagged to be refined in
13820  // an according direction.
13821 
13822  if (allow_anisotropic_smoothing == false)
13823  {
13824  // use first algorithm
13825  unsigned int refined_neighbors = 0, unrefined_neighbors = 0;
13826  for (unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
13827  ++face)
13828  if (!cell->at_boundary(face))
13829  {
13830  if (face_will_be_refined_by_neighbor(cell, face))
13831  ++refined_neighbors;
13832  else
13833  ++unrefined_neighbors;
13834  }
13835 
13836  if (unrefined_neighbors < refined_neighbors)
13837  {
13838  cell->clear_coarsen_flag();
13839  cell->set_refine_flag();
13840 
13841  // ok, so now we have flagged this cell. if we know that
13842  // there were any unrefined neighbors at all, see if any
13843  // of those will have to be refined as well
13844  if (unrefined_neighbors > 0)
13845  for (unsigned int face = 0;
13846  face < GeometryInfo<dim>::faces_per_cell;
13847  ++face)
13848  if (!cell->at_boundary(face) &&
13849  (face_will_be_refined_by_neighbor(cell, face) == false) &&
13850  (cell->neighbor(face)->has_children() == false) &&
13851  (cell->neighbor(face)->refine_flag_set() == false))
13852  possibly_refine_unrefined_island<dim, spacedim>(
13853  cell->neighbor(face), allow_anisotropic_smoothing);
13854  }
13855  }
13856  else
13857  {
13858  // variable to store the cell refine case needed to fulfill
13859  // all smoothing requirements
13860  RefinementCase<dim> smoothing_cell_refinement_case =
13862 
13863  // use second algorithm, do the check individually for each
13864  // direction
13865  for (unsigned int face_pair = 0;
13866  face_pair < GeometryInfo<dim>::faces_per_cell / 2;
13867  ++face_pair)
13868  {
13869  // variable to store the cell refine case needed to refine
13870  // at the current face pair in the same way as the
13871  // neighbors do...
13872  RefinementCase<dim> directional_cell_refinement_case =
13874 
13875  for (unsigned int face_index = 0; face_index < 2; ++face_index)
13876  {
13877  unsigned int face = 2 * face_pair + face_index;
13878  // variable to store the refine case (to come) of the
13879  // face under consideration
13880  RefinementCase<dim - 1> expected_face_ref_case =
13881  RefinementCase<dim - 1>::no_refinement;
13882 
13883  if (cell->neighbor(face).state() == IteratorState::valid)
13884  face_will_be_refined_by_neighbor<dim, spacedim>(
13885  cell, face, expected_face_ref_case);
13886  // now extract which refine case would be necessary to
13887  // achieve the same face refinement. set the
13888  // intersection with other requirements for the same
13889  // direction.
13890 
13891  // note: using the intersection is not an obvious
13892  // decision, we could also argue that it is more
13893  // natural to use the union. however, intersection is
13894  // the less aggressive tactic and favours a smaller
13895  // number of refined cells over an intensive
13896  // smoothing. this way we try not to lose too much of
13897  // the effort we put in anisotropic refinement
13898  // indicators due to overly aggressive smoothing...
13899  directional_cell_refinement_case =
13900  (directional_cell_refinement_case &
13903  expected_face_ref_case,
13904  face,
13905  cell->face_orientation(face),
13906  cell->face_flip(face),
13907  cell->face_rotation(face)));
13908  } // for both face indices
13909  // if both requirements sum up to something useful, add
13910  // this to the refine case for smoothing. note: if
13911  // directional_cell_refinement_case is isotropic still,
13912  // then something went wrong...
13913  Assert(directional_cell_refinement_case <
13915  ExcInternalError());
13916  smoothing_cell_refinement_case =
13917  smoothing_cell_refinement_case | directional_cell_refinement_case;
13918  } // for all face_pairs
13919  // no we collected contributions from all directions. combine
13920  // the new flags with the existing refine case, but only if
13921  // smoothing is required
13922  if (smoothing_cell_refinement_case)
13923  {
13924  cell->clear_coarsen_flag();
13925  cell->set_refine_flag(cell->refine_flag_set() |
13926  smoothing_cell_refinement_case);
13927  }
13928  }
13929  }
13930 } // namespace
13931 
13932 
13933 template <int dim, int spacedim>
13934 bool
13936 {
13937  // save the flags to determine whether something was changed in the
13938  // course of this function
13939  std::vector<bool> flags_before[2];
13940  save_coarsen_flags(flags_before[0]);
13941  save_refine_flags(flags_before[1]);
13942 
13943  // save the flags at the outset of each loop. we do so in order to
13944  // find out whether something was changed in the present loop, in
13945  // which case we would have to re-run the loop. the other
13946  // possibility to find this out would be to set a flag
13947  // @p{something_changed} to true each time we change something.
13948  // however, sometimes one change in one of the parts of the loop is
13949  // undone by another one, so we might end up in an endless loop. we
13950  // could be tempted to break this loop at an arbitrary number of
13951  // runs, but that would not be a clean solution, since we would
13952  // either have to 1/ break the loop too early, in which case the
13953  // promise that a second call to this function immediately after the
13954  // first one does not change anything, would be broken, or 2/ we do
13955  // as many loops as there are levels. we know that information is
13956  // transported over one level in each run of the loop, so this is
13957  // enough. Unfortunately, each loop is rather expensive, so we chose
13958  // the way presented here
13959  std::vector<bool> flags_before_loop[2] = {flags_before[0], flags_before[1]};
13960 
13961  // now for what is done in each loop: we have to fulfill several
13962  // tasks at the same time, namely several mesh smoothing algorithms
13963  // and mesh regularization, by which we mean that the next mesh
13964  // fulfills several requirements such as no double refinement at
13965  // each face or line, etc.
13966  //
13967  // since doing these things at once seems almost impossible (in the
13968  // first year of this library, they were done in two functions, one
13969  // for refinement and one for coarsening, and most things within
13970  // these were done at once, so the code was rather impossible to
13971  // join into this, only, function), we do them one after each
13972  // other. the order in which we do them is such that the important
13973  // tasks, namely regularization, are done last and the least
13974  // important things are done the first. the following order is
13975  // chosen:
13976  //
13977  // 0/ Only if coarsest_level_1 or patch_level_1 is set: clear all
13978  // coarsen flags on level 1 to avoid level 0 cells being created
13979  // by coarsening. As coarsen flags will never be added, this can
13980  // be done once and for all before the actual loop starts.
13981  //
13982  // 1/ do not coarsen a cell if 'most of the neighbors' will be
13983  // refined after the step. This is to prevent occurrence of
13984  // unrefined islands.
13985  //
13986  // 2/ eliminate refined islands in the interior and at the
13987  // boundary. since they don't do much harm besides increasing the
13988  // number of degrees of freedom, doing this has a rather low
13989  // priority.
13990  //
13991  // 3/ limit the level difference of neighboring cells at each
13992  // vertex.
13993  //
13994  // 4/ eliminate unrefined islands. this has higher priority since
13995  // this diminishes the approximation properties not only of the
13996  // unrefined island, but also of the surrounding patch.
13997  //
13998  // 5/ ensure patch level 1. Then the triangulation consists of
13999  // patches, i.e. of cells that are refined once. It follows that
14000  // if at least one of the children of a cell is or will be
14001  // refined than all children need to be refined. This step only
14002  // sets refinement flags and does not set coarsening flags. If
14003  // the patch_level_1 flag is set, then
14004  // eliminate_unrefined_islands, eliminate_refined_inner_islands
14005  // and eliminate_refined_boundary_islands will be fulfilled
14006  // automatically and do not need to be enforced separately.
14007  //
14008  // 6/ take care of the requirement that no double refinement is done
14009  // at each face
14010  //
14011  // 7/ take care that no double refinement is done at each line in 3d
14012  // or higher dimensions.
14013  //
14014  // 8/ make sure that all children of each cell are either flagged
14015  // for coarsening or none of the children is
14016  //
14017  // For some of these steps, it is known that they interact. Namely,
14018  // it is not possible to guarantee that after step 6 another step 5
14019  // would have no effect; the same holds for the opposite order and
14020  // also when taking into account step 7. however, it is important to
14021  // guarantee that step five or six do not undo something that step 5
14022  // did, and step 7 not something of step 6, otherwise the
14023  // requirements will not be satisfied even if the loop
14024  // terminates. this is accomplished by the fact that steps 5 and 6
14025  // only *add* refinement flags and delete coarsening flags
14026  // (therefore, step 6 can't undo something that step 4 already did),
14027  // and step 7 only deletes coarsening flags, never adds some. step 7
14028  // needs also take care that it won't tag cells for refinement for
14029  // which some neighbors are more refined or will be refined.
14030 
14032  // STEP 0:
14033  // Only if coarsest_level_1 or patch_level_1 is set: clear all
14034  // coarsen flags on level 1 to avoid level 0 cells being created
14035  // by coarsening.
14037  n_levels() >= 2)
14038  {
14039  active_cell_iterator cell = begin_active(1), endc = end_active(1);
14040 
14041  for (; cell != endc; ++cell)
14042  cell->clear_coarsen_flag();
14043  }
14044 
14045  bool mesh_changed_in_this_loop = false;
14046  do
14047  {
14049  // STEP 1:
14050  // do not coarsen a cell if 'most of the neighbors' will be
14051  // refined after the step. This is to prevent the occurrence
14052  // of unrefined islands. If patch_level_1 is set, this will
14053  // be automatically fulfilled.
14055  !(smooth_grid & patch_level_1))
14056  {
14057  cell_iterator cell;
14058  const cell_iterator endc = end();
14059 
14060  for (cell = begin(); cell != endc; ++cell)
14061  {
14062  // only do something if this
14063  // cell will be coarsened
14064  if (!cell->active() && cell_will_be_coarsened(cell))
14065  possibly_do_not_produce_unrefined_islands<dim, spacedim>(cell);
14066  }
14067  }
14068 
14069 
14071  // STEP 2:
14072  // eliminate refined islands in the interior and at the
14073  // boundary. since they don't do much harm besides increasing
14074  // the number of degrees of freedom, doing this has a rather
14075  // low priority. If patch_level_1 is set, this will be
14076  // automatically fulfilled.
14077  //
14078  // there is one corner case to consider: if this is a
14079  // distributed triangulation, there may be refined islands on
14080  // the boundary of which we own only part (e.g. a single cell
14081  // in the corner of a domain). the rest of the island is
14082  // ghost cells and it *looks* like the area around it
14083  // (artificial cells) are coarser but this is only because
14084  // they may actually be equally fine on other
14085  // processors. it's hard to detect this case but we can do
14086  // the following: only set coarsen flags to remove this
14087  // refined island if all cells we want to set flags on are
14088  // locally owned
14092  {
14093  cell_iterator cell;
14094  const cell_iterator endc = end();
14095 
14096  for (cell = begin(); cell != endc; ++cell)
14097  if (!cell->active() || (cell->active() && cell->refine_flag_set() &&
14098  cell->is_locally_owned()))
14099  {
14100  // check whether all children are active, i.e. not
14101  // refined themselves. This is a precondition that the
14102  // children may be coarsened away. If the cell is only
14103  // flagged for refinement, then all future children
14104  // will be active
14105  bool all_children_active = true;
14106  if (!cell->active())
14107  for (unsigned int c = 0; c < cell->n_children(); ++c)
14108  if (!cell->child(c)->active() ||
14109  cell->child(c)->is_ghost() ||
14110  cell->child(c)->is_artificial())
14111  {
14112  all_children_active = false;
14113  break;
14114  }
14115 
14116  if (all_children_active)
14117  {
14118  // count number of refined and unrefined neighbors
14119  // of cell. neighbors on lower levels are counted
14120  // as unrefined since they can only get to the
14121  // same level as this cell by the next refinement
14122  // cycle
14123  unsigned int unrefined_neighbors = 0, total_neighbors = 0;
14124 
14125  for (unsigned int n = 0;
14126  n < GeometryInfo<dim>::faces_per_cell;
14127  ++n)
14128  {
14129  const cell_iterator neighbor = cell->neighbor(n);
14130  if (neighbor.state() == IteratorState::valid)
14131  {
14132  ++total_neighbors;
14133 
14134  if (!face_will_be_refined_by_neighbor(cell, n))
14135  ++unrefined_neighbors;
14136  }
14137  }
14138 
14139  // if all neighbors unrefined: mark this cell for
14140  // coarsening or don't refine if marked for that
14141  //
14142  // also do the distinction between the two
14143  // versions of the eliminate_refined_*_islands
14144  // flag
14145  //
14146  // the last check is whether there are any
14147  // neighbors at all. if not so, then we are (e.g.)
14148  // on the coarsest grid with one cell, for which,
14149  // of course, we do not remove the refine flag.
14150  if ((unrefined_neighbors == total_neighbors) &&
14151  (((unrefined_neighbors ==
14154  ((unrefined_neighbors <
14156  (smooth_grid &
14158  (total_neighbors != 0))
14159  {
14160  if (!cell->active())
14161  for (unsigned int c = 0; c < cell->n_children(); ++c)
14162  {
14163  cell->child(c)->clear_refine_flag();
14164  cell->child(c)->set_coarsen_flag();
14165  }
14166  else
14167  cell->clear_refine_flag();
14168  }
14169  }
14170  }
14171  }
14172 
14174  // STEP 3:
14175  // limit the level difference of neighboring cells at each
14176  // vertex.
14177  //
14178  // in case of anisotropic refinement this does not make
14179  // sense. as soon as one cell is anisotropically refined, an
14180  // Assertion is thrown. therefore we can ignore this problem
14181  // later on
14183  {
14185  ExcMessage("In case of anisotropic refinement the "
14186  "limit_level_difference_at_vertices flag for "
14187  "mesh smoothing must not be set!"));
14188 
14189  // store highest level one of the cells adjacent to a vertex
14190  // belongs to
14191  std::vector<int> vertex_level(vertices.size(), 0);
14192  active_cell_iterator cell = begin_active(), endc = end();
14193  for (; cell != endc; ++cell)
14194  {
14195  if (cell->refine_flag_set())
14196  for (unsigned int vertex = 0;
14197  vertex < GeometryInfo<dim>::vertices_per_cell;
14198  ++vertex)
14199  vertex_level[cell->vertex_index(vertex)] =
14200  std::max(vertex_level[cell->vertex_index(vertex)],
14201  cell->level() + 1);
14202  else if (!cell->coarsen_flag_set())
14203  for (unsigned int vertex = 0;
14204  vertex < GeometryInfo<dim>::vertices_per_cell;
14205  ++vertex)
14206  vertex_level[cell->vertex_index(vertex)] =
14207  std::max(vertex_level[cell->vertex_index(vertex)],
14208  cell->level());
14209  else
14210  {
14211  // if coarsen flag is set then tentatively assume
14212  // that the cell will be coarsened. this isn't
14213  // always true (the coarsen flag could be removed
14214  // again) and so we may make an error here
14215  Assert(cell->coarsen_flag_set(), ExcInternalError());
14216  for (unsigned int vertex = 0;
14217  vertex < GeometryInfo<dim>::vertices_per_cell;
14218  ++vertex)
14219  vertex_level[cell->vertex_index(vertex)] =
14220  std::max(vertex_level[cell->vertex_index(vertex)],
14221  cell->level() - 1);
14222  }
14223  }
14224 
14225 
14226  // loop over all cells in reverse order. do so because we
14227  // can then update the vertex levels on the adjacent
14228  // vertices and maybe already flag additional cells in this
14229  // loop
14230  //
14231  // note that not only may we have to add additional
14232  // refinement flags, but we will also have to remove
14233  // coarsening flags on cells adjacent to vertices that will
14234  // see refinement
14235  for (cell = last_active(); cell != endc; --cell)
14236  if (cell->refine_flag_set() == false)
14237  {
14238  for (unsigned int vertex = 0;
14239  vertex < GeometryInfo<dim>::vertices_per_cell;
14240  ++vertex)
14241  if (vertex_level[cell->vertex_index(vertex)] >=
14242  cell->level() + 1)
14243  {
14244  // remove coarsen flag...
14245  cell->clear_coarsen_flag();
14246 
14247  // ...and if necessary also refine the current
14248  // cell, at the same time updating the level
14249  // information about vertices
14250  if (vertex_level[cell->vertex_index(vertex)] >
14251  cell->level() + 1)
14252  {
14253  cell->set_refine_flag();
14254 
14255  for (unsigned int v = 0;
14256  v < GeometryInfo<dim>::vertices_per_cell;
14257  ++v)
14258  vertex_level[cell->vertex_index(v)] =
14259  std::max(vertex_level[cell->vertex_index(v)],
14260  cell->level() + 1);
14261  }
14262 
14263  // continue and see whether we may, for example,
14264  // go into the inner'if'
14265  // above based on a
14266  // different vertex
14267  }
14268  }
14269  }
14270 
14272  // STEP 4:
14273  // eliminate unrefined islands. this has higher priority
14274  // since this diminishes the approximation properties not
14275  // only of the unrefined island, but also of the surrounding
14276  // patch.
14277  //
14278  // do the loop from finest to coarsest cells since we may
14279  // trigger a cascade by marking cells for refinement which
14280  // may trigger more cells further down below
14282  {
14283  active_cell_iterator cell = last_active(), endc = end();
14284 
14285  for (; cell != endc; --cell)
14286  // only do something if cell is not already flagged for
14287  // (isotropic) refinement
14288  if (cell->refine_flag_set() !=
14290  possibly_refine_unrefined_island<dim, spacedim>(
14291  cell, (smooth_grid & allow_anisotropic_smoothing) != 0);
14292  }
14293 
14295  // STEP 5:
14296  // ensure patch level 1.
14297  //
14298  // Introduce some terminology:
14299  // - a cell that is refined
14300  // once is a patch of
14301  // level 1 simply called patch.
14302  // - a cell that is globally
14303  // refined twice is called
14304  // a patch of level 2.
14305  // - patch level n says that
14306  // the triangulation consists
14307  // of patches of level n.
14308  // This makes sense only
14309  // if the grid is already at
14310  // least n times globally
14311  // refined.
14312  //
14313  // E.g. from patch level 1 follows: if at least one of the
14314  // children of a cell is or will be refined than enforce all
14315  // children to be refined.
14316 
14317  // This step 4 only sets refinement flags and does not set
14318  // coarsening flags.
14319  if (smooth_grid & patch_level_1)
14320  {
14321  // An important assumption (A) is that before calling this
14322  // function the grid was already of patch level 1.
14323 
14324  // loop over all cells whose children are all active. (By
14325  // assumption (A) either all or none of the children are
14326  // active). If the refine flag of at least one of the
14327  // children is set then set_refine_flag and
14328  // clear_coarsen_flag of all children.
14329  for (cell_iterator cell = begin(); cell != end(); ++cell)
14330  if (!cell->active())
14331  {
14332  // ensure the invariant. we can then check whether all
14333  // of its children are further refined or not by
14334  // simply looking at the first child
14335  Assert(cell_is_patch_level_1(cell), ExcInternalError());
14336  if (cell->child(0)->has_children() == true)
14337  continue;
14338 
14339  // cell is found to be a patch. combine the refine
14340  // cases of all children
14341  RefinementCase<dim> combined_ref_case =
14343  for (unsigned int i = 0; i < cell->n_children(); ++i)
14344  combined_ref_case =
14345  combined_ref_case | cell->child(i)->refine_flag_set();
14346  if (combined_ref_case != RefinementCase<dim>::no_refinement)
14347  for (unsigned int i = 0; i < cell->n_children(); ++i)
14348  {
14349  cell_iterator child = cell->child(i);
14350 
14351  child->clear_coarsen_flag();
14352  child->set_refine_flag(combined_ref_case);
14353  }
14354  }
14355 
14356  // The code above dealt with the case where we may get a
14357  // non-patch_level_1 mesh from refinement. Now also deal
14358  // with the case where we could get such a mesh by
14359  // coarsening. Coarsen the children (and remove the
14360  // grandchildren) only if all cell->grandchild(i)
14361  // ->coarsen_flag_set() are set.
14362  //
14363  // for a case where this is a bit tricky, take a look at the
14364  // mesh_smoothing_0[12] testcases
14365  for (cell_iterator cell = begin(); cell != end(); ++cell)
14366  {
14367  // check if this cell has active grandchildren. note
14368  // that we know that it is patch_level_1, i.e. if one of
14369  // its children is active then so are all, and it isn't
14370  // going to have any grandchildren at all:
14371  if (cell->active() || cell->child(0)->active())
14372  continue;
14373 
14374  // cell is not active, and so are none of its
14375  // children. check the grandchildren. note that the
14376  // children are also patch_level_1, and so we only ever
14377  // need to check their first child
14378  const unsigned int n_children = cell->n_children();
14379  bool has_active_grandchildren = false;
14380 
14381  for (unsigned int i = 0; i < n_children; ++i)
14382  if (cell->child(i)->child(0)->active())
14383  {
14384  has_active_grandchildren = true;
14385  break;
14386  }
14387 
14388  if (has_active_grandchildren == false)
14389  continue;
14390 
14391 
14392  // ok, there are active grandchildren. see if either all
14393  // or none of them are flagged for coarsening
14394  unsigned int n_grandchildren = 0;
14395 
14396  // count all coarsen flags of the grandchildren.
14397  unsigned int n_coarsen_flags = 0;
14398 
14399  // cell is not a patch (of level 1) as it has a
14400  // grandchild. Is cell a patch of level 2?? Therefore:
14401  // find out whether all cell->child(i) are patches
14402  for (unsigned int c = 0; c < n_children; ++c)
14403  {
14404  // get at the child. by assumption (A), and the
14405  // check by which we got here, the child is not
14406  // active
14407  cell_iterator child = cell->child(c);
14408 
14409  const unsigned int nn_children = child->n_children();
14410  n_grandchildren += nn_children;
14411 
14412  // if child is found to be a patch of active cells
14413  // itself, then add up how many of its children are
14414  // supposed to be coarsened
14415  if (child->child(0)->active())
14416  for (unsigned int cc = 0; cc < nn_children; ++cc)
14417  if (child->child(cc)->coarsen_flag_set())
14418  ++n_coarsen_flags;
14419  }
14420 
14421  // if not all grandchildren are supposed to be coarsened
14422  // (e.g. because some simply don't have the flag set, or
14423  // because they are not active and therefore cannot
14424  // carry the flag), then remove the coarsen flag from
14425  // all of the active grandchildren. note that there may
14426  // be coarsen flags on the grandgrandchildren -- we
14427  // don't clear them here, but we'll get to them in later
14428  // iterations if necessary
14429  //
14430  // there is nothing we have to do if no coarsen flags
14431  // have been set at all
14432  if ((n_coarsen_flags != n_grandchildren) && (n_coarsen_flags > 0))
14433  for (unsigned int c = 0; c < n_children; ++c)
14434  {
14435  const cell_iterator child = cell->child(c);
14436  if (child->child(0)->active())
14437  for (unsigned int cc = 0; cc < child->n_children(); ++cc)
14438  child->child(cc)->clear_coarsen_flag();
14439  }
14440  }
14441  }
14442 
14444  //
14445  // at the boundary we could end up with cells with negative
14446  // volume or at least with a part, that is negative, if the
14447  // cell is refined anisotropically. we have to check, whether
14448  // that can happen
14451 
14453  // STEP 6:
14454  // take care of the requirement that no
14455  // double refinement is done at each face
14456  //
14457  // in case of anisotropic refinement it is only likely, but
14458  // not sure, that the cells, which are more refined along a
14459  // certain face common to two cells are on a higher
14460  // level. therefore we cannot be sure, that the requirement
14461  // of no double refinement is fulfilled after a single pass
14462  // of the following actions. We could just wait for the next
14463  // global loop. when this function terminates, the
14464  // requirement will be fulfilled. However, it might be faster
14465  // to insert an inner loop here.
14466  bool changed = true;
14467  while (changed)
14468  {
14469  changed = false;
14470  active_cell_iterator cell = last_active(), endc = end();
14471 
14472  for (; cell != endc; --cell)
14473  if (cell->refine_flag_set())
14474  {
14475  // loop over neighbors of cell
14476  for (unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell;
14477  ++i)
14478  {
14479  // only do something if the face is not at the
14480  // boundary and if the face will be refined with
14481  // the RefineCase currently flagged for
14482  if (cell->neighbor(i).state() == IteratorState::valid &&
14484  cell->refine_flag_set(), i) !=
14486  {
14487  // 1) if the neighbor has children: nothing to
14488  // worry about. 2) if the neighbor is active
14489  // and a coarser one, ensure, that its
14490  // refine_flag is set 3) if the neighbor is
14491  // active and as refined along the face as our
14492  // current cell, make sure, that no
14493  // coarsen_flag is set. if we remove the
14494  // coarsen flag of our neighbor,
14495  // fix_coarsen_flags() makes sure, that the
14496  // mother cell will not be coarsened
14497  if (cell->neighbor(i)->active())
14498  {
14499  if (cell->neighbor_is_coarser(i))
14500  {
14501  if (cell->neighbor(i)->coarsen_flag_set())
14502  cell->neighbor(i)->clear_coarsen_flag();
14503  // we'll set the refine flag for this
14504  // neighbor below. we note, that we
14505  // have changed something by setting
14506  // the changed flag to true. We do not
14507  // need to do so, if we just removed
14508  // the coarsen flag, as the changed
14509  // flag only indicates the need to
14510  // re-run the inner loop. however, we
14511  // only loop over cells flagged for
14512  // refinement here, so nothing to
14513  // worry about if we remove coarsen
14514  // flags
14515 
14516  if (dim == 2)
14517  {
14518  if (smooth_grid &
14520  changed =
14521  cell->neighbor(i)
14522  ->flag_for_face_refinement(
14523  cell
14524  ->neighbor_of_coarser_neighbor(i)
14525  .first,
14527  else
14528  {
14529  if (!cell->neighbor(i)
14530  ->refine_flag_set())
14531  changed = true;
14532  cell->neighbor(i)->set_refine_flag();
14533  }
14534  }
14535  else // i.e. if (dim==3)
14536  {
14537  // ugly situations might arise here,
14538  // consider the following situation, which
14539  // shows neighboring cells at the common
14540  // face, where the upper right element is
14541  // coarser at the given face. Now the upper
14542  // child element of the lower left wants to
14543  // refine according to cut_z, such that
14544  // there is a 'horizontal' refinement of the
14545  // face marked with #####
14546  //
14547  // / /
14548  // / /
14549  // *---------------*
14550  // | |
14551  // | |
14552  // | |
14553  // | |
14554  // | |
14555  // | | /
14556  // | |/
14557  // *---------------*
14558  //
14559  //
14560  // *---------------*
14561  // /| /|
14562  // / | ##### / |
14563  // | |
14564  // *---------------*
14565  // /| /|
14566  // / | / |
14567  // | |
14568  // *---------------*
14569  // / /
14570  // / /
14571  //
14572  // this introduces too many hanging nodes
14573  // and the neighboring (coarser) cell (upper
14574  // right) has to be refined. If it is only
14575  // refined according to cut_z, then
14576  // everything is ok:
14577  //
14578  // / /
14579  // / /
14580  // *---------------*
14581  // | |
14582  // | | /
14583  // | |/
14584  // *---------------*
14585  // | |
14586  // | | /
14587  // | |/
14588  // *---------------*
14589  //
14590  //
14591  // *---------------*
14592  // /| /|
14593  // / *---------------*
14594  // /| /|
14595  // *---------------*
14596  // /| /|
14597  // / | / |
14598  // | |
14599  // *---------------*
14600  // / /
14601  // / /
14602  //
14603  // if however the cell wants to refine
14604  // itself in an other way, or if we disallow
14605  // anisotropic smoothing, then simply
14606  // refining the neighbor isotropically is
14607  // not going to work, since this introduces
14608  // a refinement of face ##### with both
14609  // cut_x and cut_y, which is not possible:
14610  //
14611  // / / /
14612  // / / /
14613  // *-------*-------*
14614  // | | |
14615  // | | | /
14616  // | | |/
14617  // *-------*-------*
14618  // | | |
14619  // | | | /
14620  // | | |/
14621  // *-------*-------*
14622  //
14623  //
14624  // *---------------*
14625  // /| /|
14626  // / *---------------*
14627  // /| /|
14628  // *---------------*
14629  // /| /|
14630  // / | / |
14631  // | |
14632  // *---------------*
14633  // / /
14634  // / /
14635  //
14636  // thus, in this case we also need to refine
14637  // our current cell in the new direction:
14638  //
14639  // / / /
14640  // / / /
14641  // *-------*-------*
14642  // | | |
14643  // | | | /
14644  // | | |/
14645  // *-------*-------*
14646  // | | |
14647  // | | | /
14648  // | | |/
14649  // *-------*-------*
14650  //
14651  //
14652  // *-------*-------*
14653  // /| /| /|
14654  // / *-------*-------*
14655  // /| /| /|
14656  // *-------*-------*
14657  // /| / /|
14658  // / | / |
14659  // | |
14660  // *---------------*
14661  // / /
14662  // / /
14663 
14664  std::pair<unsigned int, unsigned int>
14665  nb_indices =
14666  cell->neighbor_of_coarser_neighbor(i);
14667  unsigned int refined_along_x = 0,
14668  refined_along_y = 0,
14669  to_be_refined_along_x = 0,
14670  to_be_refined_along_y = 0;
14671 
14672  const int this_face_index =
14673  cell->face_index(i);
14674 
14675  // step 1: detect, along which axis the face
14676  // is currently refined
14677  if ((this_face_index ==
14678  cell->neighbor(i)
14679  ->face(nb_indices.first)
14680  ->child_index(0)) ||
14681  (this_face_index ==
14682  cell->neighbor(i)
14683  ->face(nb_indices.first)
14684  ->child_index(1)))
14685  {
14686  // this might be an
14687  // anisotropic child. get the
14688  // face refine case of the
14689  // neighbors face and count
14690  // refinements in x and y
14691  // direction.
14692  RefinementCase<dim - 1> frc =
14693  cell->neighbor(i)
14694  ->face(nb_indices.first)
14695  ->refinement_case();
14696  if (frc & RefinementCase<dim>::cut_x)
14697  ++refined_along_x;
14698  if (frc & RefinementCase<dim>::cut_y)
14699  ++refined_along_y;
14700  }
14701  else
14702  // this has to be an isotropic
14703  // child
14704  {
14705  ++refined_along_x;
14706  ++refined_along_y;
14707  }
14708  // step 2: detect, along which axis the face
14709  // has to be refined given the current
14710  // refine flag
14711  RefinementCase<dim - 1> flagged_frc =
14713  cell->refine_flag_set(),
14714  i,
14715  cell->face_orientation(i),
14716  cell->face_flip(i),
14717  cell->face_rotation(i));
14718  if (flagged_frc &
14720  ++to_be_refined_along_x;
14721  if (flagged_frc &
14723  ++to_be_refined_along_y;
14724 
14725  // step 3: set the refine flag of the
14726  // (coarser and active) neighbor.
14727  if ((smooth_grid &
14729  cell->neighbor(i)->refine_flag_set())
14730  {
14731  if (refined_along_x +
14732  to_be_refined_along_x >
14733  1)
14734  changed |=
14735  cell->neighbor(i)
14736  ->flag_for_face_refinement(
14737  nb_indices.first,
14738  RefinementCase<dim -
14739  1>::cut_axis(0));
14740  if (refined_along_y +
14741  to_be_refined_along_y >
14742  1)
14743  changed |=
14744  cell->neighbor(i)
14745  ->flag_for_face_refinement(
14746  nb_indices.first,
14747  RefinementCase<dim -
14748  1>::cut_axis(1));
14749  }
14750  else
14751  {
14752  if (cell->neighbor(i)
14753  ->refine_flag_set() !=
14755  dim>::isotropic_refinement)
14756  changed = true;
14757  cell->neighbor(i)->set_refine_flag();
14758  }
14759 
14760  // step 4: if necessary (see above) add to
14761  // the refine flag of the current cell
14762  cell_iterator nb = cell->neighbor(i);
14763  RefinementCase<dim - 1> nb_frc =
14765  nb->refine_flag_set(),
14766  nb_indices.first,
14767  nb->face_orientation(nb_indices.first),
14768  nb->face_flip(nb_indices.first),
14769  nb->face_rotation(nb_indices.first));
14770  if ((nb_frc & RefinementCase<dim>::cut_x) &&
14771  !(refined_along_x ||
14772  to_be_refined_along_x))
14773  changed |= cell->flag_for_face_refinement(
14774  i,
14776  if ((nb_frc & RefinementCase<dim>::cut_y) &&
14777  !(refined_along_y ||
14778  to_be_refined_along_y))
14779  changed |= cell->flag_for_face_refinement(
14780  i,
14782  }
14783  } // if neighbor is coarser
14784  else // -> now the neighbor is not coarser
14785  {
14786  cell->neighbor(i)->clear_coarsen_flag();
14787  const unsigned int nb_nb =
14788  cell->neighbor_of_neighbor(i);
14789  const cell_iterator neighbor =
14790  cell->neighbor(i);
14791  RefinementCase<dim - 1> face_ref_case =
14793  neighbor->refine_flag_set(),
14794  nb_nb,
14795  neighbor->face_orientation(nb_nb),
14796  neighbor->face_flip(nb_nb),
14797  neighbor->face_rotation(nb_nb));
14798  RefinementCase<dim - 1> needed_face_ref_case =
14800  cell->refine_flag_set(),
14801  i,
14802  cell->face_orientation(i),
14803  cell->face_flip(i),
14804  cell->face_rotation(i));
14805  // if the neighbor wants to refine the
14806  // face with cut_x and we want cut_y
14807  // or vice versa, we have to refine
14808  // isotropically at the given face
14809  if ((face_ref_case ==
14811  needed_face_ref_case ==
14813  (face_ref_case ==
14815  needed_face_ref_case ==
14817  {
14818  changed = cell->flag_for_face_refinement(
14819  i, face_ref_case);
14820  neighbor->flag_for_face_refinement(
14821  nb_nb, needed_face_ref_case);
14822  }
14823  }
14824  }
14825  else //-> the neighbor is not active
14826  {
14827  RefinementCase<dim - 1>
14828  face_ref_case = cell->face(i)->refinement_case(),
14829  needed_face_ref_case =
14831  cell->refine_flag_set(),
14832  i,
14833  cell->face_orientation(i),
14834  cell->face_flip(i),
14835  cell->face_rotation(i));
14836  // if the face is refined with cut_x and
14837  // we want cut_y or vice versa, we have to
14838  // refine isotropically at the given face
14839  if ((face_ref_case == RefinementCase<dim>::cut_x &&
14840  needed_face_ref_case ==
14842  (face_ref_case == RefinementCase<dim>::cut_y &&
14843  needed_face_ref_case ==
14845  changed =
14846  cell->flag_for_face_refinement(i,
14847  face_ref_case);
14848  }
14849  }
14850  }
14851  }
14852  }
14853 
14855  // STEP 7:
14856  // take care that no double refinement
14857  // is done at each line in 3d or higher
14858  // dimensions.
14861 
14863  // STEP 8:
14864  // make sure that all children of each
14865  // cell are either flagged for coarsening
14866  // or none of the children is
14868  // get the refinement and coarsening
14869  // flags
14870  std::vector<bool> flags_after_loop[2];
14871  save_coarsen_flags(flags_after_loop[0]);
14872  save_refine_flags(flags_after_loop[1]);
14873 
14874  // find out whether something was
14875  // changed in this loop
14876  mesh_changed_in_this_loop =
14877  ((flags_before_loop[0] != flags_after_loop[0]) ||
14878  (flags_before_loop[1] != flags_after_loop[1]));
14879 
14880  // set the flags for the next loop
14881  // already
14882  flags_before_loop[0].swap(flags_after_loop[0]);
14883  flags_before_loop[1].swap(flags_after_loop[1]);
14884  }
14885  while (mesh_changed_in_this_loop);
14886 
14887 
14888  // find out whether something was really changed in this
14889  // function. Note that @p{flags_before_loop} represents the state
14890  // after the last loop, i.e. the present state
14891  return ((flags_before[0] != flags_before_loop[0]) ||
14892  (flags_before[1] != flags_before_loop[1]));
14893 }
14894 
14895 
14896 
14897 template <int dim, int spacedim>
14898 void
14900  const unsigned int magic_number1,
14901  const std::vector<bool> &v,
14902  const unsigned int magic_number2,
14903  std::ostream & out)
14904 {
14905  const unsigned int N = v.size();
14906  unsigned char * flags = new unsigned char[N / 8 + 1];
14907  for (unsigned int i = 0; i < N / 8 + 1; ++i)
14908  flags[i] = 0;
14909 
14910  for (unsigned int position = 0; position < N; ++position)
14911  flags[position / 8] |= (v[position] ? (1 << (position % 8)) : 0);
14912 
14913  AssertThrow(out, ExcIO());
14914 
14915  // format:
14916  // 0. magic number
14917  // 1. number of flags
14918  // 2. the flags
14919  // 3. magic number
14920  out << magic_number1 << ' ' << N << std::endl;
14921  for (unsigned int i = 0; i < N / 8 + 1; ++i)
14922  out << static_cast<unsigned int>(flags[i]) << ' ';
14923 
14924  out << std::endl << magic_number2 << std::endl;
14925 
14926  delete[] flags;
14927 
14928  AssertThrow(out, ExcIO());
14929 }
14930 
14931 
14932 template <int dim, int spacedim>
14933 void
14934 Triangulation<dim, spacedim>::read_bool_vector(const unsigned int magic_number1,
14935  std::vector<bool> &v,
14936  const unsigned int magic_number2,
14937  std::istream & in)
14938 {
14939  AssertThrow(in, ExcIO());
14940 
14941  unsigned int magic_number;
14942  in >> magic_number;
14943  AssertThrow(magic_number == magic_number1, ExcGridReadError());
14944 
14945  unsigned int N;
14946  in >> N;
14947  v.resize(N);
14948 
14949  unsigned char * flags = new unsigned char[N / 8 + 1];
14950  unsigned short int tmp;
14951  for (unsigned int i = 0; i < N / 8 + 1; ++i)
14952  {
14953  in >> tmp;
14954  flags[i] = tmp;
14955  }
14956 
14957  for (unsigned int position = 0; position != N; ++position)
14958  v[position] = (flags[position / 8] & (1 << (position % 8)));
14959 
14960  in >> magic_number;
14961  AssertThrow(magic_number == magic_number2, ExcGridReadError());
14962 
14963  delete[] flags;
14964 
14965  AssertThrow(in, ExcIO());
14966 }
14967 
14968 
14969 
14970 template <int dim, int spacedim>
14971 std::size_t
14973 {
14974  std::size_t mem = 0;
14976  for (unsigned int i = 0; i < levels.size(); ++i)
14980  mem += sizeof(manifold);
14981  mem += sizeof(smooth_grid);
14983  mem += sizeof(faces);
14984  if (faces)
14986 
14987  return mem;
14988 }
14989 
14990 
14991 
14992 template <int dim, int spacedim>
14994 {
14995  // don't do anything here. the compiler will automatically convert
14996  // any exceptions created by the destructors of the member variables
14997  // into abort() in order to satisfy the throw()/noexcept
14998  // specification
14999 }
15000 
15001 
15002 // explicit instantiations
15003 #include "tria.inst"
15004 
15005 DEAL_II_NAMESPACE_CLOSE
std::vector< CellData< 1 > > boundary_lines
Definition: tria.h:258
boost::signals2::signal< void(const Triangulation< dim, spacedim > &destination_tria)> copy
Definition: tria.h:2189
TriaIterator< TriaAccessor< dim-1, dim, spacedim >> face_iterator
Definition: tria.h:1540
::internal::TriangulationImplementation::NumberCache< dim > number_cache
Definition: tria.h:3697
unsigned int n_raw_faces() const
Definition: tria.cc:12544
boost::signals2::signal< void()> post_refinement
Definition: tria.h:2149
active_line_iterator begin_active_line(const unsigned int level=0) const
Definition: tria.cc:12260
virtual void copy_triangulation(const Triangulation< dim, spacedim > &other_tria)
Definition: tria.cc:10473
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
const types::manifold_id flat_manifold_id
Definition: types.h:243
static const unsigned int invalid_unsigned_int
Definition: types.h:173
static::ExceptionBase & ExcInvalidLevel(int arg1)
void load_user_flags_line(std::istream &in)
Definition: tria.cc:11240
unsigned int manifold_id
Definition: types.h:123
boost::signals2::signal< void(const typename Triangulation< dim, spacedim >::cell_iterator &cell)> pre_coarsening_on_cell
Definition: tria.h:2169
#define AssertNothrow(cond, exc)
Definition: exceptions.h:1278
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:420
static::ExceptionBase & ExcInternalErrorOnCell(int arg1)
const types::subdomain_id invalid_subdomain_id
Definition: types.h:255
void clear_user_flags()
Definition: tria.cc:11096
line_iterator begin_line(const unsigned int level=0) const
Definition: tria.cc:12244
virtual void create_triangulation_compatibility(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
Definition: tria.cc:10536
cell_iterator end() const
Definition: tria.cc:12004
virtual unsigned int n_global_levels() const
static void prepare_refinement_dim_dependent(const Triangulation< dim, spacedim > &)
Definition: tria.cc:9837
static RefinementCase< 1 > line_refinement_case(const RefinementCase< dim > &cell_refinement_case, const unsigned int line_no)
void save_user_flags_hex(std::ostream &out) const
Definition: tria.cc:11418
unsigned int n_active_lines() const
Definition: tria.cc:12743
active_face_iterator begin_active_face() const
Definition: tria.cc:12117
unsigned int n_used_vertices() const
Definition: tria.cc:13091
static::ExceptionBase & ExcIO()
Subscriptor & operator=(const Subscriptor &)
Definition: subscriptor.cc:136
std::vector< GridTools::PeriodicFacePair< cell_iterator > > periodic_face_pairs_level_0
Definition: tria.h:3426
Task< RT > new_task(const std::function< RT()> &function)
TriaActiveIterator< TriaAccessor< dim-1, dim, spacedim >> active_face_iterator
Definition: tria.h:1554
bool check_consistency(const unsigned int dim) const
Definition: tria.cc:48
unsigned int n_faces() const
Definition: tria.cc:12525
IteratorRange< active_cell_iterator > active_cell_iterators() const
Definition: tria.cc:12060
std::vector< Point< spacedim > > vertices
Definition: tria.h:3662
std::map< types::manifold_id, std::unique_ptr< const Manifold< dim, spacedim > > > manifold
Definition: tria.h:3674
static unsigned int line_to_cell_vertices(const unsigned int line, const unsigned int vertex)
void set_all_refine_flags()
Definition: tria.cc:10756
void load_user_flags(std::istream &in)
Definition: tria.cc:11156
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const =0
bool anisotropic_refinement
Definition: tria.h:3679
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:14934
static::ExceptionBase & ExcGridReadError()
void clear_user_flags_quad()
Definition: tria.cc:11047
face_iterator begin_face() const
Definition: tria.cc:12096
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:4191
void save_user_pointers_quad(std::vector< void * > &v) const
Definition: tria.cc:11821
static::ExceptionBase & ExcCellHasNegativeMeasure(int arg1)
void flip_all_direction_flags()
Definition: tria.cc:10744
raw_hex_iterator begin_raw_hex(const unsigned int level=0) const
Definition: tria.cc:12373
STL namespace.
const std::vector< bool > & get_used_vertices() const
Definition: tria.cc:13104
cell_iterator last() const
Definition: tria.cc:11955
line_iterator end_line() const
Definition: tria.cc:12276
#define AssertThrow(cond, exc)
Definition: exceptions.h:1329
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:1372
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:14899
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
cell_iterator begin(const unsigned int level=0) const
Definition: tria.cc:11915
void execute_coarsening()
Definition: tria.cc:13399
static Triangulation< 2, spacedim >::DistortedCellList execute_refinement(Triangulation< 2, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:4880
void load_user_flags_quad(std::istream &in)
Definition: tria.cc:11363
void save_user_flags_line(std::ostream &out) const
Definition: tria.cc:11226
unsigned int n_active_cells() const
Definition: tria.cc:12509
std::bitset< 3 > orientation
Definition: grid_tools.h:2234
unsigned long long int global_dof_index
Definition: types.h:72
void load_user_pointers_line(const std::vector< void * > &v)
Definition: tria.cc:11806
unsigned int n_levels() const
void set_manifold(const types::manifold_id number, const Manifold< dim, spacedim > &manifold_object)
Definition: tria.cc:10268
IteratorRange< cell_iterator > cell_iterators() const
Definition: tria.cc:12051
virtual ~DistortedCellList() noexceptoverride
Definition: tria.cc:14993
static::ExceptionBase & ExcFacesHaveNoLevel()
std::unique_ptr<::internal::TriangulationImplementation::TriaFaces< dim > > faces
Definition: tria.h:3656
bool get_anisotropic_refinement_flag() const
Definition: tria.cc:10921
static::ExceptionBase & ExcInteriorQuadCantBeBoundary(int arg1, int arg2, int arg3, int arg4, types::boundary_id arg5)
vertex_iterator end_vertex() const
Definition: tria.cc:12199
virtual void add_periodicity(const std::vector< GridTools::PeriodicFacePair< cell_iterator >> &)
Definition: tria.cc:13200
static Triangulation< 3, spacedim >::DistortedCellList execute_refinement(Triangulation< 3, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:5258
void load_coarsen_flags(std::istream &out)
Definition: tria.cc:10889
void load_user_flags_hex(std::istream &in)
Definition: tria.cc:11432
virtual void execute_coarsening_and_refinement()
Definition: tria.cc:13229
static::ExceptionBase & ExcGridHasInvalidCell(int arg1)
void save_user_indices_hex(std::vector< unsigned int > &v) const
Definition: tria.cc:11643
unsigned int n_active_quads() const
Definition: tria.cc:12977
void join() const
void save_coarsen_flags(std::ostream &out) const
Definition: tria.cc:10875
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:13220
void save_user_indices(std::vector< unsigned int > &v) const
Definition: tria.cc:11468
virtual bool prepare_coarsening_and_refinement()
Definition: tria.cc:13935
static::ExceptionBase & ExcMessage(std::string arg1)
unsigned int n_raw_hexs(const unsigned int level) const
Definition: tria.cc:13015
boost::signals2::signal< void()> pre_refinement
Definition: tria.h:2142
static::ExceptionBase & ExcImpossibleInDim(int arg1)
unsigned int n_raw_lines() const
Definition: tria.cc:12724
static::ExceptionBase & ExcTriangulationNotEmpty(int arg1, int arg2)
void reset_active_cell_indices()
Definition: tria.cc:13270
DistortedCellList execute_refinement()
Definition: tria.cc:13367
const bool check_for_distorted_cells
Definition: tria.h:3686
unsigned int subdomain_id
Definition: types.h:43
quad_iterator end_quad() const
Definition: tria.cc:12360
static::ExceptionBase & ExcNonOrientableTriangulation()
Triangulation(const MeshSmoothing smooth_grid=none, const bool check_for_distorted_cells=false)
Definition: tria.cc:10129
unsigned int n_cells() const
Definition: tria.cc:12501
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:408
void clear_user_flags_hex()
Definition: tria.cc:11087
void load_user_indices_line(const std::vector< unsigned int > &v)
Definition: tria.cc:11594
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)
virtual void create_triangulation(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
Definition: tria.cc:10556
active_cell_iterator end_active(const unsigned int level) const
Definition: tria.cc:12039
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
Definition: tria.cc:12071
#define Assert(cond, exc)
Definition: exceptions.h:1227
Signals signals
Definition: tria.h:2287
static void prevent_distorted_boundary_cells(const Triangulation< 1, spacedim > &)
std::vector< types::manifold_id > get_manifold_ids() const
Definition: tria.cc:10450
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)
void save_user_flags(std::ostream &out) const
Definition: tria.cc:11107
hex_iterator end_hex() const
Definition: tria.cc:12435
unsigned int n_raw_quads() const
Definition: tria.cc:12958
boost::signals2::signal< void()> clear
Definition: tria.h:2204
unsigned int n_hexs() const
Definition: tria.cc:12997
void set_all_manifold_ids(const types::manifold_id number)
Definition: tria.cc:10310
static::ExceptionBase & ExcInteriorLineCantBeBoundary(int arg1, int arg2, types::boundary_id arg3)
void load_user_pointers_quad(const std::vector< void * > &v)
Definition: tria.cc:11839
active_vertex_iterator begin_active_vertex() const
Definition: tria.cc:12190
std::list< typename Triangulation< dim, spacedim >::cell_iterator > distorted_cells
Definition: tria.h:1623
std::unique_ptr< std::map< unsigned int, types::manifold_id > > vertex_to_manifold_id_map_1d
Definition: tria.h:3737
std::vector< bool > vertices_used
Definition: tria.h:3667
virtual bool has_hanging_nodes() const
Definition: tria.cc:12639
void reset_all_manifolds()
Definition: tria.cc:10302
boost::signals2::signal< void()> mesh_movement
Definition: tria.h:2158
void load_user_indices(const std::vector< unsigned int > &v)
Definition: tria.cc:11500
void save_user_pointers(std::vector< void * > &v) const
Definition: tria.cc:11724
raw_line_iterator begin_raw_line(const unsigned int level=0) const
Definition: tria.cc:12220
static::ExceptionBase & ExcMultiplySetLineInfoOfLine(int arg1, int arg2)
void clear_despite_subscriptions()
Definition: tria.cc:13351
const Manifold< dim, spacedim > & get_manifold(const types::manifold_id number) const
Definition: tria.cc:10394
TriaRawIterator< CellAccessor< dim, spacedim >> raw_cell_iterator
Definition: tria.h:3449
int face(const unsigned int i) const
Definition: tria_object.h:168
std::vector< types::boundary_id > get_boundary_ids() const
Definition: tria.cc:10417
hex_iterator begin_hex(const unsigned int level=0) const
Definition: tria.cc:12403
raw_cell_iterator begin_raw(const unsigned int level=0) const
Definition: tria.cc:11895
void save_refine_flags(std::ostream &out) const
Definition: tria.cc:10807
unsigned int n_lines() const
Definition: tria.cc:12651
std::map< std::pair< cell_iterator, unsigned int >, std::pair< std::pair< cell_iterator, unsigned int >, std::bitset< 3 > > > periodic_face_map
Definition: tria.h:3434
#define DeclException5(Exception5, type1, type2, type3, type4, type5, outsequence)
Definition: exceptions.h:459
vertex_iterator begin_vertex() const
Definition: tria.cc:12161
IteratorState::IteratorStates state() const
void save_user_indices_line(std::vector< unsigned int > &v) const
Definition: tria.cc:11580
virtual void set_mesh_smoothing(const MeshSmoothing mesh_smoothing)
Definition: tria.cc:10247
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:1875
virtual types::subdomain_id locally_owned_subdomain() const
Definition: tria.cc:13173
boost::signals2::signal< void()> create
Definition: tria.h:2133
active_cell_iterator last_active() const
Definition: tria.cc:11983
std::unique_ptr< std::map< unsigned int, types::boundary_id > > vertex_to_boundary_id_map_1d
Definition: tria.h:3714
std::vector< std::unique_ptr< ::internal::TriangulationImplementation::TriaLevel< dim > > > levels
Definition: tria.h:3648
bool vertex_used(const unsigned int index) const
IteratorRange< active_cell_iterator > active_cell_iterators_on_level(const unsigned int level) const
Definition: tria.cc:12082
void save_user_pointers_line(std::vector< void * > &v) const
Definition: tria.cc:11792
active_quad_iterator begin_active_quad(const unsigned int level=0) const
Definition: tria.cc:12344
virtual types::global_dof_index n_global_active_cells() const
Definition: tria.cc:12516
virtual const MeshSmoothing & get_mesh_smoothing() const
Definition: tria.cc:10259
void load_user_indices_hex(const std::vector< unsigned int > &v)
Definition: tria.cc:11661
static::ExceptionBase & ExcLineInexistant(int arg1, int arg2)
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
void swap(Vector< Number > &u, Vector< Number > &v)
Definition: vector.h:1353
void reset_manifold(const types::manifold_id manifold_number)
Definition: tria.cc:10290
static void alternating_form_at_vertices(const Point< spacedim >(&vertices)[vertices_per_cell], Tensor< spacedim-dim, spacedim >(&forms)[vertices_per_cell])
void save_user_indices_quad(std::vector< unsigned int > &v) const
Definition: tria.cc:11608
unsigned int n_raw_cells(const unsigned int level) const
Definition: tria.cc:12580
static bool coarsening_allowed(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
Definition: tria.cc:10047
const types::manifold_id invalid_manifold_id
Definition: types.h:234
unsigned int n_active_faces() const
Definition: tria.cc:12561
void fix_coarsen_flags()
Definition: tria.cc:13474
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:2278
void save_user_pointers_hex(std::vector< void * > &v) const
Definition: tria.cc:11856
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:1665
void update_periodic_face_map()
Definition: tria.cc:13288
std::vector< unsigned int > n_active_hexes_level
Definition: tria.h:467
face_iterator end_face() const
Definition: tria.cc:12138
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 3 > &number_cache)
Definition: tria.cc:1566
Definition: mpi.h:55
raw_cell_iterator end_raw(const unsigned int level) const
Definition: tria.cc:12015
std::vector< CellData< 2 > > boundary_quads
Definition: tria.h:266
MeshSmoothing smooth_grid
Definition: tria.h:3379
virtual ~Triangulation() override
Definition: tria.cc:10203
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:444
quad_iterator begin_quad(const unsigned int level=0) const
Definition: tria.cc:12328
unsigned int n_quads() const
Definition: tria.cc:12909
std::vector< unsigned int > n_active_lines_level
Definition: tria.h:348
active_hex_iterator begin_active_hex(const unsigned int level=0) const
Definition: tria.cc:12419
void refine_global(const unsigned int times=1)
Definition: tria.cc:10773
static::ExceptionBase & ExcNotImplemented()
Iterator points to a valid object.
Definition: table.h:37
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:432
void load_user_pointers_hex(const std::vector< void * > &v)
Definition: tria.cc:11874
void set_all_manifold_ids_on_boundary(const types::manifold_id number)
Definition: tria.cc:10329
static::ExceptionBase & ExcQuadInexistant(int arg1, int arg2, int arg3, int arg4)
const types::boundary_id internal_face_boundary_id
Definition: types.h:223
void load_user_pointers(const std::vector< void * > &v)
Definition: tria.cc:11755
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: tria.cc:11935
std::vector< unsigned int > n_active_quads_level
Definition: tria.h:407
void clear_user_flags_line()
Definition: tria.cc:11006
static::ExceptionBase & ExcBoundaryIdNotFound(types::boundary_id arg1)
unsigned int max_adjacent_cells() const
Definition: tria.cc:13138
static Triangulation< 1, spacedim >::DistortedCellList execute_refinement(Triangulation< 1, spacedim > &triangulation, const bool)
Definition: tria.cc:4634
void set_face(const unsigned int i, const int index)
Definition: tria_object.h:179
unsigned int n_vertices() const
unsigned int boundary_id
Definition: types.h:111
void clear_user_data()
Definition: tria.cc:10971
Triangulation & operator=(Triangulation< dim, spacedim > &&tria) noexcept
Definition: tria.cc:10178
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:3315
unsigned int n_active_hexs() const
Definition: tria.cc:13023
raw_quad_iterator begin_raw_quad(const unsigned int level=0) const
Definition: tria.cc:12290
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)
TriaIterator< CellAccessor< dim, spacedim >> cell_iterator
Definition: tria.h:1507
TriaActiveIterator< CellAccessor< dim, spacedim >> active_cell_iterator
Definition: tria.h:1525
void load_user_indices_quad(const std::vector< unsigned int > &v)
Definition: tria.cc:11626
boost::signals2::signal< void()> any_change
Definition: tria.h:2215
virtual void clear()
Definition: tria.cc:10232
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
void save_user_flags_quad(std::ostream &out) const
Definition: tria.cc:11349
void load_refine_flags(std::istream &in)
Definition: tria.cc:10821
static::ExceptionBase & ExcInternalError()
Triangulation< dim, spacedim > & get_triangulation()
Definition: tria.cc:13182
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::TriangulationImplementation::NumberCache< 2 > &number_cache)
Definition: tria.cc:1460
virtual std::size_t memory_consumption() const
Definition: tria.cc:14972