deal.II version 9.7.0
\(\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\}}\)
Loading...
Searching...
No Matches
derivative_form.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2013 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_derivative_form_h
16#define dealii_derivative_form_h
17
18#include <deal.II/base/config.h>
19
23#include <deal.II/base/tensor.h>
24
25#include <cstddef>
26
27
29
62template <int order, int dim, int spacedim, typename Number = double>
64{
65public:
69 DerivativeForm() = default;
70
75
83
88 operator[](const unsigned int i);
89
94 operator[](const unsigned int i) const;
95
101
106 operator=(const Tensor<order, spacedim, Tensor<1, dim, Number>> &);
107
113
117 template <typename OtherNumber>
120
127
131 operator Tensor<1, dim, Number>() const;
132
138 transpose() const;
139
146 norm() const;
147
153 Number
154 determinant() const;
155
167
168
177
182 static std::size_t
184
189 int,
190 << "Invalid DerivativeForm index " << arg1);
191
192private:
199
200
205};
206
207
208/*--------------------------- Inline functions -----------------------------*/
209
210#ifndef DOXYGEN
211
212template <int order, int dim, int spacedim, typename Number>
215{
216 Assert((dim == spacedim),
217 ExcMessage("Only allowed for forms with dim==spacedim."));
218 if (dim == spacedim)
219 for (unsigned int j = 0; j < dim; ++j)
220 (*this)[j] = T[j];
221}
222
223
224
225template <int order, int dim, int spacedim, typename Number>
227 const Tensor<1, spacedim, Tensor<order, dim, Number>> &T)
228{
229 for (unsigned int j = 0; j < spacedim; ++j)
230 (*this)[j] = T[j];
231}
232
233
234
235template <int order, int dim, int spacedim, typename Number>
239{
240 Assert((dim == spacedim), ExcMessage("Only allowed when dim==spacedim."));
241
242 if (dim == spacedim)
243 for (unsigned int j = 0; j < dim; ++j)
244 (*this)[j] = ta[j];
245 return *this;
246}
247
248
249
250template <int order, int dim, int spacedim, typename Number>
253 const Tensor<order, spacedim, Tensor<1, dim, Number>> &T)
254{
255 for (unsigned int j = 0; j < spacedim; ++j)
256 (*this)[j] = T[j];
257 return *this;
258}
259
260
261
262template <int order, int dim, int spacedim, typename Number>
265 const Tensor<1, dim, Number> &T)
266{
267 Assert((1 == spacedim) && (order == 1),
268 ExcMessage("Only allowed for spacedim==1 and order==1."));
269
270 (*this)[0] = T;
271
272 return *this;
273}
274
275
276
277template <int order, int dim, int spacedim, typename Number>
278template <typename OtherNumber>
282{
283 for (unsigned int j = 0; j < spacedim; ++j)
284 (*this)[j] = df[j];
285 return *this;
286}
287
288
289
290template <int order, int dim, int spacedim, typename Number>
293{
294 AssertIndexRange(i, spacedim);
295
296 return tensor[i];
297}
298
299
300
301template <int order, int dim, int spacedim, typename Number>
302inline const Tensor<order, dim, Number> &
304 const unsigned int i) const
305{
306 AssertIndexRange(i, spacedim);
307
308 return tensor[i];
309}
310
311
312
313template <int order, int dim, int spacedim, typename Number>
315operator Tensor<1, dim, Number>() const
316{
317 Assert((1 == spacedim) && (order == 1),
318 ExcMessage("Only allowed for spacedim==1."));
319
320 return (*this)[0];
321}
322
323
324
325template <int order, int dim, int spacedim, typename Number>
327operator Tensor<order + 1, dim, Number>() const
328{
329 Assert((dim == spacedim), ExcMessage("Only allowed when dim==spacedim."));
330
332
333 if (dim == spacedim)
334 for (unsigned int j = 0; j < dim; ++j)
335 t[j] = (*this)[j];
336
337 return t;
338}
339
340
341
342template <int order, int dim, int spacedim, typename Number>
345{
346 Assert(order == 1, ExcMessage("Only for rectangular DerivativeForm."));
348
349 for (unsigned int i = 0; i < spacedim; ++i)
350 for (unsigned int j = 0; j < dim; ++j)
351 tt[j][i] = (*this)[i][j];
352
353 return tt;
354}
355
356
357
358template <int order, int dim, int spacedim, typename Number>
361 const Tensor<2, dim, Number> &T) const
362{
363 Assert(order == 1, ExcMessage("Only for order == 1."));
365 for (unsigned int i = 0; i < spacedim; ++i)
366 for (unsigned int j = 0; j < dim; ++j)
367 dest[i][j] = (*this)[i] * T[j];
368
369 return dest;
370}
371
372
373
374template <int order, int dim, int spacedim, typename Number>
377{
378 typename numbers::NumberTraits<Number>::real_type sum_of_squares = 0;
379 for (unsigned int i = 0; i < spacedim; ++i)
380 sum_of_squares += tensor[i].norm_square();
381 return std::sqrt(sum_of_squares);
382}
383
384
385
386template <int order, int dim, int spacedim, typename Number>
387inline Number
389{
390 Assert(order == 1, ExcMessage("Only for order == 1."));
391 if (dim == spacedim)
392 {
394 static_cast<Tensor<2, dim, Number>>(*this);
395 return ::determinant(T);
396 }
397 else
398 {
399 Assert(spacedim > dim, ExcMessage("Only for spacedim>dim."));
400 return (std::sqrt(::determinant(first_fundamental_form())));
401 }
402}
403
404
405
406template <int order, int dim, int spacedim, typename Number>
409{
410 Assert(order == 1, ExcMessage("Only for order == 1."));
412
414 for (unsigned int i = 0; i < dim; ++i)
415 for (unsigned int j = 0; j < dim; ++j)
416 G[i][j] = DF_t[i] * DF_t[j];
417
418 return G;
419}
420
421
422
423template <int order, int dim, int spacedim, typename Number>
426{
427 if (dim == spacedim)
428 {
429 const Tensor<2, dim, Number> DF_t =
430 ::transpose(invert(static_cast<Tensor<2, dim, Number>>(*this)));
432 }
433 else
434 {
435 return (this->times_T_t(invert(first_fundamental_form())));
436 }
437}
438
439
440template <int order, int dim, int spacedim, typename Number>
441inline std::size_t
443{
445}
446
447#endif // DOXYGEN
448
449
450
458template <int order, int dim, int spacedim, typename Number>
459inline std::ostream &
460operator<<(std::ostream &out,
462{
463 for (unsigned int i = 0; i < spacedim; ++i)
464 {
465 out << df[i];
466 if (i != spacedim - 1)
467 for (unsigned int j = 0; j < order + 1; ++j)
468 out << ' ';
469 }
470
471 return out;
472}
473
474
475
497template <int spacedim, int dim, typename Number1, typename Number2>
500 const Tensor<1, dim, Number2> &d_x)
501{
503 for (unsigned int i = 0; i < spacedim; ++i)
504 dest[i] = grad_F[i] * d_x;
505 return dest;
506}
507
508
509
518// rank=2
519template <int spacedim, int dim, typename Number1, typename Number2>
520inline DerivativeForm<1,
521 spacedim,
522 dim,
525 const Tensor<2, dim, Number2> &D_X)
526{
528 dest;
529 for (unsigned int i = 0; i < dim; ++i)
530 dest[i] = apply_transformation(grad_F, D_X[i]);
531
532 return dest;
533}
534
535
536
547// rank=2
548template <int dim, typename Number1, typename Number2>
551 const Tensor<2, dim, Number2> &D_X)
552{
554 for (unsigned int i = 0; i < dim; ++i)
555 dest[i] = apply_transformation(grad_F, D_X[i]);
556
557 return dest;
558}
559
560
561
569template <int spacedim,
570 int dim,
571 int n_components,
572 typename Number1,
573 typename Number2>
574inline Tensor<1,
575 n_components,
579 const Tensor<1, n_components, Tensor<1, dim, Number2>> &D_X)
580{
581 Tensor<1,
582 n_components,
584 dest;
585 for (unsigned int i = 0; i < n_components; ++i)
586 dest[i] = apply_transformation(grad_F, D_X[i]);
587
588 return dest;
589}
590
591
592
608template <int spacedim, int dim, typename Number1, typename Number2>
612{
614
615 for (unsigned int i = 0; i < spacedim; ++i)
616 dest[i] = apply_transformation(DF1, DF2[i]);
617
618 return dest;
619}
620
621
622
629template <int dim, int spacedim, typename Number>
635
636
637
643template <int spacedim, int dim, typename Number1, typename Number2>
647 const Tensor<1, dim, Number2> &d_x)
648{
649 Assert(dim == spacedim,
650 ExcMessage("Only dim = spacedim allowed for diagonal transformation"));
652 for (unsigned int i = 0; i < spacedim; ++i)
653 dest[i] = grad_F[i][i] * d_x[i];
654 return dest;
655}
656
657
668template <int dim, typename Number1, typename Number2>
672 const Tensor<2, dim, Number2> &D_X)
673{
675 for (unsigned int i = 0; i < dim; ++i)
676 dest[i] = apply_diagonal_transformation(grad_F, D_X[i]);
677
678 return dest;
679}
680
681
682
690template <int spacedim,
691 int dim,
692 int n_components,
693 typename Number1,
694 typename Number2>
695inline Tensor<1,
696 n_components,
700 const Tensor<1, n_components, Tensor<1, dim, Number2>> &D_X)
701{
702 Tensor<1,
703 n_components,
705 dest;
706 for (unsigned int i = 0; i < n_components; ++i)
707 dest[i] = apply_diagonal_transformation(grad_F, D_X[i]);
708
709 return dest;
710}
711
712
713
722// rank=2
723template <int spacedim, int dim, typename Number1, typename Number2>
724inline DerivativeForm<1,
725 spacedim,
726 dim,
730 const Tensor<2, dim, Number2> &D_X)
731{
733 dest;
734 for (unsigned int i = 0; i < dim; ++i)
735 dest[i] = apply_diagonal_transformation(grad_F, D_X[i]);
736
737 return dest;
738}
739
740
742
743#endif
static std::size_t memory_consumption()
DerivativeForm & operator=(const Tensor< order, spacedim, Tensor< 1, 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]
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
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)
DerivativeForm< 1, dim, spacedim, Number > covariant_form() 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)
DerivativeForm< 1, spacedim, dim, Number > transpose() 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 & operator=(const DerivativeForm< order, dim, spacedim, OtherNumber > &df)
const Tensor< order, dim, Number > & operator[](const unsigned int i) const
DerivativeForm< 1, spacedim, dim, typename ProductType< Number1, Number2 >::type > apply_diagonal_transformation(const DerivativeForm< 1, dim, spacedim, Number1 > &grad_F, const Tensor< 2, dim, Number2 > &D_X)
DerivativeForm< 1, dim, spacedim, Number > times_T_t(const Tensor< 2, dim, Number > &T) const
Tensor< 2, spacedim, typename ProductType< Number1, Number2 >::type > apply_transformation(const DerivativeForm< 1, dim, spacedim, Number1 > &DF1, const DerivativeForm< 1, dim, spacedim, Number2 > &DF2)
DerivativeForm & operator=(const Tensor< order+1, dim, Number > &)
numbers::NumberTraits< Number >::real_type norm() const
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)
DerivativeForm & operator=(const Tensor< 1, dim, Number > &)
Tensor< 2, dim, Number > first_fundamental_form() const
DerivativeForm(const Tensor< order+1, dim, Number > &)
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)
DerivativeForm(const Tensor< 1, spacedim, Tensor< order, dim, Number > > &)
Tensor< order, dim, Number > & operator[](const unsigned int i)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:40
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41
DerivativeForm< 1, spacedim, dim, Number > transpose(const DerivativeForm< 1, dim, spacedim, Number > &DF)
std::ostream & operator<<(std::ostream &out, const DerivativeForm< order, dim, spacedim, Number > &df)
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)
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)
static ::ExceptionBase & ExcInvalidTensorIndex(int arg1)
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcMessage(std::string arg1)
constexpr char T
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
typename internal::ProductTypeImpl< std::decay_t< T >, std::decay_t< U > >::type type
DEAL_II_HOST constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)