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