Reference documentation for deal.II version 8.4.2
tria.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2016 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 at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #include <deal.II/base/memory_consumption.h>
18 #include <deal.II/base/table.h>
19 #include <deal.II/base/geometry_info.h>
20 #include <deal.II/base/std_cxx11/bind.h>
21 
22 #include <deal.II/grid/tria.h>
23 #include <deal.II/grid/tria_levels.h>
24 #include <deal.II/grid/tria_faces.h>
25 #include <deal.II/grid/manifold.h>
26 #include <deal.II/grid/tria_boundary.h>
27 #include <deal.II/grid/tria_accessor.h>
28 #include <deal.II/grid/tria_iterator.h>
29 #include <deal.II/grid/grid_tools.h>
30 #include <deal.II/grid/magic_numbers.h>
31 #include <deal.II/fe/mapping_q1.h>
32 #include <deal.II/lac/vector.h>
33 #include <deal.II/lac/full_matrix.h>
34 
35 #include <algorithm>
36 #include <numeric>
37 #include <map>
38 #include <list>
39 #include <cmath>
40 #include <functional>
41 
42 #include <deal.II/base/std_cxx11/array.h>
43 
44 DEAL_II_NAMESPACE_OPEN
45 
46 bool
47 SubCellData::check_consistency (const unsigned int dim) const
48 {
49  switch (dim)
50  {
51  case 1:
52  return ((boundary_lines.size() == 0) &&
53  (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 Triangulation
64  {
65 
67  :
68  n_levels (0),
69  n_lines (0),
70  n_active_lines (0)
71  // all other fields are
72  // default constructed
73  {}
74 
75 
76 
77  std::size_t
79  {
80  return (MemoryConsumption::memory_consumption (n_levels) +
83  MemoryConsumption::memory_consumption (n_active_lines) +
84  MemoryConsumption::memory_consumption (n_active_lines_level));
85  }
86 
87 
89  n_quads (0),
90  n_active_quads (0)
91  // all other fields are
92  // default constructed
93  {}
94 
95 
96 
97  std::size_t
99  {
102  MemoryConsumption::memory_consumption (n_quads_level) +
103  MemoryConsumption::memory_consumption (n_active_quads) +
104  MemoryConsumption::memory_consumption (n_active_quads_level));
105  }
106 
107 
108 
110  n_hexes (0),
111  n_active_hexes (0)
112  // all other fields are
113  // default constructed
114  {}
115 
116 
117 
118  std::size_t
120  {
123  MemoryConsumption::memory_consumption (n_hexes_level) +
124  MemoryConsumption::memory_consumption (n_active_hexes) +
125  MemoryConsumption::memory_consumption (n_active_hexes_level));
126  }
127  }
128 }
129 
130 // anonymous namespace for internal helper functions
131 namespace
132 {
133  // return whether the given cell is
134  // patch_level_1, i.e. determine
135  // whether either all or none of
136  // its children are further
137  // refined. this function can only
138  // be called for non-active cells.
139  template <int dim, int spacedim>
140  bool cell_is_patch_level_1 (const TriaIterator<::CellAccessor<dim, spacedim> > &cell)
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) || (n_active_children == cell->n_children());
150  }
151 
152 
153 
154  // return, whether a given @p cell will be
155  // coarsened, which is the case if all
156  // children are active and have their coarsen
157  // flag set. In case only part of the coarsen
158  // flags are set, remove them.
159  template <int dim, int spacedim>
160  bool cell_will_be_coarsened (const TriaIterator<::CellAccessor<dim,spacedim> > &cell)
161  {
162  // only cells with children should be
163  // considered for coarsening
164 
165  if (cell->has_children())
166  {
167  unsigned int children_to_coarsen=0;
168  const unsigned int n_children=cell->n_children();
169 
170  for (unsigned int c=0; c<n_children; ++c)
171  if (cell->child(c)->active() &&
172  cell->child(c)->coarsen_flag_set())
173  ++children_to_coarsen;
174  if (children_to_coarsen==n_children)
175  return true;
176  else
177  for (unsigned int c=0; c<n_children; ++c)
178  if (cell->child(c)->active())
179  cell->child(c)->clear_coarsen_flag();
180  }
181  // no children, so no coarsening
182  // possible. however, no children also
183  // means that this cell will be in the same
184  // state as if it had children and was
185  // coarsened. So, what should we return -
186  // false or true?
187  // make sure we do not have to do this at
188  // all...
189  Assert(cell->has_children(), ExcInternalError());
190  // ... and then simply return false
191  return false;
192  }
193 
194 
195  // return, whether the face @p face_no of the
196  // given @p cell will be refined after the
197  // current refinement step, considering
198  // refine and coarsen flags and considering
199  // only those refinemnts that will be caused
200  // by the neighboring cell.
201 
202  // this function is used on both active cells
203  // and cells with children. on cells with
204  // children it also of interest to know 'how'
205  // the face will be refined. thus there is an
206  // additional third argument @p
207  // expected_face_ref_case returning just
208  // that. be aware, that this vriable will
209  // only contain useful information if this
210  // function is called for an active cell.
211  //
212  // thus, this is an internal function, users
213  // should call one of the two alternatives
214  // following below.
215  template <int dim, int spacedim>
216  bool
217  face_will_be_refined_by_neighbor_internal(const TriaIterator<::CellAccessor<dim,spacedim> > &cell,
218  const unsigned int face_no,
219  RefinementCase<dim-1> &expected_face_ref_case)
220  {
221  // first of all: set the default value for
222  // expected_face_ref_case, which is no
223  // refinement at all
224  expected_face_ref_case=RefinementCase<dim-1>::no_refinement;
225 
226  const typename Triangulation<dim,spacedim>::cell_iterator neighbor=cell->neighbor(face_no);
227 
228  // If we are at the boundary, there is no
229  // neighbor which could refine the face
230  if (neighbor.state()!=IteratorState::valid)
231  return false;
232 
233  if (neighbor->has_children())
234  {
235  // if the neighbor is refined, it may be
236  // coarsened. if so, then it won't refine
237  // the face, no matter what else happens
238  if (cell_will_be_coarsened(neighbor))
239  return false;
240  else
241  // if the neighor is refined, then he
242  // is also refined at our current
243  // face. He will stay so without
244  // coarsening, so return true in that
245  // case.
246  {
247  expected_face_ref_case=cell->face(face_no)->refinement_case();
248  return true;
249  }
250  }
251 
252  // now, the neighbor is not refined, but
253  // perhaps he will be
254  const RefinementCase<dim> nb_ref_flag=neighbor->refine_flag_set();
255  if (nb_ref_flag != RefinementCase<dim>::no_refinement)
256  {
257  // now we need to know, which of the
258  // neighbors faces points towards us
259  const unsigned int neighbor_neighbor=cell->neighbor_face_no(face_no);
260  // check, whether the cell will be
261  // refined in a way that refines our
262  // face
263  const RefinementCase<dim-1> face_ref_case=
265  neighbor_neighbor,
266  neighbor->face_orientation(neighbor_neighbor),
267  neighbor->face_flip(neighbor_neighbor),
268  neighbor->face_rotation(neighbor_neighbor));
269  if (face_ref_case != RefinementCase<dim-1>::no_refinement)
270  {
271  const typename Triangulation<dim,spacedim>::face_iterator neighbor_face=neighbor->face(neighbor_neighbor);
272  const int this_face_index=cell->face_index(face_no);
273 
274  // there are still two basic
275  // possibilities here: the neighbor
276  // might be coarser or as coarse
277  // as we are
278  if (neighbor_face->index()==this_face_index)
279  // the neighbor is as coarse as
280  // we are and will be refined at
281  // the face of consideration, so
282  // return true
283  {
284  expected_face_ref_case = face_ref_case;
285  return true;
286  }
287  else
288  {
289 
290  // the neighbor is coarser.
291  // this is the most complicated
292  // case. It might be, that the
293  // neighbor's face will be
294  // refined, but that we will
295  // not see this, as we are
296  // refined in a similar way.
297 
298  // so, the neighbor's face must
299  // have children. check, if our
300  // cell's face is one of these
301  // (it could also be a
302  // grand_child)
303  for (unsigned int c=0; c<neighbor_face->n_children(); ++c)
304  if (neighbor_face->child_index(c)==this_face_index)
305  {
306  // if the flagged refine
307  // case of the face is a
308  // subset or the same as
309  // the current refine case,
310  // then the face, as seen
311  // from our cell, won't be
312  // refined by the neighbor
313  if ((neighbor_face->refinement_case() | face_ref_case)
314  == neighbor_face->refinement_case())
315  return false;
316  else
317  {
318  // if we are active, we
319  // must be an
320  // anisotropic child
321  // and the coming
322  // face_ref_case is
323  // isotropic. Thus,
324  // from our cell we
325  // will see exactly the
326  // opposite refine case
327  // that the face has
328  // now...
329  Assert(face_ref_case==RefinementCase<dim-1>::isotropic_refinement, ExcInternalError());
330  expected_face_ref_case = ~neighbor_face->refinement_case();
331  return true;
332  }
333  }
334 
335  // so, obviously we were not
336  // one of the children, but a
337  // grandchild. This is only
338  // possible in 3d.
339  Assert(dim==3, ExcInternalError());
340  // In that case, however, no
341  // matter what the neighbor
342  // does, he won't be finer
343  // after the next refinement
344  // step.
345  return false;
346  }
347  }// if face will be refined
348  }// if neighbor is flagged for refinement
349 
350  // no cases left, so the neighbor will not
351  // refine the face
352  return false;
353  }
354 
355  // version of above function for both active
356  // and non-active cells
357  template <int dim, int spacedim>
358  bool
359  face_will_be_refined_by_neighbor(const TriaIterator<::CellAccessor<dim, spacedim> > &cell,
360  const unsigned int face_no)
361  {
362  RefinementCase<dim-1> dummy = RefinementCase<dim-1>::no_refinement;
363  return face_will_be_refined_by_neighbor_internal(cell, face_no, dummy);
364  }
365 
366  // version of above function for active cells
367  // only. Additionally returning the refine
368  // case (to come) of the face under
369  // consideration
370  template <int dim, int spacedim>
371  bool
372  face_will_be_refined_by_neighbor(const TriaActiveIterator<::CellAccessor<dim,spacedim> > &cell,
373  const unsigned int face_no,
374  RefinementCase<dim-1> &expected_face_ref_case)
375  {
376  return face_will_be_refined_by_neighbor_internal(cell, face_no,
377  expected_face_ref_case);
378  }
379 
380 
381 
382  template <int dim, int spacedim>
383  bool
384  satisfies_level1_at_vertex_rule (const Triangulation<dim,spacedim> &triangulation)
385  {
386  std::vector<unsigned int> min_adjacent_cell_level (triangulation.n_vertices(),
387  triangulation.n_levels());
388  std::vector<unsigned int> max_adjacent_cell_level (triangulation.n_vertices(),
389  0);
390 
392  cell = triangulation.begin_active();
393  cell != triangulation.end(); ++cell)
394  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
395  {
396  min_adjacent_cell_level[cell->vertex_index(v)]
397  = std::min<unsigned int>
398  (min_adjacent_cell_level[cell->vertex_index(v)],
399  cell->level());
400  max_adjacent_cell_level[cell->vertex_index(v)]
401  = std::max<unsigned int> (min_adjacent_cell_level[cell->vertex_index(v)],
402  cell->level());
403  }
404 
405  for (unsigned int k=0; k<triangulation.n_vertices(); ++k)
406  if (triangulation.vertex_used(k))
407  if (max_adjacent_cell_level[k] -
408  min_adjacent_cell_level[k] > 1)
409  return false;
410  return true;
411  }
412 
413 
414 
421  template <int dim, int spacedim>
422  std::vector<unsigned int>
423  count_cells_bounded_by_line (const Triangulation<dim,spacedim> &triangulation)
424  {
425  if (dim >= 2)
426  {
427  std::vector<unsigned int> line_cell_count(triangulation.n_raw_lines(),0);
429  cell=triangulation.begin(),
430  endc=triangulation.end();
431  for (; cell!=endc; ++cell)
432  for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
433  ++line_cell_count[cell->line_index(l)];
434  return line_cell_count;
435  }
436  else
437  return std::vector<unsigned int>();
438  }
439 
440 
441 
442 
449  template <int dim, int spacedim>
450  std::vector<unsigned int>
451  count_cells_bounded_by_quad (const Triangulation<dim,spacedim> &triangulation)
452  {
453  if (dim >= 3)
454  {
455  std::vector<unsigned int> quad_cell_count (triangulation.n_raw_quads(),0);
457  cell=triangulation.begin(),
458  endc=triangulation.end();
459  for (; cell!=endc; ++cell)
460  for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
461  ++quad_cell_count[cell->quad_index(q)];
462  return quad_cell_count;
463  }
464  else
465  return std::vector<unsigned int>();
466  }
467 
468 
469 
481  void
482  reorder_compatibility (const std::vector<CellData<1> > &,
483  const SubCellData &)
484  {
485  // nothing to do here: the format
486  // hasn't changed for 1d
487  }
488 
489 
490  void
491  reorder_compatibility (std::vector<CellData<2> > &cells,
492  const SubCellData &)
493  {
494  for (unsigned int cell=0; cell<cells.size(); ++cell)
495  std::swap(cells[cell].vertices[2],cells[cell].vertices[3]);
496  }
497 
498 
499  void
500  reorder_compatibility (std::vector<CellData<3> > &cells,
501  SubCellData &subcelldata)
502  {
503  unsigned int tmp[GeometryInfo<3>::vertices_per_cell];
504  for (unsigned int cell=0; cell<cells.size(); ++cell)
505  {
506  for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
507  tmp[i] = cells[cell].vertices[i];
508  for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
509  cells[cell].vertices[GeometryInfo<3>::ucd_to_deal[i]] = tmp[i];
510  }
511 
512  // now points in boundary quads
513  std::vector<CellData<2> >::iterator boundary_quad
514  = subcelldata.boundary_quads.begin();
515  std::vector<CellData<2> >::iterator end_quad
516  = subcelldata.boundary_quads.end();
517  for (unsigned int quad_no=0; boundary_quad!=end_quad; ++boundary_quad, ++quad_no)
518  std::swap(boundary_quad->vertices[2], boundary_quad->vertices[3]);
519  }
520 
521 
522 
540  template <int dim, int spacedim>
541  unsigned int
542  middle_vertex_index(const typename Triangulation<dim,spacedim>::line_iterator &line)
543  {
544  if (line->has_children())
545  return line->child(0)->vertex_index(1);
547  }
548 
549 
550  template <int dim, int spacedim>
551  unsigned int
552  middle_vertex_index(const typename Triangulation<dim,spacedim>::quad_iterator &quad)
553  {
554  switch (static_cast<unsigned char> (quad->refinement_case()))
555  {
557  return middle_vertex_index<dim,spacedim>(quad->child(0)->line(1));
558  break;
560  return middle_vertex_index<dim,spacedim>(quad->child(0)->line(3));
561  break;
563  return quad->child(0)->vertex_index(3);
564  break;
565  default:
566  break;
567  }
569  }
570 
571 
572  template <int dim, int spacedim>
573  unsigned int
574  middle_vertex_index(const typename Triangulation<dim,spacedim>::hex_iterator &hex)
575  {
576  switch (static_cast<unsigned char> (hex->refinement_case()))
577  {
579  return middle_vertex_index<dim,spacedim>(hex->child(0)->quad(1));
580  break;
582  return middle_vertex_index<dim,spacedim>(hex->child(0)->quad(3));
583  break;
585  return middle_vertex_index<dim,spacedim>(hex->child(0)->quad(5));
586  break;
588  return middle_vertex_index<dim,spacedim>(hex->child(0)->line(11));
589  break;
591  return middle_vertex_index<dim,spacedim>(hex->child(0)->line(5));
592  break;
594  return middle_vertex_index<dim,spacedim>(hex->child(0)->line(7));
595  break;
597  return hex->child(0)->vertex_index(7);
598  break;
599  default:
600  break;
601  }
603  }
604 
605 
618  template <class TRIANGULATION>
619  inline
620  typename TRIANGULATION::DistortedCellList
621  collect_distorted_coarse_cells (const TRIANGULATION &)
622  {
623  return typename TRIANGULATION::DistortedCellList();
624  }
625 
626 
627 
636  template <int dim>
637  inline
639  collect_distorted_coarse_cells (const Triangulation<dim,dim> &triangulation)
640  {
641  typename Triangulation<dim,dim>::DistortedCellList distorted_cells;
643  cell = triangulation.begin(0); cell != triangulation.end(0); ++cell)
644  {
646  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
647  vertices[i] = cell->vertex(i);
648 
651  determinants);
652 
653  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
654  if (determinants[i] <= 1e-9 * std::pow (cell->diameter(),
655  1.*dim))
656  {
657  distorted_cells.distorted_cells.push_back (cell);
658  break;
659  }
660  }
661 
662  return distorted_cells;
663  }
664 
665 
672  template <int dim>
673  bool
674  has_distorted_children (const typename Triangulation<dim,dim>::cell_iterator &cell,
677  {
678  Assert (cell->has_children(), ExcInternalError());
679 
680  for (unsigned int c=0; c<cell->n_children(); ++c)
681  {
683  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
684  vertices[i] = cell->child(c)->vertex(i);
685 
688  determinants);
689 
690  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
691  if (determinants[i] <= 1e-9 * std::pow (cell->child(c)->diameter(),
692  1.*dim))
693  return true;
694  }
695 
696  return false;
697  }
698 
699 
707  template <int dim, int spacedim>
708  bool
709  has_distorted_children (const typename Triangulation<dim,spacedim>::cell_iterator &,
712  {
713  return false;
714  }
715 
716 
717 
722  template <int spacedim>
723  void
724  update_neighbors (Triangulation<1,spacedim> &)
725  {
726  }
727 
728 
729  template <int dim, int spacedim>
730  void
731  update_neighbors (Triangulation<dim,spacedim> &triangulation)
732  {
733  // each face can be neighbored on two sides
734  // by cells. according to the face's
735  // intrinsic normal we define the left
736  // neighbor as the one for which the face
737  // normal points outward, and store that
738  // one first; the second one is then
739  // the right neighbor for which the
740  // face normal points inward. This
741  // information depends on the type of cell
742  // and local number of face for the
743  // 'standard ordering and orientation' of
744  // faces and then on the face_orientation
745  // information for the real mesh. Set up a
746  // table to have fast access to those
747  // offsets (0 for left and 1 for
748  // right). Some of the values are invalid
749  // as they reference too large face
750  // numbers, but we just leave them at a
751  // zero value.
752  //
753  // Note, that in 2d for lines as faces the
754  // normal direction given in the
755  // GeometryInfo class is not consistent. We
756  // thus define here that the normal for a
757  // line points to the right if the line
758  // points upwards.
759  //
760  // There is one more point to
761  // consider, however: if we have
762  // dim<spacedim, then we may have
763  // cases where cells are
764  // inverted. In effect, both
765  // cells think they are the left
766  // neighbor of an edge, for
767  // example, which leads us to
768  // forget neighborship
769  // information (a case that shows
770  // this is
771  // codim_one/hanging_nodes_02). We
772  // store whether a cell is
773  // inverted using the
774  // direction_flag, so if a cell
775  // has a false direction_flag,
776  // then we need to invert our
777  // selection whether we are a
778  // left or right neighbor in all
779  // following computations.
780  //
781  // first index: dimension (minus 2)
782  // second index: local face index
783  // third index: face_orientation (false and true)
784  static const unsigned int left_right_offset[2][6][2] =
785  {
786  // quadrilateral
787  { {0,1}, // face 0, face_orientation = false and true
788  {1,0}, // face 1, face_orientation = false and true
789  {1,0}, // face 2, face_orientation = false and true
790  {0,1}, // face 3, face_orientation = false and true
791  {0,0}, // face 4, invalid face
792  {0,0}
793  },// face 5, invalid face
794  // hexahedron
795  { {0,1},
796  {1,0},
797  {0,1},
798  {1,0},
799  {0,1},
800  {1,0}
801  }
802  };
803 
804  // now create a vector of the two active
805  // neighbors (left and right) for each face
806  // and fill it by looping over all cells. For
807  // cases with anisotropic refinement and more
808  // then one cell neighboring at a given side
809  // of the face we will automatically get the
810  // active one on the highest level as we loop
811  // over cells from lower levels first.
812  const typename Triangulation<dim,spacedim>::cell_iterator dummy;
813  std::vector<typename Triangulation<dim,spacedim>::cell_iterator>
814  adjacent_cells(2*triangulation.n_raw_faces(), dummy);
815 
817  cell = triangulation.begin(),
818  endc = triangulation.end();
819  for (; cell != endc; ++cell)
820  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
821  {
823  face=cell->face(f);
824 
825  const unsigned int
826  offset = (cell->direction_flag()
827  ?
828  left_right_offset[dim-2][f][cell->face_orientation(f)]
829  :
830  1-left_right_offset[dim-2][f][cell->face_orientation(f)]);
831 
832  adjacent_cells[2*face->index() + offset] = cell;
833 
834  // if this cell is not refined, but the
835  // face is, then we'll have to set our
836  // cell as neighbor for the child faces
837  // as well. Fortunately the normal
838  // orientation of children will be just
839  // the same.
840  if (dim==2)
841  {
842  if (cell->active() && face->has_children())
843  {
844  adjacent_cells[2*face->child(0)->index() + offset] = cell;
845  adjacent_cells[2*face->child(1)->index() + offset] = cell;
846  }
847  }
848  else // -> dim == 3
849  {
850  // We need the same as in 2d
851  // here. Furthermore, if the face is
852  // refined with cut_x or cut_y then
853  // those children again in the other
854  // direction, and if this cell is
855  // refined isotropically (along the
856  // face) then the neighbor will
857  // (probably) be refined as cut_x or
858  // cut_y along the face. For those
859  // neighboring children cells, their
860  // neighbor will be the current,
861  // inactive cell, as our children are
862  // too fine to be neighbors. Catch that
863  // case by also acting on inactive
864  // cells with isotropic refinement
865  // along the face. If the situation
866  // described is not present, the data
867  // will be overwritten later on when we
868  // visit cells on finer levels, so no
869  // harm will be done.
870  if (face->has_children() &&
871  (cell->active() ||
873  {
874 
875  for (unsigned int c=0; c<face->n_children(); ++c)
876  adjacent_cells[2*face->child(c)->index() + offset] = cell;
877  if (face->child(0)->has_children())
878  {
879  adjacent_cells[2*face->child(0)->child(0)->index() + offset] = cell;
880  adjacent_cells[2*face->child(0)->child(1)->index() + offset] = cell;
881  }
882  if (face->child(1)->has_children())
883  {
884  adjacent_cells[2*face->child(1)->child(0)->index() + offset] = cell;
885  adjacent_cells[2*face->child(1)->child(1)->index() + offset] = cell;
886  }
887  } // if cell active and face refined
888  } // else -> dim==3
889  } // for all faces of all cells
890 
891  // now loop again over all cells and set the
892  // corresponding neighbor cell. Note, that we
893  // have to use the opposite of the
894  // left_right_offset in this case as we want
895  // the offset of the neighbor, not our own.
896  for (cell=triangulation.begin(); cell != endc; ++cell)
897  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
898  {
899  const unsigned int
900  offset = (cell->direction_flag()
901  ?
902  left_right_offset[dim-2][f][cell->face_orientation(f)]
903  :
904  1-left_right_offset[dim-2][f][cell->face_orientation(f)]);
905  cell->set_neighbor(f,
906  adjacent_cells[2*cell->face(f)->index() + 1 - offset]);
907  }
908  }
909 
910 }// end of anonymous namespace
911 
912 
913 namespace internal
914 {
915  namespace Triangulation
916  {
917  // make sure that if in the following we
918  // write Triangulation<dim,spacedim>
919  // we mean the *class*
920  // ::Triangulation, not the
921  // enclosing namespace
922  // internal::Triangulation
923  using ::Triangulation;
924 
929  DeclException1 (ExcGridHasInvalidCell,
930  int,
931  << "Something went wrong when making cell " << arg1
932  << ". Read the docs and the source code "
933  << "for more information.");
938  DeclException1 (ExcInternalErrorOnCell,
939  int,
940  << "Something went wrong upon construction of cell "
941  << arg1);
951  DeclException1 (ExcCellHasNegativeMeasure,
952  int,
953  << "Cell " << arg1 << " has negative measure. This typically "
954  << "indicates some distortion in the cell, or a mistakenly "
955  << "swapped pair of vertices in the input to "
956  << "Triangulation::create_triangulation().");
964  DeclException3 (ExcInvalidVertexIndex,
965  int, int, int,
966  << "Error while creating cell " << arg1
967  << ": the vertex index " << arg2 << " must be between 0 and "
968  << arg3 << ".");
973  DeclException2 (ExcLineInexistant,
974  int, int,
975  << "While trying to assign a boundary indicator to a line: "
976  << "the line with end vertices " << arg1 << " and "
977  << arg2 << " does not exist.");
982  DeclException4 (ExcQuadInexistant,
983  int, int, int, int,
984  << "While trying to assign a boundary indicator to a quad: "
985  << "the quad with bounding lines " << arg1 << ", " << arg2
986  << ", " << arg3 << ", " << arg4 << " does not exist.");
991  DeclException3 (ExcInteriorLineCantBeBoundary,
992  int, int,
994  << "The input data for creating a triangulation contained "
995  << "information about a line with indices "
996  << arg1 << " and " << arg2
997  << " that is described to have boundary indicator "
998  << (int)arg3
999  << ". However, this is an internal line not located on the "
1000  << "boundary. You cannot assign a boundary indicator to it."
1001  << std::endl
1002  << std::endl
1003  << "If this happened at a place where you call "
1004  << "Triangulation::create_triangulation() yourself, you need "
1005  << "to check the SubCellData object you pass to this function."
1006  << std::endl
1007  << std::endl
1008  << "If this happened in a place where you are reading a mesh "
1009  << "from a file, then you need to investigate why such a line "
1010  << "ended up in the input file. A typical case is a geometry "
1011  << "that consisted of multiple parts and for which the mesh "
1012  << "generator program assumes that the interface between "
1013  << "two parts is a boundary when that isn't supposed to be "
1014  << "the case, or where the mesh generator simply assigns "
1015  << "'geometry indicators' to lines at the perimeter of "
1016  << "a part that are not supposed to be interpreted as "
1017  << "'boundary indicators'.");
1022  DeclException5 (ExcInteriorQuadCantBeBoundary,
1023  int, int, int, int,
1025  << "The input data for creating a triangulation contained "
1026  << "information about a quad with indices "
1027  << arg1 << ", " << arg2 << ", " << arg3 << ", and " << arg4
1028  << " that is described to have boundary indicator "
1029  << (int)arg5
1030  << ". However, this is an internal quad not located on the "
1031  << "boundary. You cannot assign a boundary indicator to it."
1032  << std::endl
1033  << std::endl
1034  << "If this happened at a place where you call "
1035  << "Triangulation::create_triangulation() yourself, you need "
1036  << "to check the SubCellData object you pass to this function."
1037  << std::endl
1038  << std::endl
1039  << "If this happened in a place where you are reading a mesh "
1040  << "from a file, then you need to investigate why such a quad "
1041  << "ended up in the input file. A typical case is a geometry "
1042  << "that consisted of multiple parts and for which the mesh "
1043  << "generator program assumes that the interface between "
1044  << "two parts is a boundary when that isn't supposed to be "
1045  << "the case, or where the mesh generator simply assigns "
1046  << "'geometry indicators' to quads at the surface of "
1047  << "a part that are not supposed to be interpreted as "
1048  << "'boundary indicators'.");
1053  DeclException2 (ExcMultiplySetLineInfoOfLine,
1054  int, int,
1055  << "In SubCellData the line info of the line with vertex indices "
1056  << arg1 << " and " << arg2 << " appears more than once. "
1057  << "This is not allowed.");
1058 
1059 
1156  {
1172  template <int dim, int spacedim>
1173  static
1175  const unsigned int level_objects,
1177  {
1178  typedef
1179  typename Triangulation<dim,spacedim>::line_iterator line_iterator;
1180  typedef
1181  typename Triangulation<dim,spacedim>::active_line_iterator active_line_iterator;
1182 
1183  number_cache.n_levels = 0;
1184  if (level_objects > 0)
1185  // find the last level
1186  // on which there are
1187  // used cells
1188  for (unsigned int level=0; level<level_objects; ++level)
1189  if (triangulation.begin(level) !=
1190  triangulation.end(level))
1191  number_cache.n_levels = level+1;
1192 
1193  // no cells at all?
1194  Assert (number_cache.n_levels > 0, ExcInternalError());
1195 
1197  // update the number of lines
1198  // on the different levels in
1199  // the cache
1200  number_cache.n_lines_level.resize (number_cache.n_levels);
1201  number_cache.n_lines = 0;
1202 
1203  number_cache.n_active_lines_level.resize (number_cache.n_levels);
1204  number_cache.n_active_lines = 0;
1205 
1206  // for 1d, lines have levels so take
1207  // count the objects per level and
1208  // globally
1209  if (dim == 1)
1210  {
1211  for (unsigned int level=0; level<number_cache.n_levels; ++level)
1212  {
1213  // count lines on this level
1214  number_cache.n_lines_level[level] = 0;
1215 
1216  line_iterator line = triangulation.begin_line (level),
1217  endc = (level == number_cache.n_levels-1 ?
1218  line_iterator(triangulation.end_line()) :
1219  triangulation.begin_line (level+1));
1220  for (; line!=endc; ++line)
1221  ++number_cache.n_lines_level[level];
1222 
1223  // update total number of lines
1224  number_cache.n_lines += number_cache.n_lines_level[level];
1225  }
1226 
1227  // do the update for the number of
1228  // active lines as well
1229  for (unsigned int level=0; level<number_cache.n_levels; ++level)
1230  {
1231  // count lines on this level
1232  number_cache.n_active_lines_level[level] = 0;
1233 
1234  active_line_iterator line = triangulation.begin_active_line (level),
1235  endc = triangulation.end_line ();
1236  for (; (line!=endc) && (line->level() == static_cast<signed int>(level)); ++line)
1237  ++number_cache.n_active_lines_level[level];
1238 
1239  // update total number of lines
1240  number_cache.n_active_lines += number_cache.n_active_lines_level[level];
1241  }
1242  }
1243  else
1244  {
1245  // for dim>1, there are no
1246  // levels for lines
1247  {
1248  line_iterator line = triangulation.begin_line (),
1249  endc = triangulation.end_line();
1250  for (; line!=endc; ++line)
1251  ++number_cache.n_lines;
1252  }
1253 
1254  {
1255  active_line_iterator line = triangulation.begin_active_line (),
1256  endc = triangulation.end_line();
1257  for (; line!=endc; ++line)
1258  ++number_cache.n_active_lines;
1259  }
1260  }
1261  }
1262 
1282  template <int dim, int spacedim>
1283  static
1285  const unsigned int level_objects,
1287  {
1288  // update lines and n_levels
1289  compute_number_cache (triangulation,
1290  level_objects,
1292  (number_cache));
1293 
1294  typedef
1295  typename Triangulation<dim,spacedim>::quad_iterator quad_iterator;
1296  typedef
1297  typename Triangulation<dim,spacedim>::active_quad_iterator active_quad_iterator;
1298 
1300  // update the number of quads
1301  // on the different levels in
1302  // the cache
1303  number_cache.n_quads_level.resize (number_cache.n_levels);
1304  number_cache.n_quads = 0;
1305 
1306  number_cache.n_active_quads_level.resize (number_cache.n_levels);
1307  number_cache.n_active_quads = 0;
1308 
1309  // for 2d, quads have levels so take
1310  // count the objects per level and
1311  // globally
1312  if (dim == 2)
1313  {
1314  for (unsigned int level=0; level<number_cache.n_levels; ++level)
1315  {
1316  // count quads on this level
1317  number_cache.n_quads_level[level] = 0;
1318 
1319  quad_iterator quad = triangulation.begin_quad (level),
1320  endc = (level == number_cache.n_levels-1 ?
1321  quad_iterator(triangulation.end_quad()) :
1322  triangulation.begin_quad (level+1));
1323  for (; quad!=endc; ++quad)
1324  ++number_cache.n_quads_level[level];
1325 
1326  // update total number of quads
1327  number_cache.n_quads += number_cache.n_quads_level[level];
1328  }
1329 
1330  // do the update for the number of
1331  // active quads as well
1332  for (unsigned int level=0; level<number_cache.n_levels; ++level)
1333  {
1334  // count quads on this level
1335  number_cache.n_active_quads_level[level] = 0;
1336 
1337  active_quad_iterator quad = triangulation.begin_active_quad (level),
1338  endc = triangulation.end_quad ();
1339  for (; (quad!=endc) && (quad->level() == static_cast<signed int>(level)); ++quad)
1340  ++number_cache.n_active_quads_level[level];
1341 
1342  // update total number of quads
1343  number_cache.n_active_quads += number_cache.n_active_quads_level[level];
1344  }
1345  }
1346  else
1347  {
1348  // for dim>2, there are no
1349  // levels for quads
1350  {
1351  quad_iterator quad = triangulation.begin_quad (),
1352  endc = triangulation.end_quad();
1353  for (; quad!=endc; ++quad)
1354  ++number_cache.n_quads;
1355  }
1356 
1357  {
1358  active_quad_iterator quad = triangulation.begin_active_quad (),
1359  endc = triangulation.end_quad();
1360  for (; quad!=endc; ++quad)
1361  ++number_cache.n_active_quads;
1362  }
1363  }
1364  }
1365 
1386  template <int dim, int spacedim>
1387  static
1389  const unsigned int level_objects,
1391  {
1392  // update quads, lines and n_levels
1393  compute_number_cache (triangulation,
1394  level_objects,
1396  (number_cache));
1397 
1398  typedef
1399  typename Triangulation<dim,spacedim>::hex_iterator hex_iterator;
1400  typedef
1401  typename Triangulation<dim,spacedim>::active_hex_iterator active_hex_iterator;
1402 
1404  // update the number of hexes
1405  // on the different levels in
1406  // the cache
1407  number_cache.n_hexes_level.resize (number_cache.n_levels);
1408  number_cache.n_hexes = 0;
1409 
1410  number_cache.n_active_hexes_level.resize (number_cache.n_levels);
1411  number_cache.n_active_hexes = 0;
1412 
1413  // for 3d, hexes have levels so take
1414  // count the objects per level and
1415  // globally
1416  if (dim == 3)
1417  {
1418  for (unsigned int level=0; level<number_cache.n_levels; ++level)
1419  {
1420  // count hexes on this level
1421  number_cache.n_hexes_level[level] = 0;
1422 
1423  hex_iterator hex = triangulation.begin_hex (level),
1424  endc = (level == number_cache.n_levels-1 ?
1425  hex_iterator(triangulation.end_hex()) :
1426  triangulation.begin_hex (level+1));
1427  for (; hex!=endc; ++hex)
1428  ++number_cache.n_hexes_level[level];
1429 
1430  // update total number of hexes
1431  number_cache.n_hexes += number_cache.n_hexes_level[level];
1432  }
1433 
1434  // do the update for the number of
1435  // active hexes as well
1436  for (unsigned int level=0; level<number_cache.n_levels; ++level)
1437  {
1438  // count hexes on this level
1439  number_cache.n_active_hexes_level[level] = 0;
1440 
1441  active_hex_iterator hex = triangulation.begin_active_hex (level),
1442  endc = triangulation.end_hex ();
1443  for (; (hex!=endc) && (hex->level() == static_cast<signed int>(level)); ++hex)
1444  ++number_cache.n_active_hexes_level[level];
1445 
1446  // update total number of hexes
1447  number_cache.n_active_hexes += number_cache.n_active_hexes_level[level];
1448  }
1449  }
1450  else
1451  {
1452  // for dim>3, there are no
1453  // levels for hexs
1454  {
1455  hex_iterator hex = triangulation.begin_hex (),
1456  endc = triangulation.end_hex();
1457  for (; hex!=endc; ++hex)
1458  ++number_cache.n_hexes;
1459  }
1460 
1461  {
1462  active_hex_iterator hex = triangulation.begin_active_hex (),
1463  endc = triangulation.end_hex();
1464  for (; hex!=endc; ++hex)
1465  ++number_cache.n_active_hexes;
1466  }
1467  }
1468  }
1469 
1470 
1478  template <int spacedim>
1479  static
1480  void
1481  create_triangulation (const std::vector<Point<spacedim> > &v,
1482  const std::vector<CellData<1> > &cells,
1483  const SubCellData &/*subcelldata*/,
1484  Triangulation<1,spacedim> &triangulation)
1485  {
1486  AssertThrow (v.size() > 0, ExcMessage ("No vertices given"));
1487  AssertThrow (cells.size() > 0, ExcMessage ("No cells given"));
1488 
1489  // note: since no boundary
1490  // information can be given in one
1491  // dimension, the @p{subcelldata}
1492  // field is ignored. (only used for
1493  // error checking, which is a good
1494  // idea in any case)
1495  const unsigned int dim=1;
1496 
1497  // copy vertices
1498  triangulation.vertices = v;
1499  triangulation.vertices_used = std::vector<bool> (v.size(), true);
1500 
1501  // store the indices of the lines
1502  // which are adjacent to a given
1503  // vertex
1504  std::vector<std::vector<int> > lines_at_vertex (v.size());
1505 
1506  // reserve enough space
1507  triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
1508  triangulation.levels[0]->reserve_space (cells.size(), dim, spacedim);
1509  triangulation.levels[0]->cells.reserve_space (0,cells.size());
1510 
1511  // make up cells
1512  typename Triangulation<dim,spacedim>::raw_line_iterator
1513  next_free_line = triangulation.begin_raw_line ();
1514  for (unsigned int cell=0; cell<cells.size(); ++cell)
1515  {
1516  while (next_free_line->used())
1517  ++next_free_line;
1518 
1519  next_free_line->set (internal::Triangulation
1520  ::TriaObject<1> (cells[cell].vertices[0],
1521  cells[cell].vertices[1]));
1522  next_free_line->set_used_flag ();
1523  next_free_line->set_material_id (cells[cell].material_id);
1524  next_free_line->set_manifold_id (cells[cell].manifold_id);
1525  next_free_line->clear_user_data ();
1526  next_free_line->set_subdomain_id (0);
1527 
1528  // note that this cell is
1529  // adjacent to these vertices
1530  lines_at_vertex[cells[cell].vertices[0]].push_back (cell);
1531  lines_at_vertex[cells[cell].vertices[1]].push_back (cell);
1532  }
1533 
1534 
1535  // some security tests
1536  {
1537  unsigned int boundary_nodes = 0;
1538  for (unsigned int i=0; i<lines_at_vertex.size(); ++i)
1539  switch (lines_at_vertex[i].size())
1540  {
1541  case 1:
1542  // this vertex has only
1543  // one adjacent line
1544  ++boundary_nodes;
1545  break;
1546  case 2:
1547  break;
1548  default:
1549  // in 1d, a node must have one or two adjacent lines
1550  if (spacedim==1)
1551  AssertThrow (false, ExcInternalError())
1552  else
1553  AssertThrow (false,
1554  ExcMessage ("You have a vertex in your triangulation "
1555  "at which more than two cells come together. "
1556  "(For one dimensional triangulation, cells are "
1557  "line segments.)"
1558  "\n\n"
1559  "This is not currently supported because the "
1560  "Triangulation class makes the assumption that "
1561  "every cell has zero or one neighbors behind "
1562  "each face (here, behind each vertex), but in your "
1563  "situation there would be more than one."
1564  "\n\n"
1565  "Support for this is not currently implemented. "
1566  "If you need to work with triangulations where "
1567  "more than two cells come together at a vertex, "
1568  "duplicate the vertices once per cell (i.e., put "
1569  "multiple vertices at the same physical location, "
1570  "but using different vertex indices for each) "
1571  "and then ensure continuity of the solution by "
1572  "explicitly creating constraints that the degrees "
1573  "of freedom at these vertices have the same "
1574  "value, using the ConstraintMatrix class."));
1575  }
1576 
1577  // assert there are no more
1578  // than two boundary
1579  // nodes. note that if the
1580  // space dimension is
1581  // bigger than 1, then we
1582  // can have fewer than 2
1583  // nodes (for example a
1584  // ring of cells -- no end
1585  // points at all)
1586  AssertThrow (((spacedim == 1) && (boundary_nodes == 2))
1587  ||
1588  (spacedim > 1),
1589  ExcMessage("The Triangulation has too many end points"));
1590  }
1591 
1592 
1593 
1594  // update neighborship info
1595  typename Triangulation<dim,spacedim>::active_line_iterator
1596  line = triangulation.begin_active_line ();
1597  // for all lines
1598  for (; line!=triangulation.end(); ++line)
1599  // for each of the two vertices
1600  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
1601  // if first cell adjacent to
1602  // this vertex is the present
1603  // one, then the neighbor is
1604  // the second adjacent cell and
1605  // vice versa
1606  if (lines_at_vertex[line->vertex_index(vertex)][0] == line->index())
1607  if (lines_at_vertex[line->vertex_index(vertex)].size() == 2)
1608  {
1610  neighbor (&triangulation,
1611  0, // level
1612  lines_at_vertex[line->vertex_index(vertex)][1]);
1613  line->set_neighbor (vertex, neighbor);
1614  }
1615  else
1616  // no second adjacent cell
1617  // entered -> cell at
1618  // boundary
1619  line->set_neighbor (vertex, triangulation.end());
1620  else
1621  // present line is not first
1622  // adjacent one -> first
1623  // adjacent one is neighbor
1624  {
1626  neighbor (&triangulation,
1627  0, // level
1628  lines_at_vertex[line->vertex_index(vertex)][0]);
1629  line->set_neighbor (vertex, neighbor);
1630  }
1631 
1632  // finally set the
1633  // vertex_to_boundary_id_map_1d
1634  // and vertex_to_manifold_id_map_1d
1635  // maps
1636  triangulation.vertex_to_boundary_id_map_1d->clear();
1637  triangulation.vertex_to_manifold_id_map_1d->clear();
1639  cell = triangulation.begin_active();
1640  cell != triangulation.end(); ++cell)
1641  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
1642  {
1643  (*triangulation
1644  .vertex_to_manifold_id_map_1d)[cell->face(f)->vertex_index()]
1646 
1647  if (cell->at_boundary(f))
1648  (*triangulation
1649  .vertex_to_boundary_id_map_1d)[cell->face(f)->vertex_index()]
1650  = f;
1651  }
1652  }
1653 
1654 
1662  template <int spacedim>
1663  static
1664  void
1665  create_triangulation (const std::vector<Point<spacedim> > &v,
1666  const std::vector<CellData<2> > &cells,
1667  const SubCellData &subcelldata,
1668  Triangulation<2,spacedim> &triangulation)
1669  {
1670  AssertThrow (v.size() > 0, ExcMessage ("No vertices given"));
1671  AssertThrow (cells.size() > 0, ExcMessage ("No cells given"));
1672 
1673  const unsigned int dim=2;
1674 
1675  // copy vertices
1676  triangulation.vertices = v;
1677  triangulation.vertices_used = std::vector<bool> (v.size(), true);
1678 
1679  // make up a list of the needed
1680  // lines each line is a pair of
1681  // vertices. The list is kept
1682  // sorted and it is guaranteed that
1683  // each line is inserted only once.
1684  // While the key of such an entry
1685  // is the pair of vertices, the
1686  // thing it points to is an
1687  // iterator pointing to the line
1688  // object itself. In the first run,
1689  // these iterators are all invalid
1690  // ones, but they are filled
1691  // afterwards
1692  std::map<std::pair<int,int>,
1693  typename Triangulation<dim,spacedim>::line_iterator> needed_lines;
1694  for (unsigned int cell=0; cell<cells.size(); ++cell)
1695  {
1696  for (unsigned int vertex=0; vertex<4; ++vertex)
1697  AssertThrow (cells[cell].vertices[vertex] < triangulation.vertices.size(),
1698  ExcInvalidVertexIndex (cell, cells[cell].vertices[vertex],
1699  triangulation.vertices.size()));
1700 
1701  for (unsigned int line=0; line<GeometryInfo<dim>::faces_per_cell; ++line)
1702  {
1703  // given a line vertex number
1704  // (0,1) on a specific line we
1705  // get the cell vertex number
1706  // (0-4) through the
1707  // line_to_cell_vertices
1708  // function
1709  std::pair<int,int> line_vertices(
1710  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
1711  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
1712 
1713  // assert that the line was
1714  // not already inserted in
1715  // reverse order. This
1716  // happens in spite of the
1717  // vertex rotation above,
1718  // if the sense of the cell
1719  // was incorrect.
1720  //
1721  // Here is what usually
1722  // happened when this
1723  // exception is thrown:
1724  // consider these two cells
1725  // and the vertices
1726  // 3---4---5
1727  // | | |
1728  // 0---1---2
1729  // If in the input vector
1730  // the two cells are given
1731  // with vertices <0 1 4 3>
1732  // and <4 1 2 5>, in the
1733  // first cell the middle
1734  // line would have
1735  // direction 1->4, while in
1736  // the second it would be
1737  // 4->1. This will cause
1738  // the exception.
1739  AssertThrow (needed_lines.find(std::make_pair(line_vertices.second,
1740  line_vertices.first))
1741  ==
1742  needed_lines.end(),
1743  ExcGridHasInvalidCell(cell));
1744 
1745  // insert line, with
1746  // invalid iterator if line
1747  // already exists, then
1748  // nothing bad happens here
1749  needed_lines[line_vertices] = triangulation.end_line();
1750  }
1751  }
1752 
1753 
1754  // check that every vertex has at
1755  // least two adjacent lines
1756  {
1757  std::vector<unsigned short int> vertex_touch_count (v.size(), 0);
1758  typename std::map<std::pair<int,int>,
1759  typename Triangulation<dim,spacedim>::line_iterator>::iterator i;
1760  for (i=needed_lines.begin(); i!=needed_lines.end(); i++)
1761  {
1762  // touch the vertices of
1763  // this line
1764  ++vertex_touch_count[i->first.first];
1765  ++vertex_touch_count[i->first.second];
1766  }
1767 
1768  // assert minimum touch count
1769  // is at least two. if not so,
1770  // then clean triangulation and
1771  // exit with an exception
1772  AssertThrow (* (std::min_element(vertex_touch_count.begin(),
1773  vertex_touch_count.end())) >= 2,
1774  ExcMessage("During creation of a triangulation, a part of the "
1775  "algorithm encountered a vertex that is part of only "
1776  "a single adjacent line. However, in 2d, every vertex "
1777  "needs to be at least part of two lines."));
1778  }
1779 
1780  // reserve enough space
1781  triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
1782  triangulation.faces = new internal::Triangulation::TriaFaces<dim>;
1783  triangulation.levels[0]->reserve_space (cells.size(), dim, spacedim);
1784  triangulation.faces->lines.reserve_space (0,needed_lines.size());
1785  triangulation.levels[0]->cells.reserve_space (0,cells.size());
1786 
1787  // make up lines
1788  {
1789  typename Triangulation<dim,spacedim>::raw_line_iterator
1790  line = triangulation.begin_raw_line();
1791  typename std::map<std::pair<int,int>,
1792  typename Triangulation<dim,spacedim>::line_iterator>::iterator i;
1793  for (i = needed_lines.begin();
1794  line!=triangulation.end_line(); ++line, ++i)
1795  {
1796  line->set (internal::Triangulation::TriaObject<1>(i->first.first,
1797  i->first.second));
1798  line->set_used_flag ();
1799  line->clear_user_flag ();
1800  line->clear_user_data ();
1801  i->second = line;
1802  }
1803  }
1804 
1805 
1806  // store for each line index
1807  // the adjacent cells
1808  std::map<int,std::vector<typename Triangulation<dim,spacedim>::cell_iterator> >
1809  adjacent_cells;
1810 
1811  // finally make up cells
1812  {
1814  cell = triangulation.begin_raw_quad();
1815  for (unsigned int c=0; c<cells.size(); ++c, ++cell)
1816  {
1817  typename Triangulation<dim,spacedim>::line_iterator
1819  for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
1820  lines[line]=needed_lines[std::make_pair(
1821  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
1822  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)])];
1823 
1824  cell->set (internal::Triangulation::TriaObject<2> (lines[0]->index(),
1825  lines[1]->index(),
1826  lines[2]->index(),
1827  lines[3]->index()));
1828 
1829  cell->set_used_flag ();
1830  cell->set_material_id (cells[c].material_id);
1831  cell->set_manifold_id (cells[c].manifold_id);
1832  cell->clear_user_data ();
1833  cell->set_subdomain_id (0);
1834 
1835  // note that this cell is
1836  // adjacent to the four
1837  // lines
1838  for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
1839  adjacent_cells[lines[line]->index()].push_back (cell);
1840  }
1841  }
1842 
1843 
1844  for (typename Triangulation<dim,spacedim>::line_iterator
1845  line=triangulation.begin_line();
1846  line!=triangulation.end_line(); ++line)
1847  {
1848  const unsigned int n_adj_cells = adjacent_cells[line->index()].size();
1849 
1850  // assert that every line has one or two adjacent cells.
1851  // this has to be the case for 2d triangulations in 2d.
1852  // in higher dimensions, this may happen but is not
1853  // implemented
1854  if (spacedim==2)
1855  AssertThrow ((n_adj_cells >= 1) &&
1856  (n_adj_cells <= 2),
1857  ExcInternalError())
1858  else
1859  AssertThrow ((n_adj_cells >= 1) &&
1860  (n_adj_cells <= 2),
1861  ExcMessage ("You have a line in your triangulation "
1862  "at which more than two cells come together. "
1863  "\n\n"
1864  "This is not currently supported because the "
1865  "Triangulation class makes the assumption that "
1866  "every cell has zero or one neighbors behind "
1867  "each face (here, behind each line), but in your "
1868  "situation there would be more than one."
1869  "\n\n"
1870  "Support for this is not currently implemented. "
1871  "If you need to work with triangulations where "
1872  "more than two cells come together at a line, "
1873  "duplicate the vertices once per cell (i.e., put "
1874  "multiple vertices at the same physical location, "
1875  "but using different vertex indices for each) "
1876  "and then ensure continuity of the solution by "
1877  "explicitly creating constraints that the degrees "
1878  "of freedom at these lines have the same "
1879  "value, using the ConstraintMatrix class."));
1880 
1881  // if only one cell: line is at
1882  // boundary -> give it the
1883  // boundary indicator zero by
1884  // default
1885  if (n_adj_cells == 1)
1886  line->set_boundary_id (0);
1887  else
1888  // interior line -> numbers::internal_face_boundary_id
1889  line->set_boundary_id (numbers::internal_face_boundary_id);
1890  line->set_manifold_id(numbers::flat_manifold_id);
1891  }
1892 
1893  // set boundary indicators where given
1894  std::vector<CellData<1> >::const_iterator boundary_line
1895  = subcelldata.boundary_lines.begin();
1896  std::vector<CellData<1> >::const_iterator end_boundary_line
1897  = subcelldata.boundary_lines.end();
1898  for (; boundary_line!=end_boundary_line; ++boundary_line)
1899  {
1900  typename Triangulation<dim,spacedim>::line_iterator line;
1901  std::pair<int,int> line_vertices(std::make_pair(boundary_line->vertices[0],
1902  boundary_line->vertices[1]));
1903  if (needed_lines.find(line_vertices) != needed_lines.end())
1904  // line found in this direction
1905  line = needed_lines[line_vertices];
1906  else
1907  {
1908  // look whether it exists in reverse direction
1909  std::swap (line_vertices.first, line_vertices.second);
1910  if (needed_lines.find(line_vertices) != needed_lines.end())
1911  line = needed_lines[line_vertices];
1912  else
1913  // line does not exist
1914  AssertThrow (false, ExcLineInexistant(line_vertices.first,
1915  line_vertices.second));
1916  }
1917 
1918  // assert that we only set boundary info once
1919  AssertThrow (! (line->boundary_id() != 0 &&
1920  line->boundary_id() != numbers::internal_face_boundary_id),
1921  ExcMultiplySetLineInfoOfLine(line_vertices.first,
1922  line_vertices.second));
1923 
1924  // Assert that only exterior lines are given a boundary
1925  // indicator; however, it is possible that someone may
1926  // want to give an interior line a manifold id (and thus
1927  // lists this line in the subcell_data structure), and we
1928  // need to allow that
1929  if (boundary_line->boundary_id != numbers::internal_face_boundary_id)
1930  {
1931  AssertThrow (! (line->boundary_id() == numbers::internal_face_boundary_id),
1932  ExcInteriorLineCantBeBoundary(line->vertex_index(0),
1933  line->vertex_index(1),
1934  boundary_line->boundary_id));
1935  line->set_boundary_id (boundary_line->boundary_id);
1936  }
1937 
1938  line->set_manifold_id (boundary_line->manifold_id);
1939  }
1940 
1941 
1942  // finally update neighborship info
1944  cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
1945  for (unsigned int side=0; side<4; ++side)
1946  if (adjacent_cells[cell->line(side)->index()][0] == cell)
1947  // first adjacent cell is
1948  // this one
1949  {
1950  if (adjacent_cells[cell->line(side)->index()].size() == 2)
1951  // there is another
1952  // adjacent cell
1953  cell->set_neighbor (side,
1954  adjacent_cells[cell->line(side)->index()][1]);
1955  }
1956  // first adjacent cell is not this
1957  // one, -> it must be the neighbor
1958  // we are looking for
1959  else
1960  cell->set_neighbor (side,
1961  adjacent_cells[cell->line(side)->index()][0]);
1962  }
1963 
1964 
1975  {
1976  inline bool operator () (const internal::Triangulation::TriaObject<2> &q1,
1978  {
1979  // here is room to
1980  // optimize the repeated
1981  // equality test of the
1982  // previous lines; the
1983  // compiler will probably
1984  // take care of most of
1985  // it anyway
1986  if ((q1.face(0) < q2.face(0)) ||
1987  ((q1.face(0) == q2.face(0)) &&
1988  (q1.face(1) < q2.face(1))) ||
1989  ((q1.face(0) == q2.face(0)) &&
1990  (q1.face(1) == q2.face(1)) &&
1991  (q1.face(2) < q2.face(2))) ||
1992  ((q1.face(0) == q2.face(0)) &&
1993  (q1.face(1) == q2.face(1)) &&
1994  (q1.face(2) == q2.face(2)) &&
1995  (q1.face(3) < q2.face(3))))
1996  return true;
1997  else
1998  return false;
1999  }
2000  };
2001 
2002 
2010  template <int spacedim>
2011  static
2012  void
2013  create_triangulation (const std::vector<Point<spacedim> > &v,
2014  const std::vector<CellData<3> > &cells,
2015  const SubCellData &subcelldata,
2016  Triangulation<3,spacedim> &triangulation)
2017  {
2018  AssertThrow (v.size() > 0, ExcMessage ("No vertices given"));
2019  AssertThrow (cells.size() > 0, ExcMessage ("No cells given"));
2020 
2021  const unsigned int dim=3;
2022 
2023  // copy vertices
2024  triangulation.vertices = v;
2025  triangulation.vertices_used = std::vector<bool> (v.size(), true);
2026 
2027  // check that all cells have
2028  // positive volume. if not call the
2029  // invert_all_cells_of_negative_grid
2030  // and reorder_cells function of
2031  // GridReordering before creating
2032  // the triangulation
2033 #ifndef _MSC_VER
2034  //TODO: The following code does not compile with MSVC. Find a way around it
2035  for (unsigned int cell_no = 0; cell_no<cells.size(); ++cell_no)
2037  cells[cell_no].vertices) >= 0,
2038  ExcGridHasInvalidCell(cell_no));
2039 #endif
2040 
2042  // first set up some collections of data
2043  //
2044  // make up a list of the needed
2045  // lines
2046  //
2047  // each line is a pair of
2048  // vertices. The list is kept
2049  // sorted and it is guaranteed that
2050  // each line is inserted only once.
2051  // While the key of such an entry
2052  // is the pair of vertices, the
2053  // thing it points to is an
2054  // iterator pointing to the line
2055  // object itself. In the first run,
2056  // these iterators are all invalid
2057  // ones, but they are filled
2058  // afterwards same applies for the
2059  // quads
2060  typename std::map<std::pair<int,int>,
2061  typename Triangulation<dim,spacedim>::line_iterator> needed_lines;
2062  for (unsigned int cell=0; cell<cells.size(); ++cell)
2063  {
2064  // check whether vertex indices
2065  // are valid ones
2066  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
2067  AssertThrow (cells[cell].vertices[vertex] < triangulation.vertices.size(),
2068  ExcInvalidVertexIndex (cell, cells[cell].vertices[vertex],
2069  triangulation.vertices.size()));
2070 
2071  for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
2072  {
2073  // given a line vertex number
2074  // (0,1) on a specific line we
2075  // get the cell vertex number
2076  // (0-7) through the
2077  // line_to_cell_vertices
2078  // function
2079  std::pair<int,int> line_vertices(
2080  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
2081  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
2082 
2083  // if that line was already inserted
2084  // in reverse order do nothing, else
2085  // insert the line
2086  if ( (needed_lines.find(std::make_pair(line_vertices.second,
2087  line_vertices.first))
2088  ==
2089  needed_lines.end()))
2090  {
2091  // insert line, with
2092  // invalid iterator. if line
2093  // already exists, then
2094  // nothing bad happens here
2095  needed_lines[line_vertices] = triangulation.end_line();
2096  }
2097  }
2098  }
2099 
2100 
2102  // now for some sanity-checks:
2103  //
2104  // check that every vertex has at
2105  // least tree adjacent lines
2106  {
2107  std::vector<unsigned short int> vertex_touch_count (v.size(), 0);
2108  typename std::map<std::pair<int,int>,
2109  typename Triangulation<dim,spacedim>::line_iterator>::iterator i;
2110  for (i=needed_lines.begin(); i!=needed_lines.end(); i++)
2111  {
2112  // touch the vertices of
2113  // this line
2114  ++vertex_touch_count[i->first.first];
2115  ++vertex_touch_count[i->first.second];
2116  }
2117 
2118  // assert minimum touch count
2119  // is at least three. if not so,
2120  // then clean triangulation and
2121  // exit with an exception
2122  AssertThrow (* (std::min_element(vertex_touch_count.begin(),
2123  vertex_touch_count.end())) >= 3,
2124  ExcMessage("During creation of a triangulation, a part of the "
2125  "algorithm encountered a vertex that is part of only "
2126  "one or two adjacent lines. However, in 3d, every vertex "
2127  "needs to be at least part of three lines."));
2128  }
2129 
2130 
2132  // actually set up data structures
2133  // for the lines
2134  // reserve enough space
2135  triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
2136  triangulation.faces = new internal::Triangulation::TriaFaces<dim>;
2137  triangulation.levels[0]->reserve_space (cells.size(), dim, spacedim);
2138  triangulation.faces->lines.reserve_space (0,needed_lines.size());
2139 
2140  // make up lines
2141  {
2142  typename Triangulation<dim,spacedim>::raw_line_iterator
2143  line = triangulation.begin_raw_line();
2144  typename std::map<std::pair<int,int>,
2145  typename Triangulation<dim,spacedim>::line_iterator>::iterator i;
2146  for (i = needed_lines.begin(); line!=triangulation.end_line(); ++line, ++i)
2147  {
2148  line->set (internal::Triangulation::TriaObject<1>(i->first.first,
2149  i->first.second));
2150  line->set_used_flag ();
2151  line->clear_user_flag ();
2152  line->clear_user_data ();
2153 
2154  // now set the iterator for
2155  // this line
2156  i->second = line;
2157  }
2158  }
2159 
2160 
2162  // make up the quads of this triangulation
2163  //
2164  // same thing: the iterators are
2165  // set to the invalid value at
2166  // first, we only collect the data
2167  // now
2168 
2169  // the bool array stores, whether the lines
2170  // are in the standard orientation or not
2171 
2172  // note that QuadComparator is a
2173  // class declared and defined in
2174  // this file
2175  std::map<internal::Triangulation::TriaObject<2>,
2176  std::pair<typename Triangulation<dim,spacedim>::quad_iterator,
2177  std_cxx11::array<bool,GeometryInfo<dim>::lines_per_face> >,
2179  needed_quads;
2180  for (unsigned int cell=0; cell<cells.size(); ++cell)
2181  {
2182  // the faces are quads which
2183  // consist of four numbers
2184  // denoting the index of the
2185  // four lines bounding the
2186  // quad. we can get this index
2187  // by asking @p{needed_lines}
2188  // for an iterator to this
2189  // line, dereferencing it and
2190  // thus return an iterator into
2191  // the @p{lines} array of the
2192  // triangulation, which is
2193  // already set up. we can then
2194  // ask this iterator for its
2195  // index within the present
2196  // level (the level is zero, of
2197  // course)
2198  //
2199  // to make things easier, we
2200  // don't create the lines
2201  // (pairs of their vertex
2202  // indices) in place, but
2203  // before they are really
2204  // needed.
2205  std::pair<int,int> line_list[GeometryInfo<dim>::lines_per_cell],
2206  inverse_line_list[GeometryInfo<dim>::lines_per_cell];
2207  unsigned int face_line_list[GeometryInfo<dim>::lines_per_face];
2208  std_cxx11::array<bool,GeometryInfo<dim>::lines_per_face> orientation;
2209 
2210  for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
2211  {
2212  line_list[line]=std::pair<int,int> (
2213  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
2214  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
2215  inverse_line_list[line]=std::pair<int,int> (
2216  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)],
2217  cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)]);
2218  }
2219 
2220  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
2221  {
2222  // set up a list of the lines to be
2223  // used for this face. check the
2224  // direction for each line
2225  //
2226  // given a face line number (0-3) on
2227  // a specific face we get the cell
2228  // line number (0-11) through the
2229  // face_to_cell_lines function
2230  for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
2231  if (needed_lines.find (inverse_line_list[GeometryInfo<dim>::
2232  face_to_cell_lines(face,l)]) == needed_lines.end())
2233  {
2234  face_line_list[l]=needed_lines[line_list[GeometryInfo<dim>::
2235  face_to_cell_lines(face,l)]]->index();
2236  orientation[l]=true;
2237  }
2238  else
2239  {
2240  face_line_list[l]=needed_lines[inverse_line_list[GeometryInfo<dim>::
2241  face_to_cell_lines(face,l)]]->index();
2242  orientation[l]=false;
2243  }
2244 
2245 
2247  quad(face_line_list[0],
2248  face_line_list[1],
2249  face_line_list[2],
2250  face_line_list[3]);
2251 
2252  // insert quad, with
2253  // invalid iterator
2254  //
2255  // if quad already exists,
2256  // then nothing bad happens
2257  // here, as this will then
2258  // simply become an
2259  // interior face of the
2260  // triangulation. however,
2261  // we will run into major
2262  // trouble if the face was
2263  // already inserted in the
2264  // opposite
2265  // direction. there are
2266  // really only two
2267  // orientations for a face
2268  // to be in, since the edge
2269  // directions are already
2270  // set. thus, vertex 0 is
2271  // the one from which two
2272  // edges originate, and
2273  // vertex 3 is the one to
2274  // which they converge. we
2275  // are then left with
2276  // orientations 0-1-2-3 and
2277  // 2-3-0-1 for the order of
2278  // lines. the
2279  // corresponding quad can
2280  // be easily constructed by
2281  // exchanging lines. we do
2282  // so here, just to check
2283  // that that flipped quad
2284  // isn't already in the
2285  // triangulation. if it is,
2286  // then don't insert the
2287  // new one and instead
2288  // later set the
2289  // face_orientation flag
2291  test_quad_1(quad.face(2), quad.face(3),
2292  quad.face(0), quad.face(1)),//face_orientation=false, face_flip=false, face_rotation=false
2293  test_quad_2(quad.face(0), quad.face(1),
2294  quad.face(3), quad.face(2)),//face_orientation=false, face_flip=false, face_rotation=true
2295  test_quad_3(quad.face(3), quad.face(2),
2296  quad.face(1), quad.face(0)),//face_orientation=false, face_flip=true, face_rotation=false
2297  test_quad_4(quad.face(1), quad.face(0),
2298  quad.face(2), quad.face(3)),//face_orientation=false, face_flip=true, face_rotation=true
2299  test_quad_5(quad.face(2), quad.face(3),
2300  quad.face(1), quad.face(0)),//face_orientation=true, face_flip=false, face_rotation=true
2301  test_quad_6(quad.face(1), quad.face(0),
2302  quad.face(3), quad.face(2)),//face_orientation=true, face_flip=true, face_rotation=false
2303  test_quad_7(quad.face(3), quad.face(2),
2304  quad.face(0), quad.face(1));//face_orientation=true, face_flip=true, face_rotation=true
2305  if (needed_quads.find (test_quad_1) == needed_quads.end() &&
2306  needed_quads.find (test_quad_2) == needed_quads.end() &&
2307  needed_quads.find (test_quad_3) == needed_quads.end() &&
2308  needed_quads.find (test_quad_4) == needed_quads.end() &&
2309  needed_quads.find (test_quad_5) == needed_quads.end() &&
2310  needed_quads.find (test_quad_6) == needed_quads.end() &&
2311  needed_quads.find (test_quad_7) == needed_quads.end())
2312  needed_quads[quad] = std::make_pair(triangulation.end_quad(),orientation);
2313  }
2314  }
2315 
2316 
2318  // enter the resulting quads into
2319  // the arrays of the Triangulation
2320  //
2321  // first reserve enough space
2322  triangulation.faces->quads.reserve_space (0,needed_quads.size());
2323 
2324  {
2325  typename Triangulation<dim,spacedim>::raw_quad_iterator
2326  quad = triangulation.begin_raw_quad();
2327  typename std::map<internal::Triangulation::TriaObject<2>,
2328  std::pair<typename Triangulation<dim,spacedim>::quad_iterator,
2329  std_cxx11::array<bool,GeometryInfo<dim>::lines_per_face> >,
2331  ::iterator q;
2332  for (q = needed_quads.begin(); quad!=triangulation.end_quad(); ++quad, ++q)
2333  {
2334  quad->set (q->first);
2335  quad->set_used_flag ();
2336  quad->clear_user_flag ();
2337  quad->clear_user_data ();
2338  // set the line orientation
2339  quad->set_line_orientation(0,q->second.second[0]);
2340  quad->set_line_orientation(1,q->second.second[1]);
2341  quad->set_line_orientation(2,q->second.second[2]);
2342  quad->set_line_orientation(3,q->second.second[3]);
2343 
2344 
2345  // now set the iterator for
2346  // this quad
2347  q->second.first = quad;
2348  }
2349  }
2350 
2352  // finally create the cells
2353  triangulation.levels[0]->cells.reserve_space (cells.size());
2354 
2355  // store for each quad index the
2356  // adjacent cells
2357  std::map<int,std::vector<typename Triangulation<dim,spacedim>::cell_iterator> >
2358  adjacent_cells;
2359 
2360  // finally make up cells
2361  {
2363  cell = triangulation.begin_raw_hex();
2364  for (unsigned int c=0; c<cells.size(); ++c, ++cell)
2365  {
2366  // first find for each of
2367  // the cells the quad
2368  // iterator of the
2369  // respective faces.
2370  //
2371  // to this end, set up the
2372  // lines of this cell and
2373  // find the quads that are
2374  // bounded by these lines;
2375  // these are then the faces
2376  // of the present cell
2377  std::pair<int,int> line_list[GeometryInfo<dim>::lines_per_cell],
2378  inverse_line_list[GeometryInfo<dim>::lines_per_cell];
2379  unsigned int face_line_list[4];
2380  for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
2381  {
2382  line_list[line]=std::make_pair(
2383  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
2384  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
2385  inverse_line_list[line]=std::pair<int,int> (
2386  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)],
2387  cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)]);
2388  }
2389 
2390  // get the iterators
2391  // corresponding to the
2392  // faces. also store
2393  // whether they are
2394  // reversed or not
2395  typename Triangulation<dim,spacedim>::quad_iterator
2396  face_iterator[GeometryInfo<dim>::faces_per_cell];
2397  bool face_orientation[GeometryInfo<dim>::faces_per_cell];
2398  bool face_flip[GeometryInfo<dim>::faces_per_cell];
2399  bool face_rotation[GeometryInfo<dim>::faces_per_cell];
2400  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
2401  {
2402  for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
2403  if (needed_lines.find (inverse_line_list[GeometryInfo<dim>::
2404  face_to_cell_lines(face,l)]) == needed_lines.end())
2405  face_line_list[l]=needed_lines[line_list[GeometryInfo<dim>::
2406  face_to_cell_lines(face,l)]]->index();
2407  else
2408  face_line_list[l]=needed_lines[inverse_line_list[GeometryInfo<dim>::
2409  face_to_cell_lines(face,l)]]->index();
2410 
2412  quad(face_line_list[0],
2413  face_line_list[1],
2414  face_line_list[2],
2415  face_line_list[3]);
2416 
2417  if (needed_quads.find (quad) != needed_quads.end())
2418  {
2419  // face is in standard
2420  // orientation (and not
2421  // flipped or rotated). this
2422  // must be true for at least
2423  // one of the two cells
2424  // containing this face
2425  // (i.e. for the cell which
2426  // originally inserted the
2427  // face)
2428  face_iterator[face] = needed_quads[quad].first;
2429  face_orientation[face] = true;
2430  face_flip[face]=false;
2431  face_rotation[face]=false;
2432  }
2433  else
2434  {
2435  // face must be available in
2436  // reverse order
2437  // then. construct all
2438  // possibilities and check
2439  // them one after the other
2441  test_quad_1(quad.face(2), quad.face(3),
2442  quad.face(0), quad.face(1)),//face_orientation=false, face_flip=false, face_rotation=false
2443  test_quad_2(quad.face(0), quad.face(1),
2444  quad.face(3), quad.face(2)),//face_orientation=false, face_flip=false, face_rotation=true
2445  test_quad_3(quad.face(3), quad.face(2),
2446  quad.face(1), quad.face(0)),//face_orientation=false, face_flip=true, face_rotation=false
2447  test_quad_4(quad.face(1), quad.face(0),
2448  quad.face(2), quad.face(3)),//face_orientation=false, face_flip=true, face_rotation=true
2449  test_quad_5(quad.face(2), quad.face(3),
2450  quad.face(1), quad.face(0)),//face_orientation=true, face_flip=false, face_rotation=true
2451  test_quad_6(quad.face(1), quad.face(0),
2452  quad.face(3), quad.face(2)),//face_orientation=true, face_flip=true, face_rotation=false
2453  test_quad_7(quad.face(3), quad.face(2),
2454  quad.face(0), quad.face(1));//face_orientation=true, face_flip=true, face_rotation=true
2455  if (needed_quads.find (test_quad_1) != needed_quads.end())
2456  {
2457  face_iterator[face] = needed_quads[test_quad_1].first;
2458  face_orientation[face] = false;
2459  face_flip[face]=false;
2460  face_rotation[face]=false;
2461  }
2462  else if (needed_quads.find (test_quad_2) != needed_quads.end())
2463  {
2464  face_iterator[face] = needed_quads[test_quad_2].first;
2465  face_orientation[face] = false;
2466  face_flip[face]=false;
2467  face_rotation[face]=true;
2468  }
2469  else if (needed_quads.find (test_quad_3) != needed_quads.end())
2470  {
2471  face_iterator[face] = needed_quads[test_quad_3].first;
2472  face_orientation[face] = false;
2473  face_flip[face]=true;
2474  face_rotation[face]=false;
2475  }
2476  else if (needed_quads.find (test_quad_4) != needed_quads.end())
2477  {
2478  face_iterator[face] = needed_quads[test_quad_4].first;
2479  face_orientation[face] = false;
2480  face_flip[face]=true;
2481  face_rotation[face]=true;
2482  }
2483  else if (needed_quads.find (test_quad_5) != needed_quads.end())
2484  {
2485  face_iterator[face] = needed_quads[test_quad_5].first;
2486  face_orientation[face] = true;
2487  face_flip[face]=false;
2488  face_rotation[face]=true;
2489  }
2490  else if (needed_quads.find (test_quad_6) != needed_quads.end())
2491  {
2492  face_iterator[face] = needed_quads[test_quad_6].first;
2493  face_orientation[face] = true;
2494  face_flip[face]=true;
2495  face_rotation[face]=false;
2496  }
2497  else if (needed_quads.find (test_quad_7) != needed_quads.end())
2498  {
2499  face_iterator[face] = needed_quads[test_quad_7].first;
2500  face_orientation[face] = true;
2501  face_flip[face]=true;
2502  face_rotation[face]=true;
2503  }
2504 
2505  else
2506  // we didn't find the
2507  // face in any direction,
2508  // so something went
2509  // wrong above
2510  Assert(false,ExcInternalError());
2511 
2512  }
2513  }// for all faces
2514 
2515  // make the cell out of
2516  // these iterators
2517  cell->set (internal::Triangulation
2518  ::TriaObject<3> (face_iterator[0]->index(),
2519  face_iterator[1]->index(),
2520  face_iterator[2]->index(),
2521  face_iterator[3]->index(),
2522  face_iterator[4]->index(),
2523  face_iterator[5]->index()));
2524 
2525  cell->set_used_flag ();
2526  cell->set_material_id (cells[c].material_id);
2527  cell->set_manifold_id (cells[c].manifold_id);
2528  cell->clear_user_flag ();
2529  cell->clear_user_data ();
2530  cell->set_subdomain_id (0);
2531 
2532  // set orientation flag for
2533  // each of the faces
2534  for (unsigned int quad=0; quad<GeometryInfo<dim>::faces_per_cell; ++quad)
2535  {
2536  cell->set_face_orientation (quad, face_orientation[quad]);
2537  cell->set_face_flip (quad, face_flip[quad]);
2538  cell->set_face_rotation (quad, face_rotation[quad]);
2539  }
2540 
2541 
2542  // note that this cell is
2543  // adjacent to the six
2544  // quads
2545  for (unsigned int quad=0; quad<GeometryInfo<dim>::faces_per_cell; ++quad)
2546  adjacent_cells[face_iterator[quad]->index()].push_back (cell);
2547 
2548 #ifdef DEBUG
2549  // make some checks on the
2550  // lines and their
2551  // ordering
2552 
2553  // first map all cell lines
2554  // to the two face lines
2555  // which should
2556  // coincide. all face lines
2557  // are included with a cell
2558  // line number (0-11)
2559  // key. At the end all keys
2560  // will be included twice
2561  // (for each of the two
2562  // coinciding lines once)
2563  std::multimap<unsigned int, std::pair<unsigned int, unsigned int> >
2564  cell_to_face_lines;
2565  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
2566  for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_face; ++line)
2567  cell_to_face_lines.insert(
2568  std::pair<unsigned int, std::pair<unsigned int, unsigned int> > (
2570  std::pair<unsigned int, unsigned int> (face,line)));
2571  std::multimap<unsigned int, std::pair<unsigned int, unsigned int> >::const_iterator
2572  map_iter=cell_to_face_lines.begin();
2573 
2574  for (; map_iter!=cell_to_face_lines.end(); ++map_iter)
2575  {
2576  const unsigned int cell_line=map_iter->first;
2577  const unsigned int face1=map_iter->second.first;
2578  const unsigned int line1=map_iter->second.second;
2579  ++map_iter;
2580  Assert(map_iter!=cell_to_face_lines.end(), ExcInternalErrorOnCell(c));
2581  Assert(map_iter->first==cell_line, ExcInternalErrorOnCell(c));
2582  const unsigned int face2=map_iter->second.first;
2583  const unsigned int line2=map_iter->second.second;
2584 
2585  // check that the pair
2586  // of lines really
2587  // coincide. Take care
2588  // about the face
2589  // orientation;
2590  Assert (face_iterator[face1]->line(GeometryInfo<dim>::standard_to_real_face_line(
2591  line1,
2592  face_orientation[face1],
2593  face_flip[face1],
2594  face_rotation[face1])) ==
2595  face_iterator[face2]->line(GeometryInfo<dim>::standard_to_real_face_line(
2596  line2,
2597  face_orientation[face2],
2598  face_flip[face2],
2599  face_rotation[face2])),
2600  ExcInternalErrorOnCell(c));
2601  }
2602 #endif
2603  }
2604  }
2605 
2606 
2608  // find those quads which are at the
2609  // boundary and mark them appropriately
2610  for (typename Triangulation<dim,spacedim>::quad_iterator
2611  quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
2612  {
2613  const unsigned int n_adj_cells = adjacent_cells[quad->index()].size();
2614  // assert that every quad has
2615  // one or two adjacent cells
2616  AssertThrow ((n_adj_cells >= 1) &&
2617  (n_adj_cells <= 2),
2618  ExcInternalError());
2619 
2620  // if only one cell: quad is at
2621  // boundary -> give it the
2622  // boundary indicator zero by
2623  // default
2624  if (n_adj_cells == 1)
2625  quad->set_boundary_id (0);
2626  else
2627  // interior quad -> numbers::internal_face_boundary_id
2628  quad->set_boundary_id (numbers::internal_face_boundary_id);
2629  // Manifold ids are set
2630  // independently of where
2631  // they are
2632  quad->set_manifold_id(numbers::flat_manifold_id);
2633  }
2634 
2636  // next find those lines which are at
2637  // the boundary and mark all others as
2638  // interior ones
2639  //
2640  // for this: first mark all lines as interior. use this loop
2641  // to also set all manifold ids of all lines
2642  for (typename Triangulation<dim,spacedim>::line_iterator
2643  line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
2644  {
2645  line->set_boundary_id (numbers::internal_face_boundary_id);
2646  line->set_manifold_id(numbers::flat_manifold_id);
2647  }
2648 
2649  // next reset all lines bounding
2650  // boundary quads as on the
2651  // boundary also. note that since
2652  // we are in 3d, there are cases
2653  // where one or more lines of a
2654  // quad that is not on the
2655  // boundary, are actually boundary
2656  // lines. they will not be marked
2657  // when visiting this
2658  // face. however, since we do not
2659  // support dim-2 dimensional
2660  // boundaries (i.e. internal lines
2661  // constituting boundaries), every
2662  // such line is also part of a face
2663  // that is actually on the
2664  // boundary, so sooner or later we
2665  // get to mark that line for being
2666  // on the boundary
2667  for (typename Triangulation<dim,spacedim>::quad_iterator
2668  quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
2669  if (quad->at_boundary())
2670  for (unsigned int l=0; l<4; ++l)
2671  quad->line(l)->set_boundary_id (0);
2672 
2674  // now set boundary indicators
2675  // where given
2676  //
2677  // first do so for lines
2678  std::vector<CellData<1> >::const_iterator boundary_line
2679  = subcelldata.boundary_lines.begin();
2680  std::vector<CellData<1> >::const_iterator end_boundary_line
2681  = subcelldata.boundary_lines.end();
2682  for (; boundary_line!=end_boundary_line; ++boundary_line)
2683  {
2684  typename Triangulation<dim,spacedim>::line_iterator line;
2685  std::pair <int, int> line_vertices(std::make_pair(boundary_line->vertices[0],
2686  boundary_line->vertices[1]));
2687  if (needed_lines.find(line_vertices) != needed_lines.end())
2688  // line found in this
2689  // direction
2690  line = needed_lines[line_vertices];
2691 
2692  else
2693  {
2694  // look whether it exists in
2695  // reverse direction
2696  std::swap (line_vertices.first, line_vertices.second);
2697  if (needed_lines.find(line_vertices) != needed_lines.end())
2698  line = needed_lines[line_vertices];
2699  else
2700  // line does not exist
2701  AssertThrow (false, ExcLineInexistant(line_vertices.first,
2702  line_vertices.second));
2703  }
2704  // Assert that only exterior
2705  // lines are given a boundary
2706  // indicator
2707  AssertThrow (line->at_boundary(),
2708  ExcInteriorLineCantBeBoundary(line->vertex_index(0),
2709  line->vertex_index(1),
2710  boundary_line->boundary_id));
2711 
2712  // and make sure that we don't
2713  // attempt to reset the
2714  // boundary indicator to a
2715  // different than the
2716  // previously set value
2717  if (line->boundary_id() != 0)
2718  AssertThrow (line->boundary_id() == boundary_line->boundary_id,
2719  ExcMessage ("Duplicate boundary lines are only allowed "
2720  "if they carry the same boundary indicator."));
2721 
2722  line->set_boundary_id (boundary_line->boundary_id);
2723  // Set manifold id if given
2724  line->set_manifold_id(boundary_line->manifold_id);
2725  }
2726 
2727 
2728  // now go on with boundary faces
2729  std::vector<CellData<2> >::const_iterator boundary_quad
2730  = subcelldata.boundary_quads.begin();
2731  std::vector<CellData<2> >::const_iterator end_boundary_quad
2732  = subcelldata.boundary_quads.end();
2733  for (; boundary_quad!=end_boundary_quad; ++boundary_quad)
2734  {
2735  typename Triangulation<dim,spacedim>::quad_iterator quad;
2736  typename Triangulation<dim,spacedim>::line_iterator line[4];
2737 
2738  // first find the lines that
2739  // are made up of the given
2740  // vertices, then build up a
2741  // quad from these lines
2742  // finally use the find
2743  // function of the map template
2744  // to find the quad
2745  for (unsigned int i=0; i<4; ++i)
2746  {
2747  std::pair<int, int> line_vertices(
2748  boundary_quad->vertices[GeometryInfo<dim-1>::line_to_cell_vertices(i,0)],
2749  boundary_quad->vertices[GeometryInfo<dim-1>::line_to_cell_vertices(i,1)]);
2750 
2751  // check whether line
2752  // already exists
2753  if (needed_lines.find(line_vertices) != needed_lines.end())
2754  line[i] = needed_lines[line_vertices];
2755  else
2756  // look whether it exists
2757  // in reverse direction
2758  {
2759  std::swap (line_vertices.first, line_vertices.second);
2760  if (needed_lines.find(line_vertices) != needed_lines.end())
2761  line[i] = needed_lines[line_vertices];
2762  else
2763  // line does
2764  // not exist
2765  AssertThrow (false, ExcLineInexistant(line_vertices.first,
2766  line_vertices.second));
2767  }
2768  }
2769 
2770 
2771  // Set up 2 quads that are
2772  // built up from the lines for
2773  // reasons of comparison to
2774  // needed_quads. The second
2775  // quad is the reversed version
2776  // of the first quad in order
2777  // find the quad regardless of
2778  // its orientation. This is
2779  // introduced for convenience
2780  // and because boundary quad
2781  // orientation does not carry
2782  // any information.
2784  quad_compare_1(line[0]->index(), line[1]->index(),
2785  line[2]->index(), line[3]->index());
2787  quad_compare_2(line[2]->index(), line[3]->index(),
2788  line[0]->index(), line[1]->index());
2789 
2790  // try to find the quad with
2791  // lines situated as
2792  // constructed above. if it
2793  // could not be found, rotate
2794  // the boundary lines 3 times
2795  // until it is found or it does
2796  // not exist.
2797 
2798  // mapping from counterclock to
2799  // lexicographic ordering of
2800  // quad lines
2801  static const unsigned int lex2cclock[4]= {3,1,0,2};
2802  // copy lines from
2803  // lexicographic to
2804  // counterclock ordering, as
2805  // rotation is much simpler in
2806  // counterclock ordering
2807  typename Triangulation<dim,spacedim>::line_iterator
2808  line_counterclock[4];
2809  for (unsigned int i=0; i<4; ++i)
2810  line_counterclock[lex2cclock[i]]=line[i];
2811  unsigned int n_rotations=0;
2812  bool not_found_quad_1;
2813  while ( (not_found_quad_1=(needed_quads.find(quad_compare_1) == needed_quads.end())) &&
2814  ( needed_quads.find(quad_compare_2) == needed_quads.end()) &&
2815  (n_rotations<4))
2816  {
2817  // use the rotate defined
2818  // in <algorithms>
2819  rotate(line_counterclock, line_counterclock+1, line_counterclock+4);
2820  // update the quads with
2821  // rotated lines (i runs in
2822  // lexicographic ordering)
2823  for (unsigned int i=0; i<4; ++i)
2824  {
2825  quad_compare_1.set_face(i, line_counterclock[lex2cclock[i]]->index());
2826  quad_compare_2.set_face((i+2)%4, line_counterclock[lex2cclock[i]]->index());
2827  }
2828 
2829  ++n_rotations;
2830  }
2831 
2832  AssertThrow (n_rotations!=4,
2833  ExcQuadInexistant(line[0]->index(), line[1]->index(),
2834  line[2]->index(), line[3]->index()));
2835 
2836  if (not_found_quad_1)
2837  quad = needed_quads[quad_compare_2].first;
2838  else
2839  quad = needed_quads[quad_compare_1].first;
2840 
2841  // check whether this face is
2842  // really an exterior one
2843  AssertThrow (quad->at_boundary(),
2844  ExcInteriorQuadCantBeBoundary(quad->vertex_index(0),
2845  quad->vertex_index(1),
2846  quad->vertex_index(2),
2847  quad->vertex_index(3),
2848  boundary_quad->boundary_id));
2849 
2850  // and make sure that we don't
2851  // attempt to reset the
2852  // boundary indicator to a
2853  // different than the
2854  // previously set value
2855  if (quad->boundary_id() != 0)
2856  AssertThrow (quad->boundary_id() == boundary_quad->boundary_id,
2857  ExcMessage ("Duplicate boundary quads are only allowed "
2858  "if they carry the same boundary indicator."));
2859 
2860  quad->set_boundary_id (boundary_quad->boundary_id);
2861  quad->set_manifold_id (boundary_quad->manifold_id);
2862  }
2863 
2864 
2866  // finally update neighborship info
2868  cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
2869  for (unsigned int face=0; face<6; ++face)
2870  if (adjacent_cells[cell->quad(face)->index()][0] == cell)
2871  // first adjacent cell is
2872  // this one
2873  {
2874  if (adjacent_cells[cell->quad(face)->index()].size() == 2)
2875  // there is another
2876  // adjacent cell
2877  cell->set_neighbor (face,
2878  adjacent_cells[cell->quad(face)->index()][1]);
2879  }
2880  // first adjacent cell is not this
2881  // one, -> it must be the neighbor
2882  // we are looking for
2883  else
2884  cell->set_neighbor (face,
2885  adjacent_cells[cell->quad(face)->index()][0]);
2886  }
2887 
2888 
2904  template <int spacedim>
2905  static
2906  void
2909  std::vector<unsigned int> &,
2910  std::vector<unsigned int> &)
2911  {
2912  const unsigned int dim = 1;
2913 
2914  // first we need to reset the
2915  // neighbor pointers of the
2916  // neighbors of this cell's
2917  // children to this cell. This is
2918  // different for one dimension,
2919  // since there neighbors can have a
2920  // refinement level differing from
2921  // that of this cell's children by
2922  // more than one level.
2923 
2924  Assert (!cell->child(0)->has_children() && !cell->child(1)->has_children(),
2925  ExcInternalError());
2926 
2927  // first do it for the cells to the
2928  // left
2929  if (cell->neighbor(0).state() == IteratorState::valid)
2930  if (cell->neighbor(0)->has_children())
2931  {
2933  neighbor = cell->neighbor(0);
2934  Assert (neighbor->level() == cell->level(), ExcInternalError());
2935 
2936  // right child
2937  neighbor = neighbor->child(1);
2938  while (1)
2939  {
2940  Assert (neighbor->neighbor(1) == cell->child(0),
2941  ExcInternalError());
2942  neighbor->set_neighbor (1, cell);
2943 
2944  // move on to further
2945  // children on the
2946  // boundary between this
2947  // cell and its neighbor
2948  if (neighbor->has_children())
2949  neighbor = neighbor->child(1);
2950  else
2951  break;
2952  }
2953  }
2954 
2955  // now do it for the cells to the
2956  // left
2957  if (cell->neighbor(1).state() == IteratorState::valid)
2958  if (cell->neighbor(1)->has_children())
2959  {
2961  neighbor = cell->neighbor(1);
2962  Assert (neighbor->level() == cell->level(), ExcInternalError());
2963 
2964  // left child
2965  neighbor = neighbor->child(0);
2966  while (1)
2967  {
2968  Assert (neighbor->neighbor(0) == cell->child(1),
2969  ExcInternalError());
2970  neighbor->set_neighbor (0, cell);
2971 
2972  // move on to further
2973  // children on the
2974  // boundary between this
2975  // cell and its neighbor
2976  if (neighbor->has_children())
2977  neighbor = neighbor->child(0);
2978  else
2979  break;
2980  }
2981  }
2982 
2983 
2984  // delete the vertex which will not
2985  // be needed anymore. This vertex
2986  // is the second of the first child
2987  triangulation.vertices_used[cell->child(0)->vertex_index(1)] = false;
2988 
2989  // invalidate children. clear user
2990  // pointers, to avoid that they may
2991  // appear at unwanted places later
2992  // on...
2993  for (unsigned int child=0; child<cell->n_children(); ++child)
2994  {
2995  cell->child(child)->clear_user_data();
2996  cell->child(child)->clear_user_flag();
2997  cell->child(child)->clear_used_flag();
2998  }
2999 
3000 
3001  // delete pointer to children
3002  cell->clear_children ();
3003  cell->clear_user_flag();
3004  }
3005 
3006 
3007 
3008  template <int spacedim>
3009  static
3010  void
3011  delete_children (Triangulation<2,spacedim> &triangulation,
3013  std::vector<unsigned int> &line_cell_count,
3014  std::vector<unsigned int> &)
3015  {
3016  const unsigned int dim=2;
3017  const RefinementCase<dim> ref_case=cell->refinement_case();
3018 
3019  Assert(line_cell_count.size()==triangulation.n_raw_lines(), ExcInternalError());
3020 
3021  // vectors to hold all lines which
3022  // may be deleted
3023  std::vector<typename Triangulation<dim,spacedim>::line_iterator>
3024  lines_to_delete(0);
3025 
3026  lines_to_delete.reserve(4*2+4);
3027 
3028  // now we decrease the counters for
3029  // lines contained in the child
3030  // cells
3031  for (unsigned int c=0; c<cell->n_children(); ++c)
3032  {
3034  child=cell->child(c);
3035  for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
3036  --line_cell_count[child->line_index(l)];
3037  }
3038 
3039 
3040  // delete the vertex which will not
3041  // be needed anymore. This vertex
3042  // is the second of the second line
3043  // of the first child, if the cell
3044  // is refined with cut_xy, else there
3045  // is no inner vertex.
3046  // additionally delete unneeded inner
3047  // lines
3048  if (ref_case==RefinementCase<dim>::cut_xy)
3049  {
3050  triangulation.vertices_used[cell->child(0)->line(1)->vertex_index(1)] = false;
3051 
3052  lines_to_delete.push_back(cell->child(0)->line(1));
3053  lines_to_delete.push_back(cell->child(0)->line(3));
3054  lines_to_delete.push_back(cell->child(3)->line(0));
3055  lines_to_delete.push_back(cell->child(3)->line(2));
3056  }
3057  else
3058  {
3059  unsigned int inner_face_no=ref_case==RefinementCase<dim>::cut_x ? 1 : 3;
3060 
3061  // the inner line will not be
3062  // used any more
3063  lines_to_delete.push_back(cell->child(0)->line(inner_face_no));
3064  }
3065 
3066  // invalidate children
3067  for (unsigned int child=0; child<cell->n_children(); ++child)
3068  {
3069  cell->child(child)->clear_user_data();
3070  cell->child(child)->clear_user_flag();
3071  cell->child(child)->clear_used_flag();
3072  }
3073 
3074 
3075  // delete pointer to children
3076  cell->clear_children ();
3077  cell->clear_refinement_case();
3078  cell->clear_user_flag();
3079 
3080  // look at the refinement of outer
3081  // lines. if nobody needs those
3082  // anymore we can add them to the
3083  // list of lines to be deleted.
3084  for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
3085  {
3086  typename Triangulation<dim,spacedim>::line_iterator
3087  line=cell->line(line_no);
3088 
3089  if (line->has_children())
3090  {
3091  // if one of the cell counters is
3092  // zero, the other has to be as well
3093 
3094  Assert((line_cell_count[line->child_index(0)] == 0 &&
3095  line_cell_count[line->child_index(1)] == 0) ||
3096  (line_cell_count[line->child_index(0)] > 0 &&
3097  line_cell_count[line->child_index(1)] > 0),
3098  ExcInternalError());
3099 
3100  if (line_cell_count[line->child_index(0)]==0)
3101  {
3102  for (unsigned int c=0; c<2; ++c)
3103  Assert (!line->child(c)->has_children(),
3104  ExcInternalError());
3105 
3106  // we may delete the line's
3107  // children and the middle vertex
3108  // as no cell references them
3109  // anymore
3110  triangulation.vertices_used[line->child(0)->vertex_index(1)] = false;
3111 
3112  lines_to_delete.push_back(line->child(0));
3113  lines_to_delete.push_back(line->child(1));
3114 
3115  line->clear_children();
3116  }
3117  }
3118  }
3119 
3120  // finally, delete unneeded lines
3121 
3122  // clear user pointers, to avoid that
3123  // they may appear at unwanted places
3124  // later on...
3125  // same for user flags, then finally
3126  // delete the lines
3127  typename std::vector<typename Triangulation<dim,spacedim>::line_iterator>::iterator
3128  line=lines_to_delete.begin(),
3129  endline=lines_to_delete.end();
3130  for (; line!=endline; ++line)
3131  {
3132  (*line)->clear_user_data();
3133  (*line)->clear_user_flag();
3134  (*line)->clear_used_flag();
3135  }
3136  }
3137 
3138 
3139 
3140  template <int spacedim>
3141  static
3142  void
3143  delete_children (Triangulation<3,spacedim> &triangulation,
3145  std::vector<unsigned int> &line_cell_count,
3146  std::vector<unsigned int> &quad_cell_count)
3147  {
3148  const unsigned int dim=3;
3149 
3150  Assert(line_cell_count.size()==triangulation.n_raw_lines(), ExcInternalError());
3151  Assert(quad_cell_count.size()==triangulation.n_raw_quads(), ExcInternalError());
3152 
3153  // first of all, we store the RefineCase of
3154  // this cell
3155  const RefinementCase<dim> ref_case=cell->refinement_case();
3156  // vectors to hold all lines and quads which
3157  // may be deleted
3158  std::vector<typename Triangulation<dim,spacedim>::line_iterator>
3159  lines_to_delete(0);
3160  std::vector<typename Triangulation<dim,spacedim>::quad_iterator>
3161  quads_to_delete(0);
3162 
3163  lines_to_delete.reserve(12*2+6*4+6);
3164  quads_to_delete.reserve(6*4+12);
3165 
3166  // now we decrease the counters for lines and
3167  // quads contained in the child cells
3168  for (unsigned int c=0; c<cell->n_children(); ++c)
3169  {
3171  child=cell->child(c);
3172  for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
3173  --line_cell_count[child->line_index(l)];
3174  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
3175  --quad_cell_count[child->quad_index(f)];
3176  }
3177 
3179  // delete interior quads and lines and the
3180  // interior vertex, depending on the
3181  // refinement case of the cell
3182  //
3183  // for append quads and lines: only append
3184  // them to the list of objects to be deleted
3185 
3186  switch (ref_case)
3187  {
3189  quads_to_delete.push_back(cell->child(0)->face(1));
3190  break;
3192  quads_to_delete.push_back(cell->child(0)->face(3));
3193  break;
3195  quads_to_delete.push_back(cell->child(0)->face(5));
3196  break;
3198  quads_to_delete.push_back(cell->child(0)->face(1));
3199  quads_to_delete.push_back(cell->child(0)->face(3));
3200  quads_to_delete.push_back(cell->child(3)->face(0));
3201  quads_to_delete.push_back(cell->child(3)->face(2));
3202 
3203  lines_to_delete.push_back(cell->child(0)->line(11));
3204  break;
3206  quads_to_delete.push_back(cell->child(0)->face(1));
3207  quads_to_delete.push_back(cell->child(0)->face(5));
3208  quads_to_delete.push_back(cell->child(3)->face(0));
3209  quads_to_delete.push_back(cell->child(3)->face(4));
3210 
3211  lines_to_delete.push_back(cell->child(0)->line(5));
3212  break;
3214  quads_to_delete.push_back(cell->child(0)->face(3));
3215  quads_to_delete.push_back(cell->child(0)->face(5));
3216  quads_to_delete.push_back(cell->child(3)->face(2));
3217  quads_to_delete.push_back(cell->child(3)->face(4));
3218 
3219  lines_to_delete.push_back(cell->child(0)->line(7));
3220  break;
3222  quads_to_delete.push_back(cell->child(0)->face(1));
3223  quads_to_delete.push_back(cell->child(2)->face(1));
3224  quads_to_delete.push_back(cell->child(4)->face(1));
3225  quads_to_delete.push_back(cell->child(6)->face(1));
3226 
3227  quads_to_delete.push_back(cell->child(0)->face(3));
3228  quads_to_delete.push_back(cell->child(1)->face(3));
3229  quads_to_delete.push_back(cell->child(4)->face(3));
3230  quads_to_delete.push_back(cell->child(5)->face(3));
3231 
3232  quads_to_delete.push_back(cell->child(0)->face(5));
3233  quads_to_delete.push_back(cell->child(1)->face(5));
3234  quads_to_delete.push_back(cell->child(2)->face(5));
3235  quads_to_delete.push_back(cell->child(3)->face(5));
3236 
3237  lines_to_delete.push_back(cell->child(0)->line(5));
3238  lines_to_delete.push_back(cell->child(0)->line(7));
3239  lines_to_delete.push_back(cell->child(0)->line(11));
3240  lines_to_delete.push_back(cell->child(7)->line(0));
3241  lines_to_delete.push_back(cell->child(7)->line(2));
3242  lines_to_delete.push_back(cell->child(7)->line(8));
3243  // delete the vertex which will not
3244  // be needed anymore. This vertex
3245  // is the vertex at the heart of
3246  // this cell, which is the sixth of
3247  // the first child
3248  triangulation.vertices_used[cell->child(0)->vertex_index(7)] = false;
3249  break;
3250  default:
3251  // only remaining case is
3252  // no_refinement, thus an error
3253  Assert(false, ExcInternalError());
3254  break;
3255  }
3256 
3257 
3258  // invalidate children
3259  for (unsigned int child=0; child<cell->n_children(); ++child)
3260  {
3261  cell->child(child)->clear_user_data();
3262  cell->child(child)->clear_user_flag();
3263 
3264  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
3265  {
3266  // set flags denoting deviations from
3267  // standard orientation of faces back
3268  // to initialization values
3269  cell->child(child)->set_face_orientation (f, true);
3270  cell->child(child)->set_face_flip(f,false);
3271  cell->child(child)->set_face_rotation(f,false);
3272  }
3273 
3274  cell->child(child)->clear_used_flag();
3275  }
3276 
3277 
3278  // delete pointer to children
3279  cell->clear_children ();
3280  cell->clear_refinement_case ();
3281  cell->clear_user_flag();
3282 
3283  // so far we only looked at inner quads,
3284  // lines and vertices. Now we have to
3285  // consider outer ones as well. here, we have
3286  // to check, whether there are other cells
3287  // still needing these objects. oherwise we
3288  // can delete them. first for quads (and
3289  // their inner lines).
3290 
3291  for (unsigned int quad_no=0; quad_no<GeometryInfo<dim>::faces_per_cell; ++quad_no)
3292  {
3293  typename Triangulation<dim,spacedim>::quad_iterator
3294  quad=cell->face(quad_no);
3295 
3296  Assert((GeometryInfo<dim>::face_refinement_case(ref_case,quad_no) && quad->has_children()) ||
3297  GeometryInfo<dim>::face_refinement_case(ref_case,quad_no)==RefinementCase<dim-1>::no_refinement,
3298  ExcInternalError());
3299 
3300  switch (quad->refinement_case())
3301  {
3302  case RefinementCase<dim-1>::no_refinement:
3303  // nothing to do as the quad
3304  // is not refined
3305  break;
3306  case RefinementCase<dim-1>::cut_x:
3307  case RefinementCase<dim-1>::cut_y:
3308  {
3309  // if one of the cell counters is
3310  // zero, the other has to be as
3311  // well
3312  Assert((quad_cell_count[quad->child_index(0)] == 0 &&
3313  quad_cell_count[quad->child_index(1)] == 0) ||
3314  (quad_cell_count[quad->child_index(0)] > 0 &&
3315  quad_cell_count[quad->child_index(1)] > 0),
3316  ExcInternalError());
3317  // it might be, that the quad is
3318  // refined twice anisotropically,
3319  // first check, whether we may
3320  // delete possible grand_children
3321  unsigned int deleted_grandchildren=0;
3322  unsigned int number_of_child_refinements=0;
3323 
3324  for (unsigned int c=0; c<2; ++c)
3325  if (quad->child(c)->has_children())
3326  {
3327  ++number_of_child_refinements;
3328  // if one of the cell counters is
3329  // zero, the other has to be as
3330  // well
3331  Assert((quad_cell_count[quad->child(c)->child_index(0)] == 0 &&
3332  quad_cell_count[quad->child(c)->child_index(1)] == 0) ||
3333  (quad_cell_count[quad->child(c)->child_index(0)] > 0 &&
3334  quad_cell_count[quad->child(c)->child_index(1)] > 0),
3335  ExcInternalError());
3336  if (quad_cell_count[quad->child(c)->child_index(0)]==0)
3337  {
3338  // Assert, that the two
3339  // anisotropic
3340  // refinements add up to
3341  // isotropic refinement
3342  Assert(quad->refinement_case()+quad->child(c)->refinement_case()==RefinementCase<dim>::cut_xy,
3343  ExcInternalError());
3344  // we may delete the
3345  // quad's children and
3346  // the inner line as no
3347  // cell references them
3348  // anymore
3349  quads_to_delete.push_back(quad->child(c)->child(0));
3350  quads_to_delete.push_back(quad->child(c)->child(1));
3351  if (quad->child(c)->refinement_case()==RefinementCase<2>::cut_x)
3352  lines_to_delete.push_back(quad->child(c)->child(0)->line(1));
3353  else
3354  lines_to_delete.push_back(quad->child(c)->child(0)->line(3));
3355  quad->child(c)->clear_children();
3356  quad->child(c)->clear_refinement_case();
3357  ++deleted_grandchildren;
3358  }
3359  }
3360  // if no grandchildren are left, we
3361  // may as well delete the
3362  // refinement of the inner line
3363  // between our children and the
3364  // corresponding vertex
3365  if (number_of_child_refinements>0 &&
3366  deleted_grandchildren==number_of_child_refinements)
3367  {
3368  typename Triangulation<dim,spacedim>::line_iterator
3369  middle_line;
3370  if (quad->refinement_case()==RefinementCase<2>::cut_x)
3371  middle_line=quad->child(0)->line(1);
3372  else
3373  middle_line=quad->child(0)->line(3);
3374 
3375  lines_to_delete.push_back(middle_line->child(0));
3376  lines_to_delete.push_back(middle_line->child(1));
3377  triangulation.vertices_used[middle_vertex_index<dim,spacedim>(middle_line)]
3378  = false;
3379  middle_line->clear_children();
3380  }
3381 
3382  // now consider the direct children
3383  // of the given quad
3384  if (quad_cell_count[quad->child_index(0)]==0)
3385  {
3386  // we may delete the quad's
3387  // children and the inner line
3388  // as no cell references them
3389  // anymore
3390  quads_to_delete.push_back(quad->child(0));
3391  quads_to_delete.push_back(quad->child(1));
3392  if (quad->refinement_case()==RefinementCase<2>::cut_x)
3393  lines_to_delete.push_back(quad->child(0)->line(1));
3394  else
3395  lines_to_delete.push_back(quad->child(0)->line(3));
3396 
3397  // if the counters just dropped
3398  // to zero, otherwise the
3399  // children would have been
3400  // deleted earlier, then this
3401  // cell's children must have
3402  // contained the anisotropic
3403  // quad children. thus, if
3404  // those have again anisotropic
3405  // children, which are in
3406  // effect isotropic children of
3407  // the original quad, those are
3408  // still needed by a
3409  // neighboring cell and we
3410  // cannot delete them. instead,
3411  // we have to reset this quad's
3412  // refine case to isotropic and
3413  // set the children
3414  // accordingly.
3415  if (quad->child(0)->has_children())
3416  if (quad->refinement_case()==RefinementCase<2>::cut_x)
3417  {
3418  // now evereything is
3419  // quite complicated. we
3420  // have the children
3421  // numbered according to
3422  //
3423  // *---*---*
3424  // |n+1|m+1|
3425  // *---*---*
3426  // | n | m |
3427  // *---*---*
3428  //
3429  // from the original
3430  // anisotropic
3431  // refinement. we have to
3432  // reorder them as
3433  //
3434  // *---*---*
3435  // | m |m+1|
3436  // *---*---*
3437  // | n |n+1|
3438  // *---*---*
3439  //
3440  // for isotropic refinement.
3441  //
3442  // this is a bit ugly, of
3443  // course: loop over all
3444  // cells on all levels
3445  // and look for faces n+1
3446  // (switch_1) and m
3447  // (switch_2).
3448  const typename Triangulation<dim,spacedim>::quad_iterator
3449  switch_1=quad->child(0)->child(1),
3450  switch_2=quad->child(1)->child(0);
3451 
3452  Assert(!switch_1->has_children(), ExcInternalError());
3453  Assert(!switch_2->has_children(), ExcInternalError());
3454 
3455  const int switch_1_index=switch_1->index();
3456  const int switch_2_index=switch_2->index();
3457  for (unsigned int l=0; l<triangulation.levels.size(); ++l)
3458  for (unsigned int h=0; h<triangulation.levels[l]->cells.cells.size(); ++h)
3459  for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
3460  {
3461  const int index=triangulation.levels[l]->cells.cells[h].face(q);
3462  if (index==switch_1_index)
3463  triangulation.levels[l]->cells.cells[h].set_face(q,switch_2_index);
3464  else if (index==switch_2_index)
3465  triangulation.levels[l]->cells.cells[h].set_face(q,switch_1_index);
3466  }
3467  // now we have to copy
3468  // all information of the
3469  // two quads
3470  const int switch_1_lines[4]=
3471  {
3472  static_cast<signed int>(switch_1->line_index(0)),
3473  static_cast<signed int>(switch_1->line_index(1)),
3474  static_cast<signed int>(switch_1->line_index(2)),
3475  static_cast<signed int>(switch_1->line_index(3))
3476  };
3477  const bool switch_1_line_orientations[4]=
3478  {
3479  switch_1->line_orientation(0),
3480  switch_1->line_orientation(1),
3481  switch_1->line_orientation(2),
3482  switch_1->line_orientation(3)
3483  };
3484  const types::boundary_id switch_1_boundary_id=switch_1->boundary_id();
3485  const unsigned int switch_1_user_index=switch_1->user_index();
3486  const bool switch_1_user_flag=switch_1->user_flag_set();
3487 
3488  switch_1->set(internal::Triangulation::TriaObject<2>(switch_2->line_index(0),
3489  switch_2->line_index(1),
3490  switch_2->line_index(2),
3491  switch_2->line_index(3)));
3492  switch_1->set_line_orientation(0, switch_2->line_orientation(0));
3493  switch_1->set_line_orientation(1, switch_2->line_orientation(1));
3494  switch_1->set_line_orientation(2, switch_2->line_orientation(2));
3495  switch_1->set_line_orientation(3, switch_2->line_orientation(3));
3496  switch_1->set_boundary_id(switch_2->boundary_id());
3497  switch_1->set_manifold_id(switch_2->manifold_id());
3498  switch_1->set_user_index(switch_2->user_index());
3499  if (switch_2->user_flag_set())
3500  switch_1->set_user_flag();
3501  else
3502  switch_1->clear_user_flag();
3503 
3504  switch_2->set(internal::Triangulation::TriaObject<2>(switch_1_lines[0],
3505  switch_1_lines[1],
3506  switch_1_lines[2],
3507  switch_1_lines[3]));
3508  switch_2->set_line_orientation(0, switch_1_line_orientations[0]);
3509  switch_2->set_line_orientation(1, switch_1_line_orientations[1]);
3510  switch_2->set_line_orientation(2, switch_1_line_orientations[2]);
3511  switch_2->set_line_orientation(3, switch_1_line_orientations[3]);
3512  switch_2->set_boundary_id(switch_1_boundary_id);
3513  switch_2->set_manifold_id(switch_1->manifold_id());
3514  switch_2->set_user_index(switch_1_user_index);
3515  if (switch_1_user_flag)
3516  switch_2->set_user_flag();
3517  else
3518  switch_2->clear_user_flag();
3519 
3520  const unsigned int child_0=quad->child(0)->child_index(0);
3521  const unsigned int child_2=quad->child(1)->child_index(0);
3522  quad->clear_children();
3523  quad->clear_refinement_case();
3524  quad->set_refinement_case(RefinementCase<2>::cut_xy);
3525  quad->set_children(0,child_0);
3526  quad->set_children(2,child_2);
3527  std::swap(quad_cell_count[child_0+1],quad_cell_count[child_2]);
3528  }
3529  else
3530  {
3531  // the face was refined
3532  // with cut_y, thus the
3533  // children are already
3534  // in correct order. we
3535  // only have to set them
3536  // correctly, deleting
3537  // the indirection of two
3538  // anisotropic refinement
3539  // and going directly
3540  // from the quad to
3541  // isotropic children
3542  const unsigned int child_0=quad->child(0)->child_index(0);
3543  const unsigned int child_2=quad->child(1)->child_index(0);
3544  quad->clear_children();
3545  quad->clear_refinement_case();
3546  quad->set_refinement_case(RefinementCase<2>::cut_xy);
3547  quad->set_children(0,child_0);
3548  quad->set_children(2,child_2);
3549  }
3550  else
3551  {
3552  quad->clear_children();
3553  quad->clear_refinement_case();
3554  }
3555 
3556 
3557  }
3558  break;
3559  }
3560  case RefinementCase<dim-1>::cut_xy:
3561  {
3562  // if one of the cell counters is
3563  // zero, the others have to be as
3564  // well
3565 
3566  Assert((quad_cell_count[quad->child_index(0)] == 0 &&
3567  quad_cell_count[quad->child_index(1)] == 0 &&
3568  quad_cell_count[quad->child_index(2)] == 0 &&
3569  quad_cell_count[quad->child_index(3)] == 0) ||
3570  (quad_cell_count[quad->child_index(0)] > 0 &&
3571  quad_cell_count[quad->child_index(1)] > 0 &&
3572  quad_cell_count[quad->child_index(2)] > 0 &&
3573  quad_cell_count[quad->child_index(3)] > 0),
3574  ExcInternalError());
3575 
3576  if (quad_cell_count[quad->child_index(0)]==0)
3577  {
3578  // we may delete the quad's
3579  // children, the inner lines
3580  // and the middle vertex as no
3581  // cell references them anymore
3582  lines_to_delete.push_back(quad->child(0)->line(1));
3583  lines_to_delete.push_back(quad->child(3)->line(0));
3584  lines_to_delete.push_back(quad->child(0)->line(3));
3585  lines_to_delete.push_back(quad->child(3)->line(2));
3586 
3587  for (unsigned int child=0; child<quad->n_children(); ++child)
3588  quads_to_delete.push_back(quad->child(child));
3589 
3590  triangulation.vertices_used[quad->child(0)->vertex_index(3)] = false;
3591 
3592  quad->clear_children();
3593  quad->clear_refinement_case();
3594  }
3595  }
3596  break;
3597 
3598  default:
3599  Assert(false, ExcInternalError());
3600  break;
3601  }
3602 
3603  }
3604 
3605  // now we repeat a similar procedure
3606  // for the outer lines of this cell.
3607 
3608  // if in debug mode: check that each
3609  // of the lines for which we consider
3610  // deleting the children in fact has
3611  // children (the bits/coarsening_3d
3612  // test tripped over this initially)
3613  for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
3614  {
3615  typename Triangulation<dim,spacedim>::line_iterator
3616  line=cell->line(line_no);
3617 
3618  Assert((GeometryInfo<dim>::line_refinement_case(ref_case,line_no) && line->has_children()) ||
3620  ExcInternalError());
3621 
3622  if (line->has_children())
3623  {
3624  // if one of the cell counters is
3625  // zero, the other has to be as well
3626 
3627  Assert((line_cell_count[line->child_index(0)] == 0 &&
3628  line_cell_count[line->child_index(1)] == 0) ||
3629  (line_cell_count[line->child_index(0)] > 0 &&
3630  line_cell_count[line->child_index(1)] > 0),
3631  ExcInternalError());
3632 
3633  if (line_cell_count[line->child_index(0)]==0)
3634  {
3635  for (unsigned int c=0; c<2; ++c)
3636  Assert (!line->child(c)->has_children(),
3637  ExcInternalError());
3638 
3639  // we may delete the line's
3640  // children and the middle vertex
3641  // as no cell references them
3642  // anymore
3643  triangulation.vertices_used[line->child(0)->vertex_index(1)] = false;
3644 
3645  lines_to_delete.push_back(line->child(0));
3646  lines_to_delete.push_back(line->child(1));
3647 
3648  line->clear_children();
3649  }
3650  }
3651  }
3652 
3653  // finally, delete unneeded quads and lines
3654 
3655  // clear user pointers, to avoid that
3656  // they may appear at unwanted places
3657  // later on...
3658  // same for user flags, then finally
3659  // delete the quads and lines
3660  typename std::vector<typename Triangulation<dim,spacedim>::line_iterator>::iterator
3661  line=lines_to_delete.begin(),
3662  endline=lines_to_delete.end();
3663  for (; line!=endline; ++line)
3664  {
3665  (*line)->clear_user_data();
3666  (*line)->clear_user_flag();
3667  (*line)->clear_used_flag();
3668  }
3669 
3670  typename std::vector<typename Triangulation<dim,spacedim>::quad_iterator>::iterator
3671  quad=quads_to_delete.begin(),
3672  endquad=quads_to_delete.end();
3673  for (; quad!=endquad; ++quad)
3674  {
3675  (*quad)->clear_user_data();
3676  (*quad)->clear_children();
3677  (*quad)->clear_refinement_case();
3678  (*quad)->clear_user_flag();
3679  (*quad)->clear_used_flag();
3680  }
3681  }
3682 
3683 
3701  template <int spacedim>
3702  static
3703  void
3705  unsigned int &next_unused_vertex,
3706  typename Triangulation<2,spacedim>::raw_line_iterator &next_unused_line,
3707  typename Triangulation<2,spacedim>::raw_cell_iterator &next_unused_cell,
3709  {
3710  const unsigned int dim=2;
3711  // clear refinement flag
3712  const RefinementCase<dim> ref_case=cell->refine_flag_set();
3713  cell->clear_refine_flag ();
3714 
3715  /* For the refinement process: since we go the levels up from the lowest, there
3716  are (unlike above) only two possibilities: a neighbor cell is on the same
3717  level or one level up (in both cases, it may or may not be refined later on,
3718  but we don't care here).
3719 
3720  First:
3721  Set up an array of the 3x3 vertices, which are distributed on the cell
3722  (the array consists of indices into the @p{vertices} std::vector
3723 
3724  2--7--3
3725  | | |
3726  4--8--5
3727  | | |
3728  0--6--1
3729 
3730  note: in case of cut_x or cut_y not all these vertices are needed for the new
3731  cells
3732 
3733  Second:
3734  Set up an array of the new lines (the array consists of iterator pointers
3735  into the lines arrays)
3736 
3737  .-6-.-7-. The directions are: .->-.->-.
3738  1 9 3 ^ ^ ^
3739  .-10.11-. .->-.->-.
3740  0 8 2 ^ ^ ^
3741  .-4-.-5-. .->-.->-.
3742 
3743  cut_x:
3744  .-4-.-5-.
3745  | | |
3746  0 6 1
3747  | | |
3748  .-2-.-3-.
3749 
3750  cut_y:
3751  .---5---.
3752  1 3
3753  .---6---.
3754  0 2
3755  .---4---.
3756 
3757 
3758  Third:
3759  Set up an array of neighbors:
3760 
3761  6 7
3762  .--.--.
3763  1| | |3
3764  .--.--.
3765  0| | |2
3766  .--.--.
3767  4 5
3768 
3769  We need this array for two reasons: first to get the lines which will
3770  bound the four subcells (if the neighboring cell is refined, these
3771  lines already exist), and second to update neighborship information.
3772  Since if a neighbor is not refined, its neighborship record only
3773  points to the present, unrefined, cell rather than the children we
3774  are presently creating, we only need the neighborship information
3775  if the neighbor cells are refined. In all other cases, we store
3776  the unrefined neighbor address
3777 
3778  We also need for every neighbor (if refined) which number among its
3779  neighbors the present (unrefined) cell has, since that number is to
3780  be replaced and because that also is the number of the subline which
3781  will be the interface between that neighbor and the to be created cell.
3782  We will store this number (between 0 and 3) in the field
3783  @p{neighbors_neighbor}.
3784 
3785  It would be sufficient to use the children of the common line to the
3786  neighbor, if we only wanted to get the new sublines and the new vertex,
3787  but because we need to update the neighborship information of the
3788  two refined subcells of the neighbor, we need to search these anyway.
3789 
3790  Convention:
3791  The created children are numbered like this:
3792 
3793  .--.--.
3794  |2 . 3|
3795  .--.--.
3796  |0 | 1|
3797  .--.--.
3798  */
3799  // collect the
3800  // indices of the
3801  // eight
3802  // surrounding
3803  // vertices
3804  // 2--7--3
3805  // | | |
3806  // 4--9--5
3807  // | | |
3808  // 0--6--1
3809  int new_vertices[9];
3810  for (unsigned int vertex_no=0; vertex_no<4; ++vertex_no)
3811  new_vertices[vertex_no]=cell->vertex_index(vertex_no);
3812  for (unsigned int line_no=0; line_no<4; ++line_no)
3813  if (cell->line(line_no)->has_children())
3814  new_vertices[4+line_no]=cell->line(line_no)->child(0)->vertex_index(1);
3815 
3816  if (ref_case==RefinementCase<dim>::cut_xy)
3817  {
3818 
3819  // find the next
3820  // unused vertex and
3821  // allocate it for
3822  // the new vertex we
3823  // need here
3824  while (triangulation.vertices_used[next_unused_vertex] == true)
3825  ++next_unused_vertex;
3826  Assert (next_unused_vertex < triangulation.vertices.size(),
3827  ExcMessage("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."));
3828  triangulation.vertices_used[next_unused_vertex] = true;
3829 
3830  new_vertices[8] = next_unused_vertex;
3831 
3832  // if this quad lives
3833  // in 2d, then we can
3834  // compute the new
3835  // central vertex
3836  // location just from
3837  // the surrounding
3838  // ones. If this is
3839  // not the case, then
3840  // we need to ask a
3841  // boundary object
3842  if (dim == spacedim)
3843  {
3844  // triangulation.vertices[next_unused_vertex] = new_point;
3845  triangulation.vertices[next_unused_vertex] = cell->center(true);
3846 
3847  // if the user_flag is set, i.e. if the
3848  // cell is at the boundary, use a
3849  // different calculation of the middle
3850  // vertex here. this is of advantage, if
3851  // the boundary is strongly curved and
3852  // the cell has a high aspect ratio. this
3853  // can happen for example, if it was
3854  // refined anisotropically before.
3855  if (cell->user_flag_set())
3856  {
3857  // first reset the user_flag
3858  cell->clear_user_flag();
3859  // the user flag indicates: at least
3860  // one face is at the boundary. if it
3861  // is only one, set the new middle
3862  // vertex in a different way to avoid
3863  // some mis-shaped elements if the
3864  // new point on the boundary is not
3865  // where we expect it, especially if
3866  // it is to far inside the current
3867  // cell
3868  unsigned int boundary_face=GeometryInfo<dim>::faces_per_cell;
3869  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
3870  if (cell->face(face)->at_boundary())
3871  {
3872  if (boundary_face == GeometryInfo<dim>::faces_per_cell)
3873  // no boundary face found so
3874  // far, so set it now
3875  boundary_face=face;
3876  else
3877  // there is another boundary
3878  // face, so reset boundary_face to
3879  // invalid value as a flag to
3880  // do nothing in the following
3881  boundary_face=GeometryInfo<dim>::faces_per_cell+1;
3882  }
3883 
3884  if (boundary_face<GeometryInfo<dim>::faces_per_cell)
3885  // reset the cell's middle vertex to the middle
3886  // of the straight connection between the new
3887  // points on this face and on the opposite face,
3888  // as returned by the underlying manifold
3889  // object.
3890  {
3891  std::vector<Point<spacedim> > ps(2);
3892  std::vector<double> ws(2, 0.5);
3893  ps[0] = cell->face(boundary_face)
3894  ->child(0)->vertex(1);
3895  ps[1] = cell->face(GeometryInfo<dim>
3896  ::opposite_face[boundary_face])
3897  ->child(0)->vertex(1);
3898  Quadrature<spacedim> qs(ps,ws);
3899  triangulation.vertices[next_unused_vertex]
3900  = cell->get_manifold().get_new_point(qs);
3901  }
3902  }
3903  }
3904  else
3905  {
3906  // if this quad lives in a higher dimensional space
3907  // then we don't need to worry if it is at the
3908  // boundary of the manifold -- we always have to use
3909  // the boundary object anyway; so ignore whether the
3910  // user flag is set or not
3911  cell->clear_user_flag();
3912 
3913  // An assert to make sure that the static_cast in the
3914  // next line has the chance to give reasonable
3915  // results.
3916  Assert(cell->material_id()<= std::numeric_limits<types::material_id>::max(),
3917  ExcIndexRange(cell->material_id(),0,std::numeric_limits<types::material_id>::max()));
3918 
3919  // new vertex is placed on the surface according to
3920  // the information stored in the boundary class
3921  triangulation.vertices[next_unused_vertex] =
3922  cell->center(true);
3923  }
3924  }
3925 
3926 
3927  // Now the lines:
3928  typename Triangulation<dim,spacedim>::raw_line_iterator new_lines[12];
3929  unsigned int lmin=8;
3930  unsigned int lmax=12;
3931  if (ref_case!=RefinementCase<dim>::cut_xy)
3932  {
3933  lmin=6;
3934  lmax=7;
3935  }
3936 
3937  for (unsigned int l=lmin; l<lmax; ++l)
3938  {
3939  while (next_unused_line->used() == true)
3940  ++next_unused_line;
3941  new_lines[l] = next_unused_line;
3942  ++next_unused_line;
3943 
3944  Assert (new_lines[l]->used() == false,
3945  ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
3946  }
3947 
3948  if (ref_case==RefinementCase<dim>::cut_xy)
3949  {
3950  // .-6-.-7-.
3951  // 1 9 3
3952  // .-10.11-.
3953  // 0 8 2
3954  // .-4-.-5-.
3955 
3956  // lines 0-7 already exist, create only the four interior
3957  // lines 8-11
3958  unsigned int l=0;
3959  for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
3960  for (unsigned int c=0; c<2; ++c, ++l)
3961  new_lines[l]=cell->line(face_no)->child(c);
3962  Assert(l==8, ExcInternalError());
3963 
3964  new_lines[8] ->set (internal::Triangulation::
3965  TriaObject<1>(new_vertices[6], new_vertices[8]));
3966  new_lines[9] ->set (internal::Triangulation::
3967  TriaObject<1>(new_vertices[8], new_vertices[7]));
3968  new_lines[10]->set (internal::Triangulation::
3969  TriaObject<1>(new_vertices[4], new_vertices[8]));
3970  new_lines[11]->set (internal::Triangulation::
3971  TriaObject<1>(new_vertices[8], new_vertices[5]));
3972  }
3973  else if (ref_case==RefinementCase<dim>::cut_x)
3974  {
3975  // .-4-.-5-.
3976  // | | |
3977  // 0 6 1
3978  // | | |
3979  // .-2-.-3-.
3980  new_lines[0]=cell->line(0);
3981  new_lines[1]=cell->line(1);
3982  new_lines[2]=cell->line(2)->child(0);
3983  new_lines[3]=cell->line(2)->child(1);
3984  new_lines[4]=cell->line(3)->child(0);
3985  new_lines[5]=cell->line(3)->child(1);
3986  new_lines[6]->set (internal::Triangulation::
3987  TriaObject<1>(new_vertices[6], new_vertices[7]));
3988  }
3989  else
3990  {
3991  Assert(ref_case==RefinementCase<dim>::cut_y, ExcInternalError());
3992  // .---5---.
3993  // 1 3
3994  // .---6---.
3995  // 0 2
3996  // .---4---.
3997  new_lines[0]=cell->line(0)->child(0);
3998  new_lines[1]=cell->line(0)->child(1);
3999  new_lines[2]=cell->line(1)->child(0);
4000  new_lines[3]=cell->line(1)->child(1);
4001  new_lines[4]=cell->line(2);
4002  new_lines[5]=cell->line(3);
4003  new_lines[6]->set (internal::Triangulation::
4004  TriaObject<1>(new_vertices[4], new_vertices[5]));
4005  }
4006 
4007  for (unsigned int l=lmin; l<lmax; ++l)
4008  {
4009  new_lines[l]->set_used_flag();
4010  new_lines[l]->clear_user_flag();
4011  new_lines[l]->clear_user_data();
4012  new_lines[l]->clear_children();
4013  // interior line
4014  new_lines[l]->set_boundary_id(numbers::internal_face_boundary_id);
4015  new_lines[l]->set_manifold_id(cell->manifold_id());
4016  }
4017 
4018  // Now add the four (two)
4019  // new cells!
4022  while (next_unused_cell->used() == true)
4023  ++next_unused_cell;
4024 
4025  const unsigned int n_children=
4027  for (unsigned int i=0; i<n_children; ++i)
4028  {
4029  Assert (next_unused_cell->used() == false,
4030  ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4031  subcells[i] = next_unused_cell;
4032  ++next_unused_cell;
4033  if (i%2==1 && i<n_children-1)
4034  while (next_unused_cell->used() == true)
4035  ++next_unused_cell;
4036  }
4037 
4038  if (ref_case==RefinementCase<dim>::cut_xy)
4039  {
4040  // children:
4041  // .--.--.
4042  // |2 . 3|
4043  // .--.--.
4044  // |0 | 1|
4045  // .--.--.
4046  // lines:
4047  // .-6-.-7-.
4048  // 1 9 3
4049  // .-10.11-.
4050  // 0 8 2
4051  // .-4-.-5-.
4052  subcells[0]->set (internal::Triangulation::
4053  TriaObject<2>(new_lines[0]->index(),
4054  new_lines[8]->index(),
4055  new_lines[4]->index(),
4056  new_lines[10]->index()));
4057  subcells[1]->set (internal::Triangulation::
4058  TriaObject<2>(new_lines[8]->index(),
4059  new_lines[2]->index(),
4060  new_lines[5]->index(),
4061  new_lines[11]->index()));
4062  subcells[2]->set (internal::Triangulation::
4063  TriaObject<2>(new_lines[1]->index(),
4064  new_lines[9]->index(),
4065  new_lines[10]->index(),
4066  new_lines[6]->index()));
4067  subcells[3]->set (internal::Triangulation::
4068  TriaObject<2>(new_lines[9]->index(),
4069  new_lines[3]->index(),
4070  new_lines[11]->index(),
4071  new_lines[7]->index()));
4072  }
4073  else if (ref_case==RefinementCase<dim>::cut_x)
4074  {
4075  // children:
4076  // .--.--.
4077  // | . |
4078  // .0 . 1.
4079  // | | |
4080  // .--.--.
4081  // lines:
4082  // .-4-.-5-.
4083  // | | |
4084  // 0 6 1
4085  // | | |
4086  // .-2-.-3-.
4087  subcells[0]->set (internal::Triangulation::
4088  TriaObject<2>(new_lines[0]->index(),
4089  new_lines[6]->index(),
4090  new_lines[2]->index(),
4091  new_lines[4]->index()));
4092  subcells[1]->set (internal::Triangulation::
4093  TriaObject<2>(new_lines[6]->index(),
4094  new_lines[1]->index(),
4095  new_lines[3]->index(),
4096  new_lines[5]->index()));
4097  }
4098  else
4099  {
4100  Assert(ref_case==RefinementCase<dim>::cut_y, ExcInternalError());
4101  // children:
4102  // .-----.
4103  // | 1 |
4104  // .-----.
4105  // | 0 |
4106  // .-----.
4107  // lines:
4108  // .---5---.
4109  // 1 3
4110  // .---6---.
4111  // 0 2
4112  // .---4---.
4113  subcells[0]->set (internal::Triangulation::
4114  TriaObject<2>(new_lines[0]->index(),
4115  new_lines[2]->index(),
4116  new_lines[4]->index(),
4117  new_lines[6]->index()));
4118  subcells[1]->set (internal::Triangulation::
4119  TriaObject<2>(new_lines[1]->index(),
4120  new_lines[3]->index(),
4121  new_lines[6]->index(),
4122  new_lines[5]->index()));
4123  }
4124 
4125  types::subdomain_id subdomainid = cell->subdomain_id();
4126 
4127  for (unsigned int i=0; i<n_children; ++i)
4128  {
4129  subcells[i]->set_used_flag();
4130  subcells[i]->clear_refine_flag();
4131  subcells[i]->clear_user_flag();
4132  subcells[i]->clear_user_data();
4133  subcells[i]->clear_children();
4134  // inherit material
4135  // properties
4136  subcells[i]->set_material_id (cell->material_id());
4137  subcells[i]->set_manifold_id (cell->manifold_id());
4138  subcells[i]->set_subdomain_id (subdomainid);
4139 
4140  if (i%2==0)
4141  subcells[i]->set_parent (cell->index ());
4142  }
4143 
4144 
4145 
4146  // set child index for
4147  // even children children
4148  // i=0,2 (0)
4149  for (unsigned int i=0; i<n_children/2; ++i)
4150  cell->set_children (2*i, subcells[2*i]->index());
4151  // set the refine case
4152  cell->set_refinement_case(ref_case);
4153 
4154  // note that the
4155  // refinement flag was
4156  // already cleared at the
4157  // beginning of this function
4158 
4159  if (dim < spacedim)
4160  for (unsigned int c=0; c<n_children; ++c)
4161  cell->child(c)->set_direction_flag (cell->direction_flag());
4162 
4163  }
4164 
4165 
4166 
4171  template <int spacedim>
4172  static
4175  const bool /*check_for_distorted_cells*/)
4176  {
4177  const unsigned int dim = 1;
4178 
4179  // check whether a new level is needed we have to check for
4180  // this on the highest level only (on this, all used cells are
4181  // also active, so we only have to check for this)
4182  {
4184  cell = triangulation.begin_active (triangulation.levels.size()-1),
4185  endc = triangulation.end();
4186  for (; cell != endc; ++cell)
4187  if (cell->used())
4188  if (cell->refine_flag_set())
4189  {
4190  triangulation.levels
4191  .push_back (new internal::Triangulation::TriaLevel<dim>);
4192  break;
4193  }
4194  }
4195 
4196 
4197  // check how much space is needed on every level we need not
4198  // check the highest level since either - on the highest level
4199  // no cells are flagged for refinement - there are, but
4200  // prepare_refinement added another empty level
4201  unsigned int needed_vertices = 0;
4202  for (int level=triangulation.levels.size()-2; level>=0; --level)
4203  {
4204  // count number of flagged
4205  // cells on this level
4206  unsigned int flagged_cells = 0;
4208  acell = triangulation.begin_active(level),
4209  aendc = triangulation.begin_active(level+1);
4210  for (; acell!=aendc; ++acell)
4211  if (acell->refine_flag_set())
4212  ++flagged_cells;
4213 
4214  // count number of used cells
4215  // on the next higher level
4216  const unsigned int used_cells
4217  = std::count_if (triangulation.levels[level+1]->cells.used.begin(),
4218  triangulation.levels[level+1]->cells.used.end(),
4219  std::bind2nd (std::equal_to<bool>(), true));
4220 
4221  // reserve space for the used_cells cells already existing
4222  // on the next higher level as well as for the
4223  // 2*flagged_cells that will be created on that level
4224  triangulation.levels[level+1]
4225  ->reserve_space(used_cells+
4227  flagged_cells,
4228  1,
4229  spacedim);
4230  // reserve space for 2*flagged_cells new lines on the next
4231  // higher level
4232  triangulation.levels[level+1]->cells
4233  .reserve_space (GeometryInfo<1>::max_children_per_cell *
4234  flagged_cells,
4235  0);
4236 
4237  needed_vertices += flagged_cells;
4238  }
4239 
4240  // add to needed vertices how many
4241  // vertices are already in use
4242  needed_vertices += std::count_if (triangulation.vertices_used.begin(),
4243  triangulation.vertices_used.end(),
4244  std::bind2nd (std::equal_to<bool>(),
4245  true));
4246  // if we need more vertices: create them, if not: leave the
4247  // array as is, since shrinking is not really possible because
4248  // some of the vertices at the end may be in use
4249  if (needed_vertices > triangulation.vertices.size())
4250  {
4251  triangulation.vertices.resize (needed_vertices,
4252  Point<spacedim>());
4253  triangulation.vertices_used.resize (needed_vertices, false);
4254  }
4255 
4256 
4257  // Do REFINEMENT on every level; exclude highest level as
4258  // above
4259 
4260  // index of next unused vertex
4261  unsigned int next_unused_vertex = 0;
4262 
4263  for (int level=triangulation.levels.size()-2; level>=0; --level)
4264  {
4266  cell = triangulation.begin_active(level),
4267  endc = triangulation.begin_active(level+1);
4268 
4270  next_unused_cell = triangulation.begin_raw (level+1);
4271 
4272  for (; (cell!=endc) && (cell->level()==level); ++cell)
4273  if (cell->refine_flag_set())
4274  {
4275  // clear refinement flag
4276  cell->clear_refine_flag ();
4277 
4278  // search for next unused
4279  // vertex
4280  while (triangulation.vertices_used[next_unused_vertex] == true)
4281  ++next_unused_vertex;
4282  Assert (next_unused_vertex < triangulation.vertices.size(),
4283  ExcMessage("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."));
4284 
4285  // Now we always ask the cell itself where to put
4286  // the new point. The cell in turn will query the
4287  // manifold object internally.
4288  triangulation.vertices[next_unused_vertex] =
4289  cell->center(true);
4290 
4291  triangulation.vertices_used[next_unused_vertex] = true;
4292 
4293  // search for next two unused cell (++ takes care of
4294  // the end of the vector)
4296  first_child,
4297  second_child;
4298  while (next_unused_cell->used() == true)
4299  ++next_unused_cell;
4300  first_child = next_unused_cell;
4301  first_child->set_used_flag ();
4302  first_child->clear_user_data ();
4303  ++next_unused_cell;
4304  Assert (next_unused_cell->used() == false,
4305  ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4306  second_child = next_unused_cell;
4307  second_child->set_used_flag ();
4308  second_child->clear_user_data ();
4309 
4310  types::subdomain_id subdomainid = cell->subdomain_id();
4311 
4312  // insert first child
4313  cell->set_children (0, first_child->index());
4314  first_child->clear_children ();
4315  first_child->set (internal::Triangulation
4316  ::TriaObject<1> (cell->vertex_index(0),
4317  next_unused_vertex));
4318  first_child->set_material_id (cell->material_id());
4319  first_child->set_manifold_id (cell->manifold_id());
4320  first_child->set_subdomain_id (subdomainid);
4321  first_child->set_direction_flag (cell->direction_flag());
4322 
4323  first_child->set_parent (cell->index ());
4324 
4325  // Set manifold id of the right face. Only do this
4326  // on the first child.
4327  first_child->face(1)->set_manifold_id(cell->manifold_id());
4328 
4329  // reset neighborship info (refer to
4330  // internal::Triangulation::TriaLevel<0> for
4331  // details)
4332  first_child->set_neighbor (1, second_child);
4333  if (cell->neighbor(0).state() != IteratorState::valid)
4334  first_child->set_neighbor (0, cell->neighbor(0));
4335  else if (cell->neighbor(0)->active())
4336  {
4337  // since the neighbors level is always <=level,
4338  // if the cell is active, then there are no
4339  // cells to the left which may want to know
4340  // about this new child cell.
4341  Assert (cell->neighbor (0)->level () <= cell->level (),
4342  ExcInternalError ());
4343  first_child->set_neighbor (0, cell->neighbor(0));
4344  }
4345  else
4346  // left neighbor is refined
4347  {
4348  // set neighbor to cell on same level
4349  const unsigned int nbnb = cell->neighbor_of_neighbor (0);
4350  first_child->set_neighbor (0, cell->neighbor(0)->child(nbnb));
4351 
4352  // reset neighbor info of all right descendant
4353  // of the left neighbor of cell
4355  left_neighbor = cell->neighbor(0);
4356  while (left_neighbor->has_children())
4357  {
4358  left_neighbor = left_neighbor->child(nbnb);
4359  left_neighbor->set_neighbor (nbnb, first_child);
4360  }
4361  }
4362 
4363  // insert second child
4364  second_child->clear_children ();
4365  second_child->set (internal::Triangulation
4366  ::TriaObject<1>(next_unused_vertex,
4367  cell->vertex_index(1)));
4368  second_child->set_neighbor (0, first_child);
4369  second_child->set_material_id (cell->material_id());
4370  second_child->set_manifold_id (cell->manifold_id());
4371  second_child->set_subdomain_id (subdomainid);
4372  second_child->set_direction_flag (cell->direction_flag());
4373 
4374  if (cell->neighbor(1).state() != IteratorState::valid)
4375  second_child->set_neighbor (1, cell->neighbor(1));
4376  else if (cell->neighbor(1)->active())
4377  {
4378  Assert (cell->neighbor (1)->level () <= cell->level (),
4379  ExcInternalError ());
4380  second_child->set_neighbor (1, cell->neighbor(1));
4381  }
4382  else
4383  // right neighbor is refined same as above
4384  {
4385  const unsigned int nbnb = cell->neighbor_of_neighbor (1);
4386  second_child->set_neighbor (1, cell->neighbor(1)->child(nbnb));
4387 
4389  right_neighbor = cell->neighbor(1);
4390  while (right_neighbor->has_children())
4391  {
4392  right_neighbor = right_neighbor->child(nbnb);
4393  right_neighbor->set_neighbor (nbnb, second_child);
4394  }
4395  }
4396  // inform all listeners that cell refinement is done
4397  triangulation.signals.post_refinement_on_cell(cell);
4398  }
4399  }
4400 
4401  // in 1d, we can not have distorted children unless the parent
4402  // was already distorted (that is because we don't use
4403  // boundary information for 1d triangulations). so return an
4404  // empty list
4406  }
4407 
4408 
4413  template <int spacedim>
4414  static
4417  const bool check_for_distorted_cells)
4418  {
4419  const unsigned int dim = 2;
4420 
4421  // check whether a new level is needed we have to check for
4422  // this on the highest level only (on this, all used cells are
4423  // also active, so we only have to check for this)
4424  if (true)
4425  {
4427  cell = triangulation.begin_active (triangulation.levels.size()-1),
4428  endc = triangulation.end();
4429  for (; cell != endc; ++cell)
4430  if (cell->used())
4431  if (cell->refine_flag_set())
4432  {
4433  triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
4434  break;
4435  }
4436  }
4437 
4438 
4439  // first clear user flags and pointers of lines; we're going
4440  // to use them to flag which lines need refinement
4441  for (typename Triangulation<dim,spacedim>::line_iterator
4442  line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
4443  {
4444  line->clear_user_flag();
4445  line->clear_user_data();
4446  }
4447  // running over all cells and lines count the number
4448  // n_single_lines of lines which can be stored as single
4449  // lines, e.g. inner lines
4450  unsigned int n_single_lines=0;
4451 
4452  // New lines to be created: number lines which are stored in
4453  // pairs (the children of lines must be stored in pairs)
4454  unsigned int n_lines_in_pairs = 0;
4455 
4456  // check how much space is needed on every level we need not
4457  // check the highest level since either - on the highest level
4458  // no cells are flagged for refinement - there are, but
4459  // prepare_refinement added another empty level
4460  unsigned int needed_vertices = 0;
4461  for (int level=triangulation.levels.size()-2; level>=0; --level)
4462  {
4463  // count number of flagged cells on this level and compute
4464  // how many new vertices and new lines will be needed
4465  unsigned int needed_cells = 0;
4466 
4468  cell = triangulation.begin_active(level),
4469  endc = triangulation.begin_active(level+1);
4470  for (; cell!=endc; ++cell)
4471  if (cell->refine_flag_set())
4472  {
4473  if (cell->refine_flag_set()==RefinementCase<dim>::cut_xy)
4474  {
4475  needed_cells += 4;
4476 
4477  // new vertex at center of cell is needed in any
4478  // case
4479  ++needed_vertices;
4480 
4481  // the four inner lines can be stored as singles
4482  n_single_lines += 4;
4483  }
4484  else // cut_x || cut_y
4485  {
4486  // set the flag showing that anisotropic
4487  // refinement is used for at least one cell
4488  triangulation.anisotropic_refinement = true;
4489 
4490  needed_cells += 2;
4491  // no vertex at center
4492 
4493  // the inner line can be stored as single
4494  n_single_lines += 1;
4495 
4496  }
4497 
4498  // mark all faces (lines) for refinement; checking
4499  // locally whether the neighbor would also like to
4500  // refine them is rather difficult for lines so we
4501  // only flag them and after visiting all cells, we
4502  // decide which lines need refinement;
4503  for (unsigned int line_no=0; line_no<GeometryInfo<dim>::faces_per_cell;
4504  ++line_no)
4505  {
4507  cell->refine_flag_set(), line_no)==RefinementCase<1>::cut_x)
4508  {
4509  typename Triangulation<dim,spacedim>::line_iterator
4510  line = cell->line(line_no);
4511  if (line->has_children() == false)
4512  {
4513  line->set_user_flag ();
4514 //TODO[WB]: we overwrite the user_index here because we later on need
4515 // to find out which boundary object we have to ask to refine this
4516 // line. we can't use the boundary_id field because that can
4517 // only be used for lines at the boundary of the domain, but we also
4518 // need a domain description for interior lines in the codim-1 case
4519  if (spacedim > dim)
4520  {
4521  if (line->at_boundary())
4522  // if possible honor boundary
4523  // indicator
4524  line->set_user_index(line->boundary_id());
4525  else
4526  // otherwise take manifold
4527  // description from the adjacent
4528  // cell
4529  line->set_user_index(cell->material_id());
4530  }
4531  }
4532  }
4533  }
4534  }
4535 
4536 
4537  // count number of used cells on the next higher level
4538  const unsigned int used_cells
4539  = std::count_if (triangulation.levels[level+1]->cells.used.begin(),
4540  triangulation.levels[level+1]->cells.used.end(),
4541  std::bind2nd (std::equal_to<bool>(), true));
4542 
4543 
4544  // reserve space for the used_cells cells already existing
4545  // on the next higher level as well as for the
4546  // needed_cells that will be created on that level
4547  triangulation.levels[level+1]
4548  ->reserve_space (used_cells+needed_cells, 2, spacedim);
4549 
4550  // reserve space for needed_cells new quads on the next
4551  // higher level
4552  triangulation.levels[level+1]->cells.
4553  reserve_space (needed_cells,0);
4554  }
4555 
4556  // now count the lines which were flagged for refinement
4557  for (typename Triangulation<dim,spacedim>::line_iterator
4558  line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
4559  if (line->user_flag_set())
4560  {
4561  Assert (line->has_children() == false, ExcInternalError());
4562  n_lines_in_pairs += 2;
4563  needed_vertices += 1;
4564  }
4565  // reserve space for n_lines_in_pairs new lines. note, that
4566  // we can't reserve space for the single lines here as well,
4567  // as all the space reserved for lines in pairs would be
4568  // counted as unused and we would end up with too little space
4569  // to store all lines. memory reservation for n_single_lines
4570  // can only be done AFTER we refined the lines of the current
4571  // cells
4572  triangulation.faces->lines.
4573  reserve_space (n_lines_in_pairs, 0);
4574 
4575  // add to needed vertices how many vertices are already in use
4576  needed_vertices += std::count_if (triangulation.vertices_used.begin(), triangulation.vertices_used.end(),
4577  std::bind2nd (std::equal_to<bool>(), true));
4578  // if we need more vertices: create them, if not: leave the
4579  // array as is, since shrinking is not really possible because
4580  // some of the vertices at the end may be in use
4581  if (needed_vertices > triangulation.vertices.size())
4582  {
4583  triangulation.vertices.resize (needed_vertices, Point<spacedim>());
4584  triangulation.vertices_used.resize (needed_vertices, false);
4585  }
4586 
4587 
4588  // Do REFINEMENT on every level; exclude highest level as
4589  // above
4590 
4591  // index of next unused vertex
4592  unsigned int next_unused_vertex = 0;
4593 
4594  // first the refinement of lines. children are stored
4595  // pairwise
4596  if (true)
4597  {
4598  // only active objects can be refined further
4599  typename Triangulation<dim,spacedim>::active_line_iterator
4600  line = triangulation.begin_active_line(),
4601  endl = triangulation.end_line();
4602  typename Triangulation<dim,spacedim>::raw_line_iterator
4603  next_unused_line = triangulation.begin_raw_line ();
4604 
4605  for (; line!=endl; ++line)
4606  if (line->user_flag_set())
4607  {
4608  // this line needs to be refined
4609 
4610  // find the next unused vertex and set it
4611  // appropriately
4612  while (triangulation.vertices_used[next_unused_vertex] == true)
4613  ++next_unused_vertex;
4614  Assert (next_unused_vertex < triangulation.vertices.size(),
4615  ExcMessage("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."));
4616  triangulation.vertices_used[next_unused_vertex] = true;
4617 
4618  if (spacedim == dim)
4619  {
4620  // for the case of a domain in an
4621  // equal-dimensional space we only have to treat
4622  // boundary lines differently; for interior
4623  // lines we can compute the midpoint as the mean
4624  // of the two vertices: if (line->at_boundary())
4625  triangulation.vertices[next_unused_vertex]
4626  = line->center(true);
4627  }
4628  else
4629  // however, if spacedim>dim, we always have to ask
4630  // the boundary object for its answer. We use the
4631  // same object of the cell (which was stored in
4632  // line->user_index() before) unless a manifold_id
4633  // has been set on this very line.
4634  if (line->manifold_id() == numbers::invalid_manifold_id)
4635  triangulation.vertices[next_unused_vertex]
4636  = triangulation.get_manifold(line->user_index()).get_new_point_on_line (line);
4637  else
4638  triangulation.vertices[next_unused_vertex]
4639  = line->center(true);
4640 
4641  // now that we created the right point, make up the
4642  // two child lines. To this end, find a pair of
4643  // unused lines
4644  bool pair_found=false;
4645  (void)pair_found;
4646  for (; next_unused_line!=endl; ++next_unused_line)
4647  if (!next_unused_line->used() &&
4648  !(++next_unused_line)->used())
4649  {
4650  // go back to the first of the two unused
4651  // lines
4652  --next_unused_line;
4653  pair_found=true;
4654  break;
4655  }
4656  Assert (pair_found, ExcInternalError());
4657 
4658  // there are now two consecutive unused lines, such
4659  // that the children of a line will be consecutive.
4660  // then set the child pointer of the present line
4661  line->set_children (0, next_unused_line->index());
4662 
4663  // set the two new lines
4664  const typename Triangulation<dim,spacedim>::raw_line_iterator
4665  children[2] = { next_unused_line,
4666  ++next_unused_line
4667  };
4668  // some tests; if any of the iterators should be
4669  // invalid, then already dereferencing will fail
4670  Assert (children[0]->used() == false, ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4671  Assert (children[1]->used() == false, ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
4672 
4673  children[0]->set (internal::Triangulation
4674  ::TriaObject<1>(line->vertex_index(0),
4675  next_unused_vertex));
4676  children[1]->set (internal::Triangulation
4677  ::TriaObject<1>(next_unused_vertex,
4678  line->vertex_index(1)));
4679 
4680  children[0]->set_used_flag();
4681  children[1]->set_used_flag();
4682  children[0]->clear_children();
4683  children[1]->clear_children();
4684  children[0]->clear_user_data();
4685  children[1]->clear_user_data();
4686  children[0]->clear_user_flag();
4687  children[1]->clear_user_flag();
4688 
4689  children[0]->set_boundary_id (line->boundary_id());
4690  children[1]->set_boundary_id (line->boundary_id());
4691 
4692  children[0]->set_manifold_id (line->manifold_id());
4693  children[1]->set_manifold_id (line->manifold_id());
4694 
4695  // finally clear flag indicating the need for
4696  // refinement
4697  line->clear_user_flag ();
4698  }
4699  }
4700 
4701 
4702  // Now set up the new cells
4703 
4704  // reserve space for inner lines (can be stored as single
4705  // lines)
4706  triangulation.faces->lines.
4707  reserve_space (0,n_single_lines);
4708 
4710  cells_with_distorted_children;
4711 
4712  // reset next_unused_line, as now also single empty places in
4713  // the vector can be used
4714  typename Triangulation<dim,spacedim>::raw_line_iterator
4715  next_unused_line = triangulation.begin_raw_line ();
4716 
4717  for (int level=0; level<static_cast<int>(triangulation.levels.size())-1; ++level)
4718  {
4719 
4720  // Remember: as we don't operate on the finest level,
4721  // begin_*(level+1) is allowed
4723  cell = triangulation.begin_active(level),
4724  endc = triangulation.begin_active(level+1);
4725 
4727  next_unused_cell = triangulation.begin_raw (level+1);
4728 
4729  for (; cell!=endc; ++cell)
4730  if (cell->refine_flag_set())
4731  {
4732  // set the user flag to indicate, that at least one
4733  // line is at the boundary
4734 
4735  // TODO[Tobias Leicht] find a better place to set
4736  // this flag, so that we do not need so much time to
4737  // check each cell here
4738  if (cell->at_boundary())
4739  cell->set_user_flag();
4740 
4741  // actually set up the children and update neighbor
4742  // information
4743  create_children (triangulation,
4744  next_unused_vertex,
4745  next_unused_line,
4746  next_unused_cell,
4747  cell);
4748 
4749  if ((check_for_distorted_cells == true)
4750  &&
4751  has_distorted_children (cell,
4754  cells_with_distorted_children.distorted_cells.push_back (cell);
4755  // inform all listeners that cell refinement is done
4756  triangulation.signals.post_refinement_on_cell(cell);
4757  }
4758  }
4759 
4760  return cells_with_distorted_children;
4761  }
4762 
4763 
4768  template <int spacedim>
4769  static
4772  const bool check_for_distorted_cells)
4773  {
4774  const unsigned int dim = 3;
4775 
4776  // this function probably also works for spacedim>3 but it
4777  // isn't tested. it will probably be necessary to pull new
4778  // vertices onto the manifold just as we do for the other
4779  // functions above.
4780  Assert (spacedim == 3, ExcNotImplemented());
4781 
4782  // check whether a new level is needed we have to check for
4783  // this on the highest level only (on this, all used cells are
4784  // also active, so we only have to check for this)
4785  if (true)
4786  {
4788  cell = triangulation.begin_active (triangulation.levels.size()-1),
4789  endc = triangulation.end();
4790  for (; cell != endc; ++cell)
4791  if (cell->used())
4792  if (cell->refine_flag_set())
4793  {
4794  triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
4795  break;
4796  }
4797  }
4798 
4799 
4800  // first clear user flags for quads and lines; we're going to
4801  // use them to flag which lines and quads need refinement
4802  triangulation.faces->quads.clear_user_data();
4803 
4804  for (typename Triangulation<dim,spacedim>::line_iterator
4805  line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
4806  line->clear_user_flag();
4807  for (typename Triangulation<dim,spacedim>::quad_iterator
4808  quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
4809  quad->clear_user_flag();
4810 
4811  // create an array of face refine cases. User indices of faces
4812  // will be set to values corresponding with indices in this
4813  // array.
4814  const RefinementCase<dim-1> face_refinement_cases[4]=
4815  {
4816  RefinementCase<dim-1>::no_refinement,
4817  RefinementCase<dim-1>::cut_x,
4818  RefinementCase<dim-1>::cut_y,
4819  RefinementCase<dim-1>::cut_xy
4820  };
4821 
4822  // check how much space is needed on every level we need not
4823  // check the highest level since either
4824  // - on the highest level no cells are flagged for refinement
4825  // - there are, but prepare_refinement added another empty
4826  // level which then is the highest level
4827 
4828  // variables to hold the number of newly to be created
4829  // vertices, lines and quads. as these are stored globally,
4830  // declare them outside the loop over al levels. we need lines
4831  // and quads in pairs for refinement of old ones and lines and
4832  // quads, that can be stored as single ones, as they are newly
4833  // created in the inside of an existing cell
4834  unsigned int needed_vertices = 0;
4835  unsigned int needed_lines_single = 0;
4836  unsigned int needed_quads_single = 0;
4837  unsigned int needed_lines_pair = 0;
4838  unsigned int needed_quads_pair = 0;
4839  for (int level=triangulation.levels.size()-2; level>=0; --level)
4840  {
4841  // count number of flagged cells on this level and compute
4842  // how many new vertices and new lines will be needed
4843  unsigned int new_cells = 0;
4844 
4846  acell = triangulation.begin_active(level),
4847  aendc = triangulation.begin_active(level+1);
4848  for (; acell!=aendc; ++acell)
4849  if (acell->refine_flag_set())
4850  {
4851  RefinementCase<dim> ref_case=acell->refine_flag_set();
4852 
4853  // now for interior vertices, lines and quads, which
4854  // are needed in any case
4855  if (ref_case==RefinementCase<dim>::cut_x ||
4856  ref_case==RefinementCase<dim>::cut_y ||
4857  ref_case==RefinementCase<dim>::cut_z)
4858  {
4859  ++needed_quads_single;
4860  new_cells+=2;
4861  triangulation.anisotropic_refinement=true;
4862  }
4863  else if (ref_case==RefinementCase<dim>::cut_xy ||
4864  ref_case==RefinementCase<dim>::cut_xz ||
4865  ref_case==RefinementCase<dim>::cut_yz)
4866  {
4867  ++needed_lines_single;
4868  needed_quads_single += 4;
4869  new_cells+=4;
4870  triangulation.anisotropic_refinement=true;
4871  }
4872  else if (ref_case==RefinementCase<dim>::cut_xyz)
4873  {
4874  ++needed_vertices;
4875  needed_lines_single += 6;
4876  needed_quads_single += 12;
4877  new_cells+=8;
4878  }
4879  else
4880  {
4881  // we should never get here
4882  Assert(false, ExcInternalError());
4883  }
4884 
4885  // mark all faces for refinement; checking locally
4886  // if and how the neighbor would like to refine
4887  // these is difficult so we only flag them and after
4888  // visiting all cells, we decide which faces need
4889  // which refinement;
4890  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell;
4891  ++face)
4892  {
4894  aface = acell->face(face);
4895  // get the RefineCase this faces has for the
4896  // given RefineCase of the cell
4897  RefinementCase<dim-1> face_ref_case=
4899  face,
4900  acell->face_orientation(face),
4901  acell->face_flip(face),
4902  acell->face_rotation(face));
4903  // only do something, if this face has to be
4904  // refined
4905  if (face_ref_case)
4906  {
4908  {
4909  if (aface->number_of_children()<4)
4910  // we use user_flags to denote needed
4911  // isotropic refinement
4912  aface->set_user_flag();
4913  }
4914  else if (aface->refinement_case()!=face_ref_case)
4915  // we use user_indices to denote needed
4916  // anisotropic refinement. note, that we
4917  // can have at most one anisotropic
4918  // refinement case for this face, as
4919  // otherwise prepare_refinement() would
4920  // have changed one of the cells to yield
4921  // isotropic refinement at this
4922  // face. therefore we set the user_index
4923  // uniquely
4924  {
4925  Assert(aface->refinement_case()==RefinementCase<dim-1>::isotropic_refinement ||
4926  aface->refinement_case()==RefinementCase<dim-1>::no_refinement,
4927  ExcInternalError());
4928  aface->set_user_index(face_ref_case);
4929  }
4930  }
4931  }// for all faces
4932 
4933  // flag all lines, that have to be refined
4934  for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
4935  if (GeometryInfo<dim>::line_refinement_case(ref_case,line) &&
4936  !acell->line(line)->has_children())
4937  acell->line(line)->set_user_flag();
4938 
4939  }// if refine_flag set and for all cells on this level
4940 
4941 
4942  // count number of used cells on the next higher level
4943  const unsigned int used_cells
4944  = std::count_if (triangulation.levels[level+1]->cells.used.begin(),
4945  triangulation.levels[level+1]->cells.used.end(),
4946  std::bind2nd (std::equal_to<bool>(), true));
4947 
4948 
4949  // reserve space for the used_cells cells already existing
4950  // on the next higher level as well as for the
4951  // 8*flagged_cells that will be created on that level
4952  triangulation.levels[level+1]
4953  ->reserve_space (used_cells+new_cells, 3, spacedim);
4954  // reserve space for 8*flagged_cells new hexes on the next
4955  // higher level
4956  triangulation.levels[level+1]->cells.reserve_space (new_cells);
4957  }// for all levels
4958  // now count the quads and lines which were flagged for
4959  // refinement
4960  for (typename Triangulation<dim,spacedim>::quad_iterator
4961  quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
4962  {
4963  if (quad->user_flag_set())
4964  {
4965  // isotropic refinement: 1 interior vertex, 4 quads
4966  // and 4 interior lines. we store the interior lines
4967  // in pairs in case the face is already or will be
4968  // refined anisotropically
4969  needed_quads_pair += 4;
4970  needed_lines_pair += 4;
4971  needed_vertices += 1;
4972  }
4973  if (quad->user_index())
4974  {
4975  // anisotropic refinement: 1 interior
4976  // line and two quads
4977  needed_quads_pair += 2;
4978  needed_lines_single += 1;
4979  // there is a kind of complicated situation here which
4980  // requires our attention. if the quad is refined
4981  // isotropcally, two of the interior lines will get a
4982  // new mother line - the interior line of our
4983  // anisotropically refined quad. if those two lines
4984  // are not consecutive, we cannot do so and have to
4985  // replace them by two lines that are consecutive. we
4986  // try to avoid that situation, but it may happen
4987  // nevertheless throug repeated refinement and
4988  // coarsening. thus we have to check here, as we will
4989  // need some additional space to store those new lines
4990  // in case we need them...
4991  if (quad->has_children())
4992  {
4993  Assert(quad->refinement_case()==RefinementCase<dim-1>::isotropic_refinement, ExcInternalError());
4994  if ((face_refinement_cases[quad->user_index()]==RefinementCase<dim-1>::cut_x
4995  && (quad->child(0)->line_index(1)+1!=quad->child(2)->line_index(1))) ||
4996  (face_refinement_cases[quad->user_index()]==RefinementCase<dim-1>::cut_y
4997  && (quad->child(0)->line_index(3)+1!=quad->child(1)->line_index(3))))
4998  needed_lines_pair +=2;
4999  }
5000  }
5001  }
5002 
5003  for (typename Triangulation<dim,spacedim>::line_iterator
5004  line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
5005  if (line->user_flag_set())
5006  {
5007  needed_lines_pair += 2;
5008  needed_vertices += 1;
5009  }
5010 
5011  // reserve space for needed_lines new lines stored in pairs
5012  triangulation.faces->lines.
5013  reserve_space (needed_lines_pair,needed_lines_single);
5014  // reserve space for needed_quads new quads stored in pairs
5015  triangulation.faces->quads.
5016  reserve_space (needed_quads_pair,needed_quads_single);
5017 
5018 
5019  // add to needed vertices how many vertices are already in use
5020  needed_vertices += std::count_if (triangulation.vertices_used.begin(), triangulation.vertices_used.end(),
5021  std::bind2nd (std::equal_to<bool>(), true));
5022  // if we need more vertices: create them, if not: leave the
5023  // array as is, since shrinking is not really possible because
5024  // some of the vertices at the end may be in use
5025  if (needed_vertices > triangulation.vertices.size())
5026  {
5027  triangulation.vertices.resize (needed_vertices, Point<spacedim>());
5028  triangulation.vertices_used.resize (needed_vertices, false);
5029  }
5030 
5031 
5033  // Before we start with the actual refinement, we do some
5034  // sanity checks if in debug mode. especially, we try to catch
5035  // the notorious problem with lines being twice refined,
5036  // i.e. there are cells adjacent at one line ("around the
5037  // edge", but not at a face), with two cells differing by more
5038  // than one refinement level
5039  //
5040  // this check is very simple to implement here, since we have
5041  // all lines flagged if they shall be refined
5042 #ifdef DEBUG
5044  cell=triangulation.begin_active(); cell!=triangulation.end(); ++cell)
5045  if (!cell->refine_flag_set())
5046  for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
5047  if (cell->line(line)->has_children())
5048  for (unsigned int c=0; c<2; ++c)
5049  Assert (cell->line(line)->child(c)->user_flag_set() == false,
5050  ExcInternalError());
5051 #endif
5052 
5054  // Do refinement on every level
5055  //
5056  // To make life a bit easier, we first refine those lines and
5057  // quads that were flagged for refinement and then compose the
5058  // newly to be created cells.
5059  //
5060  // index of next unused vertex
5061  unsigned int next_unused_vertex = 0;
5062 
5063  // first for lines
5064  if (true)
5065  {
5066  // only active objects can be refined further
5067  typename Triangulation<dim,spacedim>::active_line_iterator
5068  line = triangulation.begin_active_line(),
5069  endl = triangulation.end_line();
5070  typename Triangulation<dim,spacedim>::raw_line_iterator
5071  next_unused_line = triangulation.begin_raw_line ();
5072 
5073  for (; line!=endl; ++line)
5074  if (line->user_flag_set())
5075  {
5076  // this line needs to be refined
5077 
5078  // find the next unused vertex and set it
5079  // appropriately
5080  while (triangulation.vertices_used[next_unused_vertex] == true)
5081  ++next_unused_vertex;
5082  Assert (next_unused_vertex < triangulation.vertices.size(),
5083  ExcMessage("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."));
5084  triangulation.vertices_used[next_unused_vertex] = true;
5085 
5086  triangulation.vertices[next_unused_vertex]
5087  = line->center(true);
5088 
5089  // now that we created the right point, make up the
5090  // two child lines (++ takes care of the end of the
5091  // vector)
5092  next_unused_line=triangulation.faces->lines.next_free_pair_object(triangulation);
5093  Assert(next_unused_line.state() == IteratorState::valid,
5094  ExcInternalError());
5095 
5096  // now we found two consecutive unused lines, such
5097  // that the children of a line will be consecutive.
5098  // then set the child pointer of the present line
5099  line->set_children (0, next_unused_line->index());
5100 
5101  // set the two new lines
5102  const typename Triangulation<dim,spacedim>::raw_line_iterator
5103  children[2] = { next_unused_line,
5104  ++next_unused_line
5105  };
5106 
5107  // some tests; if any of the iterators should be
5108  // invalid, then already dereferencing will fail
5109  Assert (children[0]->used() == false, ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5110  Assert (children[1]->used() == false, ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5111 
5112  children[0]->set (internal::Triangulation
5113  ::TriaObject<1>(line->vertex_index(0),
5114  next_unused_vertex));
5115  children[1]->set (internal::Triangulation
5116  ::TriaObject<1>(next_unused_vertex,
5117  line->vertex_index(1)));
5118 
5119  children[0]->set_used_flag();
5120  children[1]->set_used_flag();
5121  children[0]->clear_children();
5122  children[1]->clear_children();
5123  children[0]->clear_user_data();
5124  children[1]->clear_user_data();
5125  children[0]->clear_user_flag();
5126  children[1]->clear_user_flag();
5127 
5128  children[0]->set_boundary_id (line->boundary_id());
5129  children[1]->set_boundary_id (line->boundary_id());
5130 
5131  children[0]->set_manifold_id (line->manifold_id());
5132  children[1]->set_manifold_id (line->manifold_id());
5133 
5134  // finally clear flag
5135  // indicating the need
5136  // for refinement
5137  line->clear_user_flag ();
5138  }
5139  }
5140 
5141 
5143  // now refine marked quads
5145 
5146  // here we encounter several cases:
5147 
5148  // a) the quad is unrefined and shall be refined isotropically
5149 
5150  // b) the quad is unrefined and shall be refined
5151  // anisotropically
5152 
5153  // c) the quad is unrefined and shall be refined both
5154  // anisotropically and isotropically (this is reduced to case
5155  // b) and then case b) for the children again)
5156 
5157  // d) the quad is refined anisotropically and shall be refined
5158  // isotropically (this is reduced to case b) for the
5159  // anisotropic children)
5160 
5161  // e) the quad is refined isotropically and shall be refined
5162  // anisotropically (this is transformed to case c), however we
5163  // might have to renumber/rename children...)
5164 
5165  // we need a loop in cases c) and d), as the anisotropic
5166  // children migt have a lower index than the mother quad
5167  for (unsigned int loop=0; loop<2; ++loop)
5168  {
5169  // usually, only active objects can be refined
5170  // further. however, in cases d) and e) that is not true,
5171  // so we have to use 'normal' iterators here
5172  typename Triangulation<dim,spacedim>::quad_iterator
5173  quad = triangulation.begin_quad(),
5174  endq = triangulation.end_quad();
5175  typename Triangulation<dim,spacedim>::raw_line_iterator
5176  next_unused_line = triangulation.begin_raw_line ();
5177  typename Triangulation<dim,spacedim>::raw_quad_iterator
5178  next_unused_quad = triangulation.begin_raw_quad ();
5179 
5180  for (; quad!=endq; ++quad)
5181  {
5182  if (quad->user_index())
5183  {
5184  RefinementCase<dim-1> aniso_quad_ref_case=face_refinement_cases[quad->user_index()];
5185  // there is one unlikely event here, where we
5186  // already have refind the face: if the face was
5187  // refined anisotropically and we want to refine
5188  // it isotropically, both children are flagged for
5189  // anisotropic refinement. however, if those
5190  // children were already flagged for anisotropic
5191  // refinement, they might already be processed and
5192  // refined.
5193  if (aniso_quad_ref_case == quad->refinement_case())
5194  continue;
5195 
5196  Assert(quad->refinement_case()==RefinementCase<dim-1>::cut_xy ||
5197  quad->refinement_case()==RefinementCase<dim-1>::no_refinement,
5198  ExcInternalError());
5199 
5200  // this quad needs to be refined anisotropically
5201  Assert(quad->user_index() == RefinementCase<dim-1>::cut_x ||
5202  quad->user_index() == RefinementCase<dim-1>::cut_y,
5203  ExcInternalError());
5204 
5205  // make the new line interior to the quad
5206  typename Triangulation<dim,spacedim>::raw_line_iterator new_line;
5207 
5208  new_line=triangulation.faces->lines.next_free_single_object(triangulation);
5209  Assert (new_line->used() == false,
5210  ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5211 
5212  // first collect the
5213  // indices of the vertices:
5214  // *--1--*
5215  // | | |
5216  // | | | cut_x
5217  // | | |
5218  // *--0--*
5219  //
5220  // *-----*
5221  // | |
5222  // 0-----1 cut_y
5223  // | |
5224  // *-----*
5225  unsigned int vertex_indices[2];
5226  if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
5227  {
5228  vertex_indices[0]=quad->line(2)->child(0)->vertex_index(1);
5229  vertex_indices[1]=quad->line(3)->child(0)->vertex_index(1);
5230  }
5231  else
5232  {
5233  vertex_indices[0]=quad->line(0)->child(0)->vertex_index(1);
5234  vertex_indices[1]=quad->line(1)->child(0)->vertex_index(1);
5235  }
5236 
5237  new_line->set (internal::Triangulation::
5238  TriaObject<1>(vertex_indices[0], vertex_indices[1]));
5239  new_line->set_used_flag();
5240  new_line->clear_user_flag();
5241  new_line->clear_user_data();
5242  new_line->clear_children();
5243  new_line->set_boundary_id(quad->boundary_id());
5244  new_line->set_manifold_id(quad->manifold_id());
5245 
5246  // child 0 and 1 of a line are switched if the
5247  // line orientation is false. set up a miniature
5248  // table, indicating which child to take for line
5249  // orientations false and true. first index: child
5250  // index in standard orientation, second index:
5251  // line orientation
5252  const unsigned int index[2][2]=
5253  {
5254  {1,0}, // child 0, line_orientation=false and true
5255  {0,1}
5256  }; // child 1, line_orientation=false and true
5257 
5258  // find some space (consecutive) for the two newly
5259  // to be created quads.
5260  typename Triangulation<dim,spacedim>::raw_quad_iterator new_quads[2];
5261 
5262  next_unused_quad=triangulation.faces->quads.next_free_pair_object(triangulation);
5263  new_quads[0] = next_unused_quad;
5264  Assert (new_quads[0]->used() == false, ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5265 
5266  ++next_unused_quad;
5267  new_quads[1] = next_unused_quad;
5268  Assert (new_quads[1]->used() == false, ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5269 
5270 
5271  if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
5272  {
5273  new_quads[0]->set (internal::Triangulation
5274  ::TriaObject<2>(quad->line_index(0),
5275  new_line->index(),
5276  quad->line(2)->child(index[0][quad->line_orientation(2)])->index(),
5277  quad->line(3)->child(index[0][quad->line_orientation(3)])->index()));
5278  new_quads[1]->set (internal::Triangulation
5279  ::TriaObject<2>(new_line->index(),
5280  quad->line_index(1),
5281  quad->line(2)->child(index[1][quad->line_orientation(2)])->index(),
5282  quad->line(3)->child(index[1][quad->line_orientation(3)])->index()));
5283  }
5284  else
5285  {
5286  new_quads[0]->set (internal::Triangulation
5287  ::TriaObject<2>(quad->line(0)->child(index[0][quad->line_orientation(0)])->index(),
5288  quad->line(1)->child(index[0][quad->line_orientation(1)])->index(),
5289  quad->line_index(2),
5290  new_line->index()));
5291  new_quads[1]->set (internal::Triangulation
5292  ::TriaObject<2>(quad->line(0)->child(index[1][quad->line_orientation(0)])->index(),
5293  quad->line(1)->child(index[1][quad->line_orientation(1)])->index(),
5294  new_line->index(),
5295  quad->line_index(3)));
5296  }
5297 
5298  for (unsigned int i=0; i<2; ++i)
5299  {
5300  new_quads[i]->set_used_flag();
5301  new_quads[i]->clear_user_flag();
5302  new_quads[i]->clear_user_data();
5303  new_quads[i]->clear_children();
5304  new_quads[i]->set_boundary_id (quad->boundary_id());
5305  new_quads[i]->set_manifold_id (quad->manifold_id());
5306  // set all line orientations to true, change
5307  // this after the loop, as we have to consider
5308  // different lines for each child
5309  for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
5310  new_quads[i]->set_line_orientation(j,true);
5311  }
5312  // now set the line orientation of children of
5313  // outer lines correctly, the lines in the
5314  // interior of the refined quad are automatically
5315  // oriented conforming to the standard
5316  new_quads[0]->set_line_orientation(0,quad->line_orientation(0));
5317  new_quads[0]->set_line_orientation(2,quad->line_orientation(2));
5318  new_quads[1]->set_line_orientation(1,quad->line_orientation(1));
5319  new_quads[1]->set_line_orientation(3,quad->line_orientation(3));
5320  if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
5321  {
5322  new_quads[0]->set_line_orientation(3,quad->line_orientation(3));
5323  new_quads[1]->set_line_orientation(2,quad->line_orientation(2));
5324  }
5325  else
5326  {
5327  new_quads[0]->set_line_orientation(1,quad->line_orientation(1));
5328  new_quads[1]->set_line_orientation(0,quad->line_orientation(0));
5329  }
5330 
5331  // test, whether this face is refined
5332  // isotropically already. if so, set the correct
5333  // children pointers.
5334  if (quad->refinement_case()==RefinementCase<dim-1>::cut_xy)
5335  {
5336  // we will put a new refinemnt level of
5337  // anisotropic refinement between the
5338  // unrefined and isotropically refined quad
5339  // ending up with the same fine quads but
5340  // introducing anisotropically refined ones as
5341  // children of the unrefined quad and mother
5342  // cells of the original fine ones.
5343 
5344  // this process includes the creation of a new
5345  // middle line which we will assign as the
5346  // mother line of two of the existing inner
5347  // lines. If those inner lines are not
5348  // consecutive in memory, we won't find them
5349  // later on, so we have to create new ones
5350  // instead and replace all occurrences of the
5351  // old ones with those new ones. As this is
5352  // kind of ugly, we hope we don't have to do
5353  // it often...
5354  typename Triangulation<dim,spacedim>::line_iterator old_child[2];
5355  if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
5356  {
5357  old_child[0]=quad->child(0)->line(1);
5358  old_child[1]=quad->child(2)->line(1);
5359  }
5360  else
5361  {
5362  Assert(aniso_quad_ref_case==RefinementCase<dim-1>::cut_y, ExcInternalError());
5363 
5364  old_child[0]=quad->child(0)->line(3);
5365  old_child[1]=quad->child(1)->line(3);
5366  }
5367 
5368  if (old_child[0]->index()+1 != old_child[1]->index())
5369  {
5370  // this is exactly the ugly case we taked
5371  // about. so, no coimplaining, lets get
5372  // two new lines and copy all info
5373  typename Triangulation<dim,spacedim>::raw_line_iterator new_child[2];
5374 
5375  new_child[0]=new_child[1]=triangulation.faces->lines.next_free_pair_object(triangulation);
5376  ++new_child[1];
5377 
5378  new_child[0]->set_used_flag();
5379  new_child[1]->set_used_flag();
5380 
5381  const int old_index_0=old_child[0]->index(),
5382  old_index_1=old_child[1]->index(),
5383  new_index_0=new_child[0]->index(),
5384  new_index_1=new_child[1]->index();
5385 
5386  // loop over all quads and replace the old
5387  // lines
5388  for (unsigned int q=0; q<triangulation.faces->quads.cells.size(); ++q)
5389  for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
5390  {
5391  const int this_index=triangulation.faces->quads.cells[q].face(l);
5392  if (this_index==old_index_0)
5393  triangulation.faces->quads.cells[q].set_face(l,new_index_0);
5394  else if (this_index==old_index_1)
5395  triangulation.faces->quads.cells[q].set_face(l,new_index_1);
5396  }
5397  // now we have to copy all information of
5398  // the two lines
5399  for (unsigned int i=0; i<2; ++i)
5400  {
5401  Assert(!old_child[i]->has_children(), ExcInternalError());
5402 
5403  new_child[i]->set(internal::Triangulation::TriaObject<1>(old_child[i]->vertex_index(0),
5404  old_child[i]->vertex_index(1)));
5405  new_child[i]->set_boundary_id(old_child[i]->boundary_id());
5406  new_child[i]->set_manifold_id(old_child[i]->manifold_id());
5407  new_child[i]->set_user_index(old_child[i]->user_index());
5408  if (old_child[i]->user_flag_set())
5409  new_child[i]->set_user_flag();
5410  else
5411  new_child[i]->clear_user_flag();
5412 
5413  new_child[i]->clear_children();
5414 
5415  old_child[i]->clear_user_flag();
5416  old_child[i]->clear_user_index();
5417  old_child[i]->clear_used_flag();
5418  }
5419  }
5420  // now that we cared about the lines, go on
5421  // with the quads themselves, where we might
5422  // encounter similar situations...
5423  if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
5424  {
5425  new_line->set_children(0, quad->child(0)->line_index(1));
5426  Assert(new_line->child(1)==quad->child(2)->line(1),
5427  ExcInternalError());
5428  // now evereything is quite
5429  // complicated. we have the children
5430  // numbered according to
5431  //
5432  // *---*---*
5433  // |n+2|n+3|
5434  // *---*---*
5435  // | n |n+1|
5436  // *---*---*
5437  //
5438  // from the original isotropic
5439  // refinement. we have to reorder them as
5440  //
5441  // *---*---*
5442  // |n+1|n+3|
5443  // *---*---*
5444  // | n |n+2|
5445  // *---*---*
5446  //
5447  // such that n and n+1 are consecutive
5448  // children of m and n+2 and n+3 are
5449  // consecutive children of m+1, where m
5450  // and m+1 are given as in
5451  //
5452  // *---*---*
5453  // | | |
5454  // | m |m+1|
5455  // | | |
5456  // *---*---*
5457  //
5458  // this is a bit ugly, of course: loop
5459  // over all cells on all levels and look
5460  // for faces n+1 (switch_1) and n+2
5461  // (switch_2).
5462  const typename Triangulation<dim,spacedim>::quad_iterator
5463  switch_1=quad->child(1),
5464  switch_2=quad->child(2);
5465  const int switch_1_index=switch_1->index();
5466  const int switch_2_index=switch_2->index();
5467  for (unsigned int l=0; l<triangulation.levels.size(); ++l)
5468  for (unsigned int h=0; h<triangulation.levels[l]->cells.cells.size(); ++h)
5469  for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
5470  {
5471  const int face_index=triangulation.levels[l]->cells.cells[h].face(q);
5472  if (face_index==switch_1_index)
5473  triangulation.levels[l]->cells.cells[h].set_face(q,switch_2_index);
5474  else if (face_index==switch_2_index)
5475  triangulation.levels[l]->cells.cells[h].set_face(q,switch_1_index);
5476  }
5477  // now we have to copy all information of
5478  // the two quads
5479  const unsigned int switch_1_lines[4]=
5480  {
5481  switch_1->line_index(0),
5482  switch_1->line_index(1),
5483  switch_1->line_index(2),
5484  switch_1->line_index(3)
5485  };
5486  const bool switch_1_line_orientations[4]=
5487  {
5488  switch_1->line_orientation(0),
5489  switch_1->line_orientation(1),
5490  switch_1->line_orientation(2),
5491  switch_1->line_orientation(3)
5492  };
5493  const types::boundary_id switch_1_boundary_id=switch_1->boundary_id();
5494  const unsigned int switch_1_user_index=switch_1->user_index();
5495  const bool switch_1_user_flag=switch_1->user_flag_set();
5496  const RefinementCase<dim-1> switch_1_refinement_case=switch_1->refinement_case();
5497  const int switch_1_first_child_pair=(switch_1_refinement_case ? switch_1->child_index(0) : -1);
5498  const int switch_1_second_child_pair=(switch_1_refinement_case==RefinementCase<dim-1>::cut_xy ? switch_1->child_index(2) : -1);
5499 
5500  switch_1->set(internal::Triangulation::TriaObject<2>(switch_2->line_index(0),
5501  switch_2->line_index(1),
5502  switch_2->line_index(2),
5503  switch_2->line_index(3)));
5504  switch_1->set_line_orientation(0, switch_2->line_orientation(0));
5505  switch_1->set_line_orientation(1, switch_2->line_orientation(1));
5506  switch_1->set_line_orientation(2, switch_2->line_orientation(2));
5507  switch_1->set_line_orientation(3, switch_2->line_orientation(3));
5508  switch_1->set_boundary_id(switch_2->boundary_id());
5509  switch_1->set_manifold_id(switch_2->manifold_id());
5510  switch_1->set_user_index(switch_2->user_index());
5511  if (switch_2->user_flag_set())
5512  switch_1->set_user_flag();
5513  else
5514  switch_1->clear_user_flag();
5515  switch_1->clear_refinement_case();
5516  switch_1->set_refinement_case(switch_2->refinement_case());
5517  switch_1->clear_children();
5518  if (switch_2->refinement_case())
5519  switch_1->set_children(0, switch_2->child_index(0));
5520  if (switch_2->refinement_case()==RefinementCase<dim-1>::cut_xy)
5521  switch_1->set_children(2, switch_2->child_index(2));
5522 
5523  switch_2->set(internal::Triangulation::TriaObject<2>(switch_1_lines[0],
5524  switch_1_lines[1],
5525  switch_1_lines[2],
5526  switch_1_lines[3]));
5527  switch_2->set_line_orientation(0, switch_1_line_orientations[0]);
5528  switch_2->set_line_orientation(1, switch_1_line_orientations[1]);
5529  switch_2->set_line_orientation(2, switch_1_line_orientations[2]);
5530  switch_2->set_line_orientation(3, switch_1_line_orientations[3]);
5531  switch_2->set_boundary_id(switch_1_boundary_id);
5532  switch_2->set_manifold_id(switch_1->manifold_id());
5533  switch_2->set_user_index(switch_1_user_index);
5534  if (switch_1_user_flag)
5535  switch_2->set_user_flag();
5536  else
5537  switch_2->clear_user_flag();
5538  switch_2->clear_refinement_case();
5539  switch_2->set_refinement_case(switch_1_refinement_case);
5540  switch_2->clear_children();
5541  switch_2->set_children(0, switch_1_first_child_pair);
5542  switch_2->set_children(2, switch_1_second_child_pair);
5543 
5544  new_quads[0]->set_refinement_case(RefinementCase<2>::cut_y);
5545  new_quads[0]->set_children(0, quad->child_index(0));
5546  new_quads[1]->set_refinement_case(RefinementCase<2>::cut_y);
5547  new_quads[1]->set_children(0, quad->child_index(2));
5548  }
5549  else
5550  {
5551  new_quads[0]->set_refinement_case(RefinementCase<2>::cut_x);
5552  new_quads[0]->set_children(0, quad->child_index(0));
5553  new_quads[1]->set_refinement_case(RefinementCase<2>::cut_x);
5554  new_quads[1]->set_children(0, quad->child_index(2));
5555  new_line->set_children(0, quad->child(0)->line_index(3));
5556  Assert(new_line->child(1)==quad->child(1)->line(3),
5557  ExcInternalError());
5558  }
5559  quad->clear_children();
5560  }
5561 
5562  // note these quads as children to the present one
5563  quad->set_children (0, new_quads[0]->index());
5564 
5565  quad->set_refinement_case(aniso_quad_ref_case);
5566 
5567  // finally clear flag indicating the need for
5568  // refinement
5569  quad->clear_user_data ();
5570  } // if (anisotropic refinement)
5571 
5572  if (quad->user_flag_set())
5573  {
5574  // this quad needs to be refined isotropically
5575 
5576  // first of all: we only get here in the first run
5577  // of the loop
5578  Assert(loop==0,ExcInternalError());
5579 
5580  // find the next unused vertex. we'll need this in
5581  // any case
5582  while (triangulation.vertices_used[next_unused_vertex] == true)
5583  ++next_unused_vertex;
5584  Assert (next_unused_vertex < triangulation.vertices.size(),
5585  ExcMessage("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."));
5586 
5587  // now: if the quad is refined anisotropically
5588  // already, set the anisotropic refinement flag
5589  // for both children. Additionally, we have to
5590  // refine the inner line, as it is an outer line
5591  // of the two (anisotropic) children
5592  const RefinementCase<dim-1> quad_ref_case=quad->refinement_case();
5593 
5594  if (quad_ref_case==RefinementCase<dim-1>::cut_x ||
5595  quad_ref_case==RefinementCase<dim-1>::cut_y)
5596  {
5597  // set the 'opposite' refine case for children
5598  quad->child(0)->set_user_index(RefinementCase<dim-1>::cut_xy-quad_ref_case);
5599  quad->child(1)->set_user_index(RefinementCase<dim-1>::cut_xy-quad_ref_case);
5600  // refine the inner line
5601  typename Triangulation<dim,spacedim>::line_iterator middle_line;
5602  if (quad_ref_case==RefinementCase<dim-1>::cut_x)
5603  middle_line=quad->child(0)->line(1);
5604  else
5605  middle_line=quad->child(0)->line(3);
5606 
5607  // if the face has been refined
5608  // anisotropically in the last refinement step
5609  // it might be, that it is flagged already and
5610  // that the middle line is thus refined
5611  // already. if not create children.
5612  if (!middle_line->has_children())
5613  {
5614  // set the middle vertex
5615  // appropriately. double refinement of
5616  // quads can only happen in the interior
5617  // of the domain, so we need not care
5618  // about boundary quads here
5619  triangulation.vertices[next_unused_vertex]
5620  = middle_line->center(true);
5621  triangulation.vertices_used[next_unused_vertex] = true;
5622 
5623  // now search a slot for the two
5624  // child lines
5625  next_unused_line=triangulation.faces->lines.next_free_pair_object(triangulation);
5626 
5627  // set the child pointer of the present
5628  // line
5629  middle_line->set_children (0, next_unused_line->index());
5630 
5631  // set the two new lines
5632  const typename Triangulation<dim,spacedim>::raw_line_iterator
5633  children[2] = { next_unused_line,
5634  ++next_unused_line
5635  };
5636 
5637  // some tests; if any of the iterators
5638  // should be invalid, then already
5639  // dereferencing will fail
5640  Assert (children[0]->used() == false, ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5641  Assert (children[1]->used() == false, ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5642 
5643  children[0]->set (internal::Triangulation::
5644  TriaObject<1>(middle_line->vertex_index(0),
5645  next_unused_vertex));
5646  children[1]->set (internal::Triangulation::
5647  TriaObject<1>(next_unused_vertex,
5648  middle_line->vertex_index(1)));
5649 
5650  children[0]->set_used_flag();
5651  children[1]->set_used_flag();
5652  children[0]->clear_children();
5653  children[1]->clear_children();
5654  children[0]->clear_user_data();
5655  children[1]->clear_user_data();
5656  children[0]->clear_user_flag();
5657  children[1]->clear_user_flag();
5658 
5659  children[0]->set_boundary_id (middle_line->boundary_id());
5660  children[1]->set_boundary_id (middle_line->boundary_id());
5661 
5662  children[0]->set_manifold_id (middle_line->manifold_id());
5663  children[1]->set_manifold_id (middle_line->manifold_id());
5664  }
5665  // now remove the flag from the quad and go to
5666  // the next quad, the actual refinement of the
5667  // quad takes place later on in this pass of
5668  // the loop or in the next one
5669  quad->clear_user_flag();
5670  continue;
5671  } // if (several refinement cases)
5672 
5673  // if we got here, we have an unrefined quad and
5674  // have to do the usual work like in an purely
5675  // isotropic refinement
5676  Assert(quad_ref_case==RefinementCase<dim-1>::no_refinement, ExcInternalError());
5677 
5678  // set the middle vertex
5679  // appropriately
5680  if (quad->at_boundary() ||
5681  (quad->manifold_id() != numbers::invalid_manifold_id) )
5682  triangulation.vertices[next_unused_vertex]
5683  = quad->center(true);
5684  else
5685  {
5686  // it might be that the quad itself is not at
5687  // the boundary, but that one of its lines
5688  // actually is. in this case, the newly
5689  // created vertices at the centers of the
5690  // lines are not necessarily the mean values
5691  // of the adjacent vertices, so do not compute
5692  // the new vertex as the mean value of the 4
5693  // vertices of the face, but rather as a
5694  // weighted mean value of the 8 vertices which
5695  // we already have (the four old ones, and the
5696  // four ones inserted as middle points for the
5697  // four lines). summing up some more points is
5698  // generally cheaper than first asking whether
5699  // one of the lines is at the boundary
5700  //
5701  // note that the exact weights are chosen such
5702  // as to minimize the distortion of the four
5703  // new quads from the optimal shape; their
5704  // derivation and values is copied over from
5705  // the @p{MappingQ::set_laplace_on_vector}
5706  // function
5707  triangulation.vertices[next_unused_vertex] =
5708  quad->center(true, true);
5709  }
5710  triangulation.vertices_used[next_unused_vertex] = true;
5711  // now that we created the right point, make up
5712  // the four lines interior to the quad (++ takes
5713  // care of the end of the vector)
5714  typename Triangulation<dim,spacedim>::raw_line_iterator new_lines[4];
5715 
5716  for (unsigned int i=0; i<4; ++i)
5717  {
5718  if (i%2==0)
5719  // search a free pair of lines for 0. and
5720  // 2. line, so that two of them end up
5721  // together, which is necessary if later on
5722  // we want to refine the quad
5723  // anisotropically and the two lines end up
5724  // as children of new line
5725  next_unused_line=triangulation.faces->lines.next_free_pair_object(triangulation);
5726 
5727  new_lines[i] = next_unused_line;
5728  ++next_unused_line;
5729 
5730  Assert (new_lines[i]->used() == false,
5731  ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5732  }
5733 
5734  // set the data of the four lines. first collect
5735  // the indices of the five vertices:
5736  //
5737  // *--3--*
5738  // | | |
5739  // 0--4--1
5740  // | | |
5741  // *--2--*
5742  //
5743  // the lines are numbered as follows:
5744  //
5745  // *--*--*
5746  // | 1 |
5747  // *2-*-3*
5748  // | 0 |
5749  // *--*--*
5750 
5751  const unsigned int vertex_indices[5]
5752  = { quad->line(0)->child(0)->vertex_index(1),
5753  quad->line(1)->child(0)->vertex_index(1),
5754  quad->line(2)->child(0)->vertex_index(1),
5755  quad->line(3)->child(0)->vertex_index(1),
5756  next_unused_vertex
5757  };
5758 
5759  new_lines[0]->set (internal::Triangulation::
5760  TriaObject<1>(vertex_indices[2], vertex_indices[4]));
5761  new_lines[1]->set (internal::Triangulation::
5762  TriaObject<1>(vertex_indices[4], vertex_indices[3]));
5763  new_lines[2]->set (internal::Triangulation::
5764  TriaObject<1>(vertex_indices[0], vertex_indices[4]));
5765  new_lines[3]->set (internal::Triangulation::
5766  TriaObject<1>(vertex_indices[4], vertex_indices[1]));
5767 
5768  for (unsigned int i=0; i<4; ++i)
5769  {
5770  new_lines[i]->set_used_flag();
5771  new_lines[i]->clear_user_flag();
5772  new_lines[i]->clear_user_data();
5773  new_lines[i]->clear_children();
5774  new_lines[i]->set_boundary_id(quad->boundary_id());
5775  new_lines[i]->set_manifold_id(quad->manifold_id());
5776  }
5777 
5778  // now for the quads. again, first collect some
5779  // data about the indices of the lines, with the
5780  // following numbering:
5781  //
5782  // .-6-.-7-.
5783  // 1 9 3
5784  // .-10.11-.
5785  // 0 8 2
5786  // .-4-.-5-.
5787 
5788  // child 0 and 1 of a line are switched if the
5789  // line orientation is false. set up a miniature
5790  // table, indicating which child to take for line
5791  // orientations false and true. first index: child
5792  // index in standard orientation, second index:
5793  // line orientation
5794  const unsigned int index[2][2]=
5795  {
5796  {1,0}, // child 0, line_orientation=false and true
5797  {0,1}
5798  }; // child 1, line_orientation=false and true
5799 
5800  const int line_indices[12]
5801  = { quad->line(0)->child(index[0][quad->line_orientation(0)])->index(),
5802  quad->line(0)->child(index[1][quad->line_orientation(0)])->index(),
5803  quad->line(1)->child(index[0][quad->line_orientation(1)])->index(),
5804  quad->line(1)->child(index[1][quad->line_orientation(1)])->index(),
5805  quad->line(2)->child(index[0][quad->line_orientation(2)])->index(),
5806  quad->line(2)->child(index[1][quad->line_orientation(2)])->index(),
5807  quad->line(3)->child(index[0][quad->line_orientation(3)])->index(),
5808  quad->line(3)->child(index[1][quad->line_orientation(3)])->index(),
5809  new_lines[0]->index(),
5810  new_lines[1]->index(),
5811  new_lines[2]->index(),
5812  new_lines[3]->index()
5813  };
5814 
5815  // find some space (consecutive)
5816  // for the first two newly to be
5817  // created quads.
5818  typename Triangulation<dim,spacedim>::raw_quad_iterator new_quads[4];
5819 
5820  next_unused_quad=triangulation.faces->quads.next_free_pair_object(triangulation);
5821 
5822  new_quads[0] = next_unused_quad;
5823  Assert (new_quads[0]->used() == false, ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5824 
5825  ++next_unused_quad;
5826  new_quads[1] = next_unused_quad;
5827  Assert (new_quads[1]->used() == false, ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5828 
5829  next_unused_quad=triangulation.faces->quads.next_free_pair_object(triangulation);
5830  new_quads[2] = next_unused_quad;
5831  Assert (new_quads[2]->used() == false, ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5832 
5833  ++next_unused_quad;
5834  new_quads[3] = next_unused_quad;
5835  Assert (new_quads[3]->used() == false, ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5836 
5837  // note these quads as children to the present one
5838  quad->set_children (0, new_quads[0]->index());
5839  quad->set_children (2, new_quads[2]->index());
5840  new_quads[0]->set (internal::Triangulation
5841  ::TriaObject<2>(line_indices[0],
5842  line_indices[8],
5843  line_indices[4],
5844  line_indices[10]));
5845 
5846  quad->set_refinement_case(RefinementCase<2>::cut_xy);
5847 
5848  new_quads[0]->set (internal::Triangulation
5849  ::TriaObject<2>(line_indices[0],
5850  line_indices[8],
5851  line_indices[4],
5852  line_indices[10]));
5853  new_quads[1]->set (internal::Triangulation
5854  ::TriaObject<2>(line_indices[8],
5855  line_indices[2],
5856  line_indices[5],
5857  line_indices[11]));
5858  new_quads[2]->set (internal::Triangulation
5859  ::TriaObject<2>(line_indices[1],
5860  line_indices[9],
5861  line_indices[10],
5862  line_indices[6]));
5863  new_quads[3]->set (internal::Triangulation
5864  ::TriaObject<2>(line_indices[9],
5865  line_indices[3],
5866  line_indices[11],
5867  line_indices[7]));
5868  for (unsigned int i=0; i<4; ++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 (quad->boundary_id());
5875  new_quads[i]->set_manifold_id (quad->manifold_id());
5876  // set all line orientations to true, change
5877  // this after the loop, as we have to consider
5878  // different lines for each child
5879  for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
5880  new_quads[i]->set_line_orientation(j,true);
5881  }
5882  // now set the line orientation of children of
5883  // outer lines correctly, the lines in the
5884  // interior of the refined quad are automatically
5885  // oriented conforming to the standard
5886  new_quads[0]->set_line_orientation(0,quad->line_orientation(0));
5887  new_quads[0]->set_line_orientation(2,quad->line_orientation(2));
5888  new_quads[1]->set_line_orientation(1,quad->line_orientation(1));
5889  new_quads[1]->set_line_orientation(2,quad->line_orientation(2));
5890  new_quads[2]->set_line_orientation(0,quad->line_orientation(0));
5891  new_quads[2]->set_line_orientation(3,quad->line_orientation(3));
5892  new_quads[3]->set_line_orientation(1,quad->line_orientation(1));
5893  new_quads[3]->set_line_orientation(3,quad->line_orientation(3));
5894 
5895  // finally clear flag indicating the need for
5896  // refinement
5897  quad->clear_user_flag ();
5898  } // if (isotropic refinement)
5899  } // for all quads
5900  } // looped two times over all quads, all quads refined now
5901 
5903  // Now, finally, set up the new
5904  // cells
5906 
5908  cells_with_distorted_children;
5909 
5910  for (unsigned int level=0; level!=triangulation.levels.size()-1; ++level)
5911  {
5912  // only active objects can be refined further; remember
5913  // that we won't operate on the finest level, so
5914  // triangulation.begin_*(level+1) is allowed
5915  typename Triangulation<dim,spacedim>::active_hex_iterator
5916  hex = triangulation.begin_active_hex(level),
5917  endh = triangulation.begin_active_hex(level+1);
5918  typename Triangulation<dim,spacedim>::raw_hex_iterator
5919  next_unused_hex = triangulation.begin_raw_hex (level+1);
5920 
5921  for (; hex!=endh; ++hex)
5922  if (hex->refine_flag_set())
5923  {
5924  // this hex needs to be refined
5925 
5926  // clear flag indicating the need for refinement. do
5927  // it here already, since we can't do it anymore
5928  // once the cell has children
5929  const RefinementCase<dim> ref_case=hex->refine_flag_set();
5930  hex->clear_refine_flag ();
5931  hex->set_refinement_case(ref_case);
5932 
5933  // depending on the refine case we might have to
5934  // create additional vertices, lines and quads
5935  // interior of the hex before the actual children
5936  // can be set up.
5937 
5938  // in a first step: reserve the needed space for
5939  // lines, quads and hexes and initialize them
5940  // correctly
5941 
5942  unsigned int n_new_lines=0;
5943  unsigned int n_new_quads=0;
5944  unsigned int n_new_hexes=0;
5945  switch (ref_case)
5946  {
5950  n_new_lines=0;
5951  n_new_quads=1;
5952  n_new_hexes=2;
5953  break;
5957  n_new_lines=1;
5958  n_new_quads=4;
5959  n_new_hexes=4;
5960  break;
5962  n_new_lines=6;
5963  n_new_quads=12;
5964  n_new_hexes=8;
5965  break;
5966  default:
5967  Assert(false, ExcInternalError());
5968  break;
5969  }
5970 
5971  // find some space for the newly to be created
5972  // interior lines and initialize them.
5973  std::vector<typename Triangulation<dim,spacedim>::raw_line_iterator>
5974  new_lines(n_new_lines);
5975  for (unsigned int i=0; i<n_new_lines; ++i)
5976  {
5977  new_lines[i] = triangulation.faces->lines.next_free_single_object(triangulation);
5978 
5979  Assert (new_lines[i]->used() == false,
5980  ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
5981  new_lines[i]->set_used_flag();
5982  new_lines[i]->clear_user_flag();
5983  new_lines[i]->clear_user_data();
5984  new_lines[i]->clear_children();
5985  // interior line
5986  new_lines[i]->set_boundary_id(numbers::internal_face_boundary_id);
5987  // they inherit geometry description of the hex they belong to
5988  new_lines[i]->set_manifold_id(hex->manifold_id());
5989  }
5990 
5991  // find some space for the newly to be created
5992  // interior quads and initialize them.
5993  std::vector<typename Triangulation<dim,spacedim>::raw_quad_iterator>
5994  new_quads(n_new_quads);
5995  for (unsigned int i=0; i<n_new_quads; ++i)
5996  {
5997  new_quads[i] = triangulation.faces->quads.next_free_single_object(triangulation);
5998 
5999  Assert (new_quads[i]->used() == false,
6000  ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6001  new_quads[i]->set_used_flag();
6002  new_quads[i]->clear_user_flag();
6003  new_quads[i]->clear_user_data();
6004  new_quads[i]->clear_children();
6005  // interior quad
6006  new_quads[i]->set_boundary_id (numbers::internal_face_boundary_id);
6007  // they inherit geometry description of the hex they belong to
6008  new_quads[i]->set_manifold_id (hex->manifold_id());
6009  // set all line orientation flags to true by
6010  // default, change this afterwards, if necessary
6011  for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
6012  new_quads[i]->set_line_orientation(j,true);
6013  }
6014 
6015  types::subdomain_id subdomainid = hex->subdomain_id();
6016 
6017  // find some space for the newly to be created hexes
6018  // and initialize them.
6019  std::vector<typename Triangulation<dim,spacedim>::raw_hex_iterator>
6020  new_hexes(n_new_hexes);
6021  for (unsigned int i=0; i<n_new_hexes; ++i)
6022  {
6023  if (i%2==0)
6024  next_unused_hex=triangulation.levels[level+1]->cells.next_free_hex(triangulation,level+1);
6025  else
6026  ++next_unused_hex;
6027 
6028  new_hexes[i]=next_unused_hex;
6029 
6030  Assert (new_hexes[i]->used() == false,
6031  ExcMessage("Internal error: We want to use a cell during refinement that should be unused, but turns out not to be."));
6032  new_hexes[i]->set_used_flag();
6033  new_hexes[i]->clear_user_flag();
6034  new_hexes[i]->clear_user_data();
6035  new_hexes[i]->clear_children();
6036  // inherit material
6037  // properties
6038  new_hexes[i]->set_material_id (hex->material_id());
6039  new_hexes[i]->set_manifold_id (hex->manifold_id());
6040  new_hexes[i]->set_subdomain_id (subdomainid);
6041 
6042  if (i%2)
6043  new_hexes[i]->set_parent (hex->index ());
6044  // set the face_orientation flag to true for all
6045  // faces initially, as this is the default value
6046  // which is true for all faces interior to the
6047  // hex. later on go the other way round and
6048  // reset faces that are at the boundary of the
6049  // mother cube
6050  //
6051  // the same is true for the face_flip and
6052  // face_rotation flags. however, the latter two
6053  // are set to false by default as this is the
6054  // standard value
6055  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
6056  {
6057  new_hexes[i]->set_face_orientation(f, true);
6058  new_hexes[i]->set_face_flip(f, false);
6059  new_hexes[i]->set_face_rotation(f, false);
6060  }
6061  }
6062  // note these hexes as children to the present cell
6063  for (unsigned int i=0; i<n_new_hexes/2; ++i)
6064  hex->set_children (2*i, new_hexes[2*i]->index());
6065 
6066  // we have to take into account whether the
6067  // different faces are oriented correctly or in the
6068  // opposite direction, so store that up front
6069 
6070  // face_orientation
6071  const bool f_or[6]
6072  = { hex->face_orientation (0),
6073  hex->face_orientation (1),
6074  hex->face_orientation (2),
6075  hex->face_orientation (3),
6076  hex->face_orientation (4),
6077  hex->face_orientation (5)
6078  };
6079 
6080  // face_flip
6081  const bool f_fl[6]
6082  = { hex->face_flip (0),
6083  hex->face_flip (1),
6084  hex->face_flip (2),
6085  hex->face_flip (3),
6086  hex->face_flip (4),
6087  hex->face_flip (5)
6088  };
6089 
6090  // face_rotation
6091  const bool f_ro[6]
6092  = { hex->face_rotation (0),
6093  hex->face_rotation (1),
6094  hex->face_rotation (2),
6095  hex->face_rotation (3),
6096  hex->face_rotation (4),
6097  hex->face_rotation (5)
6098  };
6099 
6100  // some commonly used fields which
6101  // have varying size
6102  const unsigned int *vertex_indices=0;
6103  const typename Triangulation<dim,spacedim>::raw_line_iterator
6104  *lines=0;
6105  const unsigned int *line_indices=0;
6106  const bool *line_orientation=0;
6107  const int *quad_indices=0;
6108 
6109  // little helper table, indicating, whether the
6110  // child with index 0 or with index 1 can be found
6111  // at the standard origin of an anisotropically
6112  // refined quads in real orientation index 1:
6113  // (RefineCase - 1) index 2: face_flip
6114 
6115  // index 3: face rotation
6116  // note: face orientation has no influence
6117  const unsigned int child_at_origin[2][2][2]=
6118  {
6119  { { 0, 0 }, // RefinementCase<dim>::cut_x, face_flip=false, face_rotation=false and true
6120  { 1, 1 }
6121  }, // RefinementCase<dim>::cut_x, face_flip=true, face_rotation=false and true
6122  { { 0, 1 }, // RefinementCase<dim>::cut_y, face_flip=false, face_rotation=false and true
6123  { 1, 0 }
6124  }
6125  };// RefinementCase<dim>::cut_y, face_flip=true, face_rotation=false and true
6126 
6128  //
6129  // in the following we will do the same thing for
6130  // each refinement case: create a new vertex (if
6131  // needed), create new interior lines (if needed),
6132  // create new interior quads and afterwards build
6133  // the children hexes out of these and the existing
6134  // subfaces of the outer quads (which have been
6135  // created above). However, even if the steps are
6136  // quite similar, the actual work strongly depends
6137  // on the actual refinement case. therefore, we use
6138  // separate blocks of code for each of these cases,
6139  // which hopefully increases the readability to some
6140  // extend.
6141 
6142  switch (ref_case)
6143  {
6145  {
6147  //
6148  // RefinementCase<dim>::cut_x
6149  //
6150  // the refined cube will look
6151  // like this:
6152  //
6153  // *----*----*
6154  // / / /|
6155  // / / / |
6156  // / / / |
6157  // *----*----* |
6158  // | | | |
6159  // | | | *
6160  // | | | /
6161  // | | | /
6162  // | | |/
6163  // *----*----*
6164  //
6165  // again, first collect some data about the
6166  // indices of the lines, with the following
6167  // numbering:
6168 
6169  // face 2: front plane
6170  // (note: x,y exchanged)
6171  // *---*---*
6172  // | | |
6173  // | 0 |
6174  // | | |
6175  // *---*---*
6176  // m0
6177  // face 3: back plane
6178  // (note: x,y exchanged)
6179  // m1
6180  // *---*---*
6181  // | | |
6182  // | 1 |
6183  // | | |
6184  // *---*---*
6185  // face 4: bottom plane
6186  // *---*---*
6187  // / / /
6188  // / 2 /
6189  // / / /
6190  // *---*---*
6191  // m0
6192  // face 5: top plane
6193  // m1
6194  // *---*---*
6195  // / / /
6196  // / 3 /
6197  // / / /
6198  // *---*---*
6199 
6200  // set up a list of line iterators first. from
6201  // this, construct lists of line_indices and
6202  // line orientations later on
6203  const typename Triangulation<dim,spacedim>::raw_line_iterator
6204  lines_x[4]
6205  =
6206  {
6207  hex->face(2)->child(0)
6208  ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
6209  hex->face(3)->child(0)
6210  ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
6211  hex->face(4)->child(0)
6212  ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
6213  hex->face(5)->child(0)
6214  ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3) //3
6215  };
6216 
6217  lines=&lines_x[0];
6218 
6219  unsigned int line_indices_x[4];
6220 
6221  for (unsigned int i=0; i<4; ++i)
6222  line_indices_x[i]=lines[i]->index();
6223  line_indices=&line_indices_x[0];
6224 
6225  // the orientation of lines for the inner quads
6226  // is quite tricky. as these lines are newly
6227  // created ones and thus have no parents, they
6228  // cannot inherit this property. set up an array
6229  // and fill it with the respective values
6230  bool line_orientation_x[4];
6231 
6232  // the middle vertice marked as m0 above is the
6233  // start vertex for lines 0 and 2 in standard
6234  // orientation, whereas m1 is the end vertex of
6235  // lines 1 and 3 in standard orientation
6236  const unsigned int middle_vertices[2]=
6237  {
6238  hex->line(2)->child(0)->vertex_index(1),
6239  hex->line(7)->child(0)->vertex_index(1)
6240  };
6241 
6242  for (unsigned int i=0; i<4; ++i)
6243  if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
6244  line_orientation_x[i]=true;
6245  else
6246  {
6247  // it must be the other
6248  // way round then
6249  Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
6250  ExcInternalError());
6251  line_orientation_x[i]=false;
6252  }
6253 
6254  line_orientation=&line_orientation_x[0];
6255 
6256  // set up the new quad, line numbering is as
6257  // indicated above
6258  new_quads[0]->set (internal::Triangulation
6259  ::TriaObject<2>(line_indices[0],
6260  line_indices[1],
6261  line_indices[2],
6262  line_indices[3]));
6263 
6264  new_quads[0]->set_line_orientation(0,line_orientation[0]);
6265  new_quads[0]->set_line_orientation(1,line_orientation[1]);
6266  new_quads[0]->set_line_orientation(2,line_orientation[2]);
6267  new_quads[0]->set_line_orientation(3,line_orientation[3]);
6268 
6269  // the quads are numbered as follows:
6270  //
6271  // planes in the interior of the old hex:
6272  //
6273  // *
6274  // /|
6275  // / | x
6276  // / | *-------* *---------*
6277  // * | | | / /
6278  // | 0 | | | / /
6279  // | * | | / /
6280  // | / *-------*y *---------*x
6281  // | /
6282  // |/
6283  // *
6284  //
6285  // children of the faces of the old hex
6286  //
6287  // *---*---* *---*---*
6288  // /| | | / / /|
6289  // / | | | / 9 / 10/ |
6290  // / | 5 | 6 | / / / |
6291  // * | | | *---*---* |
6292  // | 1 *---*---* | | | 2 *
6293  // | / / / | | | /
6294  // | / 7 / 8 / | 3 | 4 | /
6295  // |/ / / | | |/
6296  // *---*---* *---*---*
6297  //
6298  // note that we have to take care of the
6299  // orientation of faces.
6300  const int quad_indices_x[11]
6301  =
6302  {
6303  new_quads[0]->index(), //0
6304 
6305  hex->face(0)->index(), //1
6306 
6307  hex->face(1)->index(), //2
6308 
6309  hex->face(2)->child_index( child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]), //3
6310  hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
6311 
6312  hex->face(3)->child_index( child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]), //5
6313  hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
6314 
6315  hex->face(4)->child_index( child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]), //7
6316  hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
6317 
6318  hex->face(5)->child_index( child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]), //9
6319  hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
6320 
6321  };
6322  quad_indices=&quad_indices_x[0];
6323 
6324  new_hexes[0]->set (internal::Triangulation
6325  ::TriaObject<3>(quad_indices[1],
6326  quad_indices[0],
6327  quad_indices[3],
6328  quad_indices[5],
6329  quad_indices[7],
6330  quad_indices[9]));
6331  new_hexes[1]->set (internal::Triangulation
6332  ::TriaObject<3>(quad_indices[0],
6333  quad_indices[2],
6334  quad_indices[4],
6335  quad_indices[6],
6336  quad_indices[8],
6337  quad_indices[10]));
6338  break;
6339  }
6341  {
6343  //
6344  // RefinementCase<dim>::cut_y
6345  //
6346  // the refined cube will look like this:
6347  //
6348  // *---------*
6349  // / /|
6350  // *---------* |
6351  // / /| |
6352  // *---------* | |
6353  // | | | |
6354  // | | | *
6355  // | | |/
6356  // | | *
6357  // | |/
6358  // *---------*
6359  //
6360  // again, first collect some data about the
6361  // indices of the lines, with the following
6362  // numbering:
6363 
6364  // face 0: left plane
6365  // *
6366  // /|
6367  // * |
6368  // /| |
6369  // * | |
6370  // | 0 |
6371  // | | *
6372  // | |/
6373  // | *m0
6374  // |/
6375  // *
6376  // face 1: right plane
6377  // *
6378  // /|
6379  // m1* |
6380  // /| |
6381  // * | |
6382  // | 1 |
6383  // | | *
6384  // | |/
6385  // | *
6386  // |/
6387  // *
6388  // face 4: bottom plane
6389  // *-------*
6390  // / /
6391  // m0*---2---*
6392  // / /
6393  // *-------*
6394  // face 5: top plane
6395  // *-------*
6396  // / /
6397  // *---3---*m1
6398  // / /
6399  // *-------*
6400 
6401  // set up a list of line iterators first. from
6402  // this, construct lists of line_indices and
6403  // line orientations later on
6404  const typename Triangulation<dim,spacedim>::raw_line_iterator
6405  lines_y[4]
6406  =
6407  {
6408  hex->face(0)->child(0)
6409  ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
6410  hex->face(1)->child(0)
6411  ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
6412  hex->face(4)->child(0)
6413  ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
6414  hex->face(5)->child(0)
6415  ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3) //3
6416  };
6417 
6418  lines=&lines_y[0];
6419 
6420  unsigned int line_indices_y[4];
6421 
6422  for (unsigned int i=0; i<4; ++i)
6423  line_indices_y[i]=lines[i]->index();
6424  line_indices=&line_indices_y[0];
6425 
6426  // the orientation of lines for the inner quads
6427  // is quite tricky. as these lines are newly
6428  // created ones and thus have no parents, they
6429  // cannot inherit this property. set up an array
6430  // and fill it with the respective values
6431  bool line_orientation_y[4];
6432 
6433  // the middle vertice marked as m0 above is the
6434  // start vertex for lines 0 and 2 in standard
6435  // orientation, whereas m1 is the end vertex of
6436  // lines 1 and 3 in standard orientation
6437  const unsigned int middle_vertices[2]=
6438  {
6439  hex->line(0)->child(0)->vertex_index(1),
6440  hex->line(5)->child(0)->vertex_index(1)
6441  };
6442 
6443  for (unsigned int i=0; i<4; ++i)
6444  if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
6445  line_orientation_y[i]=true;
6446  else
6447  {
6448  // it must be the other way round then
6449  Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
6450  ExcInternalError());
6451  line_orientation_y[i]=false;
6452  }
6453 
6454  line_orientation=&line_orientation_y[0];
6455 
6456  // set up the new quad, line numbering is as
6457  // indicated above
6458  new_quads[0]->set (internal::Triangulation
6459  ::TriaObject<2>(line_indices[2],
6460  line_indices[3],
6461  line_indices[0],
6462  line_indices[1]));
6463 
6464  new_quads[0]->set_line_orientation(0,line_orientation[2]);
6465  new_quads[0]->set_line_orientation(1,line_orientation[3]);
6466  new_quads[0]->set_line_orientation(2,line_orientation[0]);
6467  new_quads[0]->set_line_orientation(3,line_orientation[1]);
6468 
6469  // the quads are numbered as follows:
6470  //
6471  // planes in the interior of the old hex:
6472  //
6473  // *
6474  // /|
6475  // / | x
6476  // / | *-------* *---------*
6477  // * | | | / /
6478  // | | | 0 | / /
6479  // | * | | / /
6480  // | / *-------*y *---------*x
6481  // | /
6482  // |/
6483  // *
6484  //
6485  // children of the faces of the old hex
6486  //
6487  // *-------* *-------*
6488  // /| | / 10 /|
6489  // * | | *-------* |
6490  // /| | 6 | / 9 /| |
6491  // * |2| | *-------* |4|
6492  // | | *-------* | | | *
6493  // |1|/ 8 / | |3|/
6494  // | *-------* | 5 | *
6495  // |/ 7 / | |/
6496  // *-------* *-------*
6497  //
6498  // note that we have to take care of the
6499  // orientation of faces.
6500  const int quad_indices_y[11]
6501  =
6502  {
6503  new_quads[0]->index(), //0
6504 
6505  hex->face(0)->child_index( child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]), //1
6506  hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
6507 
6508  hex->face(1)->child_index( child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]), //3
6509  hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
6510 
6511  hex->face(2)->index(), //5
6512 
6513  hex->face(3)->index(), //6
6514 
6515  hex->face(4)->child_index( child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]), //7
6516  hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
6517 
6518  hex->face(5)->child_index( child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]), //9
6519  hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
6520 
6521  };
6522  quad_indices=&quad_indices_y[0];
6523 
6524  new_hexes[0]->set (internal::Triangulation
6525  ::TriaObject<3>(quad_indices[1],
6526  quad_indices[3],
6527  quad_indices[5],
6528  quad_indices[0],
6529  quad_indices[7],
6530  quad_indices[9]));
6531  new_hexes[1]->set (internal::Triangulation
6532  ::TriaObject<3>(quad_indices[2],
6533  quad_indices[4],
6534  quad_indices[0],
6535  quad_indices[6],
6536  quad_indices[8],
6537  quad_indices[10]));
6538  break;
6539  }
6541  {
6543  //
6544  // RefinementCase<dim>::cut_z
6545  //
6546  // the refined cube will look like this:
6547  //
6548  // *---------*
6549  // / /|
6550  // / / |
6551  // / / *
6552  // *---------* /|
6553  // | | / |
6554  // | |/ *
6555  // *---------* /
6556  // | | /
6557  // | |/
6558  // *---------*
6559  //
6560  // again, first collect some data about the
6561  // indices of the lines, with the following
6562  // numbering:
6563 
6564  // face 0: left plane
6565  // *
6566  // /|
6567  // / |
6568  // / *
6569  // * /|
6570  // | 0 |
6571  // |/ *
6572  // m0* /
6573  // | /
6574  // |/
6575  // *
6576  // face 1: right plane
6577  // *
6578  // /|
6579  // / |
6580  // / *m1
6581  // * /|
6582  // | 1 |
6583  // |/ *
6584  // * /
6585  // | /
6586  // |/
6587  // *
6588  // face 2: front plane
6589  // (note: x,y exchanged)
6590  // *-------*
6591  // | |
6592  // m0*---2---*
6593  // | |
6594  // *-------*
6595  // face 3: back plane
6596  // (note: x,y exchanged)
6597  // *-------*
6598  // | |
6599  // *---3---*m1
6600  // | |
6601  // *-------*
6602 
6603  // set up a list of line iterators first. from
6604  // this, construct lists of line_indices and
6605  // line orientations later on
6606  const typename Triangulation<dim,spacedim>::raw_line_iterator
6607  lines_z[4]
6608  =
6609  {
6610  hex->face(0)->child(0)
6611  ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
6612  hex->face(1)->child(0)
6613  ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
6614  hex->face(2)->child(0)
6615  ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
6616  hex->face(3)->child(0)
6617  ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3) //3
6618  };
6619 
6620  lines=&lines_z[0];
6621 
6622  unsigned int line_indices_z[4];
6623 
6624  for (unsigned int i=0; i<4; ++i)
6625  line_indices_z[i]=lines[i]->index();
6626  line_indices=&line_indices_z[0];
6627 
6628  // the orientation of lines for the inner quads
6629  // is quite tricky. as these lines are newly
6630  // created ones and thus have no parents, they
6631  // cannot inherit this property. set up an array
6632  // and fill it with the respective values
6633  bool line_orientation_z[4];
6634 
6635  // the middle vertex marked as m0 above is the
6636  // start vertex for lines 0 and 2 in standard
6637  // orientation, whereas m1 is the end vertex of
6638  // lines 1 and 3 in standard orientation
6639  const unsigned int middle_vertices[2]=
6640  {
6641  middle_vertex_index<dim,spacedim>(hex->line(8)),
6642  middle_vertex_index<dim,spacedim>(hex->line(11))
6643  };
6644 
6645  for (unsigned int i=0; i<4; ++i)
6646  if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
6647  line_orientation_z[i]=true;
6648  else
6649  {
6650  // it must be the other way round then
6651  Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
6652  ExcInternalError());
6653  line_orientation_z[i]=false;
6654  }
6655 
6656  line_orientation=&line_orientation_z[0];
6657 
6658  // set up the new quad, line numbering is as
6659  // indicated above
6660  new_quads[0]->set (internal::Triangulation
6661  ::TriaObject<2>(line_indices[0],
6662  line_indices[1],
6663  line_indices[2],
6664  line_indices[3]));
6665 
6666  new_quads[0]->set_line_orientation(0,line_orientation[0]);
6667  new_quads[0]->set_line_orientation(1,line_orientation[1]);
6668  new_quads[0]->set_line_orientation(2,line_orientation[2]);
6669  new_quads[0]->set_line_orientation(3,line_orientation[3]);
6670 
6671  // the quads are numbered as follows:
6672  //
6673  // planes in the interior of the old hex:
6674  //
6675  // *
6676  // /|
6677  // / | x
6678  // / | *-------* *---------*
6679  // * | | | / /
6680  // | | | | / 0 /
6681  // | * | | / /
6682  // | / *-------*y *---------*x
6683  // | /
6684  // |/
6685  // *
6686  //
6687  // children of the faces of the old hex
6688  //
6689  // *---*---* *-------*
6690  // /| 8 | / /|
6691  // / | | / 10 / |
6692  // / *-------* / / *
6693  // * 2/| | *-------* 4/|
6694  // | / | 7 | | 6 | / |
6695  // |/1 *-------* | |/3 *
6696  // * / / *-------* /
6697  // | / 9 / | | /
6698  // |/ / | 5 |/
6699  // *-------* *---*---*
6700  //
6701  // note that we have to take care of the
6702  // orientation of faces.
6703  const int quad_indices_z[11]
6704  =
6705  {
6706  new_quads[0]->index(), //0
6707 
6708  hex->face(0)->child_index( child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]), //1
6709  hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
6710 
6711  hex->face(1)->child_index( child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]), //3
6712  hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
6713 
6714  hex->face(2)->child_index( child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]), //5
6715  hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
6716 
6717  hex->face(3)->child_index( child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]), //7
6718  hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
6719 
6720  hex->face(4)->index(), //9
6721 
6722  hex->face(5)->index() //10
6723  };
6724  quad_indices=&quad_indices_z[0];
6725 
6726  new_hexes[0]->set (internal::Triangulation
6727  ::TriaObject<3>(quad_indices[1],
6728  quad_indices[3],
6729  quad_indices[5],
6730  quad_indices[7],
6731  quad_indices[9],
6732  quad_indices[0]));
6733  new_hexes[1]->set (internal::Triangulation
6734  ::TriaObject<3>(quad_indices[2],
6735  quad_indices[4],
6736  quad_indices[6],
6737  quad_indices[8],
6738  quad_indices[0],
6739  quad_indices[10]));
6740  break;
6741  }
6743  {
6745  //
6746  // RefinementCase<dim>::cut_xy
6747  //
6748  // the refined cube will look like this:
6749  //
6750  // *----*----*
6751  // / / /|
6752  // *----*----* |
6753  // / / /| |
6754  // *----*----* | |
6755  // | | | | |
6756  // | | | | *
6757  // | | | |/
6758  // | | | *
6759  // | | |/
6760  // *----*----*
6761  //
6762 
6763  // first, create the new internal line
6764  new_lines[0]->set (internal::Triangulation::
6765  TriaObject<1>(middle_vertex_index<dim,spacedim>(hex->face(4)),
6766  middle_vertex_index<dim,spacedim>(hex->face(5))));
6767 
6768  // again, first collect some data about the
6769  // indices of the lines, with the following
6770  // numbering:
6771 
6772  // face 0: left plane
6773  // *
6774  // /|
6775  // * |
6776  // /| |
6777  // * | |
6778  // | 0 |
6779  // | | *
6780  // | |/
6781  // | *
6782  // |/
6783  // *
6784  // face 1: right plane
6785  // *
6786  // /|
6787  // * |
6788  // /| |
6789  // * | |
6790  // | 1 |
6791  // | | *
6792  // | |/
6793  // | *
6794  // |/
6795  // *
6796  // face 2: front plane
6797  // (note: x,y exchanged)
6798  // *---*---*
6799  // | | |
6800  // | 2 |
6801  // | | |
6802  // *-------*
6803  // face 3: back plane
6804  // (note: x,y exchanged)
6805  // *---*---*
6806  // | | |
6807  // | 3 |
6808  // | | |
6809  // *---*---*
6810  // face 4: bottom plane
6811  // *---*---*
6812  // / 5 /
6813  // *-6-*-7-*
6814  // / 4 /
6815  // *---*---*
6816  // face 5: top plane
6817  // *---*---*
6818  // / 9 /
6819  // *10-*-11*
6820  // / 8 /
6821  // *---*---*
6822  // middle planes
6823  // *-------* *---*---*
6824  // / / | | |
6825  // / / | 12 |
6826  // / / | | |
6827  // *-------* *---*---*
6828 
6829  // set up a list of line iterators first. from
6830  // this, construct lists of line_indices and
6831  // line orientations later on
6832  const typename Triangulation<dim,spacedim>::raw_line_iterator
6833  lines_xy[13]
6834  =
6835  {
6836  hex->face(0)->child(0)
6837  ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
6838  hex->face(1)->child(0)
6839  ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
6840  hex->face(2)->child(0)
6841  ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
6842  hex->face(3)->child(0)
6843  ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //3
6844 
6845  hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
6846  ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[4],f_fl[4],f_ro[4])), //4
6847  hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
6848  ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[4],f_fl[4],f_ro[4])), //5
6849  hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
6850  ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[4],f_fl[4],f_ro[4])), //6
6851  hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
6852  ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[4],f_fl[4],f_ro[4])), //7
6853 
6854  hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
6855  ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[5],f_fl[5],f_ro[5])), //8
6856  hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
6857  ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[5],f_fl[5],f_ro[5])), //9
6858  hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
6859  ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[5],f_fl[5],f_ro[5])), //10
6860  hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
6861  ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[5],f_fl[5],f_ro[5])), //11
6862 
6863  new_lines[0] //12
6864  };
6865 
6866  lines=&lines_xy[0];
6867 
6868  unsigned int line_indices_xy[13];
6869 
6870  for (unsigned int i=0; i<13; ++i)
6871  line_indices_xy[i]=lines[i]->index();
6872  line_indices=&line_indices_xy[0];
6873 
6874  // the orientation of lines for the inner quads
6875  // is quite tricky. as these lines are newly
6876  // created ones and thus have no parents, they
6877  // cannot inherit this property. set up an array
6878  // and fill it with the respective values
6879  bool line_orientation_xy[13];
6880 
6881  // the middle vertices of the lines of our
6882  // bottom face
6883  const unsigned int middle_vertices[4]=
6884  {
6885  hex->line(0)->child(0)->vertex_index(1),
6886  hex->line(1)->child(0)->vertex_index(1),
6887  hex->line(2)->child(0)->vertex_index(1),
6888  hex->line(3)->child(0)->vertex_index(1),
6889  };
6890 
6891  // note: for lines 0 to 3 the orientation of the
6892  // line is 'true', if vertex 0 is on the bottom
6893  // face
6894  for (unsigned int i=0; i<4; ++i)
6895  if (lines[i]->vertex_index(0)==middle_vertices[i])
6896  line_orientation_xy[i]=true;
6897  else
6898  {
6899  // it must be the other way round then
6900  Assert(lines[i]->vertex_index(1)==middle_vertices[i],
6901  ExcInternalError());
6902  line_orientation_xy[i]=false;
6903  }
6904 
6905  // note: for lines 4 to 11 (inner lines of the
6906  // outer quads) the following holds: the second
6907  // vertex of the even lines in standard
6908  // orientation is the vertex in the middle of
6909  // the quad, whereas for odd lines the first
6910  // vertex is the same middle vertex.
6911  for (unsigned int i=4; i<12; ++i)
6912  if (lines[i]->vertex_index((i+1)%2) ==
6913  middle_vertex_index<dim,spacedim>(hex->face(3+i/4)))
6914  line_orientation_xy[i]=true;
6915  else
6916  {
6917  // it must be the other way
6918  // round then
6919  Assert(lines[i]->vertex_index(i%2) ==
6920  (middle_vertex_index<dim,spacedim>(hex->face(3+i/4))),
6921  ExcInternalError());
6922  line_orientation_xy[i]=false;
6923  }
6924  // for the last line the line orientation is
6925  // always true, since it was just constructed
6926  // that way
6927 
6928  line_orientation_xy[12]=true;
6929  line_orientation=&line_orientation_xy[0];
6930 
6931  // set up the 4 quads, numbered as follows (left
6932  // quad numbering, right line numbering
6933  // extracted from above)
6934  //
6935  // * *
6936  // /| 9|
6937  // * | * |
6938  // y/| | 8| 3
6939  // * |1| * | |
6940  // | | |x | 12|
6941  // |0| * | | *
6942  // | |/ 2 |5
6943  // | * | *
6944  // |/ |4
6945  // * *
6946  //
6947  // x
6948  // *---*---* *10-*-11*
6949  // | | | | | |
6950  // | 2 | 3 | 0 12 1
6951  // | | | | | |
6952  // *---*---*y *-6-*-7-*
6953 
6954  new_quads[0]->set (internal::Triangulation
6955  ::TriaObject<2>(line_indices[2],
6956  line_indices[12],
6957  line_indices[4],
6958  line_indices[8]));
6959  new_quads[1]->set (internal::Triangulation
6960  ::TriaObject<2>(line_indices[12],
6961  line_indices[3],
6962  line_indices[5],
6963  line_indices[9]));
6964  new_quads[2]->set (internal::Triangulation
6965  ::TriaObject<2>(line_indices[6],
6966  line_indices[10],
6967  line_indices[0],
6968  line_indices[12]));
6969  new_quads[3]->set (internal::Triangulation
6970  ::TriaObject<2>(line_indices[7],
6971  line_indices[11],
6972  line_indices[12],
6973  line_indices[1]));
6974 
6975  new_quads[0]->set_line_orientation(0,line_orientation[2]);
6976  new_quads[0]->set_line_orientation(2,line_orientation[4]);
6977  new_quads[0]->set_line_orientation(3,line_orientation[8]);
6978 
6979  new_quads[1]->set_line_orientation(1,line_orientation[3]);
6980  new_quads[1]->set_line_orientation(2,line_orientation[5]);
6981  new_quads[1]->set_line_orientation(3,line_orientation[9]);
6982 
6983  new_quads[2]->set_line_orientation(0,line_orientation[6]);
6984  new_quads[2]->set_line_orientation(1,line_orientation[10]);
6985  new_quads[2]->set_line_orientation(2,line_orientation[0]);
6986 
6987  new_quads[3]->set_line_orientation(0,line_orientation[7]);
6988  new_quads[3]->set_line_orientation(1,line_orientation[11]);
6989  new_quads[3]->set_line_orientation(3,line_orientation[1]);
6990 
6991  // the quads are numbered as follows:
6992  //
6993  // planes in the interior of the old hex:
6994  //
6995  // *
6996  // /|
6997  // * | x
6998  // /| | *---*---* *---------*
6999  // * |1| | | | / /
7000  // | | | | 2 | 3 | / /
7001  // |0| * | | | / /
7002  // | |/ *---*---*y *---------*x
7003  // | *
7004  // |/
7005  // *
7006  //
7007  // children of the faces of the old hex
7008  //
7009  // *---*---* *---*---*
7010  // /| | | /18 / 19/|
7011  // * |10 | 11| /---/---* |
7012  // /| | | | /16 / 17/| |
7013  // * |5| | | *---*---* |7|
7014  // | | *---*---* | | | | *
7015  // |4|/14 / 15/ | | |6|/
7016  // | *---/---/ | 8 | 9 | *
7017  // |/12 / 13/ | | |/
7018  // *---*---* *---*---*
7019  //
7020  // note that we have to take care of the
7021  // orientation of faces.
7022  const int quad_indices_xy[20]
7023  =
7024  {
7025  new_quads[0]->index(), //0
7026  new_quads[1]->index(),
7027  new_quads[2]->index(),
7028  new_quads[3]->index(),
7029 
7030  hex->face(0)->child_index( child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]), //4
7031  hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
7032 
7033  hex->face(1)->child_index( child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]), //6
7034  hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
7035 
7036  hex->face(2)->child_index( child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]), //8
7037  hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
7038 
7039  hex->face(3)->child_index( child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]), //10
7040  hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
7041 
7042  hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4])), //12
7043  hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[4],f_fl[4],f_ro[4])),
7044  hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[4],f_fl[4],f_ro[4])),
7045  hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4])),
7046 
7047  hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5])), //16
7048  hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[5],f_fl[5],f_ro[5])),
7049  hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[5],f_fl[5],f_ro[5])),
7050  hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
7051  };
7052  quad_indices=&quad_indices_xy[0];
7053 
7054  new_hexes[0]->set (internal::Triangulation
7055  ::TriaObject<3>(quad_indices[4],
7056  quad_indices[0],
7057  quad_indices[8],
7058  quad_indices[2],
7059  quad_indices[12],
7060  quad_indices[16]));
7061  new_hexes[1]->set (internal::Triangulation
7062  ::TriaObject<3>(quad_indices[0],
7063  quad_indices[6],
7064  quad_indices[9],
7065  quad_indices[3],
7066  quad_indices[13],
7067  quad_indices[17]));
7068  new_hexes[2]->set (internal::Triangulation
7069  ::TriaObject<3>(quad_indices[5],
7070  quad_indices[1],
7071  quad_indices[2],
7072  quad_indices[10],
7073  quad_indices[14],
7074  quad_indices[18]));
7075  new_hexes[3]->set (internal::Triangulation
7076  ::TriaObject<3>(quad_indices[1],
7077  quad_indices[7],
7078  quad_indices[3],
7079  quad_indices[11],
7080  quad_indices[15],
7081  quad_indices[19]));
7082  break;
7083  }
7085  {
7087  //
7088  // RefinementCase<dim>::cut_xz
7089  //
7090  // the refined cube will look like this:
7091  //
7092  // *----*----*
7093  // / / /|
7094  // / / / |
7095  // / / / *
7096  // *----*----* /|
7097  // | | | / |
7098  // | | |/ *
7099  // *----*----* /
7100  // | | | /
7101  // | | |/
7102  // *----*----*
7103  //
7104 
7105  // first, create the new internal line
7106  new_lines[0]->set (internal::Triangulation::
7107  TriaObject<1>(middle_vertex_index<dim,spacedim>(hex->face(2)),
7108  middle_vertex_index<dim,spacedim>(hex->face(3))));
7109 
7110  // again, first collect some data about the
7111  // indices of the lines, with the following
7112  // numbering:
7113 
7114  // face 0: left plane
7115  // *
7116  // /|
7117  // / |
7118  // / *
7119  // * /|
7120  // | 0 |
7121  // |/ *
7122  // * /
7123  // | /
7124  // |/
7125  // *
7126  // face 1: right plane
7127  // *
7128  // /|
7129  // / |
7130  // / *
7131  // * /|
7132  // | 1 |
7133  // |/ *
7134  // * /
7135  // | /
7136  // |/
7137  // *
7138  // face 2: front plane
7139  // (note: x,y exchanged)
7140  // *---*---*
7141  // | 5 |
7142  // *-6-*-7-*
7143  // | 4 |
7144  // *---*---*
7145  // face 3: back plane
7146  // (note: x,y exchanged)
7147  // *---*---*
7148  // | 9 |
7149  // *10-*-11*
7150  // | 8 |
7151  // *---*---*
7152  // face 4: bottom plane
7153  // *---*---*
7154  // / / /
7155  // / 2 /
7156  // / / /
7157  // *---*---*
7158  // face 5: top plane
7159  // *---*---*
7160  // / / /
7161  // / 3 /
7162  // / / /
7163  // *---*---*
7164  // middle planes
7165  // *---*---* *-------*
7166  // / / / | |
7167  // / 12 / | |
7168  // / / / | |
7169  // *---*---* *-------*
7170 
7171  // set up a list of line iterators first. from
7172  // this, construct lists of line_indices and
7173  // line orientations later on
7174  const typename Triangulation<dim,spacedim>::raw_line_iterator
7175  lines_xz[13]
7176  =
7177  {
7178  hex->face(0)->child(0)
7179  ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
7180  hex->face(1)->child(0)
7181  ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
7182  hex->face(4)->child(0)
7183  ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
7184  hex->face(5)->child(0)
7185  ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //3
7186 
7187  hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
7188  ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[2],f_fl[2],f_ro[2])), //4
7189  hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
7190  ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[2],f_fl[2],f_ro[2])), //5
7191  hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
7192  ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[2],f_fl[2],f_ro[2])), //6
7193  hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
7194  ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[2],f_fl[2],f_ro[2])), //7
7195 
7196  hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
7197  ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[3],f_fl[3],f_ro[3])), //8
7198  hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
7199  ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[3],f_fl[3],f_ro[3])), //9
7200  hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
7201  ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[3],f_fl[3],f_ro[3])), //10
7202  hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
7203  ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[3],f_fl[3],f_ro[3])), //11
7204 
7205  new_lines[0] //12
7206  };
7207 
7208  lines=&lines_xz[0];
7209 
7210  unsigned int line_indices_xz[13];
7211 
7212  for (unsigned int i=0; i<13; ++i)
7213  line_indices_xz[i]=lines[i]->index();
7214  line_indices=&line_indices_xz[0];
7215 
7216  // the orientation of lines for the inner quads
7217  // is quite tricky. as these lines are newly
7218  // created ones and thus have no parents, they
7219  // cannot inherit this property. set up an array
7220  // and fill it with the respective values
7221  bool line_orientation_xz[13];
7222 
7223  // the middle vertices of the
7224  // lines of our front face
7225  const unsigned int middle_vertices[4]=
7226  {
7227  hex->line(8)->child(0)->vertex_index(1),
7228  hex->line(9)->child(0)->vertex_index(1),
7229  hex->line(2)->child(0)->vertex_index(1),
7230  hex->line(6)->child(0)->vertex_index(1),
7231  };
7232 
7233  // note: for lines 0 to 3 the orientation of the
7234  // line is 'true', if vertex 0 is on the front
7235  for (unsigned int i=0; i<4; ++i)
7236  if (lines[i]->vertex_index(0)==middle_vertices[i])
7237  line_orientation_xz[i]=true;
7238  else
7239  {
7240  // it must be the other way round then
7241  Assert(lines[i]->vertex_index(1)==middle_vertices[i],
7242  ExcInternalError());
7243  line_orientation_xz[i]=false;
7244  }
7245 
7246  // note: for lines 4 to 11 (inner lines of the
7247  // outer quads) the following holds: the second
7248  // vertex of the even lines in standard
7249  // orientation is the vertex in the middle of
7250  // the quad, whereas for odd lines the first
7251  // vertex is the same middle vertex.
7252  for (unsigned int i=4; i<12; ++i)
7253  if (lines[i]->vertex_index((i+1)%2) ==
7254  middle_vertex_index<dim,spacedim>(hex->face(1+i/4)))
7255  line_orientation_xz[i]=true;
7256  else
7257  {
7258  // it must be the other way
7259  // round then
7260  Assert(lines[i]->vertex_index(i%2) ==
7261  (middle_vertex_index<dim,spacedim>(hex->face(1+i/4))),
7262  ExcInternalError());
7263  line_orientation_xz[i]=false;
7264  }
7265  // for the last line the line orientation is
7266  // always true, since it was just constructed
7267  // that way
7268 
7269  line_orientation_xz[12]=true;
7270  line_orientation=&line_orientation_xz[0];
7271 
7272  // set up the 4 quads, numbered as follows (left
7273  // quad numbering, right line numbering
7274  // extracted from above), the drawings denote
7275  // middle planes
7276  //
7277  // * *
7278  // /| /|
7279  // / | 3 9
7280  // y/ * / *
7281  // * 3/| * /|
7282  // | / |x 5 12|8
7283  // |/ * |/ *
7284  // * 2/ * /
7285  // | / 4 2
7286  // |/ |/
7287  // * *
7288  //
7289  // y
7290  // *----*----* *-10-*-11-*
7291  // / / / / / /
7292  // / 0 / 1 / 0 12 1
7293  // / / / / / /
7294  // *----*----*x *--6-*--7-*
7295 
7296  new_quads[0]->set (internal::Triangulation
7297  ::TriaObject<2>(line_indices[0],
7298  line_indices[12],
7299  line_indices[6],
7300  line_indices[10]));
7301  new_quads[1]->set (internal::Triangulation
7302  ::TriaObject<2>(line_indices[12],
7303  line_indices[1],
7304  line_indices[7],
7305  line_indices[11]));
7306  new_quads[2]->set (internal::Triangulation
7307  ::TriaObject<2>(line_indices[4],
7308  line_indices[8],
7309  line_indices[2],
7310  line_indices[12]));
7311  new_quads[3]->set (internal::Triangulation
7312  ::TriaObject<2>(line_indices[5],
7313  line_indices[9],
7314  line_indices[12],
7315  line_indices[3]));
7316 
7317  new_quads[0]->set_line_orientation(0,line_orientation[0]);
7318  new_quads[0]->set_line_orientation(2,line_orientation[6]);
7319  new_quads[0]->set_line_orientation(3,line_orientation[10]);
7320 
7321  new_quads[1]->set_line_orientation(1,line_orientation[1]);
7322  new_quads[1]->set_line_orientation(2,line_orientation[7]);
7323  new_quads[1]->set_line_orientation(3,line_orientation[11]);
7324 
7325  new_quads[2]->set_line_orientation(0,line_orientation[4]);
7326  new_quads[2]->set_line_orientation(1,line_orientation[8]);
7327  new_quads[2]->set_line_orientation(2,line_orientation[2]);
7328 
7329  new_quads[3]->set_line_orientation(0,line_orientation[5]);
7330  new_quads[3]->set_line_orientation(1,line_orientation[9]);
7331  new_quads[3]->set_line_orientation(3,line_orientation[3]);
7332 
7333  // the quads are numbered as follows:
7334  //
7335  // planes in the interior of the old hex:
7336  //
7337  // *
7338  // /|
7339  // / | x
7340  // /3 * *-------* *----*----*
7341  // * /| | | / / /
7342  // | / | | | / 0 / 1 /
7343  // |/ * | | / / /
7344  // * 2/ *-------*y *----*----*x
7345  // | /
7346  // |/
7347  // *
7348  //
7349  // children of the faces
7350  // of the old hex
7351  // *---*---* *---*---*
7352  // /|13 | 15| / / /|
7353  // / | | | /18 / 19/ |
7354  // / *---*---* / / / *
7355  // * 5/| | | *---*---* 7/|
7356  // | / |12 | 14| | 9 | 11| / |
7357  // |/4 *---*---* | | |/6 *
7358  // * / / / *---*---* /
7359  // | /16 / 17/ | | | /
7360  // |/ / / | 8 | 10|/
7361  // *---*---* *---*---*
7362  //
7363  // note that we have to take care of the
7364  // orientation of faces.
7365  const int quad_indices_xz[20]
7366  =
7367  {
7368  new_quads[0]->index(), //0
7369  new_quads[1]->index(),
7370  new_quads[2]->index(),
7371  new_quads[3]->index(),
7372 
7373  hex->face(0)->child_index( child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]), //4
7374  hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
7375 
7376  hex->face(1)->child_index( child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]), //6
7377  hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
7378 
7379  hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2])), //8
7380  hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[2],f_fl[2],f_ro[2])),
7381  hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[2],f_fl[2],f_ro[2])),
7382  hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2])),
7383 
7384  hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3])), //12
7385  hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[3],f_fl[3],f_ro[3])),
7386  hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[3],f_fl[3],f_ro[3])),
7387  hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3])),
7388 
7389  hex->face(4)->child_index( child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]), //16
7390  hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
7391 
7392  hex->face(5)->child_index( child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]), //18
7393  hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
7394  };
7395  quad_indices=&quad_indices_xz[0];
7396 
7397  // due to the exchange of x and y for the front
7398  // and back face, we order the children
7399  // according to
7400  //
7401  // *---*---*
7402  // | 1 | 3 |
7403  // *---*---*
7404  // | 0 | 2 |
7405  // *---*---*
7406  new_hexes[0]->set (internal::Triangulation
7407  ::TriaObject<3>(quad_indices[4],
7408  quad_indices[2],
7409  quad_indices[8],
7410  quad_indices[12],
7411  quad_indices[16],
7412  quad_indices[0]));
7413  new_hexes[1]->set (internal::Triangulation
7414  ::TriaObject<3>(quad_indices[5],
7415  quad_indices[3],
7416  quad_indices[9],
7417  quad_indices[13],
7418  quad_indices[0],
7419  quad_indices[18]));
7420  new_hexes[2]->set (internal::Triangulation
7421  ::TriaObject<3>(quad_indices[2],
7422  quad_indices[6],
7423  quad_indices[10],
7424  quad_indices[14],
7425  quad_indices[17],
7426  quad_indices[1]));
7427  new_hexes[3]->set (internal::Triangulation
7428  ::TriaObject<3>(quad_indices[3],
7429  quad_indices[7],
7430  quad_indices[11],
7431  quad_indices[15],
7432  quad_indices[1],
7433  quad_indices[19]));
7434  break;
7435  }
7437  {
7439  //
7440  // RefinementCase<dim>::cut_yz
7441  //
7442  // the refined cube will look like this:
7443  //
7444  // *---------*
7445  // / /|
7446  // *---------* |
7447  // / /| |
7448  // *---------* |/|
7449  // | | * |
7450  // | |/| *
7451  // *---------* |/
7452  // | | *
7453  // | |/
7454  // *---------*
7455  //
7456 
7457  // first, create the new
7458  // internal line
7459  new_lines[0]->set (internal::Triangulation::
7460  TriaObject<1>(middle_vertex_index<dim,spacedim>(hex->face(0)),
7461  middle_vertex_index<dim,spacedim>(hex->face(1))));
7462 
7463  // again, first collect some data about the
7464  // indices of the lines, with the following
7465  // numbering: (note that face 0 and 1 each are
7466  // shown twice for better readability)
7467 
7468  // face 0: left plane
7469  // * *
7470  // /| /|
7471  // * | * |
7472  // /| * /| *
7473  // * 5/| * |7|
7474  // | * | | * |
7475  // |/| * |6| *
7476  // * 4/ * |/
7477  // | * | *
7478  // |/ |/
7479  // * *
7480  // face 1: right plane
7481  // * *
7482  // /| /|
7483  // * | * |
7484  // /| * /| *
7485  // * 9/| * |11
7486  // | * | | * |
7487  // |/| * |10 *
7488  // * 8/ * |/
7489  // | * | *
7490  // |/ |/
7491  // * *
7492  // face 2: front plane
7493  // (note: x,y exchanged)
7494  // *-------*
7495  // | |
7496  // *---0---*
7497  // | |
7498  // *-------*
7499  // face 3: back plane
7500  // (note: x,y exchanged)
7501  // *-------*
7502  // | |
7503  // *---1---*
7504  // | |
7505  // *-------*
7506  // face 4: bottom plane
7507  // *-------*
7508  // / /
7509  // *---2---*
7510  // / /
7511  // *-------*
7512  // face 5: top plane
7513  // *-------*
7514  // / /
7515  // *---3---*
7516  // / /
7517  // *-------*
7518  // middle planes
7519  // *-------* *-------*
7520  // / / | |
7521  // *---12--* | |
7522  // / / | |
7523  // *-------* *-------*
7524 
7525  // set up a list of line iterators first. from
7526  // this, construct lists of line_indices and
7527  // line orientations later on
7528  const typename Triangulation<dim,spacedim>::raw_line_iterator
7529  lines_yz[13]
7530  =
7531  {
7532  hex->face(2)->child(0)
7533  ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
7534  hex->face(3)->child(0)
7535  ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
7536  hex->face(4)->child(0)
7537  ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
7538  hex->face(5)->child(0)
7539  ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //3
7540 
7541  hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
7542  ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[0],f_fl[0],f_ro[0])), //4
7543  hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
7544  ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[0],f_fl[0],f_ro[0])), //5
7545  hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
7546  ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[0],f_fl[0],f_ro[0])), //6
7547  hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
7548  ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[0],f_fl[0],f_ro[0])), //7
7549 
7550  hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
7551  ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[1],f_fl[1],f_ro[1])), //8
7552  hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
7553  ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[1],f_fl[1],f_ro[1])), //9
7554  hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
7555  ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[1],f_fl[1],f_ro[1])), //10
7556  hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
7557  ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[1],f_fl[1],f_ro[1])), //11
7558 
7559  new_lines[0] //12
7560  };
7561 
7562  lines=&lines_yz[0];
7563 
7564  unsigned int line_indices_yz[13];
7565 
7566  for (unsigned int i=0; i<13; ++i)
7567  line_indices_yz[i]=lines[i]->index();
7568  line_indices=&line_indices_yz[0];
7569 
7570  // the orientation of lines for the inner quads
7571  // is quite tricky. as these lines are newly
7572  // created ones and thus have no parents, they
7573  // cannot inherit this property. set up an array
7574  // and fill it with the respective values
7575  bool line_orientation_yz[13];
7576 
7577  // the middle vertices of the lines of our front
7578  // face
7579  const unsigned int middle_vertices[4]=
7580  {
7581  hex->line(8)->child(0)->vertex_index(1),
7582  hex->line(10)->child(0)->vertex_index(1),
7583  hex->line(0)->child(0)->vertex_index(1),
7584  hex->line(4)->child(0)->vertex_index(1),
7585  };
7586 
7587  // note: for lines 0 to 3 the orientation of the
7588  // line is 'true', if vertex 0 is on the front
7589  for (unsigned int i=0; i<4; ++i)
7590  if (lines[i]->vertex_index(0)==middle_vertices[i])
7591  line_orientation_yz[i]=true;
7592  else
7593  {
7594  // it must be the other way round then
7595  Assert(lines[i]->vertex_index(1)==middle_vertices[i],
7596  ExcInternalError());
7597  line_orientation_yz[i]=false;
7598  }
7599 
7600  // note: for lines 4 to 11 (inner lines of the
7601  // outer quads) the following holds: the second
7602  // vertex of the even lines in standard
7603  // orientation is the vertex in the middle of
7604  // the quad, whereas for odd lines the first
7605  // vertex is the same middle vertex.
7606  for (unsigned int i=4; i<12; ++i)
7607  if (lines[i]->vertex_index((i+1)%2) ==
7608  middle_vertex_index<dim,spacedim>(hex->face(i/4-1)))
7609  line_orientation_yz[i]=true;
7610  else
7611  {
7612  // it must be the other way
7613  // round then
7614  Assert(lines[i]->vertex_index(i%2) ==
7615  (middle_vertex_index<dim,spacedim>(hex->face(i/4-1))),
7616  ExcInternalError());
7617  line_orientation_yz[i]=false;
7618  }
7619  // for the last line the line orientation is
7620  // always true, since it was just constructed
7621  // that way
7622 
7623  line_orientation_yz[12]=true;
7624  line_orientation=&line_orientation_yz[0];
7625 
7626  // set up the 4 quads, numbered as follows (left
7627  // quad numbering, right line numbering
7628  // extracted from above)
7629  //
7630  // x
7631  // *-------* *---3---*
7632  // | 3 | 5 9
7633  // *-------* *---12--*
7634  // | 2 | 4 8
7635  // *-------*y *---2---*
7636  //
7637  // y
7638  // *---------* *----1----*
7639  // / 1 / 7 11
7640  // *---------* *----12---*
7641  // / 0 / 6 10
7642  // *---------*x *----0----*
7643 
7644  new_quads[0]->set (internal::Triangulation
7645  ::TriaObject<2>(line_indices[6],
7646  line_indices[10],
7647  line_indices[0],
7648  line_indices[12]));
7649  new_quads[1]->set (internal::Triangulation
7650  ::TriaObject<2>(line_indices[7],
7651  line_indices[11],
7652  line_indices[12],
7653  line_indices[1]));
7654  new_quads[2]->set (internal::Triangulation
7655  ::TriaObject<2>(line_indices[2],
7656  line_indices[12],
7657  line_indices[4],
7658  line_indices[8]));
7659  new_quads[3]->set (internal::Triangulation
7660  ::TriaObject<2>(line_indices[12],
7661  line_indices[3],
7662  line_indices[5],
7663  line_indices[9]));
7664 
7665  new_quads[0]->set_line_orientation(0,line_orientation[6]);
7666  new_quads[0]->set_line_orientation(1,line_orientation[10]);
7667  new_quads[0]->set_line_orientation(2,line_orientation[0]);
7668 
7669  new_quads[1]->set_line_orientation(0,line_orientation[7]);
7670  new_quads[1]->set_line_orientation(1,line_orientation[11]);
7671  new_quads[1]->set_line_orientation(3,line_orientation[1]);
7672 
7673  new_quads[2]->set_line_orientation(0,line_orientation[2]);
7674  new_quads[2]->set_line_orientation(2,line_orientation[4]);
7675  new_quads[2]->set_line_orientation(3,line_orientation[8]);
7676 
7677  new_quads[3]->set_line_orientation(1,line_orientation[3]);
7678  new_quads[3]->set_line_orientation(2,line_orientation[5]);
7679  new_quads[3]->set_line_orientation(3,line_orientation[9]);
7680 
7681  // the quads are numbered as follows:
7682  //
7683  // planes in the interior of the old hex:
7684  //
7685  // *
7686  // /|
7687  // / | x
7688  // / | *-------* *---------*
7689  // * | | 3 | / 1 /
7690  // | | *-------* *---------*
7691  // | * | 2 | / 0 /
7692  // | / *-------*y *---------*x
7693  // | /
7694  // |/
7695  // *
7696  //
7697  // children of the faces
7698  // of the old hex
7699  // *-------* *-------*
7700  // /| | / 19 /|
7701  // * | 15 | *-------* |
7702  // /|7*-------* / 18 /|11
7703  // * |/| | *-------* |/|
7704  // |6* | 14 | | 10* |
7705  // |/|5*-------* | 13 |/|9*
7706  // * |/ 17 / *-------* |/
7707  // |4*-------* | |8*
7708  // |/ 16 / | 12 |/
7709  // *-------* *-------*
7710  //
7711  // note that we have to take care of the
7712  // orientation of faces.
7713  const int quad_indices_yz[20]
7714  =
7715  {
7716  new_quads[0]->index(), //0
7717  new_quads[1]->index(),
7718  new_quads[2]->index(),
7719  new_quads[3]->index(),
7720 
7721  hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0])), //4
7722  hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[0],f_fl[0],f_ro[0])),
7723  hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[0],f_fl[0],f_ro[0])),
7724  hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0])),
7725 
7726  hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1])), //8
7727  hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[1],f_fl[1],f_ro[1])),
7728  hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[1],f_fl[1],f_ro[1])),
7729  hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1])),
7730 
7731  hex->face(2)->child_index( child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]), //12
7732  hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
7733 
7734  hex->face(3)->child_index( child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]), //14
7735  hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
7736 
7737  hex->face(4)->child_index( child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]), //16
7738  hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
7739 
7740  hex->face(5)->child_index( child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]), //18
7741  hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
7742  };
7743  quad_indices=&quad_indices_yz[0];
7744 
7745  new_hexes[0]->set (internal::Triangulation
7746  ::TriaObject<3>(quad_indices[4],
7747  quad_indices[8],
7748  quad_indices[12],
7749  quad_indices[2],
7750  quad_indices[16],
7751  quad_indices[0]));
7752  new_hexes[1]->set (internal::Triangulation
7753  ::TriaObject<3>(quad_indices[5],
7754  quad_indices[9],
7755  quad_indices[2],
7756  quad_indices[14],
7757  quad_indices[17],
7758  quad_indices[1]));
7759  new_hexes[2]->set (internal::Triangulation
7760  ::TriaObject<3>(quad_indices[6],
7761  quad_indices[10],
7762  quad_indices[13],
7763  quad_indices[3],
7764  quad_indices[0],
7765  quad_indices[18]));
7766  new_hexes[3]->set (internal::Triangulation
7767  ::TriaObject<3>(quad_indices[7],
7768  quad_indices[11],
7769  quad_indices[3],
7770  quad_indices[15],
7771  quad_indices[1],
7772  quad_indices[19]));
7773  break;
7774  }
7776  {
7778  //
7779  // RefinementCase<dim>::cut_xyz
7780  // isotropic refinement
7781  //
7782  // the refined cube will look
7783  // like this:
7784  //
7785  // *----*----*
7786  // / / /|
7787  // *----*----* |
7788  // / / /| *
7789  // *----*----* |/|
7790  // | | | * |
7791  // | | |/| *
7792  // *----*----* |/
7793  // | | | *
7794  // | | |/
7795  // *----*----*
7796  //
7797 
7798  // find the next unused vertex and set it
7799  // appropriately
7800  while (triangulation.vertices_used[next_unused_vertex] == true)
7801  ++next_unused_vertex;
7802  Assert (next_unused_vertex < triangulation.vertices.size(),
7803  ExcMessage("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."));
7804  triangulation.vertices_used[next_unused_vertex] = true;
7805 
7806  // the new vertex is definitely in the interior,
7807  // so we need not worry about the
7808  // boundary. However we need to worry about
7809  // Manifolds. Let the cell compute its own
7810  // center, by querying the underlying manifold
7811  // object.
7812  triangulation.vertices[next_unused_vertex] =
7813  hex->center(true, true);
7814 
7815  // set the data of the six lines. first collect
7816  // the indices of the seven vertices (consider
7817  // the two planes to be crossed to form the
7818  // planes cutting the hex in two vertically and
7819  // horizontally)
7820  //
7821  // *--3--* *--5--*
7822  // / / / | | |
7823  // 0--6--1 0--6--1
7824  // / / / | | |
7825  // *--2--* *--4--*
7826  // the lines are numbered
7827  // as follows:
7828  // *--*--* *--*--*
7829  // / 1 / | 5 |
7830  // *2-*-3* *2-*-3*
7831  // / 0 / | 4 |
7832  // *--*--* *--*--*
7833  //
7834  const unsigned int vertex_indices_xyz[7]
7835  = { middle_vertex_index<dim,spacedim>(hex->face(0)),
7836  middle_vertex_index<dim,spacedim>(hex->face(1)),
7837  middle_vertex_index<dim,spacedim>(hex->face(2)),
7838  middle_vertex_index<dim,spacedim>(hex->face(3)),
7839  middle_vertex_index<dim,spacedim>(hex->face(4)),
7840  middle_vertex_index<dim,spacedim>(hex->face(5)),
7841  next_unused_vertex
7842  };
7843  vertex_indices=&vertex_indices_xyz[0];
7844 
7845  new_lines[0]->set (internal::Triangulation::
7846  TriaObject<1>(vertex_indices[2], vertex_indices[6]));
7847  new_lines[1]->set (internal::Triangulation::
7848  TriaObject<1>(vertex_indices[6], vertex_indices[3]));
7849  new_lines[2]->set (internal::Triangulation::
7850  TriaObject<1>(vertex_indices[0], vertex_indices[6]));
7851  new_lines[3]->set (internal::Triangulation::
7852  TriaObject<1>(vertex_indices[6], vertex_indices[1]));
7853  new_lines[4]->set (internal::Triangulation::
7854  TriaObject<1>(vertex_indices[4], vertex_indices[6]));
7855  new_lines[5]->set (internal::Triangulation::
7856  TriaObject<1>(vertex_indices[6], vertex_indices[5]));
7857 
7858  // again, first collect some data about the
7859  // indices of the lines, with the following
7860  // numbering: (note that face 0 and 1 each are
7861  // shown twice for better readability)
7862 
7863  // face 0: left plane
7864  // * *
7865  // /| /|
7866  // * | * |
7867  // /| * /| *
7868  // * 1/| * |3|
7869  // | * | | * |
7870  // |/| * |2| *
7871  // * 0/ * |/
7872  // | * | *
7873  // |/ |/
7874  // * *
7875  // face 1: right plane
7876  // * *
7877  // /| /|
7878  // * | * |
7879  // /| * /| *
7880  // * 5/| * |7|
7881  // | * | | * |
7882  // |/| * |6| *
7883  // * 4/ * |/
7884  // | * | *
7885  // |/ |/
7886  // * *
7887  // face 2: front plane
7888  // (note: x,y exchanged)
7889  // *---*---*
7890  // | 11 |
7891  // *-8-*-9-*
7892  // | 10 |
7893  // *---*---*
7894  // face 3: back plane
7895  // (note: x,y exchanged)
7896  // *---*---*
7897  // | 15 |
7898  // *12-*-13*
7899  // | 14 |
7900  // *---*---*
7901  // face 4: bottom plane
7902  // *---*---*
7903  // / 17 /
7904  // *18-*-19*
7905  // / 16 /
7906  // *---*---*
7907  // face 5: top plane
7908  // *---*---*
7909  // / 21 /
7910  // *22-*-23*
7911  // / 20 /
7912  // *---*---*
7913  // middle planes
7914  // *---*---* *---*---*
7915  // / 25 / | 29 |
7916  // *26-*-27* *26-*-27*
7917  // / 24 / | 28 |
7918  // *---*---* *---*---*
7919 
7920  // set up a list of line iterators first. from
7921  // this, construct lists of line_indices and
7922  // line orientations later on
7923  const typename Triangulation<dim,spacedim>::raw_line_iterator
7924  lines_xyz[30]
7925  =
7926  {
7927  hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
7928  ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[0],f_fl[0],f_ro[0])), //0
7929  hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
7930  ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[0],f_fl[0],f_ro[0])), //1
7931  hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
7932  ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[0],f_fl[0],f_ro[0])), //2
7933  hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
7934  ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[0],f_fl[0],f_ro[0])), //3
7935 
7936  hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
7937  ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[1],f_fl[1],f_ro[1])), //4
7938  hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
7939  ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[1],f_fl[1],f_ro[1])), //5
7940  hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
7941  ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[1],f_fl[1],f_ro[1])), //6
7942  hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
7943  ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[1],f_fl[1],f_ro[1])), //7
7944 
7945  hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
7946  ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[2],f_fl[2],f_ro[2])), //8
7947  hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
7948  ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[2],f_fl[2],f_ro[2])), //9
7949  hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
7950  ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[2],f_fl[2],f_ro[2])), //10
7951  hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
7952  ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[2],f_fl[2],f_ro[2])), //11
7953 
7954  hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
7955  ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[3],f_fl[3],f_ro[3])), //12
7956  hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
7957  ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[3],f_fl[3],f_ro[3])), //13
7958  hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
7959  ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[3],f_fl[3],f_ro[3])), //14
7960  hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
7961  ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[3],f_fl[3],f_ro[3])), //15
7962 
7963  hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
7964  ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[4],f_fl[4],f_ro[4])), //16
7965  hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
7966  ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[4],f_fl[4],f_ro[4])), //17
7967  hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
7968  ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[4],f_fl[4],f_ro[4])), //18
7969  hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
7970  ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[4],f_fl[4],f_ro[4])), //19
7971 
7972  hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
7973  ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[5],f_fl[5],f_ro[5])), //20
7974  hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
7975  ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[5],f_fl[5],f_ro[5])), //21
7976  hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
7977  ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[5],f_fl[5],f_ro[5])), //22
7978  hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
7979  ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[5],f_fl[5],f_ro[5])), //23
7980 
7981  new_lines[0], //24
7982  new_lines[1], //25
7983  new_lines[2], //26
7984  new_lines[3], //27
7985  new_lines[4], //28
7986  new_lines[5] //29
7987  };
7988 
7989  lines=&lines_xyz[0];
7990 
7991  unsigned int line_indices_xyz[30];
7992  for (unsigned int i=0; i<30; ++i)
7993  line_indices_xyz[i]=lines[i]->index();
7994  line_indices=&line_indices_xyz[0];
7995 
7996  // the orientation of lines for the inner quads
7997  // is quite tricky. as these lines are newly
7998  // created ones and thus have no parents, they
7999  // cannot inherit this property. set up an array
8000  // and fill it with the respective values
8001  bool line_orientation_xyz[30];
8002 
8003  // note: for the first 24 lines (inner lines of
8004  // the outer quads) the following holds: the
8005  // second vertex of the even lines in standard
8006  // orientation is the vertex in the middle of
8007  // the quad, whereas for odd lines the first
8008  // vertex is the same middle vertex.
8009  for (unsigned int i=0; i<24; ++i)
8010  if (lines[i]->vertex_index((i+1)%2)==vertex_indices[i/4])
8011  line_orientation_xyz[i]=true;
8012  else
8013  {
8014  // it must be the other way
8015  // round then
8016  Assert(lines[i]->vertex_index(i%2)==vertex_indices[i/4],
8017  ExcInternalError());
8018  line_orientation_xyz[i]=false;
8019  }
8020  // for the last 6 lines the line orientation is
8021  // always true, since they were just constructed
8022  // that way
8023  for (unsigned int i=24; i<30; ++i)
8024  line_orientation_xyz[i]=true;
8025  line_orientation=&line_orientation_xyz[0];
8026 
8027  // set up the 12 quads, numbered as follows
8028  // (left quad numbering, right line numbering
8029  // extracted from above)
8030  //
8031  // * *
8032  // /| 21|
8033  // * | * 15
8034  // y/|3* 20| *
8035  // * |/| * |/|
8036  // |2* |x 11 * 14
8037  // |/|1* |/| *
8038  // * |/ * |17
8039  // |0* 10 *
8040  // |/ |16
8041  // * *
8042  //
8043  // x
8044  // *---*---* *22-*-23*
8045  // | 5 | 7 | 1 29 5
8046  // *---*---* *26-*-27*
8047  // | 4 | 6 | 0 28 4
8048  // *---*---*y *18-*-19*
8049  //
8050  // y
8051  // *----*----* *-12-*-13-*
8052  // / 10 / 11 / 3 25 7
8053  // *----*----* *-26-*-27-*
8054  // / 8 / 9 / 2 24 6
8055  // *----*----*x *--8-*--9-*
8056 
8057  new_quads[0]->set (internal::Triangulation
8058  ::TriaObject<2>(line_indices[10],
8059  line_indices[28],
8060  line_indices[16],
8061  line_indices[24]));
8062  new_quads[1]->set (internal::Triangulation
8063  ::TriaObject<2>(line_indices[28],
8064  line_indices[14],
8065  line_indices[17],
8066  line_indices[25]));
8067  new_quads[2]->set (internal::Triangulation
8068  ::TriaObject<2>(line_indices[11],
8069  line_indices[29],
8070  line_indices[24],
8071  line_indices[20]));
8072  new_quads[3]->set (internal::Triangulation
8073  ::TriaObject<2>(line_indices[29],
8074  line_indices[15],
8075  line_indices[25],
8076  line_indices[21]));
8077  new_quads[4]->set (internal::Triangulation
8078  ::TriaObject<2>(line_indices[18],
8079  line_indices[26],
8080  line_indices[0],
8081  line_indices[28]));
8082  new_quads[5]->set (internal::Triangulation
8083  ::TriaObject<2>(line_indices[26],
8084  line_indices[22],
8085  line_indices[1],
8086  line_indices[29]));
8087  new_quads[6]->set (internal::Triangulation
8088  ::TriaObject<2>(line_indices[19],
8089  line_indices[27],
8090  line_indices[28],
8091  line_indices[4]));
8092  new_quads[7]->set (internal::Triangulation
8093  ::TriaObject<2>(line_indices[27],
8094  line_indices[23],
8095  line_indices[29],
8096  line_indices[5]));
8097  new_quads[8]->set (internal::Triangulation
8098  ::TriaObject<2>(line_indices[2],
8099  line_indices[24],
8100  line_indices[8],
8101  line_indices[26]));
8102  new_quads[9]->set (internal::Triangulation
8103  ::TriaObject<2>(line_indices[24],
8104  line_indices[6],
8105  line_indices[9],
8106  line_indices[27]));
8107  new_quads[10]->set (internal::Triangulation
8108  ::TriaObject<2>(line_indices[3],
8109  line_indices[25],
8110  line_indices[26],
8111  line_indices[12]));
8112  new_quads[11]->set (internal::Triangulation
8113  ::TriaObject<2>(line_indices[25],
8114  line_indices[7],
8115  line_indices[27],
8116  line_indices[13]));
8117 
8118  // now reset the line_orientation flags of outer
8119  // lines as they cannot be set in a loop (at
8120  // least not easily)
8121  new_quads[0]->set_line_orientation(0,line_orientation[10]);
8122  new_quads[0]->set_line_orientation(2,line_orientation[16]);
8123 
8124  new_quads[1]->set_line_orientation(1,line_orientation[14]);
8125  new_quads[1]->set_line_orientation(2,line_orientation[17]);
8126 
8127  new_quads[2]->set_line_orientation(0,line_orientation[11]);
8128  new_quads[2]->set_line_orientation(3,line_orientation[20]);
8129 
8130  new_quads[3]->set_line_orientation(1,line_orientation[15]);
8131  new_quads[3]->set_line_orientation(3,line_orientation[21]);
8132 
8133  new_quads[4]->set_line_orientation(0,line_orientation[18]);
8134  new_quads[4]->set_line_orientation(2,line_orientation[0]);
8135 
8136  new_quads[5]->set_line_orientation(1,line_orientation[22]);
8137  new_quads[5]->set_line_orientation(2,line_orientation[1]);
8138 
8139  new_quads[6]->set_line_orientation(0,line_orientation[19]);
8140  new_quads[6]->set_line_orientation(3,line_orientation[4]);
8141 
8142  new_quads[7]->set_line_orientation(1,line_orientation[23]);
8143  new_quads[7]->set_line_orientation(3,line_orientation[5]);
8144 
8145  new_quads[8]->set_line_orientation(0,line_orientation[2]);
8146  new_quads[8]->set_line_orientation(2,line_orientation[8]);
8147 
8148  new_quads[9]->set_line_orientation(1,line_orientation[6]);
8149  new_quads[9]->set_line_orientation(2,line_orientation[9]);
8150 
8151  new_quads[10]->set_line_orientation(0,line_orientation[3]);
8152  new_quads[10]->set_line_orientation(3,line_orientation[12]);
8153 
8154  new_quads[11]->set_line_orientation(1,line_orientation[7]);
8155  new_quads[11]->set_line_orientation(3,line_orientation[13]);
8156 
8158  // create the eight new hexes
8159  //
8160  // again first collect some data. here, we need
8161  // the indices of a whole lotta quads.
8162 
8163  // the quads are numbered as follows:
8164  //
8165  // planes in the interior of the old hex:
8166  //
8167  // *
8168  // /|
8169  // * |
8170  // /|3* *---*---* *----*----*
8171  // * |/| | 5 | 7 | / 10 / 11 /
8172  // |2* | *---*---* *----*----*
8173  // |/|1* | 4 | 6 | / 8 / 9 /
8174  // * |/ *---*---*y *----*----*x
8175  // |0*
8176  // |/
8177  // *
8178  //
8179  // children of the faces
8180  // of the old hex
8181  // *-------* *-------*
8182  // /|25 27| /34 35/|
8183  // 15| | / /19
8184  // / | | /32 33/ |
8185  // * |24 26| *-------*18 |
8186  // 1413*-------* |21 23| 17*
8187  // | /30 31/ | | /
8188  // 12/ / | |16
8189  // |/28 29/ |20 22|/
8190  // *-------* *-------*
8191  //
8192  // note that we have to
8193  // take care of the
8194  // orientation of
8195  // faces.
8196  const int quad_indices_xyz[36]
8197  =
8198  {
8199  new_quads[0]->index(), //0
8200  new_quads[1]->index(),
8201  new_quads[2]->index(),
8202  new_quads[3]->index(),
8203  new_quads[4]->index(),
8204  new_quads[5]->index(),
8205  new_quads[6]->index(),
8206  new_quads[7]->index(),
8207  new_quads[8]->index(),
8208  new_quads[9]->index(),
8209  new_quads[10]->index(),
8210  new_quads[11]->index(), //11
8211 
8212  hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0])), //12
8213  hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[0],f_fl[0],f_ro[0])),
8214  hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[0],f_fl[0],f_ro[0])),
8215  hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0])),
8216 
8217  hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1])), //16
8218  hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[1],f_fl[1],f_ro[1])),
8219  hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[1],f_fl[1],f_ro[1])),
8220  hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1])),
8221 
8222  hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2])), //20
8223  hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[2],f_fl[2],f_ro[2])),
8224  hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[2],f_fl[2],f_ro[2])),
8225  hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2])),
8226 
8227  hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3])), //24
8228  hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[3],f_fl[3],f_ro[3])),
8229  hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[3],f_fl[3],f_ro[3])),
8230  hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3])),
8231 
8232  hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4])), //28
8233  hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[4],f_fl[4],f_ro[4])),
8234  hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[4],f_fl[4],f_ro[4])),
8235  hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4])),
8236 
8237  hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5])), //32
8238  hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[5],f_fl[5],f_ro[5])),
8239  hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[5],f_fl[5],f_ro[5])),
8240  hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
8241  };
8242  quad_indices=&quad_indices_xyz[0];
8243 
8244  // bottom children
8245  new_hexes[0]->set (internal::Triangulation
8246  ::TriaObject<3>(quad_indices[12],
8247  quad_indices[0],
8248  quad_indices[20],
8249  quad_indices[4],
8250  quad_indices[28],
8251  quad_indices[8]));
8252  new_hexes[1]->set (internal::Triangulation
8253  ::TriaObject<3>(quad_indices[0],
8254  quad_indices[16],
8255  quad_indices[22],
8256  quad_indices[6],
8257  quad_indices[29],
8258  quad_indices[9]));
8259  new_hexes[2]->set (internal::Triangulation
8260  ::TriaObject<3>(quad_indices[13],
8261  quad_indices[1],
8262  quad_indices[4],
8263  quad_indices[24],
8264  quad_indices[30],
8265  quad_indices[10]));
8266  new_hexes[3]->set (internal::Triangulation
8267  ::TriaObject<3>(quad_indices[1],
8268  quad_indices[17],
8269  quad_indices[6],
8270  quad_indices[26],
8271  quad_indices[31],
8272  quad_indices[11]));
8273 
8274  // top children
8275  new_hexes[4]->set (internal::Triangulation
8276  ::TriaObject<3>(quad_indices[14],
8277  quad_indices[2],
8278  quad_indices[21],
8279  quad_indices[5],
8280  quad_indices[8],
8281  quad_indices[32]));
8282  new_hexes[5]->set (internal::Triangulation
8283  ::TriaObject<3>(quad_indices[2],
8284  quad_indices[18],
8285  quad_indices[23],
8286  quad_indices[7],
8287  quad_indices[9],
8288  quad_indices[33]));
8289  new_hexes[6]->set (internal::Triangulation
8290  ::TriaObject<3>(quad_indices[15],
8291  quad_indices[3],
8292  quad_indices[5],
8293  quad_indices[25],
8294  quad_indices[10],
8295  quad_indices[34]));
8296  new_hexes[7]->set (internal::Triangulation
8297  ::TriaObject<3>(quad_indices[3],
8298  quad_indices[19],
8299  quad_indices[7],
8300  quad_indices[27],
8301  quad_indices[11],
8302  quad_indices[35]));
8303  break;
8304  }
8305  default:
8306  // all refinement cases have been treated, there
8307  // only remains
8308  // RefinementCase<dim>::no_refinement as
8309  // untreated enumeration value. However, in that
8310  // case we should have aborted much
8311  // earlier. thus we should never get here
8312  Assert(false, ExcInternalError());
8313  break;
8314  }//switch (ref_case)
8315 
8316  // and set face orientation flags. note that new
8317  // faces in the interior of the mother cell always
8318  // have a correctly oriented face, but the ones on
8319  // the outer faces will inherit this flag
8320  //
8321  // the flag have been set to true for all faces
8322  // initially, now go the other way round and reset
8323  // faces that are at the boundary of the mother cube
8324  //
8325  // the same is true for the face_flip and
8326  // face_rotation flags. however, the latter two are
8327  // set to false by default as this is the standard
8328  // value
8329 
8330  // loop over all faces and all (relevant) subfaces
8331  // of that in order to set the correct values for
8332  // face_orientation, face_flip and face_rotation,
8333  // which are inherited from the corresponding face
8334  // of the mother cube
8335  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
8336  for (unsigned int s=0;
8338  1U);
8339  ++s)
8340  {
8341  const unsigned int current_child
8343  f,
8344  s,
8345  f_or[f],
8346  f_fl[f],
8347  f_ro[f],
8349  f,
8350  f_or[f],
8351  f_fl[f],
8352  f_ro[f]));
8353  new_hexes[current_child]->set_face_orientation (f, f_or[f]);
8354  new_hexes[current_child]->set_face_flip (f, f_fl[f]);
8355  new_hexes[current_child]->set_face_rotation (f, f_ro[f]);
8356  }
8357 
8358  // now see if we have created cells that are
8359  // distorted and if so add them to our list
8360  if ((check_for_distorted_cells == true)
8361  &&
8362  has_distorted_children (hex,
8365  cells_with_distorted_children.distorted_cells.push_back (hex);
8366 
8367  // note that the refinement flag was already cleared
8368  // at the beginning of this loop
8369 
8370  // inform all listeners that cell refinement is done
8371  triangulation.signals.post_refinement_on_cell(hex);
8372  }
8373  }
8374 
8375  // clear user data on quads. we used some of this data to
8376  // indicate anisotropic refinemnt cases on faces. all data
8377  // should be cleared by now, but the information whether we
8378  // used indices or pointers is still present. reset it now to
8379  // enable the user to use whichever he likes later on.
8380  triangulation.faces->quads.clear_user_data();
8381 
8382  // return the list with distorted children
8383  return cells_with_distorted_children;
8384  }
8385 
8386 
8399  template <int spacedim>
8400  static
8401  void
8402  prevent_distorted_boundary_cells (const Triangulation<1,spacedim> &);
8403 
8404 
8405  template <int dim, int spacedim>
8406  static
8407  void
8408  prevent_distorted_boundary_cells (Triangulation<dim,spacedim> &triangulation)
8409  {
8410  // If the codimension is one, we cannot perform this check
8411  // yet.
8412  if (spacedim>dim) return;
8413 
8415  cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
8416  if (cell->at_boundary() &&
8417  cell->refine_flag_set() &&
8418  cell->refine_flag_set()!=RefinementCase<dim>::isotropic_refinement)
8419  {
8420  // The cell is at the boundary and it is flagged for
8421  // anisotropic refinement. Therefore, we have a closer
8422  // look
8423  const RefinementCase<dim> ref_case=cell->refine_flag_set();
8424  for (unsigned int face_no=0;
8425  face_no<GeometryInfo<dim>::faces_per_cell;
8426  ++face_no)
8427  if (cell->face(face_no)->at_boundary())
8428  {
8429  // this is the critical face at the boundary.
8430  if (GeometryInfo<dim>::face_refinement_case(ref_case,face_no)
8431  !=RefinementCase<dim-1>::isotropic_refinement)
8432  {
8433  // up to now, we do not want to refine this
8434  // cell along the face under consideration
8435  // here.
8437  face = cell->face(face_no);
8438  // the new point on the boundary would be this
8439  // one.
8440  const Point<spacedim> new_bound
8441  = face->center(true);
8442  // to check it, transform to the unit cell
8443  // with Q1Mapping
8444  const Point<dim> new_unit
8446  transform_real_to_unit_cell(cell,
8447  new_bound);
8448 
8449  // Now, we have to calculate the distance from
8450  // the face in the unit cell.
8451 
8452  // take the correct coordinate direction (0
8453  // for faces 0 and 1, 1 for faces 2 and 3, 2
8454  // for faces 4 and 5) and subtract the correct
8455  // boundary value of the face (0 for faces 0,
8456  // 2, and 4; 1 for faces 1, 3 and 5)
8457  const double dist = std::fabs(new_unit[face_no/2] - face_no%2);
8458 
8459  // compare this with the empirical value
8460  // allowed. if it is too big, flag the face
8461  // for isotropic refinement
8462  const double allowed=0.25;
8463 
8464  if (dist>allowed)
8465  cell->flag_for_face_refinement(face_no);
8466  }//if flagged for anistropic refinement
8467  }//if (cell->face(face)->at_boundary())
8468  }//for all cells
8469  }
8470 
8471 
8484  template <int dim, int spacedim>
8485  static
8486  void
8488  {
8489  Assert (dim < 3,
8490  ExcMessage ("Wrong function called -- there should "
8491  "be a specialization."));
8492  }
8493 
8494 
8495  template <int spacedim>
8496  static
8497  void
8498  prepare_refinement_dim_dependent (Triangulation<3,spacedim> &triangulation)
8499  {
8500  const unsigned int dim = 3;
8501 
8502  // first clear flags on lines, since we need them to determine
8503  // which lines will be refined
8504  triangulation.clear_user_flags_line();
8505 
8506  // also clear flags on hexes, since we need them to mark those
8507  // cells which are to be coarsened
8508  triangulation.clear_user_flags_hex();
8509 
8510  // variable to store whether the mesh was changed in the
8511  // present loop and in the whole process
8512  bool mesh_changed = false;
8513 
8514  do
8515  {
8516  mesh_changed = false;
8517 
8518  // for this following, we need to know which cells are
8519  // going to be coarsened, if we had to make a
8520  // decision. the following function sets these flags:
8521  triangulation.fix_coarsen_flags ();
8522 
8523 
8524  // flag those lines that are refined and will not be
8525  // coarsened and those that will be refined
8527  cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
8528  if (cell->refine_flag_set())
8529  {
8530  for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
8531  if (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(), line)
8533  // flag a line, that will be
8534  // refined
8535  cell->line(line)->set_user_flag();
8536  }
8537  else if (cell->has_children() && !cell->child(0)->coarsen_flag_set())
8538  {
8539  for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
8540  if (GeometryInfo<dim>::line_refinement_case(cell->refinement_case(), line)
8542  // flag a line, that is refined
8543  // and will stay so
8544  cell->line(line)->set_user_flag();
8545  }
8546  else if (cell->has_children() && cell->child(0)->coarsen_flag_set())
8547  cell->set_user_flag();
8548 
8549 
8550  // now check whether there are cells with lines that are
8551  // more than once refined or that will be more than once
8552  // refined. The first thing should never be the case, in
8553  // the second case we flag the cell for refinement
8555  cell=triangulation.last_active(); cell!=triangulation.end(); --cell)
8556  for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
8557  {
8558  if (cell->line(line)->has_children())
8559  {
8560  // if this line is refined, its children should
8561  // not have further children
8562  //
8563  // however, if any of the children is flagged
8564  // for further refinement, we need to refine
8565  // this cell also (at least, if the cell is not
8566  // already flagged)
8567  bool offending_line_found = false;
8568 
8569  for (unsigned int c=0; c<2; ++c)
8570  {
8571  Assert (cell->line(line)->child(c)->has_children() == false,
8572  ExcInternalError());
8573 
8574  if (cell->line(line)->child(c)->user_flag_set () &&
8575  (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(),
8576  line)
8578  {
8579  // tag this cell for refinement
8580  cell->clear_coarsen_flag ();
8581  // if anisotropic coarsening is allowed:
8582  // extend the refine_flag in the needed
8583  // direction, else set refine_flag
8584  // (isotropic)
8585  if (triangulation.smooth_grid &
8587  cell->flag_for_line_refinement(line);
8588  else
8589  cell->set_refine_flag();
8590 
8591  for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
8592  if (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(), line)
8594  // flag a line, that will be refined
8595  cell->line(l)->set_user_flag();
8596 
8597  // note that we have changed the grid
8598  offending_line_found = true;
8599 
8600  // it may save us several loop
8601  // iterations if we flag all lines of
8602  // this cell now (and not at the outset
8603  // of the next iteration) for refinement
8604  for (unsigned int l=0;
8605  l<GeometryInfo<dim>::lines_per_cell; ++l)
8606  if (!cell->line(l)->has_children() &&
8607  (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(),
8608  l)
8610  cell->line(l)->set_user_flag();
8611 
8612  break;
8613  }
8614  }
8615 
8616  if (offending_line_found)
8617  {
8618  mesh_changed = true;
8619  break;
8620  }
8621  }
8622  }
8623 
8624 
8625  // there is another thing here: if any of the lines will
8626  // be refined, then we may not coarsen the present cell
8627  // similarly, if any of the lines *is* already refined, we
8628  // may not coarsen the current cell. however, there's a
8629  // catch: if the line is refined, but the cell behind it
8630  // is going to be coarsened, then the situation
8631  // changes. if we forget this second condition, the
8632  // refine_and_coarsen_3d test will start to fail. note
8633  // that to know which cells are going to be coarsened, the
8634  // call for fix_coarsen_flags above is necessary
8636  cell=triangulation.last(); cell!=triangulation.end(); --cell)
8637  {
8638  if (cell->user_flag_set())
8639  for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
8640  if (cell->line(line)->has_children() &&
8641  (cell->line(line)->child(0)->user_flag_set() ||
8642  cell->line(line)->child(1)->user_flag_set()))
8643  {
8644  for (unsigned int c=0; c<cell->n_children(); ++c)
8645  cell->child(c)->clear_coarsen_flag ();
8646  cell->clear_user_flag();
8647  for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
8648  if (GeometryInfo<dim>::line_refinement_case(cell->refinement_case(), l)
8650  // flag a line, that is refined
8651  // and will stay so
8652  cell->line(l)->set_user_flag();
8653  mesh_changed = true;
8654  break;
8655  }
8656  }
8657  }
8658  while (mesh_changed == true);
8659  }
8660 
8661 
8662 
8669  template <int dim, int spacedim>
8670  static
8671  bool
8673  {
8674  // in 1d, coarsening is always allowed since we don't enforce
8675  // the 2:1 constraint there
8676  if (dim == 1)
8677  return true;
8678 
8679  const RefinementCase<dim> ref_case = cell->refinement_case();
8680  for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
8681  {
8682 
8683  // if the cell is not refined along that face, coarsening
8684  // will not change anything, so do nothing. the same
8685  // applies, if the face is at the boandary
8686  const RefinementCase<dim-1> face_ref_case =
8687  GeometryInfo<dim>::face_refinement_case(cell->refinement_case(), n);
8688 
8689  const unsigned int n_subfaces
8690  = GeometryInfo<dim-1>::n_children(face_ref_case);
8691 
8692  if (n_subfaces == 0 || cell->at_boundary(n))
8693  continue;
8694  for (unsigned int c=0; c<n_subfaces; ++c)
8695  {
8697  child = cell->child(GeometryInfo<dim>::
8698  child_cell_on_face(ref_case,
8699  n,c));
8700 
8702  child_neighbor = child->neighbor(n);
8703  if (!child->neighbor_is_coarser(n))
8704  // in 2d, if the child's neighbor is coarser, then
8705  // it has no children. however, in 3d it might be
8706  // otherwise. consider for example, that our face
8707  // might be refined with cut_x, but the neighbor is
8708  // refined with cut_xy at that face. then the
8709  // neighbor pointers of the children of our cell
8710  // will point to the common neighbor cell, not to
8711  // its children. what we really want to know in the
8712  // following is, whether the neighbor cell is
8713  // refined twice with reference to our cell. that
8714  // only has to be asked, if the child's neighbor is
8715  // not a coarser one.
8716  if ((child_neighbor->has_children() &&
8717  !child_neighbor->user_flag_set())||
8718  // neighbor has children, which are further
8719  // refined along the face, otherwise something
8720  // went wrong in the construction of neighbor
8721  // pointers. then only allow coarsening if this
8722  // neighbor will be coarsened as well
8723  // (user_pointer is set). the same applies, if
8724  // the neighbors children are not refined but
8725  // will be after refinement
8726  child_neighbor->refine_flag_set())
8727  return false;
8728  }
8729  }
8730  return true;
8731  }
8732  };
8733  }
8734 }
8735 
8736 
8737 template <int dim, int spacedim>
8740 
8741 
8742 
8743 template <int dim, int spacedim>
8744 const unsigned int
8746 
8747 
8748 
8749 template <int dim, int spacedim>
8751 Triangulation (const MeshSmoothing smooth_grid,
8752  const bool check_for_distorted_cells)
8753  :
8754  smooth_grid(smooth_grid),
8755  faces(NULL),
8756  anisotropic_refinement(false),
8757  check_for_distorted_cells(check_for_distorted_cells),
8758  vertex_to_boundary_id_map_1d (0),
8759  vertex_to_manifold_id_map_1d (0)
8760 {
8761  if (dim == 1)
8762  {
8764  = new std::map<unsigned int, types::boundary_id>();
8766  = new std::map<unsigned int, types::manifold_id>();
8767  }
8768 
8769  // connect the any_change signal to the other top level signals
8770  signals.create.connect (signals.any_change);
8772  signals.clear.connect (signals.any_change);
8773 }
8774 
8775 
8776 template <int dim, int spacedim>
8779 // do not set any subscriptors;
8780 // anyway, calling this constructor
8781 // is an error!
8782  :
8783  Subscriptor(),
8787 {
8788  Assert (false, ExcMessage ("You are not allowed to call this constructor "
8789  "because copying Triangulation objects is not "
8790  "allowed. Use Triangulation::copy_from() instead."));
8791 }
8792 
8793 
8794 
8795 template <int dim, int spacedim>
8797 {
8798  for (unsigned int i=0; i<levels.size(); ++i)
8799  delete levels[i];
8800  levels.clear ();
8801  delete faces;
8802 
8803  // the vertex_to_boundary_id_map_1d field
8804  // should be unused except in 1d
8805  Assert ((dim == 1)
8806  ||
8808  ExcInternalError());
8810  // the vertex_to_manifold_id_map_1d field
8811  // should be unused except in 1d
8812  Assert ((dim == 1)
8813  ||
8815  ExcInternalError());
8817 }
8818 
8819 
8820 
8821 template <int dim, int spacedim>
8823 {
8825  signals.clear();
8826 }
8827 
8828 
8829 
8830 template <int dim, int spacedim>
8831 void
8833 {
8834  Assert (n_levels() == 0,
8835  ExcTriangulationNotEmpty (vertices.size(), levels.size()));
8836  smooth_grid=mesh_smoothing;
8837 }
8838 
8839 
8840 
8841 template <int dim, int spacedim>
8842 void
8844  const Boundary<dim, spacedim> &boundary_object)
8845 {
8846  set_manifold(m_number, boundary_object);
8847 }
8848 
8849 template <int dim, int spacedim>
8850 void
8852  const Manifold<dim, spacedim> &manifold_object)
8853 {
8855  ExcIndexRange(m_number,0,numbers::invalid_manifold_id));
8856 
8857  manifold[m_number] = &manifold_object;
8858 }
8859 
8860 
8861 template <int dim, int spacedim>
8862 void
8864 {
8865  set_manifold(m_number);
8866 }
8867 
8868 
8869 template <int dim, int spacedim>
8870 void
8872 {
8874  ExcIndexRange(m_number,0,numbers::invalid_manifold_id));
8875 
8876  //delete the entry located at number.
8877  manifold.erase(m_number);
8878 }
8879 
8880 template <int dim, int spacedim>
8881 void
8883 {
8885  cell=this->begin_active(), endc=this->end();
8886 
8887  for (; cell != endc; ++cell)
8888  cell->set_all_manifold_ids(m_number);
8889 }
8890 
8891 
8892 template <int dim, int spacedim>
8893 void
8895 {
8897  cell=this->begin_active(), endc=this->end();
8898 
8899  for (; cell != endc; ++cell)
8900  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
8901  if (cell->face(f)->at_boundary())
8902  cell->face(f)->set_all_manifold_ids(m_number);
8903 }
8904 
8905 
8906 template <int dim, int spacedim>
8907 void
8909  const types::manifold_id m_number)
8910 {
8911  bool boundary_found = false;
8913  cell=this->begin_active(), endc=this->end();
8914 
8915  for (; cell != endc; ++cell)
8916  {
8917  // loop on faces
8918  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
8919  if (cell->face(f)->at_boundary() && cell->face(f)->boundary_id()==b_id)
8920  {
8921  boundary_found = true;
8922  cell->face(f)->set_manifold_id(m_number);
8923  }
8924 
8925  // loop on edges if dim >= 3
8926  if (dim>=3)
8927  for (unsigned int e=0; e<GeometryInfo<dim>::lines_per_cell; ++e)
8928  if (cell->line(e)->at_boundary() && cell->line(e)->boundary_id()==b_id)
8929  {
8930  boundary_found = true;
8931  cell->line(e)->set_manifold_id(m_number);
8932  }
8933  }
8934 
8935  (void)boundary_found;
8936  Assert(boundary_found, ExcBoundaryIdNotFound(b_id));
8937 }
8938 
8939 
8940 template <int dim, int spacedim>
8941 const Boundary<dim,spacedim> &
8943 {
8944  const Boundary<dim, spacedim> *man =
8945  dynamic_cast<const Boundary<dim, spacedim> *>(&get_manifold(m_number));
8946  Assert(man != NULL,
8947  ExcMessage("You tried to get a Boundary, but I only have a Manifold."));
8948 
8949  return *man;
8950 }
8951 
8952 
8953 template <int dim, int spacedim>
8954 const Manifold<dim,spacedim> &
8956 {
8957  //look, if there is a manifold stored at
8958  //manifold_id number.
8959  typename std::map<types::manifold_id, SmartPointer<const Manifold<dim,spacedim>, Triangulation<dim, spacedim> > >::const_iterator it
8960  = manifold.find(m_number);
8961 
8962  if (it != manifold.end())
8963  {
8964  //if we have found an entry, return it
8965  return *(it->second);
8966  }
8967  else
8968  {
8969  //if we have not found an entry connected with number, we return
8970  //straight_boundary
8971  return straight_boundary;
8972  }
8973 }
8974 
8975 
8976 
8977 
8978 template <int dim, int spacedim>
8979 std::vector<types::boundary_id>
8981 {
8982  // in 1d, we store a map of all used boundary indicators. use it for
8983  // our purposes
8984  if (dim == 1)
8985  {
8986  std::vector<types::boundary_id> boundary_ids;
8987  for (std::map<unsigned int, types::boundary_id>::const_iterator
8988  p = vertex_to_boundary_id_map_1d->begin();
8989  p != vertex_to_boundary_id_map_1d->end();
8990  ++p)
8991  boundary_ids.push_back (p->second);
8992 
8993  return boundary_ids;
8994  }
8995  else
8996  {
8997  std::set<types::boundary_id> b_ids;
8999  for (; cell!=end(); ++cell)
9000  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
9001  if (cell->at_boundary(face))
9002  b_ids.insert(cell->face(face)->boundary_id());
9003  std::vector<types::boundary_id> boundary_ids(b_ids.begin(), b_ids.end());
9004  return boundary_ids;
9005  }
9006 }
9007 
9008 
9009 
9010 template <int dim, int spacedim>
9011 std::vector<types::boundary_id>
9013 {
9014  return get_boundary_ids();
9015 }
9016 
9017 
9018 
9019 template <int dim, int spacedim>
9020 std::vector<types::manifold_id>
9022 {
9023  std::set<types::manifold_id> m_ids;
9025  for (; cell!=end(); ++cell)
9026  {
9027  m_ids.insert(cell->manifold_id());
9028  if (dim>1)
9029  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
9030  if (cell->at_boundary(face))
9031  m_ids.insert(cell->face(face)->manifold_id());
9032  }
9033  std::vector<types::manifold_id> manifold_indicators(m_ids.begin(), m_ids.end());
9034  return manifold_indicators;
9035 }
9036 
9037 /*-----------------------------------------------------------------*/
9038 
9039 
9040 template <int dim, int spacedim>
9041 void
9044 {
9045  Assert ((vertices.size() == 0) &&
9046  (levels.size () == 0) &&
9047  (faces == NULL),
9048  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
9049  Assert ((old_tria.levels.size() != 0) &&
9050  (old_tria.vertices.size() != 0) &&
9051  (dim == 1 || old_tria.faces != NULL),
9052  ExcMessage("When calling Triangulation::copy_triangulation(), "
9053  "the target triangulation must be empty but the source "
9054  "triangulation (the argument to this function) must contain "
9055  "something. Here, it seems like the source does not "
9056  "contain anything at all."));
9057 
9058 
9059  // copy normal elements
9060  vertices = old_tria.vertices;
9061  vertices_used = old_tria.vertices_used;
9063  smooth_grid = old_tria.smooth_grid;
9064 
9066 
9067  typename std::map<types::manifold_id,
9069  bdry_iterator = old_tria.manifold.begin();
9070  for (; bdry_iterator != old_tria.manifold.end() ; bdry_iterator++)
9071  manifold[bdry_iterator->first] = bdry_iterator->second;
9072 
9073 
9074  levels.reserve (old_tria.levels.size());
9075  for (unsigned int level=0; level<old_tria.levels.size(); ++level)
9076  levels.push_back (new
9078  TriaLevel<dim>(*old_tria.levels[level]));
9079 
9080  number_cache = old_tria.number_cache;
9081 
9082  if (dim == 1)
9083  {
9086  = (new std::map<unsigned int, types::boundary_id>
9087  (*old_tria.vertex_to_boundary_id_map_1d));
9088 
9091  = (new std::map<unsigned int, types::manifold_id>
9092  (*old_tria.vertex_to_manifold_id_map_1d));
9093  }
9094 
9095  // inform those who are listening on old_tria of the copy operation
9096  old_tria.signals.copy (*this);
9097  // also inform all listeners of the current triangulation that the
9098  // triangulation has been created
9099  signals.create();
9100 
9101  // note that we need not copy the
9102  // subscriptor!
9103 }
9104 
9105 
9106 
9107 template <int dim, int spacedim>
9108 void
9111  const std::vector<CellData<dim> > &cells,
9112  const SubCellData &subcelldata)
9113 {
9114  std::vector<CellData<dim> > reordered_cells (cells);
9115  SubCellData reordered_subcelldata (subcelldata);
9116 
9117  // in-place reordering of data
9118  reorder_compatibility (reordered_cells, reordered_subcelldata);
9119 
9120  // now create triangulation from
9121  // reordered data
9122  create_triangulation(v, reordered_cells, reordered_subcelldata);
9123 }
9124 
9125 
9126 
9127 template <int dim, int spacedim>
9128 void
9130 create_triangulation (const std::vector<Point<spacedim> > &v,
9131  const std::vector<CellData<dim> > &cells,
9132  const SubCellData &subcelldata)
9133 {
9134  Assert ((vertices.size() == 0) &&
9135  (levels.size () == 0) &&
9136  (faces == NULL),
9137  ExcTriangulationNotEmpty(vertices.size(), levels.size()));
9138  // check that no forbidden arrays
9139  // are used
9140  Assert (subcelldata.check_consistency(dim), ExcInternalError());
9141 
9142  // try to create a triangulation; if this fails, we still want to
9143  // throw an exception but if we just do so we'll get into trouble
9144  // because sometimes other objects are already attached to it:
9145  try
9146  {
9148  }
9149  catch (...)
9150  {
9152  throw;
9153  }
9154 
9155  // update our counts of the various elements of a triangulation, and set
9156  // active_cell_indices of all cells
9160 
9161  // now verify that there are indeed no distorted cells. as per the
9162  // documentation of this class, we first collect all distorted cells
9163  // and then throw an exception if there are any
9164  if (check_for_distorted_cells == true)
9165  {
9166  DistortedCellList distorted_cells = collect_distorted_coarse_cells (*this);
9167  // throw the array (and fill the various location fields) if
9168  // there are distorted cells. otherwise, just fall off the end
9169  // of the function
9170  AssertThrow (distorted_cells.distorted_cells.size() == 0,
9171  distorted_cells);
9172  }
9173 
9174 
9175  /*
9176  When the triangulation is a manifold (dim < spacedim), the normal field
9177  provided from the map class depends on the order of the vertices.
9178  It may happen that this normal field is discontinous.
9179  The following code takes care that this is not the case by setting the
9180  cell direction flag on those cell that produce the wrong orientation.
9181 
9182  To determine if 2 neighbours have the same or opposite orientation
9183  we use a table of truth.
9184  Its entries are indexes by the local indeces of the common face.
9185  For example if two elements share a face, and this face is
9186  face 0 for element 0 and face 1 for element 1, then
9187  table(0,1) will tell whether the orientation are the same (true) or
9188  opposite (false).
9189 
9190  Even though there may be a combinatorial/graph theory argument to get
9191  this table in any dimension, I tested by hand all the different possible
9192  cases in 1D and 2D to generate the table.
9193 
9194  Assuming that a surface respects the standard orientation for 2d meshes,
9195  the tables of truth are symmetric and their true values are the following
9196  1D curves: (0,1)
9197  2D surface: (0,1),(0,2),(1,3),(2,3)
9198 
9199  We store this data using an n_faces x n_faces full matrix, which is actually
9200  much bigger than the minimal data required, but it makes the code more readable.
9201 
9202  */
9203  if (dim < spacedim)
9204  {
9207  switch (dim)
9208  {
9209  case 1:
9210  {
9211  bool values [][2] = {{false,true},
9212  {true,false}
9213  };
9214  for (unsigned int i=0; i< GeometryInfo< dim >::faces_per_cell; ++i)
9215  for (unsigned int j=0; j< GeometryInfo< dim >::faces_per_cell; ++j)
9216  correct(i,j) = ( values[i][j]);
9217  break;
9218  }
9219  case 2:
9220  {
9221  bool values [][4]= {{false,true ,true , false},
9222  {true ,false,false, true },
9223  {true ,false,false, true },
9224  {false,true ,true , false}
9225  };
9226  for (unsigned int i=0; i< GeometryInfo< dim >::faces_per_cell; ++i)
9227  for (unsigned int j=0; j< GeometryInfo< dim >::faces_per_cell; ++j)
9228  correct(i,j) = ( values[i][j]);
9229  break;
9230  }
9231  default:
9232  Assert (false, ExcNotImplemented());
9233  }
9234 
9235 
9236  std::list<active_cell_iterator> this_round, next_round;
9237  active_cell_iterator neighbor;
9238 
9239  this_round.push_back (begin_active());
9240  begin_active()->set_direction_flag (true);
9241  begin_active()->set_user_flag ();
9242 
9243  while (this_round.size() > 0)
9244  {
9245  for ( typename std::list<active_cell_iterator>::iterator cell = this_round.begin();
9246  cell != this_round.end(); ++cell)
9247  {
9248  for (unsigned int i = 0; i < GeometryInfo< dim >::faces_per_cell; ++i)
9249  {
9250  if ( !((*cell)->face(i)->at_boundary()) )
9251  {
9252  neighbor = (*cell)->neighbor(i);
9253 
9254  unsigned int cf = (*cell)->face_index(i);
9255  unsigned int j = 0;
9256  while (neighbor->face_index(j) != cf)
9257  {
9258  ++j;
9259  }
9260 
9261  if ( (correct(i,j) && !(*cell)->direction_flag())
9262  ||
9263  (!correct(i,j) && (*cell)->direction_flag()) )
9264  {
9265  if (neighbor->user_flag_set() == false)
9266  {
9267  neighbor->set_direction_flag (false);
9268  neighbor->set_user_flag ();
9269  next_round.push_back (neighbor);
9270  }
9271  else
9272  Assert (neighbor->direction_flag() == false,
9273  ExcNonOrientableTriangulation());
9274 
9275  }
9276  }
9277  }
9278  }
9279 
9280  // Before we quit let's check
9281  // that if the triangulation
9282  // is disconnected that we
9283  // still get all cells
9284  if (next_round.size() == 0)
9285  for (active_cell_iterator cell = begin_active();
9286  cell != end(); ++cell)
9287  if (cell->user_flag_set() == false)
9288  {
9289  next_round.push_back (cell);
9290  cell->set_direction_flag (true);
9291  cell->set_user_flag ();
9292  break;
9293  }
9294 
9295  this_round = next_round;
9296  next_round.clear();
9297  }
9298  }
9299 
9300  // inform all listeners that the triangulation has been created
9301  signals.create();
9302 }
9303 
9304 
9305 
9306 
9307 template <int dim, int spacedim>
9308 void
9311 {
9312  AssertThrow (dim+1 == spacedim, ExcMessage ("Only works for dim == spacedim-1"));
9313  for (active_cell_iterator cell = begin_active();
9314  cell != end(); ++cell)
9315  cell->set_direction_flag (!cell->direction_flag());
9316 }
9317 
9318 
9319 
9320 template <int dim, int spacedim>
9322 {
9323  Assert(n_cells()>0, ExcMessage("Error: An empty Triangulation can not be refined."));
9325  endc = end();
9326 
9327  for (; cell != endc; ++cell)
9328  {
9329  cell->clear_coarsen_flag();
9330  cell->set_refine_flag ();
9331  }
9332 }
9333 
9334 
9335 
9336 template <int dim, int spacedim>
9337 void Triangulation<dim, spacedim>::refine_global (const unsigned int times)
9338 {
9339  for (unsigned int i=0; i<times; ++i)
9340  {
9343  }
9344 }
9345 
9346 
9347 
9348 /*-------------------- refine/coarsen flags -------------------------*/
9349 
9350 
9351 
9352 template <int dim, int spacedim>
9353 void Triangulation<dim, spacedim>::save_refine_flags (std::vector<bool> &v) const
9354 {
9355  v.resize (dim*n_active_cells(), false);
9356  std::vector<bool>::iterator i = v.begin();
9358  endc = end();
9359  for (; cell!=endc; ++cell)
9360  for (unsigned int j=0; j<dim; ++j,++i)
9361  if (cell->refine_flag_set() & (1<<j) )
9362  *i = true;
9363 
9364  Assert (i == v.end(), ExcInternalError());
9365 }
9366 
9367 
9368 
9369 template <int dim, int spacedim>
9371 {
9372  std::vector<bool> v;
9373  save_refine_flags (v);
9374  write_bool_vector (mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end,
9375  out);
9376 }
9377 
9378 
9379 
9380 template <int dim, int spacedim>
9382 {
9383  std::vector<bool> v;
9384  read_bool_vector (mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end,
9385  in);
9386  load_refine_flags (v);
9387 }
9388 
9389 
9390 
9391 template <int dim, int spacedim>
9392 void Triangulation<dim, spacedim>::load_refine_flags (const std::vector<bool> &v)
9393 {
9394  AssertThrow (v.size() == dim*n_active_cells(), ExcGridReadError());
9395 
9397  endc = end();
9398  std::vector<bool>::const_iterator i = v.begin();
9399  for (; cell!=endc; ++cell)
9400  {
9401  unsigned int ref_case=0;
9402 
9403  for (unsigned int j=0; j<dim; ++j, ++i)
9404  if (*i == true)
9405  ref_case+=1<<j;
9407  ExcGridReadError());
9408  if (ref_case>0)
9409  cell->set_refine_flag(RefinementCase<dim>(ref_case));
9410  else
9411  cell->clear_refine_flag();
9412  }
9413 
9414  Assert (i == v.end(), ExcInternalError());
9415 }
9416 
9417 
9418 
9419 template <int dim, int spacedim>
9420 void Triangulation<dim, spacedim>::save_coarsen_flags (std::vector<bool> &v) const
9421 {
9422  v.resize (n_active_cells(), false);
9423  std::vector<bool>::iterator i = v.begin();
9425  endc = end();
9426  for (; cell!=endc; ++cell, ++i)
9427  *i = cell->coarsen_flag_set();
9428 
9429  Assert (i == v.end(), ExcInternalError());
9430 }
9431 
9432 
9433 
9434 template <int dim, int spacedim>
9436 {
9437  std::vector<bool> v;
9438  save_coarsen_flags (v);
9439  write_bool_vector (mn_tria_coarsen_flags_begin, v, mn_tria_coarsen_flags_end,
9440  out);
9441 }
9442 
9443 
9444 
9445 template <int dim, int spacedim>
9447 {
9448  std::vector<bool> v;
9449  read_bool_vector (mn_tria_coarsen_flags_begin, v, mn_tria_coarsen_flags_end,
9450  in);
9451  load_coarsen_flags (v);
9452 }
9453 
9454 
9455 
9456 template <int dim, int spacedim>
9457 void Triangulation<dim, spacedim>::load_coarsen_flags (const std::vector<bool> &v)
9458 {
9459  Assert (v.size() == n_active_cells(), ExcGridReadError());
9460 
9462  endc = end();
9463  std::vector<bool>::const_iterator i = v.begin();
9464  for (; cell!=endc; ++cell, ++i)
9465  if (*i == true)
9466  cell->set_coarsen_flag();
9467  else
9468  cell->clear_coarsen_flag();
9469 
9470  Assert (i == v.end(), ExcInternalError());
9471 }
9472 
9473 
9474 template <int dim, int spacedim>
9476 {
9477  return anisotropic_refinement;
9478 }
9479 
9480 
9481 
9482 /*-------------------- user data/flags -------------------------*/
9483 
9484 
9485 namespace
9486 {
9487  // clear user data of cells
9488  template <int dim>
9490  {
9491  for (unsigned int level=0; level<levels.size(); ++level)
9492  levels[level]->cells.clear_user_data();
9493  }
9494 
9495 
9496  // clear user data of faces
9498  {
9499  // nothing to do in 1d
9500  }
9501 
9502 
9504  {
9505  faces->lines.clear_user_data();
9506  }
9507 
9508 
9510  {
9511  faces->lines.clear_user_data();
9512  faces->quads.clear_user_data();
9513  }
9514 }
9515 
9516 
9517 template <int dim, int spacedim>
9519 {
9520  // let functions in anonymous namespace do their work
9523 }
9524 
9525 
9526 
9527 namespace
9528 {
9531  {
9532  for (unsigned int level=0; level<levels.size(); ++level)
9533  levels[level]->cells.clear_user_flags();
9534  }
9535 
9536  template <int dim>
9539  {
9540  faces->lines.clear_user_flags();
9541  }
9542 }
9543 
9544 
9545 template <int dim, int spacedim>
9547 {
9549 }
9550 
9551 
9552 
9553 namespace
9554 {
9557  {
9558  // nothing to do in 1d
9559  }
9560 
9563  {
9564  for (unsigned int level=0; level<levels.size(); ++level)
9565  levels[level]->cells.clear_user_flags();
9566  }
9567 
9568  template <int dim>
9571  {
9572  faces->quads.clear_user_flags();
9573  }
9574 }
9575 
9576 
9577 template <int dim, int spacedim>
9579 {
9581 }
9582 
9583 
9584 
9585 namespace
9586 {
9589  {
9590  // nothing to do in 1d
9591  }
9592 
9593 
9596  {
9597  // nothing to do in 2d
9598  }
9599 
9602  {
9603  for (unsigned int level=0; level<levels.size(); ++level)
9604  levels[level]->cells.clear_user_flags();
9605  }
9606 }
9607 
9608 
9609 template <int dim, int spacedim>
9611 {
9613 }
9614 
9615 
9616 
9617 template <int dim, int spacedim>
9619 {
9623 }
9624 
9625 
9626 
9627 template <int dim, int spacedim>
9629 {
9630  save_user_flags_line (out);
9631 
9632  if (dim>=2)
9633  save_user_flags_quad (out);
9634 
9635  if (dim>=3)
9636  save_user_flags_hex (out);
9637 
9638  if (dim >= 4)
9639  Assert (false, ExcNotImplemented());
9640 }
9641 
9642 
9643 
9644 template <int dim, int spacedim>
9645 void Triangulation<dim, spacedim>::save_user_flags (std::vector<bool> &v) const
9646 {
9647  // clear vector and append
9648  // all the stuff later on
9649  v.clear ();
9650 
9651  std::vector<bool> tmp;
9652 
9653  save_user_flags_line (tmp);
9654  v.insert (v.end(), tmp.begin(), tmp.end());
9655 
9656  if (dim >= 2)
9657  {
9658  save_user_flags_quad (tmp);
9659  v.insert (v.end(), tmp.begin(), tmp.end());
9660  }
9661 
9662  if (dim >= 3)
9663  {
9664  save_user_flags_hex (tmp);
9665  v.insert (v.end(), tmp.begin(), tmp.end());
9666  }
9667 
9668  if (dim >= 4)
9669  Assert (false, ExcNotImplemented());
9670 }
9671 
9672 
9673 
9674 template <int dim, int spacedim>
9676 {
9677  load_user_flags_line (in);
9678 
9679  if (dim>=2)
9680  load_user_flags_quad (in);
9681 
9682  if (dim>=3)
9683  load_user_flags_hex (in);
9684 
9685  if (dim >= 4)
9686  Assert (false, ExcNotImplemented());
9687 }
9688 
9689 
9690 
9691 template <int dim, int spacedim>
9692 void Triangulation<dim, spacedim>::load_user_flags (const std::vector<bool> &v)
9693 {
9694  Assert (v.size() == n_lines()+n_quads()+n_hexs(), ExcInternalError());
9695  std::vector<bool> tmp;
9696 
9697  // first extract the flags
9698  // belonging to lines
9699  tmp.insert (tmp.end(),
9700  v.begin(), v.begin()+n_lines());
9701  // and set the lines
9702  load_user_flags_line (tmp);
9703 
9704  if (dim >= 2)
9705  {
9706  tmp.clear ();
9707  tmp.insert (tmp.end(),
9708  v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
9709  load_user_flags_quad (tmp);
9710  }
9711 
9712  if (dim >= 3)
9713  {
9714  tmp.clear();
9715  tmp.insert (tmp.end(),
9716  v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
9717  load_user_flags_hex (tmp);
9718  }
9719 
9720  if (dim >= 4)
9721  Assert (false, ExcNotImplemented());
9722 }
9723 
9724 
9725 
9726 template <int dim, int spacedim>
9728 {
9729  v.resize (n_lines(), false);
9730  std::vector<bool>::iterator i = v.begin();
9731  line_iterator line = begin_line(),
9732  endl = end_line();
9733  for (; line!=endl; ++line, ++i)
9734  *i = line->user_flag_set();
9735 
9736  Assert (i == v.end(), ExcInternalError());
9737 }
9738 
9739 
9740 
9741 template <int dim, int spacedim>
9743 {
9744  std::vector<bool> v;
9746  write_bool_vector (mn_tria_line_user_flags_begin, v, mn_tria_line_user_flags_end,
9747  out);
9748 }
9749 
9750 
9751 
9752 template <int dim, int spacedim>
9754 {
9755  std::vector<bool> v;
9756  read_bool_vector (mn_tria_line_user_flags_begin, v, mn_tria_line_user_flags_end,
9757  in);
9759 }
9760 
9761 
9762 
9763 template <int dim, int spacedim>
9765 {
9766  Assert (v.size() == n_lines(), ExcGridReadError());
9767 
9768  line_iterator line = begin_line(),
9769  endl = end_line();
9770  std::vector<bool>::const_iterator i = v.begin();
9771  for (; line!=endl; ++line, ++i)
9772  if (*i == true)
9773  line->set_user_flag();
9774  else
9775  line->clear_user_flag();
9776 
9777  Assert (i == v.end(), ExcInternalError());
9778 }
9779 
9780 
9781 namespace
9782 {
9783  template <typename Iterator>
9784  bool get_user_flag (const Iterator &i)
9785  {
9786  return i->user_flag_set();
9787  }
9788 
9789 
9790 
9791  template <int structdim, int dim, int spacedim>
9792  bool get_user_flag (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &)
9793  {
9794  Assert (false, ExcInternalError());
9795  return false;
9796  }
9797 
9798 
9799 
9800  template <typename Iterator>
9801  void set_user_flag (const Iterator &i)
9802  {
9803  i->set_user_flag();
9804  }
9805 
9806 
9807 
9808  template <int structdim, int dim, int spacedim>
9809  void set_user_flag (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &)
9810  {
9811  Assert (false, ExcInternalError());
9812  }
9813 
9814 
9815 
9816  template <typename Iterator>
9817  void clear_user_flag (const Iterator &i)
9818  {
9819  i->clear_user_flag();
9820  }
9821 
9822 
9823 
9824  template <int structdim, int dim, int spacedim>
9825  void clear_user_flag (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &)
9826  {
9827  Assert (false, ExcInternalError());
9828  }
9829 }
9830 
9831 
9832 template <int dim, int spacedim>
9834 {
9835  v.resize (n_quads(), false);
9836 
9837  if (dim >= 2)
9838  {
9839  std::vector<bool>::iterator i = v.begin();
9840  quad_iterator quad = begin_quad(),
9841  endq = end_quad();
9842  for (; quad!=endq; ++quad, ++i)
9843  *i = get_user_flag (quad);
9844 
9845  Assert (i == v.end(), ExcInternalError());
9846  }
9847 }
9848 
9849 
9850 
9851 template <int dim, int spacedim>
9853 {
9854  std::vector<bool> v;
9856  write_bool_vector (mn_tria_quad_user_flags_begin, v, mn_tria_quad_user_flags_end,
9857  out);
9858 }
9859 
9860 
9861 
9862 template <int dim, int spacedim>
9864 {
9865  std::vector<bool> v;
9866  read_bool_vector (mn_tria_quad_user_flags_begin, v, mn_tria_quad_user_flags_end,
9867  in);
9869 }
9870 
9871 
9872 
9873 template <int dim, int spacedim>
9875 {
9876  Assert (v.size() == n_quads(), ExcGridReadError());
9877 
9878  if (dim >= 2)
9879  {
9880  quad_iterator quad = begin_quad(),
9881  endq = end_quad();
9882  std::vector<bool>::const_iterator i = v.begin();
9883  for (; quad!=endq; ++quad, ++i)
9884  if (*i == true)
9885  set_user_flag(quad);
9886  else
9887  clear_user_flag(quad);
9888 
9889  Assert (i == v.end(), ExcInternalError());
9890  }
9891 }
9892 
9893 
9894 
9895 template <int dim, int spacedim>
9896 void Triangulation<dim, spacedim>::save_user_flags_hex (std::vector<bool> &v) const
9897 {
9898  v.resize (n_hexs(), false);
9899 
9900  if (dim >= 3)
9901  {
9902  std::vector<bool>::iterator i = v.begin();
9903  hex_iterator hex = begin_hex(),
9904  endh = end_hex();
9905  for (; hex!=endh; ++hex, ++i)
9906  *i = get_user_flag (hex);
9907 
9908  Assert (i == v.end(), ExcInternalError());
9909  }
9910 }
9911 
9912 
9913 
9914 template <int dim, int spacedim>
9916 {
9917  std::vector<bool> v;
9918  save_user_flags_hex (v);
9919  write_bool_vector (mn_tria_hex_user_flags_begin, v, mn_tria_hex_user_flags_end,
9920  out);
9921 }
9922 
9923 
9924 
9925 template <int dim, int spacedim>
9927 {
9928  std::vector<bool> v;
9929  read_bool_vector (mn_tria_hex_user_flags_begin, v, mn_tria_hex_user_flags_end,
9930  in);
9931  load_user_flags_hex (v);
9932 }
9933 
9934 
9935 
9936 template <int dim, int spacedim>
9937 void Triangulation<dim, spacedim>::load_user_flags_hex (const std::vector<bool> &v)
9938 {
9939  Assert (v.size() == n_hexs(), ExcGridReadError());
9940 
9941  if (dim >= 3)
9942  {
9943  hex_iterator hex = begin_hex(),
9944  endh = end_hex();
9945  std::vector<bool>::const_iterator i = v.begin();
9946  for (; hex!=endh; ++hex, ++i)
9947  if (*i == true)
9948  set_user_flag(hex);
9949  else
9950  clear_user_flag(hex);
9951 
9952  Assert (i == v.end(), ExcInternalError());
9953  }
9954 }
9955 
9956 
9957 
9958 template <int dim, int spacedim>
9959 void Triangulation<dim, spacedim>::save_user_indices (std::vector<unsigned int> &v) const
9960 {
9961  // clear vector and append all the
9962  // stuff later on
9963  v.clear ();
9964 
9965  std::vector<unsigned int> tmp;
9966 
9967  save_user_indices_line (tmp);
9968  v.insert (v.end(), tmp.begin(), tmp.end());
9969 
9970  if (dim >= 2)
9971  {
9972  save_user_indices_quad (tmp);
9973  v.insert (v.end(), tmp.begin(), tmp.end());
9974  }
9975 
9976  if (dim >= 3)
9977  {
9978  save_user_indices_hex (tmp);
9979  v.insert (v.end(), tmp.begin(), tmp.end());
9980  }
9981 
9982  if (dim >= 4)
9983  Assert (false, ExcNotImplemented());
9984 }
9985 
9986 
9987 
9988 template <int dim, int spacedim>
9989 void Triangulation<dim, spacedim>::load_user_indices (const std::vector<unsigned int> &v)
9990 {
9991  Assert (v.size() == n_lines()+n_quads()+n_hexs(), ExcInternalError());
9992  std::vector<unsigned int> tmp;
9993 
9994  // first extract the indices
9995  // belonging to lines
9996  tmp.insert (tmp.end(),
9997  v.begin(), v.begin()+n_lines());
9998  // and set the lines
9999  load_user_indices_line (tmp);
10000 
10001  if (dim >= 2)
10002  {
10003  tmp.clear ();
10004  tmp.insert (tmp.end(),
10005  v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
10006  load_user_indices_quad (tmp);
10007  }
10008 
10009  if (dim >= 3)
10010  {
10011  tmp.clear ();
10012  tmp.insert (tmp.end(),
10013  v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
10014  load_user_indices_hex (tmp);
10015  }
10016 
10017  if (dim >= 4)
10018  Assert (false, ExcNotImplemented());
10019 }
10020 
10021 
10022 
10023 namespace
10024 {
10025  template <typename Iterator>
10026  unsigned int get_user_index (const Iterator &i)
10027  {
10028  return i->user_index();
10029  }
10030 
10031 
10032 
10033  template <int structdim, int dim, int spacedim>
10034  unsigned int get_user_index (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &)
10035  {
10036  Assert (false, ExcInternalError());
10038  }
10039 
10040 
10041 
10042  template <typename Iterator>
10043  void set_user_index (const Iterator &i,
10044  const unsigned int x)
10045  {
10046  i->set_user_index(x);
10047  }
10048 
10049 
10050 
10051  template <int structdim, int dim, int spacedim>
10052  void set_user_index (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &,
10053  const unsigned int)
10054  {
10055  Assert (false, ExcInternalError());
10056  }
10057 }
10058 
10059 
10060 template <int dim, int spacedim>
10061 void Triangulation<dim, spacedim>::save_user_indices_line (std::vector<unsigned int> &v) const
10062 {
10063  v.resize (n_lines(), 0);
10064  std::vector<unsigned int>::iterator i = v.begin();
10065  line_iterator line = begin_line(),
10066  endl = end_line();
10067  for (; line!=endl; ++line, ++i)
10068  *i = line->user_index();
10069 }
10070 
10071 
10072 
10073 template <int dim, int spacedim>
10074 void Triangulation<dim, spacedim>::load_user_indices_line (const std::vector<unsigned int> &v)
10075 {
10076  Assert (v.size() == n_lines(), ExcGridReadError());
10077 
10078  line_iterator line = begin_line(),
10079  endl = end_line();
10080  std::vector<unsigned int>::const_iterator i = v.begin();
10081  for (; line!=endl; ++line, ++i)
10082  line->set_user_index(*i);
10083 }
10084 
10085 
10086 template <int dim, int spacedim>
10087 void Triangulation<dim, spacedim>::save_user_indices_quad (std::vector<unsigned int> &v) const
10088 {
10089  v.resize (n_quads(), 0);
10090 
10091  if (dim >= 2)
10092  {
10093  std::vector<unsigned int>::iterator i = v.begin();
10094  quad_iterator quad = begin_quad(),
10095  endq = end_quad();
10096  for (; quad!=endq; ++quad, ++i)
10097  *i = get_user_index(quad);
10098  }
10099 }
10100 
10101 
10102 
10103 template <int dim, int spacedim>
10104 void Triangulation<dim, spacedim>::load_user_indices_quad (const std::vector<unsigned int> &v)
10105 {
10106  Assert (v.size() == n_quads(), ExcGridReadError());
10107 
10108  if (dim >= 2)
10109  {
10110  quad_iterator quad = begin_quad(),
10111  endq = end_quad();
10112  std::vector<unsigned int>::const_iterator i = v.begin();
10113  for (; quad!=endq; ++quad, ++i)
10114  set_user_index(quad, *i);
10115  }
10116 }
10117 
10118 
10119 template <int dim, int spacedim>
10120 void Triangulation<dim, spacedim>::save_user_indices_hex (std::vector<unsigned int> &v) const
10121 {
10122  v.resize (n_hexs(), 0);
10123 
10124  if (dim >= 3)
10125  {
10126  std::vector<unsigned int>::iterator i = v.begin();
10127  hex_iterator hex = begin_hex(),
10128  endh = end_hex();
10129  for (; hex!=endh; ++hex, ++i)
10130  *i = get_user_index(hex);
10131  }
10132 }
10133 
10134 
10135 
10136 template <int dim, int spacedim>
10137 void Triangulation<dim, spacedim>::load_user_indices_hex (const std::vector<unsigned int> &v)
10138 {
10139  Assert (v.size() == n_hexs(), ExcGridReadError());
10140 
10141  if (dim >= 3)
10142  {
10143  hex_iterator hex = begin_hex(),
10144  endh = end_hex();
10145  std::vector<unsigned int>::const_iterator i = v.begin();
10146  for (; hex!=endh; ++hex, ++i)
10147  set_user_index(hex, *i);
10148  }
10149 }
10150 
10151 
10152 
10153 //---------------- user pointers ----------------------------------------//
10154 
10155 
10156 namespace
10157 {
10158  template <typename Iterator>
10159  void *get_user_pointer (const Iterator &i)
10160  {
10161  return i->user_pointer();
10162  }
10163 
10164 
10165 
10166  template <int structdim, int dim, int spacedim>
10167  void *get_user_pointer (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &)
10168  {
10169  Assert (false, ExcInternalError());
10170  return 0;
10171  }
10172 
10173 
10174 
10175  template <typename Iterator>
10176  void set_user_pointer (const Iterator &i,
10177  void *x)
10178  {
10179  i->set_user_pointer(x);
10180  }
10181 
10182 
10183 
10184  template <int structdim, int dim, int spacedim>
10185  void set_user_pointer (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &,
10186  void *)
10187  {
10188  Assert (false, ExcInternalError());
10189  }
10190 }
10191 
10192 
10193 template <int dim, int spacedim>
10194 void Triangulation<dim, spacedim>::save_user_pointers (std::vector<void *> &v) const
10195 {
10196  // clear vector and append all the
10197  // stuff later on
10198  v.clear ();
10199 
10200  std::vector<void *> tmp;
10201 
10203  v.insert (v.end(), tmp.begin(), tmp.end());
10204 
10205  if (dim >= 2)
10206  {
10208  v.insert (v.end(), tmp.begin(), tmp.end());
10209  }
10210 
10211  if (dim >= 3)
10212  {
10213  save_user_pointers_hex (tmp);
10214  v.insert (v.end(), tmp.begin(), tmp.end());
10215  }
10216 
10217  if (dim >= 4)
10218  Assert (false, ExcNotImplemented());
10219 }
10220 
10221 
10222 
10223 template <int dim, int spacedim>
10224 void Triangulation<dim, spacedim>::load_user_pointers (const std::vector<void *> &v)
10225 {
10226  Assert (v.size() == n_lines()+n_quads()+n_hexs(), ExcInternalError());
10227  std::vector<void *> tmp;
10228 
10229  // first extract the pointers
10230  // belonging to lines
10231  tmp.insert (tmp.end(),
10232  v.begin(), v.begin()+n_lines());
10233  // and set the lines
10235 
10236  if (dim >= 2)
10237  {
10238  tmp.clear ();
10239  tmp.insert (tmp.end(),
10240  v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
10242  }
10243 
10244  if (dim >= 3)
10245  {
10246  tmp.clear ();
10247  tmp.insert (tmp.end(),
10248  v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
10249  load_user_pointers_hex (tmp);
10250  }
10251 
10252  if (dim >= 4)
10253  Assert (false, ExcNotImplemented());
10254 }
10255 
10256 
10257 
10258 template <int dim, int spacedim>
10260 {
10261  v.resize (n_lines(), 0);
10262  std::vector<void *>::iterator i = v.begin();
10263  line_iterator line = begin_line(),
10264  endl = end_line();
10265  for (; line!=endl; ++line, ++i)
10266  *i = line->user_pointer();
10267 }
10268 
10269 
10270 
10271 template <int dim, int spacedim>
10273 {
10274  Assert (v.size() == n_lines(), ExcGridReadError());
10275 
10276  line_iterator line = begin_line(),
10277  endl = end_line();
10278  std::vector<void *>::const_iterator i = v.begin();
10279  for (; line!=endl; ++line, ++i)
10280  line->set_user_pointer(*i);
10281 }
10282 
10283 
10284 
10285 template <int dim, int spacedim>
10287 {
10288  v.resize (n_quads(), 0);
10289 
10290  if (dim >= 2)
10291  {
10292  std::vector<void *>::iterator i = v.begin();
10293  quad_iterator quad = begin_quad(),
10294  endq = end_quad();
10295  for (; quad!=endq; ++quad, ++i)
10296  *i = get_user_pointer(quad);
10297  }
10298 }
10299 
10300 
10301 
10302 template <int dim, int spacedim>
10304 {
10305  Assert (v.size() == n_quads(), ExcGridReadError());
10306 
10307  if (dim >= 2)
10308  {
10309  quad_iterator quad = begin_quad(),
10310  endq = end_quad();
10311  std::vector<void *>::const_iterator i = v.begin();
10312  for (; quad!=endq; ++quad, ++i)
10313  set_user_pointer(quad, *i);
10314  }
10315 }
10316 
10317 
10318 template <int dim, int spacedim>
10319 void Triangulation<dim, spacedim>::save_user_pointers_hex (std::vector<void *> &v) const
10320 {
10321  v.resize (n_hexs(), 0);
10322 
10323  if (dim >= 3)
10324  {
10325  std::vector<void *>::iterator i = v.begin();
10326  hex_iterator hex = begin_hex(),
10327  endh = end_hex();
10328  for (; hex!=endh; ++hex, ++i)
10329  *i = get_user_pointer(hex);
10330  }
10331 }
10332 
10333 
10334 
10335 template <int dim, int spacedim>
10336 void Triangulation<dim, spacedim>::load_user_pointers_hex (const std::vector<void *> &v)
10337 {
10338  Assert (v.size() == n_hexs(), ExcGridReadError());
10339 
10340  if (dim >= 3)
10341  {
10342  hex_iterator hex = begin_hex(),
10343  endh = end_hex();
10344  std::vector<void *>::const_iterator i = v.begin();
10345  for (; hex!=endh; ++hex, ++i)
10346  set_user_pointer(hex, *i);
10347  }
10348 }
10349 
10350 
10351 
10352 /*------------------------ Cell iterator functions ------------------------*/
10353 
10354 
10355 template <int dim, int spacedim>
10357 Triangulation<dim,spacedim>::begin_raw (const unsigned int level) const
10358 {
10359  switch (dim)
10360  {
10361  case 1:
10362  return begin_raw_line (level);
10363  case 2:
10364  return begin_raw_quad (level);
10365  case 3:
10366  return begin_raw_hex (level);
10367  default:
10368  Assert (false, ExcNotImplemented());
10369  return raw_cell_iterator();
10370  }
10371 }
10372 
10373 
10374 
10375 template <int dim, int spacedim>
10377 Triangulation<dim,spacedim>::begin (const unsigned int level) const
10378 {
10379  switch (dim)
10380  {
10381  case 1:
10382  return begin_line (level);
10383  case 2:
10384  return begin_quad (level);
10385  case 3:
10386  return begin_hex (level);
10387  default:
10388  Assert (false, ExcImpossibleInDim(dim));
10389  return cell_iterator();
10390  }
10391 }
10392 
10393 
10394 
10395 template <int dim, int spacedim>
10397 Triangulation<dim,spacedim>::begin_active (const unsigned int level) const
10398 {
10399  switch (dim)
10400  {
10401  case 1:
10402  return begin_active_line (level);
10403  case 2:
10404  return begin_active_quad (level);
10405  case 3:
10406  return begin_active_hex (level);
10407  default:
10408  Assert (false, ExcNotImplemented());
10409  return active_cell_iterator();
10410  }
10411 }
10412 
10413 
10414 
10415 template <int dim, int spacedim>
10418 {
10419  const unsigned int level = levels.size()-1;
10420 
10421  Assert (level<n_global_levels() || level<levels.size(), ExcInvalidLevel(level));
10422  if (levels[level]->cells.cells.size() ==0)
10423  return end(level);
10424 
10425  // find the last raw iterator on
10426  // this level
10427  raw_cell_iterator ri (const_cast<Triangulation<dim,spacedim>*>(this),
10428  level,
10429  levels[level]->cells.cells.size()-1);
10430 
10431  // then move to the last used one
10432  if (ri->used()==true)
10433  return ri;
10434  while ((--ri).state() == IteratorState::valid)
10435  if (ri->used()==true)
10436  return ri;
10437  return ri;
10438 }
10439 
10440 
10441 
10442 template <int dim, int spacedim>
10445 {
10446  // get the last used cell
10447  cell_iterator cell = last();
10448 
10449  if (cell != end())
10450  {
10451  // then move to the last active one
10452  if (cell->active()==true)
10453  return cell;
10454  while ((--cell).state() == IteratorState::valid)
10455  if (cell->active()==true)
10456  return cell;
10457  }
10458  return cell;
10459 }
10460 
10461 
10462 
10463 template <int dim, int spacedim>
10466 {
10467  return cell_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
10468  -1,
10469  -1);
10470 }
10471 
10472 
10473 
10474 template <int dim, int spacedim>
10476 Triangulation<dim, spacedim>::end_raw (const unsigned int level) const
10477 {
10478  Assert (level<n_global_levels(), ExcInvalidLevel(level));
10479  if (level < levels.size()-1)
10480  return begin_raw (level+1);
10481  else
10482  return end();
10483 }
10484 
10485 
10486 template <int dim, int spacedim>
10488 Triangulation<dim, spacedim>::end (const unsigned int level) const
10489 {
10490  if (level < levels.size()-1)
10491  return begin (level+1);
10492  Assert (level<n_global_levels() || level<levels.size(), ExcInvalidLevel(level));
10493  return end();
10494 }
10495 
10496 
10497 template <int dim, int spacedim>
10499 Triangulation<dim, spacedim>::end_active (const unsigned int level) const
10500 {
10501  Assert (level<n_global_levels() || level < levels.size(), ExcInvalidLevel(level));
10502  return (level >= levels.size()-1 ?
10504  begin_active (level+1));
10505 }
10506 
10507 
10508 
10509 template <int dim, int spacedim>
10512 {
10513  return
10515  (begin(), end());
10516 }
10517 
10518 
10519 template <int dim, int spacedim>
10522 {
10523  return
10525  (begin_active(), end());
10526 }
10527 
10528 
10529 
10530 template <int dim, int spacedim>
10533 {
10534  return
10536  (begin(level), end(level));
10537 }
10538 
10539 
10540 
10541 template <int dim, int spacedim>
10544 {
10545  return
10547  (begin_active(level), end_active(level));
10548 }
10549 
10550 
10551 /*------------------------ Face iterator functions ------------------------*/
10552 
10553 
10554 template <int dim, int spacedim>
10557 {
10558  switch (dim)
10559  {
10560  case 1:
10561  Assert (false, ExcImpossibleInDim(1));
10562  return raw_face_iterator();
10563  case 2:
10564  return begin_line ();
10565  case 3:
10566  return begin_quad ();
10567  default:
10568  Assert (false, ExcNotImplemented());
10569  return face_iterator ();
10570  }
10571 }
10572 
10573 
10574 
10575 template <int dim, int spacedim>
10578 {
10579  switch (dim)
10580  {
10581  case 1:
10582  Assert (false, ExcImpossibleInDim(1));
10583  return raw_face_iterator();
10584  case 2:
10585  return begin_active_line ();
10586  case 3:
10587  return begin_active_quad ();
10588  default:
10589  Assert (false, ExcNotImplemented());
10590  return active_face_iterator ();
10591  }
10592 }
10593 
10594 
10595 
10596 template <int dim, int spacedim>
10599 {
10600  switch (dim)
10601  {
10602  case 1:
10603  Assert (false, ExcImpossibleInDim(1));
10604  return raw_face_iterator();
10605  case 2:
10606  return end_line ();
10607  case 3:
10608  return end_quad ();
10609  default:
10610  Assert (false, ExcNotImplemented());
10611  return raw_face_iterator ();
10612  }
10613 }
10614 
10615 
10616 /*------------------------ Vertex iterator functions ------------------------*/
10617 
10618 
10619 template <int dim, int spacedim>
10620 typename Triangulation<dim,spacedim>::vertex_iterator
10622 {
10623  if (dim==1)
10624  {
10625  // This does not work if dim==1 because TriaAccessor<0,1,spacedim> does not
10626  // implement operator++
10627  Assert(false, ExcNotImplemented());
10628  return raw_vertex_iterator();
10629  }
10630  else
10631  {
10632  vertex_iterator i = raw_vertex_iterator(const_cast<Triangulation<dim, spacedim>*>(this),
10633  0,
10634  0);
10635  if (i.state() != IteratorState::valid)
10636  return i;
10637  // This loop will end because every triangulation has used vertices.
10638  while (i->used() == false)
10639  if ((++i).state() != IteratorState::valid)
10640  return i;
10641  return i;
10642  }
10643 }
10644 
10645 
10646 
10647 template <int dim, int spacedim>
10648 typename Triangulation<dim,spacedim>::active_vertex_iterator
10650 {
10651  return begin_vertex();
10652 }
10653 
10654 
10655 
10656 template <int dim, int spacedim>
10657 typename Triangulation<dim,spacedim>::vertex_iterator
10659 {
10660  if (dim==1)
10661  {
10662  Assert(false, ExcNotImplemented());
10663  return raw_vertex_iterator();
10664  }
10665  else
10666  return raw_vertex_iterator(const_cast<Triangulation<dim, spacedim>*>(this),
10667  -1,
10669 }
10670 
10671 
10672 
10673 
10674 /*------------------------ Line iterator functions ------------------------*/
10675 
10676 
10677 
10678 template <int dim, int spacedim>
10679 typename Triangulation<dim, spacedim>::raw_line_iterator
10680 Triangulation<dim, spacedim>::begin_raw_line (const unsigned int level) const
10681 {
10682  switch (dim)
10683  {
10684  case 1:
10685  Assert (level<n_global_levels() || level<levels.size(), ExcInvalidLevel(level));
10686 
10687  if (level >= levels.size() || levels[level]->cells.cells.size() == 0)
10688  return end_line();
10689 
10690  return raw_line_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
10691  level,
10692  0);
10693 
10694  default:
10695  Assert (level == 0, ExcFacesHaveNoLevel());
10696  return raw_line_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
10697  0,
10698  0);
10699  }
10700 }
10701 
10702 
10703 template <int dim, int spacedim>
10704 typename Triangulation<dim, spacedim>::line_iterator
10705 Triangulation<dim, spacedim>::begin_line (const unsigned int level) const
10706 {
10707  // level is checked in begin_raw
10708  raw_line_iterator ri = begin_raw_line (level);
10709  if (ri.state() != IteratorState::valid)
10710  return ri;
10711  while (ri->used() == false)
10712  if ((++ri).state() != IteratorState::valid)
10713  return ri;
10714  return ri;
10715 }
10716 
10717 
10718 
10719 template <int dim, int spacedim>
10720 typename Triangulation<dim, spacedim>::active_line_iterator
10721 Triangulation<dim, spacedim>::begin_active_line (const unsigned int level) const
10722 {
10723  // level is checked in begin_raw
10724  line_iterator i = begin_line (level);
10725  if (i.state() != IteratorState::valid)
10726  return i;
10727  while (i->has_children())
10728  if ((++i).state() != IteratorState::valid)
10729  return i;
10730  return i;
10731 }
10732 
10733 
10734 
10735 template <int dim, int spacedim>
10736 typename Triangulation<dim, spacedim>::line_iterator
10738 {
10739  return raw_line_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
10740  -1,
10741  -1);
10742 }
10743 
10744 
10745 
10746 /*------------------------ Quad iterator functions ------------------------*/
10747 
10748 
10749 template <int dim, int spacedim>
10750 typename Triangulation<dim,spacedim>::raw_quad_iterator
10751 Triangulation<dim,spacedim>::begin_raw_quad (const unsigned int level) const
10752 {
10753  switch (dim)
10754  {
10755  case 1:
10756  Assert (false, ExcImpossibleInDim(1));
10757  return raw_hex_iterator();
10758  case 2:
10759  {
10760  Assert (level<n_global_levels() || level<levels.size(), ExcInvalidLevel(level));
10761 
10762  if (level >= levels.size() || levels[level]->cells.cells.size() == 0)
10763  return end_quad();
10764 
10765  return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
10766  level,
10767  0);
10768  }
10769 
10770  case 3:
10771  {
10772  Assert (level == 0, ExcFacesHaveNoLevel());
10773 
10774  return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
10775  0,
10776  0);
10777  }
10778 
10779 
10780  default:
10781  Assert (false, ExcNotImplemented());
10782  return raw_hex_iterator();
10783  }
10784 }
10785 
10786 
10787 
10788 template <int dim, int spacedim>
10789 typename Triangulation<dim,spacedim>::quad_iterator
10790 Triangulation<dim,spacedim>::begin_quad (const unsigned int level) const
10791 {
10792  // level is checked in begin_raw
10793  raw_quad_iterator ri = begin_raw_quad (level);
10794  if (ri.state() != IteratorState::valid)
10795  return ri;
10796  while (ri->used() == false)
10797  if ((++ri).state() != IteratorState::valid)
10798  return ri;
10799  return ri;
10800 }
10801 
10802 
10803 
10804 template <int dim, int spacedim>
10805 typename Triangulation<dim,spacedim>::active_quad_iterator
10806 Triangulation<dim,spacedim>::begin_active_quad (const unsigned int level) const
10807 {
10808  // level is checked in begin_raw
10809  quad_iterator i = begin_quad (level);
10810  if (i.state() != IteratorState::valid)
10811  return i;
10812  while (i->has_children())
10813  if ((++i).state() != IteratorState::valid)
10814  return i;
10815  return i;
10816 }
10817 
10818 
10819 
10820 template <int dim, int spacedim>
10821 typename Triangulation<dim,spacedim>::quad_iterator
10823 {
10824  return raw_quad_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
10825  -1,
10826  -1);
10827 }
10828 
10829 
10830 /*------------------------ Hex iterator functions ------------------------*/
10831 
10832 
10833 template <int dim, int spacedim>
10834 typename Triangulation<dim,spacedim>::raw_hex_iterator
10835 Triangulation<dim,spacedim>::begin_raw_hex (const unsigned int level) const
10836 {
10837  switch (dim)
10838  {
10839  case 1:
10840  case 2:
10841  Assert (false, ExcImpossibleInDim(1));
10842  return raw_hex_iterator();
10843  case 3:
10844  {
10845  Assert (level<n_global_levels() || level<levels.size(), ExcInvalidLevel(level));
10846 
10847  if (level >= levels.size() || levels[level]->cells.cells.size() == 0)
10848  return end_hex();
10849 
10850  return raw_hex_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
10851  level,
10852  0);
10853  }
10854 
10855  default:
10856  Assert (false, ExcNotImplemented());
10857  return raw_hex_iterator();
10858  }
10859 }
10860 
10861 
10862 
10863 template <int dim, int spacedim>
10864 typename Triangulation<dim,spacedim>::hex_iterator
10865 Triangulation<dim,spacedim>::begin_hex (const unsigned int level) const
10866 {
10867  // level is checked in begin_raw
10868  raw_hex_iterator ri = begin_raw_hex (level);
10869  if (ri.state() != IteratorState::valid)
10870  return ri;
10871  while (ri->used() == false)
10872  if ((++ri).state() != IteratorState::valid)
10873  return ri;
10874  return ri;
10875 }
10876 
10877 
10878 
10879 template <int dim, int spacedim>
10880 typename Triangulation<dim, spacedim>::active_hex_iterator
10881 Triangulation<dim, spacedim>::begin_active_hex (const unsigned int level) const
10882 {
10883  // level is checked in begin_raw
10884  hex_iterator i = begin_hex (level);
10885  if (i.state() != IteratorState::valid)
10886  return i;
10887  while (i->has_children())
10888  if ((++i).state() != IteratorState::valid)
10889  return i;
10890  return i;
10891 }
10892 
10893 
10894 
10895 template <int dim, int spacedim>
10896 typename Triangulation<dim, spacedim>::hex_iterator
10898 {
10899  return raw_hex_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
10900  -1,
10901  -1);
10902 }
10903 
10904 
10905 
10906 
10907 // -------------------------------- number of cells etc ---------------
10908 
10909 
10910 namespace internal
10911 {
10912  namespace Triangulation
10913  {
10914  inline
10915  unsigned int
10917  {
10918  return c.n_lines;
10919  }
10920 
10921 
10922  inline
10923  unsigned int
10925  {
10926  return c.n_active_lines;
10927  }
10928 
10929 
10930  inline
10931  unsigned int
10933  {
10934  return c.n_quads;
10935  }
10936 
10937 
10938  inline
10939  unsigned int
10941  {
10942  return c.n_active_quads;
10943  }
10944 
10945 
10946  inline
10947  unsigned int
10949  {
10950  return c.n_hexes;
10951  }
10952 
10953 
10954  inline
10955  unsigned int
10957  {
10958  return c.n_active_hexes;
10959  }
10960  }
10961 }
10962 
10963 
10964 
10965 template <int dim, int spacedim>
10967 {
10968  return internal::Triangulation::n_cells (number_cache);
10969 }
10970 
10971 
10972 template <int dim, int spacedim>
10974 {
10975  return internal::Triangulation::n_active_cells (number_cache);
10976 }
10977 
10978 template <int dim, int spacedim>
10980 {
10981  return n_active_cells();
10982 }
10983 
10984 
10985 
10986 template <int dim, int spacedim>
10988 {
10989  switch (dim)
10990  {
10991  case 1:
10992  return 0;
10993  case 2:
10994  return n_lines();
10995  case 3:
10996  return n_quads();
10997  default:
10998  Assert (false, ExcNotImplemented());
10999  }
11000  return 0;
11001 }
11002 
11003 
11004 template <int dim, int spacedim>
11006 {
11007  switch (dim)
11008  {
11009  case 2:
11010  return n_raw_lines();
11011  case 3:
11012  return n_raw_quads();
11013  default:
11014  Assert (false, ExcNotImplemented());
11015  }
11016  return 0;
11017 }
11018 
11019 
11020 template <int dim, int spacedim>
11022 {
11023  switch (dim)
11024  {
11025  case 1:
11026  return 0;
11027  case 2:
11028  return n_active_lines();
11029  case 3:
11030  return n_active_quads();
11031  default:
11032  Assert (false, ExcNotImplemented());
11033  }
11034  return 0;
11035 }
11036 
11037 
11038 template <int dim, int spacedim>
11039 unsigned int Triangulation<dim, spacedim>::n_raw_cells (const unsigned int level) const
11040 {
11041  switch (dim)
11042  {
11043  case 1:
11044  return n_raw_lines(level);
11045  case 2:
11046  return n_raw_quads(level);
11047  case 3:
11048  return n_raw_hexs(level);
11049  default:
11050  Assert (false, ExcNotImplemented());
11051  }
11052  return 0;
11053 }
11054 
11055 
11056 
11057 template <int dim, int spacedim>
11058 unsigned int Triangulation<dim, spacedim>::n_cells (const unsigned int level) const
11059 {
11060  switch (dim)
11061  {
11062  case 1:
11063  return n_lines(level);
11064  case 2:
11065  return n_quads(level);
11066  case 3:
11067  return n_hexs(level);
11068  default:
11069  Assert (false, ExcNotImplemented());
11070  }
11071  return 0;
11072 }
11073 
11074 
11075 
11076 template <int dim, int spacedim>
11077 unsigned int Triangulation<dim, spacedim>::n_active_cells (const unsigned int level) const
11078 {
11079  switch (dim)
11080  {
11081  case 1:
11082  return n_active_lines(level);
11083  case 2:
11084  return n_active_quads(level);
11085  case 3:
11086  return n_active_hexs(level);
11087  default:
11088  Assert (false, ExcNotImplemented());
11089  }
11090  return 0;
11091 }
11092 
11093 
11094 template <int dim, int spacedim>
11096 {
11097  for (unsigned int lvl = 0; lvl<n_global_levels()-1; lvl++)
11098  if (n_active_cells(lvl) != 0)
11099  return true;
11100 
11101  return false;
11102 }
11103 
11104 
11105 template <int dim, int spacedim>
11107 {
11108  return number_cache.n_lines;
11109 }
11110 
11111 
11112 //TODO: Merge the following 6 functions somehow
11113 template <>
11114 unsigned int Triangulation<1,1>::n_raw_lines (const unsigned int level) const
11115 {
11116  Assert(level < n_levels(), ExcIndexRange(level,0,n_levels()));
11117  return levels[level]->cells.cells.size();
11118 }
11119 
11120 
11121 template <>
11122 unsigned int Triangulation<1,1>::n_raw_lines () const
11123 {
11124  Assert(false, ExcNotImplemented());
11125  return 0;
11126 }
11127 
11128 
11129 
11130 template <>
11131 unsigned int Triangulation<1,2>::n_raw_lines (const unsigned int level) const
11132 {
11133  Assert(level < n_levels(), ExcIndexRange(level,0,n_levels()));
11134  return levels[level]->cells.cells.size();
11135 }
11136 
11137 
11138 template <>
11139 unsigned int Triangulation<1,2>::n_raw_lines () const
11140 {
11141  Assert(false, ExcNotImplemented());
11142  return 0;
11143 }
11144 
11145 
11146 template <>
11147 unsigned int Triangulation<1,3>::n_raw_lines (const unsigned int level) const
11148 {
11149  Assert(level < n_levels(), ExcIndexRange(level,0,n_levels()));
11150  return levels[level]->cells.cells.size();
11151 }
11152 
11153 template <>
11154 unsigned int Triangulation<1,3>::n_raw_lines () const
11155 {
11156  Assert(false, ExcNotImplemented());
11157  return 0;
11158 }
11159 
11160 
11161 
11162 template <int dim, int spacedim>
11163 unsigned int Triangulation<dim, spacedim>::n_raw_lines (const unsigned int) const
11164 {
11165  Assert(false, ExcFacesHaveNoLevel());
11166  return 0;
11167 }
11168 
11169 
11170 template <int dim, int spacedim>
11172 {
11173  return faces->lines.cells.size();
11174 }
11175 
11176 
11177 template <int dim, int spacedim>
11178 unsigned int Triangulation<dim, spacedim>::n_lines (const unsigned int level) const
11179 {
11180  Assert (level < number_cache.n_lines_level.size(),
11181  ExcIndexRange (level, 0, number_cache.n_lines_level.size()));
11182  Assert (dim == 1, ExcFacesHaveNoLevel());
11183  return number_cache.n_lines_level[level];
11184 }
11185 
11186 
11187 template <int dim, int spacedim>
11189 {
11190  return number_cache.n_active_lines;
11191 }
11192 
11193 
11194 template <int dim, int spacedim>
11195 unsigned int Triangulation<dim, spacedim>::n_active_lines (const unsigned int level) const
11196 {
11197  Assert (level < number_cache.n_lines_level.size(),
11198  ExcIndexRange (level, 0, number_cache.n_lines_level.size()));
11199  Assert (dim == 1, ExcFacesHaveNoLevel());
11200 
11201  return number_cache.n_active_lines_level[level];
11202 }
11203 
11204 
11205 template <>
11206 unsigned int Triangulation<1,1>::n_quads () const
11207 {
11208  return 0;
11209 }
11210 
11211 
11212 template <>
11213 unsigned int Triangulation<1,1>::n_quads (const unsigned int) const
11214 {
11215  return 0;
11216 }
11217 
11218 
11219 template <>
11220 unsigned int Triangulation<1,1>::n_raw_quads (const unsigned int) const
11221 {
11222  return 0;
11223 }
11224 
11225 
11226 template <>
11227 unsigned int Triangulation<1,1>::n_raw_hexs (const unsigned int) const
11228 {
11229  return 0;
11230 }
11231 
11232 
11233 template <>
11234 unsigned int Triangulation<1,1>::n_active_quads (const unsigned int) const
11235 {
11236  return 0;
11237 }
11238 
11239 
11240 template <>
11241 unsigned int Triangulation<1,1>::n_active_quads () const
11242 {
11243  return 0;
11244 }
11245 
11246 
11247 
11248 
11249 template <>
11250 unsigned int Triangulation<1,2>::n_quads () const
11251 {
11252  return 0;
11253 }
11254 
11255 
11256 template <>
11257 unsigned int Triangulation<1,2>::n_quads (const unsigned int) const
11258 {
11259  return 0;
11260 }
11261 
11262 
11263 template <>
11264 unsigned int Triangulation<1,2>::n_raw_quads (const unsigned int) const
11265 {
11266  return 0;
11267 }
11268 
11269 
11270 template <>
11271 unsigned int Triangulation<1,2>::n_raw_hexs (const unsigned int) const
11272 {
11273  return 0;
11274 }
11275 
11276 
11277 template <>
11278 unsigned int Triangulation<1,2>::n_active_quads (const unsigned int) const
11279 {
11280  return 0;
11281 }
11282 
11283 
11284 template <>
11285 unsigned int Triangulation<1,2>::n_active_quads () const
11286 {
11287  return 0;
11288 }
11289 
11290 
11291 template <>
11292 unsigned int Triangulation<1,3>::n_quads () const
11293 {
11294  return 0;
11295 }
11296 
11297 
11298 template <>
11299 unsigned int Triangulation<1,3>::n_quads (const unsigned int) const
11300 {
11301  return 0;
11302 }
11303 
11304 
11305 template <>
11306 unsigned int Triangulation<1,3>::n_raw_quads (const unsigned int) const
11307 {
11308  return 0;
11309 }
11310 
11311 
11312 template <>
11313 unsigned int Triangulation<1,3>::n_raw_hexs (const unsigned int) const
11314 {
11315  return 0;
11316 }
11317 
11318 
11319 template <>
11320 unsigned int Triangulation<1,3>::n_active_quads (const unsigned int) const
11321 {
11322  return 0;
11323 }
11324 
11325 
11326 template <>
11327 unsigned int Triangulation<1,3>::n_active_quads () const
11328 {
11329  return 0;
11330 }
11331 
11332 
11333 
11334 template <int dim, int spacedim>
11336 {
11337  return number_cache.n_quads;
11338 }
11339 
11340 
11341 template <int dim, int spacedim>
11342 unsigned int Triangulation<dim, spacedim>::n_quads (const unsigned int level) const
11343 {
11344  Assert (dim == 2, ExcFacesHaveNoLevel());
11345  Assert (level < number_cache.n_quads_level.size(),
11346  ExcIndexRange (level, 0, number_cache.n_quads_level.size()));
11347  return number_cache.n_quads_level[level];
11348 }
11349 
11350 
11351 
11352 template <>
11353 unsigned int Triangulation<2,2>::n_raw_quads (const unsigned int level) const
11354 {
11355  Assert(level < n_levels(), ExcIndexRange(level,0,n_levels()));
11356  return levels[level]->cells.cells.size();
11357 }
11358 
11359 
11360 
11361 template <>
11362 unsigned int Triangulation<2,3>::n_raw_quads (const unsigned int level) const
11363 {
11364  Assert(level < n_levels(), ExcIndexRange(level,0,n_levels()));
11365  return levels[level]->cells.cells.size();
11366 }
11367 
11368 
11369 template <>
11370 unsigned int Triangulation<3,3>::n_raw_quads (const unsigned int) const
11371 {
11372  Assert(false, ExcFacesHaveNoLevel());
11373  return 0;
11374 }
11375 
11376 
11377 
11378 
11379 
11380 template <int dim, int spacedim>
11382 {
11383  Assert (false, ExcNotImplemented());
11384  return 0;
11385 }
11386 
11387 
11388 
11389 template <>
11390 unsigned int Triangulation<3,3>::n_raw_quads () const
11391 {
11392  return faces->quads.cells.size();
11393 }
11394 
11395 
11396 
11397 template <int dim, int spacedim>
11399 {
11400  return number_cache.n_active_quads;
11401 }
11402 
11403 
11404 template <int dim, int spacedim>
11405 unsigned int Triangulation<dim, spacedim>::n_active_quads (const unsigned int level) const
11406 {
11407  Assert (level < number_cache.n_quads_level.size(),
11408  ExcIndexRange (level, 0, number_cache.n_quads_level.size()));
11409  Assert (dim == 2, ExcFacesHaveNoLevel());
11410 
11411  return number_cache.n_active_quads_level[level];
11412 }
11413 
11414 
11415 template <int dim, int spacedim>
11417 {
11418  return 0;
11419 }
11420 
11421 
11422 
11423 template <int dim, int spacedim>
11424 unsigned int Triangulation<dim, spacedim>::n_hexs (const unsigned int) const
11425 {
11426  return 0;
11427 }
11428 
11429 
11430 
11431 template <int dim, int spacedim>
11432 unsigned int Triangulation<dim, spacedim>::n_raw_hexs (const unsigned int) const
11433 {
11434  return 0;
11435 }
11436 
11437 
11438 template <int dim, int spacedim>
11440 {
11441  return 0;
11442 }
11443 
11444 
11445 
11446 template <int dim, int spacedim>
11447 unsigned int Triangulation<dim, spacedim>::n_active_hexs (const unsigned int) const
11448 {
11449  return 0;
11450 }
11451 
11452 
11453 template <>
11454 unsigned int Triangulation<3,3>::n_hexs () const
11455 {
11456  return number_cache.n_hexes;
11457 }
11458 
11459 
11460 
11461 template <>
11462 unsigned int Triangulation<3,3>::n_hexs (const unsigned int level) const
11463 {
11464  Assert (level < number_cache.n_hexes_level.size(),
11465  ExcIndexRange (level, 0, number_cache.n_hexes_level.size()));
11466 
11467  return number_cache.n_hexes_level[level];
11468 }
11469 
11470 
11471 
11472 template <>
11473 unsigned int Triangulation<3,3>::n_raw_hexs (const unsigned int level) const
11474 {
11475  Assert(level < n_levels(), ExcIndexRange(level,0,n_levels()));
11476  return levels[level]->cells.cells.size();
11477 }
11478 
11479 
11480 template <>
11481 unsigned int Triangulation<3,3>::n_active_hexs () const
11482 {
11483  return number_cache.n_active_hexes;
11484 }
11485 
11486 
11487 
11488 template <>
11489 unsigned int Triangulation<3,3>::n_active_hexs (const unsigned int level) const
11490 {
11491  Assert (level < number_cache.n_hexes_level.size(),
11492  ExcIndexRange (level, 0, number_cache.n_hexes_level.size()));
11493 
11494  return number_cache.n_active_hexes_level[level];
11495 }
11496 
11497 
11498 
11499 template <int dim, int spacedim>
11500 unsigned int
11502 {
11503  return std::count_if (vertices_used.begin(), vertices_used.end(),
11504  std::bind2nd (std::equal_to<bool>(), true));
11505 }
11506 
11507 
11508 
11509 template <int dim, int spacedim>
11510 const std::vector<bool> &
11512 {
11513  return vertices_used;
11514 }
11515 
11516 
11517 
11518 
11519 template <>
11520 unsigned int Triangulation<1,1>::max_adjacent_cells () const
11521 {
11522  return 2;
11523 }
11524 
11525 
11526 
11527 template <>
11528 unsigned int Triangulation<1,2>::max_adjacent_cells () const
11529 {
11530  return 2;
11531 }
11532 
11533 
11534 template <>
11535 unsigned int Triangulation<1,3>::max_adjacent_cells () const
11536 {
11537  return 2;
11538 }
11539 
11540 
11541 template <int dim, int spacedim>
11543 {
11544  cell_iterator cell = begin(0),
11545  endc = (n_levels() > 1 ? begin(1) : cell_iterator(end()));
11546  // store the largest index of the
11547  // vertices used on level 0
11548  unsigned int max_vertex_index = 0;
11549  for (; cell!=endc; ++cell)
11550  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
11551  if (cell->vertex_index(vertex) > max_vertex_index)
11552  max_vertex_index = cell->vertex_index(vertex);
11553 
11554  // store the number of times a cell
11555  // touches a vertex. An unsigned
11556  // int should suffice, even for
11557  // larger dimensions
11558  std::vector<unsigned short int> usage_count (max_vertex_index+1, 0);
11559  // touch a vertex's usage count
11560  // every time we find an adjacent
11561  // element
11562  for (cell=begin(); cell!=endc; ++cell)
11563  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
11564  ++usage_count[cell->vertex_index(vertex)];
11565 
11566  return std::max (GeometryInfo<dim>::vertices_per_cell,
11567  static_cast<unsigned int>(*std::max_element (usage_count.begin(),
11568  usage_count.end())));
11569 }
11570 
11571 
11572 
11573 template <int dim, int spacedim>
11576 {
11578 }
11579 
11580 
11581 
11582 template <int dim, int spacedim>
11585 {
11586  return *this;
11587 }
11588 
11589 
11590 
11591 template <int dim, int spacedim>
11594 {
11595  return *this;
11596 }
11597 
11598 
11599 
11600 template <int dim, int spacedim>
11601 void
11603 {
11605 
11606  // verify a case with which we have had
11607  // some difficulty in the past (see the
11608  // deal.II/coarsening_* tests)
11610  Assert (satisfies_level1_at_vertex_rule (*this) == true,
11611  ExcInternalError());
11612 
11613  // Inform all listeners about beginning of refinement.
11615 
11617 
11618  const DistortedCellList
11619  cells_with_distorted_children = execute_refinement();
11620 
11621  // verify a case with which we have had
11622  // some difficulty in the past (see the
11623  // deal.II/coarsening_* tests)
11624  if (smooth_grid & limit_level_difference_at_vertices)
11625  Assert (satisfies_level1_at_vertex_rule (*this) == true,
11626  ExcInternalError());
11627 
11628  // finally build up neighbor connectivity information, and set
11629  // active cell indices
11630  update_neighbors(*this);
11632 
11633  // Inform all listeners about end of refinement.
11635 
11636  AssertThrow (cells_with_distorted_children.distorted_cells.size() == 0,
11637  cells_with_distorted_children);
11638 }
11639 
11640 
11641 
11642 template <int dim, int spacedim>
11643 void
11645 {
11646  unsigned int active_cell_index = 0;
11647  for (raw_cell_iterator cell=begin_raw(); cell!=end(); ++cell)
11648  if ((cell->used() == false) || cell->has_children())
11649  cell->set_active_cell_index (numbers::invalid_unsigned_int);
11650  else
11651  {
11652  cell->set_active_cell_index (active_cell_index);
11653  ++active_cell_index;
11654  }
11655 
11656  Assert (active_cell_index == n_active_cells(), ExcInternalError());
11657 }
11658 
11659 
11660 
11661 template<int dim, int spacedim>
11662 void
11664 {
11665  // This is the former function
11666  // clear without the assertion in
11667  // the beginning.
11668  for (unsigned int i=0; i<levels.size(); ++i)
11669  delete levels[i];
11670  levels.clear ();
11671 
11672  delete faces;
11673  faces = NULL;
11674 
11675  vertices.clear ();
11676  vertices_used.clear ();
11677 
11678  manifold.clear();
11679 
11681 }
11682 
11683 
11684 template <int dim, int spacedim>
11687 {
11688  const DistortedCellList
11689  cells_with_distorted_children
11690  =
11693 
11694 
11695 
11696  // re-compute number of lines
11699 
11700 #ifdef DEBUG
11701  for (unsigned int level=0; level<levels.size(); ++level)
11702  levels[level]->cells.monitor_memory (dim);
11703 
11704  // check whether really all
11705  // refinement flags are reset (also
11706  // of previously non-active cells
11707  // which we may not have
11708  // touched. If the refinement flag
11709  // of a non-active cell is set,
11710  // something went wrong since the
11711  // cell-accessors should have
11712  // caught this)
11713  cell_iterator cell = begin(),
11714  endc = end();
11715  while (cell != endc)
11716  Assert (!(cell++)->refine_flag_set(), ExcInternalError ());
11717 #endif
11718 
11719  return cells_with_distorted_children;
11720 }
11721 
11722 
11723 
11724 template <int dim, int spacedim>
11726 {
11727  // create a vector counting for each line how
11728  // many cells contain this line. in 3D, this
11729  // is used later on to decide which lines can
11730  // be deleted after coarsening a cell. in
11731  // other dimensions it will be ignored
11732  std::vector<unsigned int> line_cell_count = count_cells_bounded_by_line (*this);
11733  std::vector<unsigned int> quad_cell_count = count_cells_bounded_by_quad (*this);
11734 
11735  // loop over all cells. Flag all
11736  // cells of which all children are
11737  // flagged for
11738  // coarsening and delete the childrens'
11739  // flags. In effect, only those
11740  // cells are flagged of which originally
11741  // all children were flagged and for which
11742  // all children are on the same refinement
11743  // level. For flagging, the user flags are
11744  // used, to avoid confusion and because
11745  // non-active cells can't be flagged for
11746  // coarsening. Note that because of the
11747  // effects of @p{fix_coarsen_flags}, of a
11748  // cell either all or no children must
11749  // be flagged for coarsening, so it is
11750  // ok to only check the first child
11751  clear_user_flags ();
11752 
11753  cell_iterator cell = begin(),
11754  endc = end();
11755  for (; cell!=endc; ++cell)
11756  if (!cell->active())
11757  if (cell->child(0)->coarsen_flag_set())
11758  {
11759  cell->set_user_flag();
11760  for (unsigned int child=0; child<cell->n_children(); ++child)
11761  {
11762  Assert (cell->child(child)->coarsen_flag_set(),
11763  ExcInternalError());
11764  cell->child(child)->clear_coarsen_flag();
11765  }
11766  }
11767 
11768 
11769  // now do the actual coarsening
11770  // step. Since the loop goes over
11771  // used cells we only need not
11772  // worry about deleting some cells
11773  // since the ++operator will then
11774  // just hop over them if we should
11775  // hit one. Do the loop in the
11776  // reverse way since we may only
11777  // delete some cells if their
11778  // neighbors have already been
11779  // deleted (if the latter are on a
11780  // higher level for example)
11781  //
11782  // since we delete the *children* of cells, we can ignore cells
11783  // on the highest level, i.e., level must be less than or equal
11784  // to n_levels()-2.
11785  if (levels.size() >= 2)
11786  for (cell = last(); cell!=endc; --cell)
11787  if (cell->level()<=static_cast<int>(levels.size()-2) && cell->user_flag_set())
11788  {
11789  // inform all listeners that cell coarsening is going to happen
11791  // use a separate function,
11792  // since this is dimension
11793  // specific
11795  ::delete_children (*this, cell, line_cell_count, quad_cell_count);
11796  }
11797 
11798  // re-compute number of lines and
11799  // quads
11802 
11803  // in principle no user flags
11804  // should be
11805  // set any more at this point
11806 #if DEBUG
11807  for (cell=begin(); cell!=endc; ++cell)
11808  Assert (cell->user_flag_set() == false, ExcInternalError());
11809 #endif
11810 }
11811 
11812 
11813 
11814 template <int dim, int spacedim>
11816 {
11817  // copy a piece of code from prepare_coarsening_and_refinement that
11818  // ensures that the level difference at vertices is limited if so
11819  // desired. we need this code here since at least in 1d we don't
11820  // call the dimension-independent version of
11821  // prepare_coarsening_and_refinement function. in 2d and 3d, having
11822  // this hunk here makes our lives a bit easier as well as it takes
11823  // care of these cases earlier than it would otherwise happen.
11824  //
11825  // the main difference to the code in p_c_and_r is that here we
11826  // absolutely have to make sure that we get things right, i.e. that
11827  // in particular we set flags right if
11828  // limit_level_difference_at_vertices is set. to do so we iterate
11829  // until the flags don't change any more
11830  std::vector<bool> previous_coarsen_flags (n_active_cells());
11831  save_coarsen_flags (previous_coarsen_flags);
11832 
11833  std::vector<int> vertex_level (vertices.size(), 0);
11834 
11835  bool continue_iterating = true;
11836 
11837  do
11838  {
11840  {
11842  ExcMessage("In case of anisotropic refinement the "
11843  "limit_level_difference_at_vertices flag for "
11844  "mesh smoothing must not be set!"));
11845 
11846  // store highest level one of the cells adjacent to a vertex
11847  // belongs to
11848  std::fill (vertex_level.begin(), vertex_level.end(), 0);
11850  endc = end();
11851  for (; cell!=endc; ++cell)
11852  {
11853  if (cell->refine_flag_set())
11854  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
11855  ++vertex)
11856  vertex_level[cell->vertex_index(vertex)]
11857  = std::max (vertex_level[cell->vertex_index(vertex)],
11858  cell->level()+1);
11859  else if (!cell->coarsen_flag_set())
11860  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
11861  ++vertex)
11862  vertex_level[cell->vertex_index(vertex)]
11863  = std::max (vertex_level[cell->vertex_index(vertex)],
11864  cell->level());
11865  else
11866  {
11867  // if coarsen flag is set then tentatively assume
11868  // that the cell will be coarsened. this isn't
11869  // always true (the coarsen flag could be removed
11870  // again) and so we may make an error here. we try
11871  // to correct this by iterating over the entire
11872  // process until we are converged
11873  Assert (cell->coarsen_flag_set(), ExcInternalError());
11874  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
11875  ++vertex)
11876  vertex_level[cell->vertex_index(vertex)]
11877  = std::max (vertex_level[cell->vertex_index(vertex)],
11878  cell->level()-1);
11879  }
11880  }
11881 
11882 
11883  // loop over all cells in reverse order. do so because we
11884  // can then update the vertex levels on the adjacent
11885  // vertices and maybe already flag additional cells in this
11886  // loop
11887  //
11888  // note that not only may we have to add additional
11889  // refinement flags, but we will also have to remove
11890  // coarsening flags on cells adjacent to vertices that will
11891  // see refinement
11892  for (cell=last_active(); cell != endc; --cell)
11893  if (cell->refine_flag_set() == false)
11894  {
11895  for (unsigned int vertex=0;
11896  vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
11897  if (vertex_level[cell->vertex_index(vertex)] >=
11898  cell->level()+1)
11899  {
11900  // remove coarsen flag...
11901  cell->clear_coarsen_flag();
11902 
11903  // ...and if necessary also refine the current
11904  // cell, at the same time updating the level
11905  // information about vertices
11906  if (vertex_level[cell->vertex_index(vertex)] >
11907  cell->level()+1)
11908  {
11909  cell->set_refine_flag();
11910 
11911  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell;
11912  ++v)
11913  vertex_level[cell->vertex_index(v)]
11914  = std::max (vertex_level[cell->vertex_index(v)],
11915  cell->level()+1);
11916  }
11917 
11918  // continue and see whether we may, for example,
11919  // go into the inner 'if' above based on a
11920  // different vertex
11921  }
11922  }
11923  }
11924 
11925  // loop over all cells. Flag all cells of which all children are
11926  // flagged for coarsening and delete the childrens' flags. Also
11927  // delete all flags of cells for which not all children of a
11928  // cell are flagged. In effect, only those cells are flagged of
11929  // which originally all children were flagged and for which all
11930  // children are on the same refinement level. For flagging, the
11931  // user flags are used, to avoid confusion and because
11932  // non-active cells can't be flagged for coarsening
11933  //
11934  // In effect, all coarsen flags are turned into user flags of
11935  // the mother cell if coarsening is possible or deleted
11936  // otherwise.
11937  clear_user_flags ();
11938  // Coarsen flags of cells with no mother cell, i.e. on the
11939  // coarsest level are deleted explicitly.
11941  end_ac = end_active(0);
11942  for (; acell!=end_ac; ++acell)
11943  acell->clear_coarsen_flag();
11944 
11945  cell_iterator cell = begin(),
11946  endc = end();
11947  for (; cell!=endc; ++cell)
11948  {
11949  // nothing to do if we are already on the finest level
11950  if (cell->active())
11951  continue;
11952 
11953  const unsigned int n_children=cell->n_children();
11954  unsigned int flagged_children=0;
11955  for (unsigned int child=0; child<n_children; ++child)
11956  if (cell->child(child)->active() &&
11957  cell->child(child)->coarsen_flag_set())
11958  {
11959  ++flagged_children;
11960  // clear flag since we don't need it anymore
11961  cell->child(child)->clear_coarsen_flag();
11962  }
11963 
11964  // flag this cell for coarsening if all children were
11965  // flagged
11966  if (flagged_children == n_children)
11967  cell->set_user_flag();
11968  }
11969 
11970  // in principle no coarsen flags should be set any more at this
11971  // point
11972 #if DEBUG
11973  for (cell=begin(); cell!=endc; ++cell)
11974  Assert (cell->coarsen_flag_set() == false, ExcInternalError());
11975 #endif
11976 
11977  // now loop over all cells which have the user flag set. their
11978  // children were flagged for coarsening. set the coarsen flag
11979  // again if we are sure that none of the neighbors of these
11980  // children are refined, or will be refined, since then we would
11981  // get a two-level jump in refinement. on the other hand, if one
11982  // of the children's neighbors has their user flag set, then we
11983  // know that its children will go away by coarsening, and we
11984  // will be ok.
11985  //
11986  // note on the other hand that we do allow level-2 jumps in
11987  // refinement between neighbors in 1d, so this whole procedure
11988  // is only necessary if we are not in 1d
11989  //
11990  // since we remove some coarsening/user flags in the process, we
11991  // have to work from the finest level to the coarsest one, since
11992  // we occasionally inspect user flags of cells on finer levels
11993  // and need to be sure that these flags are final
11994  for (cell=last(); cell!=endc; --cell)
11995  if (cell->user_flag_set())
11996  // if allowed: flag the
11997  // children for coarsening
11998  if (internal::Triangulation::Implementation::template coarsening_allowed<dim,spacedim>(cell))
11999  for (unsigned int c=0; c<cell->n_children(); ++c)
12000  {
12001  Assert (cell->child(c)->refine_flag_set()==false,
12002  ExcInternalError());
12003 
12004  cell->child(c)->set_coarsen_flag();
12005  }
12006 
12007  // clear all user flags again, now that we don't need them any
12008  // more
12009  clear_user_flags ();
12010 
12011 
12012  // now see if anything has changed in the last iteration of this
12013  // function
12014  std::vector<bool> current_coarsen_flags (n_active_cells());
12015  save_coarsen_flags (current_coarsen_flags);
12016 
12017  continue_iterating = (current_coarsen_flags != previous_coarsen_flags);
12018  previous_coarsen_flags = current_coarsen_flags;
12019  }
12020  while (continue_iterating == true);
12021 }
12022 
12023 
12024 //TODO: merge the following 3 functions since they are the same
12025 template <>
12027 {
12028  // save the flags to determine whether something was changed in the
12029  // course of this function
12030  std::vector<bool> flags_before;
12031  save_coarsen_flags (flags_before);
12032 
12033  // do nothing in 1d, except setting the coarsening flags correctly
12034  fix_coarsen_flags ();
12035 
12036  std::vector<bool> flags_after;
12037  save_coarsen_flags (flags_after);
12038 
12039  return (flags_before != flags_after);
12040 }
12041 
12042 
12043 template <>
12045 {
12046  // save the flags to determine whether something was changed in the
12047  // course of this function
12048  std::vector<bool> flags_before;
12049  save_coarsen_flags (flags_before);
12050 
12051  // do nothing in 1d, except setting the coarsening flags correctly
12052  fix_coarsen_flags ();
12053 
12054  std::vector<bool> flags_after;
12055  save_coarsen_flags (flags_after);
12056 
12057  return (flags_before != flags_after);
12058 }
12059 
12060 
12061 template <>
12063 {
12064  // save the flags to determine whether something was changed in the
12065  // course of this function
12066  std::vector<bool> flags_before;
12067  save_coarsen_flags (flags_before);
12068 
12069  // do nothing in 1d, except setting the coarsening flags correctly
12070  fix_coarsen_flags ();
12071 
12072  std::vector<bool> flags_after;
12073  save_coarsen_flags (flags_after);
12074 
12075  return (flags_before != flags_after);
12076 }
12077 
12078 
12079 
12080 
12081 namespace
12082 {
12083 
12084  // check if the given @param cell marked for coarsening would
12085  // produce an unrefined island. To break up long chains of these
12086  // cells we recursively check our neighbors in case we change this
12087  // cell. This reduces the number of outer iterations dramatically.
12088  template <int dim, int spacedim>
12089  void
12090  possibly_do_not_produce_unrefined_islands(
12091  const typename Triangulation<dim,spacedim>::cell_iterator &cell)
12092  {
12093  Assert (cell->has_children(), ExcInternalError());
12094 
12095  unsigned int n_neighbors=0;
12096  // count all neighbors that will be refined along the face of our
12097  // cell after the next step
12098  unsigned int count=0;
12099  for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
12100  {
12101  const typename Triangulation<dim,spacedim>::cell_iterator neighbor = cell->neighbor(n);
12102  if (neighbor.state() == IteratorState::valid)
12103  {
12104  ++n_neighbors;
12105  if (face_will_be_refined_by_neighbor(cell,n))
12106  ++count;
12107  }
12108  }
12109  // clear coarsen flags if either all existing neighbors will be
12110  // refined or all but one will be and the cell is in the interior
12111  // of the domain
12112  if (count==n_neighbors ||
12113  (count>=n_neighbors-1 &&
12114  n_neighbors == GeometryInfo<dim>::faces_per_cell) )
12115  {
12116  for (unsigned int c=0; c<cell->n_children(); ++c)
12117  cell->child(c)->clear_coarsen_flag();
12118 
12119  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
12120  if (!cell->at_boundary(face)
12121  &&
12122  ( !cell->neighbor(face)->active() )
12123  && (cell_will_be_coarsened(cell->neighbor(face))) )
12124  possibly_do_not_produce_unrefined_islands<dim,spacedim>( cell->neighbor(face) );
12125  }
12126  }
12127 
12128 
12129  // see if the current cell needs to be refined to avoid unrefined
12130  // islands.
12131  //
12132  // there are sometimes chains of cells that induce refinement of
12133  // each other. to avoid running the loop in
12134  // prepare_coarsening_and_refinement over and over again for each
12135  // one of them, at least for the isotropic refinement case we seek
12136  // to flag neighboring elements as well as necessary. this takes
12137  // care of (slightly pathological) cases like
12138  // deal.II/mesh_smoothing_03
12139  template <int dim, int spacedim>
12140  void
12141  possibly_refine_unrefined_island
12142  (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
12143  const bool allow_anisotropic_smoothing)
12144  {
12145  Assert (cell->has_children() == false, ExcInternalError());
12146  Assert (cell->refine_flag_set() == false, ExcInternalError());
12147 
12148 
12149  // now we provide two algorithms. the first one is the standard
12150  // one, coming from the time, where only isotropic refinement was
12151  // possible. it simply counts the neighbors that are or will be
12152  // refined and compares to the number of other ones. the second
12153  // one does this check independently for each direction: if all
12154  // neighbors in one direction (normally two, at the boundary only
12155  // one) are refined, the current cell is flagged to be refined in
12156  // an according direction.
12157 
12158  if (allow_anisotropic_smoothing == false)
12159  {
12160  // use first algorithm
12161  unsigned int refined_neighbors = 0,
12162  unrefined_neighbors = 0;
12163  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
12164  if (!cell->at_boundary(face))
12165  {
12166  if (face_will_be_refined_by_neighbor(cell,face))
12167  ++refined_neighbors;
12168  else
12169  ++unrefined_neighbors;
12170  }
12171 
12172  if (unrefined_neighbors < refined_neighbors)
12173  {
12174  cell->clear_coarsen_flag();
12175  cell->set_refine_flag ();
12176 
12177  // ok, so now we have flagged this cell. if we know that
12178  // there were any unrefined neighbors at all, see if any
12179  // of those will have to be refined as well
12180  if (unrefined_neighbors > 0)
12181  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
12182  if (!cell->at_boundary(face)
12183  &&
12184  (face_will_be_refined_by_neighbor(cell,face) == false)
12185  &&
12186  (cell->neighbor(face)->has_children() == false)
12187  &&
12188  (cell->neighbor(face)->refine_flag_set() == false))
12189  possibly_refine_unrefined_island<dim,spacedim>
12190  (cell->neighbor(face),
12192  }
12193  }
12194  else
12195  {
12196  // variable to store the cell refine case needed to fulfill
12197  // all smoothing requirements
12198  RefinementCase<dim> smoothing_cell_refinement_case
12200 
12201  // use second algorithm, do the check individually for each
12202  // direction
12203  for (unsigned int face_pair=0;
12204  face_pair<GeometryInfo<dim>::faces_per_cell/2; ++face_pair)
12205  {
12206  // variable to store the cell refine case needed to refine
12207  // at the current face pair in the same way as the
12208  // neighbors do...
12209  RefinementCase<dim> directional_cell_refinement_case
12211 
12212  for (unsigned int face_index=0; face_index<2; ++face_index)
12213  {
12214  unsigned int face=2*face_pair+face_index;
12215  // variable to store the refine case (to come) of the
12216  // face under consideration
12217  RefinementCase<dim-1> expected_face_ref_case
12218  = RefinementCase<dim-1>::no_refinement;
12219 
12220  if (cell->neighbor(face).state() == IteratorState::valid)
12221  face_will_be_refined_by_neighbor<dim,spacedim>(cell,face,expected_face_ref_case);
12222  // now extract which refine case would be necessary to
12223  // achieve the same face refinement. set the
12224  // intersection with other requirements for the same
12225  // direction.
12226 
12227  // note: using the intersection is not an obvious
12228  // decision, we could also argue that it is more
12229  // natural to use the union. however, intersection is
12230  // the less aggressive tactic and favours a smaller
12231  // number of refined cells over an intensive
12232  // smoothing. this way we try not to lose too much of
12233  // the effort we put in anisotropic refinement
12234  // indicators due to overly aggressive smoothing...
12235  directional_cell_refinement_case
12236  = (directional_cell_refinement_case &
12238  expected_face_ref_case,
12239  face,
12240  cell->face_orientation(face),
12241  cell->face_flip(face),
12242  cell->face_rotation(face)));
12243  }//for both face indices
12244  // if both requirements sum up to something useful, add
12245  // this to the refine case for smoothing. note: if
12246  // directional_cell_refinement_case is isotropic still,
12247  // then something went wrong...
12248  Assert(directional_cell_refinement_case <
12250  ExcInternalError());
12251  smoothing_cell_refinement_case = smoothing_cell_refinement_case |
12252  directional_cell_refinement_case;
12253  }//for all face_pairs
12254  // no we collected contributions from all directions. combine
12255  // the new flags with the existing refine case, but only if
12256  // smoothing is required
12257  if (smoothing_cell_refinement_case)
12258  {
12259  cell->clear_coarsen_flag();
12260  cell->set_refine_flag(cell->refine_flag_set() |
12261  smoothing_cell_refinement_case);
12262  }
12263  }
12264  }
12265 }
12266 
12267 
12268 template <int dim, int spacedim>
12270 {
12271  // save the flags to determine whether something was changed in the
12272  // course of this function
12273  std::vector<bool> flags_before[2];
12274  save_coarsen_flags (flags_before[0]);
12275  save_refine_flags (flags_before[1]);
12276 
12277  // save the flags at the outset of each loop. we do so in order to
12278  // find out whether something was changed in the present loop, in
12279  // which case we would have to re-run the loop. the other
12280  // possibility to find this out would be to set a flag
12281  // @p{something_changed} to true each time we change something.
12282  // however, sometimes one change in one of the parts of the loop is
12283  // undone by another one, so we might end up in an endless loop. we
12284  // could be tempted to break this loop at an arbitrary number of
12285  // runs, but that would not be a clean solution, since we would
12286  // either have to 1/ break the loop too early, in which case the
12287  // promise that a second call to this function immediately after the
12288  // first one does not change anything, would be broken, or 2/ we do
12289  // as many loops as there are levels. we know that information is
12290  // transported over one level in each run of the loop, so this is
12291  // enough. Unfortunately, each loop is rather expensive, so we chose
12292  // the way presented here
12293  std::vector<bool> flags_before_loop[2] = {flags_before[0],
12294  flags_before[1]
12295  };
12296 
12297  // now for what is done in each loop: we have to fulfill several
12298  // tasks at the same time, namely several mesh smoothing algorithms
12299  // and mesh regularisation, by which we mean that the next mesh
12300  // fulfills several requirements such as no double refinement at
12301  // each face or line, etc.
12302  //
12303  // since doing these things at once seems almost impossible (in the
12304  // first year of this library, they were done in two functions, one
12305  // for refinement and one for coarsening, and most things within
12306  // these were done at once, so the code was rather impossible to
12307  // join into this, only, function), we do them one after each
12308  // other. the order in which we do them is such that the important
12309  // tasks, namely regularisation, are done last and the least
12310  // important things are done the first. the following order is
12311  // chosen:
12312  //
12313  // 0/ Only if coarsest_level_1 or patch_level_1 is set: clear all
12314  // coarsen flags on level 1 to avoid level 0 cells being created
12315  // by coarsening. As coarsen flags will never be added, this can
12316  // be done once and for all before the actual loop starts.
12317  //
12318  // 1/ do not coarsen a cell if 'most of the neighbors' will be
12319  // refined after the step. This is to prevent occurrence of
12320  // unrefined islands.
12321  //
12322  // 2/ eliminate refined islands in the interior and at the
12323  // boundary. since they don't do much harm besides increasing the
12324  // number of degrees of freedom, doing this has a rather low
12325  // priority.
12326  //
12327  // 3/ limit the level difference of neighboring cells at each
12328  // vertex.
12329  //
12330  // 4/ eliminate unrefined islands. this has higher priority since
12331  // this diminishes the approximation properties not only of the
12332  // unrefined island, but also of the surrounding patch.
12333  //
12334  // 5/ ensure patch level 1. Then the triangulation consists of
12335  // patches, i.e. of cells that are refined once. It follows that
12336  // if at least one of the children of a cell is or will be
12337  // refined than all children need to be refined. This step only
12338  // sets refinement flags and does not set coarsening flags. If
12339  // the patch_level_1 flag is set, then
12340  // eliminate_unrefined_islands, eliminate_refined_inner_islands
12341  // and eliminate_refined_boundary_islands will be fulfilled
12342  // automatically and do not need to be enforced separately.
12343  //
12344  // 6/ take care of the requirement that no double refinement is done
12345  // at each face
12346  //
12347  // 7/ take care that no double refinement is done at each line in 3d
12348  // or higher dimensions.
12349  //
12350  // 8/ make sure that all children of each cell are either flagged
12351  // for coarsening or none of the children is
12352  //
12353  // For some of these steps, it is known that they interact. Namely,
12354  // it is not possible to guarantee that after step 6 another step 5
12355  // would have no effect; the same holds for the opposite order and
12356  // also when taking into account step 7. however, it is important to
12357  // guarantee that step five or six do not undo something that step 5
12358  // did, and step 7 not something of step 6, otherwise the
12359  // requirements will not be satisfied even if the loop
12360  // terminates. this is accomplished by the fact that steps 5 and 6
12361  // only *add* refinement flags and delete coarsening flags
12362  // (therefore, step 6 can't undo something that step 4 already did),
12363  // and step 7 only deletes coarsening flags, never adds some. step 7
12364  // needs also take care that it won't tag cells for refinement for
12365  // which some neighbors are more refined or will be refined.
12366 
12368  // STEP 0:
12369  // Only if coarsest_level_1 or patch_level_1 is set: clear all
12370  // coarsen flags on level 1 to avoid level 0 cells being created
12371  // by coarsening.
12372  if (((smooth_grid & coarsest_level_1) ||
12373  (smooth_grid & patch_level_1)) && n_levels()>=2)
12374  {
12376  cell=begin_active(1),
12377  endc=end_active(1);
12378 
12379  for (; cell!=endc; ++cell)
12380  cell->clear_coarsen_flag();
12381  }
12382 
12383  bool mesh_changed_in_this_loop = false;
12384  do
12385  {
12387  // STEP 1:
12388  // do not coarsen a cell if 'most of the neighbors' will be
12389  // refined after the step. This is to prevent the occurrence
12390  // of unrefined islands. If patch_level_1 is set, this will
12391  // be automatically fulfilled.
12393  !(smooth_grid & patch_level_1))
12394  {
12395  cell_iterator cell;
12396  const cell_iterator endc = end();
12397 
12398  for (cell=begin(); cell!=endc; ++cell)
12399  {
12400  // only do something if this
12401  // cell will be coarsened
12402  if (!cell->active() && cell_will_be_coarsened(cell))
12403  possibly_do_not_produce_unrefined_islands<dim,spacedim>(cell);
12404  }
12405  }
12406 
12407 
12409  // STEP 2:
12410  // eliminate refined islands in the interior and at the
12411  // boundary. since they don't do much harm besides increasing
12412  // the number of degrees of freedom, doing this has a rather
12413  // low priority. If patch_level_1 is set, this will be
12414  // automatically fulfilled.
12415  //
12416  // there is one corner case to consider: if this is a
12417  // distributed triangulation, there may be refined islands on
12418  // the boundary of which we own only part (e.g. a single cell
12419  // in the corner of a domain). the rest of the island is
12420  // ghost cells and it *looks* like the area around it
12421  // (artificial cells) are coarser but this is only because
12422  // they may actually be equally fine on other
12423  // processors. it's hard to detect this case but we can do
12424  // the following: only set coarsen flags to remove this
12425  // refined island if all cells we want to set flags on are
12426  // locally owned
12430  {
12431  cell_iterator cell;
12432  const cell_iterator endc = end();
12433 
12434  for (cell=begin(); cell!=endc; ++cell)
12435  if (!cell->active() ||
12436  (cell->active() &&
12437  cell->refine_flag_set() &&
12438  cell->is_locally_owned()))
12439  {
12440  // check whether all children are active, i.e. not
12441  // refined themselves. This is a precondition that the
12442  // children may be coarsened away. If the cell is only
12443  // flagged for refinement, then all future children
12444  // will be active
12445  bool all_children_active = true;
12446  if (!cell->active())
12447  for (unsigned int c=0; c<cell->n_children(); ++c)
12448  if (!cell->child(c)->active() ||
12449  cell->child(c)->is_ghost() ||
12450  cell->child(c)->is_artificial())
12451  {
12452  all_children_active = false;
12453  break;
12454  }
12455 
12456  if (all_children_active)
12457  {
12458  // count number of refined and unrefined neighbors
12459  // of cell. neighbors on lower levels are counted
12460  // as unrefined since they can only get to the
12461  // same level as this cell by the next refinement
12462  // cycle
12463  unsigned int unrefined_neighbors = 0,
12464  total_neighbors = 0;
12465 
12466  for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
12467  {
12468  const cell_iterator neighbor = cell->neighbor(n);
12469  if (neighbor.state() == IteratorState::valid)
12470  {
12471  ++total_neighbors;
12472 
12473  if (!face_will_be_refined_by_neighbor(cell,n))
12474  ++unrefined_neighbors;
12475  }
12476 
12477  }
12478 
12479  // if all neighbors unrefined: mark this cell for
12480  // coarsening or don't refine if marked for that
12481  //
12482  // also do the distinction between the two
12483  // versions of the eliminate_refined_*_islands
12484  // flag
12485  //
12486  // the last check is whether there are any
12487  // neighbors at all. if not so, then we are (e.g.)
12488  // on the coarsest grid with one cell, for which,
12489  // of course, we do not remove the refine flag.
12490  if ((unrefined_neighbors == total_neighbors)
12491  &&
12492  (((unrefined_neighbors==GeometryInfo<dim>::faces_per_cell) &&
12494  ((unrefined_neighbors<GeometryInfo<dim>::faces_per_cell) &&
12496  &&
12497  (total_neighbors != 0))
12498  {
12499  if (!cell->active())
12500  for (unsigned int c=0; c<cell->n_children(); ++c)
12501  {
12502  cell->child(c)->clear_refine_flag ();
12503  cell->child(c)->set_coarsen_flag ();
12504  }
12505  else
12506  cell->clear_refine_flag();
12507  }
12508  }
12509  }
12510  }
12511 
12513  // STEP 3:
12514  // limit the level difference of neighboring cells at each
12515  // vertex.
12516  //
12517  // in case of anisotropic refinement this does not make
12518  // sense. as soon as one cell is anisotropically refined, an
12519  // Assertion is thrown. therefore we can ignore this problem
12520  // later on
12522  {
12524  ExcMessage("In case of anisotropic refinement the "
12525  "limit_level_difference_at_vertices flag for "
12526  "mesh smoothing must not be set!"));
12527 
12528  // store highest level one of the cells adjacent to a vertex
12529  // belongs to
12530  std::vector<int> vertex_level (vertices.size(), 0);
12532  endc = end();
12533  for (; cell!=endc; ++cell)
12534  {
12535  if (cell->refine_flag_set())
12536  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
12537  ++vertex)
12538  vertex_level[cell->vertex_index(vertex)]
12539  = std::max (vertex_level[cell->vertex_index(vertex)],
12540  cell->level()+1);
12541  else if (!cell->coarsen_flag_set())
12542  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
12543  ++vertex)
12544  vertex_level[cell->vertex_index(vertex)]
12545  = std::max (vertex_level[cell->vertex_index(vertex)],
12546  cell->level());
12547  else
12548  {
12549  // if coarsen flag is set then tentatively assume
12550  // that the cell will be coarsened. this isn't
12551  // always true (the coarsen flag could be removed
12552  // again) and so we may make an error here
12553  Assert (cell->coarsen_flag_set(), ExcInternalError());
12554  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
12555  ++vertex)
12556  vertex_level[cell->vertex_index(vertex)]
12557  = std::max (vertex_level[cell->vertex_index(vertex)],
12558  cell->level()-1);
12559  }
12560  }
12561 
12562 
12563  // loop over all cells in reverse order. do so because we
12564  // can then update the vertex levels on the adjacent
12565  // vertices and maybe already flag additional cells in this
12566  // loop
12567  //
12568  // note that not only may we have to add additional
12569  // refinement flags, but we will also have to remove
12570  // coarsening flags on cells adjacent to vertices that will
12571  // see refinement
12572  for (cell=last_active(); cell != endc; --cell)
12573  if (cell->refine_flag_set() == false)
12574  {
12575  for (unsigned int vertex=0;
12576  vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
12577  if (vertex_level[cell->vertex_index(vertex)] >=
12578  cell->level()+1)
12579  {
12580  // remove coarsen flag...
12581  cell->clear_coarsen_flag();
12582 
12583  // ...and if necessary also refine the current
12584  // cell, at the same time updating the level
12585  // information about vertices
12586  if (vertex_level[cell->vertex_index(vertex)] >
12587  cell->level()+1)
12588  {
12589  cell->set_refine_flag();
12590 
12591  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell;
12592  ++v)
12593  vertex_level[cell->vertex_index(v)]
12594  = std::max (vertex_level[cell->vertex_index(v)],
12595  cell->level()+1);
12596  }
12597 
12598  // continue and see whether we may, for example,
12599  // go into the inner'if'
12600  // above based on a
12601  // different vertex
12602  }
12603  }
12604  }
12605 
12607  // STEP 4:
12608  // eliminate unrefined islands. this has higher priority
12609  // since this diminishes the approximation properties not
12610  // only of the unrefined island, but also of the surrounding
12611  // patch.
12612  //
12613  // do the loop from finest to coarsest cells since we may
12614  // trigger a cascade by marking cells for refinement which
12615  // may trigger more cells further down below
12617  {
12619  endc=end();
12620 
12621  for (; cell != endc; --cell)
12622  // only do something if cell is not already flagged for
12623  // (isotropic) refinement
12624  if (cell->refine_flag_set() != RefinementCase<dim>::isotropic_refinement)
12625  possibly_refine_unrefined_island<dim,spacedim>
12626  (cell,
12628  }
12629 
12631  // STEP 5:
12632  // ensure patch level 1.
12633  //
12634  // Introduce some terminology:
12635  // - a cell that is refined
12636  // once is a patch of
12637  // level 1 simply called patch.
12638  // - a cell that is globally
12639  // refined twice is called
12640  // a patch of level 2.
12641  // - patch level n says that
12642  // the triangulation consists
12643  // of patches of level n.
12644  // This makes sense only
12645  // if the grid is already at
12646  // least n times globally
12647  // refined.
12648  //
12649  // E.g. from patch level 1 follows: if at least one of the
12650  // children of a cell is or will be refined than enforce all
12651  // children to be refined.
12652 
12653  // This step 4 only sets refinement flags and does not set
12654  // coarsening flags.
12655  if (smooth_grid & patch_level_1)
12656  {
12657 
12658  // An important assumption (A) is that before calling this
12659  // function the grid was already of patch level 1.
12660 
12661  // loop over all cells whose children are all active. (By
12662  // assumption (A) either all or none of the children are
12663  // active). If the refine flag of at least one of the
12664  // children is set then set_refine_flag and
12665  // clear_coarsen_flag of all children.
12666  for (cell_iterator cell = begin(); cell != end(); ++cell)
12667  if (!cell->active())
12668  {
12669  // ensure the invariant. we can then check whether all
12670  // of its children are further refined or not by
12671  // simply looking at the first child
12672  Assert (cell_is_patch_level_1(cell),
12673  ExcInternalError());
12674  if (cell->child(0)->has_children() == true)
12675  continue;
12676 
12677  // cell is found to be a patch. combine the refine
12678  // cases of all children
12680  for (unsigned int i=0; i<cell->n_children(); ++i)
12681  combined_ref_case = combined_ref_case |
12682  cell->child(i)->refine_flag_set();
12683  if (combined_ref_case != RefinementCase<dim>::no_refinement)
12684  for (unsigned int i=0; i<cell->n_children(); ++i)
12685  {
12686  cell_iterator child = cell->child(i);
12687 
12688  child->clear_coarsen_flag();
12689  child->set_refine_flag(combined_ref_case);
12690  }
12691  }
12692 
12693  // The code above dealt with the case where we may get a
12694  // non-patch_level_1 mesh from refinement. Now also deal
12695  // with the case where we could get such a mesh by
12696  // coarsening. Coarsen the children (and remove the
12697  // grandchildren) only if all cell->grandchild(i)
12698  // ->coarsen_flag_set() are set.
12699  //
12700  // for a case where this is a bit tricky, take a look at the
12701  // mesh_smoothing_0[12] testcases
12702  for (cell_iterator cell = begin(); cell != end(); ++cell)
12703  {
12704  // check if this cell has active grandchildren. note
12705  // that we know that it is patch_level_1, i.e. if one of
12706  // its children is active then so are all, and it isn't
12707  // going to have any grandchildren at all:
12708  if (cell->active()
12709  ||
12710  cell->child(0)->active())
12711  continue;
12712 
12713  // cell is not active, and so are none of its
12714  // children. check the grandchildren. note that the
12715  // children are also patch_level_1, and so we only ever
12716  // need to check their first child
12717  const unsigned int n_children=cell->n_children();
12718  bool has_active_grandchildren = false;
12719 
12720  for (unsigned int i=0; i<n_children; ++i)
12721  if (cell->child(i)->child(0)->active())
12722  {
12723  has_active_grandchildren = true;
12724  break;
12725  }
12726 
12727  if (has_active_grandchildren == false)
12728  continue;
12729 
12730 
12731  // ok, there are active grandchildren. see if either all
12732  // or none of them are flagged for coarsening
12733  unsigned int n_grandchildren=0;
12734 
12735  // count all coarsen flags of the grandchildren.
12736  unsigned int n_coarsen_flags=0;
12737 
12738  // cell is not a patch (of level 1) as it has a
12739  // grandchild. Is cell a patch of level 2?? Therefore:
12740  // find out whether all cell->child(i) are patches
12741  for (unsigned int c=0; c<n_children; ++c)
12742  {
12743  // get at the child. by assumption (A), and the
12744  // check by which we got here, the child is not
12745  // active
12746  cell_iterator child=cell->child(c);
12747 
12748  const unsigned int nn_children=child->n_children();
12749  n_grandchildren += nn_children;
12750 
12751  // if child is found to be a patch of active cells
12752  // itself, then add up how many of its children are
12753  // supposed to be coarsened
12754  if (child->child(0)->active())
12755  for (unsigned int cc=0; cc<nn_children; ++cc)
12756  if (child->child(cc)->coarsen_flag_set())
12757  ++n_coarsen_flags;
12758  }
12759 
12760  // if not all grandchildren are supposed to be coarsened
12761  // (e.g. because some simply don't have the flag set, or
12762  // because they are not active and therefore cannot
12763  // carry the flag), then remove the coarsen flag from
12764  // all of the active grandchildren. note that there may
12765  // be coarsen flags on the grandgrandchildren -- we
12766  // don't clear them here, but we'll get to them in later
12767  // iterations if necessary
12768  //
12769  // there is nothing we have to do if no coarsen flags
12770  // have been set at all
12771  if ((n_coarsen_flags != n_grandchildren)
12772  &&
12773  (n_coarsen_flags > 0))
12774  for (unsigned int c=0; c<n_children; ++c)
12775  {
12776  const cell_iterator child = cell->child(c);
12777  if (child->child(0)->active())
12778  for (unsigned int cc=0; cc<child->n_children(); ++cc)
12779  child->child(cc)->clear_coarsen_flag();
12780  }
12781  }
12782  }
12783 
12785  //
12786  // at the boundary we could end up with cells with negative
12787  // volume or at least with a part, that is negative, if the
12788  // cell is refined anisotropically. we have to check, whether
12789  // that can happen
12791 
12793  // STEP 6:
12794  // take care of the requirement that no
12795  // double refinement is done at each face
12796  //
12797  // in case of anisotropic refinement it is only likely, but
12798  // not sure, that the cells, which are more refined along a
12799  // certain face common to two cells are on a higher
12800  // level. therefore we cannot be sure, that the requirement
12801  // of no double refinement is fulfilled after a single pass
12802  // of the following actions. We could just wait for the next
12803  // global loop. when this function terminates, the
12804  // requirement will be fulfilled. However, it might be faster
12805  // to insert an inner loop here.
12806  bool changed = true;
12807  while (changed)
12808  {
12809  changed=false;
12811  endc=end();
12812 
12813  for (; cell != endc; --cell)
12814  if (cell->refine_flag_set())
12815  {
12816  // loop over neighbors of cell
12817  for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
12818  {
12819  // only do something if the face is not at the
12820  // boundary and if the face will be refined with
12821  // the RefineCase currently flagged for
12822  if (cell->neighbor(i).state() == IteratorState::valid &&
12823  (GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
12824  i)
12826  {
12827  // 1) if the neighbor has children: nothing to
12828  // worry about. 2) if the neighbor is active
12829  // and a coarser one, ensure, that its
12830  // refine_flag is set 3) if the neighbor is
12831  // active and as refined along the face as our
12832  // current cell, make sure, that no
12833  // coarsen_flag is set. if we remove the
12834  // coarsen flag of our neighbor,
12835  // fix_coarsen_flags() makes sure, that the
12836  // mother cell will not be coarsened
12837  if (cell->neighbor(i)->active())
12838  {
12839  if (cell->neighbor_is_coarser(i))
12840  {
12841  if (cell->neighbor(i)->coarsen_flag_set())
12842  cell->neighbor(i)->clear_coarsen_flag();
12843  // we'll set the refine flag for this
12844  // neighbor below. we note, that we
12845  // have changed something by setting
12846  // the changed flag to true. We do not
12847  // need to do so, if we just removed
12848  // the coarsen flag, as the changed
12849  // flag only indicates the need to
12850  // re-run the inner loop. however, we
12851  // only loop over cells flagged for
12852  // refinement here, so nothing to
12853  // worry about if we remove coarsen
12854  // flags
12855 
12856  if (dim==2)
12857  {
12859  changed=cell->neighbor(i)->flag_for_face_refinement(cell->neighbor_of_coarser_neighbor(i).first,
12860  RefinementCase<dim-1>::cut_x);
12861  else
12862  {
12863  if (!cell->neighbor(i)->refine_flag_set())
12864  changed=true;
12865  cell->neighbor(i)->set_refine_flag();
12866  }
12867  }
12868  else //i.e. if (dim==3)
12869  {
12870 // ugly situations might arise here, consider the following situation, which
12871 // shows neighboring cells at the common face, where the upper right element is
12872 // coarser at the given face. Now the upper child element of the lower left
12873 // wants to refine according to cut_z, such that there is a 'horizontal'
12874 // refinement of the face marked with #####
12875 //
12876 // / /
12877 // / /
12878 // *---------------*
12879 // | |
12880 // | |
12881 // | |
12882 // | |
12883 // | |
12884 // | | /
12885 // | |/
12886 // *---------------*
12887 //
12888 //
12889 // *---------------*
12890 // /| /|
12891 // / | ##### / |
12892 // | |
12893 // *---------------*
12894 // /| /|
12895 // / | / |
12896 // | |
12897 // *---------------*
12898 // / /
12899 // / /
12900 //
12901 // this introduces too many hanging nodes and the neighboring (coarser) cell
12902 // (upper right) has to be refined. If it is only refined according to cut_z,
12903 // then everything is ok:
12904 //
12905 // / /
12906 // / /
12907 // *---------------*
12908 // | |
12909 // | | /
12910 // | |/
12911 // *---------------*
12912 // | |
12913 // | | /
12914 // | |/
12915 // *---------------*
12916 //
12917 //
12918 // *---------------*
12919 // /| /|
12920 // / *---------------*
12921 // /| /|
12922 // *---------------*
12923 // /| /|
12924 // / | / |
12925 // | |
12926 // *---------------*
12927 // / /
12928 // / /
12929 //
12930 // if however the cell wants to refine itself in an other way, or if we disallow
12931 // anisotropic smoothing, then simply refining the neighbor isotropically is not
12932 // going to work, since this introduces a refinement of face ##### with both
12933 // cut_x and cut_y, which is not possible:
12934 //
12935 // / / /
12936 // / / /
12937 // *-------*-------*
12938 // | | |
12939 // | | | /
12940 // | | |/
12941 // *-------*-------*
12942 // | | |
12943 // | | | /
12944 // | | |/
12945 // *-------*-------*
12946 //
12947 //
12948 // *---------------*
12949 // /| /|
12950 // / *---------------*
12951 // /| /|
12952 // *---------------*
12953 // /| /|
12954 // / | / |
12955 // | |
12956 // *---------------*
12957 // / /
12958 // / /
12959 //
12960 // thus, in this case we also need to refine our current cell in the new
12961 // direction:
12962 //
12963 // / / /
12964 // / / /
12965 // *-------*-------*
12966 // | | |
12967 // | | | /
12968 // | | |/
12969 // *-------*-------*
12970 // | | |
12971 // | | | /
12972 // | | |/
12973 // *-------*-------*
12974 //
12975 //
12976 // *-------*-------*
12977 // /| /| /|
12978 // / *-------*-------*
12979 // /| /| /|
12980 // *-------*-------*
12981 // /| / /|
12982 // / | / |
12983 // | |
12984 // *---------------*
12985 // / /
12986 // / /
12987 
12988  std::pair<unsigned int, unsigned int> nb_indices
12989  =cell->neighbor_of_coarser_neighbor(i);
12990  unsigned int refined_along_x=0,
12991  refined_along_y=0,
12992  to_be_refined_along_x=0,
12993  to_be_refined_along_y=0;
12994 
12995  const int this_face_index=cell->face_index(i);
12996 
12997 // step 1: detect, along which axis the face is currently refined
12998  if ((this_face_index
12999  == cell->neighbor(i)->face(nb_indices.first)->child_index(0)) ||
13000  (this_face_index
13001  == cell->neighbor(i)->face(nb_indices.first)->child_index(1)))
13002  {
13003  // this might be an
13004  // anisotropic child. get the
13005  // face refine case of the
13006  // neighbors face and count
13007  // refinements in x and y
13008  // direction.
13009  RefinementCase<dim-1> frc=cell->neighbor(i)->face(nb_indices.first)->refinement_case();
13010  if (frc & RefinementCase<dim>::cut_x)
13011  ++refined_along_x;
13012  if (frc & RefinementCase<dim>::cut_y)
13013  ++refined_along_y;
13014  }
13015  else
13016  // this has to be an isotropic
13017  // child
13018  {
13019  ++refined_along_x;
13020  ++refined_along_y;
13021  }
13022 // step 2: detect, along which axis the face has to be refined given the current
13023 // refine flag
13024  RefinementCase<dim-1> flagged_frc=
13025  GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
13026  i,
13027  cell->face_orientation(i),
13028  cell->face_flip(i),
13029  cell->face_rotation(i));
13030  if (flagged_frc & RefinementCase<dim>::cut_x)
13031  ++to_be_refined_along_x;
13032  if (flagged_frc & RefinementCase<dim>::cut_y)
13033  ++to_be_refined_along_y;
13034 
13035 // step 3: set the refine flag of the (coarser and active) neighbor.
13037  cell->neighbor(i)->refine_flag_set())
13038  {
13039  if (refined_along_x + to_be_refined_along_x > 1)
13040  changed |= cell->neighbor(i)->flag_for_face_refinement(nb_indices.first,
13042  if (refined_along_y + to_be_refined_along_y > 1)
13043  changed |= cell->neighbor(i)->flag_for_face_refinement(nb_indices.first,
13045  }
13046  else
13047  {
13048  if (cell->neighbor(i)->refine_flag_set()!=RefinementCase<dim>::isotropic_refinement)
13049  changed=true;
13050  cell->neighbor(i)->set_refine_flag();
13051  }
13052 
13053 // step 4: if necessary (see above) add to the refine flag of the current cell
13054  cell_iterator nb=cell->neighbor(i);
13055  RefinementCase<dim-1> nb_frc
13056  = GeometryInfo<dim>::face_refinement_case(nb->refine_flag_set(),
13057  nb_indices.first,
13058  nb->face_orientation(nb_indices.first),
13059  nb->face_flip(nb_indices.first),
13060  nb->face_rotation(nb_indices.first));
13061  if ((nb_frc & RefinementCase<dim>::cut_x) &&
13062  !(refined_along_x || to_be_refined_along_x))
13063  changed |= cell->flag_for_face_refinement(i,RefinementCase<dim-1>::cut_axis(0));
13064  if ((nb_frc & RefinementCase<dim>::cut_y) &&
13065  !(refined_along_y || to_be_refined_along_y))
13066  changed |= cell->flag_for_face_refinement(i,RefinementCase<dim-1>::cut_axis(1));
13067  }
13068  }// if neighbor is coarser
13069  else // -> now the neighbor is not coarser
13070  {
13071  cell->neighbor(i)->clear_coarsen_flag();
13072  const unsigned int nb_nb=cell->neighbor_of_neighbor(i);
13073  const cell_iterator neighbor=cell->neighbor(i);
13074  RefinementCase<dim-1> face_ref_case=
13075  GeometryInfo<dim>::face_refinement_case(neighbor->refine_flag_set(),
13076  nb_nb,
13077  neighbor->face_orientation(nb_nb),
13078  neighbor->face_flip(nb_nb),
13079  neighbor->face_rotation(nb_nb));
13080  RefinementCase<dim-1> needed_face_ref_case
13081  =GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
13082  i,
13083  cell->face_orientation(i),
13084  cell->face_flip(i),
13085  cell->face_rotation(i));
13086  // if the neighbor wants to refine the
13087  // face with cut_x and we want cut_y
13088  // or vice versa, we have to refine
13089  // isotropically at the given face
13090  if ((face_ref_case==RefinementCase<dim>::cut_x && needed_face_ref_case==RefinementCase<dim>::cut_y) ||
13091  (face_ref_case==RefinementCase<dim>::cut_y && needed_face_ref_case==RefinementCase<dim>::cut_x))
13092  {
13093  changed=cell->flag_for_face_refinement(i, face_ref_case);
13094  neighbor->flag_for_face_refinement(nb_nb, needed_face_ref_case);
13095  }
13096  }
13097  }
13098  else //-> the neighbor is not active
13099  {
13100  RefinementCase<dim-1> face_ref_case = cell->face(i)->refinement_case(),
13101  needed_face_ref_case = GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
13102  i,
13103  cell->face_orientation(i),
13104  cell->face_flip(i),
13105  cell->face_rotation(i));
13106  // if the face is refined with cut_x and
13107  // we want cut_y or vice versa, we have to
13108  // refine isotropically at the given face
13109  if ((face_ref_case==RefinementCase<dim>::cut_x && needed_face_ref_case==RefinementCase<dim>::cut_y) ||
13110  (face_ref_case==RefinementCase<dim>::cut_y && needed_face_ref_case==RefinementCase<dim>::cut_x))
13111  changed=cell->flag_for_face_refinement(i, face_ref_case);
13112  }
13113  }
13114  }
13115  }
13116  }
13117 
13119  // STEP 7:
13120  // take care that no double refinement
13121  // is done at each line in 3d or higher
13122  // dimensions.
13124 
13126  // STEP 8:
13127  // make sure that all children of each
13128  // cell are either flagged for coarsening
13129  // or none of the children is
13130  fix_coarsen_flags ();
13131  // get the refinement and coarsening
13132  // flags
13133  std::vector<bool> flags_after_loop[2];
13134  save_coarsen_flags (flags_after_loop[0]);
13135  save_refine_flags (flags_after_loop[1]);
13136 
13137  // find out whether something was
13138  // changed in this loop
13139  mesh_changed_in_this_loop
13140  = ((flags_before_loop[0] != flags_after_loop[0]) ||
13141  (flags_before_loop[1] != flags_after_loop[1]));
13142 
13143  // set the flags for the next loop
13144  // already
13145  flags_before_loop[0].swap(flags_after_loop[0]);
13146  flags_before_loop[1].swap(flags_after_loop[1]);
13147  }
13148  while (mesh_changed_in_this_loop);
13149 
13150 
13151  // find out whether something was really changed in this
13152  // function. Note that @p{flags_before_loop} represents the state
13153  // after the last loop, i.e. the present state
13154  return ((flags_before[0] != flags_before_loop[0]) ||
13155  (flags_before[1] != flags_before_loop[1]));
13156 }
13157 
13158 
13159 
13160 
13161 template <int dim, int spacedim>
13162 void Triangulation<dim, spacedim>::write_bool_vector (const unsigned int magic_number1,
13163  const std::vector<bool> &v,
13164  const unsigned int magic_number2,
13165  std::ostream &out)
13166 {
13167  const unsigned int N = v.size();
13168  unsigned char *flags = new unsigned char[N/8+1];
13169  for (unsigned int i=0; i<N/8+1; ++i) flags[i]=0;
13170 
13171  for (unsigned int position=0; position<N; ++position)
13172  flags[position/8] |= (v[position] ? (1<<(position%8)) : 0);
13173 
13174  AssertThrow (out, ExcIO());
13175 
13176  // format:
13177  // 0. magic number
13178  // 1. number of flags
13179  // 2. the flags
13180  // 3. magic number
13181  out << magic_number1 << ' ' << N << std::endl;
13182  for (unsigned int i=0; i<N/8+1; ++i)
13183  out << static_cast<unsigned int>(flags[i]) << ' ';
13184 
13185  out << std::endl << magic_number2 << std::endl;
13186 
13187  delete[] flags;
13188 
13189  AssertThrow (out, ExcIO());
13190 }
13191 
13192 
13193 template <int dim, int spacedim>
13194 void Triangulation<dim, spacedim>::read_bool_vector (const unsigned int magic_number1,
13195  std::vector<bool> &v,
13196  const unsigned int magic_number2,
13197  std::istream &in)
13198 {
13199  AssertThrow (in, ExcIO());
13200 
13201  unsigned int magic_number;
13202  in >> magic_number;
13203  AssertThrow (magic_number==magic_number1, ExcGridReadError());
13204 
13205  unsigned int N;
13206  in >> N;
13207  v.resize (N);
13208 
13209  unsigned char *flags = new unsigned char[N/8+1];
13210  unsigned short int tmp;
13211  for (unsigned int i=0; i<N/8+1; ++i)
13212  {
13213  in >> tmp;
13214  flags[i] = tmp;
13215  }
13216 
13217  for (unsigned int position=0; position!=N; ++position)
13218  v[position] = (flags[position/8] & (1<<(position%8)));
13219 
13220  in >> magic_number;
13221  AssertThrow (magic_number==magic_number2, ExcGridReadError());
13222 
13223  delete[] flags;
13224 
13225  AssertThrow (in, ExcIO());
13226 }
13227 
13228 
13229 
13230 template <int dim, int spacedim>
13231 std::size_t
13233 {
13234  std::size_t mem = 0;
13236  for (unsigned int i=0; i<levels.size(); ++i)
13240  mem += sizeof(manifold);
13241  mem += sizeof(smooth_grid);
13243  mem += sizeof (faces);
13245 
13246  return mem;
13247 }
13248 
13249 
13250 
13251 
13252 template<int dim, int spacedim>
13254 {
13255  // don't do anything here. the compiler will automatically convert
13256  // any exceptions created by the destructors of the member variables
13257  // into abort() in order to satisfy the throw() specification
13258 }
13259 
13260 
13261 template <>
13263 {
13264  Assert(false, ExcImpossibleInDim(1));
13265  // We cannot simply create a temporary Manifold<2,1> because it is not
13266  // instantiated and would lead to unresolved symbols. Given the fact that
13267  // this function should be unreachable anyaway, just dereference a
13268  // nullptr:
13269  return *static_cast<FlatManifold<2,1>*>(0);
13270 }
13271 
13272 template <>
13274 {
13275  Assert(false, ExcImpossibleInDim(1));
13276  // We cannot simply create a temporary Manifold<2,1> because it is not
13277  // instantiated and would lead to unresolved symbols. Given the fact that
13278  // this function should be unreachable anyaway, just dereference a
13279  // nullptr:
13280  return *static_cast<FlatManifold<3,1>*>(0);
13281 }
13282 
13283 template <>
13285 {
13286  Assert(false, ExcImpossibleInDim(2));
13287  // We cannot simply create a temporary Manifold<2,1> because it is not
13288  // instantiated and would lead to unresolved symbols. Given the fact that
13289  // this function should be unreachable anyaway, just dereference a
13290  // nullptr:
13291  return *static_cast<FlatManifold<3,2>*>(0);
13292 }
13293 
13294 // explicit instantiations
13295 #include "tria.inst"
13296 
13297 DEAL_II_NAMESPACE_CLOSE
std::vector< CellData< 1 > > boundary_lines
Definition: tria.h:179
std::vector<::internal::Triangulation::TriaLevel< dim > * > levels
Definition: tria.h:3283
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::Triangulation::NumberCache< 1 > &number_cache)
Definition: tria.cc:1174
TriaActiveIterator< CellAccessor< dim, spacedim > > active_cell_iterator
Definition: tria.h:1410
boost::signals2::signal< void()> any_change
Definition: tria.h:2045
unsigned int n_active_cells() const
Definition: tria.cc:10973
void set_boundary(const types::manifold_id number, const Boundary< dim, spacedim > &boundary_object)
Definition: tria.cc:8843
unsigned int n_vertices() const
std::map< unsigned int, types::boundary_id > * vertex_to_boundary_id_map_1d
Definition: tria.h:3347
unsigned int n_used_vertices() const
Definition: tria.cc:11501
const types::manifold_id flat_manifold_id
Definition: types.h:228
static const unsigned int invalid_unsigned_int
Definition: types.h:164
void load_user_flags_line(std::istream &in)
Definition: tria.cc:9753
hex_iterator begin_hex(const unsigned int level=0) const
Definition: tria.cc:10865
const types::subdomain_id invalid_subdomain_id
Definition: types.h:239
void clear_user_flags()
Definition: tria.cc:9618
active_face_iterator begin_active_face() const
Definition: tria.cc:10577
::internal::Triangulation::NumberCache< dim > number_cache
Definition: tria.h:3331
void save_user_flags_quad(std::ostream &out) const
Definition: tria.cc:9852
virtual bool has_hanging_nodes() const
Definition: tria.cc:11095
TriaRawIterator< CellAccessor< dim, spacedim > > raw_cell_iterator
Definition: tria.h:3096
unsigned int n_raw_cells(const unsigned int level) const
Definition: tria.cc:11039
cell_iterator last() const
Definition: tria.cc:10417
void save_user_pointers_hex(std::vector< void *> &v) const
Definition: tria.cc:10319
vertex_iterator begin_vertex() const
Definition: tria.cc:10621
static RefinementCase< 1 > line_refinement_case(const RefinementCase< dim > &cell_refinement_case, const unsigned int line_no)
unsigned int n_cells() const
Definition: tria.cc:10966
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:1665
int face(const unsigned int i) const
Definition: tria_object.h:168
unsigned int n_raw_hexs() const
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:2907
std::list< typename Triangulation< dim, spacedim >::cell_iterator > distorted_cells
Definition: tria.h:1460
std::vector< Point< spacedim > > vertices
Definition: tria.h:3296
boost::signals2::signal< void()> clear
Definition: tria.h:2034
static unsigned int line_to_cell_vertices(const unsigned int line, const unsigned int vertex)
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::Triangulation::NumberCache< 3 > &number_cache)
Definition: tria.cc:1388
IteratorRange< active_cell_iterator > active_cell_iterators() const
Definition: tria.cc:10521
std::vector< types::boundary_id > get_boundary_indicators() const DEAL_II_DEPRECATED
Definition: tria.cc:9012
void set_all_refine_flags()
Definition: tria.cc:9321
void load_user_flags(std::istream &in)
Definition: tria.cc:9675
::ExceptionBase & ExcMessage(std::string arg1)
static void compute_number_cache(const Triangulation< dim, spacedim > &triangulation, const unsigned int level_objects, internal::Triangulation::NumberCache< 2 > &number_cache)
Definition: tria.cc:1284
bool anisotropic_refinement
Definition: tria.h:3313
std::vector< unsigned int > n_active_lines_level
Definition: tria.h:269
std::vector< unsigned int > n_hexes_level
Definition: tria.h:376
DeclException1(ExcGridHasInvalidCell, int,<< "Something went wrong when making cell "<< arg1<< ". Read the docs and the source code "<< "for more information.")
boost::signals2::signal< void(const typename Triangulation< dim, spacedim >::cell_iterator &cell)> pre_coarsening_on_cell
Definition: tria.h:2010
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:13194
line_iterator begin_line(const unsigned int level=0) const
Definition: tria.cc:10705
line_iterator end_line() const
Definition: tria.cc:10737
virtual void copy_triangulation(const Triangulation< dim, spacedim > &old_tria)
Definition: tria.cc:9043
void clear_user_flags_quad()
Definition: tria.cc:9578
unsigned int n_faces() const
Definition: tria.cc:10987
std::vector< unsigned int > n_quads_level
Definition: tria.h:317
void flip_all_direction_flags()
Definition: tria.cc:9310
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)
static Triangulation< 3, spacedim >::DistortedCellList execute_refinement(Triangulation< 3, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:4771
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: tria.cc:10397
#define AssertThrow(cond, exc)
Definition: exceptions.h:358
static Triangulation< 1, spacedim >::DistortedCellList execute_refinement(Triangulation< 1, spacedim > &triangulation, const bool)
Definition: tria.cc:4174
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:3704
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:13162
unsigned int n_active_hexs() const
Definition: tria.cc:11439
void save_user_pointers_quad(std::vector< void *> &v) const
Definition: tria.cc:10286
std::vector< unsigned int > n_active_quads_level
Definition: tria.h:327
void execute_coarsening()
Definition: tria.cc:11725
const Boundary< dim, spacedim > & get_boundary(const types::manifold_id number) const
Definition: tria.cc:8942
cell_iterator begin(const unsigned int level=0) const
Definition: tria.cc:10377
void load_user_flags_quad(std::istream &in)
Definition: tria.cc:9863
unsigned int n_levels() const
void set_manifold(const types::manifold_id number, const Manifold< dim, spacedim > &manifold_object)
Definition: tria.cc:8851
raw_hex_iterator begin_raw_hex(const unsigned int level=0) const
Definition: tria.cc:10835
void load_user_pointers_line(const std::vector< void *> &v)
Definition: tria.cc:10272
unsigned int n_active_faces() const
Definition: tria.cc:11021
raw_quad_iterator begin_raw_quad(const unsigned int level=0) const
Definition: tria.cc:10751
cell_iterator end() const
Definition: tria.cc:10465
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:2013
void load_coarsen_flags(std::istream &out)
Definition: tria.cc:9446
void load_user_flags_hex(std::istream &in)
Definition: tria.cc:9926
DeclException5(ExcInteriorQuadCantBeBoundary, int, int, int, int, types::boundary_id,<< "The input data for creating a triangulation contained "<< "information about a quad with indices "<< arg1<< ", "<< arg2<< ", "<< arg3<< ", and "<< arg4<< " that is described to have boundary indicator "<<(int) arg5<< ". However, this is an internal quad not located on the "<< "boundary. You cannot assign a boundary indicator to it."<< std::endl<< std::endl<< "If this happened at a place where you call "<< "Triangulation::create_triangulation() yourself, you need "<< "to check the SubCellData object you pass to this function."<< std::endl<< std::endl<< "If this happened in a place where you are reading a mesh "<< "from a file, then you need to investigate why such a quad "<< "ended up in the input file. A typical case is a geometry "<< "that consisted of multiple parts and for which the mesh "<< "generator program assumes that the interface between "<< "two parts is a boundary when that isn't supposed to be "<< "the case, or where the mesh generator simply assigns "<< "'geometry indicators' to quads at the surface of "<< "a part that are not supposed to be interpreted as "<< "'boundary indicators'.")
active_quad_iterator begin_active_quad(const unsigned int level=0) const
Definition: tria.cc:10806
virtual void execute_coarsening_and_refinement()
Definition: tria.cc:11602
unsigned int n_active_lines() const
Definition: tria.cc:11188
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
Definition: tria.cc:10532
Definition: tria.h:46
virtual bool prepare_coarsening_and_refinement()
Definition: tria.cc:12269
bool check_consistency(const unsigned int dim) const
Definition: tria.cc:47
void reset_active_cell_indices()
Definition: tria.cc:11644
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
DistortedCellList execute_refinement()
Definition: tria.cc:11686
const bool check_for_distorted_cells
Definition: tria.h:3320
boost::signals2::signal< void()> pre_refinement
Definition: tria.h:1994
void save_user_flags_line(std::ostream &out) const
Definition: tria.cc:9742
void save_user_pointers_line(std::vector< void *> &v) const
Definition: tria.cc:10259
static bool coarsening_allowed(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
Definition: tria.cc:8672
Triangulation(const MeshSmoothing smooth_grid=none, const bool check_for_distorted_cells=false)
Definition: tria.cc:8751
double cell_measure(const std::vector< Point< dim > > &all_vertices, const unsigned int(&vertex_indices)[GeometryInfo< dim >::vertices_per_cell])
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
Definition: tria.h:1392
void clear_user_flags_hex()
Definition: tria.cc:9610
void load_user_indices_line(const std::vector< unsigned int > &v)
Definition: tria.cc:10074
unsigned int global_dof_index
Definition: types.h:88
static unsigned int face_to_cell_lines(const unsigned int face, const unsigned int line, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
vertex_iterator end_vertex() const
Definition: tria.cc:10658
unsigned int n_raw_quads() const
Definition: tria.cc:11381
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)
#define Assert(cond, exc)
Definition: exceptions.h:294
Signals signals
Definition: tria.h:2078
active_hex_iterator begin_active_hex(const unsigned int level=0) const
Definition: tria.cc:10881
void save_user_indices_line(std::vector< unsigned int > &v) const
Definition: tria.cc:10061
std::map< types::manifold_id, SmartPointer< const Manifold< dim, spacedim >, Triangulation< dim, spacedim > > > manifold
Definition: tria.h:3307
void set_all_manifold_ids(const types::manifold_id number)
Definition: tria.cc:8882
boost::signals2::signal< void()> create
Definition: tria.h:1985
static const StraightBoundary< dim, spacedim > straight_boundary
Definition: tria.h:1171
unsigned int max_adjacent_cells() const
Definition: tria.cc:11542
bool get_anisotropic_refinement_flag() const
Definition: tria.cc:9475
unsigned int n_quads() const
Definition: tria.cc:11335
void clear_user_data(const unsigned int i)
Definition: tria_objects.h:659
std::vector< bool > vertices_used
Definition: tria.h:3301
void loop(ITERATOR begin, typename identity< ITERATOR >::type end, DOFINFO &dinfo, INFOBOX &info, const std_cxx11::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker, const std_cxx11::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker, const std_cxx11::function< void(DOFINFO &, DOFINFO &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, ASSEMBLER &assembler, const LoopControl &lctrl=LoopControl())
Definition: loop.h:370
DeclException4(ExcQuadInexistant, int, int, int, int,<< "While trying to assign a boundary indicator to a quad: "<< "the quad with bounding lines "<< arg1<< ", "<< arg2<< ", "<< arg3<< ", "<< arg4<< " does not exist.")
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
Definition: tria.cc:9130
void save_coarsen_flags(std::ostream &out) const
Definition: tria.cc:9435
void save_user_indices(std::vector< unsigned int > &v) const
Definition: tria.cc:9959
TriaObjects< TriaObject< 1 > > lines
Definition: tria_faces.h:97
void load_user_indices(const std::vector< unsigned int > &v)
Definition: tria.cc:9989
void save_refine_flags(std::ostream &out) const
Definition: tria.cc:9370
unsigned int n_lines() const
Definition: tria.cc:11106
void clear_despite_subscriptions()
Definition: tria.cc:11663
raw_cell_iterator begin_raw(const unsigned int level=0) const
Definition: tria.cc:10357
unsigned int n_raw_lines() const
Definition: tria.cc:11171
virtual ~Triangulation()
Definition: tria.cc:8796
virtual std::size_t memory_consumption() const
Definition: tria.cc:13232
std::map< unsigned int, types::manifold_id > * vertex_to_manifold_id_map_1d
Definition: tria.h:3369
virtual void set_mesh_smoothing(const MeshSmoothing mesh_smoothing)
Definition: tria.cc:8832
void load_user_pointers_hex(const std::vector< void *> &v)
Definition: tria.cc:10336
void save_user_flags_hex(std::ostream &out) const
Definition: tria.cc:9915
face_iterator begin_face() const
Definition: tria.cc:10556
unsigned int subdomain_id
Definition: types.h:42
boost::signals2::signal< void()> post_refinement
Definition: tria.h:2001
virtual types::global_dof_index n_global_active_cells() const
Definition: tria.cc:10979
unsigned int n_hexs() const
Definition: tria.cc:11416
DeclException2(ExcLineInexistant, int, int,<< "While trying to assign a boundary indicator to a line: "<< "the line with end vertices "<< arg1<< " and "<< arg2<< " does not exist.")
void set_face(const unsigned int i, const int index)
Definition: tria_object.h:179
unsigned int n_active_quads() const
Definition: tria.cc:11398
TriaObjects< TriaObject< 1 > > lines
Definition: tria_faces.h:132
active_line_iterator begin_active_line(const unsigned int level=0) const
Definition: tria.cc:10721
raw_cell_iterator end_raw(const unsigned int level) const
Definition: tria.cc:10476
unsigned int n_raw_faces() const
Definition: tria.cc:11005
void load_user_indices_hex(const std::vector< unsigned int > &v)
Definition: tria.cc:10137
active_vertex_iterator begin_active_vertex() const
Definition: tria.cc:10649
static void alternating_form_at_vertices(const Point< spacedim >(&vertices)[vertices_per_cell], Tensor< spacedim-dim, spacedim >(&forms)[vertices_per_cell])
DeclException3(ExcInvalidVertexIndex, int, int, int,<< "Error while creating cell "<< arg1<< ": the vertex index "<< arg2<< " must be between 0 and "<< arg3<< ".")
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
std::vector< types::boundary_id > get_boundary_ids() const
Definition: tria.cc:8980
const types::manifold_id invalid_manifold_id
Definition: types.h:220
std::vector< unsigned int > n_active_hexes_level
Definition: tria.h:386
unsigned int manifold_id
Definition: types.h:122
void load_user_pointers_quad(const std::vector< void *> &v)
Definition: tria.cc:10303
void fix_coarsen_flags()
Definition: tria.cc:11815
active_cell_iterator end_active(const unsigned int level) const
Definition: tria.cc:10499
static void prevent_distorted_boundary_cells(const Triangulation< 1, spacedim > &)
::internal::Triangulation::TriaFaces< dim > * faces
Definition: tria.h:3290
Definition: mpi.h:48
void save_user_indices_quad(std::vector< unsigned int > &v) const
Definition: tria.cc:10087
const std::vector< bool > & get_used_vertices() const
Definition: tria.cc:11511
virtual unsigned int n_global_levels() const
hex_iterator end_hex() const
Definition: tria.cc:10897
std::vector< CellData< 2 > > boundary_quads
Definition: tria.h:185
MeshSmoothing smooth_grid
Definition: tria.h:3053
IteratorRange< active_cell_iterator > active_cell_iterators_on_level(const unsigned int level) const
Definition: tria.cc:10543
void load_user_pointers(const std::vector< void *> &v)
Definition: tria.cc:10224
void refine_global(const unsigned int times=1)
Definition: tria.cc:9337
void save_user_pointers(std::vector< void *> &v) const
Definition: tria.cc:10194
void save_user_flags(std::ostream &out) const
Definition: tria.cc:9628
Iterator points to a valid object.
quad_iterator end_quad() const
Definition: tria.cc:10822
IteratorRange< cell_iterator > cell_iterators() const
Definition: tria.cc:10511
unsigned char boundary_id
Definition: types.h:110
face_iterator end_face() const
Definition: tria.cc:10598
void set_all_manifold_ids_on_boundary(const types::manifold_id number)
Definition: tria.cc:8894
active_cell_iterator last_active() const
Definition: tria.cc:10444
const types::boundary_id internal_face_boundary_id
Definition: types.h:210
void clear_user_flags_line()
Definition: tria.cc:9546
IteratorState::IteratorStates state() const
static Triangulation< 2, spacedim >::DistortedCellList execute_refinement(Triangulation< 2, spacedim > &triangulation, const bool check_for_distorted_cells)
Definition: tria.cc:4416
quad_iterator begin_quad(const unsigned int level=0) const
Definition: tria.cc:10790
static void prepare_refinement_dim_dependent(const Triangulation< dim, spacedim > &)
Definition: tria.cc:8487
void clear_user_data()
Definition: tria.cc:9518
std::vector< types::manifold_id > get_manifold_ids() const
Definition: tria.cc:9021
bool vertex_used(const unsigned int index) const
const Manifold< dim, spacedim > & get_manifold(const types::manifold_id number) const
Definition: tria.cc:8955
virtual void create_triangulation_compatibility(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
Definition: tria.cc:9110
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)
void load_user_indices_quad(const std::vector< unsigned int > &v)
Definition: tria.cc:10104
virtual types::subdomain_id locally_owned_subdomain() const
Definition: tria.cc:11575
raw_line_iterator begin_raw_line(const unsigned int level=0) const
Definition: tria.cc:10680
virtual void clear()
Definition: tria.cc:8822
boost::signals2::signal< void(const Triangulation< dim, spacedim > &destination_tria)> copy
Definition: tria.h:2026
void load_refine_flags(std::istream &in)
Definition: tria.cc:9381
std::vector< unsigned int > n_lines_level
Definition: tria.h:259
Triangulation< dim, spacedim > & get_triangulation()
Definition: tria.cc:11584
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:1481
void save_user_indices_hex(std::vector< unsigned int > &v) const
Definition: tria.cc:10120