15#if defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)
20# include <type_traits>
28#if defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)
39 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
41 const unsigned int n_independent_variables,
42 const unsigned int n_dependent_variables)
43 : independent_variable_values(
44 n_independent_variables,
46 , registered_independent_variable_values(n_independent_variables, false)
47 , registered_marked_independent_variables(n_independent_variables, false)
48 , registered_marked_dependent_variables(n_dependent_variables, false)
57 "Floating point/arithmetic numbers have no derivatives."));
61 "The AD number type does not support the calculation of any derivatives."));
81 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
84 ScalarType>::reset_registered_independent_variables()
86 std::fill(registered_independent_variable_values.begin(),
87 registered_independent_variable_values.end(),
93 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
98 std::fill(registered_marked_dependent_variables.begin(),
99 registered_marked_dependent_variables.end(),
105 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
108 const unsigned int index,
116 if (this->is_recording() ==
false)
117 start_recording_operations(1 );
119 Assert(this->is_recording() ==
true,
121 "Cannot change the value of an independent variable "
122 "of the tapeless variety while this class is not set "
123 "in recording operations."));
127 Assert(this->active_tape_index() !=
132 index < n_independent_variables(),
134 "Trying to set the value of a non-existent independent variable."));
136 independent_variable_values[index] = value;
137 registered_independent_variable_values[index] =
true;
142 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
145 const unsigned int index,
149 Assert(registered_independent_variable_values[index] ==
true,
155 registered_marked_independent_variables[index - 1] ==
true,
157 "Need to extract sensitivities in the order they're created."));
164 Assert(is_recording() ==
true,
166 "The marking of independent variables is only valid "
167 "during recording."));
171 independent_variable_values[index],
173 this->n_independent_variables(),
175 registered_marked_independent_variables[index] =
true;
180 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
183 ScalarType>::finalize_sensitive_independent_variables()
const
186 Assert(n_registered_independent_variables() == n_independent_variables(),
187 ExcMessage(
"Not all values of sensitivities have been recorded!"));
190 if (this->independent_variables.empty())
192 this->independent_variables.resize(
193 this->n_independent_variables(),
197 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
198 this->mark_independent_variable(i, this->independent_variables[i]);
204 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
215 Assert(is_recording() ==
false,
217 "The initialization of non-sensitive independent variables is "
218 "only valid outside of recording operations."));
221 Assert(registered_independent_variable_values[index] ==
true,
224 out = independent_variable_values[index];
229 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
232 ScalarType>::n_registered_independent_variables()
const
234 return std::count(registered_independent_variable_values.begin(),
235 registered_independent_variable_values.end(),
241 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
245 return independent_variable_values.size();
250 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
255 return std::count(registered_marked_dependent_variables.begin(),
256 registered_marked_dependent_variables.end(),
262 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
266 return dependent_variables.size();
271 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
276 return taped_driver.is_recording();
278 return tapeless_driver.is_dependent_variable_marking_allowed();
283 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
289 return taped_driver.active_tape_index();
296 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
302 return taped_driver.is_registered_tape(tape_index);
309 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
314 const std::ios_base::fmtflags stream_flags(stream.flags());
316 stream.setf(std::ios_base::boolalpha);
318 stream <<
"Active tape index: " << active_tape_index() <<
'\n';
319 stream <<
"Recording? " << is_recording() <<
'\n';
320 stream << std::flush;
323 taped_driver.print(stream);
325 stream <<
"Registered independent variables: " <<
'\n';
326 for (
unsigned int i = 0; i < n_independent_variables(); ++i)
327 stream << registered_independent_variable_values[i]
328 << (i < (n_independent_variables() - 1) ?
"," :
"");
331 stream <<
"Independent variable values: " <<
'\n';
332 print_values(stream);
334 stream <<
"Registered marked independent variables: " <<
'\n';
335 for (
unsigned int i = 0; i < n_independent_variables(); ++i)
336 stream << registered_marked_independent_variables[i]
337 << (i < (n_independent_variables() - 1) ?
"," :
"")
341 stream <<
"Dependent variable values: " <<
'\n';
342 for (
unsigned int i = 0; i < n_dependent_variables(); ++i)
343 stream << dependent_variables[i]
344 << (i < (n_dependent_variables() - 1) ?
"," :
"");
347 stream <<
"Registered dependent variables: " <<
'\n';
348 for (
unsigned int i = 0; i < n_dependent_variables(); ++i)
349 stream << registered_marked_dependent_variables[i]
350 << (i < (n_dependent_variables() - 1) ?
"," :
"");
354 stream.flags(stream_flags);
359 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
362 std::ostream &stream)
const
364 for (
unsigned int i = 0; i < n_independent_variables(); ++i)
365 stream << independent_variable_values[i]
366 << (i < (n_independent_variables() - 1) ?
"," :
"")
373 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
377 std::ostream &stream)
const
382 Assert(is_registered_tape(tape_index),
385 this->taped_driver.print_tape_stats(tape_index, stream);
390 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
393 const unsigned int n_independent_variables,
394 const unsigned int n_dependent_variables,
395 const bool clear_registered_tapes)
397 const unsigned int new_n_independent_variables =
399 n_independent_variables :
400 this->n_independent_variables());
401 const unsigned int new_n_dependent_variables =
403 n_dependent_variables :
404 this->n_dependent_variables());
418 std::vector<ad_type>().swap(independent_variables);
419 std::vector<ad_type>().swap(dependent_variables);
426 configure_tapeless_mode(new_n_independent_variables,
430 taped_driver.reset(clear_registered_tapes);
432 independent_variable_values = std::vector<scalar_type>(
433 new_n_independent_variables,
435 registered_independent_variable_values =
436 std::vector<bool>(new_n_independent_variables,
false);
437 registered_marked_independent_variables =
438 std::vector<bool>(new_n_independent_variables,
false);
439 dependent_variables =
440 std::vector<ad_type>(new_n_dependent_variables,
442 registered_marked_dependent_variables =
443 std::vector<bool>(new_n_dependent_variables,
false);
448 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
451 const unsigned int n_independent_variables,
452 const bool ensure_persistent_setting)
459 n_independent_variables);
461 if (ensure_persistent_setting ==
true)
474 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
479 activate_tape(tape_index,
true );
484 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
492 return taped_driver.requires_retaping(tape_index);
497 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
505 return taped_driver.last_action_requires_retaping();
510 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
517 taped_driver.remove_tape(taped_driver.active_tape_index());
522 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
526 const bool read_mode)
533 ExcMessage(
"Tape index exceeds maximum allowable value"));
534 taped_driver.activate_tape(tape_index);
535 reset_registered_independent_variables();
540 if (read_mode ==
true)
542 Assert(is_registered_tape(tape_index),
544 reset_registered_dependent_variables(
true);
545 Assert(n_registered_dependent_variables() ==
546 n_dependent_variables(),
547 ExcMessage(
"Not all dependent variables have been set!"));
559 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
570 taped_driver.set_tape_buffer_sizes(obufsize,
578 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
582 const bool overwrite_tape,
583 const bool keep_independent_values)
586 const bool read_mode =
false;
590 if (overwrite_tape !=
true)
592 Assert(is_recording() ==
false,
597 if (is_registered_tape(tape_index) ==
false || overwrite_tape ==
true)
601 activate_tape(tape_index, read_mode);
604 taped_driver.start_taping(active_tape_index(),
605 keep_independent_values);
609 reset_registered_independent_variables();
610 reset_registered_dependent_variables();
614 Assert(is_recording() ==
false,
616 "Tape recording is unexpectedly still enabled."));
620 activate_recorded_tape(tape_index);
625 Assert(ADNumberTraits<ad_type>::is_tapeless ==
true,
630 tapeless_driver.allow_dependent_variable_marking();
635 activate_tape(tape_index, read_mode);
638 return is_recording();
643 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
646 const bool write_tapes_to_file)
651 Assert(n_registered_independent_variables() == n_independent_variables(),
652 ExcMessage(
"Not all values of sensitivities have been recorded!"));
657 taped_driver.stop_taping(active_tape_index(), write_tapes_to_file);
664 Assert(n_registered_dependent_variables() == n_dependent_variables(),
673 tapeless_driver.prevent_dependent_variable_marking();
679 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
682 const unsigned int index,
686 Assert(registered_marked_dependent_variables[index] ==
false,
688 "This dependent variable has already been registered."));
694 Assert(is_recording() ==
true,
696 "Must be recording when registering dependent variables."));
702 registered_marked_dependent_variables[index] =
true;
711 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
713 const unsigned int n_independent_variables,
714 const unsigned int n_dependent_variables)
715 :
HelperBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
716 n_dependent_variables)
721 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
724 const std::vector<scalar_type> &dof_values)
730 Assert(dof_values.size() == this->n_independent_variables(),
732 "Vector size does not match number of independent variables"));
733 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
735 Assert(this->registered_independent_variable_values[i] ==
false,
736 ExcMessage(
"Independent variable value already registered."));
738 set_dof_values(dof_values);
743 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
751 Assert(this->active_tape_index() !=
758 this->finalize_sensitive_independent_variables();
759 Assert(this->independent_variables.size() ==
760 this->n_independent_variables(),
762 this->n_independent_variables()));
764 return this->independent_variables;
769 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
772 const std::vector<scalar_type> &values)
776 Assert(this->active_tape_index() !=
780 Assert(values.size() == this->n_independent_variables(),
782 "Vector size does not match number of independent variables"));
783 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
794 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
796 const unsigned int n_independent_variables)
797 :
CellLevelBase<ADNumberTypeCode, ScalarType>(n_independent_variables, 1)
802 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
814 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
819 this->taped_driver.keep_independent_values() ==
false) ||
823 this->n_registered_independent_variables() ==
824 this->n_independent_variables(),
826 "Not all values of sensitivities have been registered or subsequently set!"));
828 Assert(this->n_registered_dependent_variables() ==
829 this->n_dependent_variables(),
830 ExcMessage(
"Not all dependent variables have been registered."));
833 this->n_dependent_variables() == 1,
835 "The EnergyFunctional class expects there to be only one dependent variable."));
839 Assert(this->active_tape_index() !=
842 Assert(this->is_recording() ==
false,
844 "Cannot compute value while tape is being recorded."));
845 Assert(this->independent_variable_values.size() ==
846 this->n_independent_variables(),
848 this->n_independent_variables()));
850 return this->taped_driver.value(this->active_tape_index(),
851 this->independent_variable_values);
857 Assert(this->independent_variables.size() ==
858 this->n_independent_variables(),
860 this->n_independent_variables()));
862 return this->tapeless_driver.value(this->dependent_variables);
868 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
874 this->taped_driver.keep_independent_values() ==
false) ||
878 this->n_registered_independent_variables() ==
879 this->n_independent_variables(),
881 "Not all values of sensitivities have been registered or subsequently set!"));
883 Assert(this->n_registered_dependent_variables() ==
884 this->n_dependent_variables(),
885 ExcMessage(
"Not all dependent variables have been registered."));
888 this->n_dependent_variables() == 1,
890 "The EnergyFunctional class expects there to be only one dependent variable."));
895 if (gradient.size() != this->n_independent_variables())
896 gradient.reinit(this->n_independent_variables(),
901 Assert(this->active_tape_index() !=
906 "Cannot compute gradient while tape is being recorded."));
907 Assert(this->independent_variable_values.size() ==
908 this->n_independent_variables(),
910 this->n_independent_variables()));
912 this->taped_driver.gradient(this->active_tape_index(),
913 this->independent_variable_values,
920 Assert(this->independent_variables.size() ==
921 this->n_independent_variables(),
923 this->n_independent_variables()));
925 this->tapeless_driver.gradient(this->independent_variables,
926 this->dependent_variables,
933 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
940 "Cannot computed function Hessian: AD number type does "
941 "not support the calculation of second order derivatives."));
944 this->taped_driver.keep_independent_values() ==
false))
947 this->n_registered_independent_variables() ==
948 this->n_independent_variables(),
950 "Not all values of sensitivities have been registered or subsequently set!"));
952 Assert(this->n_registered_dependent_variables() ==
953 this->n_dependent_variables(),
954 ExcMessage(
"Not all dependent variables have been registered."));
957 this->n_dependent_variables() == 1,
959 "The EnergyFunctional class expects there to be only one dependent variable."));
964 if (hessian.m() != this->n_independent_variables() ||
965 hessian.n() != this->n_independent_variables())
966 hessian.reinit({this->n_independent_variables(),
967 this->n_independent_variables()},
970 if (ADNumberTraits<ad_type>::is_taped ==
true)
972 Assert(this->active_tape_index() !=
975 Assert(this->is_recording() ==
false,
977 "Cannot compute hessian while tape is being recorded."));
978 Assert(this->independent_variable_values.size() ==
979 this->n_independent_variables(),
981 this->n_independent_variables()));
983 this->taped_driver.hessian(this->active_tape_index(),
984 this->independent_variable_values,
991 Assert(this->independent_variables.size() ==
992 this->n_independent_variables(),
994 this->n_independent_variables()));
996 this->tapeless_driver.hessian(this->independent_variables,
997 this->dependent_variables,
1007 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1009 const unsigned int n_independent_variables,
1010 const unsigned int n_dependent_variables)
1011 :
CellLevelBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
1012 n_dependent_variables)
1017 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1022 Assert(residual.size() == this->n_dependent_variables(),
1024 "Vector size does not match number of dependent variables"));
1025 for (
unsigned int i = 0; i < this->n_dependent_variables(); ++i)
1032 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1038 this->taped_driver.keep_independent_values() ==
false) ||
1042 this->n_registered_independent_variables() ==
1043 this->n_independent_variables(),
1045 "Not all values of sensitivities have been registered or subsequently set!"));
1047 Assert(this->n_registered_dependent_variables() ==
1048 this->n_dependent_variables(),
1049 ExcMessage(
"Not all dependent variables have been registered."));
1054 if (values.size() != this->n_dependent_variables())
1055 values.reinit(this->n_dependent_variables(),
1060 Assert(this->active_tape_index() !=
1063 Assert(this->is_recording() ==
false,
1065 "Cannot compute values while tape is being recorded."));
1066 Assert(this->independent_variable_values.size() ==
1067 this->n_independent_variables(),
1069 this->n_independent_variables()));
1071 this->taped_driver.values(this->active_tape_index(),
1072 this->n_dependent_variables(),
1073 this->independent_variable_values,
1080 this->tapeless_driver.values(this->dependent_variables, values);
1086 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1092 this->taped_driver.keep_independent_values() ==
false) ||
1096 this->n_registered_independent_variables() ==
1097 this->n_independent_variables(),
1099 "Not all values of sensitivities have been registered or subsequently set!"));
1101 Assert(this->n_registered_dependent_variables() ==
1102 this->n_dependent_variables(),
1103 ExcMessage(
"Not all dependent variables have been registered."));
1108 if (jacobian.
m() != this->n_dependent_variables() ||
1109 jacobian.
n() != this->n_independent_variables())
1110 jacobian.reinit({this->n_dependent_variables(),
1111 this->n_independent_variables()},
1116 Assert(this->active_tape_index() !=
1119 Assert(this->is_recording() ==
false,
1121 "Cannot compute hessian while tape is being recorded."));
1122 Assert(this->independent_variable_values.size() ==
1123 this->n_independent_variables(),
1125 this->n_independent_variables()));
1127 this->taped_driver.jacobian(this->active_tape_index(),
1128 this->n_dependent_variables(),
1129 this->independent_variable_values,
1136 Assert(this->independent_variables.size() ==
1137 this->n_independent_variables(),
1139 this->n_independent_variables()));
1141 this->tapeless_driver.jacobian(this->independent_variables,
1142 this->dependent_variables,
1155 typename ScalarType>
1158 const unsigned int n_dependent_variables)
1159 :
HelperBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
1160 n_dependent_variables)
1161 , symmetric_independent_variables(n_independent_variables, false)
1168 typename ScalarType>
1171 const unsigned int n_independent_variables,
1172 const unsigned int n_dependent_variables,
1173 const bool clear_registered_tapes)
1176 n_dependent_variables,
1177 clear_registered_tapes);
1179 const unsigned int new_n_independent_variables =
1181 n_independent_variables :
1182 this->n_independent_variables());
1183 symmetric_independent_variables =
1184 std::vector<bool>(new_n_independent_variables,
false);
1191 typename ScalarType>
1196 Assert(index < symmetric_independent_variables.size(),
1198 return symmetric_independent_variables[index];
1205 typename ScalarType>
1210 return std::count(symmetric_independent_variables.begin(),
1211 symmetric_independent_variables.end(),
1219 typename ScalarType>
1228 Assert(values.size() == this->n_independent_variables(),
1230 "Vector size does not match number of independent variables"));
1231 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1233 Assert(this->registered_independent_variable_values[i] ==
false,
1234 ExcMessage(
"Independent variable value already registered."));
1236 set_independent_variables(values);
1243 typename ScalarType>
1246 ScalarType>::ad_type> &
1252 Assert(this->active_tape_index() !=
1260 this->finalize_sensitive_independent_variables();
1261 Assert(this->independent_variables.size() ==
1262 this->n_independent_variables(),
1264 this->n_independent_variables()));
1266 return this->independent_variables;
1273 typename ScalarType>
1277 const bool symmetric_component,
1283 index < this->n_independent_variables(),
1285 "Trying to set the symmetry flag of a non-existent independent variable."));
1286 Assert(index < symmetric_independent_variables.size(),
1288 symmetric_independent_variables[index] = symmetric_component;
1295 typename ScalarType>
1302 Assert(this->active_tape_index() !=
1306 Assert(values.size() == this->n_independent_variables(),
1308 "Vector size does not match number of independent variables"));
1309 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1322 typename ScalarType>
1324 const unsigned int n_independent_variables)
1326 n_independent_variables,
1334 typename ScalarType>
1348 typename ScalarType>
1353 this->taped_driver.keep_independent_values() ==
false) ||
1357 this->n_registered_independent_variables() ==
1358 this->n_independent_variables(),
1360 "Not all values of sensitivities have been registered or subsequently set!"));
1362 Assert(this->n_registered_dependent_variables() ==
1363 this->n_dependent_variables(),
1364 ExcMessage(
"Not all dependent variables have been registered."));
1367 this->n_dependent_variables() == 1,
1369 "The ScalarFunction class expects there to be only one dependent variable."));
1373 Assert(this->active_tape_index() !=
1376 Assert(this->is_recording() ==
false,
1378 "Cannot compute values while tape is being recorded."));
1379 Assert(this->independent_variable_values.size() ==
1380 this->n_independent_variables(),
1382 this->n_independent_variables()));
1384 return this->taped_driver.value(this->active_tape_index(),
1385 this->independent_variable_values);
1391 return this->tapeless_driver.value(this->dependent_variables);
1398 typename ScalarType>
1404 this->taped_driver.keep_independent_values() ==
false) ||
1408 this->n_registered_independent_variables() ==
1409 this->n_independent_variables(),
1411 "Not all values of sensitivities have been registered or subsequently set!"));
1413 Assert(this->n_registered_dependent_variables() ==
1414 this->n_dependent_variables(),
1415 ExcMessage(
"Not all dependent variables have been registered."));
1418 this->n_dependent_variables() == 1,
1420 "The ScalarFunction class expects there to be only one dependent variable."));
1425 if (gradient.size() != this->n_independent_variables())
1426 gradient.reinit(this->n_independent_variables(),
1431 Assert(this->active_tape_index() !=
1434 Assert(this->is_recording() ==
false,
1436 "Cannot compute gradient while tape is being recorded."));
1437 Assert(this->independent_variable_values.size() ==
1438 this->n_independent_variables(),
1440 this->n_independent_variables()));
1442 this->taped_driver.gradient(this->active_tape_index(),
1443 this->independent_variable_values,
1450 Assert(this->independent_variables.size() ==
1451 this->n_independent_variables(),
1453 this->n_independent_variables()));
1455 this->tapeless_driver.gradient(this->independent_variables,
1456 this->dependent_variables,
1461 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1463 if (this->is_symmetric_independent_variable(i) ==
true)
1472 typename ScalarType>
1479 "Cannot computed function Hessian: AD number type does "
1480 "not support the calculation of second order derivatives."));
1483 this->taped_driver.keep_independent_values() ==
false))
1486 this->n_registered_independent_variables() ==
1487 this->n_independent_variables(),
1489 "Not all values of sensitivities have been registered or subsequently set!"));
1491 Assert(this->n_registered_dependent_variables() ==
1492 this->n_dependent_variables(),
1493 ExcMessage(
"Not all dependent variables have been registered."));
1496 this->n_dependent_variables() == 1,
1498 "The ScalarFunction class expects there to be only one dependent variable."));
1503 if (hessian.m() != this->n_independent_variables() ||
1504 hessian.n() != this->n_independent_variables())
1505 hessian.reinit({this->n_independent_variables(),
1506 this->n_independent_variables()},
1511 Assert(this->active_tape_index() !=
1514 Assert(this->is_recording() ==
false,
1516 "Cannot compute Hessian while tape is being recorded."));
1517 Assert(this->independent_variable_values.size() ==
1518 this->n_independent_variables(),
1520 this->n_independent_variables()));
1522 this->taped_driver.hessian(this->active_tape_index(),
1523 this->independent_variable_values,
1530 Assert(this->independent_variables.size() ==
1531 this->n_independent_variables(),
1533 this->n_independent_variables()));
1535 this->tapeless_driver.hessian(this->independent_variables,
1536 this->dependent_variables,
1541 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1542 for (
unsigned int j = 0; j < i + 1; ++j)
1544 if (this->is_symmetric_independent_variable(i) ==
true &&
1545 this->is_symmetric_independent_variable(j) ==
true)
1547 hessian[i][j] *= 0.25;
1549 hessian[j][i] *= 0.25;
1551 else if ((this->is_symmetric_independent_variable(i) ==
true &&
1552 this->is_symmetric_independent_variable(j) ==
false) ||
1553 (this->is_symmetric_independent_variable(j) ==
true &&
1554 this->is_symmetric_independent_variable(i) ==
false))
1556 hessian[i][j] *= 0.5;
1558 hessian[j][i] *= 0.5;
1567 typename ScalarType>
1586 const std::vector<unsigned int> row_index_set(
1587 internal::extract_field_component_indices<dim>(extractor_row));
1588 const std::vector<unsigned int> col_index_set(
1589 internal::extract_field_component_indices<dim>(extractor_col));
1595 hessian[row_index_set[0]][col_index_set[0]]);
1604 typename ScalarType>
1624 const std::vector<unsigned int> row_index_set(
1625 internal::extract_field_component_indices<dim>(extractor_row));
1626 const std::vector<unsigned int> col_index_set(
1627 internal::extract_field_component_indices<dim>(extractor_col));
1629 for (
unsigned int r = 0; r < row_index_set.size(); ++r)
1630 for (
unsigned int c = 0; c < col_index_set.size(); ++c)
1633 out, r, c, hessian[row_index_set[r]][col_index_set[c]]);
1647 typename ScalarType>
1649 const unsigned int n_independent_variables,
1650 const unsigned int n_dependent_variables)
1652 n_independent_variables,
1653 n_dependent_variables)
1660 typename ScalarType>
1665 Assert(funcs.size() == this->n_dependent_variables(),
1667 "Vector size does not match number of dependent variables"));
1668 for (
unsigned int i = 0; i < this->n_dependent_variables(); ++i)
1677 typename ScalarType>
1683 this->taped_driver.keep_independent_values() ==
false) ||
1687 this->n_registered_independent_variables() ==
1688 this->n_independent_variables(),
1690 "Not all values of sensitivities have been registered or subsequently set!"));
1692 Assert(this->n_registered_dependent_variables() ==
1693 this->n_dependent_variables(),
1694 ExcMessage(
"Not all dependent variables have been registered."));
1699 if (values.size() != this->n_dependent_variables())
1700 values.reinit(this->n_dependent_variables(),
1705 Assert(this->active_tape_index() !=
1708 Assert(this->is_recording() ==
false,
1710 "Cannot compute values while tape is being recorded."));
1711 Assert(this->independent_variable_values.size() ==
1712 this->n_independent_variables(),
1714 this->n_independent_variables()));
1716 this->taped_driver.values(this->active_tape_index(),
1717 this->n_dependent_variables(),
1718 this->independent_variable_values,
1725 this->tapeless_driver.values(this->dependent_variables, values);
1733 typename ScalarType>
1739 this->taped_driver.keep_independent_values() ==
false) ||
1743 this->n_registered_independent_variables() ==
1744 this->n_independent_variables(),
1746 "Not all values of sensitivities have been registered or subsequently set!"));
1748 Assert(this->n_registered_dependent_variables() ==
1749 this->n_dependent_variables(),
1750 ExcMessage(
"Not all dependent variables have been registered."));
1755 if (jacobian.
m() != this->n_dependent_variables() ||
1756 jacobian.
n() != this->n_independent_variables())
1757 jacobian.reinit({this->n_dependent_variables(),
1758 this->n_independent_variables()},
1763 Assert(this->active_tape_index() !=
1766 Assert(this->is_recording() ==
false,
1768 "Cannot compute Jacobian while tape is being recorded."));
1769 Assert(this->independent_variable_values.size() ==
1770 this->n_independent_variables(),
1772 this->n_independent_variables()));
1774 this->taped_driver.jacobian(this->active_tape_index(),
1775 this->n_dependent_variables(),
1776 this->independent_variable_values,
1783 Assert(this->independent_variables.size() ==
1784 this->n_independent_variables(),
1786 this->n_independent_variables()));
1788 this->tapeless_driver.jacobian(this->independent_variables,
1789 this->dependent_variables,
1793 for (
unsigned int j = 0; j < this->n_independent_variables(); ++j)
1798 if (this->is_symmetric_independent_variable(j) ==
true)
1799 for (
unsigned int i = 0; i < this->n_dependent_variables(); ++i)
1800 jacobian[i][j] *= 0.5;
1808 typename ScalarType>
1828 const std::vector<unsigned int> row_index_set(
1829 internal::extract_field_component_indices<dim>(extractor_row));
1830 const std::vector<unsigned int> col_index_set(
1831 internal::extract_field_component_indices<dim>(extractor_col));
1837 jacobian[row_index_set[0]][col_index_set[0]]);
1846 typename ScalarType>
1866 const std::vector<unsigned int> row_index_set(
1867 internal::extract_field_component_indices<dim>(extractor_row));
1868 const std::vector<unsigned int> col_index_set(
1869 internal::extract_field_component_indices<dim>(extractor_col));
1871 for (
unsigned int r = 0; r < row_index_set.size(); ++r)
1872 for (
unsigned int c = 0; c < col_index_set.size(); ++c)
1875 out, r, c, jacobian[row_index_set[r]][col_index_set[c]]);
1887# include "differentiation/ad/ad_helpers.inst"
1889# ifdef DEAL_II_WITH_ADOLC
1890# include "differentiation/ad/ad_helpers.inst1"
1892# ifdef DEAL_II_TRILINOS_WITH_SACADO
1893# include "differentiation/ad/ad_helpers.inst2"
const std::vector< ad_type > & get_sensitive_dof_values() const
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
void set_dof_values(const std::vector< scalar_type > &dof_values)
void register_dof_values(const std::vector< scalar_type > &dof_values)
CellLevelBase(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
void register_energy_functional(const ad_type &energy)
EnergyFunctional(const unsigned int n_independent_variables)
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
void compute_residual(Vector< scalar_type > &residual) const override
virtual void compute_linearization(FullMatrix< scalar_type > &linearization) const override
scalar_type compute_energy() const
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
unsigned int n_registered_dependent_variables() const
void stop_recording_operations(const bool write_tapes_to_file=false)
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::scalar_type scalar_type
Types< ad_type >::tape_index active_tape_index() const
void print_tape_stats(const typename Types< ad_type >::tape_index tape_index, std::ostream &stream) const
std::size_t n_independent_variables() const
bool start_recording_operations(const typename Types< ad_type >::tape_index tape_index, const bool overwrite_tape=false, const bool keep_independent_values=true)
void mark_independent_variable(const unsigned int index, ad_type &out) const
bool is_registered_tape(const typename Types< ad_type >::tape_index tape_index) const
void reset_registered_dependent_variables(const bool flag=false)
void activate_tape(const typename Types< ad_type >::tape_index tape_index, const bool read_mode)
void set_tape_buffer_sizes(const typename Types< ad_type >::tape_buffer_sizes obufsize=64 *1024 *1024, const typename Types< ad_type >::tape_buffer_sizes lbufsize=64 *1024 *1024, const typename Types< ad_type >::tape_buffer_sizes vbufsize=64 *1024 *1024, const typename Types< ad_type >::tape_buffer_sizes tbufsize=64 *1024 *1024)
void print(std::ostream &stream) const
void set_sensitivity_value(const unsigned int index, const scalar_type &value)
bool active_tape_requires_retaping() const
HelperBase(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
virtual void reset(const unsigned int n_independent_variables=::numbers::invalid_unsigned_int, const unsigned int n_dependent_variables=::numbers::invalid_unsigned_int, const bool clear_registered_tapes=true)
bool recorded_tape_requires_retaping(const typename Types< ad_type >::tape_index tape_index) const
std::vector< ad_type > dependent_variables
bool is_recording() const
std::size_t n_dependent_variables() const
void print_values(std::ostream &stream) const
void register_dependent_variable(const unsigned int index, const ad_type &func)
static void configure_tapeless_mode(const unsigned int n_independent_variables, const bool ensure_persistent_setting=true)
void initialize_non_sensitive_independent_variable(const unsigned int index, ad_type &out) const
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::ad_type ad_type
void activate_recorded_tape(const typename Types< ad_type >::tape_index tape_index)
bool is_symmetric_independent_variable(const unsigned int index) const
PointLevelFunctionsBase(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
void set_independent_variables(const std::vector< scalar_type > &values)
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
unsigned int n_symmetric_independent_variables() const
void register_independent_variables(const std::vector< scalar_type > &values)
void set_sensitivity_value(const unsigned int index, const bool symmetric_component, const scalar_type &value)
const std::vector< ad_type > & get_sensitive_variables() const
virtual void reset(const unsigned int n_independent_variables=::numbers::invalid_unsigned_int, const unsigned int n_dependent_variables=::numbers::invalid_unsigned_int, const bool clear_registered_tapes=true) override
ResidualLinearization(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
virtual void compute_residual(Vector< scalar_type > &residual) const override
virtual void compute_linearization(FullMatrix< scalar_type > &linearization) const override
void register_residual_vector(const std::vector< ad_type > &residual)
static internal::ScalarFieldHessian< dim, scalar_type, ExtractorType_Row, ExtractorType_Col >::type extract_hessian_component(const FullMatrix< scalar_type > &hessian, const ExtractorType_Row &extractor_row, const ExtractorType_Col &extractor_col)
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
void register_dependent_variable(const ad_type &func)
ScalarFunction(const unsigned int n_independent_variables)
void compute_gradient(Vector< scalar_type > &gradient) const
scalar_type compute_value() const
void compute_hessian(FullMatrix< scalar_type > &hessian) const
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
void compute_values(Vector< scalar_type > &values) const
void register_dependent_variables(const std::vector< ad_type > &funcs)
void compute_jacobian(FullMatrix< scalar_type > &jacobian) const
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
static internal::VectorFieldJacobian< dim, scalar_type, ExtractorType_Row, ExtractorType_Col >::type extract_jacobian_component(const FullMatrix< scalar_type > &jacobian, const ExtractorType_Row &extractor_row, const ExtractorType_Col &extractor_col)
VectorFunction(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
void set_tensor_entry(TensorType &t, const unsigned int unrolled_index, const NumberType &value)
constexpr unsigned int invalid_unsigned_int
static const Types< ADNumberType >::tape_index invalid_tape_index
static void initialize_global_environment(const unsigned int n_independent_variables)