18#if defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)
23# include <type_traits>
37 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
39 const unsigned int n_independent_variables,
40 const unsigned int n_dependent_variables)
41 : independent_variable_values(
42 n_independent_variables,
44 , registered_independent_variable_values(n_independent_variables, false)
45 , registered_marked_independent_variables(n_independent_variables, false)
46 , registered_marked_dependent_variables(n_dependent_variables, false)
55 "Floating point/arithmetic numbers have no derivatives."));
59 "The AD number type does not support the calculation of any derivatives."));
79 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
82 ScalarType>::reset_registered_independent_variables()
84 std::fill(registered_independent_variable_values.begin(),
85 registered_independent_variable_values.end(),
91 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
96 std::fill(registered_marked_dependent_variables.begin(),
97 registered_marked_dependent_variables.end(),
103 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
106 const unsigned int index,
114 if (this->is_recording() ==
false)
115 start_recording_operations(1 );
117 Assert(this->is_recording() ==
true,
119 "Cannot change the value of an independent variable "
120 "of the tapeless variety while this class is not set "
121 "in recording operations."));
125 Assert(this->active_tape_index() !=
130 index < n_independent_variables(),
132 "Trying to set the value of a non-existent independent variable."));
134 independent_variable_values[index] = value;
135 registered_independent_variable_values[index] =
true;
140 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
143 const unsigned int index,
147 Assert(registered_independent_variable_values[index] ==
true,
153 registered_marked_independent_variables[index - 1] ==
true,
155 "Need to extract sensitivities in the order they're created."));
162 Assert(is_recording() ==
true,
164 "The marking of independent variables is only valid "
165 "during recording."));
169 independent_variable_values[index],
171 this->n_independent_variables(),
173 registered_marked_independent_variables[index] =
true;
178 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
181 ScalarType>::finalize_sensitive_independent_variables()
const
184 Assert(n_registered_independent_variables() == n_independent_variables(),
185 ExcMessage(
"Not all values of sensitivities have been recorded!"));
188 if (this->independent_variables.size() == 0)
190 this->independent_variables.resize(
191 this->n_independent_variables(),
195 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
196 this->mark_independent_variable(i, this->independent_variables[i]);
202 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
213 Assert(is_recording() ==
false,
215 "The initialization of non-sensitive independent variables is "
216 "only valid outside of recording operations."));
219 Assert(registered_independent_variable_values[index] ==
true,
222 out = independent_variable_values[index];
227 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
230 ScalarType>::n_registered_independent_variables()
const
232 return std::count(registered_independent_variable_values.begin(),
233 registered_independent_variable_values.end(),
239 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
243 return independent_variable_values.size();
248 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
253 return std::count(registered_marked_dependent_variables.begin(),
254 registered_marked_dependent_variables.end(),
260 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
264 return dependent_variables.size();
269 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
274 return taped_driver.is_recording();
276 return tapeless_driver.is_dependent_variable_marking_allowed();
281 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
287 return taped_driver.active_tape_index();
294 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
300 return taped_driver.is_registered_tape(tape_index);
307 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
312 const std::ios_base::fmtflags stream_flags(stream.flags());
314 stream.setf(std::ios_base::boolalpha);
316 stream <<
"Active tape index: " << active_tape_index() <<
'\n';
317 stream <<
"Recording? " << is_recording() <<
'\n';
318 stream << std::flush;
321 taped_driver.print(stream);
323 stream <<
"Registered independent variables: " <<
'\n';
324 for (
unsigned int i = 0; i < n_independent_variables(); ++i)
325 stream << registered_independent_variable_values[i]
326 << (i < (n_independent_variables() - 1) ?
"," :
"");
329 stream <<
"Independent variable values: " <<
'\n';
330 print_values(stream);
332 stream <<
"Registered marked independent variables: " <<
'\n';
333 for (
unsigned int i = 0; i < n_independent_variables(); ++i)
334 stream << registered_marked_independent_variables[i]
335 << (i < (n_independent_variables() - 1) ?
"," :
"")
339 stream <<
"Dependent variable values: " <<
'\n';
340 for (
unsigned int i = 0; i < n_dependent_variables(); ++i)
341 stream << dependent_variables[i]
342 << (i < (n_dependent_variables() - 1) ?
"," :
"");
345 stream <<
"Registered dependent variables: " <<
'\n';
346 for (
unsigned int i = 0; i < n_dependent_variables(); ++i)
347 stream << registered_marked_dependent_variables[i]
348 << (i < (n_dependent_variables() - 1) ?
"," :
"");
352 stream.flags(stream_flags);
357 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
360 std::ostream &stream)
const
362 for (
unsigned int i = 0; i < n_independent_variables(); ++i)
363 stream << independent_variable_values[i]
364 << (i < (n_independent_variables() - 1) ?
"," :
"")
371 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
375 std::ostream & stream)
const
380 Assert(is_registered_tape(tape_index),
383 this->taped_driver.print_tape_stats(tape_index, stream);
388 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
391 const unsigned int n_independent_variables,
392 const unsigned int n_dependent_variables,
393 const bool clear_registered_tapes)
395 const unsigned int new_n_independent_variables =
397 n_independent_variables :
398 this->n_independent_variables());
399 const unsigned int new_n_dependent_variables =
401 n_dependent_variables :
402 this->n_dependent_variables());
416 std::vector<ad_type>().swap(independent_variables);
417 std::vector<ad_type>().swap(dependent_variables);
424 configure_tapeless_mode(new_n_independent_variables,
428 taped_driver.reset(clear_registered_tapes);
430 independent_variable_values = std::vector<scalar_type>(
431 new_n_independent_variables,
433 registered_independent_variable_values =
434 std::vector<bool>(new_n_independent_variables,
false);
435 registered_marked_independent_variables =
436 std::vector<bool>(new_n_independent_variables,
false);
437 dependent_variables =
438 std::vector<ad_type>(new_n_dependent_variables,
440 registered_marked_dependent_variables =
441 std::vector<bool>(new_n_dependent_variables,
false);
446 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
449 const unsigned int n_independent_variables,
450 const bool ensure_persistent_setting)
457 n_independent_variables);
459 if (ensure_persistent_setting ==
true)
472 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
477 activate_tape(tape_index,
true );
482 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
490 return taped_driver.requires_retaping(tape_index);
495 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
503 return taped_driver.last_action_requires_retaping();
508 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
515 taped_driver.remove_tape(taped_driver.active_tape_index());
520 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
524 const bool read_mode)
531 ExcMessage(
"Tape index exceeds maximum allowable value"));
532 taped_driver.activate_tape(tape_index);
533 reset_registered_independent_variables();
538 if (read_mode ==
true)
540 Assert(is_registered_tape(tape_index),
542 reset_registered_dependent_variables(
true);
543 Assert(n_registered_dependent_variables() ==
544 n_dependent_variables(),
545 ExcMessage(
"Not all dependent variables have been set!"));
557 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
568 taped_driver.set_tape_buffer_sizes(obufsize,
576 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
580 const bool overwrite_tape,
581 const bool keep_independent_values)
584 const bool read_mode =
false;
588 if (overwrite_tape !=
true)
590 Assert(is_recording() ==
false,
595 if (is_registered_tape(tape_index) ==
false || overwrite_tape ==
true)
599 activate_tape(tape_index, read_mode);
602 taped_driver.start_taping(active_tape_index(),
603 keep_independent_values);
607 reset_registered_independent_variables();
608 reset_registered_dependent_variables();
612 Assert(is_recording() ==
false,
614 "Tape recording is unexpectedly still enabled."));
618 activate_recorded_tape(tape_index);
623 Assert(ADNumberTraits<ad_type>::is_tapeless ==
true,
628 tapeless_driver.allow_dependent_variable_marking();
633 activate_tape(tape_index, read_mode);
636 return is_recording();
641 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
644 const bool write_tapes_to_file)
649 Assert(n_registered_independent_variables() == n_independent_variables(),
650 ExcMessage(
"Not all values of sensitivities have been recorded!"));
655 taped_driver.stop_taping(active_tape_index(), write_tapes_to_file);
662 Assert(n_registered_dependent_variables() == n_dependent_variables(),
663 ExcMessage(
"Not all dependent variables have been set!"));
671 tapeless_driver.prevent_dependent_variable_marking();
677 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
680 const unsigned int index,
684 Assert(registered_marked_dependent_variables[index] ==
false,
686 "This dependent variable has already been registered."));
692 Assert(is_recording() ==
true,
694 "Must be recording when registering dependent variables."));
700 registered_marked_dependent_variables[index] =
true;
709 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
711 const unsigned int n_independent_variables,
712 const unsigned int n_dependent_variables)
713 :
HelperBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
714 n_dependent_variables)
719 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
722 const std::vector<scalar_type> &dof_values)
728 Assert(dof_values.size() == this->n_independent_variables(),
730 "Vector size does not match number of independent variables"));
731 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
733 Assert(this->registered_independent_variable_values[i] ==
false,
734 ExcMessage(
"Independent variable value already registered."));
736 set_dof_values(dof_values);
741 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
749 Assert(this->active_tape_index() !=
756 this->finalize_sensitive_independent_variables();
757 Assert(this->independent_variables.size() ==
758 this->n_independent_variables(),
760 this->n_independent_variables()));
762 return this->independent_variables;
767 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
770 const std::vector<scalar_type> &values)
774 Assert(this->active_tape_index() !=
778 Assert(values.size() == this->n_independent_variables(),
780 "Vector size does not match number of independent variables"));
781 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
792 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
794 const unsigned int n_independent_variables)
795 :
CellLevelBase<ADNumberTypeCode, ScalarType>(n_independent_variables, 1)
800 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
812 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
817 this->taped_driver.keep_independent_values() ==
false) ||
821 this->n_registered_independent_variables() ==
822 this->n_independent_variables(),
824 "Not all values of sensitivities have been registered or subsequently set!"));
826 Assert(this->n_registered_dependent_variables() ==
827 this->n_dependent_variables(),
828 ExcMessage(
"Not all dependent variables have been registered."));
831 this->n_dependent_variables() == 1,
833 "The EnergyFunctional class expects there to be only one dependent variable."));
837 Assert(this->active_tape_index() !=
840 Assert(this->is_recording() ==
false,
842 "Cannot compute value while tape is being recorded."));
843 Assert(this->independent_variable_values.size() ==
844 this->n_independent_variables(),
846 this->n_independent_variables()));
848 return this->taped_driver.value(this->active_tape_index(),
849 this->independent_variable_values);
855 Assert(this->independent_variables.size() ==
856 this->n_independent_variables(),
858 this->n_independent_variables()));
860 return this->tapeless_driver.value(this->dependent_variables);
866 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
872 this->taped_driver.keep_independent_values() ==
false) ||
876 this->n_registered_independent_variables() ==
877 this->n_independent_variables(),
879 "Not all values of sensitivities have been registered or subsequently set!"));
881 Assert(this->n_registered_dependent_variables() ==
882 this->n_dependent_variables(),
883 ExcMessage(
"Not all dependent variables have been registered."));
886 this->n_dependent_variables() == 1,
888 "The EnergyFunctional class expects there to be only one dependent variable."));
893 if (gradient.size() != this->n_independent_variables())
894 gradient.reinit(this->n_independent_variables(),
899 Assert(this->active_tape_index() !=
902 Assert(this->is_recording() ==
false,
904 "Cannot compute gradient while tape is being recorded."));
905 Assert(this->independent_variable_values.size() ==
906 this->n_independent_variables(),
908 this->n_independent_variables()));
910 this->taped_driver.gradient(this->active_tape_index(),
911 this->independent_variable_values,
918 Assert(this->independent_variables.size() ==
919 this->n_independent_variables(),
921 this->n_independent_variables()));
923 this->tapeless_driver.gradient(this->independent_variables,
924 this->dependent_variables,
931 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
938 "Cannot computed function Hessian: AD number type does "
939 "not support the calculation of second order derivatives."));
942 this->taped_driver.keep_independent_values() ==
false))
945 this->n_registered_independent_variables() ==
946 this->n_independent_variables(),
948 "Not all values of sensitivities have been registered or subsequently set!"));
950 Assert(this->n_registered_dependent_variables() ==
951 this->n_dependent_variables(),
952 ExcMessage(
"Not all dependent variables have been registered."));
955 this->n_dependent_variables() == 1,
957 "The EnergyFunctional class expects there to be only one dependent variable."));
962 if (hessian.m() != this->n_independent_variables() ||
963 hessian.n() != this->n_independent_variables())
964 hessian.reinit({this->n_independent_variables(),
965 this->n_independent_variables()},
970 Assert(this->active_tape_index() !=
973 Assert(this->is_recording() ==
false,
975 "Cannot compute hessian while tape is being recorded."));
976 Assert(this->independent_variable_values.size() ==
977 this->n_independent_variables(),
979 this->n_independent_variables()));
981 this->taped_driver.hessian(this->active_tape_index(),
982 this->independent_variable_values,
989 Assert(this->independent_variables.size() ==
990 this->n_independent_variables(),
992 this->n_independent_variables()));
994 this->tapeless_driver.hessian(this->independent_variables,
995 this->dependent_variables,
1005 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1007 const unsigned int n_independent_variables,
1008 const unsigned int n_dependent_variables)
1009 :
CellLevelBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
1010 n_dependent_variables)
1015 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1020 Assert(residual.size() == this->n_dependent_variables(),
1022 "Vector size does not match number of dependent variables"));
1023 for (
unsigned int i = 0; i < this->n_dependent_variables(); ++i)
1030 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1036 this->taped_driver.keep_independent_values() ==
false) ||
1040 this->n_registered_independent_variables() ==
1041 this->n_independent_variables(),
1043 "Not all values of sensitivities have been registered or subsequently set!"));
1045 Assert(this->n_registered_dependent_variables() ==
1046 this->n_dependent_variables(),
1047 ExcMessage(
"Not all dependent variables have been registered."));
1052 if (values.size() != this->n_dependent_variables())
1053 values.reinit(this->n_dependent_variables(),
1058 Assert(this->active_tape_index() !=
1061 Assert(this->is_recording() ==
false,
1063 "Cannot compute values while tape is being recorded."));
1064 Assert(this->independent_variable_values.size() ==
1065 this->n_independent_variables(),
1067 this->n_independent_variables()));
1069 this->taped_driver.values(this->active_tape_index(),
1070 this->n_dependent_variables(),
1071 this->independent_variable_values,
1078 this->tapeless_driver.values(this->dependent_variables, values);
1084 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1090 this->taped_driver.keep_independent_values() ==
false) ||
1094 this->n_registered_independent_variables() ==
1095 this->n_independent_variables(),
1097 "Not all values of sensitivities have been registered or subsequently set!"));
1099 Assert(this->n_registered_dependent_variables() ==
1100 this->n_dependent_variables(),
1101 ExcMessage(
"Not all dependent variables have been registered."));
1106 if (jacobian.
m() != this->n_dependent_variables() ||
1107 jacobian.
n() != this->n_independent_variables())
1108 jacobian.reinit({this->n_dependent_variables(),
1109 this->n_independent_variables()},
1114 Assert(this->active_tape_index() !=
1117 Assert(this->is_recording() ==
false,
1119 "Cannot compute hessian while tape is being recorded."));
1120 Assert(this->independent_variable_values.size() ==
1121 this->n_independent_variables(),
1123 this->n_independent_variables()));
1125 this->taped_driver.jacobian(this->active_tape_index(),
1126 this->n_dependent_variables(),
1127 this->independent_variable_values,
1134 Assert(this->independent_variables.size() ==
1135 this->n_independent_variables(),
1137 this->n_independent_variables()));
1139 this->tapeless_driver.jacobian(this->independent_variables,
1140 this->dependent_variables,
1153 typename ScalarType>
1156 const unsigned int n_dependent_variables)
1157 :
HelperBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
1158 n_dependent_variables)
1159 , symmetric_independent_variables(n_independent_variables, false)
1166 typename ScalarType>
1169 const unsigned int n_independent_variables,
1170 const unsigned int n_dependent_variables,
1171 const bool clear_registered_tapes)
1174 n_dependent_variables,
1175 clear_registered_tapes);
1177 const unsigned int new_n_independent_variables =
1179 n_independent_variables :
1180 this->n_independent_variables());
1181 symmetric_independent_variables =
1182 std::vector<bool>(new_n_independent_variables,
false);
1189 typename ScalarType>
1194 Assert(index < symmetric_independent_variables.size(),
1196 return symmetric_independent_variables[index];
1203 typename ScalarType>
1208 return std::count(symmetric_independent_variables.begin(),
1209 symmetric_independent_variables.end(),
1217 typename ScalarType>
1226 Assert(values.size() == this->n_independent_variables(),
1228 "Vector size does not match number of independent variables"));
1229 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1231 Assert(this->registered_independent_variable_values[i] ==
false,
1232 ExcMessage(
"Independent variable value already registered."));
1234 set_independent_variables(values);
1241 typename ScalarType>
1244 ScalarType>::ad_type> &
1250 Assert(this->active_tape_index() !=
1258 this->finalize_sensitive_independent_variables();
1259 Assert(this->independent_variables.size() ==
1260 this->n_independent_variables(),
1262 this->n_independent_variables()));
1264 return this->independent_variables;
1271 typename ScalarType>
1275 const bool symmetric_component,
1281 index < this->n_independent_variables(),
1283 "Trying to set the symmetry flag of a non-existent independent variable."));
1284 Assert(index < symmetric_independent_variables.size(),
1286 symmetric_independent_variables[index] = symmetric_component;
1293 typename ScalarType>
1300 Assert(this->active_tape_index() !=
1304 Assert(values.size() == this->n_independent_variables(),
1306 "Vector size does not match number of independent variables"));
1307 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1320 typename ScalarType>
1322 const unsigned int n_independent_variables)
1324 n_independent_variables,
1332 typename ScalarType>
1346 typename ScalarType>
1351 this->taped_driver.keep_independent_values() ==
false) ||
1355 this->n_registered_independent_variables() ==
1356 this->n_independent_variables(),
1358 "Not all values of sensitivities have been registered or subsequently set!"));
1360 Assert(this->n_registered_dependent_variables() ==
1361 this->n_dependent_variables(),
1362 ExcMessage(
"Not all dependent variables have been registered."));
1365 this->n_dependent_variables() == 1,
1367 "The ScalarFunction class expects there to be only one dependent variable."));
1371 Assert(this->active_tape_index() !=
1374 Assert(this->is_recording() ==
false,
1376 "Cannot compute values while tape is being recorded."));
1377 Assert(this->independent_variable_values.size() ==
1378 this->n_independent_variables(),
1380 this->n_independent_variables()));
1382 return this->taped_driver.value(this->active_tape_index(),
1383 this->independent_variable_values);
1389 return this->tapeless_driver.value(this->dependent_variables);
1396 typename ScalarType>
1402 this->taped_driver.keep_independent_values() ==
false) ||
1406 this->n_registered_independent_variables() ==
1407 this->n_independent_variables(),
1409 "Not all values of sensitivities have been registered or subsequently set!"));
1411 Assert(this->n_registered_dependent_variables() ==
1412 this->n_dependent_variables(),
1413 ExcMessage(
"Not all dependent variables have been registered."));
1416 this->n_dependent_variables() == 1,
1418 "The ScalarFunction class expects there to be only one dependent variable."));
1423 if (gradient.size() != this->n_independent_variables())
1424 gradient.reinit(this->n_independent_variables(),
1429 Assert(this->active_tape_index() !=
1432 Assert(this->is_recording() ==
false,
1434 "Cannot compute gradient while tape is being recorded."));
1435 Assert(this->independent_variable_values.size() ==
1436 this->n_independent_variables(),
1438 this->n_independent_variables()));
1440 this->taped_driver.gradient(this->active_tape_index(),
1441 this->independent_variable_values,
1448 Assert(this->independent_variables.size() ==
1449 this->n_independent_variables(),
1451 this->n_independent_variables()));
1453 this->tapeless_driver.gradient(this->independent_variables,
1454 this->dependent_variables,
1459 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1461 if (this->is_symmetric_independent_variable(i) ==
true)
1470 typename ScalarType>
1477 "Cannot computed function Hessian: AD number type does "
1478 "not support the calculation of second order derivatives."));
1481 this->taped_driver.keep_independent_values() ==
false))
1484 this->n_registered_independent_variables() ==
1485 this->n_independent_variables(),
1487 "Not all values of sensitivities have been registered or subsequently set!"));
1489 Assert(this->n_registered_dependent_variables() ==
1490 this->n_dependent_variables(),
1491 ExcMessage(
"Not all dependent variables have been registered."));
1494 this->n_dependent_variables() == 1,
1496 "The ScalarFunction class expects there to be only one dependent variable."));
1501 if (hessian.m() != this->n_independent_variables() ||
1502 hessian.n() != this->n_independent_variables())
1503 hessian.reinit({this->n_independent_variables(),
1504 this->n_independent_variables()},
1509 Assert(this->active_tape_index() !=
1512 Assert(this->is_recording() ==
false,
1514 "Cannot compute Hessian while tape is being recorded."));
1515 Assert(this->independent_variable_values.size() ==
1516 this->n_independent_variables(),
1518 this->n_independent_variables()));
1520 this->taped_driver.hessian(this->active_tape_index(),
1521 this->independent_variable_values,
1528 Assert(this->independent_variables.size() ==
1529 this->n_independent_variables(),
1531 this->n_independent_variables()));
1533 this->tapeless_driver.hessian(this->independent_variables,
1534 this->dependent_variables,
1539 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1540 for (
unsigned int j = 0; j < i + 1; ++j)
1542 if (this->is_symmetric_independent_variable(i) ==
true &&
1543 this->is_symmetric_independent_variable(j) ==
true)
1545 hessian[i][j] *= 0.25;
1547 hessian[j][i] *= 0.25;
1549 else if ((this->is_symmetric_independent_variable(i) ==
true &&
1550 this->is_symmetric_independent_variable(j) ==
false) ||
1551 (this->is_symmetric_independent_variable(j) ==
true &&
1552 this->is_symmetric_independent_variable(i) ==
false))
1554 hessian[i][j] *= 0.5;
1556 hessian[j][i] *= 0.5;
1565 typename ScalarType>
1584 const std::vector<unsigned int> row_index_set(
1585 internal::extract_field_component_indices<dim>(extractor_row));
1586 const std::vector<unsigned int> col_index_set(
1587 internal::extract_field_component_indices<dim>(extractor_col));
1593 hessian[row_index_set[0]][col_index_set[0]]);
1602 typename ScalarType>
1622 const std::vector<unsigned int> row_index_set(
1623 internal::extract_field_component_indices<dim>(extractor_row));
1624 const std::vector<unsigned int> col_index_set(
1625 internal::extract_field_component_indices<dim>(extractor_col));
1627 for (
unsigned int r = 0; r < row_index_set.size(); ++r)
1628 for (
unsigned int c = 0; c < col_index_set.size(); ++c)
1631 out, r, c, hessian[row_index_set[r]][col_index_set[c]]);
1645 typename ScalarType>
1647 const unsigned int n_independent_variables,
1648 const unsigned int n_dependent_variables)
1650 n_independent_variables,
1651 n_dependent_variables)
1658 typename ScalarType>
1663 Assert(funcs.size() == this->n_dependent_variables(),
1665 "Vector size does not match number of dependent variables"));
1666 for (
unsigned int i = 0; i < this->n_dependent_variables(); ++i)
1675 typename ScalarType>
1681 this->taped_driver.keep_independent_values() ==
false) ||
1685 this->n_registered_independent_variables() ==
1686 this->n_independent_variables(),
1688 "Not all values of sensitivities have been registered or subsequently set!"));
1690 Assert(this->n_registered_dependent_variables() ==
1691 this->n_dependent_variables(),
1692 ExcMessage(
"Not all dependent variables have been registered."));
1697 if (values.size() != this->n_dependent_variables())
1698 values.reinit(this->n_dependent_variables(),
1703 Assert(this->active_tape_index() !=
1706 Assert(this->is_recording() ==
false,
1708 "Cannot compute values while tape is being recorded."));
1709 Assert(this->independent_variable_values.size() ==
1710 this->n_independent_variables(),
1712 this->n_independent_variables()));
1714 this->taped_driver.values(this->active_tape_index(),
1715 this->n_dependent_variables(),
1716 this->independent_variable_values,
1723 this->tapeless_driver.values(this->dependent_variables, values);
1731 typename ScalarType>
1737 this->taped_driver.keep_independent_values() ==
false) ||
1741 this->n_registered_independent_variables() ==
1742 this->n_independent_variables(),
1744 "Not all values of sensitivities have been registered or subsequently set!"));
1746 Assert(this->n_registered_dependent_variables() ==
1747 this->n_dependent_variables(),
1748 ExcMessage(
"Not all dependent variables have been registered."));
1753 if (jacobian.
m() != this->n_dependent_variables() ||
1754 jacobian.
n() != this->n_independent_variables())
1755 jacobian.reinit({this->n_dependent_variables(),
1756 this->n_independent_variables()},
1761 Assert(this->active_tape_index() !=
1764 Assert(this->is_recording() ==
false,
1766 "Cannot compute Jacobian while tape is being recorded."));
1767 Assert(this->independent_variable_values.size() ==
1768 this->n_independent_variables(),
1770 this->n_independent_variables()));
1772 this->taped_driver.jacobian(this->active_tape_index(),
1773 this->n_dependent_variables(),
1774 this->independent_variable_values,
1781 Assert(this->independent_variables.size() ==
1782 this->n_independent_variables(),
1784 this->n_independent_variables()));
1786 this->tapeless_driver.jacobian(this->independent_variables,
1787 this->dependent_variables,
1791 for (
unsigned int j = 0; j < this->n_independent_variables(); ++j)
1796 if (this->is_symmetric_independent_variable(j) ==
true)
1797 for (
unsigned int i = 0; i < this->n_dependent_variables(); ++i)
1798 jacobian[i][j] *= 0.5;
1806 typename ScalarType>
1826 const std::vector<unsigned int> row_index_set(
1827 internal::extract_field_component_indices<dim>(extractor_row));
1828 const std::vector<unsigned int> col_index_set(
1829 internal::extract_field_component_indices<dim>(extractor_col));
1835 jacobian[row_index_set[0]][col_index_set[0]]);
1844 typename ScalarType>
1864 const std::vector<unsigned int> row_index_set(
1865 internal::extract_field_component_indices<dim>(extractor_row));
1866 const std::vector<unsigned int> col_index_set(
1867 internal::extract_field_component_indices<dim>(extractor_col));
1869 for (
unsigned int r = 0; r < row_index_set.size(); ++r)
1870 for (
unsigned int c = 0; c < col_index_set.size(); ++c)
1873 out, r, c, jacobian[row_index_set[r]][col_index_set[c]]);
1885# include "ad_helpers.inst"
1887# ifdef DEAL_II_WITH_ADOLC
1888# include "ad_helpers.inst1"
1890# ifdef DEAL_II_TRILINOS_WITH_SACADO
1891# include "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)
static const unsigned int invalid_unsigned_int
static void initialize_global_environment(const unsigned int n_independent_variables)