Reference documentation for deal.II version 9.1.1
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
tensor_product_manifold.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2016 - 2018 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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_tensor_product_manifold_h
17 #define dealii_tensor_product_manifold_h
18 
19 #include <deal.II/base/config.h>
20 
21 #include <deal.II/base/point.h>
22 #include <deal.II/base/std_cxx14/memory.h>
23 #include <deal.II/base/subscriptor.h>
24 #include <deal.II/base/utilities.h>
25 
26 #include <deal.II/grid/manifold.h>
27 
28 DEAL_II_NAMESPACE_OPEN
29 
30 
31 
64 template <int dim,
65  int dim_A,
66  int spacedim_A,
67  int chartdim_A,
68  int dim_B,
69  int spacedim_B,
70  int chartdim_B>
72  : public ChartManifold<dim, spacedim_A + spacedim_B, chartdim_A + chartdim_B>
73 {
74 public:
79  static const unsigned int chartdim = chartdim_A + chartdim_B;
84  static const unsigned int spacedim = spacedim_A + spacedim_B;
85 
92 
96  virtual std::unique_ptr<Manifold<dim, spacedim_A + spacedim_B>>
97  clone() const override;
98 
102  virtual Point<chartdim>
103  pull_back(const Point<spacedim> &space_point) const override;
104 
108  virtual Point<spacedim>
109  push_forward(const Point<chartdim> &chart_point) const override;
110 
115  push_forward_gradient(const Point<chartdim> &chart_point) const override;
116 
117 private:
118  std::unique_ptr<const ChartManifold<dim_A, spacedim_A, chartdim_A>>
119  manifold_A;
120 
121  std::unique_ptr<const ChartManifold<dim_B, spacedim_B, chartdim_B>>
122  manifold_B;
123 };
124 
125 
126 
127 /*------------------Template Implementations------------------------*/
128 
129 
130 
131 namespace internal
132 {
133  namespace TensorProductManifoldImplementation
134  {
135  template <int dim1, int dim2>
137  concat(const Tensor<1, dim1> &p1, const Tensor<1, dim2> &p2)
138  {
140  for (unsigned int d = 0; d < dim1; ++d)
141  r[d] = p1[d];
142  for (unsigned int d = 0; d < dim2; ++d)
143  r[dim1 + d] = p2[d];
144  return r;
145  }
146 
147  template <int dim1, int dim2>
149  concat(const Point<dim1> &p1, const Point<dim2> &p2)
150  {
152  for (unsigned int d = 0; d < dim1; ++d)
153  r[d] = p1[d];
154  for (unsigned int d = 0; d < dim2; ++d)
155  r[dim1 + d] = p2[d];
156  return r;
157  }
158 
159  template <int dim1, int dim2>
160  void
161  split_point(const Point<dim1 + dim2> &source,
162  Point<dim1> & p1,
163  Point<dim2> & p2)
164  {
165  for (unsigned int d = 0; d < dim1; ++d)
166  p1[d] = source[d];
167  for (unsigned int d = 0; d < dim2; ++d)
168  p2[d] = source[dim1 + d];
169  }
170 
171  } // namespace TensorProductManifoldImplementation
172 } // namespace internal
173 
174 template <int dim,
175  int dim_A,
176  int spacedim_A,
177  int chartdim_A,
178  int dim_B,
179  int spacedim_B,
180  int chartdim_B>
182  dim_A,
183  spacedim_A,
184  chartdim_A,
185  dim_B,
186  spacedim_B,
187  chartdim_B>::
188  TensorProductManifold(
191  : ChartManifold<dim, spacedim_A + spacedim_B, chartdim_A + chartdim_B>(
192  internal::TensorProductManifoldImplementation::concat(
193  manifold_A.get_periodicity(),
194  manifold_B.get_periodicity()))
195  , manifold_A(Utilities::dynamic_unique_cast<
196  ChartManifold<dim_A, spacedim_A, chartdim_A>,
197  Manifold<dim_A, spacedim_A>>(manifold_A.clone()))
198  , manifold_B(Utilities::dynamic_unique_cast<
199  ChartManifold<dim_B, spacedim_B, chartdim_B>,
200  Manifold<dim_B, spacedim_B>>(manifold_B.clone()))
201 {}
202 
203 template <int dim,
204  int dim_A,
205  int spacedim_A,
206  int chartdim_A,
207  int dim_B,
208  int spacedim_B,
209  int chartdim_B>
210 std::unique_ptr<Manifold<dim, spacedim_A + spacedim_B>>
212  dim_A,
213  spacedim_A,
214  chartdim_A,
215  dim_B,
216  spacedim_B,
217  chartdim_B>::clone() const
218 {
219  return std_cxx14::make_unique<TensorProductManifold<dim,
220  dim_A,
221  spacedim_A,
222  chartdim_A,
223  dim_B,
224  spacedim_B,
225  chartdim_B>>(*manifold_A,
226  *manifold_B);
227 }
228 
229 template <int dim,
230  int dim_A,
231  int spacedim_A,
232  int chartdim_A,
233  int dim_B,
234  int spacedim_B,
235  int chartdim_B>
237  dim_A,
238  spacedim_A,
239  chartdim_A,
240  dim_B,
241  spacedim_B,
242  chartdim_B>::chartdim>
244  dim_A,
245  spacedim_A,
246  chartdim_A,
247  dim_B,
248  spacedim_B,
249  chartdim_B>::
250  pull_back(
251  const Point<TensorProductManifold<dim,
252  dim_A,
253  spacedim_A,
254  chartdim_A,
255  dim_B,
256  spacedim_B,
257  chartdim_B>::spacedim> &space_point) const
258 {
259  Point<spacedim_A> space_point_A;
260  Point<spacedim_B> space_point_B;
261  internal::TensorProductManifoldImplementation::split_point(space_point,
262  space_point_A,
263  space_point_B);
264 
265  Point<chartdim_A> result_A = manifold_A->pull_back(space_point_A);
266  Point<chartdim_B> result_B = manifold_B->pull_back(space_point_B);
267 
268  return internal::TensorProductManifoldImplementation::concat(result_A,
269  result_B);
270 }
271 
272 template <int dim,
273  int dim_A,
274  int spacedim_A,
275  int chartdim_A,
276  int dim_B,
277  int spacedim_B,
278  int chartdim_B>
280  dim_A,
281  spacedim_A,
282  chartdim_A,
283  dim_B,
284  spacedim_B,
285  chartdim_B>::spacedim>
287  dim_A,
288  spacedim_A,
289  chartdim_A,
290  dim_B,
291  spacedim_B,
292  chartdim_B>::
293  push_forward(
294  const Point<TensorProductManifold<dim,
295  dim_A,
296  spacedim_A,
297  chartdim_A,
298  dim_B,
299  spacedim_B,
300  chartdim_B>::chartdim> &chart_point) const
301 {
302  Point<chartdim_A> chart_point_A;
303  Point<chartdim_B> chart_point_B;
304  internal::TensorProductManifoldImplementation::split_point(chart_point,
305  chart_point_A,
306  chart_point_B);
307 
308  Point<spacedim_A> result_A = manifold_A->push_forward(chart_point_A);
309  Point<spacedim_B> result_B = manifold_B->push_forward(chart_point_B);
310 
311  return internal::TensorProductManifoldImplementation::concat(result_A,
312  result_B);
313 }
314 
315 template <int dim,
316  int dim_A,
317  int spacedim_A,
318  int chartdim_A,
319  int dim_B,
320  int spacedim_B,
321  int chartdim_B>
324  dim_A,
325  spacedim_A,
326  chartdim_A,
327  dim_B,
328  spacedim_B,
329  chartdim_B>::chartdim,
331  dim_A,
332  spacedim_A,
333  chartdim_A,
334  dim_B,
335  spacedim_B,
336  chartdim_B>::spacedim>
337 
339  dim_A,
340  spacedim_A,
341  chartdim_A,
342  dim_B,
343  spacedim_B,
344  chartdim_B>::
345  push_forward_gradient(
346  const Point<TensorProductManifold<dim,
347  dim_A,
348  spacedim_A,
349  chartdim_A,
350  dim_B,
351  spacedim_B,
352  chartdim_B>::chartdim> &chart_point) const
353 {
354  Point<chartdim_A> chart_point_A;
355  Point<chartdim_B> chart_point_B;
356  internal::TensorProductManifoldImplementation::split_point(chart_point,
357  chart_point_A,
358  chart_point_B);
359 
361  manifold_A->push_forward_gradient(chart_point_A);
363  manifold_B->push_forward_gradient(chart_point_B);
364 
365 
367  for (unsigned int i = 0; i < chartdim_A; ++i)
368  for (unsigned int j = 0; j < spacedim_A; ++j)
369  result[j][i] = result_A[j][i];
370  for (unsigned int i = 0; i < chartdim_B; ++i)
371  for (unsigned int j = 0; j < spacedim_B; ++j)
372  result[j + spacedim_A][i + chartdim_A] = result_B[j][i];
373 
374  return result;
375 }
376 
377 
378 
379 DEAL_II_NAMESPACE_CLOSE
380 
381 #endif
virtual DerivativeForm< 1, chartdim, spacedim > push_forward_gradient(const Point< chartdim > &chart_point) const override
virtual Point< spacedim > push_forward(const Point< chartdim > &chart_point) const override
static const unsigned int chartdim
virtual Point< chartdim > pull_back(const Point< spacedim > &space_point) const override
Definition: point.h:110
Tensor product manifold of two ChartManifolds.
virtual std::unique_ptr< Manifold< dim, spacedim_A+spacedim_B > > clone() const override
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
Definition: cuda.h:31
static const unsigned int spacedim
Definition: mpi.h:90
TensorProductManifold(const ChartManifold< dim_A, spacedim_A, chartdim_A > &manifold_A, const ChartManifold< dim_B, spacedim_B, chartdim_B > &manifold_B)