Reference documentation for deal.II version 8.5.1
mapping_c1.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2001 - 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/grid/tria_accessor.h>
17 #include <deal.II/grid/tria_iterator.h>
18 #include <deal.II/grid/tria_boundary.h>
19 #include <deal.II/fe/mapping_c1.h>
20 #include <cmath>
21 
22 DEAL_II_NAMESPACE_OPEN
23 
24 
25 
26 template <int dim, int spacedim>
28  :
29  MappingQGeneric<dim,spacedim> (3)
30 {}
31 
32 
33 
34 template <int dim, int spacedim>
36  :
37  MappingQ<dim,spacedim> (3)
38 {
39  Assert (dim > 1, ExcImpossibleInDim(dim));
40 
41  // replace the mapping_qp objects of the base class by something
42  // that knows about generating data points based on the geometry
43  //
44  // we only need to replace the Qp mapping because that's the one that's
45  // used on boundary cells where it matters
47 }
48 
49 
50 
51 template <>
52 void
54  std::vector<Point<1> > &) const
55 {
56  const unsigned int dim = 1;
57  (void)dim;
58  Assert (dim > 1, ExcImpossibleInDim(dim));
59 }
60 
61 
62 
63 template <>
64 void
66  std::vector<Point<2> > &a) const
67 {
68  const unsigned int dim = 2;
69  std::vector<Point<dim> > line_points (2);
70 
71  // loop over each of the lines, and if it is at the boundary, then first get
72  // the boundary description and second compute the points on it. if not at
73  // the boundary, get the respective points from another function
74  for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
75  {
76  const Triangulation<dim>::line_iterator line = cell->line(line_no);
77 
78  if (line->at_boundary())
79  {
80  // first get the normal vectors at the two vertices of this line
81  // from the boundary description
82  const Boundary<dim> &boundary
83  = line->get_triangulation().get_boundary(line->boundary_id());
84 
85  Boundary<dim>::FaceVertexNormals face_vertex_normals;
86  boundary.get_normals_at_vertices (line, face_vertex_normals);
87 
88  // then transform them into interpolation points for a cubic
89  // polynomial
90  //
91  // for this, note that if we describe the boundary curve as a
92  // polynomial in tangential coordinate @p{t=0..1} (along the line)
93  // and @p{s} in normal direction, then the cubic mapping is such
94  // that @p{s = a*t**3 + b*t**2 + c*t + d}, and we want to determine
95  // the interpolation points at @p{t=0.276} and @p{t=0.724}
96  // (Gauss-Lobatto points). Since at @p{t=0,1} we want a vertex which
97  // is actually at the boundary, we know that @p{d=0} and @p{a=-b-c},
98  // which gives @p{s(0.276)} and @p{s(0.726)} in terms of @p{b,c}. As
99  // side-conditions, we want that the derivatives at @p{t=0} and
100  // @p{t=1}, i.e. at the vertices match those returned by the
101  // boundary.
102  //
103  // The task is then first to determine the coefficients from the
104  // tangentials. for that, first rotate the tangents of @p{s(t)} into
105  // the global coordinate system. they are @p{A (1,c)} and @p{A
106  // (1,-b-2c)} with @p{A} the rotation matrix, since the tangentials
107  // in the coordinate system relative to the line are @p{(1,c)} and
108  // @p{(1,-b-2c)} at the two vertices, respectively. We then have to
109  // make sure by matching @p{b,c} that these tangentials are
110  // orthogonal to the normals returned by the boundary object
111  const Tensor<1,2> coordinate_vector = line->vertex(1) - line->vertex(0);
112  const double h = std::sqrt(coordinate_vector * coordinate_vector);
113  Tensor<1,2> coordinate_axis = coordinate_vector;
114  coordinate_axis /= h;
115 
116  const double alpha = std::atan2(coordinate_axis[1], coordinate_axis[0]);
117  const double c = -((face_vertex_normals[0][1] * std::sin(alpha)
118  +face_vertex_normals[0][0] * std::cos(alpha)) /
119  (face_vertex_normals[0][1] * std::cos(alpha)
120  -face_vertex_normals[0][0] * std::sin(alpha)));
121  const double b = ((face_vertex_normals[1][1] * std::sin(alpha)
122  +face_vertex_normals[1][0] * std::cos(alpha)) /
123  (face_vertex_normals[1][1] * std::cos(alpha)
124  -face_vertex_normals[1][0] * std::sin(alpha)))
125  -2*c;
126 
127  QGaussLobatto<1> quad_points(4);
128  const double t1 = quad_points.point(1)[0];
129  const double t2 = quad_points.point(2)[0];
130  const double s_t1 = (((-b-c)*t1+b)*t1+c)*t1;
131  const double s_t2 = (((-b-c)*t2+b)*t2+c)*t2;
132 
133  // next evaluate the so determined cubic polynomial at the points
134  // 1/3 and 2/3, first in unit coordinates
135  const Point<2> new_unit_points[2] = { Point<2>(t1, s_t1),
136  Point<2>(t2, s_t2)
137  };
138  // then transform these points to real coordinates by rotating,
139  // scaling and shifting
140  for (unsigned int i=0; i<2; ++i)
141  {
142  Point<2> real_point (std::cos(alpha) * new_unit_points[i][0]
143  - std::sin(alpha) * new_unit_points[i][1],
144  std::sin(alpha) * new_unit_points[i][0]
145  + std::cos(alpha) * new_unit_points[i][1]);
146  real_point *= h;
147  real_point += line->vertex(0);
148  a.push_back (real_point);
149  };
150  }
151  else
152  // not at boundary
153  {
154  static const StraightBoundary<dim> straight_boundary;
155  straight_boundary.get_intermediate_points_on_line (line, line_points);
156  a.insert (a.end(), line_points.begin(), line_points.end());
157  }
158  }
159 }
160 
161 
162 
163 template<int dim, int spacedim>
164 void
166  std::vector<Point<dim> > &) const
167 {
168  Assert (false, ExcNotImplemented());
169 }
170 
171 
172 
173 template <>
174 void
176  std::vector<Point<1> > &) const
177 {
178  const unsigned int dim = 1;
179  (void)dim;
180  Assert (dim > 2, ExcImpossibleInDim(dim));
181 }
182 
183 
184 
185 template <>
186 void
188  std::vector<Point<2> > &) const
189 {
190  const unsigned int dim = 2;
191  (void)dim;
192  Assert (dim > 2, ExcImpossibleInDim(dim));
193 }
194 
195 
196 
197 template<int dim, int spacedim>
198 void
200  std::vector<Point<dim> > &) const
201 {
202  Assert (false, ExcNotImplemented());
203 }
204 
205 
206 
207 template<int dim, int spacedim>
210 {
211  return new MappingC1<dim,spacedim>();
212 }
213 
214 
215 
216 
217 // explicit instantiations
218 #include "mapping_c1.inst"
219 
220 
221 DEAL_II_NAMESPACE_CLOSE
virtual Mapping< dim, spacedim > * clone() const
Definition: mapping_c1.cc:209
const Boundary< dim, spacedim > & get_boundary(const types::manifold_id number) const
Definition: tria.cc:9223
Definition: point.h:89
virtual void add_quad_support_points(const typename Triangulation< dim >::cell_iterator &cell, std::vector< Point< dim > > &a) const
Definition: mapping_c1.cc:199
virtual void get_intermediate_points_on_line(const typename Triangulation< dim, spacedim >::line_iterator &line, std::vector< Point< spacedim > > &points) const
Definition: tria.h:52
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
#define Assert(cond, exc)
Definition: exceptions.h:313
Abstract base class for mapping classes.
Definition: dof_tools.h:46
virtual void add_line_support_points(const typename Triangulation< dim >::cell_iterator &cell, std::vector< Point< dim > > &a) const
Definition: mapping_c1.cc:165
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
Definition: mpi.h:41
static ::ExceptionBase & ExcNotImplemented()
std_cxx11::shared_ptr< const MappingQGeneric< dim, spacedim > > qp_mapping
Definition: mapping_q.h:371
virtual void get_normals_at_vertices(const typename Triangulation< dim, spacedim >::face_iterator &face, FaceVertexNormals &face_vertex_normals) const
Definition: manifold.cc:360
Triangulation< dim, spacedim > & get_triangulation()
Definition: tria.cc:11855