deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11: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
sacado_number_types.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) 2017 - 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_differentiation_ad_sacado_number_types_h
14#define dealii_differentiation_ad_sacado_number_types_h
15
16#include <deal.II/base/config.h>
17
20
23
24#ifdef DEAL_II_TRILINOS_WITH_SACADO
25// It appears that some versions of Trilinos do not directly or indirectly
26// include all the headers for all forward and reverse Sacado AD types
27// in Sacado.hpp, so we also directly include these here as a precaution:
28# include <Sacado.hpp>
29# include <Sacado_Fad_DFad.hpp>
30# include <Sacado_trad.hpp>
31
32# include <complex>
33#endif
34
35#include <type_traits>
36
37
39
40
41namespace Differentiation
42{
43 namespace AD
44 {
50 template <typename NumberType, typename = void>
51 struct is_sacado_number : std::false_type
52 {};
53
54
60 template <typename NumberType, typename = void>
61 struct is_sacado_dfad_number : std::false_type
62 {};
63
64
70 template <typename NumberType, typename = void>
71 struct is_sacado_rad_number : std::false_type
72 {};
73
74 } // namespace AD
75} // namespace Differentiation
76
77
78
79#ifdef DEAL_II_TRILINOS_WITH_SACADO
80
81
82namespace Differentiation
83{
84 namespace AD
85 {
86 namespace internal
87 {
94 template <typename SacadoNumber, typename = void>
96
97 } // namespace internal
98
99
100
101 } // namespace AD
102} // namespace Differentiation
103
104
105/* ----------- inline and template functions and specializations ----------- */
106
107
108# ifndef DOXYGEN
109
110namespace Differentiation
111{
112 namespace AD
113 {
114 namespace internal
115 {
116 // The documentation on Sacado numbers is pretty sparse and/or hard to
117 // navigate. As a point of reference, see
118 // https://trilinos.org/docs/dev/packages/sacado/doc/html/classSacado_1_1Fad_1_1SimpleFad.html
119 // for semi-applicable documentation for the Sacado::Fad::Dfad class.
120 // and the examples in
121 // https://github.com/trilinos/Trilinos/tree/master/packages/sacado/example
122 //
123 // If one dares to venture there, the relevant files for the classes
124 // supported here are:
125 //
126 // Forward-mode auto-differentiable types:
127 // https://github.com/trilinos/Trilinos/blob/master/packages/sacado/src/sacado_dfad_DFad.hpp
128 // https://github.com/trilinos/Trilinos/blob/master/packages/sacado/src/sacado_dfad_GeneralFad.hpp
129 //
130 // Reverse-mode auto-differentiable types:
131 // https://github.com/trilinos/Trilinos/blob/master/packages/sacado/src/Sacado_trad.hpp
132
133
137 template <typename SacadoNumber>
138 struct SacadoNumberInfo<
139 SacadoNumber,
140 std::enable_if_t<
141 std::is_same_v<SacadoNumber,
142 Sacado::Fad::DFad<typename SacadoNumber::value_type>>>>
143 {
144 using ad_type = SacadoNumber;
145 using scalar_type = typename ad_type::scalar_type;
146 using value_type = typename ad_type::value_type;
147 using derivative_type = typename ad_type::value_type;
148
149 static const unsigned int n_supported_derivative_levels =
150 1 + SacadoNumberInfo<derivative_type>::n_supported_derivative_levels;
151 };
152
153
157 template <typename SacadoNumber>
158 struct SacadoNumberInfo<
159 SacadoNumber,
160 std::enable_if_t<std::is_same_v<
161 SacadoNumber,
162 Sacado::Rad::ADvar<typename SacadoNumber::value_type>>>>
163 {
164 using ad_type = SacadoNumber;
165 using scalar_type = typename ad_type::ADVari::scalar_type;
166 using value_type = typename ad_type::ADVari::value_type;
167 using derivative_type = typename ad_type::ADVari::value_type;
168
169 static const unsigned int n_supported_derivative_levels =
170 1 + SacadoNumberInfo<derivative_type>::n_supported_derivative_levels;
171 };
172
173
180 template <typename Number>
181 struct SacadoNumberInfo<
182 Number,
183 std::enable_if_t<std::is_arithmetic_v<std::decay_t<Number>>>>
184 {
185 static const unsigned int n_supported_derivative_levels = 0;
186 };
187
188
193 template <typename ScalarType>
194 struct ADNumberInfoFromEnum<
195 ScalarType,
197 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
198 {
199 static const bool is_taped = false;
200 using real_type = Sacado::Fad::DFad<ScalarType>;
201 using derivative_type =
202 typename SacadoNumberInfo<real_type>::derivative_type;
203 static const unsigned int n_supported_derivative_levels =
204 SacadoNumberInfo<real_type>::n_supported_derivative_levels;
205 };
206
207
212 template <typename ScalarType>
213 struct ADNumberInfoFromEnum<
214 ScalarType,
216 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
217 {
218 static const bool is_taped = false;
219 using real_type = Sacado::Fad::DFad<Sacado::Fad::DFad<ScalarType>>;
220 using derivative_type =
221 typename SacadoNumberInfo<real_type>::derivative_type;
222 static const unsigned int n_supported_derivative_levels =
223 SacadoNumberInfo<real_type>::n_supported_derivative_levels;
224 };
225
226
231 template <typename ScalarType>
232 struct ADNumberInfoFromEnum<
233 ScalarType,
235 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
236 {
237 static const bool is_taped = false;
238 using real_type = Sacado::Rad::ADvar<ScalarType>;
239 using derivative_type =
240 typename SacadoNumberInfo<real_type>::derivative_type;
241 static const unsigned int n_supported_derivative_levels =
242 SacadoNumberInfo<real_type>::n_supported_derivative_levels;
243 };
244
245
250 template <typename ScalarType>
251 struct ADNumberInfoFromEnum<
252 ScalarType,
254 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
255 {
256 static const bool is_taped = false;
257 using real_type = Sacado::Rad::ADvar<Sacado::Fad::DFad<ScalarType>>;
258 using derivative_type =
259 typename SacadoNumberInfo<real_type>::derivative_type;
260 static const unsigned int n_supported_derivative_levels =
261 SacadoNumberInfo<real_type>::n_supported_derivative_levels;
262 };
263
264
269 template <typename NumberType>
270 struct Marking<Sacado::Fad::DFad<NumberType>>
271 {
272 using ad_type =
273 typename SacadoNumberInfo<Sacado::Fad::DFad<NumberType>>::ad_type;
274 using derivative_type = typename SacadoNumberInfo<
275 Sacado::Fad::DFad<NumberType>>::derivative_type;
276 using scalar_type =
277 typename SacadoNumberInfo<Sacado::Fad::DFad<NumberType>>::scalar_type;
278
279 /*
280 * Initialize the state of an independent variable.
281 */
282 static void
283 independent_variable(const scalar_type &in,
284 const unsigned int index,
285 const unsigned int n_independent_variables,
286 ad_type &out)
287 {
288 // It is required that we first initialize the outer number before
289 // any of the nested ones.
290 out = ad_type(n_independent_variables, index, in);
291
292 // Initialize potential nested directional derivatives
293 Marking<derivative_type>::independent_variable(
294 in, index, n_independent_variables, out.val());
295 }
296
297 /*
298 * Initialize the state of a dependent variable.
299 */
300 static void
301 dependent_variable(ad_type &out, const ad_type &func)
302 {
303 out = func;
304 }
305 };
306
307
312 template <typename NumberType>
313 struct Marking<Sacado::Rad::ADvar<NumberType>>
314 {
315 using ad_type =
316 typename SacadoNumberInfo<Sacado::Rad::ADvar<NumberType>>::ad_type;
317 using derivative_type = typename SacadoNumberInfo<
318 Sacado::Rad::ADvar<NumberType>>::derivative_type;
319 using scalar_type = typename SacadoNumberInfo<
320 Sacado::Rad::ADvar<NumberType>>::scalar_type;
321
322 /*
323 * Initialize the state of an independent variable.
324 */
325 static void
326 independent_variable(const scalar_type &in,
327 const unsigned int index,
328 const unsigned int n_independent_variables,
329 ad_type &out)
330 {
331 // For Sacado::Rad::ADvar numbers, we have to initialize the
332 // ADNumber with an already fully-configured value. This means
333 // that if this nests another ADNumber then the nested number
334 // must already be set up and ready for use.
335
336 // Initialize potential nested directional derivatives
337 derivative_type derivative_initializer;
338 Marking<derivative_type>::independent_variable(
339 in, index, n_independent_variables, derivative_initializer);
340
341 // Initialize the outer ad_type
342 out = derivative_initializer;
343 }
344
345 /*
346 * Initialize the state of a dependent variable.
347 */
348 static void
349 dependent_variable(ad_type &out, const ad_type &func)
350 {
351 out = func;
352 }
353 };
354
355
361 template <typename NumberType>
362 struct ExtractData<Sacado::Fad::DFad<NumberType>>
363 {
364 using derivative_type = typename SacadoNumberInfo<
365 Sacado::Fad::DFad<NumberType>>::derivative_type;
366 using scalar_type =
367 typename SacadoNumberInfo<Sacado::Fad::DFad<NumberType>>::scalar_type;
368 using value_type =
369 typename SacadoNumberInfo<Sacado::Fad::DFad<NumberType>>::value_type;
370
374 static scalar_type
375 value(const Sacado::Fad::DFad<NumberType> &x)
376 {
377 return ExtractData<value_type>::value(x.val());
378 }
379
380
384 static unsigned int
385 n_directional_derivatives(const Sacado::Fad::DFad<NumberType> &x)
386 {
387 return x.size();
388 }
389
390
394 static derivative_type
395 directional_derivative(const Sacado::Fad::DFad<NumberType> &x,
396 const unsigned int direction)
397 {
398 if (x.hasFastAccess())
399 return x.fastAccessDx(direction);
400 else
401 return x.dx(direction);
402 }
403 };
404
405
411 template <typename NumberType>
412 struct ExtractData<Sacado::Rad::ADvar<NumberType>>
413 {
414 using derivative_type = typename SacadoNumberInfo<
415 Sacado::Rad::ADvar<NumberType>>::derivative_type;
416 using scalar_type = typename SacadoNumberInfo<
417 Sacado::Rad::ADvar<NumberType>>::scalar_type;
418 using value_type =
419 typename SacadoNumberInfo<Sacado::Rad::ADvar<NumberType>>::value_type;
420
424 static scalar_type
425 value(const Sacado::Rad::ADvar<NumberType> &x)
426 {
427 return ExtractData<value_type>::value(x.val());
428 }
429
430
434 static unsigned int
435 n_directional_derivatives(const Sacado::Rad::ADvar<NumberType> &)
436 {
437 // There are as many directional derivatives as there are
438 // independent variables, but each independent variable can
439 // only return one directional derivative.
440 return 1;
441 }
442
443
451 static derivative_type
452 directional_derivative(const Sacado::Rad::ADvar<NumberType> &x,
453 const unsigned int)
454 {
455 return x.adj();
456 }
457 };
458
459 } // namespace internal
460
461
462 /* -------------- NumberTypes::sacado_dfad -------------- */
463
464
471 template <typename ADNumberType>
472 struct ADNumberTraits<
473 ADNumberType,
474 std::enable_if_t<
475 std::is_same_v<ADNumberType,
476 Sacado::Fad::DFad<typename ADNumberType::scalar_type>>>>
477 : NumberTraits<typename ADNumberType::scalar_type,
478 NumberTypes::sacado_dfad>
479 {};
480
481
488 template <typename ADNumberType>
489 struct ADNumberTraits<
490 ADNumberType,
491 std::enable_if_t<
492 std::is_same_v<ADNumberType,
493 std::complex<Sacado::Fad::DFad<
494 typename ADNumberType::value_type::scalar_type>>>>>
495 : NumberTraits<
496 std::complex<typename ADNumberType::value_type::scalar_type>,
497 NumberTypes::sacado_dfad>
498 {};
499
500
505 template <>
506 struct NumberTraits<Sacado::Fad::DFad<float>, NumberTypes::sacado_dfad>
507 : NumberTraits<
508 typename ADNumberTraits<Sacado::Fad::DFad<float>>::scalar_type,
509 NumberTypes::sacado_dfad>
510 {};
511
512
517 template <>
518 struct NumberTraits<std::complex<Sacado::Fad::DFad<float>>,
520 : NumberTraits<typename ADNumberTraits<
521 std::complex<Sacado::Fad::DFad<float>>>::scalar_type,
522 NumberTypes::sacado_dfad>
523 {};
524
525
530 template <>
531 struct NumberTraits<Sacado::Fad::DFad<double>, NumberTypes::sacado_dfad>
532 : NumberTraits<
533 typename ADNumberTraits<Sacado::Fad::DFad<double>>::scalar_type,
534 NumberTypes::sacado_dfad>
535 {};
536
537
542 template <>
543 struct NumberTraits<std::complex<Sacado::Fad::DFad<double>>,
545 : NumberTraits<typename ADNumberTraits<
546 std::complex<Sacado::Fad::DFad<double>>>::scalar_type,
547 NumberTypes::sacado_dfad>
548 {};
549
550
551 /* -------------- NumberTypes::sacado_rad -------------- */
552
553
560 template <typename ADNumberType>
561 struct ADNumberTraits<
562 ADNumberType,
563 std::enable_if_t<std::is_same_v<
564 ADNumberType,
565 Sacado::Rad::ADvar<typename ADNumberType::ADVari::scalar_type>>>>
566 : NumberTraits<typename ADNumberType::ADVari::scalar_type,
567 NumberTypes::sacado_rad>
568 {};
569
570
575 template <>
576 struct NumberTraits<Sacado::Rad::ADvar<float>, NumberTypes::sacado_rad>
577 : NumberTraits<
578 typename ADNumberTraits<Sacado::Rad::ADvar<float>>::scalar_type,
579 NumberTypes::sacado_rad>
580 {};
581
582
587 template <>
588 struct NumberTraits<Sacado::Rad::ADvar<double>, NumberTypes::sacado_rad>
589 : NumberTraits<
590 typename ADNumberTraits<Sacado::Rad::ADvar<double>>::scalar_type,
591 NumberTypes::sacado_rad>
592 {};
593
594
595# ifdef DEAL_II_TRILINOS_CXX_SUPPORTS_SACADO_COMPLEX_RAD
596
597
604 template <typename ADNumberType>
605 struct ADNumberTraits<
606 ADNumberType,
607 std::enable_if_t<std::is_same_v<
608 ADNumberType,
609 std::complex<Sacado::Rad::ADvar<
610 typename ADNumberType::value_type::ADVari::scalar_type>>>>>
611 : NumberTraits<
612 std::complex<typename ADNumberType::value_type::ADVari::scalar_type>,
613 NumberTypes::sacado_rad>
614 {};
615
616
621 template <>
622 struct NumberTraits<std::complex<Sacado::Rad::ADvar<float>>,
624 : NumberTraits<typename ADNumberTraits<
625 std::complex<Sacado::Rad::ADvar<float>>>::scalar_type,
626 NumberTypes::sacado_rad>
627 {};
628
629
634 template <>
635 struct NumberTraits<std::complex<Sacado::Rad::ADvar<double>>,
637 : NumberTraits<typename ADNumberTraits<
638 std::complex<Sacado::Rad::ADvar<double>>>::scalar_type,
639 NumberTypes::sacado_rad>
640 {};
641
642
643# endif
644
645
646 /* -------------- NumberTypes::sacado_dfad_dfad -------------- */
647
655 template <typename ADNumberType>
656 struct ADNumberTraits<
657 ADNumberType,
658 std::enable_if_t<std::is_same_v<ADNumberType,
659 Sacado::Fad::DFad<Sacado::Fad::DFad<
660 typename ADNumberType::scalar_type>>>>>
661 : NumberTraits<typename ADNumberType::scalar_type,
662 NumberTypes::sacado_dfad_dfad>
663 {};
664
665
673 template <typename ADNumberType>
674 struct ADNumberTraits<
675 ADNumberType,
676 std::enable_if_t<
677 std::is_same_v<ADNumberType,
678 std::complex<Sacado::Fad::DFad<Sacado::Fad::DFad<
679 typename ADNumberType::value_type::scalar_type>>>>>>
680 : NumberTraits<
681 std::complex<typename ADNumberType::value_type::scalar_type>,
682 NumberTypes::sacado_dfad_dfad>
683 {};
684
685
690 template <>
691 struct NumberTraits<Sacado::Fad::DFad<Sacado::Fad::DFad<float>>,
693 : NumberTraits<typename ADNumberTraits<Sacado::Fad::DFad<
694 Sacado::Fad::DFad<float>>>::scalar_type,
695 NumberTypes::sacado_dfad_dfad>
696 {};
697
698
703 template <>
704 struct NumberTraits<
705 std::complex<Sacado::Fad::DFad<Sacado::Fad::DFad<float>>>,
707 : NumberTraits<typename ADNumberTraits<std::complex<Sacado::Fad::DFad<
708 Sacado::Fad::DFad<float>>>>::scalar_type,
709 NumberTypes::sacado_dfad_dfad>
710 {};
711
712
717 template <>
718 struct NumberTraits<Sacado::Fad::DFad<Sacado::Fad::DFad<double>>,
720 : NumberTraits<typename ADNumberTraits<Sacado::Fad::DFad<
721 Sacado::Fad::DFad<double>>>::scalar_type,
722 NumberTypes::sacado_dfad_dfad>
723 {};
724
725
730 template <>
731 struct NumberTraits<
732 std::complex<Sacado::Fad::DFad<Sacado::Fad::DFad<double>>>,
734 : NumberTraits<typename ADNumberTraits<std::complex<Sacado::Fad::DFad<
735 Sacado::Fad::DFad<double>>>>::scalar_type,
736 NumberTypes::sacado_dfad_dfad>
737 {};
738
739
740 /* -------------- NumberTypes::sacado_rad_dfad -------------- */
741
749 template <typename ADNumberType>
750 struct ADNumberTraits<ADNumberType,
751 std::enable_if_t<std::is_same_v<
752 ADNumberType,
753 Sacado::Rad::ADvar<Sacado::Fad::DFad<
754 typename ADNumberType::ADVari::scalar_type>>>>>
755 : NumberTraits<typename ADNumberType::ADVari::scalar_type,
756 NumberTypes::sacado_rad_dfad>
757 {};
758
759
764 template <>
765 struct NumberTraits<Sacado::Rad::ADvar<Sacado::Fad::DFad<float>>,
767 : NumberTraits<typename ADNumberTraits<Sacado::Rad::ADvar<
768 Sacado::Fad::DFad<float>>>::scalar_type,
769 NumberTypes::sacado_rad_dfad>
770 {};
771
772
777 template <>
778 struct NumberTraits<Sacado::Rad::ADvar<Sacado::Fad::DFad<double>>,
780 : NumberTraits<typename ADNumberTraits<Sacado::Rad::ADvar<
781 Sacado::Fad::DFad<double>>>::scalar_type,
782 NumberTypes::sacado_rad_dfad>
783 {};
784
785
786# ifdef DEAL_II_TRILINOS_CXX_SUPPORTS_SACADO_COMPLEX_RAD
787
788
796 template <typename ADNumberType>
797 struct ADNumberTraits<
798 ADNumberType,
799 std::enable_if_t<std::is_same_v<
800 ADNumberType,
801 std::complex<Sacado::Rad::ADvar<Sacado::Fad::DFad<
802 typename ADNumberType::value_type::ADVari::scalar_type>>>>>>
803 : NumberTraits<
804 std::complex<typename ADNumberType::value_type::ADVari::scalar_type>,
805 NumberTypes::sacado_rad_dfad>
806 {};
807
808
813 template <>
814 struct NumberTraits<
815 std::complex<Sacado::Rad::ADvar<Sacado::Fad::DFad<float>>>,
817 : NumberTraits<typename ADNumberTraits<std::complex<Sacado::Rad::ADvar<
818 Sacado::Fad::DFad<float>>>>::scalar_type,
819 NumberTypes::sacado_rad_dfad>
820 {};
821
822
827 template <>
828 struct NumberTraits<
829 std::complex<Sacado::Rad::ADvar<Sacado::Fad::DFad<double>>>,
831 : NumberTraits<typename ADNumberTraits<std::complex<Sacado::Rad::ADvar<
832 Sacado::Fad::DFad<double>>>>::scalar_type,
833 NumberTypes::sacado_rad_dfad>
834 {};
835
836
837# endif
838
839
840 /* -------------- Additional type traits -------------- */
841
842
843 template <typename NumberType>
844 struct is_sacado_dfad_number<
845 NumberType,
846 std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::type_code ==
847 NumberTypes::sacado_dfad ||
848 ADNumberTraits<std::decay_t<NumberType>>::type_code ==
849 NumberTypes::sacado_dfad_dfad>> : std::true_type
850 {};
851
852
853 template <typename NumberType>
854 struct is_sacado_dfad_number<
855 NumberType,
856 std::enable_if_t<
857 std::is_same_v<NumberType,
858 Sacado::Fad::Expr<typename NumberType::value_type>>>>
859 : std::true_type
860 {};
861
862
863 template <typename NumberType>
864 struct is_sacado_rad_number<
865 NumberType,
866 std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::type_code ==
867 NumberTypes::sacado_rad ||
868 ADNumberTraits<std::decay_t<NumberType>>::type_code ==
869 NumberTypes::sacado_rad_dfad>> : std::true_type
870 {};
871
872
873 template <typename NumberType>
874 struct is_sacado_rad_number<
875 NumberType,
876 std::enable_if_t<
877 std::is_same_v<NumberType,
878 Sacado::Rad::ADvari<Sacado::Fad::DFad<
879 typename NumberType::ADVari::scalar_type>>>>>
880 : std::true_type
881 {};
882
883
884 template <typename NumberType>
885 struct is_sacado_number<
886 NumberType,
887 std::enable_if_t<is_sacado_dfad_number<NumberType>::value ||
888 is_sacado_rad_number<NumberType>::value>>
889 : std::true_type
890 {};
891
892 } // namespace AD
893} // namespace Differentiation
894
895
896# endif // DOXYGEN
897
898
899#endif // DEAL_II_TRILINOS_WITH_SACADO
900
901
903
904#endif
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
*  *  *  RotationFunction< dim, Number >::RotationFunction Number(dim)
STL namespace.