18 #if defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)
33 # ifdef DEAL_II_WITH_ADOLC
36 # include <adolc/adolc_fatalerror.h>
37 # include <adolc/drivers/drivers.h>
38 # include <adolc/taping.h>
41 # endif // DEAL_II_WITH_ADOLC
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
262 template <
typename ADNumberType>
266 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
268 : active_tape(
Numbers<ADNumberType>::invalid_tape_index)
270 , is_recording_flag(false)
271 , use_stored_taped_buffer_sizes(false)
280 template <
typename ADNumberType>
285 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
286 NumberTypes::adolc_taped>::type>::is_recording()
289 return is_recording_flag;
293 template <
typename ADNumberType>
295 TapedDrivers<ADNumberType,
297 typename std::enable_if<
298 ADNumberTraits<ADNumberType>::type_code ==
299 NumberTypes::adolc_taped>::type>::active_tape_index()
const
305 template <
typename ADNumberType>
307 TapedDrivers<ADNumberType,
309 typename std::enable_if<
310 ADNumberTraits<ADNumberType>::type_code ==
311 NumberTypes::adolc_taped>::type>::keep_independent_values()
318 template <
typename ADNumberType>
323 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
324 NumberTypes::adolc_taped>::type>::
370 const std::vector<typename Types<ADNumberType>::tape_index>
371 registered_tape_indices = get_registered_tape_indices();
372 const auto it = std::find(registered_tape_indices.begin(),
373 registered_tape_indices.end(),
375 if (it == registered_tape_indices.end())
381 std::vector<std::size_t> counts(STAT_SIZE);
382 ::tapestats(tape_index, counts.data());
385 catch (const ::FatalError &exc)
392 template <
typename ADNumberType>
397 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
398 NumberTypes::adolc_taped>::type>::
399 set_tape_buffer_sizes(
407 obufsize = in_obufsize;
408 lbufsize = in_lbufsize;
409 vbufsize = in_vbufsize;
410 tbufsize = in_tbufsize;
411 use_stored_taped_buffer_sizes =
true;
415 template <
typename ADNumberType>
420 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
421 NumberTypes::adolc_taped>::type>::
423 const bool keep_independent_values)
425 if (use_stored_taped_buffer_sizes)
427 keep_independent_values,
433 trace_on(tape_index, keep_independent_values);
436 keep_values = keep_independent_values;
437 is_recording_flag =
true;
441 template <
typename ADNumberType>
446 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
447 NumberTypes::adolc_taped>::type>::
450 const bool write_tapes_to_file)
452 if (write_tapes_to_file)
453 trace_off(active_tape_index);
459 is_recording_flag =
false;
465 if (keep_independent_values() ==
false)
466 active_tape = Numbers<ADNumberType>::invalid_tape_index;
470 template <
typename ADNumberType>
471 std::vector<typename Types<ADNumberType>::tape_index>
475 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
476 NumberTypes::adolc_taped>::type>::
477 get_registered_tape_indices()
const
483 std::vector<short> registered_tape_indices_s;
484 cachedTraceTags(registered_tape_indices_s);
486 return std::vector<typename Types<ADNumberType>::tape_index>(
487 registered_tape_indices_s.begin(), registered_tape_indices_s.end());
491 template <
typename ADNumberType>
496 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
497 NumberTypes::adolc_taped>::type>::
500 active_tape = tape_index;
504 template <
typename ADNumberType>
509 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
510 NumberTypes::adolc_taped>::type>::
515 is_registered_tape(tape_index) ==
true,
517 "Cannot ask for the status of a tape that has not yet been recorded and used."));
519 const auto it_status_tape = status.find(tape_index);
531 if (it_status_tape == status.end())
534 const auto status_tape = it_status_tape->second;
539 status_tape < 4 && status_tape >= -2,
541 "The tape status is not within the range specified within the ADOL-C documentation."));
542 return (status_tape < 0);
546 template <
typename ADNumberType>
551 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
552 NumberTypes::adolc_taped>::type>::
553 last_action_requires_retaping()
const
555 return requires_retaping(active_tape);
559 template <
typename ADNumberType>
564 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
565 NumberTypes::adolc_taped>::type>::
568 Assert(is_registered_tape(tape_index),
570 "This tape does not exist, and therefore cannot be cleared."));
571 removeTape(tape_index, TapeRemovalType::ADOLC_REMOVE_COMPLETELY);
575 template <
typename ADNumberType>
580 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
581 NumberTypes::adolc_taped>::type>::
582 reset(
const bool clear_registered_tapes)
584 active_tape = Numbers<ADNumberType>::invalid_tape_index;
585 is_recording_flag =
false;
587 if (clear_registered_tapes)
589 const std::vector<typename Types<ADNumberType>::tape_index>
590 registered_tape_indices = get_registered_tape_indices();
591 for (
const auto &tape_index : registered_tape_indices)
592 remove_tape(tape_index);
597 template <
typename ADNumberType>
599 TapedDrivers<ADNumberType,
601 typename std::enable_if<
602 ADNumberTraits<ADNumberType>::type_code ==
603 NumberTypes::adolc_taped>::type>::print(std::ostream &stream)
606 const std::vector<typename Types<ADNumberType>::tape_index>
607 registered_tape_indices = get_registered_tape_indices();
608 stream <<
"Registered tapes and their status: ";
609 auto it_registered_tape = registered_tape_indices.begin();
610 for (
unsigned int i = 0; i < registered_tape_indices.size();
611 ++i, ++it_registered_tape)
613 const auto tape_index = *it_registered_tape;
614 const auto it_status_tape = status.find(tape_index);
615 Assert(it_status_tape != status.end(),
617 "This tape's status has not been found in the map."));
618 const auto status_tape = it_status_tape->second;
620 stream << tape_index <<
"->" << status_tape
621 << (i < (registered_tape_indices.size() - 1) ?
"," :
"");
625 stream <<
"Keep values? " << keep_independent_values() <<
"\n";
626 stream <<
"Use stored tape buffer sizes? "
627 << use_stored_taped_buffer_sizes <<
"\n";
631 template <
typename ADNumberType>
636 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
637 NumberTypes::adolc_taped>::type>::
640 std::ostream & stream)
const
644 std::vector<std::size_t> counts(STAT_SIZE);
645 ::tapestats(tape_index, counts.data());
648 <<
"Tape index: " << tape_index <<
"\n"
649 <<
"Number of independent variables: " << counts[0] <<
"\n"
650 <<
"Number of dependent variables: " << counts[1] <<
"\n"
651 <<
"Max number of live, active variables: " << counts[2] <<
"\n"
652 <<
"Size of taylor stack (number of overwrites): " << counts[3] <<
"\n"
653 <<
"Operations buffer size: " << counts[4] <<
"\n"
654 <<
"Total number of recorded operations: " << counts[5] <<
"\n"
655 <<
"Operations file written or not: " << counts[6] <<
"\n"
656 <<
"Overall number of locations: " << counts[7] <<
"\n"
657 <<
"Locations file written or not: " << counts[8] <<
"\n"
658 <<
"Overall number of values: " << counts[9] <<
"\n"
659 <<
"Values file written or not: " << counts[10] <<
"\n"
660 <<
"Locations buffer size: " << counts[11] <<
"\n"
661 <<
"Values buffer size: " << counts[12] <<
"\n"
662 <<
"Taylor buffer size: " << counts[13] <<
"\n"
663 <<
"Number of eq_*_prod for sparsity pattern: " << counts[14] <<
"\n"
664 <<
"Use of 'min_op', deferred to 'abs_op' for piecewise calculations: "
665 << counts[15] <<
"\n"
666 <<
"Number of 'abs' calls that can switch branch: " << counts[16]
668 <<
"Number of parameters (doubles) interchangeable without retaping: "
669 << counts[17] <<
"\n"
674 template <
typename ADNumberType>
675 typename TapedDrivers<
678 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
683 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
684 NumberTypes::adolc_taped>::type>
::
686 const std::vector<scalar_type> &independent_variables)
const
688 Assert(is_registered_tape(active_tape_index),
689 ExcMessage(
"This tape has not yet been recorded."));
693 status[active_tape_index] =
694 ::function(active_tape_index,
696 independent_variables.size(),
697 const_cast<double *
>(independent_variables.data()),
704 template <
typename ADNumberType>
709 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
710 NumberTypes::adolc_taped>::type>::
712 const std::vector<scalar_type> &independent_variables,
713 Vector<scalar_type> & gradient)
const
715 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
718 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
720 Assert(gradient.size() == independent_variables.size(),
722 independent_variables.size()));
723 Assert(is_registered_tape(active_tape_index),
724 ExcMessage(
"This tape has not yet been recorded."));
729 status[active_tape_index] =
730 ::gradient(active_tape_index,
731 independent_variables.size(),
732 const_cast<scalar_type *
>(independent_variables.data()),
737 template <
typename ADNumberType>
742 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
743 NumberTypes::adolc_taped>::type>::
745 const std::vector<scalar_type> &independent_variables,
748 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
751 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
753 Assert(hessian.
m() == independent_variables.size(),
755 Assert(hessian.
n() == independent_variables.size(),
757 Assert(is_registered_tape(active_tape_index),
758 ExcMessage(
"This tape has not yet been recorded."));
760 const unsigned int n_independent_variables = independent_variables.size();
761 std::vector<scalar_type *> H(n_independent_variables);
762 for (
unsigned int i = 0; i < n_independent_variables; ++i)
763 H[i] = &hessian[i][0];
765 status[active_tape_index] =
766 ::hessian(active_tape_index,
767 n_independent_variables,
768 const_cast<scalar_type *
>(independent_variables.data()),
774 for (
unsigned int i = 0; i < n_independent_variables; i++)
775 for (
unsigned int j = 0; j < i; j++)
776 hessian[j][i] = hessian[i][j];
780 template <
typename ADNumberType>
785 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
786 NumberTypes::adolc_taped>::type>::
788 const unsigned int n_dependent_variables,
789 const std::vector<scalar_type> &independent_variables,
790 Vector<scalar_type> & values)
const
792 Assert(values.size() == n_dependent_variables,
794 Assert(is_registered_tape(active_tape_index),
795 ExcMessage(
"This tape has not yet been recorded."));
800 status[active_tape_index] =
801 ::function(active_tape_index,
802 n_dependent_variables,
803 independent_variables.size(),
804 const_cast<scalar_type *
>(independent_variables.data()),
809 template <
typename ADNumberType>
814 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
815 NumberTypes::adolc_taped>::type>::
817 const unsigned int n_dependent_variables,
818 const std::vector<scalar_type> &independent_variables,
821 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
824 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
826 Assert(jacobian.
m() == n_dependent_variables,
828 Assert(jacobian.
n() == independent_variables.size(),
830 Assert(is_registered_tape(active_tape_index),
831 ExcMessage(
"This tape has not yet been recorded."));
833 std::vector<scalar_type *> J(n_dependent_variables);
834 for (
unsigned int i = 0; i < n_dependent_variables; ++i)
835 J[i] = &jacobian[i][0];
837 status[active_tape_index] = ::jacobian(active_tape_index,
838 n_dependent_variables,
839 independent_variables.size(),
840 independent_variables.data(),
848 template <
typename ADNumberType>
853 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
854 NumberTypes::adolc_taped>::type>::is_recording()
862 template <
typename ADNumberType>
864 TapedDrivers<ADNumberType,
866 typename std::enable_if<
867 ADNumberTraits<ADNumberType>::type_code ==
868 NumberTypes::adolc_taped>::type>::active_tape_index()
const
871 return Numbers<ADNumberType>::invalid_tape_index;
875 template <
typename ADNumberType>
877 TapedDrivers<ADNumberType,
879 typename std::enable_if<
880 ADNumberTraits<ADNumberType>::type_code ==
881 NumberTypes::adolc_taped>::type>::keep_independent_values()
889 template <
typename ADNumberType>
894 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
895 NumberTypes::adolc_taped>::type>::
903 template <
typename ADNumberType>
908 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
909 NumberTypes::adolc_taped>::type>::
910 set_tape_buffer_sizes(
920 template <
typename ADNumberType>
925 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
926 NumberTypes::adolc_taped>::type>::
933 template <
typename ADNumberType>
938 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
939 NumberTypes::adolc_taped>::type>::
946 template <
typename ADNumberType>
947 std::vector<typename Types<ADNumberType>::tape_index>
951 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
952 NumberTypes::adolc_taped>::type>::
953 get_registered_tape_indices()
const
956 return std::vector<typename Types<ADNumberType>::tape_index>();
960 template <
typename ADNumberType>
965 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
966 NumberTypes::adolc_taped>::type>::
973 template <
typename ADNumberType>
978 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
979 NumberTypes::adolc_taped>::type>::
987 template <
typename ADNumberType>
992 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
993 NumberTypes::adolc_taped>::type>::
994 last_action_requires_retaping()
const
1001 template <
typename ADNumberType>
1006 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1007 NumberTypes::adolc_taped>::type>::
1014 template <
typename ADNumberType>
1016 TapedDrivers<ADNumberType,
1018 typename std::enable_if<
1019 ADNumberTraits<ADNumberType>::type_code ==
1020 NumberTypes::adolc_taped>::type>::reset(
const bool)
1026 template <
typename ADNumberType>
1028 TapedDrivers<ADNumberType,
1030 typename std::enable_if<
1031 ADNumberTraits<ADNumberType>::type_code ==
1032 NumberTypes::adolc_taped>::type>::print(std::ostream &)
const
1038 template <
typename ADNumberType>
1043 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1044 NumberTypes::adolc_taped>::type>::
1046 std::ostream &)
const
1052 template <
typename ADNumberType>
1053 typename TapedDrivers<
1056 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1061 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1062 NumberTypes::adolc_taped>::type>
::
1064 const std::vector<scalar_type> &)
const
1071 template <
typename ADNumberType>
1076 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1077 NumberTypes::adolc_taped>::type>::
1079 const std::vector<scalar_type> &,
1080 Vector<scalar_type> &)
const
1086 template <
typename ADNumberType>
1091 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1092 NumberTypes::adolc_taped>::type>::
1094 const std::vector<scalar_type> &,
1101 template <
typename ADNumberType>
1106 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1107 NumberTypes::adolc_taped>::type>::
1110 const std::vector<scalar_type> &,
1111 Vector<scalar_type> &)
const
1117 template <
typename ADNumberType>
1122 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1123 NumberTypes::adolc_taped>::type>::
1126 const std::vector<scalar_type> &,
1132 # endif // DEAL_II_WITH_ADOLC
1138 template <
typename ADNumberType>
1143 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1144 NumberTypes::adolc_taped>::type>::is_recording()
1149 return taped_driver.is_recording();
1153 template <
typename ADNumberType>
1155 TapedDrivers<ADNumberType,
1157 typename std::enable_if<
1158 ADNumberTraits<ADNumberType>::type_code ==
1159 NumberTypes::adolc_taped>::type>::active_tape_index()
const
1163 return taped_driver.active_tape_index();
1167 template <
typename ADNumberType>
1169 TapedDrivers<ADNumberType,
1171 typename std::enable_if<
1172 ADNumberTraits<ADNumberType>::type_code ==
1173 NumberTypes::adolc_taped>::type>::keep_independent_values()
1176 return taped_driver.keep_independent_values();
1180 template <
typename ADNumberType>
1185 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1186 NumberTypes::adolc_taped>::type>::
1192 return taped_driver.is_registered_tape(tape_index);
1196 template <
typename ADNumberType>
1201 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1202 NumberTypes::adolc_taped>::type>::
1203 set_tape_buffer_sizes(
1211 taped_driver.set_tape_buffer_sizes(obufsize,
1218 template <
typename ADNumberType>
1223 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1224 NumberTypes::adolc_taped>::type>::
1226 const bool keep_independent_values)
1230 taped_driver.start_taping(tape_index, keep_independent_values);
1234 template <
typename ADNumberType>
1239 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1240 NumberTypes::adolc_taped>::type>::
1243 const bool write_tapes_to_file)
1247 taped_driver.stop_taping(active_tape_index, write_tapes_to_file);
1251 template <
typename ADNumberType>
1252 std::vector<typename Types<ADNumberType>::tape_index>
1256 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1257 NumberTypes::adolc_taped>::type>::
1258 get_registered_tape_indices()
const
1260 return taped_driver.get_registered_tape_indices();
1264 template <
typename ADNumberType>
1269 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1270 NumberTypes::adolc_taped>::type>::
1273 taped_driver.activate_tape(tape_index);
1277 template <
typename ADNumberType>
1282 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1283 NumberTypes::adolc_taped>::type>::
1287 return taped_driver.requires_retaping(tape_index);
1291 template <
typename ADNumberType>
1296 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1297 NumberTypes::adolc_taped>::type>::
1298 last_action_requires_retaping()
const
1300 return taped_driver.last_action_requires_retaping();
1304 template <
typename ADNumberType>
1309 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1310 NumberTypes::adolc_taped>::type>::
1313 taped_driver.remove_tape(tape_index);
1317 template <
typename ADNumberType>
1322 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1323 NumberTypes::adolc_taped>::type>::
1324 reset(
const bool clear_registered_tapes)
1326 taped_driver.reset(clear_registered_tapes);
1330 template <
typename ADNumberType>
1332 TapedDrivers<ADNumberType,
1334 typename std::enable_if<
1335 ADNumberTraits<ADNumberType>::type_code ==
1336 NumberTypes::adolc_taped>::type>::print(std::ostream &stream)
1339 taped_driver.print(stream);
1343 template <
typename ADNumberType>
1348 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1349 NumberTypes::adolc_taped>::type>::
1352 std::ostream & stream)
const
1356 taped_driver.print_tape_stats(tape_index, stream);
1360 template <
typename ADNumberType>
1361 typename TapedDrivers<
1364 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1369 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1370 NumberTypes::adolc_taped>::type>
::
1372 const std::vector<scalar_type> &independent_variables)
const
1376 return taped_driver.value(active_tape_index,
1377 vector_float_to_double(independent_variables));
1381 template <
typename ADNumberType>
1386 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1387 NumberTypes::adolc_taped>::type>::
1389 const std::vector<scalar_type> &independent_variables,
1390 Vector<scalar_type> & gradient)
const
1395 taped_driver.gradient(active_tape_index,
1396 vector_float_to_double(independent_variables),
1398 gradient = gradient_double;
1402 template <
typename ADNumberType>
1407 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1408 NumberTypes::adolc_taped>::type>::
1410 const std::vector<scalar_type> &independent_variables,
1416 taped_driver.hessian(active_tape_index,
1417 vector_float_to_double(independent_variables),
1419 hessian = hessian_double;
1423 template <
typename ADNumberType>
1428 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1429 NumberTypes::adolc_taped>::type>::
1431 const unsigned int n_dependent_variables,
1432 const std::vector<scalar_type> &independent_variables,
1433 Vector<scalar_type> & values)
const
1438 taped_driver.values(active_tape_index,
1439 n_dependent_variables,
1440 vector_float_to_double(independent_variables),
1442 values = values_double;
1446 template <
typename ADNumberType>
1451 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1452 NumberTypes::adolc_taped>::type>::
1454 const unsigned int n_dependent_variables,
1455 const std::vector<scalar_type> &independent_variables,
1461 taped_driver.jacobian(active_tape_index,
1462 n_dependent_variables,
1463 vector_float_to_double(independent_variables),
1465 jacobian = jacobian_double;
1470 template <
typename ADNumberType>
1475 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1476 NumberTypes::adolc_taped>::type>::
1477 vector_float_to_double(
const std::vector<float> &in)
const
1479 std::vector<double> out(in.size());
1480 std::copy(in.begin(), in.end(), out.begin());
1489 template <
typename ADNumberType,
typename ScalarType,
typename T>
1497 template <
typename ADNumberType,
typename ScalarType,
typename T>
1505 template <
typename ADNumberType,
typename ScalarType,
typename T>
1513 template <
typename ADNumberType,
typename ScalarType,
typename T>
1523 template <
typename ADNumberType,
typename ScalarType,
typename T>
1526 const std::vector<ADNumberType> &)
const
1529 return ScalarType(0.0);
1533 template <
typename ADNumberType,
typename ScalarType,
typename T>
1536 const std::vector<ADNumberType> &,
1537 const std::vector<ADNumberType> &,
1538 Vector<ScalarType> &)
const
1544 template <
typename ADNumberType,
typename ScalarType,
typename T>
1547 const std::vector<ADNumberType> &,
1548 const std::vector<ADNumberType> &,
1555 template <
typename ADNumberType,
typename ScalarType,
typename T>
1558 const std::vector<ADNumberType> &,
1559 Vector<ScalarType> &)
const
1565 template <
typename ADNumberType,
typename ScalarType,
typename T>
1568 const std::vector<ADNumberType> &,
1569 const std::vector<ADNumberType> &,
1582 template <
typename ADNumberType>
1584 NumberTypes::sacado_rad ||
1586 NumberTypes::sacado_rad_dfad)>::type
1590 # ifdef DEAL_II_TRILINOS_WITH_SACADO
1601 template <
typename ADNumberType>
1602 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1603 NumberTypes::sacado_rad ||
1605 NumberTypes::sacado_rad_dfad>::type
1607 ADNumberType &dependent_variable)
1617 ADNumberType::Outvar_Gradcomp(dependent_variable);
1627 template <
typename ADNumberType>
1629 NumberTypes::adolc_tapeless)>::type
1634 # ifdef DEAL_II_WITH_ADOLC
1644 template <
typename ADNumberType>
1645 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1646 NumberTypes::adolc_tapeless>::type
1649 # ifdef DEAL_II_ADOLC_WITH_TAPELESS_REFCOUNTING
1664 const std::size_t n_live_variables = adtl::refcounter::getNumLiveVar();
1665 if (n_live_variables == 0)
1667 adtl::setNumDir(n_directional_derivatives);
1676 const std::size_t n_set_directional_derivatives = adtl::getNumDir();
1677 if (n_directional_derivatives > n_set_directional_derivatives)
1679 n_live_variables == 0,
1683 "adtl::adouble variables in existence. They currently "
1686 " directional derivatives "
1687 "but you wish to increase this to " +
1690 "To safely change (or more specifically in this case, "
1691 "increase) the number of directional derivatives, there "
1692 "must be no tapeless doubles in local/global scope."));
1698 adtl::setNumDir(n_directional_derivatives);
1702 # else // DEAL_II_WITH_ADOLC
1704 template <
typename ADNumberType>
1705 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1706 NumberTypes::adolc_tapeless>::type
1723 template <
typename ADNumberType,
typename ScalarType>
1727 typename std::enable_if<
1728 ADNumberTraits<ADNumberType>::type_code == NumberTypes::sacado_rad ||
1729 ADNumberTraits<ADNumberType>::type_code ==
1730 NumberTypes::sacado_rad_dfad>::type>::TapelessDrivers()
1731 : dependent_variable_marking_safe(false)
1736 template <
typename ADNumberType,
typename ScalarType>
1741 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1743 ADNumberTraits<ADNumberType>::type_code ==
1745 initialize_global_environment(
const unsigned int n_independent_variables)
1747 internal::configure_tapeless_mode<ADNumberType>(n_independent_variables);
1751 template <
typename ADNumberType,
typename ScalarType>
1756 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1758 ADNumberTraits<ADNumberType>::type_code ==
1760 allow_dependent_variable_marking()
1762 dependent_variable_marking_safe =
true;
1766 template <
typename ADNumberType,
typename ScalarType>
1771 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1773 ADNumberTraits<ADNumberType>::type_code ==
1775 prevent_dependent_variable_marking()
1777 dependent_variable_marking_safe =
false;
1781 template <
typename ADNumberType,
typename ScalarType>
1786 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1788 ADNumberTraits<ADNumberType>::type_code ==
1790 is_dependent_variable_marking_allowed()
const
1792 return dependent_variable_marking_safe;
1796 template <
typename ADNumberType,
typename ScalarType>
1801 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1803 ADNumberTraits<ADNumberType>::type_code ==
1805 value(
const std::vector<ADNumberType> &dependent_variables)
const
1807 Assert(dependent_variables.size() == 1,
1809 return ADNumberTraits<ADNumberType>::get_scalar_value(
1810 dependent_variables[0]);
1814 template <
typename ADNumberType,
typename ScalarType>
1819 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1821 ADNumberTraits<ADNumberType>::type_code ==
1823 gradient(
const std::vector<ADNumberType> &independent_variables,
1824 const std::vector<ADNumberType> &dependent_variables,
1825 Vector<ScalarType> & gradient)
const
1827 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
1830 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
1832 Assert(dependent_variables.size() == 1,
1834 Assert(gradient.size() == independent_variables.size(),
1836 independent_variables.size()));
1841 const_cast<ADNumberType &
>(dependent_variables[0]));
1842 const std::size_t n_independent_variables = independent_variables.size();
1843 for (
unsigned int i = 0; i < n_independent_variables; i++)
1845 ADNumberTraits<ADNumberType>::get_directional_derivative(
1846 independent_variables[i], 0 ));
1850 template <
typename ADNumberType,
typename ScalarType>
1855 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1857 ADNumberTraits<ADNumberType>::type_code ==
1859 hessian(
const std::vector<ADNumberType> &independent_variables,
1860 const std::vector<ADNumberType> &dependent_variables,
1863 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
1866 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
1868 Assert(dependent_variables.size() == 1,
1870 Assert(hessian.
m() == independent_variables.size(),
1872 Assert(hessian.
n() == independent_variables.size(),
1878 const_cast<ADNumberType &
>(dependent_variables[0]));
1879 const std::size_t n_independent_variables = independent_variables.size();
1880 for (
unsigned int i = 0; i < n_independent_variables; i++)
1882 using derivative_type =
1883 typename ADNumberTraits<ADNumberType>::derivative_type;
1884 const derivative_type gradient_i =
1885 ADNumberTraits<ADNumberType>::get_directional_derivative(
1886 independent_variables[i], i);
1888 for (
unsigned int j = 0; j <= i; ++j)
1893 const ScalarType hessian_ij =
1895 ADNumberTraits<derivative_type>::get_directional_derivative(
1897 hessian[i][j] = hessian_ij;
1899 hessian[j][i] = hessian_ij;
1905 template <
typename ADNumberType,
typename ScalarType>
1910 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1912 ADNumberTraits<ADNumberType>::type_code ==
1914 values(
const std::vector<ADNumberType> &dependent_variables,
1915 Vector<ScalarType> & values)
const
1917 Assert(values.size() == dependent_variables.size(),
1920 const std::size_t n_dependent_variables = dependent_variables.size();
1921 for (
unsigned int i = 0; i < n_dependent_variables; i++)
1922 values[i] = ADNumberTraits<ADNumberType>::get_scalar_value(
1923 dependent_variables[i]);
1927 template <
typename ADNumberType,
typename ScalarType>
1932 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
1934 ADNumberTraits<ADNumberType>::type_code ==
1936 jacobian(
const std::vector<ADNumberType> &independent_variables,
1937 const std::vector<ADNumberType> &dependent_variables,
1940 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
1943 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
1945 Assert(jacobian.
m() == dependent_variables.size(),
1947 Assert(jacobian.
n() == independent_variables.size(),
1950 const std::size_t n_independent_variables = independent_variables.size();
1951 const std::size_t n_dependent_variables = dependent_variables.size();
1962 using accumulation_type =
1963 typename ADNumberTraits<ADNumberType>::derivative_type;
1964 std::vector<accumulation_type> rad_accumulation(
1965 n_independent_variables,
1968 for (
unsigned int i = 0; i < n_dependent_variables; i++)
1971 const_cast<ADNumberType &
>(dependent_variables[i]));
1972 for (
unsigned int j = 0; j < n_independent_variables; j++)
1974 const accumulation_type df_i_dx_j =
1975 ADNumberTraits<ADNumberType>::get_directional_derivative(
1976 independent_variables[j],
1978 rad_accumulation[j];
1981 rad_accumulation[j] += df_i_dx_j;
1993 template <
typename ADNumberType,
typename ScalarType>
1997 typename std::enable_if<
1998 ADNumberTraits<ADNumberType>::type_code ==
2001 ADNumberTraits<ADNumberType>::type_code ==
2003 : dependent_variable_marking_safe(false)
2008 template <
typename ADNumberType,
typename ScalarType>
2013 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2015 ADNumberTraits<ADNumberType>::type_code ==
2017 ADNumberTraits<ADNumberType>::type_code ==
2019 initialize_global_environment(
const unsigned int n_independent_variables)
2021 internal::configure_tapeless_mode<ADNumberType>(n_independent_variables);
2025 template <
typename ADNumberType,
typename ScalarType>
2030 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2032 ADNumberTraits<ADNumberType>::type_code ==
2034 ADNumberTraits<ADNumberType>::type_code ==
2036 allow_dependent_variable_marking()
2038 dependent_variable_marking_safe =
true;
2042 template <
typename ADNumberType,
typename ScalarType>
2047 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2049 ADNumberTraits<ADNumberType>::type_code ==
2051 ADNumberTraits<ADNumberType>::type_code ==
2053 prevent_dependent_variable_marking()
2055 dependent_variable_marking_safe =
false;
2059 template <
typename ADNumberType,
typename ScalarType>
2064 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2066 ADNumberTraits<ADNumberType>::type_code ==
2068 ADNumberTraits<ADNumberType>::type_code ==
2070 is_dependent_variable_marking_allowed()
const
2072 return dependent_variable_marking_safe;
2076 template <
typename ADNumberType,
typename ScalarType>
2081 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2083 ADNumberTraits<ADNumberType>::type_code ==
2085 ADNumberTraits<ADNumberType>::type_code ==
2087 value(
const std::vector<ADNumberType> &dependent_variables)
const
2089 Assert(dependent_variables.size() == 1,
2091 return ADNumberTraits<ADNumberType>::get_scalar_value(
2092 dependent_variables[0]);
2096 template <
typename ADNumberType,
typename ScalarType>
2101 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2103 ADNumberTraits<ADNumberType>::type_code ==
2105 ADNumberTraits<ADNumberType>::type_code ==
2107 gradient(
const std::vector<ADNumberType> &independent_variables,
2108 const std::vector<ADNumberType> &dependent_variables,
2109 Vector<ScalarType> & gradient)
const
2111 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
2114 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
2116 Assert(dependent_variables.size() == 1,
2118 Assert(gradient.size() == independent_variables.size(),
2120 independent_variables.size()));
2124 const std::size_t n_independent_variables = independent_variables.size();
2125 for (
unsigned int i = 0; i < n_independent_variables; i++)
2127 ADNumberTraits<ADNumberType>::get_directional_derivative(
2128 dependent_variables[0], i));
2132 template <
typename ADNumberType,
typename ScalarType>
2137 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2139 ADNumberTraits<ADNumberType>::type_code ==
2141 ADNumberTraits<ADNumberType>::type_code ==
2143 hessian(
const std::vector<ADNumberType> &independent_variables,
2144 const std::vector<ADNumberType> &dependent_variables,
2147 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
2150 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
2152 Assert(dependent_variables.size() == 1,
2154 Assert(hessian.
m() == independent_variables.size(),
2156 Assert(hessian.
n() == independent_variables.size(),
2161 const std::size_t n_independent_variables = independent_variables.size();
2162 for (
unsigned int i = 0; i < n_independent_variables; i++)
2164 using derivative_type =
2165 typename ADNumberTraits<ADNumberType>::derivative_type;
2166 const derivative_type gradient_i =
2167 ADNumberTraits<ADNumberType>::get_directional_derivative(
2168 dependent_variables[0], i);
2170 for (
unsigned int j = 0; j <= i; ++j)
2175 const ScalarType hessian_ij =
2177 ADNumberTraits<derivative_type>::get_directional_derivative(
2179 hessian[i][j] = hessian_ij;
2181 hessian[j][i] = hessian_ij;
2187 template <
typename ADNumberType,
typename ScalarType>
2192 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2194 ADNumberTraits<ADNumberType>::type_code ==
2196 ADNumberTraits<ADNumberType>::type_code ==
2198 values(
const std::vector<ADNumberType> &dependent_variables,
2199 Vector<ScalarType> & values)
const
2201 Assert(values.size() == dependent_variables.size(),
2204 const std::size_t n_dependent_variables = dependent_variables.size();
2205 for (
unsigned int i = 0; i < n_dependent_variables; i++)
2206 values[i] = ADNumberTraits<ADNumberType>::get_scalar_value(
2207 dependent_variables[i]);
2211 template <
typename ADNumberType,
typename ScalarType>
2216 typename std::enable_if<ADNumberTraits<ADNumberType>::type_code ==
2218 ADNumberTraits<ADNumberType>::type_code ==
2220 ADNumberTraits<ADNumberType>::type_code ==
2222 jacobian(
const std::vector<ADNumberType> &independent_variables,
2223 const std::vector<ADNumberType> &dependent_variables,
2226 Assert(AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels >=
2229 AD::ADNumberTraits<ADNumberType>::n_supported_derivative_levels,
2231 Assert(jacobian.
m() == dependent_variables.size(),
2233 Assert(jacobian.
n() == independent_variables.size(),
2236 const std::size_t n_independent_variables = independent_variables.size();
2237 const std::size_t n_dependent_variables = dependent_variables.size();
2241 for (
unsigned int i = 0; i < n_dependent_variables; i++)
2242 for (
unsigned int j = 0; j < n_independent_variables; j++)
2244 ADNumberTraits<ADNumberType>::get_directional_derivative(
2245 dependent_variables[i], j));
2254 # include "ad_drivers.inst"
2255 # ifdef DEAL_II_WITH_ADOLC
2256 # include "ad_drivers.inst1"
2258 # ifdef DEAL_II_TRILINOS_WITH_SACADO
2259 # include "ad_drivers.inst2"
2266 #endif // defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)