16 #include <deal.II/base/config.h> 18 #if defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO) 20 # include <deal.II/base/exceptions.h> 21 # include <deal.II/base/types.h> 22 # include <deal.II/base/utilities.h> 24 # include <deal.II/differentiation/ad/ad_drivers.h> 25 # include <deal.II/differentiation/ad/ad_number_traits.h> 26 # include <deal.II/differentiation/ad/ad_number_types.h> 27 # include <deal.II/differentiation/ad/adolc_number_types.h> 28 # include <deal.II/differentiation/ad/sacado_number_types.h> 30 # include <deal.II/lac/full_matrix.h> 31 # include <deal.II/lac/vector.h> 33 # ifdef DEAL_II_WITH_ADOLC 35 DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
36 # include <adolc/adolc_fatalerror.h> 37 # include <adolc/drivers/drivers.h> 38 # include <adolc/taping.h> 39 DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
41 # endif // DEAL_II_WITH_ADOLC 46 DEAL_II_NAMESPACE_OPEN
56 template <
typename ADNumberType,
typename ScalarType,
typename T>
65 template <
typename ADNumberType,
typename ScalarType,
typename T>
74 template <
typename ADNumberType,
typename ScalarType,
typename T>
84 template <
typename ADNumberType,
typename ScalarType,
typename T>
93 template <
typename ADNumberType,
typename ScalarType,
typename T>
105 template <
typename ADNumberType,
typename ScalarType,
typename T>
115 template <
typename ADNumberType,
typename ScalarType,
typename T>
125 template <
typename ADNumberType,
typename ScalarType,
typename T>
126 std::vector<typename Types<ADNumberType>::tape_index>
131 return std::vector<typename Types<ADNumberType>::tape_index>();
135 template <
typename ADNumberType,
typename ScalarType,
typename T>
144 template <
typename ADNumberType,
typename ScalarType,
typename T>
154 template <
typename ADNumberType,
typename ScalarType,
typename T>
164 template <
typename ADNumberType,
typename ScalarType,
typename T>
173 template <
typename ADNumberType,
typename ScalarType,
typename T>
181 template <
typename ADNumberType,
typename ScalarType,
typename T>
189 template <
typename ADNumberType,
typename ScalarType,
typename T>
193 std::ostream &)
const 199 template <
typename ADNumberType,
typename ScalarType,
typename T>
203 const std::vector<ScalarType> &)
const 206 return ScalarType(0.0);
210 template <
typename ADNumberType,
typename ScalarType,
typename T>
214 const std::vector<ScalarType> &,
215 Vector<ScalarType> &)
const 221 template <
typename ADNumberType,
typename ScalarType,
typename T>
225 const std::vector<ScalarType> &,
232 template <
typename ADNumberType,
typename ScalarType,
typename T>
237 const std::vector<ScalarType> &,
238 Vector<ScalarType> &)
const 244 template <
typename ADNumberType,
typename ScalarType,
typename T>
249 const std::vector<ScalarType> &,
257 # ifdef DEAL_II_WITH_ADOLC 261 template <
typename ADNumberType>
265 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
267 : active_tape(
Numbers<ADNumberType>::invalid_tape_index)
269 , is_recording_flag(false)
270 , use_stored_taped_buffer_sizes(false)
278 template <
typename ADNumberType>
283 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
284 NumberTypes::adolc_taped>::type>::is_recording()
287 return is_recording_flag;
291 template <
typename ADNumberType>
293 TapedDrivers<ADNumberType,
295 typename std::enable_if<
296 ADNumberTraits<ADNumberType>::type_code ==
297 NumberTypes::adolc_taped>::type>::active_tape_index()
const 303 template <
typename ADNumberType>
305 TapedDrivers<ADNumberType,
307 typename std::enable_if<
308 ADNumberTraits<ADNumberType>::type_code ==
309 NumberTypes::adolc_taped>::type>::keep_independent_values()
316 template <
typename ADNumberType>
321 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
322 NumberTypes::adolc_taped>::type>::
368 const std::vector<typename Types<ADNumberType>::tape_index>
369 registered_tape_indices = get_registered_tape_indices();
370 const auto it = std::find(registered_tape_indices.begin(),
371 registered_tape_indices.end(),
373 if (it == registered_tape_indices.end())
379 std::vector<std::size_t> counts(STAT_SIZE);
380 ::tapestats(tape_index, counts.data());
383 catch (const ::FatalError &exc)
390 template <
typename ADNumberType>
395 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
396 NumberTypes::adolc_taped>::type>::
397 set_tape_buffer_sizes(
405 obufsize = in_obufsize;
406 lbufsize = in_lbufsize;
407 vbufsize = in_vbufsize;
408 tbufsize = in_tbufsize;
409 use_stored_taped_buffer_sizes =
true;
413 template <
typename ADNumberType>
418 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
419 NumberTypes::adolc_taped>::type>::
421 const bool keep_independent_values)
423 if (use_stored_taped_buffer_sizes)
425 keep_independent_values,
431 trace_on(tape_index, keep_independent_values);
434 keep_values = keep_independent_values;
435 is_recording_flag =
true;
439 template <
typename ADNumberType>
444 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
445 NumberTypes::adolc_taped>::type>::
448 const bool write_tapes_to_file)
450 if (write_tapes_to_file)
451 trace_off(active_tape_index);
457 is_recording_flag =
false;
463 if (keep_independent_values() ==
false)
464 active_tape = Numbers<ADNumberType>::invalid_tape_index;
468 template <
typename ADNumberType>
469 std::vector<typename Types<ADNumberType>::tape_index>
473 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
474 NumberTypes::adolc_taped>::type>::
475 get_registered_tape_indices()
const 481 std::vector<short> registered_tape_indices_s;
482 cachedTraceTags(registered_tape_indices_s);
484 return std::vector<typename Types<ADNumberType>::tape_index>(
485 registered_tape_indices_s.begin(), registered_tape_indices_s.end());
489 template <
typename ADNumberType>
494 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
495 NumberTypes::adolc_taped>::type>::
498 active_tape = tape_index;
502 template <
typename ADNumberType>
507 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
508 NumberTypes::adolc_taped>::type>::
513 is_registered_tape(tape_index) ==
true,
515 "Cannot ask for the status of a tape that has not yet been recorded and used."));
517 const auto it_status_tape = status.find(tape_index);
529 if (it_status_tape == status.end())
532 const auto status_tape = it_status_tape->second;
537 status_tape < 4 && status_tape >= -2,
539 "The tape status is not within the range specified within the ADOL-C documentation."));
540 return (status_tape < 0);
544 template <
typename ADNumberType>
549 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
550 NumberTypes::adolc_taped>::type>::
551 last_action_requires_retaping()
const 553 return requires_retaping(active_tape);
557 template <
typename ADNumberType>
562 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
563 NumberTypes::adolc_taped>::type>::
566 Assert(is_registered_tape(tape_index),
568 "This tape does not exist, and therefore cannot be cleared."));
569 removeTape(tape_index, TapeRemovalType::ADOLC_REMOVE_COMPLETELY);
573 template <
typename ADNumberType>
578 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
579 NumberTypes::adolc_taped>::type>::
580 reset(
const bool clear_registered_tapes)
582 active_tape = Numbers<ADNumberType>::invalid_tape_index;
583 is_recording_flag =
false;
585 if (clear_registered_tapes)
587 const std::vector<typename Types<ADNumberType>::tape_index>
588 registered_tape_indices = get_registered_tape_indices();
589 for (
const auto &tape_index : registered_tape_indices)
590 remove_tape(tape_index);
595 template <
typename ADNumberType>
597 TapedDrivers<ADNumberType,
599 typename std::enable_if<
600 ADNumberTraits<ADNumberType>::type_code ==
601 NumberTypes::adolc_taped>::type>::print(std::ostream &stream)
604 const std::vector<typename Types<ADNumberType>::tape_index>
605 registered_tape_indices = get_registered_tape_indices();
606 stream <<
"Registered tapes and their status: ";
607 auto it_registered_tape = registered_tape_indices.begin();
608 for (
unsigned int i = 0; i < registered_tape_indices.size();
609 ++i, ++it_registered_tape)
611 const auto tape_index = *it_registered_tape;
612 const auto it_status_tape = status.find(tape_index);
613 Assert(it_status_tape != status.end(),
615 "This tape's status has not been found in the map."));
616 const auto status_tape = it_status_tape->second;
618 stream << tape_index <<
"->" << status_tape
619 << (i < (registered_tape_indices.size() - 1) ?
"," :
"");
623 stream <<
"Keep values? " << keep_independent_values() <<
"\n";
624 stream <<
"Use stored tape buffer sizes? " 625 << use_stored_taped_buffer_sizes <<
"\n";
629 template <
typename ADNumberType>
634 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
635 NumberTypes::adolc_taped>::type>::
638 std::ostream & stream)
const 642 std::vector<std::size_t> counts(STAT_SIZE);
643 ::tapestats(tape_index, counts.data());
646 <<
"Tape index: " << tape_index <<
"\n" 647 <<
"Number of independent variables: " << counts[0] <<
"\n" 648 <<
"Number of dependent variables: " << counts[1] <<
"\n" 649 <<
"Max number of live, active variables: " << counts[2] <<
"\n" 650 <<
"Size of taylor stack (number of overwrites): " << counts[3] <<
"\n" 651 <<
"Operations buffer size: " << counts[4] <<
"\n" 652 <<
"Total number of recorded operations: " << counts[5] <<
"\n" 653 <<
"Operations file written or not: " << counts[6] <<
"\n" 654 <<
"Overall number of locations: " << counts[7] <<
"\n" 655 <<
"Locations file written or not: " << counts[8] <<
"\n" 656 <<
"Overall number of values: " << counts[9] <<
"\n" 657 <<
"Values file written or not: " << counts[10] <<
"\n" 658 <<
"Locations buffer size: " << counts[11] <<
"\n" 659 <<
"Values buffer size: " << counts[12] <<
"\n" 660 <<
"Taylor buffer size: " << counts[13] <<
"\n" 661 <<
"Number of eq_*_prod for sparsity pattern: " << counts[14] <<
"\n" 662 <<
"Use of 'min_op', deferred to 'abs_op' for piecewise calculations: " 663 << counts[15] <<
"\n" 664 <<
"Number of 'abs' calls that can switch branch: " << counts[16]
666 <<
"Number of parameters (doubles) interchangeable without retaping: " 667 << counts[17] <<
"\n" 672 template <
typename ADNumberType>
673 typename TapedDrivers<
676 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
677 NumberTypes::adolc_taped>::type>::scalar_type
681 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
682 NumberTypes::adolc_taped>::type>::
684 const std::vector<scalar_type> &independent_variables)
const 686 Assert(is_registered_tape(active_tape_index),
687 ExcMessage(
"This tape has not yet been recorded."));
689 scalar_type value = 0.0;
691 status[active_tape_index] =
692 ::function(active_tape_index,
694 independent_variables.size(),
695 const_cast<double *
>(independent_variables.data()),
702 template <
typename ADNumberType>
707 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
708 NumberTypes::adolc_taped>::type>::
710 const std::vector<scalar_type> &independent_variables,
711 Vector<scalar_type> & gradient)
const 713 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
716 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
718 Assert(gradient.size() == independent_variables.size(),
720 independent_variables.size()));
721 Assert(is_registered_tape(active_tape_index),
722 ExcMessage(
"This tape has not yet been recorded."));
727 status[active_tape_index] =
728 ::gradient(active_tape_index,
729 independent_variables.size(),
730 const_cast<scalar_type *
>(independent_variables.data()),
735 template <
typename ADNumberType>
740 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
741 NumberTypes::adolc_taped>::type>::
743 const std::vector<scalar_type> &independent_variables,
746 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
749 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
751 Assert(hessian.
m() == independent_variables.size(),
753 Assert(hessian.
n() == independent_variables.size(),
755 Assert(is_registered_tape(active_tape_index),
756 ExcMessage(
"This tape has not yet been recorded."));
758 const unsigned int n_independent_variables = independent_variables.size();
759 std::vector<scalar_type *> H(n_independent_variables);
760 for (
unsigned int i = 0; i < n_independent_variables; ++i)
761 H[i] = &hessian[i][0];
763 status[active_tape_index] =
764 ::hessian(active_tape_index,
765 n_independent_variables,
766 const_cast<scalar_type *>(independent_variables.data()),
772 for (
unsigned int i = 0; i < n_independent_variables; i++)
773 for (
unsigned int j = 0; j < i; j++)
774 hessian[j][i] = hessian[i][j];
778 template <
typename ADNumberType>
783 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
784 NumberTypes::adolc_taped>::type>::
786 const unsigned int n_dependent_variables,
787 const std::vector<scalar_type> &independent_variables,
788 Vector<scalar_type> & values)
const 790 Assert(values.size() == n_dependent_variables,
792 Assert(is_registered_tape(active_tape_index),
793 ExcMessage(
"This tape has not yet been recorded."));
798 status[active_tape_index] =
799 ::function(active_tape_index,
800 n_dependent_variables,
801 independent_variables.size(),
802 const_cast<scalar_type *
>(independent_variables.data()),
807 template <
typename ADNumberType>
812 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
813 NumberTypes::adolc_taped>::type>::
815 const unsigned int n_dependent_variables,
816 const std::vector<scalar_type> &independent_variables,
819 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
822 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
824 Assert(jacobian.
m() == n_dependent_variables,
826 Assert(jacobian.
n() == independent_variables.size(),
828 Assert(is_registered_tape(active_tape_index),
829 ExcMessage(
"This tape has not yet been recorded."));
831 std::vector<scalar_type *> J(n_dependent_variables);
832 for (
unsigned int i = 0; i < n_dependent_variables; ++i)
833 J[i] = &jacobian[i][0];
835 status[active_tape_index] = ::jacobian(active_tape_index,
836 n_dependent_variables,
837 independent_variables.size(),
838 independent_variables.data(),
846 template <
typename ADNumberType>
851 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
852 NumberTypes::adolc_taped>::type>::is_recording()
860 template <
typename ADNumberType>
862 TapedDrivers<ADNumberType,
864 typename std::enable_if<
865 ADNumberTraits<ADNumberType>::type_code ==
866 NumberTypes::adolc_taped>::type>::active_tape_index()
const 869 return Numbers<ADNumberType>::invalid_tape_index;
873 template <
typename ADNumberType>
875 TapedDrivers<ADNumberType,
877 typename std::enable_if<
878 ADNumberTraits<ADNumberType>::type_code ==
879 NumberTypes::adolc_taped>::type>::keep_independent_values()
887 template <
typename ADNumberType>
892 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
893 NumberTypes::adolc_taped>::type>::
901 template <
typename ADNumberType>
906 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
907 NumberTypes::adolc_taped>::type>::
908 set_tape_buffer_sizes(
918 template <
typename ADNumberType>
923 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
924 NumberTypes::adolc_taped>::type>::
931 template <
typename ADNumberType>
936 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
937 NumberTypes::adolc_taped>::type>::
944 template <
typename ADNumberType>
945 std::vector<typename Types<ADNumberType>::tape_index>
949 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
950 NumberTypes::adolc_taped>::type>::
951 get_registered_tape_indices()
const 954 return std::vector<typename Types<ADNumberType>::tape_index>();
958 template <
typename ADNumberType>
963 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
964 NumberTypes::adolc_taped>::type>::
971 template <
typename ADNumberType>
976 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
977 NumberTypes::adolc_taped>::type>::
985 template <
typename ADNumberType>
990 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
991 NumberTypes::adolc_taped>::type>::
992 last_action_requires_retaping()
const 999 template <
typename ADNumberType>
1004 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1005 NumberTypes::adolc_taped>::type>::
1012 template <
typename ADNumberType>
1014 TapedDrivers<ADNumberType,
1016 typename std::enable_if<
1017 ADNumberTraits<ADNumberType>::type_code ==
1018 NumberTypes::adolc_taped>::type>::reset(
const bool)
1024 template <
typename ADNumberType>
1026 TapedDrivers<ADNumberType,
1028 typename std::enable_if<
1029 ADNumberTraits<ADNumberType>::type_code ==
1030 NumberTypes::adolc_taped>::type>::print(std::ostream &)
const 1036 template <
typename ADNumberType>
1041 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1042 NumberTypes::adolc_taped>::type>::
1044 std::ostream &)
const 1050 template <
typename ADNumberType>
1051 typename TapedDrivers<
1054 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1055 NumberTypes::adolc_taped>::type>::scalar_type
1059 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1060 NumberTypes::adolc_taped>::type>::
1062 const std::vector<scalar_type> &)
const 1069 template <
typename ADNumberType>
1074 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1075 NumberTypes::adolc_taped>::type>::
1077 const std::vector<scalar_type> &,
1078 Vector<scalar_type> &)
const 1084 template <
typename ADNumberType>
1089 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1090 NumberTypes::adolc_taped>::type>::
1092 const std::vector<scalar_type> &,
1099 template <
typename ADNumberType>
1104 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1105 NumberTypes::adolc_taped>::type>::
1108 const std::vector<scalar_type> &,
1109 Vector<scalar_type> &)
const 1115 template <
typename ADNumberType>
1120 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1121 NumberTypes::adolc_taped>::type>::
1124 const std::vector<scalar_type> &,
1130 # endif // DEAL_II_WITH_ADOLC 1136 template <
typename ADNumberType>
1141 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1142 NumberTypes::adolc_taped>::type>::is_recording()
1147 return taped_driver.is_recording();
1151 template <
typename ADNumberType>
1153 TapedDrivers<ADNumberType,
1155 typename std::enable_if<
1156 ADNumberTraits<ADNumberType>::type_code ==
1157 NumberTypes::adolc_taped>::type>::active_tape_index()
const 1161 return taped_driver.active_tape_index();
1165 template <
typename ADNumberType>
1167 TapedDrivers<ADNumberType,
1169 typename std::enable_if<
1170 ADNumberTraits<ADNumberType>::type_code ==
1171 NumberTypes::adolc_taped>::type>::keep_independent_values()
1174 return taped_driver.keep_independent_values();
1178 template <
typename ADNumberType>
1183 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1184 NumberTypes::adolc_taped>::type>::
1190 return taped_driver.is_registered_tape(tape_index);
1194 template <
typename ADNumberType>
1199 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1200 NumberTypes::adolc_taped>::type>::
1201 set_tape_buffer_sizes(
1209 taped_driver.set_tape_buffer_sizes(obufsize,
1216 template <
typename ADNumberType>
1221 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1222 NumberTypes::adolc_taped>::type>::
1224 const bool keep_independent_values)
1228 taped_driver.start_taping(tape_index, keep_independent_values);
1232 template <
typename ADNumberType>
1237 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1238 NumberTypes::adolc_taped>::type>::
1241 const bool write_tapes_to_file)
1245 taped_driver.stop_taping(active_tape_index, write_tapes_to_file);
1249 template <
typename ADNumberType>
1250 std::vector<typename Types<ADNumberType>::tape_index>
1254 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1255 NumberTypes::adolc_taped>::type>::
1256 get_registered_tape_indices()
const 1258 return taped_driver.get_registered_tape_indices();
1262 template <
typename ADNumberType>
1267 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1268 NumberTypes::adolc_taped>::type>::
1271 taped_driver.activate_tape(tape_index);
1275 template <
typename ADNumberType>
1280 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1281 NumberTypes::adolc_taped>::type>::
1285 return taped_driver.requires_retaping(tape_index);
1289 template <
typename ADNumberType>
1294 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1295 NumberTypes::adolc_taped>::type>::
1296 last_action_requires_retaping()
const 1298 return taped_driver.last_action_requires_retaping();
1302 template <
typename ADNumberType>
1307 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1308 NumberTypes::adolc_taped>::type>::
1311 taped_driver.remove_tape(tape_index);
1315 template <
typename ADNumberType>
1320 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1321 NumberTypes::adolc_taped>::type>::
1322 reset(
const bool clear_registered_tapes)
1324 taped_driver.reset(clear_registered_tapes);
1328 template <
typename ADNumberType>
1330 TapedDrivers<ADNumberType,
1332 typename std::enable_if<
1333 ADNumberTraits<ADNumberType>::type_code ==
1334 NumberTypes::adolc_taped>::type>::print(std::ostream &stream)
1337 taped_driver.print(stream);
1341 template <
typename ADNumberType>
1346 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1347 NumberTypes::adolc_taped>::type>::
1350 std::ostream & stream)
const 1354 taped_driver.print_tape_stats(tape_index, stream);
1358 template <
typename ADNumberType>
1359 typename TapedDrivers<
1362 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1363 NumberTypes::adolc_taped>::type>::scalar_type
1367 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1368 NumberTypes::adolc_taped>::type>::
1370 const std::vector<scalar_type> &independent_variables)
const 1374 return taped_driver.value(active_tape_index,
1375 vector_float_to_double(independent_variables));
1379 template <
typename ADNumberType>
1384 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1385 NumberTypes::adolc_taped>::type>::
1387 const std::vector<scalar_type> &independent_variables,
1388 Vector<scalar_type> & gradient)
const 1393 taped_driver.gradient(active_tape_index,
1394 vector_float_to_double(independent_variables),
1396 gradient = gradient_double;
1400 template <
typename ADNumberType>
1405 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1406 NumberTypes::adolc_taped>::type>::
1408 const std::vector<scalar_type> &independent_variables,
1414 taped_driver.hessian(active_tape_index,
1415 vector_float_to_double(independent_variables),
1417 hessian = hessian_double;
1421 template <
typename ADNumberType>
1426 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1427 NumberTypes::adolc_taped>::type>::
1429 const unsigned int n_dependent_variables,
1430 const std::vector<scalar_type> &independent_variables,
1431 Vector<scalar_type> & values)
const 1436 taped_driver.
values(active_tape_index,
1437 n_dependent_variables,
1438 vector_float_to_double(independent_variables),
1440 values = values_double;
1444 template <
typename ADNumberType>
1449 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1450 NumberTypes::adolc_taped>::type>::
1452 const unsigned int n_dependent_variables,
1453 const std::vector<scalar_type> &independent_variables,
1459 taped_driver.jacobian(active_tape_index,
1460 n_dependent_variables,
1461 vector_float_to_double(independent_variables),
1463 jacobian = jacobian_double;
1467 template <
typename ADNumberType>
1472 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1473 NumberTypes::adolc_taped>::type>::
1474 vector_float_to_double(
const std::vector<float> &in)
const 1476 std::vector<double> out(in.size());
1477 std::copy(in.begin(), in.end(), out.begin());
1485 template <
typename ADNumberType,
typename ScalarType,
typename T>
1493 template <
typename ADNumberType,
typename ScalarType,
typename T>
1501 template <
typename ADNumberType,
typename ScalarType,
typename T>
1509 template <
typename ADNumberType,
typename ScalarType,
typename T>
1519 template <
typename ADNumberType,
typename ScalarType,
typename T>
1522 const std::vector<ADNumberType> &)
const 1525 return ScalarType(0.0);
1529 template <
typename ADNumberType,
typename ScalarType,
typename T>
1532 const std::vector<ADNumberType> &,
1533 const std::vector<ADNumberType> &,
1534 Vector<ScalarType> &)
const 1540 template <
typename ADNumberType,
typename ScalarType,
typename T>
1543 const std::vector<ADNumberType> &,
1544 const std::vector<ADNumberType> &,
1551 template <
typename ADNumberType,
typename ScalarType,
typename T>
1554 const std::vector<ADNumberType> &,
1555 Vector<ScalarType> &)
const 1561 template <
typename ADNumberType,
typename ScalarType,
typename T>
1564 const std::vector<ADNumberType> &,
1565 const std::vector<ADNumberType> &,
1578 template <
typename ADNumberType>
1579 typename std::enable_if<!(ADNumberTraits<ADNumberType>::type_code ==
1580 NumberTypes::sacado_rad ||
1582 NumberTypes::sacado_rad_dfad)>::type
1586 # ifdef DEAL_II_TRILINOS_WITH_SACADO 1597 template <
typename ADNumberType>
1598 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1599 NumberTypes::sacado_rad ||
1601 NumberTypes::sacado_rad_dfad>::type
1603 ADNumberType &dependent_variable)
1613 ADNumberType::Outvar_Gradcomp(dependent_variable);
1623 template <
typename ADNumberType>
1624 typename std::enable_if<!(ADNumberTraits<ADNumberType>::type_code ==
1625 NumberTypes::adolc_tapeless)>::type
1630 # ifdef DEAL_II_WITH_ADOLC 1640 template <
typename ADNumberType>
1641 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1642 NumberTypes::adolc_tapeless>::type
1645 # ifdef DEAL_II_ADOLC_WITH_TAPELESS_REFCOUNTING 1660 const std::size_t n_live_variables = adtl::refcounter::getNumLiveVar();
1661 if (n_live_variables == 0)
1663 adtl::setNumDir(n_directional_derivatives);
1672 const std::size_t n_set_directional_derivatives = adtl::getNumDir();
1673 if (n_directional_derivatives > n_set_directional_derivatives)
1675 n_live_variables == 0,
1677 "There are currently " +
1680 "adtl::adouble variables in existence. They currently " 1683 " directional derivatives " 1684 "but you wish to increase this to " +
1687 "To safely change (or more specifically in this case, " 1688 "increase) the number of directional derivatives, there " 1689 "must be no tapeless doubles in local/global scope."));
1695 adtl::setNumDir(n_directional_derivatives);
1699 # else // DEAL_II_WITH_ADOLC 1701 template <
typename ADNumberType>
1702 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1703 NumberTypes::adolc_tapeless>::type
1704 configure_tapeless_mode(
const unsigned int )
1719 template <
typename ADNumberType,
typename ScalarType>
1723 typename std::enable_if<
1724 ADNumberTraits<ADNumberType>::type_code == NumberTypes::sacado_rad ||
1725 ADNumberTraits<ADNumberType>::type_code ==
1726 NumberTypes::sacado_rad_dfad>::type>::TapelessDrivers()
1727 : dependent_variable_marking_safe(false)
1731 template <
typename ADNumberType,
typename ScalarType>
1736 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1738 ADNumberTraits<ADNumberType>::type_code ==
1740 initialize_global_environment(
const unsigned int n_independent_variables)
1742 internal::configure_tapeless_mode<ADNumberType>(n_independent_variables);
1746 template <
typename ADNumberType,
typename ScalarType>
1751 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1753 ADNumberTraits<ADNumberType>::type_code ==
1755 allow_dependent_variable_marking()
1757 dependent_variable_marking_safe =
true;
1761 template <
typename ADNumberType,
typename ScalarType>
1766 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1768 ADNumberTraits<ADNumberType>::type_code ==
1770 prevent_dependent_variable_marking()
1772 dependent_variable_marking_safe =
false;
1776 template <
typename ADNumberType,
typename ScalarType>
1781 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1783 ADNumberTraits<ADNumberType>::type_code ==
1785 is_dependent_variable_marking_allowed()
const 1787 return dependent_variable_marking_safe;
1791 template <
typename ADNumberType,
typename ScalarType>
1796 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1798 ADNumberTraits<ADNumberType>::type_code ==
1800 value(
const std::vector<ADNumberType> &dependent_variables)
const 1802 Assert(dependent_variables.size() == 1,
1804 return ADNumberTraits<ADNumberType>::get_scalar_value(
1805 dependent_variables[0]);
1809 template <
typename ADNumberType,
typename ScalarType>
1814 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1816 ADNumberTraits<ADNumberType>::type_code ==
1818 gradient(
const std::vector<ADNumberType> &independent_variables,
1819 const std::vector<ADNumberType> &dependent_variables,
1820 Vector<ScalarType> & gradient)
const 1822 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
1825 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
1827 Assert(dependent_variables.size() == 1,
1829 Assert(gradient.size() == independent_variables.size(),
1831 independent_variables.size()));
1836 const_cast<ADNumberType &>(dependent_variables[0]));
1837 const std::size_t n_independent_variables = independent_variables.size();
1838 for (
unsigned int i = 0; i < n_independent_variables; i++)
1840 ADNumberTraits<ADNumberType>::get_directional_derivative(
1841 independent_variables[i], 0 ));
1845 template <
typename ADNumberType,
typename ScalarType>
1850 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1852 ADNumberTraits<ADNumberType>::type_code ==
1854 hessian(
const std::vector<ADNumberType> &independent_variables,
1855 const std::vector<ADNumberType> &dependent_variables,
1858 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
1861 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
1863 Assert(dependent_variables.size() == 1,
1865 Assert(hessian.
m() == independent_variables.size(),
1867 Assert(hessian.
n() == independent_variables.size(),
1873 const_cast<ADNumberType &>(dependent_variables[0]));
1874 const std::size_t n_independent_variables = independent_variables.size();
1875 for (
unsigned int i = 0; i < n_independent_variables; i++)
1877 using derivative_type =
1878 typename ADNumberTraits<ADNumberType>::derivative_type;
1879 const derivative_type gradient_i =
1880 ADNumberTraits<ADNumberType>::get_directional_derivative(
1881 independent_variables[i], i);
1883 for (
unsigned int j = 0; j <= i; ++j)
1888 const ScalarType hessian_ij =
1890 ADNumberTraits<derivative_type>::get_directional_derivative(
1892 hessian[i][j] = hessian_ij;
1894 hessian[j][i] = hessian_ij;
1900 template <
typename ADNumberType,
typename ScalarType>
1905 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1907 ADNumberTraits<ADNumberType>::type_code ==
1909 values(
const std::vector<ADNumberType> &dependent_variables,
1910 Vector<ScalarType> & values)
const 1912 Assert(values.size() == dependent_variables.size(),
1915 const std::size_t n_dependent_variables = dependent_variables.size();
1916 for (
unsigned int i = 0; i < n_dependent_variables; i++)
1917 values[i] = ADNumberTraits<ADNumberType>::get_scalar_value(
1918 dependent_variables[i]);
1922 template <
typename ADNumberType,
typename ScalarType>
1927 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1929 ADNumberTraits<ADNumberType>::type_code ==
1931 jacobian(
const std::vector<ADNumberType> &independent_variables,
1932 const std::vector<ADNumberType> &dependent_variables,
1935 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
1938 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
1940 Assert(jacobian.
m() == dependent_variables.size(),
1942 Assert(jacobian.
n() == independent_variables.size(),
1945 const std::size_t n_independent_variables = independent_variables.size();
1946 const std::size_t n_dependent_variables = dependent_variables.size();
1957 using accumulation_type =
1958 typename ADNumberTraits<ADNumberType>::derivative_type;
1959 std::vector<accumulation_type> rad_accumulation(
1960 n_independent_variables,
1963 for (
unsigned int i = 0; i < n_dependent_variables; i++)
1966 const_cast<ADNumberType &>(dependent_variables[i]));
1967 for (
unsigned int j = 0; j < n_independent_variables; j++)
1969 const accumulation_type df_i_dx_j =
1970 ADNumberTraits<ADNumberType>::get_directional_derivative(
1971 independent_variables[j],
1973 rad_accumulation[j];
1976 rad_accumulation[j] += df_i_dx_j;
1987 template <
typename ADNumberType,
typename ScalarType>
1991 typename std::enable_if<
1992 ADNumberTraits<ADNumberType>::type_code ==
1995 ADNumberTraits<ADNumberType>::type_code ==
1997 : dependent_variable_marking_safe(false)
2001 template <
typename ADNumberType,
typename ScalarType>
2006 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2008 ADNumberTraits<ADNumberType>::type_code ==
2010 ADNumberTraits<ADNumberType>::type_code ==
2012 initialize_global_environment(
const unsigned int n_independent_variables)
2014 internal::configure_tapeless_mode<ADNumberType>(n_independent_variables);
2018 template <
typename ADNumberType,
typename ScalarType>
2023 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2025 ADNumberTraits<ADNumberType>::type_code ==
2027 ADNumberTraits<ADNumberType>::type_code ==
2029 allow_dependent_variable_marking()
2031 dependent_variable_marking_safe =
true;
2035 template <
typename ADNumberType,
typename ScalarType>
2040 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2042 ADNumberTraits<ADNumberType>::type_code ==
2044 ADNumberTraits<ADNumberType>::type_code ==
2046 prevent_dependent_variable_marking()
2048 dependent_variable_marking_safe =
false;
2052 template <
typename ADNumberType,
typename ScalarType>
2057 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2059 ADNumberTraits<ADNumberType>::type_code ==
2061 ADNumberTraits<ADNumberType>::type_code ==
2063 is_dependent_variable_marking_allowed()
const 2065 return dependent_variable_marking_safe;
2069 template <
typename ADNumberType,
typename ScalarType>
2074 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2076 ADNumberTraits<ADNumberType>::type_code ==
2078 ADNumberTraits<ADNumberType>::type_code ==
2080 value(
const std::vector<ADNumberType> &dependent_variables)
const 2082 Assert(dependent_variables.size() == 1,
2084 return ADNumberTraits<ADNumberType>::get_scalar_value(
2085 dependent_variables[0]);
2089 template <
typename ADNumberType,
typename ScalarType>
2094 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2096 ADNumberTraits<ADNumberType>::type_code ==
2098 ADNumberTraits<ADNumberType>::type_code ==
2100 gradient(
const std::vector<ADNumberType> &independent_variables,
2101 const std::vector<ADNumberType> &dependent_variables,
2102 Vector<ScalarType> & gradient)
const 2104 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
2107 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
2109 Assert(dependent_variables.size() == 1,
2111 Assert(gradient.size() == independent_variables.size(),
2113 independent_variables.size()));
2117 const std::size_t n_independent_variables = independent_variables.size();
2118 for (
unsigned int i = 0; i < n_independent_variables; i++)
2120 ADNumberTraits<ADNumberType>::get_directional_derivative(
2121 dependent_variables[0], i));
2125 template <
typename ADNumberType,
typename ScalarType>
2130 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2132 ADNumberTraits<ADNumberType>::type_code ==
2134 ADNumberTraits<ADNumberType>::type_code ==
2136 hessian(
const std::vector<ADNumberType> &independent_variables,
2137 const std::vector<ADNumberType> &dependent_variables,
2140 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
2143 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
2145 Assert(dependent_variables.size() == 1,
2147 Assert(hessian.
m() == independent_variables.size(),
2149 Assert(hessian.
n() == independent_variables.size(),
2154 const std::size_t n_independent_variables = independent_variables.size();
2155 for (
unsigned int i = 0; i < n_independent_variables; i++)
2157 using derivative_type =
2158 typename ADNumberTraits<ADNumberType>::derivative_type;
2159 const derivative_type gradient_i =
2160 ADNumberTraits<ADNumberType>::get_directional_derivative(
2161 dependent_variables[0], i);
2163 for (
unsigned int j = 0; j <= i; ++j)
2168 const ScalarType hessian_ij =
2170 ADNumberTraits<derivative_type>::get_directional_derivative(
2172 hessian[i][j] = hessian_ij;
2174 hessian[j][i] = hessian_ij;
2180 template <
typename ADNumberType,
typename ScalarType>
2185 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2187 ADNumberTraits<ADNumberType>::type_code ==
2189 ADNumberTraits<ADNumberType>::type_code ==
2191 values(
const std::vector<ADNumberType> &dependent_variables,
2192 Vector<ScalarType> & values)
const 2194 Assert(values.size() == dependent_variables.size(),
2197 const std::size_t n_dependent_variables = dependent_variables.size();
2198 for (
unsigned int i = 0; i < n_dependent_variables; i++)
2199 values[i] = ADNumberTraits<ADNumberType>::get_scalar_value(
2200 dependent_variables[i]);
2204 template <
typename ADNumberType,
typename ScalarType>
2209 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2211 ADNumberTraits<ADNumberType>::type_code ==
2213 ADNumberTraits<ADNumberType>::type_code ==
2215 jacobian(
const std::vector<ADNumberType> &independent_variables,
2216 const std::vector<ADNumberType> &dependent_variables,
2219 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
2222 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
2224 Assert(jacobian.
m() == dependent_variables.size(),
2226 Assert(jacobian.
n() == independent_variables.size(),
2229 const std::size_t n_independent_variables = independent_variables.size();
2230 const std::size_t n_dependent_variables = dependent_variables.size();
2234 for (
unsigned int i = 0; i < n_dependent_variables; i++)
2235 for (
unsigned int j = 0; j < n_independent_variables; j++)
2237 ADNumberTraits<ADNumberType>::get_directional_derivative(
2238 dependent_variables[i], j));
2247 # include "ad_drivers.inst" 2248 # ifdef DEAL_II_WITH_ADOLC 2249 # include "ad_drivers.inst1" 2251 # ifdef DEAL_II_TRILINOS_WITH_SACADO 2252 # include "ad_drivers.inst2" 2256 DEAL_II_NAMESPACE_CLOSE
2259 #endif // defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO) void values(const typename Types< ADNumberType >::tape_index active_tape_index, const unsigned int n_dependent_variables, const std::vector< ScalarType > &independent_variables, Vector< ScalarType > &values) const
static ::ExceptionBase & ExcRequiresADNumberSpecialization()
static ::ExceptionBase & ExcSupportedDerivativeLevels(std::size_t arg1, std::size_t arg2)
Types< ADNumberType >::tape_index active_tape_index() const
std::enable_if<!(ADNumberTraits< ADNumberType >::type_code==NumberTypes::adolc_tapeless)>::type configure_tapeless_mode(const unsigned int)
static ::ExceptionBase & ExcRequiresADOLC()
ScalarType value(const typename Types< ADNumberType >::tape_index active_tape_index, const std::vector< ScalarType > &independent_variables) const
unsigned int tape_buffer_sizes
void activate_tape(const typename Types< ADNumberType >::tape_index tape_index)
#define AssertThrow(cond, exc)
void jacobian(const typename Types< ADNumberType >::tape_index active_tape_index, const unsigned int n_dependent_variables, const std::vector< ScalarType > &independent_variables, FullMatrix< ScalarType > &jacobian) const
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
void hessian(const typename Types< ADNumberType >::tape_index active_tape_index, const std::vector< ScalarType > &independent_variables, FullMatrix< ScalarType > &hessian) const
bool keep_independent_values() const
bool requires_retaping(const typename Types< ADNumberType >::tape_index tape_index) const
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void print_tape_stats(const typename Types< ADNumberType >::tape_index tape_index, std::ostream &stream) const
void start_taping(const typename Types< ADNumberType >::tape_index tape_index, const bool keep_independent_values)
bool is_recording() const
std::vector< typename Types< ADNumberType >::tape_index > get_registered_tape_indices() const
void set_tape_buffer_sizes(const typename Types< ADNumberType >::tape_buffer_sizes obufsize=64 *1024 *1024, const typename Types< ADNumberType >::tape_buffer_sizes lbufsize=64 *1024 *1024, const typename Types< ADNumberType >::tape_buffer_sizes vbufsize=64 *1024 *1024, const typename Types< ADNumberType >::tape_buffer_sizes tbufsize=64 *1024 *1024)
void print(std::ostream &stream) const
void gradient(const typename Types< ADNumberType >::tape_index active_tape_index, const std::vector< ScalarType > &independent_variables, Vector< ScalarType > &gradient) const
std::enable_if<!(ADNumberTraits< ADNumberType >::type_code==NumberTypes::sacado_rad||ADNumberTraits< ADNumberType >::type_code==NumberTypes::sacado_rad_dfad)>::type reverse_mode_dependent_variable_activation(ADNumberType &)
bool is_registered_tape(const typename Types< ADNumberType >::tape_index tape_index) const
void reset(const bool clear_registered_tapes)
AlignedVector< Number > values
void stop_taping(const typename Types< ADNumberType >::tape_index active_tape_index, const bool write_tapes_to_file)
bool last_action_requires_retaping() const
void remove_tape(const typename Types< ADNumberType >::tape_index tape_index)
static ::ExceptionBase & ExcInternalError()