Reference documentation for deal.II version 8.5.1
grid_tools.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2001 - 2017 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 #include <deal.II/base/std_cxx11/array.h>
17 #include <deal.II/base/quadrature_lib.h>
18 #include <deal.II/base/thread_management.h>
19 #include <deal.II/lac/vector.h>
20 #include <deal.II/lac/vector_memory.h>
21 #include <deal.II/lac/filtered_matrix.h>
22 #include <deal.II/lac/precondition.h>
23 #include <deal.II/lac/solver_cg.h>
24 #include <deal.II/lac/sparse_matrix.h>
25 #include <deal.II/lac/dynamic_sparsity_pattern.h>
26 #include <deal.II/lac/constraint_matrix.h>
27 #include <deal.II/lac/sparsity_pattern.h>
28 #include <deal.II/lac/sparsity_tools.h>
29 #include <deal.II/grid/filtered_iterator.h>
30 #include <deal.II/grid/tria.h>
31 #include <deal.II/distributed/tria.h>
32 #include <deal.II/distributed/shared_tria.h>
33 #include <deal.II/distributed/tria_base.h>
34 #include <deal.II/grid/tria_accessor.h>
35 #include <deal.II/grid/tria_iterator.h>
36 #include <deal.II/grid/tria_boundary.h>
37 #include <deal.II/grid/grid_generator.h>
38 #include <deal.II/grid/grid_tools.h>
39 #include <deal.II/dofs/dof_handler.h>
40 #include <deal.II/dofs/dof_accessor.h>
41 #include <deal.II/dofs/dof_tools.h>
42 #include <deal.II/fe/fe_nothing.h>
43 #include <deal.II/fe/mapping_q1.h>
44 #include <deal.II/fe/mapping_q.h>
45 #include <deal.II/fe/fe_values.h>
46 #include <deal.II/hp/mapping_collection.h>
47 #include <deal.II/numerics/matrix_tools.h>
48 
49 #include <boost/random/uniform_real_distribution.hpp>
50 #include <boost/random/mersenne_twister.hpp>
51 
52 #include <cmath>
53 #include <numeric>
54 #include <list>
55 #include <set>
56 
57 
58 DEAL_II_NAMESPACE_OPEN
59 
60 
61 namespace GridTools
62 {
63 
64  template <int dim, int spacedim>
65  double
67  {
68  // we can't deal with distributed meshes since we don't have all
69  // vertices locally. there is one exception, however: if the mesh has
70  // never been refined. the way to test this is not to ask
71  // tria.n_levels()==1, since this is something that can happen on one
72  // processor without being true on all. however, we can ask for the
73  // global number of active cells and use that
74 #if defined(DEAL_II_WITH_P4EST) && defined(DEBUG)
76  = dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>(&tria))
77  Assert (p_tria->n_global_active_cells() == tria.n_cells(0),
79 #endif
80 
81  // the algorithm used simply traverses all cells and picks out the
82  // boundary vertices. it may or may not be faster to simply get all
83  // vectors, don't mark boundary vertices, and compute the distances
84  // thereof, but at least as the mesh is refined, it seems better to
85  // first mark boundary nodes, as marking is O(N) in the number of
86  // cells/vertices, while computing the maximal distance is O(N*N)
87  const std::vector<Point<spacedim> > &vertices = tria.get_vertices ();
88  std::vector<bool> boundary_vertices (vertices.size(), false);
89 
91  cell = tria.begin_active();
93  endc = tria.end();
94  for (; cell!=endc; ++cell)
95  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
96  if (cell->face(face)->at_boundary ())
97  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
98  boundary_vertices[cell->face(face)->vertex_index(i)] = true;
99 
100  // now traverse the list of boundary vertices and check distances.
101  // since distances are symmetric, we only have to check one half
102  double max_distance_sqr = 0;
103  std::vector<bool>::const_iterator pi = boundary_vertices.begin();
104  const unsigned int N = boundary_vertices.size();
105  for (unsigned int i=0; i<N; ++i, ++pi)
106  {
107  std::vector<bool>::const_iterator pj = pi+1;
108  for (unsigned int j=i+1; j<N; ++j, ++pj)
109  if ((*pi==true) && (*pj==true) &&
110  ((vertices[i]-vertices[j]).norm_square() > max_distance_sqr))
111  max_distance_sqr = (vertices[i]-vertices[j]).norm_square();
112  };
113 
114  return std::sqrt(max_distance_sqr);
115  }
116 
117 
118 
119  template <int dim, int spacedim>
120  double
121  volume (const Triangulation<dim, spacedim> &triangulation,
122  const Mapping<dim,spacedim> &mapping)
123  {
124  // get the degree of the mapping if possible. if not, just assume 1
125  const unsigned int mapping_degree
126  = (dynamic_cast<const MappingQ<dim,spacedim>*>(&mapping) != 0 ?
127  dynamic_cast<const MappingQ<dim,spacedim>*>(&mapping)->get_degree() :
128  1);
129 
130  // then initialize an appropriate quadrature formula
131  const QGauss<dim> quadrature_formula (mapping_degree + 1);
132  const unsigned int n_q_points = quadrature_formula.size();
133 
134  // we really want the JxW values from the FEValues object, but it
135  // wants a finite element. create a cheap element as a dummy
136  // element
137  FE_Nothing<dim,spacedim> dummy_fe;
138  FEValues<dim,spacedim> fe_values (mapping, dummy_fe, quadrature_formula,
140 
142  cell = triangulation.begin_active(),
143  endc = triangulation.end();
144 
145  double local_volume = 0;
146 
147  // compute the integral quantities by quadrature
148  for (; cell!=endc; ++cell)
149  if (cell->is_locally_owned())
150  {
151  fe_values.reinit (cell);
152  for (unsigned int q=0; q<n_q_points; ++q)
153  local_volume += fe_values.JxW(q);
154  }
155 
156  double global_volume = 0;
157 
158 #ifdef DEAL_II_WITH_MPI
159  if (const parallel::Triangulation<dim,spacedim> *p_tria
160  = dynamic_cast<const parallel::Triangulation<dim,spacedim>*>(&triangulation))
161  global_volume = Utilities::MPI::sum (local_volume, p_tria->get_communicator());
162  else
163 #endif
164  global_volume = local_volume;
165 
166  return global_volume;
167  }
168 
169 
170 
171  template <>
172  double
173  cell_measure<1>
174  (const std::vector<Point<1> > &all_vertices,
175  const unsigned int (&vertex_indices)[GeometryInfo<1>::vertices_per_cell])
176  {
177  return all_vertices[vertex_indices[1]][0]
178  - all_vertices[vertex_indices[0]][0];
179  }
180 
181 
182 
183  template <>
184  double
185  cell_measure<3>
186  (const std::vector<Point<3> > &all_vertices,
187  const unsigned int (&vertex_indices)[GeometryInfo<3>::vertices_per_cell])
188  {
189  // note that this is the
190  // cell_measure based on the new
191  // deal.II numbering. When called
192  // from inside GridReordering make
193  // sure that you reorder the
194  // vertex_indices before
195  const double x[8] = { all_vertices[vertex_indices[0]](0),
196  all_vertices[vertex_indices[1]](0),
197  all_vertices[vertex_indices[2]](0),
198  all_vertices[vertex_indices[3]](0),
199  all_vertices[vertex_indices[4]](0),
200  all_vertices[vertex_indices[5]](0),
201  all_vertices[vertex_indices[6]](0),
202  all_vertices[vertex_indices[7]](0)
203  };
204  const double y[8] = { all_vertices[vertex_indices[0]](1),
205  all_vertices[vertex_indices[1]](1),
206  all_vertices[vertex_indices[2]](1),
207  all_vertices[vertex_indices[3]](1),
208  all_vertices[vertex_indices[4]](1),
209  all_vertices[vertex_indices[5]](1),
210  all_vertices[vertex_indices[6]](1),
211  all_vertices[vertex_indices[7]](1)
212  };
213  const double z[8] = { all_vertices[vertex_indices[0]](2),
214  all_vertices[vertex_indices[1]](2),
215  all_vertices[vertex_indices[2]](2),
216  all_vertices[vertex_indices[3]](2),
217  all_vertices[vertex_indices[4]](2),
218  all_vertices[vertex_indices[5]](2),
219  all_vertices[vertex_indices[6]](2),
220  all_vertices[vertex_indices[7]](2)
221  };
222 
223  /*
224  This is the same Maple script as in the barycenter method above
225  except of that here the shape functions tphi[0]-tphi[7] are ordered
226  according to the lexicographic numbering.
227 
228  x := array(0..7):
229  y := array(0..7):
230  z := array(0..7):
231  tphi[0] := (1-xi)*(1-eta)*(1-zeta):
232  tphi[1] := xi*(1-eta)*(1-zeta):
233  tphi[2] := (1-xi)* eta*(1-zeta):
234  tphi[3] := xi* eta*(1-zeta):
235  tphi[4] := (1-xi)*(1-eta)*zeta:
236  tphi[5] := xi*(1-eta)*zeta:
237  tphi[6] := (1-xi)* eta*zeta:
238  tphi[7] := xi* eta*zeta:
239  x_real := sum(x[s]*tphi[s], s=0..7):
240  y_real := sum(y[s]*tphi[s], s=0..7):
241  z_real := sum(z[s]*tphi[s], s=0..7):
242  with (linalg):
243  J := matrix(3,3, [[diff(x_real, xi), diff(x_real, eta), diff(x_real, zeta)],
244  [diff(y_real, xi), diff(y_real, eta), diff(y_real, zeta)],
245  [diff(z_real, xi), diff(z_real, eta), diff(z_real, zeta)]]):
246  detJ := det (J):
247 
248  measure := simplify ( int ( int ( int (detJ, xi=0..1), eta=0..1), zeta=0..1)):
249 
250  readlib(C):
251 
252  C(measure, optimized);
253 
254  The C code produced by this maple script is further optimized by
255  hand. In particular, division by 12 is performed only once, not
256  hundred of times.
257  */
258 
259  const double t3 = y[3]*x[2];
260  const double t5 = z[1]*x[5];
261  const double t9 = z[3]*x[2];
262  const double t11 = x[1]*y[0];
263  const double t14 = x[4]*y[0];
264  const double t18 = x[5]*y[7];
265  const double t20 = y[1]*x[3];
266  const double t22 = y[5]*x[4];
267  const double t26 = z[7]*x[6];
268  const double t28 = x[0]*y[4];
269  const double t34 = z[3]*x[1]*y[2]+t3*z[1]-t5*y[7]+y[7]*x[4]*z[6]+t9*y[6]-t11*z[4]-t5*y[3]-t14*z[2]+z[1]*x[4]*y[0]-t18*z[3]+t20*z[0]-t22*z[0]-y[0]*x[5]*z[4]-t26*y[3]+t28*z[2]-t9*y[1]-y[1]*x[4]*z[0]-t11*z[5];
270  const double t37 = y[1]*x[0];
271  const double t44 = x[1]*y[5];
272  const double t46 = z[1]*x[0];
273  const double t49 = x[0]*y[2];
274  const double t52 = y[5]*x[7];
275  const double t54 = x[3]*y[7];
276  const double t56 = x[2]*z[0];
277  const double t58 = x[3]*y[2];
278  const double t64 = -x[6]*y[4]*z[2]-t37*z[2]+t18*z[6]-x[3]*y[6]*z[2]+t11*z[2]+t5*y[0]+t44*z[4]-t46*y[4]-t20*z[7]-t49*z[6]-t22*z[1]+t52*z[3]-t54*z[2]-t56*y[4]-t58*z[0]+y[1]*x[2]*z[0]+t9*y[7]+t37*z[4];
279  const double t66 = x[1]*y[7];
280  const double t68 = y[0]*x[6];
281  const double t70 = x[7]*y[6];
282  const double t73 = z[5]*x[4];
283  const double t76 = x[6]*y[7];
284  const double t90 = x[4]*z[0];
285  const double t92 = x[1]*y[3];
286  const double t95 = -t66*z[3]-t68*z[2]-t70*z[2]+t26*y[5]-t73*y[6]-t14*z[6]+t76*z[2]-t3*z[6]+x[6]*y[2]*z[4]-z[3]*x[6]*y[2]+t26*y[4]-t44*z[3]-x[1]*y[2]*z[0]+x[5]*y[6]*z[4]+t54*z[5]+t90*y[2]-t92*z[2]+t46*y[2];
287  const double t102 = x[2]*y[0];
288  const double t107 = y[3]*x[7];
289  const double t114 = x[0]*y[6];
290  const double t125 = y[0]*x[3]*z[2]-z[7]*x[5]*y[6]-x[2]*y[6]*z[4]+t102*z[6]-t52*z[6]+x[2]*y[4]*z[6]-t107*z[5]-t54*z[6]+t58*z[6]-x[7]*y[4]*z[6]+t37*z[5]-t114*z[4]+t102*z[4]-z[1]*x[2]*y[0]+t28*z[6]-y[5]*x[6]*z[4]-z[5]*x[1]*y[4]-t73*y[7];
291  const double t129 = z[0]*x[6];
292  const double t133 = y[1]*x[7];
293  const double t145 = y[1]*x[5];
294  const double t156 = t90*y[6]-t129*y[4]+z[7]*x[2]*y[6]-t133*z[5]+x[5]*y[3]*z[7]-t26*y[2]-t70*z[3]+t46*y[3]+z[5]*x[7]*y[4]+z[7]*x[3]*y[6]-t49*z[4]+t145*z[7]-x[2]*y[7]*z[6]+t70*z[5]+t66*z[5]-z[7]*x[4]*y[6]+t18*z[4]+x[1]*y[4]*z[0];
295  const double t160 = x[5]*y[4];
296  const double t165 = z[1]*x[7];
297  const double t178 = z[1]*x[3];
298  const double t181 = t107*z[6]+t22*z[7]+t76*z[3]+t160*z[1]-x[4]*y[2]*z[6]+t70*z[4]+t165*y[5]+x[7]*y[2]*z[6]-t76*z[5]-t76*z[4]+t133*z[3]-t58*z[1]+y[5]*x[0]*z[4]+t114*z[2]-t3*z[7]+t20*z[2]+t178*y[7]+t129*y[2];
299  const double t207 = t92*z[7]+t22*z[6]+z[3]*x[0]*y[2]-x[0]*y[3]*z[2]-z[3]*x[7]*y[2]-t165*y[3]-t9*y[0]+t58*z[7]+y[3]*x[6]*z[2]+t107*z[2]+t73*y[0]-x[3]*y[5]*z[7]+t3*z[0]-t56*y[6]-z[5]*x[0]*y[4]+t73*y[1]-t160*z[6]+t160*z[0];
300  const double t228 = -t44*z[7]+z[5]*x[6]*y[4]-t52*z[4]-t145*z[4]+t68*z[4]+t92*z[5]-t92*z[0]+t11*z[3]+t44*z[0]+t178*y[5]-t46*y[5]-t178*y[0]-t145*z[0]-t20*z[5]-t37*z[3]-t160*z[7]+t145*z[3]+x[4]*y[6]*z[2];
301 
302  return (t34+t64+t95+t125+t156+t181+t207+t228)/12.;
303  }
304 
305 
306 
307  template <>
308  double
309  cell_measure<2>
310  (const std::vector<Point<2> > &all_vertices,
311  const unsigned int (&vertex_indices) [GeometryInfo<2>::vertices_per_cell])
312  {
313  /*
314  Get the computation of the measure by this little Maple script. We
315  use the blinear mapping of the unit quad to the real quad. However,
316  every transformation mapping the unit faces to straight lines should
317  do.
318 
319  Remember that the area of the quad is given by
320  \int_K 1 dx dy = \int_{\hat K} |det J| d(xi) d(eta)
321 
322  # x and y are arrays holding the x- and y-values of the four vertices
323  # of this cell in real space.
324  x := array(0..3);
325  y := array(0..3);
326  z := array(0..3);
327  tphi[0] := (1-xi)*(1-eta):
328  tphi[1] := xi*(1-eta):
329  tphi[2] := (1-xi)*eta:
330  tphi[3] := xi*eta:
331  x_real := sum(x[s]*tphi[s], s=0..3):
332  y_real := sum(y[s]*tphi[s], s=0..3):
333  z_real := sum(z[s]*tphi[s], s=0..3):
334 
335  Jxi := <diff(x_real,xi) | diff(y_real,xi) | diff(z_real,xi)>;
336  Jeta := <diff(x_real,eta)| diff(y_real,eta)| diff(z_real,eta)>;
337  with(VectorCalculus):
338  J := CrossProduct(Jxi, Jeta);
339  detJ := sqrt(J[1]^2 + J[2]^2 +J[3]^2);
340 
341  # measure := evalf (Int (Int (detJ, xi=0..1, method = _NCrule ) , eta=0..1, method = _NCrule ) ):
342  # readlib(C):
343 
344  # C(measure, optimized);
345 
346  additional optimizaton: divide by 2 only one time
347  */
348 
349  const double x[4] = { all_vertices[vertex_indices[0]](0),
350  all_vertices[vertex_indices[1]](0),
351  all_vertices[vertex_indices[2]](0),
352  all_vertices[vertex_indices[3]](0)
353  };
354 
355  const double y[4] = { all_vertices[vertex_indices[0]](1),
356  all_vertices[vertex_indices[1]](1),
357  all_vertices[vertex_indices[2]](1),
358  all_vertices[vertex_indices[3]](1)
359  };
360 
361  return (-x[1]*y[0]+x[1]*y[3]+y[0]*x[2]+x[0]*y[1]-x[0]*y[2]-y[1]*x[3]-x[2]*y[3]+x[3]*y[2])/2;
362 
363  }
364 
365 
366  template <int dim, int spacedim>
367  void
368  delete_unused_vertices (std::vector<Point<spacedim> > &vertices,
369  std::vector<CellData<dim> > &cells,
370  SubCellData &subcelldata)
371  {
372  Assert(subcelldata.check_consistency(dim),
373  ExcMessage("Invalid SubCellData supplied according to ::check_consistency(). "
374  "This is caused by data containing objects for the wrong dimension."));
375 
376  // first check which vertices are actually used
377  std::vector<bool> vertex_used (vertices.size(), false);
378  for (unsigned int c=0; c<cells.size(); ++c)
379  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
380  {
381  Assert(cells[c].vertices[v] < vertices.size(),
382  ExcMessage("Invalid vertex index encountered! cells["
384  + "].vertices["
386  + "]="
387  + Utilities::int_to_string(cells[c].vertices[v])
388  + " is invalid, because only "
389  + Utilities::int_to_string(vertices.size())
390  + " vertices were supplied."));
391  vertex_used[cells[c].vertices[v]] = true;
392  }
393 
394 
395  // then renumber the vertices that are actually used in the same order as
396  // they were beforehand
397  const unsigned int invalid_vertex = numbers::invalid_unsigned_int;
398  std::vector<unsigned int> new_vertex_numbers (vertices.size(), invalid_vertex);
399  unsigned int next_free_number = 0;
400  for (unsigned int i=0; i<vertices.size(); ++i)
401  if (vertex_used[i] == true)
402  {
403  new_vertex_numbers[i] = next_free_number;
404  ++next_free_number;
405  }
406 
407  // next replace old vertex numbers by the new ones
408  for (unsigned int c=0; c<cells.size(); ++c)
409  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
410  cells[c].vertices[v] = new_vertex_numbers[cells[c].vertices[v]];
411 
412  // same for boundary data
413  for (unsigned int c=0; c<subcelldata.boundary_lines.size(); ++c)
414  for (unsigned int v=0; v<GeometryInfo<1>::vertices_per_cell; ++v)
415  {
416  Assert(subcelldata.boundary_lines[c].vertices[v] < new_vertex_numbers.size(),
417  ExcMessage("Invalid vertex index in subcelldata.boundary_lines. "
418  "subcelldata.boundary_lines["
420  + "].vertices["
422  + "]="
423  + Utilities::int_to_string(subcelldata.boundary_lines[c].vertices[v])
424  + " is invalid, because only "
425  + Utilities::int_to_string(vertices.size())
426  + " vertices were supplied."));
427  subcelldata.boundary_lines[c].vertices[v]
428  = new_vertex_numbers[subcelldata.boundary_lines[c].vertices[v]];
429  }
430 
431  for (unsigned int c=0; c<subcelldata.boundary_quads.size(); ++c)
432  for (unsigned int v=0; v<GeometryInfo<2>::vertices_per_cell; ++v)
433  {
434  Assert(subcelldata.boundary_quads[c].vertices[v] < new_vertex_numbers.size(),
435  ExcMessage("Invalid vertex index in subcelldata.boundary_quads. "
436  "subcelldata.boundary_quads["
438  + "].vertices["
440  + "]="
441  + Utilities::int_to_string(subcelldata.boundary_quads[c].vertices[v])
442  + " is invalid, because only "
443  + Utilities::int_to_string(vertices.size())
444  + " vertices were supplied."));
445 
446  subcelldata.boundary_quads[c].vertices[v]
447  = new_vertex_numbers[subcelldata.boundary_quads[c].vertices[v]];
448  }
449 
450  // finally copy over the vertices which we really need to a new array and
451  // replace the old one by the new one
452  std::vector<Point<spacedim> > tmp;
453  tmp.reserve (std::count(vertex_used.begin(), vertex_used.end(), true));
454  for (unsigned int v=0; v<vertices.size(); ++v)
455  if (vertex_used[v] == true)
456  tmp.push_back (vertices[v]);
457  swap (vertices, tmp);
458  }
459 
460 
461 
462  template <int dim, int spacedim>
463  void
464  delete_duplicated_vertices (std::vector<Point<spacedim> > &vertices,
465  std::vector<CellData<dim> > &cells,
466  SubCellData &subcelldata,
467  std::vector<unsigned int> &considered_vertices,
468  double tol)
469  {
470  // create a vector of vertex
471  // indices. initialize it to the identity,
472  // later on change that if necessary.
473  std::vector<unsigned int> new_vertex_numbers(vertices.size());
474  for (unsigned int i=0; i<vertices.size(); ++i)
475  new_vertex_numbers[i] = i;
476 
477  // if the considered_vertices vector is
478  // empty, consider all vertices
479  if (considered_vertices.size()==0)
480  considered_vertices = new_vertex_numbers;
481 
482  Assert(considered_vertices.size() <= vertices.size(),
483  ExcInternalError());
484 
485 
486  // now loop over all vertices to be
487  // considered and try to find an identical
488  // one
489  for (unsigned int i=0; i<considered_vertices.size(); ++i)
490  {
491  Assert(considered_vertices[i]<vertices.size(),
492  ExcInternalError());
493  if (new_vertex_numbers[considered_vertices[i]]!=considered_vertices[i])
494  // this vertex has been identified with
495  // another one already, skip it in the
496  // test
497  continue;
498  // this vertex is not identified with
499  // another one so far. search in the list
500  // of remaining vertices. if a duplicate
501  // vertex is found, set the new vertex
502  // index for that vertex to this vertex'
503  // index.
504  for (unsigned int j=i+1; j<considered_vertices.size(); ++j)
505  {
506  bool equal=true;
507  for (unsigned int d=0; d<spacedim; ++d)
508  equal &= (fabs(vertices[considered_vertices[j]](d)-vertices[considered_vertices[i]](d))<tol);
509  if (equal)
510  {
511  new_vertex_numbers[considered_vertices[j]]=considered_vertices[i];
512  // we do not suppose, that there might be another duplicate
513  // vertex, so break here
514  break;
515  }
516  }
517  }
518 
519  // now we got a renumbering list. simply
520  // renumber all vertices (non-duplicate
521  // vertices get renumbered to themselves, so
522  // nothing bad happens). after that, the
523  // duplicate vertices will be unused, so call
524  // delete_unused_vertices() to do that part
525  // of the job.
526  for (unsigned int c=0; c<cells.size(); ++c)
527  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
528  cells[c].vertices[v]=new_vertex_numbers[cells[c].vertices[v]];
529 
530  delete_unused_vertices(vertices, cells, subcelldata);
531  }
532 
533 
534 
535 // define some transformations in an anonymous namespace
536  namespace
537  {
538  template <int spacedim>
539  class Shift
540  {
541  public:
542  Shift (const Tensor<1,spacedim> &shift)
543  :
544  shift(shift)
545  {}
546  Point<spacedim> operator() (const Point<spacedim> p) const
547  {
548  return p+shift;
549  }
550  private:
552  };
553 
554 
555  // the following class is only
556  // needed in 2d, so avoid trouble
557  // with compilers warning otherwise
558  class Rotate2d
559  {
560  public:
561  Rotate2d (const double angle)
562  :
563  angle(angle)
564  {}
565  Point<2> operator() (const Point<2> &p) const
566  {
567  return Point<2> (std::cos(angle)*p(0) - std::sin(angle) * p(1),
568  std::sin(angle)*p(0) + std::cos(angle) * p(1));
569  }
570  private:
571  const double angle;
572  };
573 
574  // Transformation to rotate around one of the cartesian axes.
575  class Rotate3d
576  {
577  public:
578  Rotate3d (const double angle,
579  const unsigned int axis)
580  :
581  angle(angle),
582  axis(axis)
583  {}
584 
585  Point<3> operator() (const Point<3> &p) const
586  {
587  if (axis==0)
588  return Point<3> (p(0),
589  std::cos(angle)*p(1) - std::sin(angle) * p(2),
590  std::sin(angle)*p(1) + std::cos(angle) * p(2));
591  else if (axis==1)
592  return Point<3> (std::cos(angle)*p(0) + std::sin(angle) * p(2),
593  p(1),
594  -std::sin(angle)*p(0) + std::cos(angle) * p(2));
595  else
596  return Point<3> (std::cos(angle)*p(0) - std::sin(angle) * p(1),
597  std::sin(angle)*p(0) + std::cos(angle) * p(1),
598  p(2));
599  }
600  private:
601  const double angle;
602  const unsigned int axis;
603  };
604 
605  template <int spacedim>
606  class Scale
607  {
608  public:
609  Scale (const double factor)
610  :
611  factor(factor)
612  {}
613  Point<spacedim> operator() (const Point<spacedim> p) const
614  {
615  return p*factor;
616  }
617  private:
618  const double factor;
619  };
620  }
621 
622 
623  template <int dim, int spacedim>
624  void
625  shift (const Tensor<1,spacedim> &shift_vector,
626  Triangulation<dim, spacedim> &triangulation)
627  {
628  transform (Shift<spacedim>(shift_vector), triangulation);
629  }
630 
631 
632 
633  void
634  rotate (const double angle,
635  Triangulation<2> &triangulation)
636  {
637  transform (Rotate2d(angle), triangulation);
638  }
639 
640  template<int dim>
641  void
642  rotate (const double angle,
643  const unsigned int axis,
644  Triangulation<dim,3> &triangulation)
645  {
646  Assert(axis<3, ExcMessage("Invalid axis given!"));
647 
648  transform (Rotate3d(angle, axis), triangulation);
649  }
650 
651  template <int dim, int spacedim>
652  void
653  scale (const double scaling_factor,
654  Triangulation<dim, spacedim> &triangulation)
655  {
656  Assert (scaling_factor>0, ExcScalingFactorNotPositive (scaling_factor));
657  transform (Scale<spacedim>(scaling_factor), triangulation);
658  }
659 
660 
661  namespace
662  {
668  void laplace_solve (const SparseMatrix<double> &S,
669  const std::map<types::global_dof_index,double> &fixed_dofs,
670  Vector<double> &u)
671  {
672  const unsigned int n_dofs=S.n();
675  prec.initialize(S, 1.2);
676  FilteredMatrix<Vector<double> > PF (prec);
677 
678  SolverControl control (n_dofs, 1.e-10, false, false);
680  SolverCG<Vector<double> > solver (control, mem);
681 
682  Vector<double> f(n_dofs);
683 
684  SF.add_constraints(fixed_dofs);
685  SF.apply_constraints (f, true);
686  solver.solve(SF, u, f, PF);
687  }
688  }
689 
690 
691 
692  // Implementation for 1D only
693  template <>
694  void laplace_transform (const std::map<unsigned int,Point<1> > &,
696  const Function<1> *,
697  const bool )
698  {
699  Assert(false, ExcNotImplemented());
700  }
701 
702 
703  // Implementation for dimensions except 1
704  template <int dim>
705  void
706  laplace_transform (const std::map<unsigned int,Point<dim> > &new_points,
707  Triangulation<dim> &triangulation,
708  const Function<dim> *coefficient,
709  const bool solve_for_absolute_positions)
710  {
711  // first provide everything that is needed for solving a Laplace
712  // equation.
713  FE_Q<dim> q1(1);
714 
715  DoFHandler<dim> dof_handler(triangulation);
716  dof_handler.distribute_dofs(q1);
717 
718  DynamicSparsityPattern dsp (dof_handler.n_dofs (),
719  dof_handler.n_dofs ());
720  DoFTools::make_sparsity_pattern (dof_handler, dsp);
721  dsp.compress ();
722 
723  SparsityPattern sparsity_pattern;
724  sparsity_pattern.copy_from (dsp);
725  sparsity_pattern.compress ();
726 
727  SparseMatrix<double> S(sparsity_pattern);
728 
729  QGauss<dim> quadrature(4);
730 
731  MatrixCreator::create_laplace_matrix(StaticMappingQ1<dim>::mapping, dof_handler, quadrature, S, coefficient);
732 
733  // set up the boundary values for the laplace problem
734  std::map<types::global_dof_index,double> fixed_dofs[dim];
735  typename std::map<unsigned int,Point<dim> >::const_iterator map_end=new_points.end();
736 
737  // fill these maps using the data given by new_points
738  typename DoFHandler<dim>::cell_iterator cell=dof_handler.begin_active(),
739  endc=dof_handler.end();
740  for (; cell!=endc; ++cell)
741  {
742  // loop over all vertices of the cell and see if it is listed in the map
743  // given as first argument of the function
744  for (unsigned int vertex_no=0;
745  vertex_no<GeometryInfo<dim>::vertices_per_cell; ++vertex_no)
746  {
747  const unsigned int vertex_index=cell->vertex_index(vertex_no);
748  const Point<dim> &vertex_point=cell->vertex(vertex_no);
749 
750  const typename std::map<unsigned int,Point<dim> >::const_iterator map_iter
751  = new_points.find(vertex_index);
752 
753  if (map_iter!=map_end)
754  for (unsigned int i=0; i<dim; ++i)
755  fixed_dofs[i].insert(std::pair<types::global_dof_index,double>
756  (cell->vertex_dof_index(vertex_no, 0),
757  (solve_for_absolute_positions ?
758  map_iter->second(i) :
759  map_iter->second(i) - vertex_point[i])
760  ));
761  }
762  }
763 
764  // solve the dim problems with different right hand sides.
765  Vector<double> us[dim];
766  for (unsigned int i=0; i<dim; ++i)
767  us[i].reinit (dof_handler.n_dofs());
768 
769  // solve linear systems in parallel
770  Threads::TaskGroup<> tasks;
771  for (unsigned int i=0; i<dim; ++i)
772  tasks += Threads::new_task (&laplace_solve,
773  S, fixed_dofs[i], us[i]);
774  tasks.join_all ();
775 
776  // change the coordinates of the points of the triangulation
777  // according to the computed values
778  std::vector<bool> vertex_touched (triangulation.n_vertices(), false);
779  for (cell=dof_handler.begin_active(); cell!=endc; ++cell)
780  for (unsigned int vertex_no=0;
781  vertex_no<GeometryInfo<dim>::vertices_per_cell; ++vertex_no)
782  if (vertex_touched[cell->vertex_index(vertex_no)] == false)
783  {
784  Point<dim> &v = cell->vertex(vertex_no);
785 
786  const types::global_dof_index dof_index = cell->vertex_dof_index(vertex_no, 0);
787  for (unsigned int i=0; i<dim; ++i)
788  if (solve_for_absolute_positions)
789  v(i) = us[i](dof_index);
790  else
791  v(i) += us[i](dof_index);
792 
793  vertex_touched[cell->vertex_index(vertex_no)] = true;
794  }
795  }
796 
797  template <int dim, int spacedim>
798  std::map<unsigned int, Point<spacedim> >
800  {
801  std::map<unsigned int, Point<spacedim> > vertex_map;
803  cell = tria.begin_active(),
804  endc = tria.end();
805  for (; cell!=endc; ++cell)
806  {
807  for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
808  {
810  = cell->face(i);
811  if (face->at_boundary())
812  {
813  for (unsigned j = 0; j < GeometryInfo<dim>::vertices_per_face; ++j)
814  {
815  const Point<spacedim> &vertex = face->vertex(j);
816  const unsigned int vertex_index = face->vertex_index(j);
817  vertex_map[vertex_index] = vertex;
818  }
819  }
820  }
821  }
822  return vertex_map;
823  }
824 
829  template <int dim, int spacedim>
830  void
831  distort_random (const double factor,
832  Triangulation<dim,spacedim> &triangulation,
833  const bool keep_boundary)
834  {
835  // if spacedim>dim we need to make sure that we perturb
836  // points but keep them on
837  // the manifold. however, this isn't implemented right now
838  Assert (spacedim == dim, ExcNotImplemented());
839 
840 
841  // find the smallest length of the
842  // lines adjacent to the
843  // vertex. take the initial value
844  // to be larger than anything that
845  // might be found: the diameter of
846  // the triangulation, here
847  // estimated by adding up the
848  // diameters of the coarse grid
849  // cells.
850  double almost_infinite_length = 0;
852  cell=triangulation.begin(0); cell!=triangulation.end(0); ++cell)
853  almost_infinite_length += cell->diameter();
854 
855  std::vector<double> minimal_length (triangulation.n_vertices(),
856  almost_infinite_length);
857 
858  // also note if a vertex is at the boundary
859  std::vector<bool> at_boundary (triangulation.n_vertices(), false);
861  cell=triangulation.begin_active(); cell!=triangulation.end(); ++cell)
862  if (cell->is_locally_owned())
863  {
864  if (dim>1)
865  {
866  for (unsigned int i=0; i<GeometryInfo<dim>::lines_per_cell; ++i)
867  {
868  const typename Triangulation<dim,spacedim>::line_iterator line
869  = cell->line(i);
870 
871  if (keep_boundary && line->at_boundary())
872  {
873  at_boundary[line->vertex_index(0)] = true;
874  at_boundary[line->vertex_index(1)] = true;
875  }
876 
877  minimal_length[line->vertex_index(0)]
878  = std::min(line->diameter(),
879  minimal_length[line->vertex_index(0)]);
880  minimal_length[line->vertex_index(1)]
881  = std::min(line->diameter(),
882  minimal_length[line->vertex_index(1)]);
883  }
884  }
885  else //dim==1
886  {
887  if (keep_boundary)
888  for (unsigned int vertex=0; vertex<2; ++vertex)
889  if (cell->at_boundary(vertex) == true)
890  at_boundary[cell->vertex_index(vertex)] = true;
891 
892  minimal_length[cell->vertex_index(0)]
893  = std::min(cell->diameter(),
894  minimal_length[cell->vertex_index(0)]);
895  minimal_length[cell->vertex_index(1)]
896  = std::min(cell->diameter(),
897  minimal_length[cell->vertex_index(1)]);
898  }
899  }
900 
901  // create a random number generator for the interval [-1,1]. we use
902  // this to make sure the distribution we get is repeatable, i.e.,
903  // if you call the function twice on the same mesh, then you will
904  // get the same mesh. this would not be the case if you used
905  // the rand() function, which carries around some internal state
906  boost::random::mt19937 rng;
907  boost::random::uniform_real_distribution<> uniform_distribution(-1,1);
908 
909  // If the triangulation is distributed, we need to
910  // exchange the moved vertices across mpi processes
911  if (parallel::distributed::Triangulation< dim, spacedim > *distributed_triangulation
912  = dynamic_cast<parallel::distributed::Triangulation<dim,spacedim>*> (&triangulation))
913  {
914  const std::vector<bool> locally_owned_vertices = get_locally_owned_vertices(triangulation);
915  std::vector<bool> vertex_moved (triangulation.n_vertices(), false);
916 
917  // Next move vertices on locally owned cells
919  cell=triangulation.begin_active(); cell!=triangulation.end(); ++cell)
920  if (cell->is_locally_owned())
921  {
922  for (unsigned int vertex_no=0; vertex_no<GeometryInfo<dim>::vertices_per_cell;
923  ++vertex_no)
924  {
925  const unsigned global_vertex_no = cell->vertex_index(vertex_no);
926 
927  // ignore this vertex if we shall keep the boundary and
928  // this vertex *is* at the boundary, if it is already moved
929  // or if another process moves this vertex
930  if ((keep_boundary && at_boundary[global_vertex_no])
931  || vertex_moved[global_vertex_no]
932  || !locally_owned_vertices[global_vertex_no])
933  continue;
934 
935  // first compute a random shift vector
936  Point<spacedim> shift_vector;
937  for (unsigned int d=0; d<spacedim; ++d)
938  shift_vector(d) = uniform_distribution(rng);
939 
940  shift_vector *= factor * minimal_length[global_vertex_no] /
941  std::sqrt(shift_vector.square());
942 
943  // finally move the vertex
944  cell->vertex(vertex_no) += shift_vector;
945  vertex_moved[global_vertex_no] = true;
946  }
947  }
948 
949 #ifdef DEAL_II_WITH_P4EST
950  distributed_triangulation
951  ->communicate_locally_moved_vertices(locally_owned_vertices);
952 #else
953  (void)distributed_triangulation;
954  Assert (false, ExcInternalError());
955 #endif
956  }
957  else
958  // if this is a sequential triangulation, we could in principle
959  // use the algorithm above, but we'll use an algorithm that we used
960  // before the parallel::distributed::Triangulation was introduced
961  // in order to preserve backward compatibility
962  {
963  // loop over all vertices and compute their new locations
964  const unsigned int n_vertices = triangulation.n_vertices();
965  std::vector<Point<spacedim> > new_vertex_locations (n_vertices);
966  const std::vector<Point<spacedim> > &old_vertex_locations
967  = triangulation.get_vertices();
968 
969  for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
970  {
971  // ignore this vertex if we will keep the boundary and
972  // this vertex *is* at the boundary
973  if (keep_boundary && at_boundary[vertex])
974  new_vertex_locations[vertex] = old_vertex_locations[vertex];
975  else
976  {
977  // compute a random shift vector
978  Point<spacedim> shift_vector;
979  for (unsigned int d=0; d<spacedim; ++d)
980  shift_vector(d) = uniform_distribution(rng);
981 
982  shift_vector *= factor * minimal_length[vertex] /
983  std::sqrt(shift_vector.square());
984 
985  // record new vertex location
986  new_vertex_locations[vertex] = old_vertex_locations[vertex] + shift_vector;
987  }
988  }
989 
990  // now do the actual move of the vertices
992  cell=triangulation.begin_active(); cell!=triangulation.end(); ++cell)
993  for (unsigned int vertex_no=0;
994  vertex_no<GeometryInfo<dim>::vertices_per_cell; ++vertex_no)
995  cell->vertex(vertex_no) = new_vertex_locations[cell->vertex_index(vertex_no)];
996  }
997 
998  // Correct hanging nodes if necessary
999  if (dim>=2)
1000  {
1001  // We do the same as in GridTools::transform
1002  //
1003  // exclude hanging nodes at the boundaries of artificial cells:
1004  // these may belong to ghost cells for which we know the exact
1005  // location of vertices, whereas the artificial cell may or may
1006  // not be further refined, and so we cannot know whether
1007  // the location of the hanging node is correct or not
1009  cell = triangulation.begin_active(),
1010  endc = triangulation.end();
1011  for (; cell!=endc; ++cell)
1012  if (!cell->is_artificial())
1013  for (unsigned int face=0;
1014  face<GeometryInfo<dim>::faces_per_cell; ++face)
1015  if (cell->face(face)->has_children() &&
1016  !cell->face(face)->at_boundary())
1017  {
1018  // this face has hanging nodes
1019  if (dim==2)
1020  cell->face(face)->child(0)->vertex(1)
1021  = (cell->face(face)->vertex(0) +
1022  cell->face(face)->vertex(1)) / 2;
1023  else if (dim==3)
1024  {
1025  cell->face(face)->child(0)->vertex(1)
1026  = .5*(cell->face(face)->vertex(0)
1027  +cell->face(face)->vertex(1));
1028  cell->face(face)->child(0)->vertex(2)
1029  = .5*(cell->face(face)->vertex(0)
1030  +cell->face(face)->vertex(2));
1031  cell->face(face)->child(1)->vertex(3)
1032  = .5*(cell->face(face)->vertex(1)
1033  +cell->face(face)->vertex(3));
1034  cell->face(face)->child(2)->vertex(3)
1035  = .5*(cell->face(face)->vertex(2)
1036  +cell->face(face)->vertex(3));
1037 
1038  // center of the face
1039  cell->face(face)->child(0)->vertex(3)
1040  = .25*(cell->face(face)->vertex(0)
1041  +cell->face(face)->vertex(1)
1042  +cell->face(face)->vertex(2)
1043  +cell->face(face)->vertex(3));
1044  }
1045  }
1046  }
1047  }
1048 
1049 
1050 
1051  template <int dim, template <int, int> class MeshType, int spacedim>
1052  unsigned int
1053  find_closest_vertex (const MeshType<dim,spacedim> &mesh,
1054  const Point<spacedim> &p)
1055  {
1056  // first get the underlying
1057  // triangulation from the
1058  // mesh and determine vertices
1059  // and used vertices
1060  const Triangulation<dim, spacedim> &tria = mesh.get_triangulation();
1061 
1062  const std::vector< Point<spacedim> > &vertices = tria.get_vertices();
1063  const std::vector< bool > &used = tria.get_used_vertices();
1064 
1065  // At the beginning, the first
1066  // used vertex is the closest one
1067  std::vector<bool>::const_iterator first =
1068  std::find(used.begin(), used.end(), true);
1069 
1070  // Assert that at least one vertex
1071  // is actually used
1072  Assert(first != used.end(), ExcInternalError());
1073 
1074  unsigned int best_vertex = std::distance(used.begin(), first);
1075  double best_dist = (p - vertices[best_vertex]).norm_square();
1076 
1077  // For all remaining vertices, test
1078  // whether they are any closer
1079  for (unsigned int j = best_vertex+1; j < vertices.size(); j++)
1080  if (used[j])
1081  {
1082  double dist = (p - vertices[j]).norm_square();
1083  if (dist < best_dist)
1084  {
1085  best_vertex = j;
1086  best_dist = dist;
1087  }
1088  }
1089 
1090  return best_vertex;
1091  }
1092 
1093 
1094  template<int dim, template<int, int> class MeshType, int spacedim>
1095 #ifndef _MSC_VER
1096  std::vector<typename MeshType<dim, spacedim>::active_cell_iterator>
1097 #else
1098  std::vector<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type>
1099 #endif
1100  find_cells_adjacent_to_vertex(const MeshType<dim,spacedim> &mesh,
1101  const unsigned int vertex)
1102  {
1103  // make sure that the given vertex is
1104  // an active vertex of the underlying
1105  // triangulation
1106  Assert(vertex < mesh.get_triangulation().n_vertices(),
1107  ExcIndexRange(0,mesh.get_triangulation().n_vertices(),vertex));
1108  Assert(mesh.get_triangulation().get_used_vertices()[vertex],
1109  ExcVertexNotUsed(vertex));
1110 
1111  // use a set instead of a vector
1112  // to ensure that cells are inserted only
1113  // once
1114  std::set<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type> adjacent_cells;
1115 
1116  typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type
1117  cell = mesh.begin_active(),
1118  endc = mesh.end();
1119 
1120  // go through all active cells and look if the vertex is part of that cell
1121  //
1122  // in 1d, this is all we need to care about. in 2d/3d we also need to worry
1123  // that the vertex might be a hanging node on a face or edge of a cell; in
1124  // this case, we would want to add those cells as well on whose faces the
1125  // vertex is located but for which it is not a vertex itself.
1126  //
1127  // getting this right is a lot simpler in 2d than in 3d. in 2d, a hanging
1128  // node can only be in the middle of a face and we can query the neighboring
1129  // cell from the current cell. on the other hand, in 3d a hanging node
1130  // vertex can also be on an edge but there can be many other cells on
1131  // this edge and we can not access them from the cell we are currently
1132  // on.
1133  //
1134  // so, in the 3d case, if we run the algorithm as in 2d, we catch all
1135  // those cells for which the vertex we seek is on a *subface*, but we
1136  // miss the case of cells for which the vertex we seek is on a
1137  // sub-edge for which there is no corresponding sub-face (because the
1138  // immediate neighbor behind this face is not refined), see for example
1139  // the bits/find_cells_adjacent_to_vertex_6 testcase. thus, if we
1140  // haven't yet found the vertex for the current cell we also need to
1141  // look at the mid-points of edges
1142  //
1143  // as a final note, deciding whether a neighbor is actually coarser is
1144  // simple in the case of isotropic refinement (we just need to look at
1145  // the level of the current and the neighboring cell). however, this
1146  // isn't so simple if we have used anisotropic refinement since then
1147  // the level of a cell is not indicative of whether it is coarser or
1148  // not than the current cell. ultimately, we want to add all cells on
1149  // which the vertex is, independent of whether they are coarser or
1150  // finer and so in the 2d case below we simply add *any* *active* neighbor.
1151  // in the worst case, we add cells multiple times to the adjacent_cells
1152  // list, but std::set throws out those cells already entered
1153  for (; cell != endc; ++cell)
1154  {
1155  for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; v++)
1156  if (cell->vertex_index(v) == vertex)
1157  {
1158  // OK, we found a cell that contains
1159  // the given vertex. We add it
1160  // to the list.
1161  adjacent_cells.insert(cell);
1162 
1163  // as explained above, in 2+d we need to check whether
1164  // this vertex is on a face behind which there is a
1165  // (possibly) coarser neighbor. if this is the case,
1166  // then we need to also add this neighbor
1167  if (dim >= 2)
1168  for (unsigned int vface = 0; vface < dim; vface++)
1169  {
1170  const unsigned int face =
1172 
1173  if (!cell->at_boundary(face)
1174  &&
1175  cell->neighbor(face)->active())
1176  {
1177  // there is a (possibly) coarser cell behind a
1178  // face to which the vertex belongs. the
1179  // vertex we are looking at is then either a
1180  // vertex of that coarser neighbor, or it is a
1181  // hanging node on one of the faces of that
1182  // cell. in either case, it is adjacent to the
1183  // vertex, so add it to the list as well (if
1184  // the cell was already in the list then the
1185  // std::set makes sure that we get it only
1186  // once)
1187  adjacent_cells.insert (cell->neighbor(face));
1188  }
1189  }
1190 
1191  // in any case, we have found a cell, so go to the next cell
1192  goto next_cell;
1193  }
1194 
1195  // in 3d also loop over the edges
1196  if (dim >= 3)
1197  {
1198  for (unsigned int e=0; e<GeometryInfo<dim>::lines_per_cell; ++e)
1199  if (cell->line(e)->has_children())
1200  // the only place where this vertex could have been
1201  // hiding is on the mid-edge point of the edge we
1202  // are looking at
1203  if (cell->line(e)->child(0)->vertex_index(1) == vertex)
1204  {
1205  adjacent_cells.insert(cell);
1206 
1207  // jump out of this tangle of nested loops
1208  goto next_cell;
1209  }
1210  }
1211 
1212  // in more than 3d we would probably have to do the same as
1213  // above also for even lower-dimensional objects
1214  Assert (dim <= 3, ExcNotImplemented());
1215 
1216  // move on to the next cell if we have found the
1217  // vertex on the current one
1218 next_cell:
1219  ;
1220  }
1221 
1222  // if this was an active vertex then there needs to have been
1223  // at least one cell to which it is adjacent!
1224  Assert (adjacent_cells.size() > 0, ExcInternalError());
1225 
1226  // return the result as a vector, rather than the set we built above
1227  return
1228  std::vector<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type>
1229  (adjacent_cells.begin(), adjacent_cells.end());
1230  }
1231 
1232 
1233 
1234  namespace
1235  {
1236  template <int dim, template<int, int> class MeshType, int spacedim>
1237  void find_active_cell_around_point_internal
1238  (const MeshType<dim,spacedim> &mesh,
1239 #ifndef _MSC_VER
1240  std::set<typename MeshType<dim, spacedim>::active_cell_iterator> &searched_cells,
1241  std::set<typename MeshType<dim, spacedim>::active_cell_iterator> &adjacent_cells)
1242 #else
1243  std::set<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type> &searched_cells,
1244  std::set<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type> &adjacent_cells)
1245 #endif
1246  {
1247 #ifndef _MSC_VER
1248  typedef typename MeshType<dim, spacedim>::active_cell_iterator cell_iterator;
1249 #else
1250  typedef typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type cell_iterator;
1251 #endif
1252 
1253  // update the searched cells
1254  searched_cells.insert(adjacent_cells.begin(), adjacent_cells.end());
1255  // now we to collect all neighbors
1256  // of the cells in adjacent_cells we
1257  // have not yet searched.
1258  std::set<cell_iterator> adjacent_cells_new;
1259 
1260  typename std::set<cell_iterator>::const_iterator
1261  cell = adjacent_cells.begin(),
1262  endc = adjacent_cells.end();
1263  for (; cell != endc; ++cell)
1264  {
1265  std::vector<cell_iterator> active_neighbors;
1266  get_active_neighbors<MeshType<dim, spacedim> >(*cell, active_neighbors);
1267  for (unsigned int i=0; i<active_neighbors.size(); ++i)
1268  if (searched_cells.find(active_neighbors[i]) == searched_cells.end())
1269  adjacent_cells_new.insert(active_neighbors[i]);
1270  }
1271  adjacent_cells.clear();
1272  adjacent_cells.insert(adjacent_cells_new.begin(), adjacent_cells_new.end());
1273  if (adjacent_cells.size() == 0)
1274  {
1275  // we haven't found any other cell that would be a
1276  // neighbor of a previously found cell, but we know
1277  // that we haven't checked all cells yet. that means
1278  // that the domain is disconnected. in that case,
1279  // choose the first previously untouched cell we
1280  // can find
1281  cell_iterator it = mesh.begin_active();
1282  for ( ; it!=mesh.end(); ++it)
1283  if (searched_cells.find(it) == searched_cells.end())
1284  {
1285  adjacent_cells.insert(it);
1286  break;
1287  }
1288  }
1289  }
1290  }
1291 
1292  template <int dim, template<int, int> class MeshType, int spacedim>
1293 #ifndef _MSC_VER
1294  typename MeshType<dim, spacedim>::active_cell_iterator
1295 #else
1296  typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type
1297 #endif
1298  find_active_cell_around_point (const MeshType<dim,spacedim> &mesh,
1299  const Point<spacedim> &p)
1300  {
1301  return
1302  find_active_cell_around_point<dim,MeshType,spacedim>
1304  mesh, p).first;
1305  }
1306 
1307 
1308  template <int dim, template <int, int> class MeshType, int spacedim>
1309 #ifndef _MSC_VER
1310  std::pair<typename MeshType<dim, spacedim>::active_cell_iterator, Point<dim> >
1311 #else
1312  std::pair<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type, Point<dim> >
1313 #endif
1315  const MeshType<dim,spacedim> &mesh,
1316  const Point<spacedim> &p)
1317  {
1318  typedef typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type active_cell_iterator;
1319 
1320  // The best distance is set to the
1321  // maximum allowable distance from
1322  // the unit cell; we assume a
1323  // max. deviation of 1e-10
1324  double best_distance = 1e-10;
1325  int best_level = -1;
1326  std::pair<active_cell_iterator, Point<dim> > best_cell;
1327 
1328  // Find closest vertex and determine
1329  // all adjacent cells
1330  std::vector<active_cell_iterator> adjacent_cells_tmp
1332  find_closest_vertex(mesh, p));
1333 
1334  // Make sure that we have found
1335  // at least one cell adjacent to vertex.
1336  Assert(adjacent_cells_tmp.size()>0, ExcInternalError());
1337 
1338  // Copy all the cells into a std::set
1339  std::set<active_cell_iterator> adjacent_cells (adjacent_cells_tmp.begin(),
1340  adjacent_cells_tmp.end());
1341  std::set<active_cell_iterator> searched_cells;
1342 
1343  // Determine the maximal number of cells
1344  // in the grid.
1345  // As long as we have not found
1346  // the cell and have not searched
1347  // every cell in the triangulation,
1348  // we keep on looking.
1349  const unsigned int n_active_cells = mesh.get_triangulation().n_active_cells();
1350  bool found = false;
1351  unsigned int cells_searched = 0;
1352  while (!found && cells_searched < n_active_cells)
1353  {
1354  typename std::set<active_cell_iterator>::const_iterator
1355  cell = adjacent_cells.begin(),
1356  endc = adjacent_cells.end();
1357  for (; cell != endc; ++cell)
1358  {
1359  try
1360  {
1361  const Point<dim> p_cell = mapping.transform_real_to_unit_cell(*cell, p);
1362 
1363  // calculate the infinity norm of
1364  // the distance vector to the unit cell.
1365  const double dist = GeometryInfo<dim>::distance_to_unit_cell(p_cell);
1366 
1367  // We compare if the point is inside the
1368  // unit cell (or at least not too far
1369  // outside). If it is, it is also checked
1370  // that the cell has a more refined state
1371  if ((dist < best_distance)
1372  ||
1373  ((dist == best_distance)
1374  &&
1375  ((*cell)->level() > best_level)))
1376  {
1377  found = true;
1378  best_distance = dist;
1379  best_level = (*cell)->level();
1380  best_cell = std::make_pair(*cell, p_cell);
1381  }
1382  }
1384  {
1385  // ok, the transformation
1386  // failed presumably
1387  // because the point we
1388  // are looking for lies
1389  // outside the current
1390  // cell. this means that
1391  // the current cell can't
1392  // be the cell around the
1393  // point, so just ignore
1394  // this cell and move on
1395  // to the next
1396  }
1397  }
1398 
1399  // update the number of cells searched
1400  cells_searched += adjacent_cells.size();
1401 
1402  // if we have not found the cell in
1403  // question and have not yet searched every
1404  // cell, we expand our search to
1405  // all the not already searched neighbors of
1406  // the cells in adjacent_cells. This is
1407  // what find_active_cell_around_point_internal
1408  // is for.
1409  if (!found && cells_searched < n_active_cells)
1410  {
1411  find_active_cell_around_point_internal<dim,MeshType,spacedim>
1412  (mesh, searched_cells, adjacent_cells);
1413  }
1414  }
1415 
1416  AssertThrow (best_cell.first.state() == IteratorState::valid,
1417  ExcPointNotFound<spacedim>(p));
1418 
1419  return best_cell;
1420  }
1421 
1422 
1423 
1424  template <int dim, int spacedim>
1425  std::pair<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator, Point<dim> >
1427  const hp::DoFHandler<dim,spacedim> &mesh,
1428  const Point<spacedim> &p)
1429  {
1430  Assert ((mapping.size() == 1) ||
1431  (mapping.size() == mesh.get_fe().size()),
1432  ExcMessage ("Mapping collection needs to have either size 1 "
1433  "or size equal to the number of elements in "
1434  "the FECollection."));
1435 
1436  typedef typename hp::DoFHandler<dim,spacedim>::active_cell_iterator cell_iterator;
1437 
1438  std::pair<cell_iterator, Point<dim> > best_cell;
1439  //If we have only one element in the MappingCollection,
1440  //we use find_active_cell_around_point using only one
1441  //mapping.
1442  if (mapping.size() == 1)
1443  best_cell = find_active_cell_around_point(mapping[0], mesh, p);
1444  else
1445  {
1446 
1447 
1448  // The best distance is set to the
1449  // maximum allowable distance from
1450  // the unit cell; we assume a
1451  // max. deviation of 1e-10
1452  double best_distance = 1e-10;
1453  int best_level = -1;
1454 
1455 
1456  // Find closest vertex and determine
1457  // all adjacent cells
1458  unsigned int vertex = find_closest_vertex(mesh, p);
1459 
1460  std::vector<cell_iterator> adjacent_cells_tmp =
1461  find_cells_adjacent_to_vertex(mesh, vertex);
1462 
1463  // Make sure that we have found
1464  // at least one cell adjacent to vertex.
1465  Assert(adjacent_cells_tmp.size()>0, ExcInternalError());
1466 
1467  // Copy all the cells into a std::set
1468  std::set<cell_iterator> adjacent_cells(adjacent_cells_tmp.begin(), adjacent_cells_tmp.end());
1469  std::set<cell_iterator> searched_cells;
1470 
1471  // Determine the maximal number of cells
1472  // in the grid.
1473  // As long as we have not found
1474  // the cell and have not searched
1475  // every cell in the triangulation,
1476  // we keep on looking.
1477  const unsigned int n_cells = mesh.get_triangulation().n_cells();
1478  bool found = false;
1479  unsigned int cells_searched = 0;
1480  while (!found && cells_searched < n_cells)
1481  {
1482  typename std::set<cell_iterator>::const_iterator
1483  cell = adjacent_cells.begin(),
1484  endc = adjacent_cells.end();
1485  for (; cell != endc; ++cell)
1486  {
1487  try
1488  {
1489  const Point<dim> p_cell = mapping[(*cell)->active_fe_index()].transform_real_to_unit_cell(*cell, p);
1490 
1491 
1492  // calculate the infinity norm of
1493  // the distance vector to the unit cell.
1494  const double dist = GeometryInfo<dim>::distance_to_unit_cell(p_cell);
1495 
1496  // We compare if the point is inside the
1497  // unit cell (or at least not too far
1498  // outside). If it is, it is also checked
1499  // that the cell has a more refined state
1500  if (dist < best_distance ||
1501  (dist == best_distance && (*cell)->level() > best_level))
1502  {
1503  found = true;
1504  best_distance = dist;
1505  best_level = (*cell)->level();
1506  best_cell = std::make_pair(*cell, p_cell);
1507  }
1508  }
1510  {
1511  // ok, the transformation
1512  // failed presumably
1513  // because the point we
1514  // are looking for lies
1515  // outside the current
1516  // cell. this means that
1517  // the current cell can't
1518  // be the cell around the
1519  // point, so just ignore
1520  // this cell and move on
1521  // to the next
1522  }
1523  }
1524  //udpate the number of cells searched
1525  cells_searched += adjacent_cells.size();
1526  // if we have not found the cell in
1527  // question and have not yet searched every
1528  // cell, we expand our search to
1529  // all the not already searched neighbors of
1530  // the cells in adjacent_cells.
1531  if (!found && cells_searched < n_cells)
1532  {
1533  find_active_cell_around_point_internal<dim,hp::DoFHandler,spacedim>
1534  (mesh, searched_cells, adjacent_cells);
1535  }
1536 
1537  }
1538  }
1539 
1540  AssertThrow (best_cell.first.state() == IteratorState::valid,
1541  ExcPointNotFound<spacedim>(p));
1542 
1543  return best_cell;
1544  }
1545 
1546 
1547  namespace
1548  {
1549 
1550  template<class MeshType>
1551  bool
1552  contains_locally_owned_cells (const std::vector<typename MeshType::active_cell_iterator> &cells)
1553  {
1554  for (typename std::vector<typename MeshType::active_cell_iterator>::const_iterator
1555  it = cells.begin(); it != cells.end(); ++it)
1556  {
1557  if ((*it)->is_locally_owned())
1558  return true;
1559  }
1560  return false;
1561  }
1562 
1563  template<class MeshType>
1564  bool
1565  contains_artificial_cells (const std::vector<typename MeshType::active_cell_iterator> &cells)
1566  {
1567  for (typename std::vector<typename MeshType::active_cell_iterator>::const_iterator
1568  it = cells.begin(); it != cells.end(); ++it)
1569  {
1570  if ((*it)->is_artificial())
1571  return true;
1572  }
1573  return false;
1574  }
1575 
1576  }
1577 
1578 
1579 
1580  template <class MeshType>
1581  std::vector<typename MeshType::active_cell_iterator>
1583  (const MeshType &mesh,
1584  const std_cxx11::function<bool (const typename MeshType::active_cell_iterator &)> &predicate)
1585  {
1586  std::vector<typename MeshType::active_cell_iterator> active_halo_layer;
1587  std::vector<bool> locally_active_vertices_on_subdomain (mesh.get_triangulation().n_vertices(),
1588  false);
1589 
1590  // Find the cells for which the predicate is true
1591  // These are the cells around which we wish to construct
1592  // the halo layer
1593  for (typename MeshType::active_cell_iterator
1594  cell = mesh.begin_active();
1595  cell != mesh.end(); ++cell)
1596  if (predicate(cell)) // True predicate --> Part of subdomain
1597  for (unsigned int v=0; v<GeometryInfo<MeshType::dimension>::vertices_per_cell; ++v)
1598  locally_active_vertices_on_subdomain[cell->vertex_index(v)] = true;
1599 
1600  // Find the cells that do not conform to the predicate
1601  // but share a vertex with the selected subdomain
1602  // These comprise the halo layer
1603  for (typename MeshType::active_cell_iterator
1604  cell = mesh.begin_active();
1605  cell != mesh.end(); ++cell)
1606  if (!predicate(cell)) // False predicate --> Potential halo cell
1607  for (unsigned int v=0; v<GeometryInfo<MeshType::dimension>::vertices_per_cell; ++v)
1608  if (locally_active_vertices_on_subdomain[cell->vertex_index(v)] == true)
1609  {
1610  active_halo_layer.push_back(cell);
1611  break;
1612  }
1613 
1614  return active_halo_layer;
1615  }
1616 
1617 
1618 
1619  template <class MeshType>
1620  std::vector<typename MeshType::active_cell_iterator>
1621  compute_ghost_cell_halo_layer (const MeshType &mesh)
1622  {
1623  std_cxx11::function<bool (const typename MeshType::active_cell_iterator &)> predicate
1625 
1626  const std::vector<typename MeshType::active_cell_iterator>
1627  active_halo_layer = compute_active_cell_halo_layer (mesh, predicate);
1628 
1629  // Check that we never return locally owned or artificial cells
1630  // What is left should only be the ghost cells
1631  Assert(contains_locally_owned_cells<MeshType>(active_halo_layer) == false,
1632  ExcMessage("Halo layer contains locally owned cells"));
1633  Assert(contains_artificial_cells<MeshType>(active_halo_layer) == false,
1634  ExcMessage("Halo layer contains artificial cells"));
1635 
1636  return active_halo_layer;
1637  }
1638 
1639 
1640 
1641  template <int dim, int spacedim>
1642  std::vector<std::set<typename Triangulation<dim,spacedim>::active_cell_iterator> >
1644  {
1645  std::vector<std::set<typename Triangulation<dim,spacedim>::active_cell_iterator> >
1646  vertex_to_cell_map(triangulation.n_vertices());
1647  typename Triangulation<dim,spacedim>::active_cell_iterator cell = triangulation.begin_active(),
1648  endc = triangulation.end();
1649  for (; cell!=endc; ++cell)
1650  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
1651  vertex_to_cell_map[cell->vertex_index(i)].insert(cell);
1652 
1653  // Take care of hanging nodes
1654  cell = triangulation.begin_active();
1655  for (; cell!=endc; ++cell)
1656  {
1657  for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
1658  {
1659  if ((cell->at_boundary(i)==false) && (cell->neighbor(i)->active()))
1660  {
1661  typename Triangulation<dim,spacedim>::active_cell_iterator adjacent_cell =
1662  cell->neighbor(i);
1663  for (unsigned int j=0; j<GeometryInfo<dim>::vertices_per_face; ++j)
1664  vertex_to_cell_map[cell->face(i)->vertex_index(j)].insert(adjacent_cell);
1665  }
1666  }
1667 
1668  // in 3d also loop over the edges
1669  if (dim==3)
1670  {
1671  for (unsigned int i=0; i<GeometryInfo<dim>::lines_per_cell; ++i)
1672  if (cell->line(i)->has_children())
1673  // the only place where this vertex could have been
1674  // hiding is on the mid-edge point of the edge we
1675  // are looking at
1676  vertex_to_cell_map[cell->line(i)->child(0)->vertex_index(1)].insert(cell);
1677  }
1678  }
1679 
1680  return vertex_to_cell_map;
1681  }
1682 
1683 
1684 
1685  template <int dim, int spacedim>
1686  std::map<unsigned int,types::global_vertex_index>
1689  {
1690  std::map<unsigned int,types::global_vertex_index> local_to_global_vertex_index;
1691 
1692 #ifndef DEAL_II_WITH_MPI
1693 
1694  // without MPI, this function doesn't make sense because on cannot
1695  // use parallel::distributed::Triangulation in any meaninful
1696  // way
1697  (void)triangulation;
1698  Assert (false, ExcMessage ("This function does not make any sense "
1699  "for parallel::distributed::Triangulation "
1700  "objects if you do not have MPI enabled."));
1701 
1702 #else
1703 
1704  typedef typename Triangulation<dim,spacedim>::active_cell_iterator active_cell_iterator;
1705  const std::vector<std::set<active_cell_iterator> > vertex_to_cell =
1706  vertex_to_cell_map(triangulation);
1707 
1708  // Create a local index for the locally "owned" vertices
1709  types::global_vertex_index next_index = 0;
1710  unsigned int max_cellid_size = 0;
1711  std::set<std::pair<types::subdomain_id,types::global_vertex_index> > vertices_added;
1712  std::map<types::subdomain_id,std::set<unsigned int> > vertices_to_recv;
1713  std::map<types::subdomain_id,std::vector<std_cxx11::tuple<types::global_vertex_index,
1714  types::global_vertex_index,std::string> > > vertices_to_send;
1715  active_cell_iterator cell = triangulation.begin_active(),
1716  endc = triangulation.end();
1717  std::set<active_cell_iterator> missing_vert_cells;
1718  std::set<unsigned int> used_vertex_index;
1719  for (; cell!=endc; ++cell)
1720  {
1721  if (cell->is_locally_owned())
1722  {
1723  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
1724  {
1725  types::subdomain_id lowest_subdomain_id = cell->subdomain_id();
1726  typename std::set<active_cell_iterator>::iterator
1727  adjacent_cell = vertex_to_cell[cell->vertex_index(i)].begin(),
1728  end_adj_cell = vertex_to_cell[cell->vertex_index(i)].end();
1729  for (; adjacent_cell!=end_adj_cell; ++adjacent_cell)
1730  lowest_subdomain_id = std::min(lowest_subdomain_id,
1731  (*adjacent_cell)->subdomain_id());
1732 
1733  // See if I "own" this vertex
1734  if (lowest_subdomain_id==cell->subdomain_id())
1735  {
1736  // Check that the vertex we are working on a vertex that has not be
1737  // dealt with yet
1738  if (used_vertex_index.find(cell->vertex_index(i))==used_vertex_index.end())
1739  {
1740  // Set the local index
1741  local_to_global_vertex_index[cell->vertex_index(i)] = next_index++;
1742 
1743  // Store the information that will be sent to the adjacent cells
1744  // on other subdomains
1745  adjacent_cell = vertex_to_cell[cell->vertex_index(i)].begin();
1746  for (; adjacent_cell!=end_adj_cell; ++adjacent_cell)
1747  if ((*adjacent_cell)->subdomain_id()!=cell->subdomain_id())
1748  {
1749  std::pair<types::subdomain_id,types::global_vertex_index>
1750  tmp((*adjacent_cell)->subdomain_id(), cell->vertex_index(i));
1751  if (vertices_added.find(tmp)==vertices_added.end())
1752  {
1753  vertices_to_send[(*adjacent_cell)->subdomain_id()].push_back(
1755  std::string> (i,cell->vertex_index(i),
1756  cell->id().to_string()));
1757  if (cell->id().to_string().size() > max_cellid_size)
1758  max_cellid_size = cell->id().to_string().size();
1759  vertices_added.insert(tmp);
1760  }
1761  }
1762  used_vertex_index.insert(cell->vertex_index(i));
1763  }
1764  }
1765  else
1766  {
1767  // We don't own the vertex so we will receive its global index
1768  vertices_to_recv[lowest_subdomain_id].insert(cell->vertex_index(i));
1769  missing_vert_cells.insert(cell);
1770  }
1771  }
1772  }
1773 
1774  // Some hanging nodes are vertices of ghost cells. They need to be
1775  // received.
1776  if (cell->is_ghost())
1777  {
1778  for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
1779  {
1780  if (cell->at_boundary(i)==false)
1781  {
1782  if (cell->neighbor(i)->active())
1783  {
1784  typename Triangulation<dim,spacedim>::active_cell_iterator adjacent_cell =
1785  cell->neighbor(i);
1786  if ((adjacent_cell->is_locally_owned()))
1787  {
1788  types::subdomain_id adj_subdomain_id = adjacent_cell->subdomain_id();
1789  if (cell->subdomain_id()<adj_subdomain_id)
1790  for (unsigned int j=0; j<GeometryInfo<dim>::vertices_per_face; ++j)
1791  {
1792  vertices_to_recv[cell->subdomain_id()].insert(cell->face(i)->vertex_index(j));
1793  missing_vert_cells.insert(cell);
1794  }
1795  }
1796  }
1797  }
1798  }
1799  }
1800  }
1801 
1802  // Get the size of the largest CellID string
1803  max_cellid_size = Utilities::MPI::max(max_cellid_size, triangulation.get_communicator());
1804 
1805  // Make indices global by getting the number of vertices owned by each
1806  // processors and shifting the indices accordingly
1807  const unsigned int n_cpu = Utilities::MPI::n_mpi_processes(triangulation.get_communicator());
1808  std::vector<types::global_vertex_index> indices(n_cpu);
1809  int ierr = MPI_Allgather(&next_index, 1, DEAL_II_DOF_INDEX_MPI_TYPE, &indices[0],
1810  indices.size(), DEAL_II_DOF_INDEX_MPI_TYPE, triangulation.get_communicator());
1811  AssertThrowMPI(ierr);
1812  const types::global_vertex_index shift = std::accumulate(&indices[0],
1813  &indices[0]+triangulation.locally_owned_subdomain(),0);
1814 
1815  std::map<unsigned int,types::global_vertex_index>::iterator
1816  global_index_it = local_to_global_vertex_index.begin(),
1817  global_index_end = local_to_global_vertex_index.end();
1818  for (; global_index_it!=global_index_end; ++global_index_it)
1819  global_index_it->second += shift;
1820 
1821  // In a first message, send the global ID of the vertices and the local
1822  // positions in the cells. In a second messages, send the cell ID as a
1823  // resize string. This is done in two messages so that types are not mixed
1824 
1825  // Send the first message
1826  std::vector<std::vector<types::global_vertex_index> > vertices_send_buffers(
1827  vertices_to_send.size());
1828  std::vector<MPI_Request> first_requests(vertices_to_send.size());
1829  typename std::map<types::subdomain_id,
1830  std::vector<std_cxx11::tuple<types::global_vertex_index,
1831  types::global_vertex_index,std::string> > >::iterator
1832  vert_to_send_it = vertices_to_send.begin(),
1833  vert_to_send_end = vertices_to_send.end();
1834  for (unsigned int i=0; vert_to_send_it!=vert_to_send_end;
1835  ++vert_to_send_it, ++i)
1836  {
1837  int destination = vert_to_send_it->first;
1838  const unsigned int n_vertices = vert_to_send_it->second.size();
1839  const int buffer_size = 2*n_vertices;
1840  vertices_send_buffers[i].resize(buffer_size);
1841 
1842  // fill the buffer
1843  for (unsigned int j=0; j<n_vertices; ++j)
1844  {
1845  vertices_send_buffers[i][2*j] = std_cxx11::get<0>(vert_to_send_it->second[j]);
1846  vertices_send_buffers[i][2*j+1] =
1847  local_to_global_vertex_index[std_cxx11::get<1>(vert_to_send_it->second[j])];
1848  }
1849 
1850  // Send the message
1851  ierr = MPI_Isend(&vertices_send_buffers[i][0],buffer_size,DEAL_II_VERTEX_INDEX_MPI_TYPE,
1852  destination, 0, triangulation.get_communicator(), &first_requests[i]);
1853  AssertThrowMPI(ierr);
1854  }
1855 
1856  // Receive the first message
1857  std::vector<std::vector<types::global_vertex_index> > vertices_recv_buffers(
1858  vertices_to_recv.size());
1859  typename std::map<types::subdomain_id,std::set<unsigned int> >::iterator
1860  vert_to_recv_it = vertices_to_recv.begin(),
1861  vert_to_recv_end = vertices_to_recv.end();
1862  for (unsigned int i=0; vert_to_recv_it!=vert_to_recv_end; ++vert_to_recv_it, ++i)
1863  {
1864  int source = vert_to_recv_it->first;
1865  const unsigned int n_vertices = vert_to_recv_it->second.size();
1866  const int buffer_size = 2*n_vertices;
1867  vertices_recv_buffers[i].resize(buffer_size);
1868 
1869  // Receive the message
1870  ierr = MPI_Recv(&vertices_recv_buffers[i][0],buffer_size,DEAL_II_VERTEX_INDEX_MPI_TYPE,
1871  source, 0, triangulation.get_communicator(), MPI_STATUS_IGNORE);
1872  AssertThrowMPI(ierr);
1873  }
1874 
1875 
1876  // Send second message
1877  std::vector<std::vector<char> > cellids_send_buffers(vertices_to_send.size());
1878  std::vector<MPI_Request> second_requests(vertices_to_send.size());
1879  vert_to_send_it = vertices_to_send.begin();
1880  for (unsigned int i=0; vert_to_send_it!=vert_to_send_end;
1881  ++vert_to_send_it, ++i)
1882  {
1883  int destination = vert_to_send_it->first;
1884  const unsigned int n_vertices = vert_to_send_it->second.size();
1885  const int buffer_size = max_cellid_size*n_vertices;
1886  cellids_send_buffers[i].resize(buffer_size);
1887 
1888  // fill the buffer
1889  unsigned int pos = 0;
1890  for (unsigned int j=0; j<n_vertices; ++j)
1891  {
1892  std::string cell_id = std_cxx11::get<2>(vert_to_send_it->second[j]);
1893  for (unsigned int k=0; k<max_cellid_size; ++k, ++pos)
1894  {
1895  if (k<cell_id.size())
1896  cellids_send_buffers[i][pos] = cell_id[k];
1897  // if necessary fill up the reserved part of the buffer with an
1898  // invalid value
1899  else
1900  cellids_send_buffers[i][pos] = '-';
1901  }
1902  }
1903 
1904  // Send the message
1905  ierr = MPI_Isend(&cellids_send_buffers[i][0], buffer_size, MPI_CHAR,
1906  destination, 0, triangulation.get_communicator(), &second_requests[i]);
1907  AssertThrowMPI(ierr);
1908  }
1909 
1910  // Receive the second message
1911  std::vector<std::vector<char> > cellids_recv_buffers(vertices_to_recv.size());
1912  vert_to_recv_it = vertices_to_recv.begin();
1913  for (unsigned int i=0; vert_to_recv_it!=vert_to_recv_end; ++vert_to_recv_it, ++i)
1914  {
1915  int source = vert_to_recv_it->first;
1916  const unsigned int n_vertices = vert_to_recv_it->second.size();
1917  const int buffer_size = max_cellid_size*n_vertices;
1918  cellids_recv_buffers[i].resize(buffer_size);
1919 
1920  // Receive the message
1921  ierr = MPI_Recv(&cellids_recv_buffers[i][0],buffer_size, MPI_CHAR,
1922  source, 0, triangulation.get_communicator(), MPI_STATUS_IGNORE);
1923  AssertThrowMPI(ierr);
1924  }
1925 
1926 
1927  // Match the data received with the required vertices
1928  vert_to_recv_it = vertices_to_recv.begin();
1929  for (unsigned int i=0; vert_to_recv_it!=vert_to_recv_end; ++i, ++vert_to_recv_it)
1930  {
1931  for (unsigned int j=0; j<vert_to_recv_it->second.size(); ++j)
1932  {
1933  const unsigned int local_pos_recv = vertices_recv_buffers[i][2*j];
1934  const types::global_vertex_index global_id_recv = vertices_recv_buffers[i][2*j+1];
1935  const std::string cellid_recv(&cellids_recv_buffers[i][max_cellid_size*j],
1936  &cellids_recv_buffers[i][max_cellid_size*(j+1)]);
1937  bool found = false;
1938  typename std::set<active_cell_iterator>::iterator
1939  cell_set_it = missing_vert_cells.begin(),
1940  end_cell_set = missing_vert_cells.end();
1941  for (; (found==false) && (cell_set_it!=end_cell_set); ++cell_set_it)
1942  {
1943  typename std::set<active_cell_iterator>::iterator
1944  candidate_cell = vertex_to_cell[(*cell_set_it)->vertex_index(i)].begin(),
1945  end_cell = vertex_to_cell[(*cell_set_it)->vertex_index(i)].end();
1946  for (; candidate_cell!=end_cell; ++candidate_cell)
1947  {
1948  std::string current_cellid = (*candidate_cell)->id().to_string();
1949  current_cellid.resize(max_cellid_size,'-');
1950  if (current_cellid.compare(cellid_recv)==0)
1951  {
1952  local_to_global_vertex_index[(*candidate_cell)->vertex_index(local_pos_recv)] =
1953  global_id_recv;
1954  found = true;
1955 
1956  break;
1957  }
1958  }
1959  }
1960  }
1961  }
1962 #endif
1963 
1964  return local_to_global_vertex_index;
1965  }
1966 
1967 
1968 
1969  template <int dim, int spacedim>
1970  void
1972  DynamicSparsityPattern &cell_connectivity)
1973  {
1974  cell_connectivity.reinit (triangulation.n_active_cells(),
1975  triangulation.n_active_cells());
1976 
1977  // create a map pair<lvl,idx> -> SparsityPattern index
1978  // TODO: we are no longer using user_indices for this because we can get
1979  // pointer/index clashes when saving/restoring them. The following approach
1980  // works, but this map can get quite big. Not sure about more efficient solutions.
1981  std::map< std::pair<unsigned int,unsigned int>, unsigned int >
1982  indexmap;
1983  for (typename ::internal::ActiveCellIterator<dim, spacedim, Triangulation<dim, spacedim> >::type
1984  cell = triangulation.begin_active();
1985  cell != triangulation.end(); ++cell)
1986  indexmap[std::pair<unsigned int,unsigned int>(cell->level(),cell->index())] = cell->active_cell_index();
1987 
1988  // next loop over all cells and their neighbors to build the sparsity
1989  // pattern. note that it's a bit hard to enter all the connections when a
1990  // neighbor has children since we would need to find out which of its
1991  // children is adjacent to the current cell. this problem can be omitted
1992  // if we only do something if the neighbor has no children -- in that case
1993  // it is either on the same or a coarser level than we are. in return, we
1994  // have to add entries in both directions for both cells
1995  for (typename ::internal::ActiveCellIterator<dim, spacedim, Triangulation<dim, spacedim> >::type
1996  cell = triangulation.begin_active();
1997  cell != triangulation.end(); ++cell)
1998  {
1999  const unsigned int index = cell->active_cell_index();
2000  cell_connectivity.add (index, index);
2001  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
2002  if ((cell->at_boundary(f) == false)
2003  &&
2004  (cell->neighbor(f)->has_children() == false))
2005  {
2006  unsigned int other_index = indexmap.find(
2007  std::pair<unsigned int,unsigned int>(cell->neighbor(f)->level(),cell->neighbor(f)->index()))->second;
2008  cell_connectivity.add (index, other_index);
2009  cell_connectivity.add (other_index, index);
2010  }
2011  }
2012  }
2013 
2014 
2015 
2016  template <int dim, int spacedim>
2017  void
2019  SparsityPattern &cell_connectivity)
2020  {
2022  get_face_connectivity_of_cells(triangulation, dsp);
2023  cell_connectivity.copy_from(dsp);
2024  }
2025 
2026 
2027 
2028  template <int dim, int spacedim>
2029  void
2031  DynamicSparsityPattern &cell_connectivity)
2032  {
2033  std::vector<std::vector<unsigned int> > vertex_to_cell(triangulation.n_vertices());
2035  triangulation.begin_active(); cell != triangulation.end(); ++cell)
2036  {
2037  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
2038  vertex_to_cell[cell->vertex_index(v)].push_back(cell->active_cell_index());
2039  }
2040 
2041  cell_connectivity.reinit (triangulation.n_active_cells(),
2042  triangulation.n_active_cells());
2044  triangulation.begin_active(); cell != triangulation.end(); ++cell)
2045  {
2046  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
2047  for (unsigned int n=0; n<vertex_to_cell[cell->vertex_index(v)].size(); ++n)
2048  cell_connectivity.add(cell->active_cell_index(), vertex_to_cell[cell->vertex_index(v)][n]);
2049  }
2050  }
2051 
2052 
2053 
2054  template <int dim, int spacedim>
2055  void
2056  partition_triangulation (const unsigned int n_partitions,
2057  Triangulation<dim,spacedim> &triangulation)
2058  {
2060  (&triangulation)
2061  == 0),
2062  ExcMessage ("Objects of type parallel::distributed::Triangulation "
2063  "are already partitioned implicitly and can not be "
2064  "partitioned again explicitly."));
2065  Assert (n_partitions > 0, ExcInvalidNumberOfPartitions(n_partitions));
2066 
2067  // check for an easy return
2068  if (n_partitions == 1)
2069  {
2070  for (typename ::internal::ActiveCellIterator<dim, spacedim, Triangulation<dim, spacedim> >::type
2071  cell = triangulation.begin_active();
2072  cell != triangulation.end(); ++cell)
2073  cell->set_subdomain_id (0);
2074  return;
2075  }
2076 
2077  // we decompose the domain by first
2078  // generating the connection graph of all
2079  // cells with their neighbors, and then
2080  // passing this graph off to METIS.
2081  // finally defer to the other function for
2082  // partitioning and assigning subdomain ids
2083  SparsityPattern cell_connectivity;
2084  get_face_connectivity_of_cells (triangulation, cell_connectivity);
2085 
2086  partition_triangulation (n_partitions,
2087  cell_connectivity,
2088  triangulation);
2089  }
2090 
2091 
2092 
2093  template <int dim, int spacedim>
2094  void
2095  partition_triangulation (const unsigned int n_partitions,
2096  const SparsityPattern &cell_connection_graph,
2097  Triangulation<dim,spacedim> &triangulation)
2098  {
2100  (&triangulation)
2101  == 0),
2102  ExcMessage ("Objects of type parallel::distributed::Triangulation "
2103  "are already partitioned implicitly and can not be "
2104  "partitioned again explicitly."));
2105  Assert (n_partitions > 0, ExcInvalidNumberOfPartitions(n_partitions));
2106  Assert (cell_connection_graph.n_rows() == triangulation.n_active_cells(),
2107  ExcMessage ("Connectivity graph has wrong size"));
2108  Assert (cell_connection_graph.n_cols() == triangulation.n_active_cells(),
2109  ExcMessage ("Connectivity graph has wrong size"));
2110 
2111  // check for an easy return
2112  if (n_partitions == 1)
2113  {
2114  for (typename ::internal::ActiveCellIterator<dim, spacedim, Triangulation<dim, spacedim> >::type
2115  cell = triangulation.begin_active();
2116  cell != triangulation.end(); ++cell)
2117  cell->set_subdomain_id (0);
2118  return;
2119  }
2120 
2121  // partition this connection graph and get
2122  // back a vector of indices, one per degree
2123  // of freedom (which is associated with a
2124  // cell)
2125  std::vector<unsigned int> partition_indices (triangulation.n_active_cells());
2126  SparsityTools::partition (cell_connection_graph, n_partitions, partition_indices);
2127 
2128  // finally loop over all cells and set the
2129  // subdomain ids
2130  for (typename ::internal::ActiveCellIterator<dim, spacedim, Triangulation<dim, spacedim> >::type
2131  cell = triangulation.begin_active();
2132  cell != triangulation.end(); ++cell)
2133  cell->set_subdomain_id (partition_indices[cell->active_cell_index()]);
2134  }
2135 
2136 
2137 
2138  template <int dim, int spacedim>
2139  void
2141  std::vector<types::subdomain_id> &subdomain)
2142  {
2143  Assert (subdomain.size() == triangulation.n_active_cells(),
2144  ExcDimensionMismatch (subdomain.size(),
2145  triangulation.n_active_cells()));
2147  cell = triangulation.begin_active(); cell!=triangulation.end(); ++cell)
2148  subdomain[cell->active_cell_index()] = cell->subdomain_id();
2149  }
2150 
2151 
2152 
2153  template <int dim, int spacedim>
2154  unsigned int
2156  const types::subdomain_id subdomain)
2157  {
2158  unsigned int count = 0;
2160  cell = triangulation.begin_active();
2161  cell!=triangulation.end(); ++cell)
2162  if (cell->subdomain_id() == subdomain)
2163  ++count;
2164 
2165  return count;
2166  }
2167 
2168 
2169 
2170  template <int dim, int spacedim>
2171  std::vector<bool>
2173  {
2174  // start with all vertices
2175  std::vector<bool> locally_owned_vertices = triangulation.get_used_vertices();
2176 
2177  // if the triangulation is distributed, eliminate those that
2178  // are owned by other processors -- either because the vertex is
2179  // on an artificial cell, or because it is on a ghost cell with
2180  // a smaller subdomain
2183  (&triangulation))
2184  for (typename ::internal::ActiveCellIterator<dim, spacedim, Triangulation<dim, spacedim> >::type
2185  cell = triangulation.begin_active();
2186  cell != triangulation.end(); ++cell)
2187  if (cell->is_artificial()
2188  ||
2189  (cell->is_ghost() &&
2190  (cell->subdomain_id() < tr->locally_owned_subdomain())))
2191  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
2192  locally_owned_vertices[cell->vertex_index(v)] = false;
2193 
2194  return locally_owned_vertices;
2195  }
2196 
2197 
2198 
2199  template <typename MeshType>
2200  std::list<std::pair<typename MeshType::cell_iterator,
2201  typename MeshType::cell_iterator> >
2202  get_finest_common_cells (const MeshType &mesh_1,
2203  const MeshType &mesh_2)
2204  {
2205  Assert (have_same_coarse_mesh (mesh_1, mesh_2),
2206  ExcMessage ("The two meshes must be represent triangulations that "
2207  "have the same coarse meshes"));
2208 
2209  // the algorithm goes as follows:
2210  // first, we fill a list with pairs
2211  // of iterators common to the two
2212  // meshes on the coarsest
2213  // level. then we traverse the
2214  // list; each time, we find a pair
2215  // of iterators for which both
2216  // correspond to non-active cells,
2217  // we delete this item and push the
2218  // pairs of iterators to their
2219  // children to the back. if these
2220  // again both correspond to
2221  // non-active cells, we will get to
2222  // the later on for further
2223  // consideration
2224  typedef
2225  std::list<std::pair<typename MeshType::cell_iterator,
2226  typename MeshType::cell_iterator> >
2227  CellList;
2228 
2229  CellList cell_list;
2230 
2231  // first push the coarse level cells
2232  typename MeshType::cell_iterator
2233  cell_1 = mesh_1.begin(0),
2234  cell_2 = mesh_2.begin(0);
2235  for (; cell_1 != mesh_1.end(0); ++cell_1, ++cell_2)
2236  cell_list.push_back (std::make_pair (cell_1, cell_2));
2237 
2238  // then traverse list as described
2239  // above
2240  typename CellList::iterator cell_pair = cell_list.begin();
2241  while (cell_pair != cell_list.end())
2242  {
2243  // if both cells in this pair
2244  // have children, then erase
2245  // this element and push their
2246  // children instead
2247  if (cell_pair->first->has_children()
2248  &&
2249  cell_pair->second->has_children())
2250  {
2251  Assert(cell_pair->first->refinement_case()==
2252  cell_pair->second->refinement_case(), ExcNotImplemented());
2253  for (unsigned int c=0; c<cell_pair->first->n_children(); ++c)
2254  cell_list.push_back (std::make_pair (cell_pair->first->child(c),
2255  cell_pair->second->child(c)));
2256 
2257  // erasing an iterator
2258  // keeps other iterators
2259  // valid, so already
2260  // advance the present
2261  // iterator by one and then
2262  // delete the element we've
2263  // visited before
2264  const typename CellList::iterator previous_cell_pair = cell_pair;
2265  ++cell_pair;
2266 
2267  cell_list.erase (previous_cell_pair);
2268  }
2269  else
2270  // both cells are active, do
2271  // nothing
2272  ++cell_pair;
2273  }
2274 
2275  // just to make sure everything is ok,
2276  // validate that all pairs have at least one
2277  // active iterator or have different
2278  // refinement_cases
2279  for (cell_pair = cell_list.begin(); cell_pair != cell_list.end(); ++cell_pair)
2280  Assert (cell_pair->first->active()
2281  ||
2282  cell_pair->second->active()
2283  ||
2284  (cell_pair->first->refinement_case()
2285  != cell_pair->second->refinement_case()),
2286  ExcInternalError());
2287 
2288  return cell_list;
2289  }
2290 
2291  template <int dim, int spacedim>
2292  bool
2294  const Triangulation<dim, spacedim> &mesh_2)
2295  {
2296  // make sure the two meshes have
2297  // the same number of coarse cells
2298  if (mesh_1.n_cells (0) != mesh_2.n_cells (0))
2299  return false;
2300 
2301  // if so, also make sure they have
2302  // the same vertices on the cells
2303  // of the coarse mesh
2305  cell_1 = mesh_1.begin(0),
2306  cell_2 = mesh_2.begin(0),
2307  endc = mesh_1.end(0);
2308  for (; cell_1!=endc; ++cell_1, ++cell_2)
2309  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
2310  if (cell_1->vertex(v) != cell_2->vertex(v))
2311  return false;
2312 
2313  // if we've gotten through all
2314  // this, then the meshes really
2315  // seem to have a common coarse
2316  // mesh
2317  return true;
2318  }
2319 
2320 
2321 
2322  template <typename MeshType>
2323  bool
2324  have_same_coarse_mesh (const MeshType &mesh_1,
2325  const MeshType &mesh_2)
2326  {
2327  return have_same_coarse_mesh (mesh_1.get_triangulation(),
2328  mesh_2.get_triangulation());
2329  }
2330 
2331 
2332 
2333  template <int dim, int spacedim>
2334  double
2336  {
2337  double min_diameter = triangulation.begin_active()->diameter();
2339  cell = triangulation.begin_active(); cell != triangulation.end();
2340  ++cell)
2341  min_diameter = std::min (min_diameter,
2342  cell->diameter());
2343  return min_diameter;
2344  }
2345 
2346 
2347 
2348  template <int dim, int spacedim>
2349  double
2351  {
2352  double max_diameter = triangulation.begin_active()->diameter();
2354  cell = triangulation.begin_active(); cell != triangulation.end();
2355  ++cell)
2356  max_diameter = std::max (max_diameter,
2357  cell->diameter());
2358  return max_diameter;
2359  }
2360 
2361 
2362 
2363  namespace internal
2364  {
2365  namespace FixUpDistortedChildCells
2366  {
2367  // compute the mean square
2368  // deviation of the alternating
2369  // forms of the children of the
2370  // given object from that of
2371  // the object itself. for
2372  // objects with
2373  // structdim==spacedim, the
2374  // alternating form is the
2375  // determinant of the jacobian,
2376  // whereas for faces with
2377  // structdim==spacedim-1, the
2378  // alternating form is the
2379  // (signed and scaled) normal
2380  // vector
2381  //
2382  // this average square
2383  // deviation is computed for an
2384  // object where the center node
2385  // has been replaced by the
2386  // second argument to this
2387  // function
2388  template <typename Iterator, int spacedim>
2389  double
2390  objective_function (const Iterator &object,
2391  const Point<spacedim> &object_mid_point)
2392  {
2393  const unsigned int structdim = Iterator::AccessorType::structure_dimension;
2394  Assert (spacedim == Iterator::AccessorType::dimension,
2395  ExcInternalError());
2396 
2397  // everything below is wrong
2398  // if not for the following
2399  // condition
2400  Assert (object->refinement_case() == RefinementCase<structdim>::isotropic_refinement,
2401  ExcNotImplemented());
2402  // first calculate the
2403  // average alternating form
2404  // for the parent cell/face
2405  Point<spacedim> parent_vertices
2407  Tensor<spacedim-structdim,spacedim> parent_alternating_forms
2409 
2410  for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2411  parent_vertices[i] = object->vertex(i);
2412 
2414  parent_alternating_forms);
2415 
2416  const Tensor<spacedim-structdim,spacedim>
2417  average_parent_alternating_form
2418  = std::accumulate (&parent_alternating_forms[0],
2419  &parent_alternating_forms[GeometryInfo<structdim>::vertices_per_cell],
2421 
2422  // now do the same
2423  // computation for the
2424  // children where we use the
2425  // given location for the
2426  // object mid point instead of
2427  // the one the triangulation
2428  // currently reports
2429  Point<spacedim> child_vertices
2432  Tensor<spacedim-structdim,spacedim> child_alternating_forms
2435 
2436  for (unsigned int c=0; c<object->n_children(); ++c)
2437  for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2438  child_vertices[c][i] = object->child(c)->vertex(i);
2439 
2440  // replace mid-object
2441  // vertex. note that for
2442  // child i, the mid-object
2443  // vertex happens to have the
2444  // number
2445  // max_children_per_cell-i
2446  for (unsigned int c=0; c<object->n_children(); ++c)
2447  child_vertices[c][GeometryInfo<structdim>::max_children_per_cell-c-1]
2448  = object_mid_point;
2449 
2450  for (unsigned int c=0; c<object->n_children(); ++c)
2452  child_alternating_forms[c]);
2453 
2454  // on a uniformly refined
2455  // hypercube object, the child
2456  // alternating forms should
2457  // all be smaller by a factor
2458  // of 2^structdim than the
2459  // ones of the parent. as a
2460  // consequence, we'll use the
2461  // squared deviation from
2462  // this ideal value as an
2463  // objective function
2464  double objective = 0;
2465  for (unsigned int c=0; c<object->n_children(); ++c)
2466  for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2467  objective += (child_alternating_forms[c][i] -
2468  average_parent_alternating_form/std::pow(2.,1.*structdim))
2469  .norm_square();
2470 
2471  return objective;
2472  }
2473 
2474 
2480  template <typename Iterator>
2482  get_face_midpoint (const Iterator &object,
2483  const unsigned int f,
2485  {
2486  return object->vertex(f);
2487  }
2488 
2489 
2490 
2496  template <typename Iterator>
2498  get_face_midpoint (const Iterator &object,
2499  const unsigned int f,
2501  {
2502  return object->line(f)->center();
2503  }
2504 
2505 
2506 
2512  template <typename Iterator>
2514  get_face_midpoint (const Iterator &object,
2515  const unsigned int f,
2517  {
2518  return object->face(f)->center();
2519  }
2520 
2521 
2522 
2523 
2546  template <typename Iterator>
2547  double
2548  minimal_diameter (const Iterator &object)
2549  {
2550  const unsigned int
2551  structdim = Iterator::AccessorType::structure_dimension;
2552 
2553  double diameter = object->diameter();
2554  for (unsigned int f=0;
2555  f<GeometryInfo<structdim>::faces_per_cell;
2556  ++f)
2557  for (unsigned int e=f+1;
2558  e<GeometryInfo<structdim>::faces_per_cell;
2559  ++e)
2560  diameter = std::min (diameter,
2561  get_face_midpoint
2562  (object, f,
2564  .distance (get_face_midpoint
2565  (object,
2566  e,
2568 
2569  return diameter;
2570  }
2571 
2572 
2573 
2584  template <typename Iterator>
2585  bool
2586  fix_up_object (const Iterator &object,
2587  const bool respect_manifold)
2588  {
2589  const Boundary<Iterator::AccessorType::dimension,
2590  Iterator::AccessorType::space_dimension>
2591  *manifold = (respect_manifold ?
2592  &object->get_boundary() :
2593  0);
2594 
2595  const unsigned int structdim = Iterator::AccessorType::structure_dimension;
2596  const unsigned int spacedim = Iterator::AccessorType::space_dimension;
2597 
2598  // right now we can only deal
2599  // with cells that have been
2600  // refined isotropically
2601  // because that is the only
2602  // case where we have a cell
2603  // mid-point that can be moved
2604  // around without having to
2605  // consider boundary
2606  // information
2607  Assert (object->has_children(), ExcInternalError());
2608  Assert (object->refinement_case() == RefinementCase<structdim>::isotropic_refinement,
2609  ExcNotImplemented());
2610 
2611  // get the current location of
2612  // the object mid-vertex:
2613  Point<spacedim> object_mid_point
2614  = object->child(0)->vertex (GeometryInfo<structdim>::max_children_per_cell-1);
2615 
2616  // now do a few steepest descent
2617  // steps to reduce the objective
2618  // function. compute the diameter in
2619  // the helper function above
2620  unsigned int iteration = 0;
2621  const double diameter = minimal_diameter (object);
2622 
2623  // current value of objective
2624  // function and initial delta
2625  double current_value = objective_function (object, object_mid_point);
2626  double initial_delta = 0;
2627 
2628  do
2629  {
2630  // choose a step length
2631  // that is initially 1/4
2632  // of the child objects'
2633  // diameter, and a sequence
2634  // whose sum does not
2635  // converge (to avoid
2636  // premature termination of
2637  // the iteration)
2638  const double step_length = diameter / 4 / (iteration + 1);
2639 
2640  // compute the objective
2641  // function's derivative using a
2642  // two-sided difference formula
2643  // with eps=step_length/10
2644  Tensor<1,spacedim> gradient;
2645  for (unsigned int d=0; d<spacedim; ++d)
2646  {
2647  const double eps = step_length/10;
2648 
2650  h[d] = eps/2;
2651 
2652  if (respect_manifold == false)
2653  gradient[d]
2654  = ((objective_function (object, object_mid_point + h)
2655  -
2656  objective_function (object, object_mid_point - h))
2657  /
2658  eps);
2659  else
2660  gradient[d]
2661  = ((objective_function (object,
2662  manifold->project_to_surface(object,
2663  object_mid_point + h))
2664  -
2665  objective_function (object,
2666  manifold->project_to_surface(object,
2667  object_mid_point - h)))
2668  /
2669  eps);
2670  }
2671 
2672  // sometimes, the
2673  // (unprojected) gradient
2674  // is perpendicular to
2675  // the manifold, but we
2676  // can't go there if
2677  // respect_manifold==true. in
2678  // that case, gradient=0,
2679  // and we simply need to
2680  // quite the loop here
2681  if (gradient.norm() == 0)
2682  break;
2683 
2684  // so we need to go in
2685  // direction -gradient. the
2686  // optimal value of the
2687  // objective function is
2688  // zero, so assuming that
2689  // the model is quadratic
2690  // we would have to go
2691  // -2*val/||gradient|| in
2692  // this direction, make
2693  // sure we go at most
2694  // step_length into this
2695  // direction
2696  object_mid_point -= std::min(2 * current_value / (gradient*gradient),
2697  step_length / gradient.norm()) *
2698  gradient;
2699 
2700  if (respect_manifold == true)
2701  object_mid_point = manifold->project_to_surface(object,
2702  object_mid_point);
2703 
2704  // compute current value of the
2705  // objective function
2706  const double previous_value = current_value;
2707  current_value = objective_function (object, object_mid_point);
2708 
2709  if (iteration == 0)
2710  initial_delta = (previous_value - current_value);
2711 
2712  // stop if we aren't moving much
2713  // any more
2714  if ((iteration >= 1) &&
2715  ((previous_value - current_value < 0)
2716  ||
2717  (std::fabs (previous_value - current_value)
2718  <
2719  0.001 * initial_delta)))
2720  break;
2721 
2722  ++iteration;
2723  }
2724  while (iteration < 20);
2725 
2726  // verify that the new
2727  // location is indeed better
2728  // than the one before. check
2729  // this by comparing whether
2730  // the minimum value of the
2731  // products of parent and
2732  // child alternating forms is
2733  // positive. for cells this
2734  // means that the
2735  // determinants have the same
2736  // sign, for faces that the
2737  // face normals of parent and
2738  // children point in the same
2739  // general direction
2740  double old_min_product, new_min_product;
2741 
2742  Point<spacedim> parent_vertices
2744  for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2745  parent_vertices[i] = object->vertex(i);
2746 
2747  Tensor<spacedim-structdim,spacedim> parent_alternating_forms
2750  parent_alternating_forms);
2751 
2752  Point<spacedim> child_vertices
2755 
2756  for (unsigned int c=0; c<object->n_children(); ++c)
2757  for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2758  child_vertices[c][i] = object->child(c)->vertex(i);
2759 
2760  Tensor<spacedim-structdim,spacedim> child_alternating_forms
2763 
2764  for (unsigned int c=0; c<object->n_children(); ++c)
2766  child_alternating_forms[c]);
2767 
2768  old_min_product = child_alternating_forms[0][0] * parent_alternating_forms[0];
2769  for (unsigned int c=0; c<object->n_children(); ++c)
2770  for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2771  for (unsigned int j=0; j<GeometryInfo<structdim>::vertices_per_cell; ++j)
2772  old_min_product =
2773  std::min<double> (old_min_product,
2774  child_alternating_forms[c][i] *
2775  parent_alternating_forms[j]);
2776 
2777  // for the new minimum value,
2778  // replace mid-object
2779  // vertex. note that for child
2780  // i, the mid-object vertex
2781  // happens to have the number
2782  // max_children_per_cell-i
2783  for (unsigned int c=0; c<object->n_children(); ++c)
2784  child_vertices[c][GeometryInfo<structdim>::max_children_per_cell-c-1]
2785  = object_mid_point;
2786 
2787  for (unsigned int c=0; c<object->n_children(); ++c)
2789  child_alternating_forms[c]);
2790 
2791  new_min_product = child_alternating_forms[0][0] * parent_alternating_forms[0];
2792  for (unsigned int c=0; c<object->n_children(); ++c)
2793  for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2794  for (unsigned int j=0; j<GeometryInfo<structdim>::vertices_per_cell; ++j)
2795  new_min_product =
2796  std::min<double> (new_min_product,
2797  child_alternating_forms[c][i] *
2798  parent_alternating_forms[j]);
2799 
2800  // if new minimum value is
2801  // better than before, then set the
2802  // new mid point. otherwise
2803  // return this object as one of
2804  // those that can't apparently
2805  // be fixed
2806  if (new_min_product >= old_min_product)
2807  object->child(0)->vertex (GeometryInfo<structdim>::max_children_per_cell-1)
2808  = object_mid_point;
2809 
2810  // return whether after this
2811  // operation we have an object that
2812  // is well oriented
2813  return (std::max (new_min_product, old_min_product) > 0);
2814  }
2815 
2816 
2817 
2818  void fix_up_faces (const ::Triangulation<1,1>::cell_iterator &,
2821  {
2822  // nothing to do for the faces of
2823  // cells in 1d
2824  }
2825 
2826 
2827 
2828  // possibly fix up the faces of
2829  // a cell by moving around its
2830  // mid-points
2831  template <int structdim, int spacedim>
2832  void fix_up_faces (const typename ::Triangulation<structdim,spacedim>::cell_iterator &cell,
2835  {
2836  // see if we first can fix up
2837  // some of the faces of this
2838  // object. we can mess with
2839  // faces if and only if it is
2840  // not at the boundary (since
2841  // otherwise the location of
2842  // the face mid-point has been
2843  // determined by the boundary
2844  // object) and if the
2845  // neighboring cell is not even
2846  // more refined than we are
2847  // (since in that case the
2848  // sub-faces have themselves
2849  // children that we can't move
2850  // around any more). however,
2851  // the latter case shouldn't
2852  // happen anyway: if the
2853  // current face is distorted
2854  // but the neighbor is even
2855  // more refined, then the face
2856  // had been deformed before
2857  // already, and had been
2858  // ignored at the time; we
2859  // should then also be able to
2860  // ignore it this time as well
2861  for (unsigned int f=0; f<GeometryInfo<structdim>::faces_per_cell; ++f)
2862  {
2863  Assert (cell->face(f)->has_children(), ExcInternalError());
2864  Assert (cell->face(f)->refinement_case() ==
2865  RefinementCase<structdim-1>::isotropic_refinement,
2866  ExcInternalError());
2867 
2868  bool subface_is_more_refined = false;
2869  for (unsigned int g=0; g<GeometryInfo<structdim>::max_children_per_face; ++g)
2870  if (cell->face(f)->child(g)->has_children())
2871  {
2872  subface_is_more_refined = true;
2873  break;
2874  }
2875 
2876  if (subface_is_more_refined == true)
2877  continue;
2878 
2879  // so, now we finally know
2880  // that we can do something
2881  // about this face
2882  fix_up_object (cell->face(f), cell->at_boundary(f));
2883  }
2884  }
2885 
2886 
2887  } /* namespace FixUpDistortedChildCells */
2888  } /* namespace internal */
2889 
2890 
2891  template <int dim, int spacedim>
2893 
2895  Triangulation<dim,spacedim> &/*triangulation*/)
2896  {
2897  typename Triangulation<dim,spacedim>::DistortedCellList unfixable_subset;
2898 
2899  // loop over all cells that we have
2900  // to fix up
2901  for (typename std::list<typename Triangulation<dim,spacedim>::cell_iterator>::const_iterator
2902  cell_ptr = distorted_cells.distorted_cells.begin();
2903  cell_ptr != distorted_cells.distorted_cells.end(); ++cell_ptr)
2904  {
2906  cell = *cell_ptr;
2907 
2908  internal::FixUpDistortedChildCells
2909  ::fix_up_faces (cell,
2912 
2913  // fix up the object. we need to
2914  // respect the manifold if the cell is
2915  // embedded in a higher dimensional
2916  // space; otherwise, like a hex in 3d,
2917  // every point within the cell interior
2918  // is fair game
2919  if (! internal::FixUpDistortedChildCells::fix_up_object (cell,
2920  (dim < spacedim)))
2921  unfixable_subset.distorted_cells.push_back (cell);
2922  }
2923 
2924  return unfixable_subset;
2925  }
2926 
2927 
2928 
2929  template <class MeshType>
2930  std::vector<typename MeshType::active_cell_iterator>
2931  get_patch_around_cell(const typename MeshType::active_cell_iterator &cell)
2932  {
2933  Assert (cell->is_locally_owned(),
2934  ExcMessage ("This function only makes sense if the cell for "
2935  "which you are asking for a patch, is locally "
2936  "owned."));
2937 
2938  std::vector<typename MeshType::active_cell_iterator> patch;
2939  patch.push_back (cell);
2940  for (unsigned int face_number=0; face_number<GeometryInfo<MeshType::dimension>::faces_per_cell; ++face_number)
2941  if (cell->face(face_number)->at_boundary()==false)
2942  {
2943  if (cell->neighbor(face_number)->has_children() == false)
2944  patch.push_back (cell->neighbor(face_number));
2945  else
2946  // the neighbor is refined. in 2d/3d, we can simply ask for the children
2947  // of the neighbor because they can not be further refined and,
2948  // consequently, the children is active
2949  if (MeshType::dimension > 1)
2950  {
2951  for (unsigned int subface=0; subface<cell->face(face_number)->n_children(); ++subface)
2952  patch.push_back (cell->neighbor_child_on_subface (face_number, subface));
2953  }
2954  else
2955  {
2956  // in 1d, we need to work a bit harder: iterate until we find
2957  // the child by going from cell to child to child etc
2958  typename MeshType::cell_iterator neighbor
2959  = cell->neighbor (face_number);
2960  while (neighbor->has_children())
2961  neighbor = neighbor->child(1-face_number);
2962 
2963  Assert (neighbor->neighbor(1-face_number) == cell, ExcInternalError());
2964  patch.push_back (neighbor);
2965  }
2966  }
2967  return patch;
2968  }
2969 
2970 
2971 
2972  template <class Container>
2973  std::vector<typename Container::cell_iterator>
2975  const std::vector<typename Container::active_cell_iterator> &patch)
2976  {
2977  Assert (patch.size() > 0, ExcMessage("Vector containing patch cells should not be an empty vector!"));
2978  // In order to extract the set of cells with the coarsest common level from the give vector of cells:
2979  // First it finds the number associated with the minimum level of refinmenet, namely "min_level"
2980  int min_level = patch[0]->level();
2981 
2982  for (unsigned int i=0; i<patch.size(); ++i)
2983  min_level = std::min (min_level, patch[i]->level() );
2984  std::set<typename Container::cell_iterator> uniform_cells;
2985  typename std::vector<typename Container::active_cell_iterator>::const_iterator patch_cell;
2986  // it loops through all cells of the input vector
2987  for (patch_cell=patch.begin(); patch_cell!=patch.end () ; ++patch_cell)
2988  {
2989  // If the refinement level of each cell i the loop be equal to the min_level, so that
2990  // that cell inserted into the set of uniform_cells, as the set of cells with the coarsest common refinement level
2991  if ((*patch_cell)->level() == min_level)
2992  uniform_cells.insert (*patch_cell);
2993  else
2994  // If not, it asks for the parent of the cell, until it finds the parent cell
2995  // with the refinement level equal to the min_level and inserts that parent cell into the
2996  // the set of uniform_cells, as the set of cells with the coarsest common refinement level.
2997  {
2998  typename Container::cell_iterator parent = *patch_cell;
2999 
3000  while (parent->level() > min_level)
3001  parent = parent-> parent();
3002  uniform_cells.insert (parent);
3003  }
3004  }
3005 
3006  return std::vector<typename Container::cell_iterator> (uniform_cells.begin(),
3007  uniform_cells.end());
3008  }
3009 
3010 
3011 
3012  template <class Container>
3013  void build_triangulation_from_patch(const std::vector<typename Container::active_cell_iterator> &patch,
3016  typename Container::active_cell_iterator> &patch_to_global_tria_map)
3017 
3018  {
3019  const std::vector<typename Container::cell_iterator> uniform_cells =
3020  get_cells_at_coarsest_common_level <Container> (patch);
3021  // First it creates triangulation from the vector of "uniform_cells"
3022  local_triangulation.clear();
3023  std::vector<Point<Container::space_dimension> > vertices;
3024  const unsigned int n_uniform_cells=uniform_cells.size();
3025  std::vector<CellData<Container::dimension> > cells(n_uniform_cells);
3026  unsigned int k=0;// for enumerating cells
3027  unsigned int i=0;// for enumerating vertices
3028  typename std::vector<typename Container::cell_iterator>::const_iterator uniform_cell;
3029  for (uniform_cell=uniform_cells.begin(); uniform_cell!=uniform_cells.end(); ++uniform_cell)
3030  {
3031  for (unsigned int v=0; v<GeometryInfo<Container::dimension>::vertices_per_cell; ++v)
3032  {
3033  Point<Container::space_dimension> position=(*uniform_cell)->vertex (v);
3034  bool repeat_vertex=false;
3035 
3036  for (unsigned int m=0; m<i; ++m)
3037  {
3038  if (position == vertices[m])
3039  {
3040  repeat_vertex=true;
3041  cells[k].vertices[v]=m;
3042  break;
3043  }
3044  }
3045  if (repeat_vertex==false)
3046  {
3047  vertices.push_back(position);
3048  cells[k].vertices[v]=i;
3049  i=i+1;
3050  }
3051 
3052  }//for vertices_per_cell
3053  k=k+1;
3054  }
3055  local_triangulation.create_triangulation(vertices,cells,SubCellData());
3056  Assert (local_triangulation.n_active_cells() == uniform_cells.size(), ExcInternalError());
3057  local_triangulation.clear_user_flags ();
3058  unsigned int index=0;
3059  // Create a map between cells of class DofHandler into class Triangulation
3060  std::map<typename Triangulation<Container::dimension,Container::space_dimension>::cell_iterator,
3061  typename Container::cell_iterator> patch_to_global_tria_map_tmp;
3062  for (typename Triangulation<Container::dimension,Container::space_dimension>::cell_iterator coarse_cell = local_triangulation.begin();
3063  coarse_cell != local_triangulation.end(); ++coarse_cell, ++index)
3064  {
3065  patch_to_global_tria_map_tmp.insert (std::make_pair(coarse_cell, uniform_cells[index]));
3066  // To ensure that the cells with the same coordinates (here, we compare their centers) are mapped into each other.
3067 
3068  Assert(coarse_cell->center().distance( uniform_cells[index]->center())<=1e-15*coarse_cell->diameter(),
3069  ExcInternalError());
3070  }
3071  bool refinement_necessary;
3072  // In this loop we start to do refinement on the above coarse triangulation to reach
3073  // to the same level of refinement as the patch cells are really on
3074  do
3075  {
3076  refinement_necessary = false;
3078  active_tria_cell = local_triangulation.begin_active();
3079  active_tria_cell != local_triangulation.end(); ++active_tria_cell)
3080  {
3081  if (patch_to_global_tria_map_tmp[active_tria_cell]->has_children())
3082  {
3083  active_tria_cell -> set_refine_flag();
3084  refinement_necessary = true;
3085  }
3086  else for (unsigned int i=0; i<patch.size(); ++i)
3087  {
3088  // Even though vertices may not be exactly the same, the
3089  // appropriate cells will match since == for TriAccessors
3090  // checks only cell level and index.
3091  if (patch_to_global_tria_map_tmp[active_tria_cell]==patch[i])
3092  {
3093  // adjust the cell vertices of the local_triangulation to
3094  // match cell vertices of the global triangulation
3095  for (unsigned int v=0; v<GeometryInfo<Container::dimension>::vertices_per_cell; ++v)
3096  active_tria_cell->vertex(v) = patch[i]->vertex(v);
3097 
3098  Assert(active_tria_cell->center().distance(patch_to_global_tria_map_tmp[active_tria_cell]->center())
3099  <=1e-15*active_tria_cell->diameter(), ExcInternalError());
3100 
3101  active_tria_cell->set_user_flag();
3102  break;
3103  }
3104  }
3105  }
3106 
3107  if (refinement_necessary)
3108  {
3109  local_triangulation.execute_coarsening_and_refinement ();
3110 
3112  cell = local_triangulation.begin();
3113  cell != local_triangulation.end(); ++cell)
3114  {
3115 
3116  if (patch_to_global_tria_map_tmp.find(cell)!=patch_to_global_tria_map_tmp.end())
3117  {
3118  if (cell-> has_children())
3119  {
3120  // Note: Since the cell got children, then it should not be in the map anymore
3121  // children may be added into the map, instead
3122 
3123  // these children may not yet be in the map
3124  for (unsigned int c=0; c<cell->n_children(); ++c)
3125  {
3126  if (patch_to_global_tria_map_tmp.find(cell->child(c)) ==
3127  patch_to_global_tria_map_tmp.end())
3128  {
3129  patch_to_global_tria_map_tmp.insert (std::make_pair(cell->child(c),
3130  patch_to_global_tria_map_tmp[cell]->child(c)));
3131 
3132  // One might be tempted to assert that the cell
3133  // being added here has the same center as the
3134  // equivalent cell in the global triangulation,
3135  // but it may not be the case. For triangulations
3136  // that have been perturbed or smoothed, the cell
3137  // indices and levels may be the same, but the
3138  // vertex locations may not. We adjust
3139  // the vertices of the cells that have no
3140  // children (ie the active cells) to be
3141  // consistent with the global triangulation
3142  // later on and add assertions at that time
3143  // to guarantee the cells in the
3144  // local_triangulation are physically at the same
3145  // locations of the cells in the patch of the
3146  // global triangulation.
3147 
3148  }
3149  }
3150  // The parent cell whose children were added
3151  // into the map should be deleted from the map
3152  patch_to_global_tria_map_tmp.erase(cell);
3153  }
3154  }
3155  }
3156  }
3157 
3158  }
3159  while (refinement_necessary);
3160 
3161 
3162  // Last assertion check to make sure we have the right cells and centers
3163  // in the map, and hence the correct vertices of the triangulation
3165  cell = local_triangulation.begin();
3166  cell != local_triangulation.end(); ++cell)
3167  {
3168  if (cell->user_flag_set() )
3169  {
3170  Assert(patch_to_global_tria_map_tmp.find(cell) != patch_to_global_tria_map_tmp.end(),
3171  ExcInternalError() );
3172 
3173  Assert(cell->center().distance( patch_to_global_tria_map_tmp[cell]->center())<=1e-15*cell->diameter(),
3174  ExcInternalError());
3175  }
3176  }
3177 
3178 
3179  typename std::map<typename Triangulation<Container::dimension,Container::space_dimension>::cell_iterator,
3180  typename Container::cell_iterator>::iterator map_tmp_it =
3181  patch_to_global_tria_map_tmp.begin(),map_tmp_end = patch_to_global_tria_map_tmp.end();
3182  // Now we just need to take the temporary map of pairs of type cell_iterator "patch_to_global_tria_map_tmp"
3183  // making pair of active_cell_iterators so that filling out the final map "patch_to_global_tria_map"
3184  for (; map_tmp_it!=map_tmp_end; ++map_tmp_it)
3185  patch_to_global_tria_map[map_tmp_it->first] = map_tmp_it->second;
3186  }
3187 
3188 
3189 
3190 
3191  template <class DoFHandlerType>
3192  std::map< types::global_dof_index,std::vector<typename DoFHandlerType::active_cell_iterator> >
3193  get_dof_to_support_patch_map(DoFHandlerType &dof_handler)
3194  {
3195 
3196  // This is the map from global_dof_index to
3197  // a set of cells on patch. We first map into
3198  // a set because it is very likely that we
3199  // will attempt to add a cell more than once
3200  // to a particular patch and we want to preserve
3201  // uniqueness of cell iterators. std::set does this
3202  // automatically for us. Later after it is all
3203  // constructed, we will copy to a map of vectors
3204  // since that is the prefered output for other
3205  // functions.
3206  std::map< types::global_dof_index,std::set<typename DoFHandlerType::active_cell_iterator> > dof_to_set_of_cells_map;
3207 
3208  std::vector<types::global_dof_index> local_dof_indices;
3209  std::vector<types::global_dof_index> local_face_dof_indices;
3210  std::vector<types::global_dof_index> local_line_dof_indices;
3211 
3212  // a place to save the dof_handler user flags and restore them later
3213  // to maintain const of dof_handler.
3214  std::vector<bool> user_flags;
3215 
3216 
3217  // in 3d, we need pointers from active lines to the
3218  // active parent lines, so we construct it as needed.
3219  std::map<typename DoFHandlerType::active_line_iterator, typename DoFHandlerType::line_iterator > lines_to_parent_lines_map;
3220  if (DoFHandlerType::dimension == 3)
3221  {
3222 
3223  // save user flags as they will be modified and then later restored
3224  dof_handler.get_triangulation().save_user_flags(user_flags);
3225  const_cast<::Triangulation<DoFHandlerType::dimension,DoFHandlerType::space_dimension> &>(dof_handler.get_triangulation()).clear_user_flags ();
3226 
3227 
3228  typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
3229  endc = dof_handler.end();
3230  for (; cell!=endc; ++cell)
3231  {
3232  // We only want lines that are locally_relevant
3233  // although it doesn't hurt to have lines that
3234  // are children of ghost cells since there are
3235  // few and we don't have to use them.
3236  if (cell->is_artificial() == false)
3237  {
3238  for (unsigned int l=0; l<GeometryInfo<DoFHandlerType::dimension>::lines_per_cell; ++l)
3239  if (cell->line(l)->has_children())
3240  for (unsigned int c=0; c<cell->line(l)->n_children(); ++c)
3241  {
3242  lines_to_parent_lines_map[cell->line(l)->child(c)] = cell->line(l);
3243  // set flags to know that child
3244  // line has an active parent.
3245  cell->line(l)->child(c)->set_user_flag();
3246  }
3247  }
3248  }
3249  }
3250 
3251 
3252  // We loop through all cells and add cell to the
3253  // map for the dofs that it immediately touches
3254  // and then account for all the other dofs of
3255  // which it is a part, mainly the ones that must
3256  // be added on account of adaptivity hanging node
3257  // constraints.
3258  typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
3259  endc = dof_handler.end();
3260  for (; cell!=endc; ++cell)
3261  {
3262  // Need to loop through all cells that could
3263  // be in the patch of dofs on locally_owned
3264  // cells including ghost cells
3265  if (cell->is_artificial() == false)
3266  {
3267  const unsigned int n_dofs_per_cell = cell->get_fe().dofs_per_cell;
3268  local_dof_indices.resize(n_dofs_per_cell);
3269 
3270  // Take care of adding cell pointer to each
3271  // dofs that exists on cell.
3272  cell->get_dof_indices(local_dof_indices);
3273  for (unsigned int i=0; i< n_dofs_per_cell; ++i )
3274  dof_to_set_of_cells_map[local_dof_indices[i]].insert(cell);
3275 
3276  // In the case of the adjacent cell (over
3277  // faces or edges) being more refined, we
3278  // want to add all of the children to the
3279  // patch since the support function at that
3280  // dof could be non-zero along that entire
3281  // face (or line).
3282 
3283  // Take care of dofs on neighbor faces
3284  for (unsigned int f=0; f<GeometryInfo<DoFHandlerType::dimension>::faces_per_cell; ++f)
3285  {
3286  if (cell->face(f)->has_children())
3287  {
3288  for (unsigned int c=0; c<cell->face(f)->n_children(); ++c)
3289  {
3290  // Add cell to dofs of all subfaces
3291  //
3292  // *-------------------*----------*---------*
3293  // | | add cell | |
3294  // | |<- to dofs| |
3295  // | |of subface| |
3296  // | cell *----------*---------*
3297  // | | add cell | |
3298  // | |<- to dofs| |
3299  // | |of subface| |
3300  // *-------------------*----------*---------*
3301  //
3302  Assert (cell->face(f)->child(c)->has_children() == false, ExcInternalError());
3303 
3304  const unsigned int n_dofs_per_face = cell->get_fe().dofs_per_face;
3305  local_face_dof_indices.resize(n_dofs_per_face);
3306 
3307  cell->face(f)->child(c)->get_dof_indices(local_face_dof_indices);
3308  for (unsigned int i=0; i< n_dofs_per_face; ++i )
3309  dof_to_set_of_cells_map[local_face_dof_indices[i]].insert(cell);
3310  }
3311  }
3312  else if ((cell->face(f)->at_boundary() == false) && (cell->neighbor_is_coarser(f)))
3313  {
3314 
3315  // Add cell to dofs of parent face and all
3316  // child faces of parent face
3317  //
3318  // *-------------------*----------*---------*
3319  // | | | |
3320  // | | cell | |
3321  // | add cell | | |
3322  // | to dofs -> *----------*---------*
3323  // | of parent | add cell | |
3324  // | face |<- to dofs| |
3325  // | |of subface| |
3326  // *-------------------*----------*---------*
3327  //
3328 
3329  // Add cell to all dofs of parent face
3330  std::pair<unsigned int, unsigned int> neighbor_face_no_subface_no = cell->neighbor_of_coarser_neighbor(f);
3331  unsigned int face_no = neighbor_face_no_subface_no.first;
3332  unsigned int subface = neighbor_face_no_subface_no.second;
3333 
3334  const unsigned int n_dofs_per_face = cell->get_fe().dofs_per_face;
3335  local_face_dof_indices.resize(n_dofs_per_face);
3336 
3337  cell->neighbor(f)->face(face_no)->get_dof_indices(local_face_dof_indices);
3338  for (unsigned int i=0; i< n_dofs_per_face; ++i )
3339  dof_to_set_of_cells_map[local_face_dof_indices[i]].insert(cell);
3340 
3341  // Add cell to all dofs of children of
3342  // parent face
3343  for (unsigned int c=0; c<cell->neighbor(f)->face(face_no)->n_children(); ++c)
3344  {
3345  if (c != subface) // don't repeat work on dofs of original cell
3346  {
3347  const unsigned int n_dofs_per_face = cell->get_fe().dofs_per_face;
3348  local_face_dof_indices.resize(n_dofs_per_face);
3349 
3350  Assert (cell->neighbor(f)->face(face_no)->child(c)->has_children() == false, ExcInternalError());
3351  cell->neighbor(f)->face(face_no)->child(c)->get_dof_indices(local_face_dof_indices);
3352  for (unsigned int i=0; i<n_dofs_per_face; ++i )
3353  dof_to_set_of_cells_map[local_face_dof_indices[i]].insert(cell);
3354  }
3355  }
3356  }
3357  }
3358 
3359 
3360  // If 3d, take care of dofs on lines in the
3361  // same pattern as faces above. That is, if
3362  // a cell's line has children, distribute
3363  // cell to dofs of children of line, and
3364  // if cell's line has an active parent, then
3365  // distribute cell to dofs on parent line
3366  // and dofs on all children of parent line.
3367  if (DoFHandlerType::dimension == 3)
3368  {
3369  for (unsigned int l=0; l<GeometryInfo<DoFHandlerType::dimension>::lines_per_cell; ++l)
3370  {
3371  if (cell->line(l)->has_children())
3372  {
3373  for (unsigned int c=0; c<cell->line(l)->n_children(); ++c)
3374  {
3375  Assert (cell->line(l)->child(c)->has_children() == false, ExcInternalError());
3376 
3377  // dofs_per_line returns number of dofs
3378  // on line not including the vertices of the line.
3379  const unsigned int n_dofs_per_line = 2*cell->get_fe().dofs_per_vertex
3380  + cell->get_fe().dofs_per_line;
3381  local_line_dof_indices.resize(n_dofs_per_line);
3382 
3383  cell->line(l)->child(c)->get_dof_indices(local_line_dof_indices);
3384  for (unsigned int i=0; i<n_dofs_per_line; ++i )
3385  dof_to_set_of_cells_map[local_line_dof_indices[i]].insert(cell);
3386  }
3387  }
3388  // user flag was set above to denote that
3389  // an active parent line exists so add
3390  // cell to dofs of parent and all it's
3391  // children
3392  else if (cell->line(l)->user_flag_set() == true)
3393  {
3394  typename DoFHandlerType::line_iterator parent_line = lines_to_parent_lines_map[cell->line(l)];
3395  Assert (parent_line->has_children(), ExcInternalError() );
3396 
3397  // dofs_per_line returns number of dofs
3398  // on line not including the vertices of the line.
3399  const unsigned int n_dofs_per_line = 2*cell->get_fe().dofs_per_vertex
3400  + cell->get_fe().dofs_per_line;
3401  local_line_dof_indices.resize(n_dofs_per_line);
3402 
3403  parent_line->get_dof_indices(local_line_dof_indices);
3404  for (unsigned int i=0; i<n_dofs_per_line; ++i )
3405  dof_to_set_of_cells_map[local_line_dof_indices[i]].insert(cell);
3406 
3407  for (unsigned int c=0; c<parent_line->n_children(); ++c)
3408  {
3409  Assert (parent_line->child(c)->has_children() == false, ExcInternalError());
3410 
3411  const unsigned int n_dofs_per_line = 2*cell->get_fe().dofs_per_vertex
3412  + cell->get_fe().dofs_per_line;
3413  local_line_dof_indices.resize(n_dofs_per_line);
3414 
3415  parent_line->child(c)->get_dof_indices(local_line_dof_indices);
3416  for (unsigned int i=0; i<n_dofs_per_line; ++i )
3417  dof_to_set_of_cells_map[local_line_dof_indices[i]].insert(cell);
3418  }
3419 
3420 
3421  }
3422  } // for lines l
3423  }// if DoFHandlerType::dimension == 3
3424  }// if cell->is_locally_owned()
3425  }// for cells
3426 
3427 
3428  if (DoFHandlerType::dimension == 3)
3429  {
3430  // finally, restore user flags that were changed above
3431  // to when we constructed the pointers to parent of lines
3432  // Since dof_handler is const, we must leave it unchanged.
3433  const_cast<::Triangulation<DoFHandlerType::dimension,DoFHandlerType::space_dimension> &>(dof_handler.get_triangulation()).load_user_flags (user_flags);
3434  }
3435 
3436  // Finally, we copy map of sets to
3437  // map of vectors using the std::vector::assign() function
3438  std::map< types::global_dof_index, std::vector<typename DoFHandlerType::active_cell_iterator> > dof_to_cell_patches;
3439 
3440  typename std::map<types::global_dof_index, std::set< typename DoFHandlerType::active_cell_iterator> >::iterator
3441  it = dof_to_set_of_cells_map.begin(),
3442  it_end = dof_to_set_of_cells_map.end();
3443  for ( ; it!=it_end; ++it)
3444  dof_to_cell_patches[it->first].assign( it->second.begin(), it->second.end() );
3445 
3446  return dof_to_cell_patches;
3447  }
3448 
3449 
3450 
3451  /*
3452  * Internally used in orthogonal_equality
3453  *
3454  * An orthogonal equality test for points:
3455  *
3456  * point1 and point2 are considered equal, if
3457  * matrix.point1 + offset - point2
3458  * is parallel to the unit vector in <direction>
3459  */
3460  template<int spacedim>
3461  inline bool orthogonal_equality (const Point<spacedim> &point1,
3462  const Point<spacedim> &point2,
3463  const int direction,
3464  const Tensor<1,spacedim> &offset,
3465  const FullMatrix<double> &matrix)
3466  {
3467  Assert (0<=direction && direction<spacedim,
3468  ExcIndexRange (direction, 0, spacedim));
3469 
3470  Assert(matrix.m() == matrix.n(), ExcInternalError());
3471 
3472  Point<spacedim> distance;
3473 
3474  if (matrix.m() == spacedim)
3475  for (int i = 0; i < spacedim; ++i)
3476  for (int j = 0; j < spacedim; ++j)
3477  distance(i) += matrix(i,j) * point1(j);
3478  else
3479  distance = point1;
3480 
3481  distance += offset - point2;
3482 
3483  for (int i = 0; i < spacedim; ++i)
3484  {
3485  // Only compare coordinate-components != direction:
3486  if (i == direction)
3487  continue;
3488 
3489  if (fabs(distance(i)) > 1.e-10)
3490  return false;
3491  }
3492 
3493  return true;
3494  }
3495 
3496 
3497  /*
3498  * Internally used in orthogonal_equality
3499  *
3500  * A lookup table to transform vertex matchings to orientation flags of
3501  * the form (face_orientation, face_flip, face_rotation)
3502  *
3503  * See the comment on the next function as well as the detailed
3504  * documentation of make_periodicity_constraints and
3505  * collect_periodic_faces for details
3506  */
3507  template<int dim> struct OrientationLookupTable {};
3508 
3509  template<> struct OrientationLookupTable<1>
3510  {
3511  typedef std_cxx11::array<unsigned int, GeometryInfo<1>::vertices_per_face> MATCH_T;
3512  static inline std::bitset<3> lookup (const MATCH_T &)
3513  {
3514  // The 1D case is trivial
3515  return 1; // [true ,false,false]
3516  }
3517  };
3518 
3519  template<> struct OrientationLookupTable<2>
3520  {
3521  typedef std_cxx11::array<unsigned int, GeometryInfo<2>::vertices_per_face> MATCH_T;
3522  static inline std::bitset<3> lookup (const MATCH_T &matching)
3523  {
3524  // In 2D matching faces (=lines) results in two cases: Either
3525  // they are aligned or flipped. We store this "line_flip"
3526  // property somewhat sloppy as "face_flip"
3527  // (always: face_orientation = true, face_rotation = false)
3528 
3529  static const MATCH_T m_tff = {{ 0 , 1 }};
3530  if (matching == m_tff) return 1; // [true ,false,false]
3531  static const MATCH_T m_ttf = {{ 1 , 0 }};
3532  if (matching == m_ttf) return 3; // [true ,true ,false]
3533  Assert(false, ExcInternalError());
3534  // what follows is dead code, but it avoids warnings about the lack
3535  // of a return value
3536  return 0;
3537  }
3538  };
3539 
3540  template<> struct OrientationLookupTable<3>
3541  {
3542  typedef std_cxx11::array<unsigned int, GeometryInfo<3>::vertices_per_face> MATCH_T;
3543  static inline std::bitset<3> lookup (const MATCH_T &matching)
3544  {
3545  // The full fledged 3D case. *Yay*
3546  // See the documentation in include/deal.II/base/geometry_info.h
3547  // as well as the actual implementation in source/grid/tria.cc
3548  // for more details...
3549 
3550  static const MATCH_T m_tff = {{ 0 , 1 , 2 , 3 }};
3551  if (matching == m_tff) return 1; // [true ,false,false]
3552  static const MATCH_T m_tft = {{ 1 , 3 , 0 , 2 }};
3553  if (matching == m_tft) return 5; // [true ,false,true ]
3554  static const MATCH_T m_ttf = {{ 3 , 2 , 1 , 0 }};
3555  if (matching == m_ttf) return 3; // [true ,true ,false]
3556  static const MATCH_T m_ttt = {{ 2 , 0 , 3 , 1 }};
3557  if (matching == m_ttt) return 7; // [true ,true ,true ]
3558  static const MATCH_T m_fff = {{ 0 , 2 , 1 , 3 }};
3559  if (matching == m_fff) return 0; // [false,false,false]
3560  static const MATCH_T m_fft = {{ 2 , 3 , 0 , 1 }};
3561  if (matching == m_fft) return 4; // [false,false,true ]
3562  static const MATCH_T m_ftf = {{ 3 , 1 , 2 , 0 }};
3563  if (matching == m_ftf) return 2; // [false,true ,false]
3564  static const MATCH_T m_ftt = {{ 1 , 0 , 3 , 2 }};
3565  if (matching == m_ftt) return 6; // [false,true ,true ]
3566  Assert(false, ExcInternalError());
3567  // what follows is dead code, but it avoids warnings about the lack
3568  // of a return value
3569  return 0;
3570  }
3571  };
3572 
3573 
3574 
3575  template<typename FaceIterator>
3576  inline bool
3577  orthogonal_equality (std::bitset<3> &orientation,
3578  const FaceIterator &face1,
3579  const FaceIterator &face2,
3580  const int direction,
3582  const FullMatrix<double> &matrix)
3583  {
3584  Assert(matrix.m() == matrix.n(),
3585  ExcMessage("The supplied matrix must be a square matrix"));
3586 
3587  static const int dim = FaceIterator::AccessorType::dimension;
3588 
3589  // Do a full matching of the face vertices:
3590 
3591  std_cxx11::
3592  array<unsigned int, GeometryInfo<dim>::vertices_per_face> matching;
3593 
3594  std::set<unsigned int> face2_vertices;
3595  for (unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_face; ++i)
3596  face2_vertices.insert(i);
3597 
3598  for (unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_face; ++i)
3599  {
3600  for (std::set<unsigned int>::iterator it = face2_vertices.begin();
3601  it != face2_vertices.end();
3602  ++it)
3603  {
3604  if (orthogonal_equality(face1->vertex(i),face2->vertex(*it),
3605  direction, offset, matrix))
3606  {
3607  matching[i] = *it;
3608  face2_vertices.erase(it);
3609  break; // jump out of the innermost loop
3610  }
3611  }
3612  }
3613 
3614  // And finally, a lookup to determine the ordering bitmask:
3615  if (face2_vertices.empty())
3616  orientation = OrientationLookupTable<dim>::lookup(matching);
3617 
3618  return face2_vertices.empty();
3619  }
3620 
3621 
3622 
3623  template<typename FaceIterator>
3624  inline bool
3625  orthogonal_equality (const FaceIterator &face1,
3626  const FaceIterator &face2,
3627  const int direction,
3629  const FullMatrix<double> &matrix)
3630  {
3631  // Call the function above with a dummy orientation array
3632  std::bitset<3> dummy;
3633  return orthogonal_equality (dummy, face1, face2, direction, offset, matrix);
3634  }
3635 
3636 
3637 
3638  /*
3639  * Internally used in collect_periodic_faces
3640  */
3641  template<typename CellIterator>
3642  void
3643  match_periodic_face_pairs
3644  (std::set<std::pair<CellIterator, unsigned int> > &pairs1,
3645  std::set<std::pair<typename identity<CellIterator>::type, unsigned int> > &pairs2,
3646  const int direction,
3647  std::vector<PeriodicFacePair<CellIterator> > &matched_pairs,
3648  const ::Tensor<1,CellIterator::AccessorType::space_dimension> &offset,
3649  const FullMatrix<double> &matrix)
3650  {
3651  static const int space_dim = CellIterator::AccessorType::space_dimension;
3652  (void)space_dim;
3653  Assert (0<=direction && direction<space_dim,
3654  ExcIndexRange (direction, 0, space_dim));
3655 
3656  Assert (pairs1.size() == pairs2.size(),
3657  ExcMessage ("Unmatched faces on periodic boundaries"));
3658 
3659  unsigned int n_matches = 0;
3660 
3661  // Match with a complexity of O(n^2). This could be improved...
3662  std::bitset<3> orientation;
3663  typedef typename std::set
3664  <std::pair<CellIterator, unsigned int> >::const_iterator PairIterator;
3665  for (PairIterator it1 = pairs1.begin(); it1 != pairs1.end(); ++it1)
3666  {
3667  for (PairIterator it2 = pairs2.begin(); it2 != pairs2.end(); ++it2)
3668  {
3669  const CellIterator cell1 = it1->first;
3670  const CellIterator cell2 = it2->first;
3671  const unsigned int face_idx1 = it1->second;
3672  const unsigned int face_idx2 = it2->second;
3673  if (GridTools::orthogonal_equality(orientation,
3674  cell1->face(face_idx1),
3675  cell2->face(face_idx2),
3676  direction, offset,
3677  matrix))
3678  {
3679  // We have a match, so insert the matching pairs and
3680  // remove the matched cell in pairs2 to speed up the
3681  // matching:
3682  const PeriodicFacePair<CellIterator> matched_face =
3683  {
3684  {cell1, cell2},
3685  {face_idx1, face_idx2},
3686  orientation,
3687  matrix
3688  };
3689  matched_pairs.push_back(matched_face);
3690  pairs2.erase(it2);
3691  ++n_matches;
3692  break;
3693  }
3694  }
3695  }
3696 
3697  //Assure that all faces are matched
3698  AssertThrow (n_matches == pairs1.size() && pairs2.size() == 0,
3699  ExcMessage ("Unmatched faces on periodic boundaries"));
3700  }
3701 
3702 
3703 
3704  template<typename MeshType>
3705  void
3707  (const MeshType &mesh,
3708  const types::boundary_id b_id1,
3709  const types::boundary_id b_id2,
3710  const int direction,
3711  std::vector<PeriodicFacePair<typename MeshType::cell_iterator> > &matched_pairs,
3713  const FullMatrix<double> &matrix)
3714  {
3715  static const int dim = MeshType::dimension;
3716  static const int space_dim = MeshType::space_dimension;
3717  (void)dim;
3718  (void)space_dim;
3719  Assert (0<=direction && direction<space_dim,
3720  ExcIndexRange (direction, 0, space_dim));
3721 
3722  // Loop over all cells on the highest level and collect all boundary
3723  // faces belonging to b_id1 and b_id2:
3724 
3725  std::set<std::pair<typename MeshType::cell_iterator, unsigned int> > pairs1;
3726  std::set<std::pair<typename MeshType::cell_iterator, unsigned int> > pairs2;
3727 
3728  for (typename MeshType::cell_iterator cell = mesh.begin(0);
3729  cell != mesh.end(0); ++cell)
3730  {
3731  for (unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
3732  {
3733  const typename MeshType::face_iterator face = cell->face(i);
3734  if (face->at_boundary() && face->boundary_id() == b_id1)
3735  {
3736  const std::pair<typename MeshType::cell_iterator, unsigned int> pair1
3737  = std::make_pair(cell, i);
3738  pairs1.insert(pair1);
3739  }
3740 
3741  if (face->at_boundary() && face->boundary_id() == b_id2)
3742  {
3743  const std::pair<typename MeshType::cell_iterator, unsigned int> pair2
3744  = std::make_pair(cell, i);
3745  pairs2.insert(pair2);
3746  }
3747  }
3748  }
3749 
3750  Assert (pairs1.size() == pairs2.size(),
3751  ExcMessage ("Unmatched faces on periodic boundaries"));
3752 
3753  Assert (pairs1.size() > 0,
3754  ExcMessage("No new periodic face pairs have been found. "
3755  "Are you sure that you've selected the correct boundary "
3756  "id's and that the coarsest level mesh is colorized?"));
3757 
3758  // and call match_periodic_face_pairs that does the actual matching:
3759  match_periodic_face_pairs(pairs1, pairs2, direction, matched_pairs, offset,
3760  matrix);
3761  }
3762 
3763 
3764 
3765  template<typename MeshType>
3766  void
3768  (const MeshType &mesh,
3769  const types::boundary_id b_id,
3770  const int direction,
3771  std::vector<PeriodicFacePair<typename MeshType::cell_iterator> > &matched_pairs,
3773  const FullMatrix<double> &matrix)
3774  {
3775  static const int dim = MeshType::dimension;
3776  static const int space_dim = MeshType::space_dimension;
3777  (void)dim;
3778  (void)space_dim;
3779  Assert (0<=direction && direction<space_dim,
3780  ExcIndexRange (direction, 0, space_dim));
3781 
3782  Assert(dim == space_dim,
3783  ExcNotImplemented());
3784 
3785  // Loop over all cells on the highest level and collect all boundary
3786  // faces 2*direction and 2*direction*1:
3787 
3788  std::set<std::pair<typename MeshType::cell_iterator, unsigned int> > pairs1;
3789  std::set<std::pair<typename MeshType::cell_iterator, unsigned int> > pairs2;
3790 
3791  for (typename MeshType::cell_iterator cell = mesh.begin(0);
3792  cell != mesh.end(0); ++cell)
3793  {
3794  const typename MeshType::face_iterator face_1 = cell->face(2*direction);
3795  const typename MeshType::face_iterator face_2 = cell->face(2*direction+1);
3796 
3797  if (face_1->at_boundary() && face_1->boundary_id() == b_id)
3798  {
3799  const std::pair<typename MeshType::cell_iterator, unsigned int> pair1
3800  = std::make_pair(cell, 2*direction);
3801  pairs1.insert(pair1);
3802  }
3803 
3804  if (face_2->at_boundary() && face_2->boundary_id() == b_id)
3805  {
3806  const std::pair<typename MeshType::cell_iterator, unsigned int> pair2
3807  = std::make_pair(cell, 2*direction+1);
3808  pairs2.insert(pair2);
3809  }
3810  }
3811 
3812  Assert (pairs1.size() == pairs2.size(),
3813  ExcMessage ("Unmatched faces on periodic boundaries"));
3814 
3815  Assert (pairs1.size() > 0,
3816  ExcMessage("No new periodic face pairs have been found. "
3817  "Are you sure that you've selected the correct boundary "
3818  "id's and that the coarsest level mesh is colorized?"));
3819 
3820 #ifdef DEBUG
3821  const unsigned int size_old = matched_pairs.size();
3822 #endif
3823 
3824  // and call match_periodic_face_pairs that does the actual matching:
3825  match_periodic_face_pairs(pairs1, pairs2, direction, matched_pairs, offset,
3826  matrix);
3827 
3828 #ifdef DEBUG
3829  //check for standard orientation
3830  const unsigned int size_new = matched_pairs.size();
3831  for (unsigned int i = size_old; i < size_new; ++i)
3832  {
3833  Assert(matched_pairs[i].orientation == 1,
3834  ExcMessage("Found a face match with non standard orientation. "
3835  "This function is only suitable for meshes with cells "
3836  "in default orientation"));
3837  }
3838 #endif
3839  }
3840 
3841 
3842 
3843  template <int dim, int spacedim>
3845  const bool reset_boundary_ids)
3846  {
3847  // in 3d, we not only have to copy boundary ids of faces, but also of edges
3848  // because we see them twice (once from each adjacent boundary face),
3849  // we cannot immediately reset their boundary ids. thus, copy first
3850  // and reset later
3851  if (dim >= 3)
3853  cell=tria.begin_active();
3854  cell != tria.end(); ++cell)
3855  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
3856  if (cell->face(f)->at_boundary())
3857  for (signed int e=0; e<static_cast<signed int>(GeometryInfo<dim>::lines_per_face); ++e)
3858  cell->face(f)->line(e)->set_manifold_id
3859  (static_cast<types::manifold_id>(cell->face(f)->line(e)->boundary_id()));
3860 
3861  // now do cells
3863  cell=tria.begin_active();
3864  cell != tria.end(); ++cell)
3865  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
3866  if (cell->face(f)->at_boundary())
3867  {
3868  // copy boundary to manifold ids
3869  cell->face(f)->set_manifold_id
3870  (static_cast<types::manifold_id>(cell->face(f)->boundary_id()));
3871 
3872  // then reset boundary ids if so desired, and in 3d also that
3873  // of edges
3874  if (reset_boundary_ids == true)
3875  {
3876  cell->face(f)->set_boundary_id(0);
3877  if (dim >= 3)
3878  for (signed int e=0; e<static_cast<signed int>(GeometryInfo<dim>::lines_per_face); ++e)
3879  cell->face(f)->line(e)->set_boundary_id(0);
3880  }
3881  }
3882  }
3883 
3884 
3885 
3886  template <int dim, int spacedim>
3888  const bool compute_face_ids)
3889  {
3891  cell=tria.begin_active(), endc=tria.end();
3892 
3893  for (; cell != endc; ++cell)
3894  {
3895  cell->set_manifold_id(cell->material_id());
3896  if (compute_face_ids == true)
3897  {
3898  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
3899  {
3900  if (cell->at_boundary(f) == false)
3901  cell->face(f)->set_manifold_id
3902  (std::min(cell->material_id(),
3903  cell->neighbor(f)->material_id()));
3904  else
3905  cell->face(f)->set_manifold_id(cell->material_id());
3906  }
3907  }
3908  }
3909  }
3910 
3911  template<int dim, int spacedim>
3912  std::pair<unsigned int, double>
3914  {
3915  double max_ratio = 1;
3916  unsigned int index = 0;
3917 
3918  for (unsigned int i = 0; i < dim; ++i)
3919  for (unsigned int j = i+1; j < dim; ++j)
3920  {
3921  unsigned int ax = i % dim;
3922  unsigned int next_ax = j % dim;
3923 
3924  double ratio = cell->extent_in_direction(ax) / cell->extent_in_direction(next_ax);
3925 
3926  if ( ratio > max_ratio )
3927  {
3928  max_ratio = ratio;
3929  index = ax;
3930  }
3931  else if ( 1.0 /ratio > max_ratio )
3932  {
3933  max_ratio = 1.0 /ratio;
3934  index = next_ax;
3935  }
3936  }
3937  return std::make_pair(index, max_ratio);
3938  }
3939 
3940 
3941  template<int dim, int spacedim>
3942  void
3944  const bool isotropic,
3945  const unsigned int max_iterations)
3946  {
3947  unsigned int iter = 0;
3948  bool continue_refinement = true;
3949 
3951  cell = tria.begin_active(),
3952  endc = tria.end();
3953 
3954  while ( continue_refinement && (iter < max_iterations) )
3955  {
3956  if (max_iterations != numbers::invalid_unsigned_int) iter++;
3957  continue_refinement = false;
3958 
3959  for (cell=tria.begin_active(); cell!= endc; ++cell)
3960  for (unsigned int j = 0; j < GeometryInfo<dim>::faces_per_cell; j++)
3961  if (cell->at_boundary(j)==false && cell->neighbor(j)->has_children())
3962  {
3963  if (isotropic)
3964  {
3965  cell->set_refine_flag();
3966  continue_refinement = true;
3967  }
3968  else
3969  continue_refinement |= cell->flag_for_face_refinement(j);
3970  }
3971 
3973  }
3974  }
3975 
3976  template<int dim, int spacedim>
3977  void
3979  const double max_ratio,
3980  const unsigned int max_iterations)
3981  {
3982  unsigned int iter = 0;
3983  bool continue_refinement = true;
3984 
3986  cell = tria.begin_active(),
3987  endc = tria.end();
3988 
3989  while ( continue_refinement && (iter<max_iterations) )
3990  {
3991  iter++;
3992  continue_refinement = false;
3993  for (cell=tria.begin_active(); cell!= endc; ++cell)
3994  {
3995  std::pair<unsigned int, double> info = GridTools::get_longest_direction<dim,spacedim>(cell);
3996  if (info.second > max_ratio)
3997  {
3998  cell->set_refine_flag(RefinementCase<dim>::cut_axis(info.first));
3999  continue_refinement = true;
4000  }
4001  }
4003  }
4004  }
4005 
4006 } /* namespace GridTools */
4007 
4008 
4009 // explicit instantiations
4010 #include "grid_tools.inst"
4011 
4012 DEAL_II_NAMESPACE_CLOSE
void remove_hanging_nodes(Triangulation< dim, spacedim > &tria, const bool isotropic=false, const unsigned int max_iterations=100)
Definition: grid_tools.cc:3943
std::vector< CellData< 1 > > boundary_lines
Definition: tria.h:256
Transformed quadrature weights.
unsigned int get_degree() const
Definition: mapping_q.cc:107
static ::ExceptionBase & ExcScalingFactorNotPositive(double arg1)
unsigned int n_active_cells() const
Definition: tria.cc:11244
unsigned int n_vertices() const
static const unsigned int invalid_unsigned_int
Definition: types.h:170
std::map< unsigned int, Point< spacedim > > get_all_vertices_at_boundary(const Triangulation< dim, spacedim > &tria)
Definition: grid_tools.cc:799
void copy_boundary_to_manifold_id(Triangulation< dim, spacedim > &tria, const bool reset_boundary_ids=false)
Definition: grid_tools.cc:3844
void clear_user_flags()
Definition: tria.cc:9889
double diameter(const Triangulation< dim, spacedim > &tria)
Definition: grid_tools.cc:66
void distort_random(const double factor, Triangulation< dim, spacedim > &triangulation, const bool keep_boundary=true)
Definition: grid_tools.cc:831
cell_iterator begin(const unsigned int level=0) const
Definition: dof_handler.cc:728
void delete_duplicated_vertices(std::vector< Point< spacedim > > &all_vertices, std::vector< CellData< dim > > &cells, SubCellData &subcelldata, std::vector< unsigned int > &considered_vertices, const double tol=1e-12)
Definition: grid_tools.cc:464
double maximal_cell_diameter(const Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:2350
bool have_same_coarse_mesh(const Triangulation< dim, spacedim > &mesh_1, const Triangulation< dim, spacedim > &mesh_2)
Definition: grid_tools.cc:2293
unsigned int n_cells() const
Definition: tria.cc:11237
std::pair< unsigned int, double > get_longest_direction(typename Triangulation< dim, spacedim >::active_cell_iterator cell)
Definition: grid_tools.cc:3913
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
std::list< typename Triangulation< dim, spacedim >::cell_iterator > distorted_cells
Definition: tria.h:1549
void add(const size_type i, const size_type j)
bool orthogonal_equality(std::bitset< 3 > &orientation, const FaceIterator &face1, const FaceIterator &face2, const int direction, const Tensor< 1, FaceIterator::AccessorType::space_dimension > &offset=Tensor< 1, FaceIterator::AccessorType::space_dimension >(), const FullMatrix< double > &matrix=FullMatrix< double >())
Definition: grid_tools.cc:3577
void scale(const double scaling_factor, Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:653
double volume(const Triangulation< dim, spacedim > &tria, const Mapping< dim, spacedim > &mapping=(StaticMappingQ1< dim, spacedim >::mapping))
Definition: grid_tools.cc:121
std::vector< std::set< typename Triangulation< dim, spacedim >::active_cell_iterator > > vertex_to_cell_map(const Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:1643
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: tria.cc:10668
std::map< unsigned int, types::global_vertex_index > compute_local_to_global_vertex_index_map(const parallel::distributed::Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:1687
void create_laplace_matrix(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const Quadrature< dim > &q, SparseMatrix< double > &matrix, const Function< spacedim > *const a=0, const ConstraintMatrix &constraints=ConstraintMatrix())
#define AssertThrow(cond, exc)
Definition: exceptions.h:369
numbers::NumberTraits< Number >::real_type norm() const
Definition: tensor.h:991
virtual Point< dim > transform_real_to_unit_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< spacedim > &p) const =0
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
cell_iterator begin(const unsigned int level=0) const
Definition: tria.cc:10648
size_type n_cols() const
ActiveSelector::active_cell_iterator active_cell_iterator
Definition: dof_handler.h:163
size_type n_rows() const
void get_vertex_connectivity_of_cells(const Triangulation< dim, spacedim > &triangulation, DynamicSparsityPattern &connectivity)
Definition: grid_tools.cc:2030
cell_iterator end() const
Definition: tria.cc:10736
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: dof_handler.cc:740
size_type n() const
const hp::FECollection< dim, spacedim > & get_fe() const
virtual void execute_coarsening_and_refinement()
Definition: tria.cc:11899
Definition: tria.h:76
void laplace_transform(const std::map< unsigned int, Point< dim > > &new_points, Triangulation< dim > &tria, const Function< dim, double > *coefficient=0, const bool solve_for_absolute_positions=false)
static ::ExceptionBase & ExcInvalidNumberOfPartitions(int arg1)
Definition: tria.h:52
static ::ExceptionBase & ExcMessage(std::string arg1)
void partition(const SparsityPattern &sparsity_pattern, const unsigned int n_partitions, std::vector< unsigned int > &partition_indices)
bool check_consistency(const unsigned int dim) const
Definition: tria.cc:47
T sum(const T &t, const MPI_Comm &mpi_communicator)
unsigned int global_dof_index
Definition: types.h:88
#define Assert(cond, exc)
Definition: exceptions.h:313
void reinit(const size_type m, const size_type n, const IndexSet &rowset=IndexSet())
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static double distance_to_unit_cell(const Point< dim > &p)
Abstract base class for mapping classes.
Definition: dof_tools.h:46
virtual MPI_Comm get_communicator() const
Definition: tria_base.cc:146
void collect_periodic_faces(const MeshType &mesh, const types::boundary_id b_id1, const types::boundary_id b_id2, const int direction, std::vector< PeriodicFacePair< typename MeshType::cell_iterator > > &matched_pairs, const Tensor< 1, MeshType::space_dimension > &offset=::Tensor< 1, MeshType::space_dimension >(), const FullMatrix< double > &matrix=FullMatrix< double >())
Definition: grid_tools.cc:3707
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
Definition: tria.cc:9401
const std::vector< Point< spacedim > > & get_vertices() const
void remove_anisotropy(Triangulation< dim, spacedim > &tria, const double max_ratio=1.6180339887, const unsigned int max_iterations=5)
Definition: grid_tools.cc:3978
void build_triangulation_from_patch(const std::vector< typename Container::active_cell_iterator > &patch, Triangulation< Container::dimension, Container::space_dimension > &local_triangulation, std::map< typename Triangulation< Container::dimension, Container::space_dimension >::active_cell_iterator, typename Container::active_cell_iterator > &patch_to_global_tria_map)
Definition: grid_tools.cc:3013
void initialize(const MatrixType &A, const AdditionalData &parameters=AdditionalData())
unsigned long long int global_vertex_index
Definition: types.h:47
void copy_material_to_manifold_id(Triangulation< dim, spacedim > &tria, const bool compute_face_ids=false)
Definition: grid_tools.cc:3887
void rotate(const double angle, Triangulation< 2 > &triangulation)
Definition: grid_tools.cc:634
void partition_triangulation(const unsigned int n_partitions, Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:2056
Triangulation< dim, spacedim >::DistortedCellList fix_up_distorted_child_cells(const typename Triangulation< dim, spacedim >::DistortedCellList &distorted_cells, Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:2894
void copy_from(const size_type n_rows, const size_type n_cols, const ForwardIterator begin, const ForwardIterator end)
unsigned int subdomain_id
Definition: types.h:42
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:85
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
std::vector< typename MeshType::active_cell_iterator > compute_ghost_cell_halo_layer(const MeshType &mesh)
Definition: grid_tools.cc:1621
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
Definition: mpi.cc:63
unsigned int size() const
double minimal_cell_diameter(const Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:2335
static void alternating_form_at_vertices(const Point< spacedim >(&vertices)[vertices_per_cell], Tensor< spacedim-dim, spacedim >(&forms)[vertices_per_cell])
#define AssertThrowMPI(error_code)
Definition: exceptions.h:1211
const Triangulation< dim, spacedim > & get_triangulation() const
std::map< types::global_dof_index, std::vector< typename DoFHandlerType::active_cell_iterator > > get_dof_to_support_patch_map(DoFHandlerType &dof_handler)
Definition: grid_tools.cc:3193
void make_sparsity_pattern(const DoFHandlerType &dof_handler, SparsityPatternType &sparsity_pattern, const ConstraintMatrix &constraints=ConstraintMatrix(), const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
void transform(const Transformation &transformation, Triangulation< dim, spacedim > &triangulation)
double JxW(const unsigned int quadrature_point) const
const std::vector< bool > & get_used_vertices() const
Definition: tria.cc:11782
unsigned int find_closest_vertex(const MeshType< dim, spacedim > &mesh, const Point< spacedim > &p)
Definition: grid_tools.cc:1053
std::vector< typename MeshType< dim, spacedim >::active_cell_iterator > find_cells_adjacent_to_vertex(const MeshType< dim, spacedim > &container, const unsigned int vertex_index)
Definition: grid_tools.cc:1100
std::vector< CellData< 2 > > boundary_quads
Definition: tria.h:264
numbers::NumberTraits< Number >::real_type square() const
void get_subdomain_association(const Triangulation< dim, spacedim > &triangulation, std::vector< types::subdomain_id > &subdomain)
Definition: grid_tools.cc:2140
void get_face_connectivity_of_cells(const Triangulation< dim, spacedim > &triangulation, DynamicSparsityPattern &connectivity)
Definition: grid_tools.cc:1971
Definition: fe.h:30
void delete_unused_vertices(std::vector< Point< spacedim > > &vertices, std::vector< CellData< dim > > &cells, SubCellData &subcelldata)
Definition: grid_tools.cc:368
static ::ExceptionBase & ExcNotImplemented()
Iterator points to a valid object.
std::vector< bool > get_locally_owned_vertices(const Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:2172
std::vector< typename Container::cell_iterator > get_cells_at_coarsest_common_level(const std::vector< typename Container::active_cell_iterator > &patch_cells)
Definition: grid_tools.cc:2974
unsigned char boundary_id
Definition: types.h:110
static ::ExceptionBase & ExcVertexNotUsed(unsigned int arg1)
types::subdomain_id locally_owned_subdomain() const
Definition: tria_base.cc:230
std::vector< typename MeshType::active_cell_iterator > compute_active_cell_halo_layer(const MeshType &mesh, const std_cxx11::function< bool(const typename MeshType::active_cell_iterator &)> &predicate)
Definition: grid_tools.cc:1583
std::list< std::pair< typename MeshType::cell_iterator, typename MeshType::cell_iterator > > get_finest_common_cells(const MeshType &mesh_1, const MeshType &mesh_2)
Definition: grid_tools.cc:2202
unsigned int size() const
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access > > &cell)
Definition: fe_values.cc:3729
MeshType< dim, spacedim >::active_cell_iterator find_active_cell_around_point(const MeshType< dim, spacedim > &mesh, const Point< spacedim > &p)
Definition: grid_tools.cc:1298
T max(const T &t, const MPI_Comm &mpi_communicator)
void shift(const Tensor< 1, spacedim > &shift_vector, Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:625
unsigned int count_cells_with_subdomain_association(const Triangulation< dim, spacedim > &triangulation, const types::subdomain_id subdomain)
Definition: grid_tools.cc:2155
virtual void clear()
Definition: tria.cc:9080
Task< RT > new_task(const std_cxx11::function< RT()> &function)
std::vector< typename MeshType::active_cell_iterator > get_patch_around_cell(const typename MeshType::active_cell_iterator &cell)
Definition: grid_tools.cc:2931
static ::ExceptionBase & ExcInternalError()
Triangulation< dim, spacedim > & get_triangulation()
Definition: tria.cc:11855