16 #include <deal.II/base/config.h> 18 #if defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO) 20 # include <deal.II/differentiation/ad/ad_drivers.h> 21 # include <deal.II/differentiation/ad/ad_helpers.h> 23 # include <type_traits> 26 DEAL_II_NAMESPACE_OPEN
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 for (
typename std::vector<bool>::iterator it =
85 registered_independent_variable_values.begin();
86 it != registered_independent_variable_values.end();
93 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
98 for (
typename std::vector<bool>::iterator it =
99 registered_marked_dependent_variables.begin();
100 it != registered_marked_dependent_variables.end();
107 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
110 const unsigned int index,
118 if (this->is_recording() ==
false)
119 start_recording_operations(1 );
121 Assert(this->is_recording() ==
true,
123 "Cannot change the value of an independent variable " 124 "of the tapeless variety while this class is not set" 125 "in recording operations."));
129 Assert(this->active_tape_index() !=
134 index < n_independent_variables(),
136 "Trying to set the value of a non-existent independent variable."));
138 independent_variable_values[index] = value;
139 registered_independent_variable_values[index] =
true;
144 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
147 const unsigned int index,
151 Assert(registered_independent_variable_values[index] ==
true,
157 registered_marked_independent_variables[index - 1] ==
true,
159 "Need to extract sensitivities in the order they're created."));
166 Assert(is_recording() ==
true,
168 "The marking of independent variables is only valid " 169 "during recording."));
173 independent_variable_values[index],
175 this->n_independent_variables(),
177 registered_marked_independent_variables[index] =
true;
182 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
185 ScalarType>::finalize_sensitive_independent_variables()
const 188 Assert(n_registered_independent_variables() == n_independent_variables(),
189 ExcMessage(
"Not all values of sensitivities have been recorded!"));
192 if (this->independent_variables.size() == 0)
194 this->independent_variables.resize(
195 this->n_independent_variables(),
199 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
200 this->mark_independent_variable(i, this->independent_variables[i]);
206 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
217 Assert(is_recording() ==
false,
219 "The initialization of non-sensitive independent variables is " 220 "only valid outside of recording operations."));
223 Assert(registered_independent_variable_values[index] ==
true,
226 out = independent_variable_values[index];
231 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
234 ScalarType>::n_registered_independent_variables()
const 236 return std::count(registered_independent_variable_values.begin(),
237 registered_independent_variable_values.end(),
243 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
247 return independent_variable_values.size();
252 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
257 return std::count(registered_marked_dependent_variables.begin(),
258 registered_marked_dependent_variables.end(),
264 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
268 return dependent_variables.size();
273 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
278 return taped_driver.is_recording();
280 return tapeless_driver.is_dependent_variable_marking_allowed();
285 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
291 return taped_driver.active_tape_index();
298 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
304 return taped_driver.is_registered_tape(tape_index);
311 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
316 const std::ios_base::fmtflags stream_flags(stream.flags());
318 stream.setf(std::ios_base::boolalpha);
320 stream <<
"Active tape index: " << active_tape_index() <<
"\n";
321 stream <<
"Recording? " << is_recording() <<
"\n";
322 stream << std::flush;
325 taped_driver.print(stream);
327 stream <<
"Registered independent variables: " 329 for (
unsigned int i = 0; i < n_independent_variables(); i++)
330 stream << registered_independent_variable_values[i]
331 << (i < (n_independent_variables() - 1) ?
"," :
"");
334 stream <<
"Independent variable values: " 336 print_values(stream);
338 stream <<
"Registered marked independent variables: " 340 for (
unsigned int i = 0; i < n_independent_variables(); i++)
341 stream << registered_marked_independent_variables[i]
342 << (i < (n_independent_variables() - 1) ?
"," :
"")
346 stream <<
"Dependent variable values: " 348 for (
unsigned int i = 0; i < n_dependent_variables(); i++)
349 stream << dependent_variables[i]
350 << (i < (n_dependent_variables() - 1) ?
"," :
"");
353 stream <<
"Registered dependent variables: " 355 for (
unsigned int i = 0; i < n_dependent_variables(); i++)
356 stream << registered_marked_dependent_variables[i]
357 << (i < (n_dependent_variables() - 1) ?
"," :
"");
361 stream.flags(stream_flags);
366 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
369 std::ostream &stream)
const 371 for (
unsigned int i = 0; i < n_independent_variables(); i++)
372 stream << independent_variable_values[i]
373 << (i < (n_independent_variables() - 1) ?
"," :
"")
380 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
384 std::ostream & stream)
const 389 Assert(is_registered_tape(tape_index),
392 this->taped_driver.print_tape_stats(tape_index, stream);
397 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
400 const unsigned int n_independent_variables,
401 const unsigned int n_dependent_variables,
402 const bool clear_registered_tapes)
404 const unsigned int new_n_independent_variables =
405 (n_independent_variables != ::numbers::invalid_unsigned_int ?
406 n_independent_variables :
407 this->n_independent_variables());
408 const unsigned int new_n_dependent_variables =
409 (n_dependent_variables != ::numbers::invalid_unsigned_int ?
410 n_dependent_variables :
411 this->n_dependent_variables());
425 std::vector<ad_type>().
swap(independent_variables);
426 std::vector<ad_type>().
swap(dependent_variables);
433 configure_tapeless_mode(new_n_independent_variables,
437 taped_driver.reset(clear_registered_tapes);
439 independent_variable_values = std::vector<scalar_type>(
440 new_n_independent_variables,
442 registered_independent_variable_values =
443 std::vector<bool>(new_n_independent_variables,
false);
444 registered_marked_independent_variables =
445 std::vector<bool>(new_n_independent_variables,
false);
446 dependent_variables =
447 std::vector<ad_type>(new_n_dependent_variables,
449 registered_marked_dependent_variables =
450 std::vector<bool>(new_n_dependent_variables,
false);
455 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
458 const unsigned int n_independent_variables,
459 const bool ensure_persistent_setting)
466 n_independent_variables);
468 if (ensure_persistent_setting ==
true)
481 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
486 activate_tape(tape_index,
true );
491 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
499 return taped_driver.requires_retaping(tape_index);
504 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
512 return taped_driver.last_action_requires_retaping();
517 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
524 taped_driver.remove_tape(taped_driver.active_tape_index());
529 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
533 const bool read_mode)
540 ExcMessage(
"Tape index exceeds maximum allowable value"));
541 taped_driver.activate_tape(tape_index);
542 reset_registered_independent_variables();
547 if (read_mode ==
true)
549 Assert(is_registered_tape(tape_index),
551 reset_registered_dependent_variables(
true);
552 Assert(n_registered_dependent_variables() ==
553 n_dependent_variables(),
554 ExcMessage(
"Not all dependent variables have been set!"));
566 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
577 taped_driver.set_tape_buffer_sizes(obufsize,
585 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
589 const bool overwrite_tape,
590 const bool keep_independent_values)
593 const bool read_mode =
false;
597 if (overwrite_tape !=
true)
599 Assert(is_recording() ==
false,
604 if (is_registered_tape(tape_index) ==
false || overwrite_tape ==
true)
608 activate_tape(tape_index, read_mode);
611 taped_driver.start_taping(active_tape_index(),
612 keep_independent_values);
616 reset_registered_independent_variables();
617 reset_registered_dependent_variables();
621 Assert(is_recording() ==
false,
623 "Tape recording is unexpectedly still enabled."));
627 activate_recorded_tape(tape_index);
637 tapeless_driver.allow_dependent_variable_marking();
642 activate_tape(tape_index, read_mode);
645 return is_recording();
650 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
653 const bool write_tapes_to_file)
658 Assert(n_registered_independent_variables() == n_independent_variables(),
659 ExcMessage(
"Not all values of sensitivities have been recorded!"));
664 taped_driver.stop_taping(active_tape_index(), write_tapes_to_file);
671 Assert(n_registered_dependent_variables() == n_dependent_variables(),
672 ExcMessage(
"Not all dependent variables have been set!"));
680 tapeless_driver.prevent_dependent_variable_marking();
686 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
689 const unsigned int index,
693 Assert(registered_marked_dependent_variables[index] ==
false,
695 "This dependent variable has already been registered."));
701 Assert(is_recording() ==
true,
703 "Must be recording when registering dependent variables."));
709 registered_marked_dependent_variables[index] =
true;
718 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
720 const unsigned int n_independent_variables,
721 const unsigned int n_dependent_variables)
722 :
HelperBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
723 n_dependent_variables)
728 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
731 const std::vector<scalar_type> &dof_values)
737 Assert(dof_values.size() == this->n_independent_variables(),
739 "Vector size does not match number of independent variables"));
740 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
742 Assert(this->registered_independent_variable_values[i] ==
false,
743 ExcMessage(
"Independent variable value already registered."));
745 set_dof_values(dof_values);
750 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
758 Assert(this->active_tape_index() !=
765 this->finalize_sensitive_independent_variables();
766 Assert(this->independent_variables.size() ==
767 this->n_independent_variables(),
769 this->n_independent_variables()));
771 return this->independent_variables;
776 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
779 const std::vector<scalar_type> &values)
783 Assert(this->active_tape_index() !=
787 Assert(values.size() == this->n_independent_variables(),
789 "Vector size does not match number of independent variables"));
790 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
801 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
803 const unsigned int n_independent_variables)
804 :
CellLevelBase<ADNumberTypeCode, ScalarType>(n_independent_variables, 1)
809 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
821 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
826 this->taped_driver.keep_independent_values() ==
false) ||
830 this->n_registered_independent_variables() ==
831 this->n_independent_variables(),
833 "Not all values of sensitivities have been registered or subsequently set!"));
835 Assert(this->n_registered_dependent_variables() ==
836 this->n_dependent_variables(),
837 ExcMessage(
"Not all dependent variables have been registered."));
840 this->n_dependent_variables() == 1,
842 "The EnergyFunctional class expects there to be only one dependent variable."));
846 Assert(this->active_tape_index() !=
849 Assert(this->is_recording() ==
false,
851 "Cannot compute value while tape is being recorded."));
852 Assert(this->independent_variable_values.size() ==
853 this->n_independent_variables(),
855 this->n_independent_variables()));
857 return this->taped_driver.value(this->active_tape_index(),
858 this->independent_variable_values);
864 Assert(this->independent_variables.size() ==
865 this->n_independent_variables(),
867 this->n_independent_variables()));
869 return this->tapeless_driver.value(this->dependent_variables);
875 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
878 Vector<scalar_type> &gradient)
const 881 this->taped_driver.keep_independent_values() ==
false) ||
885 this->n_registered_independent_variables() ==
886 this->n_independent_variables(),
888 "Not all values of sensitivities have been registered or subsequently set!"));
890 Assert(this->n_registered_dependent_variables() ==
891 this->n_dependent_variables(),
892 ExcMessage(
"Not all dependent variables have been registered."));
895 this->n_dependent_variables() == 1,
897 "The EnergyFunctional class expects there to be only one dependent variable."));
902 if (gradient.size() != this->n_independent_variables())
903 gradient.reinit(this->n_independent_variables(),
908 Assert(this->active_tape_index() !=
911 Assert(this->is_recording() ==
false,
913 "Cannot compute gradient while tape is being recorded."));
914 Assert(this->independent_variable_values.size() ==
915 this->n_independent_variables(),
917 this->n_independent_variables()));
919 this->taped_driver.gradient(this->active_tape_index(),
920 this->independent_variable_values,
927 Assert(this->independent_variables.size() ==
928 this->n_independent_variables(),
930 this->n_independent_variables()));
932 this->tapeless_driver.gradient(this->independent_variables,
933 this->dependent_variables,
940 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
947 "Cannot computed function Hessian: AD number type does" 948 "not support the calculation of second order derivatives."));
951 this->taped_driver.keep_independent_values() ==
false))
954 this->n_registered_independent_variables() ==
955 this->n_independent_variables(),
957 "Not all values of sensitivities have been registered or subsequently set!"));
959 Assert(this->n_registered_dependent_variables() ==
960 this->n_dependent_variables(),
961 ExcMessage(
"Not all dependent variables have been registered."));
964 this->n_dependent_variables() == 1,
966 "The EnergyFunctional class expects there to be only one dependent variable."));
971 if (hessian.
m() != this->n_independent_variables() ||
972 hessian.
n() != this->n_independent_variables())
973 hessian.
reinit({this->n_independent_variables(),
974 this->n_independent_variables()},
979 Assert(this->active_tape_index() !=
982 Assert(this->is_recording() ==
false,
984 "Cannot compute hessian while tape is being recorded."));
985 Assert(this->independent_variable_values.size() ==
986 this->n_independent_variables(),
988 this->n_independent_variables()));
990 this->taped_driver.hessian(this->active_tape_index(),
991 this->independent_variable_values,
998 Assert(this->independent_variables.size() ==
999 this->n_independent_variables(),
1001 this->n_independent_variables()));
1003 this->tapeless_driver.hessian(this->independent_variables,
1004 this->dependent_variables,
1014 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1016 const unsigned int n_independent_variables,
1017 const unsigned int n_dependent_variables)
1018 :
CellLevelBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
1019 n_dependent_variables)
1024 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1029 Assert(residual.size() == this->n_dependent_variables(),
1031 "Vector size does not match number of dependent variables"));
1032 for (
unsigned int i = 0; i < this->n_dependent_variables(); ++i)
1039 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1042 Vector<scalar_type> &values)
const 1045 this->taped_driver.keep_independent_values() ==
false) ||
1049 this->n_registered_independent_variables() ==
1050 this->n_independent_variables(),
1052 "Not all values of sensitivities have been registered or subsequently set!"));
1054 Assert(this->n_registered_dependent_variables() ==
1055 this->n_dependent_variables(),
1056 ExcMessage(
"Not all dependent variables have been registered."));
1061 if (values.size() != this->n_dependent_variables())
1062 values.reinit(this->n_dependent_variables(),
1067 Assert(this->active_tape_index() !=
1070 Assert(this->is_recording() ==
false,
1072 "Cannot compute values while tape is being recorded."));
1073 Assert(this->independent_variable_values.size() ==
1074 this->n_independent_variables(),
1076 this->n_independent_variables()));
1078 this->taped_driver.values(this->active_tape_index(),
1079 this->n_dependent_variables(),
1080 this->independent_variable_values,
1087 this->tapeless_driver.values(this->dependent_variables, values);
1093 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1099 this->taped_driver.keep_independent_values() ==
false) ||
1103 this->n_registered_independent_variables() ==
1104 this->n_independent_variables(),
1106 "Not all values of sensitivities have been registered or subsequently set!"));
1108 Assert(this->n_registered_dependent_variables() ==
1109 this->n_dependent_variables(),
1110 ExcMessage(
"Not all dependent variables have been registered."));
1115 if (jacobian.
m() != this->n_dependent_variables() ||
1116 jacobian.
n() != this->n_independent_variables())
1117 jacobian.
reinit({this->n_dependent_variables(),
1118 this->n_independent_variables()},
1123 Assert(this->active_tape_index() !=
1126 Assert(this->is_recording() ==
false,
1128 "Cannot compute hessian while tape is being recorded."));
1129 Assert(this->independent_variable_values.size() ==
1130 this->n_independent_variables(),
1132 this->n_independent_variables()));
1134 this->taped_driver.jacobian(this->active_tape_index(),
1135 this->n_dependent_variables(),
1136 this->independent_variable_values,
1143 Assert(this->independent_variables.size() ==
1144 this->n_independent_variables(),
1146 this->n_independent_variables()));
1148 this->tapeless_driver.jacobian(this->independent_variables,
1149 this->dependent_variables,
1162 typename ScalarType>
1165 const unsigned int n_dependent_variables)
1166 :
HelperBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
1167 n_dependent_variables)
1168 , symmetric_independent_variables(n_independent_variables, false)
1175 typename ScalarType>
1178 const unsigned int n_independent_variables,
1179 const unsigned int n_dependent_variables,
1180 const bool clear_registered_tapes)
1183 n_dependent_variables,
1184 clear_registered_tapes);
1186 const unsigned int new_n_independent_variables =
1187 (n_independent_variables != ::numbers::invalid_unsigned_int ?
1188 n_independent_variables :
1189 this->n_independent_variables());
1190 symmetric_independent_variables =
1191 std::vector<bool>(new_n_independent_variables,
false);
1198 typename ScalarType>
1203 Assert(index < symmetric_independent_variables.size(),
1205 return symmetric_independent_variables[index];
1212 typename ScalarType>
1217 return std::count(symmetric_independent_variables.begin(),
1218 symmetric_independent_variables.end(),
1226 typename ScalarType>
1235 Assert(values.size() == this->n_independent_variables(),
1237 "Vector size does not match number of independent variables"));
1238 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1240 Assert(this->registered_independent_variable_values[i] ==
false,
1241 ExcMessage(
"Independent variable value already registered."));
1243 set_independent_variables(values);
1250 typename ScalarType>
1253 ScalarType>::ad_type> &
1259 Assert(this->active_tape_index() !=
1267 this->finalize_sensitive_independent_variables();
1268 Assert(this->independent_variables.size() ==
1269 this->n_independent_variables(),
1271 this->n_independent_variables()));
1273 return this->independent_variables;
1280 typename ScalarType>
1284 const bool symmetric_component,
1290 index < this->n_independent_variables(),
1292 "Trying to set the symmetry flag of a non-existent independent variable."));
1293 Assert(index < symmetric_independent_variables.size(),
1295 symmetric_independent_variables[index] = symmetric_component;
1302 typename ScalarType>
1309 Assert(this->active_tape_index() !=
1313 Assert(values.size() == this->n_independent_variables(),
1315 "Vector size does not match number of independent variables"));
1316 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1329 typename ScalarType>
1331 const unsigned int n_independent_variables)
1333 n_independent_variables,
1341 typename ScalarType>
1355 typename ScalarType>
1360 this->taped_driver.keep_independent_values() ==
false) ||
1364 this->n_registered_independent_variables() ==
1365 this->n_independent_variables(),
1367 "Not all values of sensitivities have been registered or subsequently set!"));
1369 Assert(this->n_registered_dependent_variables() ==
1370 this->n_dependent_variables(),
1371 ExcMessage(
"Not all dependent variables have been registered."));
1374 this->n_dependent_variables() == 1,
1376 "The ScalarFunction class expects there to be only one dependent variable."));
1380 Assert(this->active_tape_index() !=
1383 Assert(this->is_recording() ==
false,
1385 "Cannot compute values while tape is being recorded."));
1386 Assert(this->independent_variable_values.size() ==
1387 this->n_independent_variables(),
1389 this->n_independent_variables()));
1391 return this->taped_driver.value(this->active_tape_index(),
1392 this->independent_variable_values);
1398 return this->tapeless_driver.value(this->dependent_variables);
1405 typename ScalarType>
1408 Vector<scalar_type> &gradient)
const 1411 this->taped_driver.keep_independent_values() ==
false) ||
1415 this->n_registered_independent_variables() ==
1416 this->n_independent_variables(),
1418 "Not all values of sensitivities have been registered or subsequently set!"));
1420 Assert(this->n_registered_dependent_variables() ==
1421 this->n_dependent_variables(),
1422 ExcMessage(
"Not all dependent variables have been registered."));
1425 this->n_dependent_variables() == 1,
1427 "The ScalarFunction class expects there to be only one dependent variable."));
1432 if (gradient.size() != this->n_independent_variables())
1433 gradient.reinit(this->n_independent_variables(),
1438 Assert(this->active_tape_index() !=
1441 Assert(this->is_recording() ==
false,
1443 "Cannot compute gradient while tape is being recorded."));
1444 Assert(this->independent_variable_values.size() ==
1445 this->n_independent_variables(),
1447 this->n_independent_variables()));
1449 this->taped_driver.gradient(this->active_tape_index(),
1450 this->independent_variable_values,
1457 Assert(this->independent_variables.size() ==
1458 this->n_independent_variables(),
1460 this->n_independent_variables()));
1462 this->tapeless_driver.gradient(this->independent_variables,
1463 this->dependent_variables,
1468 for (
unsigned int i = 0; i < this->n_independent_variables(); i++)
1470 if (this->is_symmetric_independent_variable(i) ==
true)
1479 typename ScalarType>
1486 "Cannot computed function Hessian: AD number type does" 1487 "not support the calculation of second order derivatives."));
1490 this->taped_driver.keep_independent_values() ==
false))
1493 this->n_registered_independent_variables() ==
1494 this->n_independent_variables(),
1496 "Not all values of sensitivities have been registered or subsequently set!"));
1498 Assert(this->n_registered_dependent_variables() ==
1499 this->n_dependent_variables(),
1500 ExcMessage(
"Not all dependent variables have been registered."));
1503 this->n_dependent_variables() == 1,
1505 "The ScalarFunction class expects there to be only one dependent variable."));
1510 if (hessian.
m() != this->n_independent_variables() ||
1511 hessian.
n() != this->n_independent_variables())
1512 hessian.
reinit({this->n_independent_variables(),
1513 this->n_independent_variables()},
1518 Assert(this->active_tape_index() !=
1521 Assert(this->is_recording() ==
false,
1523 "Cannot compute Hessian while tape is being recorded."));
1524 Assert(this->independent_variable_values.size() ==
1525 this->n_independent_variables(),
1527 this->n_independent_variables()));
1529 this->taped_driver.hessian(this->active_tape_index(),
1530 this->independent_variable_values,
1537 Assert(this->independent_variables.size() ==
1538 this->n_independent_variables(),
1540 this->n_independent_variables()));
1542 this->tapeless_driver.hessian(this->independent_variables,
1543 this->dependent_variables,
1548 for (
unsigned int i = 0; i < this->n_independent_variables(); i++)
1549 for (
unsigned int j = 0; j < i + 1; j++)
1551 if (this->is_symmetric_independent_variable(i) ==
true &&
1552 this->is_symmetric_independent_variable(j) ==
true)
1554 hessian[i][j] *= 0.25;
1556 hessian[j][i] *= 0.25;
1558 else if ((this->is_symmetric_independent_variable(i) ==
true &&
1559 this->is_symmetric_independent_variable(j) ==
false) ||
1560 (this->is_symmetric_independent_variable(j) ==
true &&
1561 this->is_symmetric_independent_variable(i) ==
false))
1563 hessian[i][j] *= 0.5;
1565 hessian[j][i] *= 0.5;
1574 typename ScalarType>
1593 const std::vector<unsigned int> row_index_set(
1594 internal::extract_field_component_indices<dim>(extractor_row));
1595 const std::vector<unsigned int> col_index_set(
1596 internal::extract_field_component_indices<dim>(extractor_col));
1602 hessian[row_index_set[0]][col_index_set[0]]);
1611 typename ScalarType>
1631 const std::vector<unsigned int> row_index_set(
1632 internal::extract_field_component_indices<dim>(extractor_row));
1633 const std::vector<unsigned int> col_index_set(
1634 internal::extract_field_component_indices<dim>(extractor_col));
1636 for (
unsigned int r = 0; r < row_index_set.size(); ++r)
1637 for (
unsigned int c = 0; c < col_index_set.size(); ++c)
1640 out, r, c, hessian[row_index_set[r]][col_index_set[c]]);
1654 typename ScalarType>
1656 const unsigned int n_independent_variables,
1657 const unsigned int n_dependent_variables)
1659 n_independent_variables,
1660 n_dependent_variables)
1667 typename ScalarType>
1672 Assert(funcs.size() == this->n_dependent_variables(),
1674 "Vector size does not match number of dependent variables"));
1675 for (
unsigned int i = 0; i < this->n_dependent_variables(); ++i)
1684 typename ScalarType>
1687 Vector<scalar_type> &values)
const 1690 this->taped_driver.keep_independent_values() ==
false) ||
1694 this->n_registered_independent_variables() ==
1695 this->n_independent_variables(),
1697 "Not all values of sensitivities have been registered or subsequently set!"));
1699 Assert(this->n_registered_dependent_variables() ==
1700 this->n_dependent_variables(),
1701 ExcMessage(
"Not all dependent variables have been registered."));
1706 if (values.size() != this->n_dependent_variables())
1707 values.reinit(this->n_dependent_variables(),
1712 Assert(this->active_tape_index() !=
1715 Assert(this->is_recording() ==
false,
1717 "Cannot compute values while tape is being recorded."));
1718 Assert(this->independent_variable_values.size() ==
1719 this->n_independent_variables(),
1721 this->n_independent_variables()));
1723 this->taped_driver.values(this->active_tape_index(),
1724 this->n_dependent_variables(),
1725 this->independent_variable_values,
1732 this->tapeless_driver.values(this->dependent_variables, values);
1740 typename ScalarType>
1746 this->taped_driver.keep_independent_values() ==
false) ||
1750 this->n_registered_independent_variables() ==
1751 this->n_independent_variables(),
1753 "Not all values of sensitivities have been registered or subsequently set!"));
1755 Assert(this->n_registered_dependent_variables() ==
1756 this->n_dependent_variables(),
1757 ExcMessage(
"Not all dependent variables have been registered."));
1762 if (jacobian.
m() != this->n_dependent_variables() ||
1763 jacobian.
n() != this->n_independent_variables())
1764 jacobian.
reinit({this->n_dependent_variables(),
1765 this->n_independent_variables()},
1770 Assert(this->active_tape_index() !=
1773 Assert(this->is_recording() ==
false,
1775 "Cannot compute Jacobian while tape is being recorded."));
1776 Assert(this->independent_variable_values.size() ==
1777 this->n_independent_variables(),
1779 this->n_independent_variables()));
1781 this->taped_driver.jacobian(this->active_tape_index(),
1782 this->n_dependent_variables(),
1783 this->independent_variable_values,
1790 Assert(this->independent_variables.size() ==
1791 this->n_independent_variables(),
1793 this->n_independent_variables()));
1795 this->tapeless_driver.jacobian(this->independent_variables,
1796 this->dependent_variables,
1800 for (
unsigned int j = 0; j < this->n_independent_variables(); j++)
1805 if (this->is_symmetric_independent_variable(j) ==
true)
1806 for (
unsigned int i = 0; i < this->n_dependent_variables(); i++)
1807 jacobian[i][j] *= 0.5;
1815 typename ScalarType>
1835 const std::vector<unsigned int> row_index_set(
1836 internal::extract_field_component_indices<dim>(extractor_row));
1837 const std::vector<unsigned int> col_index_set(
1838 internal::extract_field_component_indices<dim>(extractor_col));
1844 jacobian[row_index_set[0]][col_index_set[0]]);
1853 typename ScalarType>
1873 const std::vector<unsigned int> row_index_set(
1874 internal::extract_field_component_indices<dim>(extractor_row));
1875 const std::vector<unsigned int> col_index_set(
1876 internal::extract_field_component_indices<dim>(extractor_col));
1878 for (
unsigned int r = 0; r < row_index_set.size(); ++r)
1879 for (
unsigned int c = 0; c < col_index_set.size(); ++c)
1882 out, r, c, jacobian[row_index_set[r]][col_index_set[c]]);
1894 # include "ad_helpers.inst" 1896 # ifdef DEAL_II_WITH_ADOLC 1897 # include "ad_helpers.inst1" 1899 # ifdef DEAL_II_TRILINOS_WITH_SACADO 1900 # include "ad_helpers.inst2" 1904 DEAL_II_NAMESPACE_CLOSE
1906 #endif // defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)
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 is_recording() const
HelperBase(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
PointLevelFunctionsBase(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
void compute_jacobian(FullMatrix< scalar_type > &jacobian) const
VectorFunction(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
void set_sensitivity_value(const unsigned int index, const scalar_type &value)
scalar_type compute_energy() const
void mark_independent_variable(const unsigned int index, ad_type &out) const
void set_tensor_entry(TensorType &t, const unsigned int &unrolled_index, const NumberType &value)
void compute_residual(Vector< scalar_type > &residual) const override
CellLevelBase(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
void register_independent_variables(const std::vector< scalar_type > &values)
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)
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)
virtual void compute_residual(Vector< scalar_type > &residual) const override
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)
const std::vector< ad_type > & get_sensitive_dof_values() const
unsigned int tape_buffer_sizes
void register_dependent_variable(const ad_type &func)
void stop_recording_operations(const bool write_tapes_to_file=false)
void compute_gradient(Vector< scalar_type > &gradient) const
static void configure_tapeless_mode(const unsigned int n_independent_variables, const bool ensure_persistent_setting=true)
Types< ad_type >::tape_index active_tape_index() const
void set_sensitivity_value(const unsigned int index, const bool symmetric_component, const scalar_type &value)
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
ResidualLinearization(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
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 compute_values(Vector< scalar_type > &values) const
unsigned int n_symmetric_independent_variables() const
void reset_registered_dependent_variables(const bool flag=false)
void register_dependent_variable(const unsigned int index, const ad_type &func)
void print_values(std::ostream &stream) const
static ::ExceptionBase & ExcMessage(std::string arg1)
std::vector< ad_type > dependent_variables
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::ad_type ad_type
virtual void compute_linearization(FullMatrix< scalar_type > &linearization) const override
void compute_hessian(FullMatrix< scalar_type > &hessian) const
std::size_t n_independent_variables() const
void reinit(const TableIndices< N > &new_size, const bool omit_default_initialization=false)
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::scalar_type scalar_type
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
ScalarFunction(const unsigned int n_independent_variables)
scalar_type compute_value() const
unsigned int n_registered_dependent_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
void register_energy_functional(const ad_type &energy)
void print(std::ostream &stream) const
virtual void compute_linearization(FullMatrix< scalar_type > &linearization) const override
bool is_symmetric_independent_variable(const unsigned int index) const
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
void swap(Vector< Number > &u, Vector< Number > &v)
void register_dof_values(const std::vector< scalar_type > &dof_values)
static void initialize_global_environment(const unsigned int n_independent_variables)
bool active_tape_requires_retaping() const
void register_dependent_variables(const std::vector< ad_type > &funcs)
void initialize_non_sensitive_independent_variable(const unsigned int index, ad_type &out) const
bool recorded_tape_requires_retaping(const typename Types< ad_type >::tape_index tape_index) const
void register_residual_vector(const std::vector< ad_type > &residual)
void print_tape_stats(const typename Types< ad_type >::tape_index tape_index, std::ostream &stream) const
bool is_registered_tape(const typename Types< ad_type >::tape_index tape_index) const
std::size_t n_dependent_variables() const
void activate_recorded_tape(const typename Types< ad_type >::tape_index tape_index)
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
void set_independent_variables(const std::vector< scalar_type > &values)
EnergyFunctional(const unsigned int n_independent_variables)
const std::vector< ad_type > & get_sensitive_variables() const
void set_dof_values(const std::vector< scalar_type > &dof_values)
static ::ExceptionBase & ExcInternalError()
void activate_tape(const typename Types< ad_type >::tape_index tape_index, const bool read_mode)