Reference documentation for deal.II version Git 8ba89c874e 2021-08-04 22:06:33 -0600
\(\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 - 2020 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 
74  DerivativeForm(const Tensor<order, spacedim, Tensor<1, dim, Number>> &);
75 
80  operator[](const unsigned int i);
81 
86  operator[](const unsigned int i) const;
87 
93 
98  operator=(const Tensor<order, spacedim, Tensor<1, dim, Number>> &);
99 
105 
111  operator Tensor<order + 1, dim, Number>() const;
112 
116  operator Tensor<1, dim, Number>() const;
117 
123  transpose() const;
124 
131  norm() const;
132 
138  Number
139  determinant() const;
140 
151  covariant_form() const;
152 
157  static std::size_t
159 
164  int,
165  << "Invalid DerivativeForm index " << arg1);
166 
167 private:
173  times_T_t(const Tensor<2, dim, Number> &T) const;
174 
175 
180 };
181 
182 
183 /*--------------------------- Inline functions -----------------------------*/
184 
185 #ifndef DOXYGEN
186 
187 template <int order, int dim, int spacedim, typename Number>
190 {
191  Assert((dim == spacedim),
192  ExcMessage("Only allowed for forms with dim==spacedim."));
193  if (dim == spacedim)
194  for (unsigned int j = 0; j < dim; ++j)
195  (*this)[j] = T[j];
196 }
197 
198 
199 
200 template <int order, int dim, int spacedim, typename Number>
202  const Tensor<order, spacedim, Tensor<1, dim, Number>> &T)
203 {
204  for (unsigned int j = 0; j < spacedim; ++j)
205  (*this)[j] = T[j];
206 }
207 
208 
209 
210 template <int order, int dim, int spacedim, typename Number>
214 {
215  Assert((dim == spacedim), ExcMessage("Only allowed when dim==spacedim."));
216 
217  if (dim == spacedim)
218  for (unsigned int j = 0; j < dim; ++j)
219  (*this)[j] = ta[j];
220  return *this;
221 }
222 
223 
224 
225 template <int order, int dim, int spacedim, typename Number>
228  const Tensor<order, spacedim, Tensor<1, dim, Number>> &T)
229 {
230  for (unsigned int j = 0; j < spacedim; ++j)
231  (*this)[j] = T[j];
232  return *this;
233 }
234 
235 
236 
237 template <int order, int dim, int spacedim, typename Number>
240  const Tensor<1, dim, Number> &T)
241 {
242  Assert((1 == spacedim) && (order == 1),
243  ExcMessage("Only allowed for spacedim==1 and order==1."));
244 
245  (*this)[0] = T;
246 
247  return *this;
248 }
249 
250 
251 
252 template <int order, int dim, int spacedim, typename Number>
255 {
256  AssertIndexRange(i, spacedim);
257 
258  return tensor[i];
259 }
260 
261 
262 
263 template <int order, int dim, int spacedim, typename Number>
264 inline const Tensor<order, dim, Number> &
266  const unsigned int i) const
267 {
268  AssertIndexRange(i, spacedim);
269 
270  return tensor[i];
271 }
272 
273 
274 
275 template <int order, int dim, int spacedim, typename Number>
277 operator Tensor<1, dim, Number>() const
278 {
279  Assert((1 == spacedim) && (order == 1),
280  ExcMessage("Only allowed for spacedim==1."));
281 
282  return (*this)[0];
283 }
284 
285 
286 
287 template <int order, int dim, int spacedim, typename Number>
289 operator Tensor<order + 1, dim, Number>() const
290 {
291  Assert((dim == spacedim), ExcMessage("Only allowed when dim==spacedim."));
292 
294 
295  if (dim == spacedim)
296  for (unsigned int j = 0; j < dim; ++j)
297  t[j] = (*this)[j];
298 
299  return t;
300 }
301 
302 
303 
304 template <int order, int dim, int spacedim, typename Number>
307 {
308  Assert(order == 1, ExcMessage("Only for rectangular DerivativeForm."));
310 
311  for (unsigned int i = 0; i < spacedim; ++i)
312  for (unsigned int j = 0; j < dim; ++j)
313  tt[j][i] = (*this)[i][j];
314 
315  return tt;
316 }
317 
318 
319 
320 template <int order, int dim, int spacedim, typename Number>
323  const Tensor<2, dim, Number> &T) const
324 {
325  Assert(order == 1, ExcMessage("Only for order == 1."));
327  for (unsigned int i = 0; i < spacedim; ++i)
328  for (unsigned int j = 0; j < dim; ++j)
329  dest[i][j] = (*this)[i] * T[j];
330 
331  return dest;
332 }
333 
334 
335 
336 template <int order, int dim, int spacedim, typename Number>
339 {
340  typename numbers::NumberTraits<Number>::real_type sum_of_squares = 0;
341  for (unsigned int i = 0; i < spacedim; ++i)
342  sum_of_squares += tensor[i].norm_square();
343  return std::sqrt(sum_of_squares);
344 }
345 
346 
347 
348 template <int order, int dim, int spacedim, typename Number>
349 inline Number
351 {
352  Assert(order == 1, ExcMessage("Only for order == 1."));
353  if (dim == spacedim)
354  {
355  const Tensor<2, dim, Number> T =
356  static_cast<Tensor<2, dim, Number>>(*this);
358  }
359  else
360  {
361  Assert(spacedim > dim, ExcMessage("Only for spacedim>dim."));
363  Tensor<2, dim, Number> G; // First fundamental form
364  for (unsigned int i = 0; i < dim; ++i)
365  for (unsigned int j = 0; j < dim; ++j)
366  G[i][j] = DF_t[i] * DF_t[j];
367 
368  return (std::sqrt(::determinant(G)));
369  }
370 }
371 
372 
373 
374 template <int order, int dim, int spacedim, typename Number>
377 {
378  if (dim == spacedim)
379  {
380  const Tensor<2, dim, Number> DF_t =
381  ::transpose(invert(static_cast<Tensor<2, dim, Number>>(*this)));
383  }
384  else
385  {
387  Tensor<2, dim, Number> G; // First fundamental form
388  for (unsigned int i = 0; i < dim; ++i)
389  for (unsigned int j = 0; j < dim; ++j)
390  G[i][j] = DF_t[i] * DF_t[j];
391 
392  return (this->times_T_t(invert(G)));
393  }
394 }
395 
396 
397 template <int order, int dim, int spacedim, typename Number>
398 inline std::size_t
400 {
402 }
403 
404 #endif // DOXYGEN
405 
406 
407 
429 template <int spacedim, int dim, typename Number1, typename Number2>
432  const Tensor<1, dim, Number2> & d_x)
433 {
435  for (unsigned int i = 0; i < spacedim; ++i)
436  dest[i] = grad_F[i] * d_x;
437  return dest;
438 }
439 
440 
441 
450 // rank=2
451 template <int spacedim, int dim, typename Number1, typename Number2>
452 inline DerivativeForm<1,
453  spacedim,
454  dim,
457  const Tensor<2, dim, Number2> & D_X)
458 {
460  dest;
461  for (unsigned int i = 0; i < dim; ++i)
462  dest[i] = apply_transformation(grad_F, D_X[i]);
463 
464  return dest;
465 }
466 
467 
468 
476 template <int spacedim,
477  int dim,
478  int n_components,
479  typename Number1,
480  typename Number2>
481 inline Tensor<1,
482  n_components,
486  const Tensor<1, n_components, Tensor<1, dim, Number2>> &D_X)
487 {
488  Tensor<1,
489  n_components,
491  dest;
492  for (unsigned int i = 0; i < n_components; ++i)
493  dest[i] = apply_transformation(grad_F, D_X[i]);
494 
495  return dest;
496 }
497 
498 
499 
515 template <int spacedim, int dim, typename Number1, typename Number2>
519 {
521 
522  for (unsigned int i = 0; i < spacedim; ++i)
523  dest[i] = apply_transformation(DF1, DF2[i]);
524 
525  return dest;
526 }
527 
528 
529 
536 template <int dim, int spacedim, typename Number>
539 {
541  tt = DF.transpose();
542  return tt;
543 }
544 
545 
547 
548 #endif
constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
typename internal::ProductTypeImpl< typename std::decay< T >::type, typename std::decay< U >::type >::type type
#define AssertIndexRange(index, range)
Definition: exceptions.h:1724
DerivativeForm & operator=(const Tensor< order+1, dim, Number > &)
Number determinant() const
Tensor< order, dim, Number > tensor[spacedim]
static ::ExceptionBase & ExcMessage(std::string arg1)
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:515
static const char T
DerivativeForm< 1, dim, spacedim, Number > times_T_t(const Tensor< 2, dim, Number > &T) const
#define Assert(cond, exc)
Definition: exceptions.h:1467
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)
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:401
DerivativeForm()=default
DerivativeForm< 1, spacedim, dim, Number > transpose() const
static std::size_t memory_consumption()
numbers::NumberTraits< Number >::real_type norm() const
DerivativeForm< 1, dim, spacedim, Number > covariant_form() const
Definition: tensor.h:472
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:400
static ::ExceptionBase & ExcInvalidTensorIndex(int arg1)
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)
Tensor< order, dim, Number > & operator[](const unsigned int i)