deal.II version GIT relicensing-1927-g3de9220933 2024-10-03 08:40:00+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: LGPL-2.1-or-later
4// Copyright (C) 2013 - 2024 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
20#include <deal.II/base/tensor.h>
21
23
56template <int order, int dim, int spacedim, typename Number = double>
58{
59public:
63 DerivativeForm() = default;
64
69
77
82 operator[](const unsigned int i);
83
88 operator[](const unsigned int i) const;
89
95
100 operator=(const Tensor<order, spacedim, Tensor<1, dim, Number>> &);
101
107
111 template <typename OtherNumber>
114
121
125 operator Tensor<1, dim, Number>() const;
126
132 transpose() const;
133
140 norm() const;
141
147 Number
148 determinant() const;
149
161
166 static std::size_t
168
173 int,
174 << "Invalid DerivativeForm index " << arg1);
175
176private:
183
184
189};
190
191
192/*--------------------------- Inline functions -----------------------------*/
193
194#ifndef DOXYGEN
195
196template <int order, int dim, int spacedim, typename Number>
199{
200 Assert((dim == spacedim),
201 ExcMessage("Only allowed for forms with dim==spacedim."));
202 if (dim == spacedim)
203 for (unsigned int j = 0; j < dim; ++j)
204 (*this)[j] = T[j];
205}
206
207
208
209template <int order, int dim, int spacedim, typename Number>
211 const Tensor<1, spacedim, Tensor<order, dim, Number>> &T)
212{
213 for (unsigned int j = 0; j < spacedim; ++j)
214 (*this)[j] = T[j];
215}
216
217
218
219template <int order, int dim, int spacedim, typename Number>
223{
224 Assert((dim == spacedim), ExcMessage("Only allowed when dim==spacedim."));
225
226 if (dim == spacedim)
227 for (unsigned int j = 0; j < dim; ++j)
228 (*this)[j] = ta[j];
229 return *this;
230}
231
232
233
234template <int order, int dim, int spacedim, typename Number>
237 const Tensor<order, spacedim, Tensor<1, dim, Number>> &T)
238{
239 for (unsigned int j = 0; j < spacedim; ++j)
240 (*this)[j] = T[j];
241 return *this;
242}
243
244
245
246template <int order, int dim, int spacedim, typename Number>
249 const Tensor<1, dim, Number> &T)
250{
251 Assert((1 == spacedim) && (order == 1),
252 ExcMessage("Only allowed for spacedim==1 and order==1."));
253
254 (*this)[0] = T;
255
256 return *this;
257}
258
259
260
261template <int order, int dim, int spacedim, typename Number>
262template <typename OtherNumber>
266{
267 for (unsigned int j = 0; j < spacedim; ++j)
268 (*this)[j] = df[j];
269 return *this;
270}
271
272
273
274template <int order, int dim, int spacedim, typename Number>
277{
278 AssertIndexRange(i, spacedim);
279
280 return tensor[i];
281}
282
283
284
285template <int order, int dim, int spacedim, typename Number>
286inline const Tensor<order, dim, Number> &
288 const unsigned int i) const
289{
290 AssertIndexRange(i, spacedim);
291
292 return tensor[i];
293}
294
295
296
297template <int order, int dim, int spacedim, typename Number>
299operator Tensor<1, dim, Number>() const
300{
301 Assert((1 == spacedim) && (order == 1),
302 ExcMessage("Only allowed for spacedim==1."));
303
304 return (*this)[0];
305}
306
307
308
309template <int order, int dim, int spacedim, typename Number>
311operator Tensor<order + 1, dim, Number>() const
312{
313 Assert((dim == spacedim), ExcMessage("Only allowed when dim==spacedim."));
314
316
317 if (dim == spacedim)
318 for (unsigned int j = 0; j < dim; ++j)
319 t[j] = (*this)[j];
320
321 return t;
322}
323
324
325
326template <int order, int dim, int spacedim, typename Number>
329{
330 Assert(order == 1, ExcMessage("Only for rectangular DerivativeForm."));
332
333 for (unsigned int i = 0; i < spacedim; ++i)
334 for (unsigned int j = 0; j < dim; ++j)
335 tt[j][i] = (*this)[i][j];
336
337 return tt;
338}
339
340
341
342template <int order, int dim, int spacedim, typename Number>
345 const Tensor<2, dim, Number> &T) const
346{
347 Assert(order == 1, ExcMessage("Only for order == 1."));
349 for (unsigned int i = 0; i < spacedim; ++i)
350 for (unsigned int j = 0; j < dim; ++j)
351 dest[i][j] = (*this)[i] * T[j];
352
353 return dest;
354}
355
356
357
358template <int order, int dim, int spacedim, typename Number>
361{
362 typename numbers::NumberTraits<Number>::real_type sum_of_squares = 0;
363 for (unsigned int i = 0; i < spacedim; ++i)
364 sum_of_squares += tensor[i].norm_square();
365 return std::sqrt(sum_of_squares);
366}
367
368
369
370template <int order, int dim, int spacedim, typename Number>
371inline Number
373{
374 Assert(order == 1, ExcMessage("Only for order == 1."));
375 if (dim == spacedim)
376 {
377 const Tensor<2, dim, Number> T =
378 static_cast<Tensor<2, dim, Number>>(*this);
379 return ::determinant(T);
380 }
381 else
382 {
383 Assert(spacedim > dim, ExcMessage("Only for spacedim>dim."));
385 Tensor<2, dim, Number> G; // First fundamental form
386 for (unsigned int i = 0; i < dim; ++i)
387 for (unsigned int j = 0; j < dim; ++j)
388 G[i][j] = DF_t[i] * DF_t[j];
389
390 return (std::sqrt(::determinant(G)));
391 }
392}
393
394
395
396template <int order, int dim, int spacedim, typename Number>
399{
400 if (dim == spacedim)
401 {
402 const Tensor<2, dim, Number> DF_t =
403 ::transpose(invert(static_cast<Tensor<2, dim, Number>>(*this)));
405 }
406 else
407 {
409 Tensor<2, dim, Number> G; // First fundamental form
410 for (unsigned int i = 0; i < dim; ++i)
411 for (unsigned int j = 0; j < dim; ++j)
412 G[i][j] = DF_t[i] * DF_t[j];
413
414 return (this->times_T_t(invert(G)));
415 }
416}
417
418
419template <int order, int dim, int spacedim, typename Number>
420inline std::size_t
422{
424}
425
426#endif // DOXYGEN
427
428
429
437template <int order, int dim, int spacedim, typename Number>
438inline std::ostream &
439operator<<(std::ostream &out,
441{
442 for (unsigned int i = 0; i < spacedim; ++i)
443 {
444 out << df[i];
445 if (i != spacedim - 1)
446 for (unsigned int j = 0; j < order + 1; ++j)
447 out << ' ';
448 }
449
450 return out;
451}
452
453
454
476template <int spacedim, int dim, typename Number1, typename Number2>
479 const Tensor<1, dim, Number2> &d_x)
480{
482 for (unsigned int i = 0; i < spacedim; ++i)
483 dest[i] = grad_F[i] * d_x;
484 return dest;
485}
486
487
488
497// rank=2
498template <int spacedim, int dim, typename Number1, typename Number2>
499inline DerivativeForm<1,
500 spacedim,
501 dim,
504 const Tensor<2, dim, Number2> &D_X)
505{
507 dest;
508 for (unsigned int i = 0; i < dim; ++i)
509 dest[i] = apply_transformation(grad_F, D_X[i]);
510
511 return dest;
512}
513
514
515
526// rank=2
527template <int dim, typename Number1, typename Number2>
530 const Tensor<2, dim, Number2> &D_X)
531{
533 for (unsigned int i = 0; i < dim; ++i)
534 dest[i] = apply_transformation(grad_F, D_X[i]);
535
536 return dest;
537}
538
539
540
548template <int spacedim,
549 int dim,
550 int n_components,
551 typename Number1,
552 typename Number2>
553inline Tensor<1,
554 n_components,
558 const Tensor<1, n_components, Tensor<1, dim, Number2>> &D_X)
559{
560 Tensor<1,
561 n_components,
563 dest;
564 for (unsigned int i = 0; i < n_components; ++i)
565 dest[i] = apply_transformation(grad_F, D_X[i]);
566
567 return dest;
568}
569
570
571
587template <int spacedim, int dim, typename Number1, typename Number2>
591{
593
594 for (unsigned int i = 0; i < spacedim; ++i)
595 dest[i] = apply_transformation(DF1, DF2[i]);
596
597 return dest;
598}
599
600
601
608template <int dim, int spacedim, typename Number>
614
615
616
622template <int spacedim, int dim, typename Number1, typename Number2>
626 const Tensor<1, dim, Number2> &d_x)
627{
628 Assert(dim == spacedim,
629 ExcMessage("Only dim = spacedim allowed for diagonal transformation"));
631 for (unsigned int i = 0; i < spacedim; ++i)
632 dest[i] = grad_F[i][i] * d_x[i];
633 return dest;
634}
635
636
647template <int dim, typename Number1, typename Number2>
651 const Tensor<2, dim, Number2> &D_X)
652{
654 for (unsigned int i = 0; i < dim; ++i)
655 dest[i] = apply_diagonal_transformation(grad_F, D_X[i]);
656
657 return dest;
658}
659
660
661
669template <int spacedim,
670 int dim,
671 int n_components,
672 typename Number1,
673 typename Number2>
674inline Tensor<1,
675 n_components,
679 const Tensor<1, n_components, Tensor<1, dim, Number2>> &D_X)
680{
681 Tensor<1,
682 n_components,
684 dest;
685 for (unsigned int i = 0; i < n_components; ++i)
686 dest[i] = apply_diagonal_transformation(grad_F, D_X[i]);
687
688 return dest;
689}
690
691
692
701// rank=2
702template <int spacedim, int dim, typename Number1, typename Number2>
703inline DerivativeForm<1,
704 spacedim,
705 dim,
709 const Tensor<2, dim, Number2> &D_X)
710{
712 dest;
713 for (unsigned int i = 0; i < dim; ++i)
714 dest[i] = apply_diagonal_transformation(grad_F, D_X[i]);
715
716 return dest;
717}
718
719
721
722#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 > &)
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:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
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)
Definition exceptions.h:511
static ::ExceptionBase & ExcMessage(std::string arg1)
::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 > &)