Reference documentation for deal.II version GIT 9042b9283b 2023-12-02 14:50:02+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
derivative_form.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2013 - 2023 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_derivative_form_h
17 #define dealii_derivative_form_h
18 
19 #include <deal.II/base/config.h>
20 
21 #include <deal.II/base/tensor.h>
22 
24 
57 template <int order, int dim, int spacedim, typename Number = double>
59 {
60 public:
64  DerivativeForm() = default;
65 
70 
78 
83  operator[](const unsigned int i);
84 
89  operator[](const unsigned int i) const;
90 
96 
101  operator=(const Tensor<order, spacedim, Tensor<1, dim, Number>> &);
102 
108 
112  template <typename OtherNumber>
115 
122 
126  operator Tensor<1, dim, Number>() const;
127 
133  transpose() const;
134 
141  norm() const;
142 
148  Number
149  determinant() const;
150 
161  covariant_form() const;
162 
167  static std::size_t
169 
174  int,
175  << "Invalid DerivativeForm index " << arg1);
176 
177 private:
184 
185 
190 };
191 
192 
193 /*--------------------------- Inline functions -----------------------------*/
194 
195 #ifndef DOXYGEN
196 
197 template <int order, int dim, int spacedim, typename Number>
200 {
201  Assert((dim == spacedim),
202  ExcMessage("Only allowed for forms with dim==spacedim."));
203  if (dim == spacedim)
204  for (unsigned int j = 0; j < dim; ++j)
205  (*this)[j] = T[j];
206 }
207 
208 
209 
210 template <int order, int dim, int spacedim, typename Number>
212  const Tensor<1, spacedim, Tensor<order, dim, Number>> &T)
213 {
214  for (unsigned int j = 0; j < spacedim; ++j)
215  (*this)[j] = T[j];
216 }
217 
218 
219 
220 template <int order, int dim, int spacedim, typename Number>
224 {
225  Assert((dim == spacedim), ExcMessage("Only allowed when dim==spacedim."));
226 
227  if (dim == spacedim)
228  for (unsigned int j = 0; j < dim; ++j)
229  (*this)[j] = ta[j];
230  return *this;
231 }
232 
233 
234 
235 template <int order, int dim, int spacedim, typename Number>
238  const Tensor<order, spacedim, Tensor<1, dim, Number>> &T)
239 {
240  for (unsigned int j = 0; j < spacedim; ++j)
241  (*this)[j] = T[j];
242  return *this;
243 }
244 
245 
246 
247 template <int order, int dim, int spacedim, typename Number>
250  const Tensor<1, dim, Number> &T)
251 {
252  Assert((1 == spacedim) && (order == 1),
253  ExcMessage("Only allowed for spacedim==1 and order==1."));
254 
255  (*this)[0] = T;
256 
257  return *this;
258 }
259 
260 
261 
262 template <int order, int dim, int spacedim, typename Number>
263 template <typename OtherNumber>
267 {
268  for (unsigned int j = 0; j < spacedim; ++j)
269  (*this)[j] = df[j];
270  return *this;
271 }
272 
273 
274 
275 template <int order, int dim, int spacedim, typename Number>
278 {
279  AssertIndexRange(i, spacedim);
280 
281  return tensor[i];
282 }
283 
284 
285 
286 template <int order, int dim, int spacedim, typename Number>
287 inline const Tensor<order, dim, Number> &
289  const unsigned int i) const
290 {
291  AssertIndexRange(i, spacedim);
292 
293  return tensor[i];
294 }
295 
296 
297 
298 template <int order, int dim, int spacedim, typename Number>
300 operator Tensor<1, dim, Number>() const
301 {
302  Assert((1 == spacedim) && (order == 1),
303  ExcMessage("Only allowed for spacedim==1."));
304 
305  return (*this)[0];
306 }
307 
308 
309 
310 template <int order, int dim, int spacedim, typename Number>
312 operator Tensor<order + 1, dim, Number>() const
313 {
314  Assert((dim == spacedim), ExcMessage("Only allowed when dim==spacedim."));
315 
317 
318  if (dim == spacedim)
319  for (unsigned int j = 0; j < dim; ++j)
320  t[j] = (*this)[j];
321 
322  return t;
323 }
324 
325 
326 
327 template <int order, int dim, int spacedim, typename Number>
330 {
331  Assert(order == 1, ExcMessage("Only for rectangular DerivativeForm."));
333 
334  for (unsigned int i = 0; i < spacedim; ++i)
335  for (unsigned int j = 0; j < dim; ++j)
336  tt[j][i] = (*this)[i][j];
337 
338  return tt;
339 }
340 
341 
342 
343 template <int order, int dim, int spacedim, typename Number>
346  const Tensor<2, dim, Number> &T) const
347 {
348  Assert(order == 1, ExcMessage("Only for order == 1."));
350  for (unsigned int i = 0; i < spacedim; ++i)
351  for (unsigned int j = 0; j < dim; ++j)
352  dest[i][j] = (*this)[i] * T[j];
353 
354  return dest;
355 }
356 
357 
358 
359 template <int order, int dim, int spacedim, typename Number>
362 {
363  typename numbers::NumberTraits<Number>::real_type sum_of_squares = 0;
364  for (unsigned int i = 0; i < spacedim; ++i)
365  sum_of_squares += tensor[i].norm_square();
366  return std::sqrt(sum_of_squares);
367 }
368 
369 
370 
371 template <int order, int dim, int spacedim, typename Number>
372 inline Number
374 {
375  Assert(order == 1, ExcMessage("Only for order == 1."));
376  if (dim == spacedim)
377  {
378  const Tensor<2, dim, Number> T =
379  static_cast<Tensor<2, dim, Number>>(*this);
381  }
382  else
383  {
384  Assert(spacedim > dim, ExcMessage("Only for spacedim>dim."));
386  Tensor<2, dim, Number> G; // First fundamental form
387  for (unsigned int i = 0; i < dim; ++i)
388  for (unsigned int j = 0; j < dim; ++j)
389  G[i][j] = DF_t[i] * DF_t[j];
390 
391  return (std::sqrt(::determinant(G)));
392  }
393 }
394 
395 
396 
397 template <int order, int dim, int spacedim, typename Number>
400 {
401  if (dim == spacedim)
402  {
403  const Tensor<2, dim, Number> DF_t =
404  ::transpose(invert(static_cast<Tensor<2, dim, Number>>(*this)));
406  }
407  else
408  {
410  Tensor<2, dim, Number> G; // First fundamental form
411  for (unsigned int i = 0; i < dim; ++i)
412  for (unsigned int j = 0; j < dim; ++j)
413  G[i][j] = DF_t[i] * DF_t[j];
414 
415  return (this->times_T_t(invert(G)));
416  }
417 }
418 
419 
420 template <int order, int dim, int spacedim, typename Number>
421 inline std::size_t
423 {
425 }
426 
427 #endif // DOXYGEN
428 
429 
430 
438 template <int order, int dim, int spacedim, typename Number>
439 inline std::ostream &
440 operator<<(std::ostream &out,
442 {
443  for (unsigned int i = 0; i < spacedim; ++i)
444  {
445  out << df[i];
446  if (i != spacedim - 1)
447  for (unsigned int j = 0; j < order + 1; ++j)
448  out << ' ';
449  }
450 
451  return out;
452 }
453 
454 
455 
477 template <int spacedim, int dim, typename Number1, typename Number2>
480  const Tensor<1, dim, Number2> &d_x)
481 {
483  for (unsigned int i = 0; i < spacedim; ++i)
484  dest[i] = grad_F[i] * d_x;
485  return dest;
486 }
487 
488 
489 
498 // rank=2
499 template <int spacedim, int dim, typename Number1, typename Number2>
500 inline DerivativeForm<1,
501  spacedim,
502  dim,
505  const Tensor<2, dim, Number2> &D_X)
506 {
508  dest;
509  for (unsigned int i = 0; i < dim; ++i)
510  dest[i] = apply_transformation(grad_F, D_X[i]);
511 
512  return dest;
513 }
514 
515 
516 
527 // rank=2
528 template <int dim, typename Number1, typename Number2>
531  const Tensor<2, dim, Number2> &D_X)
532 {
534  for (unsigned int i = 0; i < dim; ++i)
535  dest[i] = apply_transformation(grad_F, D_X[i]);
536 
537  return dest;
538 }
539 
540 
541 
549 template <int spacedim,
550  int dim,
551  int n_components,
552  typename Number1,
553  typename Number2>
554 inline Tensor<1,
555  n_components,
559  const Tensor<1, n_components, Tensor<1, dim, Number2>> &D_X)
560 {
561  Tensor<1,
562  n_components,
564  dest;
565  for (unsigned int i = 0; i < n_components; ++i)
566  dest[i] = apply_transformation(grad_F, D_X[i]);
567 
568  return dest;
569 }
570 
571 
572 
588 template <int spacedim, int dim, typename Number1, typename Number2>
592 {
594 
595  for (unsigned int i = 0; i < spacedim; ++i)
596  dest[i] = apply_transformation(DF1, DF2[i]);
597 
598  return dest;
599 }
600 
601 
602 
609 template <int dim, int spacedim, typename Number>
612 {
614  tt = DF.transpose();
615  return tt;
616 }
617 
618 
619 
625 template <int spacedim, int dim, typename Number1, typename Number2>
629  const Tensor<1, dim, Number2> &d_x)
630 {
631  Assert(dim == spacedim,
632  ExcMessage("Only dim = spacedim allowed for diagonal transformation"));
634  for (unsigned int i = 0; i < spacedim; ++i)
635  dest[i] = grad_F[i][i] * d_x[i];
636  return dest;
637 }
638 
639 
650 template <int dim, typename Number1, typename Number2>
654  const Tensor<2, dim, Number2> &D_X)
655 {
657  for (unsigned int i = 0; i < dim; ++i)
658  dest[i] = apply_diagonal_transformation(grad_F, D_X[i]);
659 
660  return dest;
661 }
662 
663 
664 
672 template <int spacedim,
673  int dim,
674  int n_components,
675  typename Number1,
676  typename Number2>
677 inline Tensor<1,
678  n_components,
682  const Tensor<1, n_components, Tensor<1, dim, Number2>> &D_X)
683 {
684  Tensor<1,
685  n_components,
687  dest;
688  for (unsigned int i = 0; i < n_components; ++i)
689  dest[i] = apply_diagonal_transformation(grad_F, D_X[i]);
690 
691  return dest;
692 }
693 
694 
696 
697 #endif
OutputOperator< VectorType > & operator<<(OutputOperator< VectorType > &out, unsigned int step)
Definition: operator.h:165
static std::size_t memory_consumption()
DerivativeForm & operator=(const Tensor< order, spacedim, Tensor< 1, dim, Number >> &)
DerivativeForm(const Tensor< 1, spacedim, Tensor< order, dim, Number >> &)
Tensor< 2, dim, typename ProductType< Number1, Number2 >::type > apply_transformation(const DerivativeForm< 1, dim, dim, Number1 > &grad_F, const Tensor< 2, dim, Number2 > &D_X)
Tensor< order, dim, Number > tensor[spacedim]
DerivativeForm & operator=(const Tensor< 1, dim, Number > &)
Tensor< 2, dim, typename ProductType< Number1, Number2 >::type > apply_diagonal_transformation(const DerivativeForm< 1, dim, dim, Number1 > &grad_F, const Tensor< 2, dim, Number2 > &D_X)
Number determinant() const
DerivativeForm< 1, dim, spacedim, Number > times_T_t(const Tensor< 2, dim, Number > &T) const
DerivativeForm< 1, spacedim, dim, Number > transpose(const DerivativeForm< 1, dim, spacedim, Number > &DF)
DerivativeForm< 1, spacedim, dim, typename ProductType< Number1, Number2 >::type > apply_transformation(const DerivativeForm< 1, dim, spacedim, Number1 > &grad_F, const Tensor< 2, dim, Number2 > &D_X)
const Tensor< order, dim, Number > & operator[](const unsigned int i) const
DerivativeForm()=default
Tensor< 1, spacedim, typename ProductType< Number1, Number2 >::type > apply_transformation(const DerivativeForm< 1, dim, spacedim, Number1 > &grad_F, const Tensor< 1, dim, Number2 > &d_x)
DerivativeForm< 1, dim, spacedim, Number > covariant_form() const
DerivativeForm & operator=(const DerivativeForm< order, dim, spacedim, OtherNumber > &df)
DerivativeForm & operator=(const Tensor< order+1, dim, Number > &)
DerivativeForm< 1, spacedim, dim, Number > transpose() const
Tensor< 1, n_components, Tensor< 1, spacedim, typename ProductType< Number1, Number2 >::type > > apply_transformation(const DerivativeForm< 1, dim, spacedim, Number1 > &grad_F, const Tensor< 1, n_components, Tensor< 1, dim, Number2 >> &D_X)
Tensor< 1, n_components, Tensor< 1, spacedim, typename ProductType< Number1, Number2 >::type > > apply_diagonal_transformation(const DerivativeForm< 1, dim, spacedim, Number1 > &grad_F, const Tensor< 1, n_components, Tensor< 1, dim, Number2 >> &D_X)
Tensor< 2, spacedim, typename ProductType< Number1, Number2 >::type > apply_transformation(const DerivativeForm< 1, dim, spacedim, Number1 > &DF1, const DerivativeForm< 1, dim, spacedim, Number2 > &DF2)
Tensor< 1, spacedim, typename ProductType< Number1, Number2 >::type > apply_diagonal_transformation(const DerivativeForm< 1, dim, spacedim, Number1 > &grad_F, const Tensor< 1, dim, Number2 > &d_x)
numbers::NumberTraits< Number >::real_type norm() const
DerivativeForm(const Tensor< order+1, dim, Number > &)
Tensor< order, dim, Number > & operator[](const unsigned int i)
constexpr DEAL_II_HOST Number determinant(const SymmetricTensor< 2, dim, Number > &)
constexpr DEAL_II_HOST SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &t)
Definition: tensor.h:516
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:477
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:478
#define Assert(cond, exc)
Definition: exceptions.h:1631
static ::ExceptionBase & ExcInvalidTensorIndex(int arg1)
#define AssertIndexRange(index, range)
Definition: exceptions.h:1888
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:517
static ::ExceptionBase & ExcMessage(std::string arg1)
static const char T
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
typename internal::ProductTypeImpl< std::decay_t< T >, std::decay_t< U > >::type type
constexpr DEAL_II_HOST Number determinant(const SymmetricTensor< 2, dim, Number > &)