Reference documentation for deal.II version 9.4.0
derivative_form.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2013 - 2021 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
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
57template <int order, int dim, int spacedim, typename Number = double>
59{
60public:
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
112
116 operator Tensor<1, dim, Number>() const;
117
123 transpose() const;
124
131 norm() const;
132
138 Number
139 determinant() const;
140
152
157 static std::size_t
159
164 int,
165 << "Invalid DerivativeForm index " << arg1);
166
167private:
174
175
180};
181
182
183/*--------------------------- Inline functions -----------------------------*/
184
185#ifndef DOXYGEN
186
187template <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
200template <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
210template <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
225template <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
237template <int order, int dim, int spacedim, typename Number>
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
252template <int order, int dim, int spacedim, typename Number>
255{
256 AssertIndexRange(i, spacedim);
257
258 return tensor[i];
259}
260
261
262
263template <int order, int dim, int spacedim, typename Number>
264inline 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
275template <int order, int dim, int spacedim, typename Number>
277operator 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
287template <int order, int dim, int spacedim, typename Number>
289operator 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
304template <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
320template <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
336template <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
348template <int order, int dim, int spacedim, typename Number>
349inline Number
351{
352 Assert(order == 1, ExcMessage("Only for order == 1."));
353 if (dim == spacedim)
354 {
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
374template <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
397template <int order, int dim, int spacedim, typename Number>
398inline std::size_t
400{
402}
403
404#endif // DOXYGEN
405
406
407
429template <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
451template <int spacedim, int dim, typename Number1, typename Number2>
452inline 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)
463
464 return dest;
465}
466
467
468
476template <int spacedim,
477 int dim,
478 int n_components,
479 typename Number1,
480 typename Number2>
481inline 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)
494
495 return dest;
496}
497
498
499
515template <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
536template <int dim, int spacedim, typename Number>
539{
541 tt = DF.transpose();
542 return tt;
543}
544
545
547
548#endif
static std::size_t memory_consumption()
DerivativeForm & operator=(const Tensor< order, spacedim, Tensor< 1, dim, Number > > &)
Tensor< order, dim, Number > tensor[spacedim]
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)
const Tensor< order, dim, Number > & operator[](const unsigned int i) const
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
DerivativeForm & operator=(const Tensor< 1, dim, Number > &)
DerivativeForm(const Tensor< order, spacedim, Tensor< 1, dim, Number > > &)
DerivativeForm(const Tensor< order+1, dim, Number > &)
Tensor< order, dim, Number > & operator[](const unsigned int i)
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &t)
constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &t)
Definition: tensor.h:503
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:442
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:443
static ::ExceptionBase & ExcInvalidTensorIndex(int arg1)
#define Assert(cond, exc)
Definition: exceptions.h:1473
#define AssertIndexRange(index, range)
Definition: exceptions.h:1732
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:509
static ::ExceptionBase & ExcMessage(std::string arg1)
static const char T
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
typename internal::ProductTypeImpl< typename std::decay< T >::type, typename std::decay< U >::type >::type type
constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)