deal.II version GIT relicensing-6809-ge913b9bb34 2026-09-25 17:20:01+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\}}\)
Loading...
Searching...
No Matches
derivative_form.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR 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// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_derivative_form_h
14#define dealii_derivative_form_h
15
16#include <deal.II/base/config.h>
17
21#include <deal.II/base/tensor.h>
22
23#include <cstddef>
24
25
27
60template <int order, int dim, int spacedim, typename Number = double>
62{
63public:
67 DerivativeForm() = default;
68
73
81
86 operator[](const unsigned int i);
87
92 operator[](const unsigned int i) const;
93
99
104 operator=(const Tensor<order, spacedim, Tensor<1, dim, Number>> &);
105
111
115 template <typename OtherNumber>
118
125
129 operator Tensor<1, dim, Number>() const;
130
136 transpose() const;
137
144 norm() const;
145
151 Number
152 determinant() const;
153
165
166
175
180 static std::size_t
182
187 int,
188 << "Invalid DerivativeForm index " << arg1);
189
190private:
197
198
203};
204
205
206/*--------------------------- Inline functions -----------------------------*/
207
208#ifndef DOXYGEN
209
210template <int order, int dim, int spacedim, typename Number>
213{
214 Assert((dim == spacedim),
215 ExcMessage("Only allowed for forms with dim==spacedim."));
216 if (dim == spacedim)
217 for (unsigned int j = 0; j < dim; ++j)
218 (*this)[j] = T[j];
219}
220
221
222
223template <int order, int dim, int spacedim, typename Number>
225 const Tensor<1, spacedim, Tensor<order, dim, Number>> &T)
226{
227 for (unsigned int j = 0; j < spacedim; ++j)
228 (*this)[j] = T[j];
229}
230
231
232
233template <int order, int dim, int spacedim, typename Number>
237{
238 Assert((dim == spacedim), ExcMessage("Only allowed when dim==spacedim."));
239
240 if (dim == spacedim)
241 for (unsigned int j = 0; j < dim; ++j)
242 (*this)[j] = ta[j];
243 return *this;
244}
245
246
247
248template <int order, int dim, int spacedim, typename Number>
251 const Tensor<order, spacedim, Tensor<1, dim, Number>> &T)
252{
253 for (unsigned int j = 0; j < spacedim; ++j)
254 (*this)[j] = T[j];
255 return *this;
256}
257
258
259
260template <int order, int dim, int spacedim, typename Number>
263 const Tensor<1, dim, Number> &T)
264{
265 Assert((1 == spacedim) && (order == 1),
266 ExcMessage("Only allowed for spacedim==1 and order==1."));
267
268 (*this)[0] = T;
269
270 return *this;
271}
272
273
274
275template <int order, int dim, int spacedim, typename Number>
276template <typename OtherNumber>
280{
281 for (unsigned int j = 0; j < spacedim; ++j)
282 (*this)[j] = df[j];
283 return *this;
284}
285
286
287
288template <int order, int dim, int spacedim, typename Number>
291{
292 AssertIndexRange(i, spacedim);
293
294 return tensor[i];
295}
296
297
298
299template <int order, int dim, int spacedim, typename Number>
300inline const Tensor<order, dim, Number> &
302 const unsigned int i) const
303{
304 AssertIndexRange(i, spacedim);
305
306 return tensor[i];
307}
308
309
310
311template <int order, int dim, int spacedim, typename Number>
313operator Tensor<1, dim, Number>() const
314{
315 Assert((1 == spacedim) && (order == 1),
316 ExcMessage("Only allowed for spacedim==1."));
317
318 return (*this)[0];
319}
320
321
322
323template <int order, int dim, int spacedim, typename Number>
325operator Tensor<order + 1, dim, Number>() const
326{
327 Assert((dim == spacedim), ExcMessage("Only allowed when dim==spacedim."));
328
330
331 if (dim == spacedim)
332 for (unsigned int j = 0; j < dim; ++j)
333 t[j] = (*this)[j];
334
335 return t;
336}
337
338
339
340template <int order, int dim, int spacedim, typename Number>
343{
344 Assert(order == 1, ExcMessage("Only for rectangular DerivativeForm."));
346
347 for (unsigned int i = 0; i < spacedim; ++i)
348 for (unsigned int j = 0; j < dim; ++j)
349 tt[j][i] = (*this)[i][j];
350
351 return tt;
352}
353
354
355
356template <int order, int dim, int spacedim, typename Number>
359 const Tensor<2, dim, Number> &T) const
360{
361 Assert(order == 1, ExcMessage("Only for order == 1."));
363 for (unsigned int i = 0; i < spacedim; ++i)
364 for (unsigned int j = 0; j < dim; ++j)
365 dest[i][j] = (*this)[i] * T[j];
366
367 return dest;
368}
369
370
371
372template <int order, int dim, int spacedim, typename Number>
375{
376 typename numbers::NumberTraits<Number>::real_type sum_of_squares = 0;
377 for (unsigned int i = 0; i < spacedim; ++i)
378 sum_of_squares += tensor[i].norm_square();
379 return std::sqrt(sum_of_squares);
380}
381
382
383
384template <int order, int dim, int spacedim, typename Number>
385inline Number
387{
388 Assert(order == 1, ExcMessage("Only for order == 1."));
389 if (dim == spacedim)
390 {
392 static_cast<Tensor<2, dim, Number>>(*this);
393 return ::determinant(T);
394 }
395 else
396 {
397 Assert(spacedim > dim, ExcMessage("Only for spacedim>dim."));
398 return (std::sqrt(::determinant(first_fundamental_form())));
399 }
400}
401
402
403
404template <int order, int dim, int spacedim, typename Number>
407{
408 Assert(order == 1, ExcMessage("Only for order == 1."));
410
412 for (unsigned int i = 0; i < dim; ++i)
413 for (unsigned int j = 0; j < dim; ++j)
414 G[i][j] = DF_t[i] * DF_t[j];
415
416 return G;
417}
418
419
420
421template <int order, int dim, int spacedim, typename Number>
424{
425 if (dim == spacedim)
426 {
427 const Tensor<2, dim, Number> DF_t =
428 ::transpose(invert(static_cast<Tensor<2, dim, Number>>(*this)));
430 }
431 else
432 {
433 return (this->times_T_t(invert(first_fundamental_form())));
434 }
435}
436
437
438template <int order, int dim, int spacedim, typename Number>
439inline std::size_t
441{
443}
444
445#endif // DOXYGEN
446
447
448
456template <int order, int dim, int spacedim, typename Number>
457inline std::ostream &
458operator<<(std::ostream &out,
460{
461 for (unsigned int i = 0; i < spacedim; ++i)
462 {
463 out << df[i];
464 if (i != spacedim - 1)
465 for (unsigned int j = 0; j < order + 1; ++j)
466 out << ' ';
467 }
468
469 return out;
470}
471
472
473
495template <int spacedim, int dim, typename Number1, typename Number2>
498 const Tensor<1, dim, Number2> &d_x)
499{
501 for (unsigned int i = 0; i < spacedim; ++i)
502 dest[i] = grad_F[i] * d_x;
503 return dest;
504}
505
506
507
516// rank=2
517template <int spacedim, int dim, typename Number1, typename Number2>
518inline DerivativeForm<1,
519 spacedim,
520 dim,
523 const Tensor<2, dim, Number2> &D_X)
524{
526 dest;
527 for (unsigned int i = 0; i < dim; ++i)
528 dest[i] = apply_transformation(grad_F, D_X[i]);
529
530 return dest;
531}
532
533
534
545// rank=2
546template <int dim, typename Number1, typename Number2>
549 const Tensor<2, dim, Number2> &D_X)
550{
552 for (unsigned int i = 0; i < dim; ++i)
553 dest[i] = apply_transformation(grad_F, D_X[i]);
554
555 return dest;
556}
557
558
559
567template <int spacedim,
568 int dim,
569 int n_components,
570 typename Number1,
571 typename Number2>
572inline Tensor<1,
573 n_components,
577 const Tensor<1, n_components, Tensor<1, dim, Number2>> &D_X)
578{
579 Tensor<1,
580 n_components,
582 dest;
583 for (unsigned int i = 0; i < n_components; ++i)
584 dest[i] = apply_transformation(grad_F, D_X[i]);
585
586 return dest;
587}
588
589
590
606template <int spacedim, int dim, typename Number1, typename Number2>
610{
612
613 for (unsigned int i = 0; i < spacedim; ++i)
614 dest[i] = apply_transformation(DF1, DF2[i]);
615
616 return dest;
617}
618
619
620
627template <int dim, int spacedim, typename Number>
633
634
635
641template <int spacedim, int dim, typename Number1, typename Number2>
645 const Tensor<1, dim, Number2> &d_x)
646{
647 Assert(dim == spacedim,
648 ExcMessage("Only dim = spacedim allowed for diagonal transformation"));
650 for (unsigned int i = 0; i < spacedim; ++i)
651 dest[i] = grad_F[i][i] * d_x[i];
652 return dest;
653}
654
655
666template <int dim, typename Number1, typename Number2>
670 const Tensor<2, dim, Number2> &D_X)
671{
673 for (unsigned int i = 0; i < dim; ++i)
674 dest[i] = apply_diagonal_transformation(grad_F, D_X[i]);
675
676 return dest;
677}
678
679
680
688template <int spacedim,
689 int dim,
690 int n_components,
691 typename Number1,
692 typename Number2>
693inline Tensor<1,
694 n_components,
698 const Tensor<1, n_components, Tensor<1, dim, Number2>> &D_X)
699{
700 Tensor<1,
701 n_components,
703 dest;
704 for (unsigned int i = 0; i < n_components; ++i)
705 dest[i] = apply_diagonal_transformation(grad_F, D_X[i]);
706
707 return dest;
708}
709
710
711
720// rank=2
721template <int spacedim, int dim, typename Number1, typename Number2>
722inline DerivativeForm<1,
723 spacedim,
724 dim,
728 const Tensor<2, dim, Number2> &D_X)
729{
731 dest;
732 for (unsigned int i = 0; i < dim; ++i)
733 dest[i] = apply_diagonal_transformation(grad_F, D_X[i]);
734
735 return dest;
736}
737
738
740
741#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:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
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
*  *  *  RotationFunction< dim, Number >::RotationFunction Number(dim)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
typename internal::ProductTypeImpl< std::decay_t< T >, std::decay_t< U > >::type type
constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)