17#if defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)
22# include <type_traits>
36 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
38 const unsigned int n_independent_variables,
39 const unsigned int n_dependent_variables)
40 : independent_variable_values(
41 n_independent_variables,
43 , registered_independent_variable_values(n_independent_variables, false)
44 , registered_marked_independent_variables(n_independent_variables, false)
45 , registered_marked_dependent_variables(n_dependent_variables, false)
54 "Floating point/arithmetic numbers have no derivatives."));
58 "The AD number type does not support the calculation of any derivatives."));
78 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
81 ScalarType>::reset_registered_independent_variables()
83 std::fill(registered_independent_variable_values.begin(),
84 registered_independent_variable_values.end(),
90 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
95 std::fill(registered_marked_dependent_variables.begin(),
96 registered_marked_dependent_variables.end(),
102 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
105 const unsigned int index,
113 if (this->is_recording() ==
false)
114 start_recording_operations(1 );
116 Assert(this->is_recording() ==
true,
118 "Cannot change the value of an independent variable "
119 "of the tapeless variety while this class is not set "
120 "in recording operations."));
124 Assert(this->active_tape_index() !=
129 index < n_independent_variables(),
131 "Trying to set the value of a non-existent independent variable."));
133 independent_variable_values[index] = value;
134 registered_independent_variable_values[index] =
true;
139 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
142 const unsigned int index,
146 Assert(registered_independent_variable_values[index] ==
true,
152 registered_marked_independent_variables[index - 1] ==
true,
154 "Need to extract sensitivities in the order they're created."));
161 Assert(is_recording() ==
true,
163 "The marking of independent variables is only valid "
164 "during recording."));
168 independent_variable_values[index],
170 this->n_independent_variables(),
172 registered_marked_independent_variables[index] =
true;
177 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
180 ScalarType>::finalize_sensitive_independent_variables()
const
183 Assert(n_registered_independent_variables() == n_independent_variables(),
184 ExcMessage(
"Not all values of sensitivities have been recorded!"));
187 if (this->independent_variables.empty())
189 this->independent_variables.resize(
190 this->n_independent_variables(),
194 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
195 this->mark_independent_variable(i, this->independent_variables[i]);
201 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
212 Assert(is_recording() ==
false,
214 "The initialization of non-sensitive independent variables is "
215 "only valid outside of recording operations."));
218 Assert(registered_independent_variable_values[index] ==
true,
221 out = independent_variable_values[index];
226 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
229 ScalarType>::n_registered_independent_variables()
const
231 return std::count(registered_independent_variable_values.begin(),
232 registered_independent_variable_values.end(),
238 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
242 return independent_variable_values.size();
247 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
252 return std::count(registered_marked_dependent_variables.begin(),
253 registered_marked_dependent_variables.end(),
259 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
263 return dependent_variables.size();
268 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
273 return taped_driver.is_recording();
275 return tapeless_driver.is_dependent_variable_marking_allowed();
280 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
286 return taped_driver.active_tape_index();
293 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
299 return taped_driver.is_registered_tape(tape_index);
306 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
311 const std::ios_base::fmtflags stream_flags(stream.flags());
313 stream.setf(std::ios_base::boolalpha);
315 stream <<
"Active tape index: " << active_tape_index() <<
'\n';
316 stream <<
"Recording? " << is_recording() <<
'\n';
317 stream << std::flush;
320 taped_driver.print(stream);
322 stream <<
"Registered independent variables: " <<
'\n';
323 for (
unsigned int i = 0; i < n_independent_variables(); ++i)
324 stream << registered_independent_variable_values[i]
325 << (i < (n_independent_variables() - 1) ?
"," :
"");
328 stream <<
"Independent variable values: " <<
'\n';
329 print_values(stream);
331 stream <<
"Registered marked independent variables: " <<
'\n';
332 for (
unsigned int i = 0; i < n_independent_variables(); ++i)
333 stream << registered_marked_independent_variables[i]
334 << (i < (n_independent_variables() - 1) ?
"," :
"")
338 stream <<
"Dependent variable values: " <<
'\n';
339 for (
unsigned int i = 0; i < n_dependent_variables(); ++i)
340 stream << dependent_variables[i]
341 << (i < (n_dependent_variables() - 1) ?
"," :
"");
344 stream <<
"Registered dependent variables: " <<
'\n';
345 for (
unsigned int i = 0; i < n_dependent_variables(); ++i)
346 stream << registered_marked_dependent_variables[i]
347 << (i < (n_dependent_variables() - 1) ?
"," :
"");
351 stream.flags(stream_flags);
356 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
359 std::ostream &stream)
const
361 for (
unsigned int i = 0; i < n_independent_variables(); ++i)
362 stream << independent_variable_values[i]
363 << (i < (n_independent_variables() - 1) ?
"," :
"")
370 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
374 std::ostream &stream)
const
379 Assert(is_registered_tape(tape_index),
382 this->taped_driver.print_tape_stats(tape_index, stream);
387 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
390 const unsigned int n_independent_variables,
391 const unsigned int n_dependent_variables,
392 const bool clear_registered_tapes)
394 const unsigned int new_n_independent_variables =
396 n_independent_variables :
397 this->n_independent_variables());
398 const unsigned int new_n_dependent_variables =
400 n_dependent_variables :
401 this->n_dependent_variables());
415 std::vector<ad_type>().swap(independent_variables);
416 std::vector<ad_type>().swap(dependent_variables);
423 configure_tapeless_mode(new_n_independent_variables,
427 taped_driver.reset(clear_registered_tapes);
429 independent_variable_values = std::vector<scalar_type>(
430 new_n_independent_variables,
432 registered_independent_variable_values =
433 std::vector<bool>(new_n_independent_variables,
false);
434 registered_marked_independent_variables =
435 std::vector<bool>(new_n_independent_variables,
false);
436 dependent_variables =
437 std::vector<ad_type>(new_n_dependent_variables,
439 registered_marked_dependent_variables =
440 std::vector<bool>(new_n_dependent_variables,
false);
445 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
448 const unsigned int n_independent_variables,
449 const bool ensure_persistent_setting)
456 n_independent_variables);
458 if (ensure_persistent_setting ==
true)
471 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
476 activate_tape(tape_index,
true );
481 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
489 return taped_driver.requires_retaping(tape_index);
494 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
502 return taped_driver.last_action_requires_retaping();
507 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
514 taped_driver.remove_tape(taped_driver.active_tape_index());
519 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
523 const bool read_mode)
530 ExcMessage(
"Tape index exceeds maximum allowable value"));
531 taped_driver.activate_tape(tape_index);
532 reset_registered_independent_variables();
537 if (read_mode ==
true)
539 Assert(is_registered_tape(tape_index),
541 reset_registered_dependent_variables(
true);
542 Assert(n_registered_dependent_variables() ==
543 n_dependent_variables(),
544 ExcMessage(
"Not all dependent variables have been set!"));
556 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
567 taped_driver.set_tape_buffer_sizes(obufsize,
575 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
579 const bool overwrite_tape,
580 const bool keep_independent_values)
583 const bool read_mode =
false;
587 if (overwrite_tape !=
true)
589 Assert(is_recording() ==
false,
594 if (is_registered_tape(tape_index) ==
false || overwrite_tape ==
true)
598 activate_tape(tape_index, read_mode);
601 taped_driver.start_taping(active_tape_index(),
602 keep_independent_values);
606 reset_registered_independent_variables();
607 reset_registered_dependent_variables();
611 Assert(is_recording() ==
false,
613 "Tape recording is unexpectedly still enabled."));
617 activate_recorded_tape(tape_index);
622 Assert(ADNumberTraits<ad_type>::is_tapeless ==
true,
627 tapeless_driver.allow_dependent_variable_marking();
632 activate_tape(tape_index, read_mode);
635 return is_recording();
640 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
643 const bool write_tapes_to_file)
648 Assert(n_registered_independent_variables() == n_independent_variables(),
649 ExcMessage(
"Not all values of sensitivities have been recorded!"));
654 taped_driver.stop_taping(active_tape_index(), write_tapes_to_file);
661 Assert(n_registered_dependent_variables() == n_dependent_variables(),
662 ExcMessage(
"Not all dependent variables have been set!"));
670 tapeless_driver.prevent_dependent_variable_marking();
676 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
679 const unsigned int index,
683 Assert(registered_marked_dependent_variables[index] ==
false,
685 "This dependent variable has already been registered."));
691 Assert(is_recording() ==
true,
693 "Must be recording when registering dependent variables."));
699 registered_marked_dependent_variables[index] =
true;
708 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
710 const unsigned int n_independent_variables,
711 const unsigned int n_dependent_variables)
712 :
HelperBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
713 n_dependent_variables)
718 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
721 const std::vector<scalar_type> &dof_values)
727 Assert(dof_values.size() == this->n_independent_variables(),
729 "Vector size does not match number of independent variables"));
730 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
732 Assert(this->registered_independent_variable_values[i] ==
false,
733 ExcMessage(
"Independent variable value already registered."));
735 set_dof_values(dof_values);
740 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
748 Assert(this->active_tape_index() !=
755 this->finalize_sensitive_independent_variables();
756 Assert(this->independent_variables.size() ==
757 this->n_independent_variables(),
759 this->n_independent_variables()));
761 return this->independent_variables;
766 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
769 const std::vector<scalar_type> &values)
773 Assert(this->active_tape_index() !=
777 Assert(values.size() == this->n_independent_variables(),
779 "Vector size does not match number of independent variables"));
780 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
791 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
793 const unsigned int n_independent_variables)
794 :
CellLevelBase<ADNumberTypeCode, ScalarType>(n_independent_variables, 1)
799 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
811 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
816 this->taped_driver.keep_independent_values() ==
false) ||
820 this->n_registered_independent_variables() ==
821 this->n_independent_variables(),
823 "Not all values of sensitivities have been registered or subsequently set!"));
825 Assert(this->n_registered_dependent_variables() ==
826 this->n_dependent_variables(),
827 ExcMessage(
"Not all dependent variables have been registered."));
830 this->n_dependent_variables() == 1,
832 "The EnergyFunctional class expects there to be only one dependent variable."));
836 Assert(this->active_tape_index() !=
839 Assert(this->is_recording() ==
false,
841 "Cannot compute value while tape is being recorded."));
842 Assert(this->independent_variable_values.size() ==
843 this->n_independent_variables(),
845 this->n_independent_variables()));
847 return this->taped_driver.value(this->active_tape_index(),
848 this->independent_variable_values);
854 Assert(this->independent_variables.size() ==
855 this->n_independent_variables(),
857 this->n_independent_variables()));
859 return this->tapeless_driver.value(this->dependent_variables);
865 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
871 this->taped_driver.keep_independent_values() ==
false) ||
875 this->n_registered_independent_variables() ==
876 this->n_independent_variables(),
878 "Not all values of sensitivities have been registered or subsequently set!"));
880 Assert(this->n_registered_dependent_variables() ==
881 this->n_dependent_variables(),
882 ExcMessage(
"Not all dependent variables have been registered."));
885 this->n_dependent_variables() == 1,
887 "The EnergyFunctional class expects there to be only one dependent variable."));
892 if (gradient.size() != this->n_independent_variables())
893 gradient.reinit(this->n_independent_variables(),
898 Assert(this->active_tape_index() !=
901 Assert(this->is_recording() ==
false,
903 "Cannot compute gradient while tape is being recorded."));
904 Assert(this->independent_variable_values.size() ==
905 this->n_independent_variables(),
907 this->n_independent_variables()));
909 this->taped_driver.gradient(this->active_tape_index(),
910 this->independent_variable_values,
917 Assert(this->independent_variables.size() ==
918 this->n_independent_variables(),
920 this->n_independent_variables()));
922 this->tapeless_driver.gradient(this->independent_variables,
923 this->dependent_variables,
930 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
937 "Cannot computed function Hessian: AD number type does "
938 "not support the calculation of second order derivatives."));
941 this->taped_driver.keep_independent_values() ==
false))
944 this->n_registered_independent_variables() ==
945 this->n_independent_variables(),
947 "Not all values of sensitivities have been registered or subsequently set!"));
949 Assert(this->n_registered_dependent_variables() ==
950 this->n_dependent_variables(),
951 ExcMessage(
"Not all dependent variables have been registered."));
954 this->n_dependent_variables() == 1,
956 "The EnergyFunctional class expects there to be only one dependent variable."));
961 if (hessian.m() != this->n_independent_variables() ||
962 hessian.n() != this->n_independent_variables())
963 hessian.reinit({this->n_independent_variables(),
964 this->n_independent_variables()},
969 Assert(this->active_tape_index() !=
972 Assert(this->is_recording() ==
false,
974 "Cannot compute hessian while tape is being recorded."));
975 Assert(this->independent_variable_values.size() ==
976 this->n_independent_variables(),
978 this->n_independent_variables()));
980 this->taped_driver.hessian(this->active_tape_index(),
981 this->independent_variable_values,
988 Assert(this->independent_variables.size() ==
989 this->n_independent_variables(),
991 this->n_independent_variables()));
993 this->tapeless_driver.hessian(this->independent_variables,
994 this->dependent_variables,
1004 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1006 const unsigned int n_independent_variables,
1007 const unsigned int n_dependent_variables)
1008 :
CellLevelBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
1009 n_dependent_variables)
1014 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1019 Assert(residual.size() == this->n_dependent_variables(),
1021 "Vector size does not match number of dependent variables"));
1022 for (
unsigned int i = 0; i < this->n_dependent_variables(); ++i)
1029 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1035 this->taped_driver.keep_independent_values() ==
false) ||
1039 this->n_registered_independent_variables() ==
1040 this->n_independent_variables(),
1042 "Not all values of sensitivities have been registered or subsequently set!"));
1044 Assert(this->n_registered_dependent_variables() ==
1045 this->n_dependent_variables(),
1046 ExcMessage(
"Not all dependent variables have been registered."));
1051 if (values.size() != this->n_dependent_variables())
1052 values.reinit(this->n_dependent_variables(),
1057 Assert(this->active_tape_index() !=
1060 Assert(this->is_recording() ==
false,
1062 "Cannot compute values while tape is being recorded."));
1063 Assert(this->independent_variable_values.size() ==
1064 this->n_independent_variables(),
1066 this->n_independent_variables()));
1068 this->taped_driver.values(this->active_tape_index(),
1069 this->n_dependent_variables(),
1070 this->independent_variable_values,
1077 this->tapeless_driver.values(this->dependent_variables, values);
1083 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1089 this->taped_driver.keep_independent_values() ==
false) ||
1093 this->n_registered_independent_variables() ==
1094 this->n_independent_variables(),
1096 "Not all values of sensitivities have been registered or subsequently set!"));
1098 Assert(this->n_registered_dependent_variables() ==
1099 this->n_dependent_variables(),
1100 ExcMessage(
"Not all dependent variables have been registered."));
1105 if (jacobian.
m() != this->n_dependent_variables() ||
1106 jacobian.
n() != this->n_independent_variables())
1107 jacobian.reinit({this->n_dependent_variables(),
1108 this->n_independent_variables()},
1113 Assert(this->active_tape_index() !=
1116 Assert(this->is_recording() ==
false,
1118 "Cannot compute hessian while tape is being recorded."));
1119 Assert(this->independent_variable_values.size() ==
1120 this->n_independent_variables(),
1122 this->n_independent_variables()));
1124 this->taped_driver.jacobian(this->active_tape_index(),
1125 this->n_dependent_variables(),
1126 this->independent_variable_values,
1133 Assert(this->independent_variables.size() ==
1134 this->n_independent_variables(),
1136 this->n_independent_variables()));
1138 this->tapeless_driver.jacobian(this->independent_variables,
1139 this->dependent_variables,
1152 typename ScalarType>
1155 const unsigned int n_dependent_variables)
1156 :
HelperBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
1157 n_dependent_variables)
1158 , symmetric_independent_variables(n_independent_variables, false)
1165 typename ScalarType>
1168 const unsigned int n_independent_variables,
1169 const unsigned int n_dependent_variables,
1170 const bool clear_registered_tapes)
1173 n_dependent_variables,
1174 clear_registered_tapes);
1176 const unsigned int new_n_independent_variables =
1178 n_independent_variables :
1179 this->n_independent_variables());
1180 symmetric_independent_variables =
1181 std::vector<bool>(new_n_independent_variables,
false);
1188 typename ScalarType>
1193 Assert(index < symmetric_independent_variables.size(),
1195 return symmetric_independent_variables[index];
1202 typename ScalarType>
1207 return std::count(symmetric_independent_variables.begin(),
1208 symmetric_independent_variables.end(),
1216 typename ScalarType>
1225 Assert(values.size() == this->n_independent_variables(),
1227 "Vector size does not match number of independent variables"));
1228 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1230 Assert(this->registered_independent_variable_values[i] ==
false,
1231 ExcMessage(
"Independent variable value already registered."));
1233 set_independent_variables(values);
1240 typename ScalarType>
1243 ScalarType>::ad_type> &
1249 Assert(this->active_tape_index() !=
1257 this->finalize_sensitive_independent_variables();
1258 Assert(this->independent_variables.size() ==
1259 this->n_independent_variables(),
1261 this->n_independent_variables()));
1263 return this->independent_variables;
1270 typename ScalarType>
1274 const bool symmetric_component,
1280 index < this->n_independent_variables(),
1282 "Trying to set the symmetry flag of a non-existent independent variable."));
1283 Assert(index < symmetric_independent_variables.size(),
1285 symmetric_independent_variables[index] = symmetric_component;
1292 typename ScalarType>
1299 Assert(this->active_tape_index() !=
1303 Assert(values.size() == this->n_independent_variables(),
1305 "Vector size does not match number of independent variables"));
1306 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1319 typename ScalarType>
1321 const unsigned int n_independent_variables)
1323 n_independent_variables,
1331 typename ScalarType>
1345 typename ScalarType>
1350 this->taped_driver.keep_independent_values() ==
false) ||
1354 this->n_registered_independent_variables() ==
1355 this->n_independent_variables(),
1357 "Not all values of sensitivities have been registered or subsequently set!"));
1359 Assert(this->n_registered_dependent_variables() ==
1360 this->n_dependent_variables(),
1361 ExcMessage(
"Not all dependent variables have been registered."));
1364 this->n_dependent_variables() == 1,
1366 "The ScalarFunction class expects there to be only one dependent variable."));
1370 Assert(this->active_tape_index() !=
1373 Assert(this->is_recording() ==
false,
1375 "Cannot compute values while tape is being recorded."));
1376 Assert(this->independent_variable_values.size() ==
1377 this->n_independent_variables(),
1379 this->n_independent_variables()));
1381 return this->taped_driver.value(this->active_tape_index(),
1382 this->independent_variable_values);
1388 return this->tapeless_driver.value(this->dependent_variables);
1395 typename ScalarType>
1401 this->taped_driver.keep_independent_values() ==
false) ||
1405 this->n_registered_independent_variables() ==
1406 this->n_independent_variables(),
1408 "Not all values of sensitivities have been registered or subsequently set!"));
1410 Assert(this->n_registered_dependent_variables() ==
1411 this->n_dependent_variables(),
1412 ExcMessage(
"Not all dependent variables have been registered."));
1415 this->n_dependent_variables() == 1,
1417 "The ScalarFunction class expects there to be only one dependent variable."));
1422 if (gradient.size() != this->n_independent_variables())
1423 gradient.reinit(this->n_independent_variables(),
1428 Assert(this->active_tape_index() !=
1431 Assert(this->is_recording() ==
false,
1433 "Cannot compute gradient while tape is being recorded."));
1434 Assert(this->independent_variable_values.size() ==
1435 this->n_independent_variables(),
1437 this->n_independent_variables()));
1439 this->taped_driver.gradient(this->active_tape_index(),
1440 this->independent_variable_values,
1447 Assert(this->independent_variables.size() ==
1448 this->n_independent_variables(),
1450 this->n_independent_variables()));
1452 this->tapeless_driver.gradient(this->independent_variables,
1453 this->dependent_variables,
1458 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1460 if (this->is_symmetric_independent_variable(i) ==
true)
1469 typename ScalarType>
1476 "Cannot computed function Hessian: AD number type does "
1477 "not support the calculation of second order derivatives."));
1480 this->taped_driver.keep_independent_values() ==
false))
1483 this->n_registered_independent_variables() ==
1484 this->n_independent_variables(),
1486 "Not all values of sensitivities have been registered or subsequently set!"));
1488 Assert(this->n_registered_dependent_variables() ==
1489 this->n_dependent_variables(),
1490 ExcMessage(
"Not all dependent variables have been registered."));
1493 this->n_dependent_variables() == 1,
1495 "The ScalarFunction class expects there to be only one dependent variable."));
1500 if (hessian.m() != this->n_independent_variables() ||
1501 hessian.n() != this->n_independent_variables())
1502 hessian.reinit({this->n_independent_variables(),
1503 this->n_independent_variables()},
1508 Assert(this->active_tape_index() !=
1511 Assert(this->is_recording() ==
false,
1513 "Cannot compute Hessian while tape is being recorded."));
1514 Assert(this->independent_variable_values.size() ==
1515 this->n_independent_variables(),
1517 this->n_independent_variables()));
1519 this->taped_driver.hessian(this->active_tape_index(),
1520 this->independent_variable_values,
1527 Assert(this->independent_variables.size() ==
1528 this->n_independent_variables(),
1530 this->n_independent_variables()));
1532 this->tapeless_driver.hessian(this->independent_variables,
1533 this->dependent_variables,
1538 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1539 for (
unsigned int j = 0; j < i + 1; ++j)
1541 if (this->is_symmetric_independent_variable(i) ==
true &&
1542 this->is_symmetric_independent_variable(j) ==
true)
1544 hessian[i][j] *= 0.25;
1546 hessian[j][i] *= 0.25;
1548 else if ((this->is_symmetric_independent_variable(i) ==
true &&
1549 this->is_symmetric_independent_variable(j) ==
false) ||
1550 (this->is_symmetric_independent_variable(j) ==
true &&
1551 this->is_symmetric_independent_variable(i) ==
false))
1553 hessian[i][j] *= 0.5;
1555 hessian[j][i] *= 0.5;
1564 typename ScalarType>
1583 const std::vector<unsigned int> row_index_set(
1585 const std::vector<unsigned int> col_index_set(
1592 hessian[row_index_set[0]][col_index_set[0]]);
1601 typename ScalarType>
1621 const std::vector<unsigned int> row_index_set(
1623 const std::vector<unsigned int> col_index_set(
1626 for (
unsigned int r = 0; r < row_index_set.size(); ++r)
1627 for (
unsigned int c = 0; c < col_index_set.size(); ++c)
1630 out, r, c, hessian[row_index_set[r]][col_index_set[c]]);
1644 typename ScalarType>
1646 const unsigned int n_independent_variables,
1647 const unsigned int n_dependent_variables)
1649 n_independent_variables,
1650 n_dependent_variables)
1657 typename ScalarType>
1662 Assert(funcs.size() == this->n_dependent_variables(),
1664 "Vector size does not match number of dependent variables"));
1665 for (
unsigned int i = 0; i < this->n_dependent_variables(); ++i)
1674 typename ScalarType>
1680 this->taped_driver.keep_independent_values() ==
false) ||
1684 this->n_registered_independent_variables() ==
1685 this->n_independent_variables(),
1687 "Not all values of sensitivities have been registered or subsequently set!"));
1689 Assert(this->n_registered_dependent_variables() ==
1690 this->n_dependent_variables(),
1691 ExcMessage(
"Not all dependent variables have been registered."));
1696 if (values.size() != this->n_dependent_variables())
1697 values.reinit(this->n_dependent_variables(),
1702 Assert(this->active_tape_index() !=
1705 Assert(this->is_recording() ==
false,
1707 "Cannot compute values while tape is being recorded."));
1708 Assert(this->independent_variable_values.size() ==
1709 this->n_independent_variables(),
1711 this->n_independent_variables()));
1713 this->taped_driver.values(this->active_tape_index(),
1714 this->n_dependent_variables(),
1715 this->independent_variable_values,
1722 this->tapeless_driver.values(this->dependent_variables, values);
1730 typename ScalarType>
1736 this->taped_driver.keep_independent_values() ==
false) ||
1740 this->n_registered_independent_variables() ==
1741 this->n_independent_variables(),
1743 "Not all values of sensitivities have been registered or subsequently set!"));
1745 Assert(this->n_registered_dependent_variables() ==
1746 this->n_dependent_variables(),
1747 ExcMessage(
"Not all dependent variables have been registered."));
1752 if (jacobian.
m() != this->n_dependent_variables() ||
1753 jacobian.
n() != this->n_independent_variables())
1754 jacobian.reinit({this->n_dependent_variables(),
1755 this->n_independent_variables()},
1760 Assert(this->active_tape_index() !=
1763 Assert(this->is_recording() ==
false,
1765 "Cannot compute Jacobian while tape is being recorded."));
1766 Assert(this->independent_variable_values.size() ==
1767 this->n_independent_variables(),
1769 this->n_independent_variables()));
1771 this->taped_driver.jacobian(this->active_tape_index(),
1772 this->n_dependent_variables(),
1773 this->independent_variable_values,
1780 Assert(this->independent_variables.size() ==
1781 this->n_independent_variables(),
1783 this->n_independent_variables()));
1785 this->tapeless_driver.jacobian(this->independent_variables,
1786 this->dependent_variables,
1790 for (
unsigned int j = 0; j < this->n_independent_variables(); ++j)
1795 if (this->is_symmetric_independent_variable(j) ==
true)
1796 for (
unsigned int i = 0; i < this->n_dependent_variables(); ++i)
1797 jacobian[i][j] *= 0.5;
1805 typename ScalarType>
1825 const std::vector<unsigned int> row_index_set(
1827 const std::vector<unsigned int> col_index_set(
1834 jacobian[row_index_set[0]][col_index_set[0]]);
1843 typename ScalarType>
1863 const std::vector<unsigned int> row_index_set(
1865 const std::vector<unsigned int> col_index_set(
1868 for (
unsigned int r = 0; r < row_index_set.size(); ++r)
1869 for (
unsigned int c = 0; c < col_index_set.size(); ++c)
1872 out, r, c, jacobian[row_index_set[r]][col_index_set[c]]);
1884# include "ad_helpers.inst"
1886# ifdef DEAL_II_WITH_ADOLC
1887# include "ad_helpers.inst1"
1889# ifdef DEAL_II_TRILINOS_WITH_SACADO
1890# include "ad_helpers.inst2"
const std::vector< ad_type > & get_sensitive_dof_values() const
void set_dof_values(const std::vector< scalar_type > &dof_values)
void register_dof_values(const std::vector< scalar_type > &dof_values)
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
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
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::ad_type ad_type
void stop_recording_operations(const bool write_tapes_to_file=false)
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
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::scalar_type scalar_type
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
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)
unsigned int n_symmetric_independent_variables() const
void register_independent_variables(const std::vector< scalar_type > &values)
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
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)
void register_dependent_variable(const ad_type &func)
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
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 >::ad_type ad_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)
std::vector< IndexType > extract_field_component_indices(const ExtractorType &extractor, const bool ignore_symmetries=true)
static const unsigned int invalid_unsigned_int
static void initialize_global_environment(const unsigned int n_independent_variables)