Reference documentation for deal.II version 9.1.0-pre
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 
25 #include <deal.II/grid/manifold.h>
26 
27 DEAL_II_NAMESPACE_OPEN
28 
29 
30 
63 template <int dim,
64  int dim_A,
65  int spacedim_A,
66  int chartdim_A,
67  int dim_B,
68  int spacedim_B,
69  int chartdim_B>
71  : public ChartManifold<dim, spacedim_A + spacedim_B, chartdim_A + chartdim_B>
72 {
73 public:
78  static const unsigned int chartdim = chartdim_A + chartdim_B;
83  static const unsigned int spacedim = spacedim_A + spacedim_B;
84 
91 
95  virtual std::unique_ptr<Manifold<dim, spacedim_A + spacedim_B>>
96  clone() const override;
97 
101  virtual Point<chartdim>
102  pull_back(const Point<spacedim> &space_point) const override;
103 
107  virtual Point<spacedim>
108  push_forward(const Point<chartdim> &chart_point) const override;
109 
114  push_forward_gradient(const Point<chartdim> &chart_point) const override;
115 
116 private:
119  dim_A,
120  spacedim_A,
121  chartdim_A,
122  dim_B,
123  spacedim_B,
124  chartdim_B>>
125  manifold_A;
126 
129  dim_A,
130  spacedim_A,
131  chartdim_A,
132  dim_B,
133  spacedim_B,
134  chartdim_B>>
135  manifold_B;
136 };
137 
138 
139 
140 /*------------------Template Implementations------------------------*/
141 
142 
143 
144 namespace internal
145 {
146  namespace TensorProductManifoldImplementation
147  {
148  template <int dim1, int dim2>
150  concat(const Tensor<1, dim1> &p1, const Tensor<1, dim2> &p2)
151  {
153  for (unsigned int d = 0; d < dim1; ++d)
154  r[d] = p1[d];
155  for (unsigned int d = 0; d < dim2; ++d)
156  r[dim1 + d] = p2[d];
157  return r;
158  }
159 
160  template <int dim1, int dim2>
162  concat(const Point<dim1> &p1, const Point<dim2> &p2)
163  {
165  for (unsigned int d = 0; d < dim1; ++d)
166  r[d] = p1[d];
167  for (unsigned int d = 0; d < dim2; ++d)
168  r[dim1 + d] = p2[d];
169  return r;
170  }
171 
172  template <int dim1, int dim2>
173  void
174  split_point(const Point<dim1 + dim2> &source,
175  Point<dim1> & p1,
176  Point<dim2> & p2)
177  {
178  for (unsigned int d = 0; d < dim1; ++d)
179  p1[d] = source[d];
180  for (unsigned int d = 0; d < dim2; ++d)
181  p2[d] = source[dim1 + d];
182  }
183 
184  } // namespace TensorProductManifoldImplementation
185 } // namespace internal
186 
187 template <int dim,
188  int dim_A,
189  int spacedim_A,
190  int chartdim_A,
191  int dim_B,
192  int spacedim_B,
193  int chartdim_B>
195  dim_A,
196  spacedim_A,
197  chartdim_A,
198  dim_B,
199  spacedim_B,
200  chartdim_B>::
204  : ChartManifold<dim, spacedim_A + spacedim_B, chartdim_A + chartdim_B>(
205  internal::TensorProductManifoldImplementation::concat(
206  manifold_A.get_periodicity(),
207  manifold_B.get_periodicity()))
208  , manifold_A(&manifold_A)
209  , manifold_B(&manifold_B)
210 {}
211 
212 template <int dim,
213  int dim_A,
214  int spacedim_A,
215  int chartdim_A,
216  int dim_B,
217  int spacedim_B,
218  int chartdim_B>
219 std::unique_ptr<Manifold<dim, spacedim_A + spacedim_B>>
221  dim_A,
222  spacedim_A,
223  chartdim_A,
224  dim_B,
225  spacedim_B,
226  chartdim_B>::clone() const
227 {
228  return std_cxx14::make_unique<TensorProductManifold<dim,
229  dim_A,
230  spacedim_A,
231  chartdim_A,
232  dim_B,
233  spacedim_B,
234  chartdim_B>>(*manifold_A,
235  *manifold_B);
236 }
237 
238 template <int dim,
239  int dim_A,
240  int spacedim_A,
241  int chartdim_A,
242  int dim_B,
243  int spacedim_B,
244  int chartdim_B>
246  dim_A,
247  spacedim_A,
248  chartdim_A,
249  dim_B,
250  spacedim_B,
251  chartdim_B>::chartdim>
253  dim_A,
254  spacedim_A,
255  chartdim_A,
256  dim_B,
257  spacedim_B,
258  chartdim_B>::
260  const Point<TensorProductManifold<dim,
261  dim_A,
262  spacedim_A,
263  chartdim_A,
264  dim_B,
265  spacedim_B,
266  chartdim_B>::spacedim> &space_point) const
267 {
268  Point<spacedim_A> space_point_A;
269  Point<spacedim_B> space_point_B;
270  internal::TensorProductManifoldImplementation::split_point(space_point,
271  space_point_A,
272  space_point_B);
273 
274  Point<chartdim_A> result_A = manifold_A->pull_back(space_point_A);
275  Point<chartdim_B> result_B = manifold_B->pull_back(space_point_B);
276 
277  return internal::TensorProductManifoldImplementation::concat(result_A,
278  result_B);
279 }
280 
281 template <int dim,
282  int dim_A,
283  int spacedim_A,
284  int chartdim_A,
285  int dim_B,
286  int spacedim_B,
287  int chartdim_B>
289  dim_A,
290  spacedim_A,
291  chartdim_A,
292  dim_B,
293  spacedim_B,
294  chartdim_B>::spacedim>
296  dim_A,
297  spacedim_A,
298  chartdim_A,
299  dim_B,
300  spacedim_B,
301  chartdim_B>::
303  const Point<TensorProductManifold<dim,
304  dim_A,
305  spacedim_A,
306  chartdim_A,
307  dim_B,
308  spacedim_B,
309  chartdim_B>::chartdim> &chart_point) const
310 {
311  Point<chartdim_A> chart_point_A;
312  Point<chartdim_B> chart_point_B;
313  internal::TensorProductManifoldImplementation::split_point(chart_point,
314  chart_point_A,
315  chart_point_B);
316 
317  Point<spacedim_A> result_A = manifold_A->push_forward(chart_point_A);
318  Point<spacedim_B> result_B = manifold_B->push_forward(chart_point_B);
319 
320  return internal::TensorProductManifoldImplementation::concat(result_A,
321  result_B);
322 }
323 
324 template <int dim,
325  int dim_A,
326  int spacedim_A,
327  int chartdim_A,
328  int dim_B,
329  int spacedim_B,
330  int chartdim_B>
333  dim_A,
334  spacedim_A,
335  chartdim_A,
336  dim_B,
337  spacedim_B,
338  chartdim_B>::chartdim,
340  dim_A,
341  spacedim_A,
342  chartdim_A,
343  dim_B,
344  spacedim_B,
345  chartdim_B>::spacedim>
346 
348  dim_A,
349  spacedim_A,
350  chartdim_A,
351  dim_B,
352  spacedim_B,
353  chartdim_B>::
355  const Point<TensorProductManifold<dim,
356  dim_A,
357  spacedim_A,
358  chartdim_A,
359  dim_B,
360  spacedim_B,
361  chartdim_B>::chartdim> &chart_point) const
362 {
363  Point<chartdim_A> chart_point_A;
364  Point<chartdim_B> chart_point_B;
365  internal::TensorProductManifoldImplementation::split_point(chart_point,
366  chart_point_A,
367  chart_point_B);
368 
370  manifold_A->push_forward_gradient(chart_point_A);
372  manifold_B->push_forward_gradient(chart_point_B);
373 
374 
376  for (unsigned int i = 0; i < chartdim_A; ++i)
377  for (unsigned int j = 0; j < spacedim_A; ++j)
378  result[j][i] = result_A[j][i];
379  for (unsigned int i = 0; i < chartdim_B; ++i)
380  for (unsigned int j = 0; j < spacedim_B; ++j)
381  result[j + spacedim_A][i + chartdim_A] = result_B[j][i];
382 
383  return result;
384 }
385 
386 
387 
388 DEAL_II_NAMESPACE_CLOSE
389 
390 #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:106
Tensor product manifold of two ChartManifolds.
virtual std::unique_ptr< Manifold< dim, spacedim_A+spacedim_B > > clone() const override
virtual DerivativeForm< 1, chartdim, spacedim > push_forward_gradient(const Point< chartdim > &chart_point) const
Definition: manifold.cc:1024
static const unsigned int spacedim
Definition: mpi.h:55
TensorProductManifold(const ChartManifold< dim_A, spacedim_A, chartdim_A > &manifold_A, const ChartManifold< dim_B, spacedim_B, chartdim_B > &manifold_B)
virtual Point< spacedim > push_forward(const Point< chartdim > &chart_point) const =0
virtual Point< chartdim > pull_back(const Point< spacedim > &space_point) const =0