Reference documentation for deal.II version 8.4.2
tria_boundary.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2015 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/tensor.h>
17 #include <deal.II/grid/tria_boundary.h>
18 #include <deal.II/grid/tria.h>
19 #include <deal.II/grid/tria_iterator.h>
20 #include <deal.II/grid/tria_accessor.h>
21 #include <deal.II/fe/fe_q.h>
22 #include <cmath>
23 
24 DEAL_II_NAMESPACE_OPEN
25 
26 
27 
28 /* -------------------------- Boundary --------------------- */
29 
30 
31 template <int dim, int spacedim>
33 {}
34 
35 
36 template <int dim, int spacedim>
37 void
39 get_intermediate_points_on_line (const typename Triangulation<dim, spacedim>::line_iterator &,
40  std::vector<Point<spacedim> > &) const
41 {
42  Assert (false, ExcPureFunctionCalled());
43 }
44 
45 
46 
47 template <int dim, int spacedim>
48 void
50 get_intermediate_points_on_quad (const typename Triangulation<dim, spacedim>::quad_iterator &,
51  std::vector<Point<spacedim> > &) const
52 {
53  Assert (false, ExcPureFunctionCalled());
54 }
55 
56 
57 template <int dim, int spacedim>
58 void
61  std::vector<Point<spacedim> > &points) const
62 {
63  Assert (dim>1, ExcImpossibleInDim(dim));
64 
65  switch (dim)
66  {
67  case 2:
68  get_intermediate_points_on_line (face, points);
69  break;
70  case 3:
71  get_intermediate_points_on_quad (face, points);
72  break;
73  default:
74  Assert (false, ExcNotImplemented());
75  }
76 }
77 
78 
79 template <>
80 void
83  std::vector<Point<1> > &) const
84 {
85  Assert (false, ExcImpossibleInDim(1));
86 }
87 
88 
89 template <>
90 void
93  std::vector<Point<2> > &) const
94 {
95  Assert (false, ExcImpossibleInDim(1));
96 }
97 
98 
99 template <>
100 void
103  std::vector<Point<3> > &) const
104 {
105  Assert (false, ExcImpossibleInDim(1));
106 }
107 
108 
109 
110 
111 template <int dim, int spacedim>
115  const Point<spacedim> &) const
116 {
117  Assert (false, ExcPureFunctionCalled());
118  return Tensor<1,spacedim>();
119 }
120 
121 
122 
123 template <int dim, int spacedim>
124 void
127  FaceVertexNormals &) const
128 {
129  Assert (false, ExcPureFunctionCalled());
130 }
131 
132 
133 
134 template <int dim, int spacedim>
137 project_to_surface (const typename Triangulation<dim, spacedim>::line_iterator &,
138  const Point<spacedim> &trial_point) const
139 {
140  if (spacedim <= 1)
141  return trial_point;
142  else
143  {
144  Assert (false, ExcPureFunctionCalled());
145  return Point<spacedim>();
146  }
147 }
148 
149 
150 
151 template <int dim, int spacedim>
154 project_to_surface (const typename Triangulation<dim, spacedim>::quad_iterator &,
155  const Point<spacedim> &trial_point) const
156 {
157  if (spacedim <= 2)
158  return trial_point;
159  else
160  {
161  Assert (false, ExcPureFunctionCalled());
162  return Point<spacedim>();
163  }
164 }
165 
166 
167 
168 template <int dim, int spacedim>
171 project_to_surface (const typename Triangulation<dim, spacedim>::hex_iterator &,
172  const Point<spacedim> &trial_point) const
173 {
174  if (spacedim <= 3)
175  return trial_point;
176  else
177  {
178  Assert (false, ExcPureFunctionCalled());
179  return Point<spacedim>();
180  }
181 }
182 
183 
184 
185 template <int dim, int spacedim>
186 const std::vector<Point<1> > &
188 get_line_support_points (const unsigned int n_intermediate_points) const
189 {
190  if (points.size() <= n_intermediate_points ||
191  points[n_intermediate_points].get() == 0)
192  {
193  Threads::Mutex::ScopedLock lock(mutex);
194  if (points.size() <= n_intermediate_points)
195  points.resize(n_intermediate_points+1);
196 
197  // another thread might have created points in the meantime
198  if (points[n_intermediate_points].get() == 0)
199  {
200  std_cxx11::shared_ptr<QGaussLobatto<1> >
201  quadrature (new QGaussLobatto<1>(n_intermediate_points+2));
202  points[n_intermediate_points] = quadrature;
203  }
204  }
205  return points[n_intermediate_points]->get_points();
206 }
207 
208 
209 
210 
211 /* -------------------------- StraightBoundary --------------------- */
212 
213 
214 template <int dim, int spacedim>
216 {}
217 
218 
219 template <int dim, int spacedim>
222 get_new_point_on_line (const typename Triangulation<dim, spacedim>::line_iterator &line) const
223 {
224  return (line->vertex(0) + line->vertex(1)) / 2;
225 }
226 
227 
228 namespace
229 {
230  // compute the new midpoint of a quad --
231  // either of a 2d cell on a manifold in 3d
232  // or of a face of a 3d triangulation in 3d
233  template <int dim>
234  Point<3>
235  compute_new_point_on_quad (const typename Triangulation<dim, 3>::quad_iterator &quad)
236  {
237  // generate a new point in the middle of
238  // the face based on the points on the
239  // edges and the vertices.
240  //
241  // there is a pathological situation when
242  // this face is on a straight boundary, but
243  // one of its edges and the face behind it
244  // are not; if that face is refined first,
245  // the new point in the middle of that edge
246  // may not be at the same position as
247  // quad->line(.)->center() would have been,
248  // but would have been moved to the
249  // non-straight boundary. We cater to that
250  // situation by using existing edge
251  // midpoints if available, or center() if
252  // not
253  //
254  // note that this situation can not happen
255  // during mesh refinement, as there the
256  // edges are refined first and only then
257  // the face. thus, the check whether a line
258  // has children does not lead to the
259  // situation where the new face midpoints
260  // have different positions depending on
261  // which of the two cells is refined first.
262  //
263  // the situation where the edges aren't
264  // refined happens when a higher order
265  // MappingQ requests the midpoint of a
266  // face, though, and it is for these cases
267  // that we need to have the check available
268  //
269  // note that the factor of 1/8 for each
270  // of the 8 surrounding points isn't
271  // chosen arbitrarily. rather, we may ask
272  // where the harmonic map would place the
273  // point (0,0) if we map the square
274  // [-1,1]^2 onto the domain that is
275  // described using the 4 vertices and 4
276  // edge point points of this quad. we can
277  // then discretize the harmonic map using
278  // four cells and Q1 elements on each of
279  // the quadrants of the square [-1,1]^2
280  // and see where the midpoint would land
281  // (this is the procedure we choose, for
282  // example, in
283  // GridGenerator::laplace_solve) and it
284  // turns out that it will land at the
285  // mean of the 8 surrounding
286  // points. whether a discretization of
287  // the harmonic map with only 4 cells is
288  // adequate is a different question
289  // altogether, of course.
290  return (quad->vertex(0) + quad->vertex(1) +
291  quad->vertex(2) + quad->vertex(3) +
292  (quad->line(0)->has_children() ?
293  quad->line(0)->child(0)->vertex(1) :
294  quad->line(0)->center()) +
295  (quad->line(1)->has_children() ?
296  quad->line(1)->child(0)->vertex(1) :
297  quad->line(1)->center()) +
298  (quad->line(2)->has_children() ?
299  quad->line(2)->child(0)->vertex(1) :
300  quad->line(2)->center()) +
301  (quad->line(3)->has_children() ?
302  quad->line(3)->child(0)->vertex(1) :
303  quad->line(3)->center()) ) / 8;
304  }
305 }
306 
307 
308 
309 template <int dim, int spacedim>
312 get_new_point_on_quad (const typename Triangulation<dim, spacedim>::quad_iterator &quad) const
313 {
315 }
316 
317 
318 template <>
319 Point<3>
321 get_new_point_on_quad (const Triangulation<2,3>::quad_iterator &quad) const
322 {
323  return compute_new_point_on_quad<2> (quad);
324 }
325 
326 
327 
328 template <>
329 Point<3>
331 get_new_point_on_quad (const Triangulation<3>::quad_iterator &quad) const
332 {
333  return compute_new_point_on_quad<3> (quad);
334 }
335 
336 
337 
338 template <int dim, int spacedim>
339 void
341 get_intermediate_points_on_line (const typename Triangulation<dim, spacedim>::line_iterator &line,
342  std::vector<Point<spacedim> > &points) const
343 {
344  const unsigned int n=points.size();
345  Assert(n>0, ExcInternalError());
346 
347  // Use interior points of QGaussLobatto quadrature formula support points
348  // for consistency with MappingQ
349  const std::vector<Point<1> > &line_points = this->get_line_support_points(n);
350 
351  const Point<spacedim> vertices[2] = { line->vertex(0),
352  line->vertex(1)
353  };
354 
355  for (unsigned int i=0; i<n; ++i)
356  {
357  const double x = line_points[1+i][0];
358  points[i] = (1-x)*vertices[0] + x*vertices[1];
359  }
360 }
361 
362 
363 
364 
365 template <int dim, int spacedim>
366 void
368 get_intermediate_points_on_quad (const typename Triangulation<dim, spacedim>::quad_iterator &,
369  std::vector<Point<spacedim> > &) const
370 {
371  Assert(false, ExcImpossibleInDim(dim));
372 }
373 
374 
375 
376 template <>
377 void
379 get_intermediate_points_on_quad (const Triangulation<3>::quad_iterator &quad,
380  std::vector<Point<3> > &points) const
381 {
382  const unsigned int spacedim = 3;
383 
384  const unsigned int n=points.size(),
385  m=static_cast<unsigned int>(std::sqrt(static_cast<double>(n)));
386  // is n a square number
387  Assert(m*m==n, ExcInternalError());
388 
389  const std::vector<Point<1> > &line_points = this->get_line_support_points(m);
390 
391  const Point<spacedim> vertices[4] = { quad->vertex(0),
392  quad->vertex(1),
393  quad->vertex(2),
394  quad->vertex(3)
395  };
396 
397  for (unsigned int i=0; i<m; ++i)
398  {
399  const double y=line_points[1+i][0];
400  for (unsigned int j=0; j<m; ++j)
401  {
402  const double x=line_points[1+j][0];
403  points[i*m+j]=((1-x) * vertices[0] +
404  x * vertices[1]) * (1-y) +
405  ((1-x) * vertices[2] +
406  x * vertices[3]) * y;
407  }
408  }
409 }
410 
411 
412 
413 template <>
414 void
416 get_intermediate_points_on_quad (const Triangulation<2,3>::quad_iterator &quad,
417  std::vector<Point<3> > &points) const
418 {
419  const unsigned int spacedim = 3;
420 
421  const unsigned int n=points.size(),
422  m=static_cast<unsigned int>(std::sqrt(static_cast<double>(n)));
423  // is n a square number
424  Assert(m*m==n, ExcInternalError());
425 
426  const std::vector<Point<1> > &line_points = this->get_line_support_points(m);
427 
428  const Point<spacedim> vertices[4] = { quad->vertex(0),
429  quad->vertex(1),
430  quad->vertex(2),
431  quad->vertex(3)
432  };
433 
434  for (unsigned int i=0; i<m; ++i)
435  {
436  const double y=line_points[1+i][0];
437  for (unsigned int j=0; j<m; ++j)
438  {
439  const double x=line_points[1+j][0];
440  points[i*m+j]=((1-x) * vertices[0] +
441  x * vertices[1]) * (1-y) +
442  ((1-x) * vertices[2] +
443  x * vertices[3]) * y;
444  }
445  }
446 }
447 
448 
449 
450 template <>
454  const Point<1> &) const
455 {
456  Assert (false, ExcNotImplemented());
457  return Tensor<1,1>();
458 }
459 
460 
461 template <>
465  const Point<2> &) const
466 {
467  Assert (false, ExcNotImplemented());
468  return Tensor<1,2>();
469 }
470 
471 
472 template <>
476  const Point<3> &) const
477 {
478  Assert (false, ExcNotImplemented());
479  return Tensor<1,3>();
480 }
481 
482 
483 namespace internal
484 {
485  namespace
486  {
492  normalized_alternating_product (const Tensor<1,2> (&basis_vectors)[1])
493  {
494  Tensor<1,2> tmp = cross_product_2d (basis_vectors[0]);
495  return tmp/tmp.norm();
496  }
497 
498 
499 
501  normalized_alternating_product (const Tensor<1,3> ( &)[1])
502  {
503  // we get here from StraightBoundary<2,3>::normal_vector, but
504  // the implementation below is bogus for this case anyway
505  // (see the assert at the beginning of that function).
506  Assert (false, ExcNotImplemented());
507  return Tensor<1,3>();
508  }
509 
510 
511 
513  normalized_alternating_product (const Tensor<1,3> (&basis_vectors)[2])
514  {
515  Tensor<1,3> tmp = cross_product_3d (basis_vectors[0], basis_vectors[1]);
516  return tmp/tmp.norm();
517  }
518 
519  }
520 }
521 
522 
523 template <int dim, int spacedim>
527  const Point<spacedim> &p) const
528 {
529  // I don't think the implementation below will work when dim!=spacedim;
530  // in fact, I believe that we don't even have enough information here,
531  // because we would need to know not only about the tangent vectors
532  // of the face, but also of the cell, to compute the normal vector.
533  // Someone will have to think about this some more.
534  Assert (dim == spacedim, ExcNotImplemented());
535 
536  // in order to find out what the normal vector is, we first need to
537  // find the reference coordinates of the point p on the given face,
538  // or at least the reference coordinates of the closest point on the
539  // face
540  //
541  // in other words, we need to find a point xi so that f(xi)=||F(xi)-p||^2->min
542  // where F(xi) is the mapping. this algorithm is implemented in
543  // MappingQ1<dim,spacedim>::transform_real_to_unit_cell but only for cells,
544  // while we need it for faces here. it's also implemented in somewhat
545  // more generality there using the machinery of the MappingQ1 class
546  // while we really only need it for a specific case here
547  //
548  // in any case, the iteration we use here is a Gauss-Newton's iteration with
549  // xi^{n+1} = xi^n - H(xi^n)^{-1} J(xi^n)
550  // where
551  // J(xi) = (grad F(xi))^T (F(xi)-p)
552  // and
553  // H(xi) = [grad F(xi)]^T [grad F(xi)]
554  // In all this,
555  // F(xi) = sum_v vertex[v] phi_v(xi)
556  // We get the shape functions phi_v from an object of type FE_Q<dim-1>(1)
557 
558  // we start with the point xi=1/2, xi=(1/2,1/2), ...
559  const unsigned int facedim = dim-1;
560 
561  Point<facedim> xi;
562  for (unsigned int i=0; i<facedim; ++i)
563  xi[i] = 1./2;
564 
565  FE_Q<facedim> linear_fe(1);
566 
567  const double eps = 1e-12;
568  Tensor<1,spacedim> grad_F[facedim];
569  unsigned int iteration = 0;
570  while (true)
571  {
572  Point<spacedim> F;
573  for (unsigned int v=0; v<GeometryInfo<facedim>::vertices_per_cell; ++v)
574  F += face->vertex(v) * linear_fe.shape_value(v, xi);
575 
576  for (unsigned int i=0; i<facedim; ++i)
577  {
578  grad_F[i] = 0;
579  for (unsigned int v=0; v<GeometryInfo<facedim>::vertices_per_cell; ++v)
580  grad_F[i] += face->vertex(v) * linear_fe.shape_grad(v, xi)[i];
581  }
582 
584  for (unsigned int i=0; i<facedim; ++i)
585  for (unsigned int j=0; j<spacedim; ++j)
586  J[i] += grad_F[i][j] * (F-p)[j];
587 
589  for (unsigned int i=0; i<facedim; ++i)
590  for (unsigned int j=0; j<facedim; ++j)
591  for (unsigned int k=0; k<spacedim; ++k)
592  H[i][j] += grad_F[i][k] * grad_F[j][k];
593 
594  const Tensor<1,facedim> delta_xi = -invert(H) * J;
595  xi += delta_xi;
596  ++iteration;
597 
598  Assert (iteration<10,
599  ExcMessage("The Newton iteration to find the reference point "
600  "did not converge in 10 iterations. Do you have a "
601  "deformed cell? (See the glossary for a definition "
602  "of what a deformed cell is. You may want to output "
603  "the vertices of your cell."));
604 
605  if (delta_xi.norm() < eps)
606  break;
607  }
608 
609  // so now we have the reference coordinates xi of the point p.
610  // we then have to compute the normal vector, which we can do
611  // by taking the (normalize) alternating product of all the tangent
612  // vectors given by grad_F
613  return internal::normalized_alternating_product(grad_F);
614 }
615 
616 
617 
618 template <>
619 void
623 {
624  Assert (false, ExcImpossibleInDim(1));
625 }
626 
627 template <>
628 void
632 {
633  Assert (false, ExcNotImplemented());
634 }
635 
636 
637 template <>
638 void
642 {
643  Assert (false, ExcNotImplemented());
644 }
645 
646 
647 
648 template <>
649 void
652  Boundary<2,2>::FaceVertexNormals &face_vertex_normals) const
653 {
654  const Tensor<1,2> tangent = face->vertex(1) - face->vertex(0);
655  for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_face; ++vertex)
656  // compute normals from tangent
657  face_vertex_normals[vertex] = Point<2>(tangent[1],
658  -tangent[0]);
659 }
660 
661 template <>
662 void
665  Boundary<2,3>::FaceVertexNormals &face_vertex_normals) const
666 {
667  const Tensor<1,3> tangent = face->vertex(1) - face->vertex(0);
668  for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_face; ++vertex)
669  // compute normals from tangent
670  face_vertex_normals[vertex] = Point<3>(tangent[1],
671  -tangent[0],0);
672  Assert(false, ExcNotImplemented());
673 }
674 
675 
676 
677 
678 template <>
679 void
682  Boundary<3,3>::FaceVertexNormals &face_vertex_normals) const
683 {
684  const unsigned int vertices_per_face = GeometryInfo<3>::vertices_per_face;
685 
686  static const unsigned int neighboring_vertices[4][2]=
687  { {1,2},{3,0},{0,3},{2,1}};
688  for (unsigned int vertex=0; vertex<vertices_per_face; ++vertex)
689  {
690  // first define the two tangent vectors at the vertex by using the
691  // two lines radiating away from this vertex
692  const Tensor<1,3> tangents[2]
693  = { face->vertex(neighboring_vertices[vertex][0])
694  - face->vertex(vertex),
695  face->vertex(neighboring_vertices[vertex][1])
696  - face->vertex(vertex)
697  };
698 
699  // then compute the normal by taking the cross product. since the
700  // normal is not required to be normalized, no problem here
701  face_vertex_normals[vertex] = cross_product_3d(tangents[0], tangents[1]);
702  };
703 }
704 
705 
706 
707 template <int dim, int spacedim>
710 project_to_surface (const typename Triangulation<dim, spacedim>::line_iterator &line,
711  const Point<spacedim> &trial_point) const
712 {
713  if (spacedim <= 1)
714  return trial_point;
715  else
716  {
717  // find the point that lies on
718  // the line p1--p2. the
719  // formulas pan out to
720  // something rather simple
721  // because the mapping to the
722  // line is linear
723  const Point<spacedim> p1 = line->vertex(0),
724  p2 = line->vertex(1);
725  const double s = (trial_point-p1)*(p2-p1) / ((p2-p1)*(p2-p1));
726  return p1 + s*(p2-p1);
727  }
728 }
729 
730 
731 
732 namespace internal
733 {
734  template <typename Iterator, int spacedim, int dim>
736  compute_projection (const Iterator &object,
737  const Point<spacedim> &y,
739  {
740  // let's look at this for
741  // simplicity for a quad (dim==2)
742  // in a space with spacedim>2:
743 
744  // all points on the surface are given by
745  // x(\xi) = sum_i v_i phi_x(\xi)
746  // where v_i are the vertices of the quad,
747  // and \xi=(\xi_1,\xi_2) are the reference
748  // coordinates of the quad. so what we are
749  // trying to do is find a point x on
750  // the surface that is closest to the point
751  // y. there are different ways
752  // to solve this problem, but in the end
753  // it's a nonlinear problem and we have to
754  // find reference coordinates \xi so that
755  // J(\xi) = 1/2 || x(\xi)-y ||^2
756  // is minimal. x(\xi) is a function that
757  // is dim-linear in \xi, so J(\xi) is
758  // a polynomial of degree 2*dim that
759  // we'd like to minimize. unless dim==1,
760  // we'll have to use a Newton
761  // method to find the
762  // answer. This leads to the
763  // following formulation of
764  // Newton steps:
765  //
766  // Given \xi_k, find \delta\xi_k so that
767  // H_k \delta\xi_k = - F_k
768  // where H_k is an approximation to the
769  // second derivatives of J at \xi_k, and
770  // F_k is the first derivative of J.
771  // We'll iterate this a number of times
772  // until the right hand side is small
773  // enough. As a stopping criterion, we
774  // terminate if ||\delta\xi||<eps.
775  //
776  // As for the Hessian, the best choice
777  // would be
778  // H_k = J''(\xi_k)
779  // but we'll opt for the simpler
780  // Gauss-Newton form
781  // H_k = A^T A
782  // i.e.
783  // (H_k)_{nm} = \sum_{i,j} v_i*v_j *
784  // \partial_n phi_i *
785  // \partial_m phi_j
786  // we start at xi=(0.5,0.5).
787  Point<dim> xi;
788  for (unsigned int d=0; d<dim; ++d)
789  xi[d] = 0.5;
790 
791  Point<spacedim> x_k;
792  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
793  x_k += object->vertex(i) *
795 
796  do
797  {
798  Tensor<1,dim> F_k;
799  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
800  F_k += (x_k-y)*object->vertex(i) *
802 
803  Tensor<2,dim> H_k;
804  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
805  for (unsigned int j=0; j<GeometryInfo<dim>::vertices_per_cell; ++j)
806  {
807  Tensor<2, dim> tmp = outer_product(
810  H_k += (object->vertex(i) * object->vertex(j)) * tmp;
811  }
812 
813  const Tensor<1,dim> delta_xi = - invert(H_k) * F_k;
814  xi += delta_xi;
815 
816  x_k = Point<spacedim>();
817  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
818  x_k += object->vertex(i) *
820 
821  if (delta_xi.norm() < 1e-5)
822  break;
823  }
824  while (true);
825 
826  return x_k;
827  }
828 
829 
830  // specialization for a quad in 1d
831  template <typename Iterator>
832  Point<1>
833  compute_projection (const Iterator &,
834  const Point<1> &y,
835  /* it's a quad: */internal::int2type<2>)
836  {
837  return y;
838  }
839 
840  // specialization for a quad in 2d
841  template <typename Iterator>
842  Point<2>
843  compute_projection (const Iterator &,
844  const Point<2> &y,
845  /* it's a quad: */internal::int2type<2>)
846  {
847  return y;
848  }
849 }
850 
851 
852 
853 
854 
855 template <>
856 Point<3>
858 project_to_surface (const Triangulation<1, 3>::quad_iterator &,
859  const Point<3> &y) const
860 {
861  return y;
862 }
863 
864 //TODO[SP]: This is just a horrible way out to make it compile in codim 2.
865 template <int dim, int spacedim>
868 project_to_surface (const typename Triangulation<dim, spacedim>::quad_iterator &quad,
869  const Point<spacedim> &y) const
870 {
871  if (spacedim <= 2)
872  return y;
873  else
874  return internal::compute_projection (quad, y,
875  /* it's a quad */internal::int2type<2>());
876 }
877 
878 
879 
880 template <int dim, int spacedim>
883 project_to_surface (const typename Triangulation<dim, spacedim>::hex_iterator &,
884  const Point<spacedim> &trial_point) const
885 {
886  if (spacedim <= 3)
887  return trial_point;
888  else
889  {
890  // we can presumably call the
891  // same function as above (it's
892  // written in a generic way)
893  // but someone needs to check
894  // whether that actually yields
895  // the correct result
896  Assert (false, ExcNotImplemented());
897  return Point<spacedim>();
898  }
899 }
900 
901 
902 
903 // explicit instantiations
904 #include "tria_boundary.inst"
905 
906 DEAL_II_NAMESPACE_CLOSE
907 
const std::vector< Point< 1 > > & get_line_support_points(const unsigned int n_intermediate_points) const
virtual Tensor< 1, spacedim > normal_vector(const typename Triangulation< dim, spacedim >::face_iterator &face, const Point< spacedim > &p) const
::ExceptionBase & ExcMessage(std::string arg1)
virtual void get_intermediate_points_on_line(const typename Triangulation< dim, spacedim >::line_iterator &line, std::vector< Point< spacedim > > &points) const
virtual Point< spacedim > get_new_point_on_line(const typename Triangulation< dim, spacedim >::line_iterator &line) const
numbers::NumberTraits< Number >::real_type norm() const
Definition: tensor.h:1047
virtual Tensor< 1, dim > shape_grad(const unsigned int i, const Point< dim > &p) const
virtual void get_intermediate_points_on_line(const typename Triangulation< dim, spacedim >::line_iterator &line, std::vector< Point< spacedim > > &points) const
virtual Tensor< 1, spacedim > normal_vector(const typename Triangulation< dim, spacedim >::face_iterator &face, const Point< spacedim > &p) const
virtual Point< spacedim > project_to_surface(const typename Triangulation< dim, spacedim >::line_iterator &line, const Point< spacedim > &candidate) const
virtual void get_intermediate_points_on_quad(const typename Triangulation< dim, spacedim >::quad_iterator &quad, std::vector< Point< spacedim > > &points) const
Definition: tria.h:46
virtual Point< spacedim > get_new_point_on_quad(const typename Triangulation< dim, spacedim >::quad_iterator &quad) const
Definition: fe_q.h:522
virtual ~Boundary()
#define Assert(cond, exc)
Definition: exceptions.h:294
void get_intermediate_points_on_face(const typename Triangulation< dim, spacedim >::face_iterator &face, std::vector< Point< spacedim > > &points) const
virtual double shape_value(const unsigned int i, const Point< dim > &p) const
virtual void get_normals_at_vertices(const typename Triangulation< dim, spacedim >::face_iterator &face, FaceVertexNormals &face_vertex_normals) const
virtual Point< spacedim > get_new_point_on_quad(const typename Triangulation< dim, spacedim >::quad_iterator &quad) const
Definition: manifold.cc:85
virtual void get_intermediate_points_on_quad(const typename Triangulation< dim, spacedim >::quad_iterator &quad, std::vector< Point< spacedim > > &points) const
virtual Point< spacedim > project_to_surface(const typename Triangulation< dim, spacedim >::line_iterator &line, const Point< spacedim > &candidate) const
virtual void get_normals_at_vertices(const typename Triangulation< dim, spacedim >::face_iterator &face, typename Boundary< dim, spacedim >::FaceVertexNormals &face_vertex_normals) const
static Tensor< 1, dim > d_linear_shape_function_gradient(const Point< dim > &xi, const unsigned int i)
static double d_linear_shape_function(const Point< dim > &xi, const unsigned int i)